mirror of https://github.com/kurisufriend/Clover
parent
99ce139bf8
commit
5fc8c7b0d7
@ -0,0 +1,25 @@ |
|||||||
|
/* |
||||||
|
* Clover - 4chan browser https://github.com/Floens/Clover/
|
||||||
|
* Copyright (C) 2014 Floens |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
package org.floens.chan.core.site.common; |
||||||
|
|
||||||
|
import org.floens.chan.core.model.Post; |
||||||
|
import org.floens.chan.ui.theme.Theme; |
||||||
|
|
||||||
|
public interface ChanParser { |
||||||
|
Post parse(Theme theme, Post.Builder builder); |
||||||
|
} |
@ -0,0 +1,160 @@ |
|||||||
|
/* |
||||||
|
* Clover - 4chan browser https://github.com/Floens/Clover/
|
||||||
|
* Copyright (C) 2014 Floens |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
package org.floens.chan.core.site.common; |
||||||
|
|
||||||
|
import android.graphics.Typeface; |
||||||
|
import android.text.SpannableString; |
||||||
|
import android.text.TextUtils; |
||||||
|
import android.text.style.StrikethroughSpan; |
||||||
|
import android.text.style.StyleSpan; |
||||||
|
|
||||||
|
import org.floens.chan.core.model.Post; |
||||||
|
import org.floens.chan.core.model.PostLinkable; |
||||||
|
import org.floens.chan.ui.span.ForegroundColorSpanHashed; |
||||||
|
import org.floens.chan.ui.theme.Theme; |
||||||
|
import org.jsoup.nodes.Element; |
||||||
|
|
||||||
|
import java.util.Set; |
||||||
|
import java.util.regex.Matcher; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
public class DefaultFutabaChanParserHandler implements FutabaChanParserHandler { |
||||||
|
private static final Pattern COLOR_PATTERN = Pattern.compile("color:#([0-9a-fA-F]*)"); |
||||||
|
|
||||||
|
@Override |
||||||
|
public CharSequence handleParagraph(FutabaChanParser parser, Theme theme, Post.Builder post, CharSequence text, Element element) { |
||||||
|
return text; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CharSequence handleSpan(FutabaChanParser parser, Theme theme, Post.Builder post, Element span) { |
||||||
|
SpannableString quote; |
||||||
|
|
||||||
|
Set<String> classes = span.classNames(); |
||||||
|
if (classes.contains("deadlink")) { |
||||||
|
quote = new SpannableString(span.text()); |
||||||
|
quote.setSpan(new ForegroundColorSpanHashed(theme.quoteColor), 0, quote.length(), 0); |
||||||
|
quote.setSpan(new StrikethroughSpan(), 0, quote.length(), 0); |
||||||
|
} else if (classes.contains("fortune")) { |
||||||
|
// html looks like <span class="fortune" style="color:#0893e1"><br><br><b>Your fortune:</b>
|
||||||
|
// manually add these <br>
|
||||||
|
quote = new SpannableString("\n\n" + span.text()); |
||||||
|
|
||||||
|
String style = span.attr("style"); |
||||||
|
if (!TextUtils.isEmpty(style)) { |
||||||
|
style = style.replace(" ", ""); |
||||||
|
|
||||||
|
// private static final Pattern COLOR_PATTERN = Pattern.compile("color:#([0-9a-fA-F]*)");
|
||||||
|
Matcher matcher = COLOR_PATTERN.matcher(style); |
||||||
|
|
||||||
|
int hexColor = 0xff0000; |
||||||
|
if (matcher.find()) { |
||||||
|
String group = matcher.group(1); |
||||||
|
if (!TextUtils.isEmpty(group)) { |
||||||
|
try { |
||||||
|
hexColor = Integer.parseInt(group, 16); |
||||||
|
} catch (NumberFormatException ignored) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (hexColor >= 0 && hexColor <= 0xffffff) { |
||||||
|
quote.setSpan(new ForegroundColorSpanHashed(0xff000000 + hexColor), 0, quote.length(), 0); |
||||||
|
quote.setSpan(new StyleSpan(Typeface.BOLD), 0, quote.length(), 0); |
||||||
|
} |
||||||
|
} |
||||||
|
} else if (classes.contains("abbr")) { |
||||||
|
return null; |
||||||
|
} else { |
||||||
|
quote = new SpannableString(span.text()); |
||||||
|
quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0); |
||||||
|
parser.detectLinks(theme, post, span.text(), quote); |
||||||
|
} |
||||||
|
|
||||||
|
return quote; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Link getLink(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor) { |
||||||
|
String href = anchor.attr("href"); |
||||||
|
Set<String> classes = anchor.classNames(); |
||||||
|
|
||||||
|
PostLinkable.Type t = null; |
||||||
|
String key = null; |
||||||
|
Object value = null; |
||||||
|
if (classes.contains("quotelink")) { |
||||||
|
if (href.contains("/thread/")) { |
||||||
|
// link to another thread
|
||||||
|
PostLinkable.ThreadLink threadLink = null; |
||||||
|
|
||||||
|
String[] slashSplit = href.split("/"); |
||||||
|
if (slashSplit.length == 4) { |
||||||
|
String board = slashSplit[1]; |
||||||
|
String nums = slashSplit[3]; |
||||||
|
String[] numsSplitted = nums.split("#p"); |
||||||
|
if (numsSplitted.length == 2) { |
||||||
|
try { |
||||||
|
int tId = Integer.parseInt(numsSplitted[0]); |
||||||
|
int pId = Integer.parseInt(numsSplitted[1]); |
||||||
|
threadLink = new PostLinkable.ThreadLink(board, tId, pId); |
||||||
|
} catch (NumberFormatException ignored) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (threadLink != null) { |
||||||
|
t = PostLinkable.Type.THREAD; |
||||||
|
key = anchor.text(); |
||||||
|
value = threadLink; |
||||||
|
} |
||||||
|
} else { |
||||||
|
// normal quote
|
||||||
|
int id = -1; |
||||||
|
|
||||||
|
String[] splitted = href.split("#p"); |
||||||
|
if (splitted.length == 2) { |
||||||
|
try { |
||||||
|
id = Integer.parseInt(splitted[1]); |
||||||
|
} catch (NumberFormatException ignored) { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (id >= 0) { |
||||||
|
t = PostLinkable.Type.QUOTE; |
||||||
|
key = anchor.text(); |
||||||
|
value = id; |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
// normal link
|
||||||
|
t = PostLinkable.Type.LINK; |
||||||
|
key = anchor.text(); |
||||||
|
value = href; |
||||||
|
} |
||||||
|
|
||||||
|
if (t != null && key != null && value != null) { |
||||||
|
Link link = new Link(); |
||||||
|
link.type = t; |
||||||
|
link.key = key; |
||||||
|
link.value = value; |
||||||
|
return link; |
||||||
|
} else { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
/* |
||||||
|
* Clover - 4chan browser https://github.com/Floens/Clover/
|
||||||
|
* Copyright (C) 2014 Floens |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/package org.floens.chan.core.site.common; |
||||||
|
|
||||||
|
import org.floens.chan.core.model.Post; |
||||||
|
import org.floens.chan.core.model.PostLinkable; |
||||||
|
import org.floens.chan.ui.theme.Theme; |
||||||
|
import org.jsoup.nodes.Element; |
||||||
|
|
||||||
|
public interface FutabaChanParserHandler { |
||||||
|
CharSequence handleParagraph(FutabaChanParser parser, Theme theme, Post.Builder post, CharSequence text, Element element); |
||||||
|
|
||||||
|
CharSequence handleSpan(FutabaChanParser parser, Theme theme, Post.Builder post, Element span); |
||||||
|
|
||||||
|
Link getLink(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor); |
||||||
|
|
||||||
|
class Link { |
||||||
|
public PostLinkable.Type type; |
||||||
|
public String key; |
||||||
|
public Object value; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,133 @@ |
|||||||
|
/* |
||||||
|
* Clover - 4chan browser https://github.com/Floens/Clover/
|
||||||
|
* Copyright (C) 2014 Floens |
||||||
|
* |
||||||
|
* This program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
package org.floens.chan.core.site.sites.chan8; |
||||||
|
|
||||||
|
import android.text.SpannableString; |
||||||
|
|
||||||
|
import org.floens.chan.core.model.Post; |
||||||
|
import org.floens.chan.core.model.PostLinkable; |
||||||
|
import org.floens.chan.core.site.common.DefaultFutabaChanParserHandler; |
||||||
|
import org.floens.chan.core.site.common.FutabaChanParser; |
||||||
|
import org.floens.chan.ui.span.ForegroundColorSpanHashed; |
||||||
|
import org.floens.chan.ui.theme.Theme; |
||||||
|
import org.jsoup.nodes.Element; |
||||||
|
|
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
public class Chan8ParserHandler extends DefaultFutabaChanParserHandler { |
||||||
|
@Override |
||||||
|
public CharSequence handleParagraph(FutabaChanParser parser, Theme theme, Post.Builder post, CharSequence text, Element element) { |
||||||
|
if (element.hasClass("quote")) { |
||||||
|
SpannableString quote = new SpannableString(text); |
||||||
|
quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0); |
||||||
|
parser.detectLinks(theme, post, quote.toString(), quote); |
||||||
|
return quote; |
||||||
|
} else { |
||||||
|
return text; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CharSequence handleSpan(FutabaChanParser parser, Theme theme, Post.Builder post, Element span) { |
||||||
|
SpannableString quote; |
||||||
|
|
||||||
|
Set<String> classes = span.classNames(); |
||||||
|
if (classes.contains("abbr")) { |
||||||
|
return null; |
||||||
|
} else if (classes.contains("spoiler")) { |
||||||
|
quote = new SpannableString(span.text()); |
||||||
|
PostLinkable pl = new PostLinkable(theme, span.text(), span.text(), PostLinkable.Type.SPOILER); |
||||||
|
quote.setSpan(pl, 0, quote.length(), 0); |
||||||
|
post.addLinkable(pl); |
||||||
|
} else { |
||||||
|
quote = new SpannableString(span.text()); |
||||||
|
quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0); |
||||||
|
parser.detectLinks(theme, post, span.text(), quote); |
||||||
|
} |
||||||
|
|
||||||
|
return quote; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Link getLink(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor) { |
||||||
|
String href = anchor.attr("href"); |
||||||
|
|
||||||
|
PostLinkable.Type t = null; |
||||||
|
String key = null; |
||||||
|
Object value = null; |
||||||
|
if (href.startsWith("/")) { |
||||||
|
if (href.contains("/thread/")) { |
||||||
|
// link to another thread
|
||||||
|
PostLinkable.ThreadLink threadLink = null; |
||||||
|
|
||||||
|
String[] slashSplit = href.split("/"); |
||||||
|
if (slashSplit.length == 4) { |
||||||
|
String board = slashSplit[1]; |
||||||
|
String nums = slashSplit[3]; |
||||||
|
String[] numsSplitted = nums.split("#p"); |
||||||
|
if (numsSplitted.length == 2) { |
||||||
|
try { |
||||||
|
int tId = Integer.parseInt(numsSplitted[0]); |
||||||
|
int pId = Integer.parseInt(numsSplitted[1]); |
||||||
|
threadLink = new PostLinkable.ThreadLink(board, tId, pId); |
||||||
|
} catch (NumberFormatException ignored) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (threadLink != null) { |
||||||
|
t = PostLinkable.Type.THREAD; |
||||||
|
key = anchor.text(); |
||||||
|
value = threadLink; |
||||||
|
} |
||||||
|
} else { |
||||||
|
// normal quote
|
||||||
|
int id = -1; |
||||||
|
|
||||||
|
String[] splitted = href.split("#"); |
||||||
|
if (splitted.length == 2) { |
||||||
|
try { |
||||||
|
id = Integer.parseInt(splitted[1]); |
||||||
|
} catch (NumberFormatException ignored) { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (id >= 0) { |
||||||
|
t = PostLinkable.Type.QUOTE; |
||||||
|
key = anchor.text(); |
||||||
|
value = id; |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
// normal link
|
||||||
|
t = PostLinkable.Type.LINK; |
||||||
|
key = anchor.text(); |
||||||
|
value = href; |
||||||
|
} |
||||||
|
|
||||||
|
if (t != null && key != null && value != null) { |
||||||
|
Link link = new Link(); |
||||||
|
link.type = t; |
||||||
|
link.key = key; |
||||||
|
link.value = value; |
||||||
|
return link; |
||||||
|
} else { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue