|
|
@ -15,7 +15,7 @@ |
|
|
|
* You should have received a copy of the GNU General Public License |
|
|
|
* You should have received a copy of the GNU General Public License |
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
package org.floens.chan.core.loader; |
|
|
|
package org.floens.chan.chan; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import android.content.Context; |
|
|
|
import android.content.Context; |
|
|
@ -29,6 +29,7 @@ import android.text.style.ForegroundColorSpan; |
|
|
|
import android.text.style.StrikethroughSpan; |
|
|
|
import android.text.style.StrikethroughSpan; |
|
|
|
import android.text.style.StyleSpan; |
|
|
|
import android.text.style.StyleSpan; |
|
|
|
import android.text.style.TypefaceSpan; |
|
|
|
import android.text.style.TypefaceSpan; |
|
|
|
|
|
|
|
import android.text.style.UnderlineSpan; |
|
|
|
|
|
|
|
|
|
|
|
import org.floens.chan.Chan; |
|
|
|
import org.floens.chan.Chan; |
|
|
|
import org.floens.chan.R; |
|
|
|
import org.floens.chan.R; |
|
|
@ -36,6 +37,7 @@ import org.floens.chan.core.model.Post; |
|
|
|
import org.floens.chan.core.model.PostLinkable; |
|
|
|
import org.floens.chan.core.model.PostLinkable; |
|
|
|
import org.floens.chan.core.settings.ChanSettings; |
|
|
|
import org.floens.chan.core.settings.ChanSettings; |
|
|
|
import org.floens.chan.utils.AndroidUtils; |
|
|
|
import org.floens.chan.utils.AndroidUtils; |
|
|
|
|
|
|
|
import org.floens.chan.utils.Logger; |
|
|
|
import org.floens.chan.utils.ThemeHelper; |
|
|
|
import org.floens.chan.utils.ThemeHelper; |
|
|
|
import org.jsoup.Jsoup; |
|
|
|
import org.jsoup.Jsoup; |
|
|
|
import org.jsoup.helper.StringUtil; |
|
|
|
import org.jsoup.helper.StringUtil; |
|
|
@ -44,9 +46,11 @@ import org.jsoup.nodes.Element; |
|
|
|
import org.jsoup.nodes.Node; |
|
|
|
import org.jsoup.nodes.Node; |
|
|
|
import org.jsoup.nodes.TextNode; |
|
|
|
import org.jsoup.nodes.TextNode; |
|
|
|
import org.jsoup.parser.Parser; |
|
|
|
import org.jsoup.parser.Parser; |
|
|
|
|
|
|
|
import org.jsoup.select.Elements; |
|
|
|
import org.jsoup.select.NodeTraversor; |
|
|
|
import org.jsoup.select.NodeTraversor; |
|
|
|
import org.jsoup.select.NodeVisitor; |
|
|
|
import org.jsoup.select.NodeVisitor; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.regex.Matcher; |
|
|
|
import java.util.regex.Matcher; |
|
|
@ -55,6 +59,7 @@ import java.util.regex.Pattern; |
|
|
|
import static org.floens.chan.utils.AndroidUtils.sp; |
|
|
|
import static org.floens.chan.utils.AndroidUtils.sp; |
|
|
|
|
|
|
|
|
|
|
|
public class ChanParser { |
|
|
|
public class ChanParser { |
|
|
|
|
|
|
|
private static final String TAG = "ChanParser"; |
|
|
|
private static final Pattern colorPattern = Pattern.compile("color:#([0-9a-fA-F]*)"); |
|
|
|
private static final Pattern colorPattern = Pattern.compile("color:#([0-9a-fA-F]*)"); |
|
|
|
|
|
|
|
|
|
|
|
private static ChanParser instance = new ChanParser(); |
|
|
|
private static ChanParser instance = new ChanParser(); |
|
|
@ -192,15 +197,18 @@ public class ChanParser { |
|
|
|
Document document = Jsoup.parseBodyFragment(comment); |
|
|
|
Document document = Jsoup.parseBodyFragment(comment); |
|
|
|
|
|
|
|
|
|
|
|
List<Node> nodes = document.body().childNodes(); |
|
|
|
List<Node> nodes = document.body().childNodes(); |
|
|
|
|
|
|
|
List<CharSequence> texts = new ArrayList<>(nodes.size()); |
|
|
|
|
|
|
|
|
|
|
|
for (Node node : nodes) { |
|
|
|
for (Node node : nodes) { |
|
|
|
CharSequence nodeParsed = parseNode(post, node); |
|
|
|
CharSequence nodeParsed = parseNode(post, node); |
|
|
|
if (nodeParsed != null) { |
|
|
|
if (nodeParsed != null) { |
|
|
|
total = TextUtils.concat(total, nodeParsed); |
|
|
|
texts.add(nodeParsed); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
total = TextUtils.concat(texts.toArray(new CharSequence[texts.size()])); |
|
|
|
} catch (Exception e) { |
|
|
|
} catch (Exception e) { |
|
|
|
e.printStackTrace(); |
|
|
|
Logger.e(TAG, "Error parsing comment html", e); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return total; |
|
|
|
return total; |
|
|
@ -222,7 +230,7 @@ public class ChanParser { |
|
|
|
case "span": { |
|
|
|
case "span": { |
|
|
|
Element span = (Element) node; |
|
|
|
Element span = (Element) node; |
|
|
|
|
|
|
|
|
|
|
|
SpannableString quote = null; |
|
|
|
SpannableString quote; |
|
|
|
|
|
|
|
|
|
|
|
Set<String> classes = span.classNames(); |
|
|
|
Set<String> classes = span.classNames(); |
|
|
|
if (classes.contains("deadlink")) { |
|
|
|
if (classes.contains("deadlink")) { |
|
|
@ -247,7 +255,7 @@ public class ChanParser { |
|
|
|
if (!TextUtils.isEmpty(group)) { |
|
|
|
if (!TextUtils.isEmpty(group)) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
hexColor = Integer.parseInt(group, 16); |
|
|
|
hexColor = Integer.parseInt(group, 16); |
|
|
|
} catch (NumberFormatException e) { |
|
|
|
} catch (NumberFormatException ignored) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -257,6 +265,8 @@ public class ChanParser { |
|
|
|
quote.setSpan(new StyleSpan(Typeface.BOLD), 0, quote.length(), 0); |
|
|
|
quote.setSpan(new StyleSpan(Typeface.BOLD), 0, quote.length(), 0); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else if (classes.contains("abbr")) { |
|
|
|
|
|
|
|
return null; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
quote = new SpannableString(span.text()); |
|
|
|
quote = new SpannableString(span.text()); |
|
|
|
quote.setSpan(new ForegroundColorSpan(ThemeHelper.getInstance().getInlineQuoteColor()), 0, quote.length(), 0); |
|
|
|
quote.setSpan(new ForegroundColorSpan(ThemeHelper.getInstance().getInlineQuoteColor()), 0, quote.length(), 0); |
|
|
@ -265,6 +275,43 @@ public class ChanParser { |
|
|
|
|
|
|
|
|
|
|
|
return quote; |
|
|
|
return quote; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
case "table": { |
|
|
|
|
|
|
|
Element table = (Element) node; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<CharSequence> parts = new ArrayList<>(); |
|
|
|
|
|
|
|
Elements tableRows = table.getElementsByTag("tr"); |
|
|
|
|
|
|
|
for (int i = 0; i < tableRows.size(); i++) { |
|
|
|
|
|
|
|
Element tableRow = tableRows.get(i); |
|
|
|
|
|
|
|
if (tableRow.text().length() > 0) { |
|
|
|
|
|
|
|
Elements tableDatas = tableRow.getElementsByTag("td"); |
|
|
|
|
|
|
|
for (int j = 0; j < tableDatas.size(); j++) { |
|
|
|
|
|
|
|
Element tableData = tableDatas.get(j); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SpannableString tableDataPart = new SpannableString(tableData.text()); |
|
|
|
|
|
|
|
if (tableData.getElementsByTag("b").size() > 0) { |
|
|
|
|
|
|
|
tableDataPart.setSpan(new StyleSpan(Typeface.BOLD), 0, tableDataPart.length(), 0); |
|
|
|
|
|
|
|
tableDataPart.setSpan(new UnderlineSpan(), 0, tableDataPart.length(), 0); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
parts.add(tableDataPart); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (j < tableDatas.size() - 1) { |
|
|
|
|
|
|
|
parts.add(": "); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i < tableRows.size() - 1) { |
|
|
|
|
|
|
|
parts.add("\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SpannableString tableTotal = new SpannableString(TextUtils.concat(parts.toArray(new CharSequence[parts.size()]))); |
|
|
|
|
|
|
|
tableTotal.setSpan(new ForegroundColorSpan(ThemeHelper.getInstance().getInlineQuoteColor()), 0, tableTotal.length(), 0); |
|
|
|
|
|
|
|
tableTotal.setSpan(new AbsoluteSizeSpan(sp(12f)), 0, tableTotal.length(), 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return tableTotal; |
|
|
|
|
|
|
|
} |
|
|
|
case "strong": { |
|
|
|
case "strong": { |
|
|
|
Element strong = (Element) node; |
|
|
|
Element strong = (Element) node; |
|
|
|
|
|
|
|
|
|
|
@ -341,7 +388,7 @@ public class ChanParser { |
|
|
|
int tId = Integer.parseInt(numsSplitted[0]); |
|
|
|
int tId = Integer.parseInt(numsSplitted[0]); |
|
|
|
int pId = Integer.parseInt(numsSplitted[1]); |
|
|
|
int pId = Integer.parseInt(numsSplitted[1]); |
|
|
|
threadLink = new PostLinkable.ThreadLink(board, tId, pId); |
|
|
|
threadLink = new PostLinkable.ThreadLink(board, tId, pId); |
|
|
|
} catch (NumberFormatException e) { |
|
|
|
} catch (NumberFormatException ignored) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -359,7 +406,7 @@ public class ChanParser { |
|
|
|
if (splitted.length == 2) { |
|
|
|
if (splitted.length == 2) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
id = Integer.parseInt(splitted[1]); |
|
|
|
id = Integer.parseInt(splitted[1]); |
|
|
|
} catch (NumberFormatException e) { |
|
|
|
} catch (NumberFormatException ignored) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|