Revised newlines (draft)

pull/187/head
M66B 5 years ago
parent 9dc71d2a46
commit dcc53885d4

@ -77,7 +77,6 @@ import com.steadystate.css.parser.selectors.ClassConditionImpl;
import com.steadystate.css.parser.selectors.ConditionalSelectorImpl; import com.steadystate.css.parser.selectors.ConditionalSelectorImpl;
import com.steadystate.css.parser.selectors.ElementSelectorImpl; import com.steadystate.css.parser.selectors.ElementSelectorImpl;
import org.jsoup.internal.StringUtil;
import org.jsoup.nodes.Attribute; import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Comment; import org.jsoup.nodes.Comment;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
@ -442,7 +441,6 @@ public class HtmlHelper {
// Limit length // Limit length
if (view && truncate(parsed, true)) { if (view && truncate(parsed, true)) {
parsed.body() parsed.body()
.appendElement("br")
.appendElement("p") .appendElement("p")
.appendElement("em") .appendElement("em")
.text(context.getString(R.string.title_too_large)); .text(context.getString(R.string.title_too_large));
@ -741,34 +739,18 @@ public class HtmlHelper {
} }
} }
if (element.isBlock()) if (element.isBlock() &&
!"true".equals(element.attr("x-inline")))
element.attr("x-block", "true"); element.attr("x-block", "true");
} }
// Remove trailing br from div
for (Element div : document.select("div")) {
boolean inline = Boolean.parseBoolean(div.attr("x-inline"));
if (!inline && hasVisibleContent(div, true)) {
Element last = div.lastElementSibling();
if (last != null && "br".equals(last.tagName()))
last.remove();
}
}
// Replace headings // Replace headings
for (Element h : document.select("h1,h2,h3,h4,h5,h6")) { if (!text_size)
if (!"false".equals(h.attr("x-line-after"))) document.select("h1,h2,h3,h4,h5,h6").tagName("strong");
h.appendElement("br");
if (!text_size) {
h.appendElement("br");
h.tagName("strong");
}
}
// Paragraphs // Paragraphs
for (Element p : document.select("p")) { for (Element p : document.select("p")) {
if (!"false".equals(p.attr("x-line-after"))) p.attr("x-paragraph", "true");
p.appendElement("br");
p.tagName("div"); p.tagName("div");
} }
@ -816,13 +798,11 @@ public class HtmlHelper {
// Descriptions // Descriptions
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl
document.select("dl").tagName("div"); document.select("dl").tagName("div");
for (Element dt : document.select("dt")) { for (Element dt : document.select("dt"))
dt.tagName("strong"); dt.tagName("strong");
dt.appendElement("br");
}
for (Element dd : document.select("dd")) { for (Element dd : document.select("dd")) {
dd.tagName("em"); dd.tagName("em");
dd.appendElement("br").appendElement("br"); dd.attr("x-line-after", "true");
} }
// Abbreviations // Abbreviations
@ -839,10 +819,7 @@ public class HtmlHelper {
// Tables // Tables
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table
for (Element col : document.select("th,td")) { for (Element col : document.select("th,td")) {
// separate columns col.attr("x-col", "true");
if (hasVisibleContent(col, false))
if (col.nextElementSibling() != null)
col.append(" ");
if ("th".equals(col.tagName())) if ("th".equals(col.tagName()))
col.tagName("strong"); col.tagName("strong");
@ -850,18 +827,8 @@ public class HtmlHelper {
col.tagName("span"); col.tagName("span");
} }
for (Element row : document.select("tr")) { for (Element row : document.select("tr"))
row.tagName("span"); row.tagName("span").attr("x-row", "true");
if (hasVisibleContent(row, true)) {
Element next = row.nextElementSibling();
if (next != null && "tr".equals(next.tagName()))
if (text_separators && view)
row.appendElement("hr")
.attr("x-dashed", "true");
else
row.appendElement("br");
}
}
document.select("caption").tagName("div"); document.select("caption").tagName("div");
@ -1014,29 +981,8 @@ public class HtmlHelper {
} }
// Selective new lines // Selective new lines
for (Element div : document.select("div")) { for (Element div : document.select("div"))
boolean inline = Boolean.parseBoolean(div.attr("x-inline"));
if (!inline && hasVisibleContent(div, true))
div.attr("x-line-after", "true");
div.tagName("span"); div.tagName("span");
}
for (Element e : document.select("*[x-line-before],*[x-line-after]")) {
if ("true".equals(e.attr("x-line-before"))) {
Element prev = e.previousElementSibling();
if (prev == null || !"br".equals(prev.tagName()))
e.prependElement("br");
}
if ("true".equals(e.attr("x-line-after"))) {
Element next = e.nextElementSibling();
if (next == null || !"br".equals(next.tagName()))
e.appendElement("br");
}
e.removeAttr("x-line-before");
e.removeAttr("x-line-after");
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
for (Element span : document.select("span")) for (Element span : document.select("span"))
@ -1369,30 +1315,6 @@ public class HtmlHelper {
return (color & 0xFFFFFF); return (color & 0xFFFFFF);
} }
private static boolean hasVisibleContent(Element root, boolean block) {
for (Node node : root.childNodes())
if (node instanceof TextNode) {
String text = ((TextNode) node).getWholeText();
for (int i = 0; i < text.length(); i++) {
char kar = text.charAt(i);
if (!StringUtil.isWhitespace(kar) && kar != '\u00a0' /* nbsp */)
return true;
}
} else if (node instanceof Element) {
Element element = (Element) node;
if (element.hasText())
return true;
if (block && "true".equals(element.attr("x-block")))
return false;
if (element.selectFirst("img[src~=.+]") != null)
return true;
for (Element a : element.select("a[href~=.+]"))
if (a.childNodes().size() > 0)
return true;
}
return false;
}
// https://tools.ietf.org/html/rfc3676 // https://tools.ietf.org/html/rfc3676
static String flow(String text) { static String flow(String text) {
boolean continuation = false; boolean continuation = false;
@ -2061,12 +1983,39 @@ public class HtmlHelper {
NodeTraversor.traverse(new NodeVisitor() { NodeTraversor.traverse(new NodeVisitor() {
private Element element; private Element element;
private TextNode tnode; private TextNode tnode;
private int rows = 0;
private int cols = 0;
@Override @Override
public void head(Node node, int depth) { public void head(Node node, int depth) {
if (node instanceof Element) { if (node instanceof Element) {
element = (Element) node; element = (Element) node;
if (rows == 0) {
if ("true".equals(element.attr("x-block")))
if (ssb.length() > 1 && ssb.charAt(ssb.length() - 1) != '\n')
ssb.append('\n');
if ("true".equals(element.attr("x-paragraph")))
if (ssb.length() > 2 &&
(ssb.charAt(ssb.length() - 2) != '\n' ||
ssb.charAt(ssb.length() - 1) != '\n'))
ssb.append('\n');
}
if ("true".equals(element.attr("x-row"))) {
rows++;
if (ssb.length() > 1 && ssb.charAt(ssb.length() - 1) != '\n')
ssb.append('\n');
}
if ("true".equals(element.attr("x-col")))
cols++;
if ("true".equals(element.attr("x-line-before")) &&
ssb.length() > 0 && ssb.charAt(ssb.length() - 1) == '\n')
ssb.append('\n');
element.attr("start-index", Integer.toString(ssb.length())); element.attr("start-index", Integer.toString(ssb.length()));
if (debug) if (debug)
ssb.append("[" + element.tagName() + ":" + element.attr("style") + "]"); ssb.append("[" + element.tagName() + ":" + element.attr("style") + "]");
} else if (node instanceof TextNode) { } else if (node instanceof TextNode) {
@ -2085,8 +2034,6 @@ public class HtmlHelper {
if (node instanceof Element) { if (node instanceof Element) {
element = (Element) node; element = (Element) node;
int start = Integer.parseInt(element.attr("start-index")); int start = Integer.parseInt(element.attr("start-index"));
if (debug)
ssb.append("[/" + element.tagName() + "]");
// Apply style // Apply style
String style = element.attr("style"); String style = element.attr("style");
@ -2131,19 +2078,8 @@ public class HtmlHelper {
setSpan(ssb, new StrikethroughSpan(), start, ssb.length()); setSpan(ssb, new StrikethroughSpan(), start, ssb.length());
break; break;
case "text-align": case "text-align":
boolean table = false;
Element e = element;
while (e != null) {
if ("table".equals(e.tagName()) ||
"true".equals(e.attr("x-table"))) {
table = true;
break;
}
e = e.parent();
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/text-align // https://developer.mozilla.org/en-US/docs/Web/CSS/text-align
if (!table) { if (rows == 0) {
Layout.Alignment alignment = null; Layout.Alignment alignment = null;
switch (value) { switch (value) {
case "left": case "left":
@ -2207,12 +2143,10 @@ public class HtmlHelper {
setSpan(ssb, new QuoteSpan(colorPrimary, dp3, dp6), start, ssb.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); setSpan(ssb, new QuoteSpan(colorPrimary, dp3, dp6), start, ssb.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
break; break;
case "br": case "br":
newline(ssb.length()); ssb.append('\n');
break; break;
case "div": // compose case "div": // compose
case "p": // compose case "p": // compose
newline(ssb.length());
newline(ssb.length());
break; break;
case "i": case "i":
case "em": case "em":
@ -2232,8 +2166,6 @@ public class HtmlHelper {
int level = element.tagName().charAt(1) - '1'; int level = element.tagName().charAt(1) - '1';
setSpan(ssb, new RelativeSizeSpan(HEADING_SIZES[level]), start, ssb.length()); setSpan(ssb, new RelativeSizeSpan(HEADING_SIZES[level]), start, ssb.length());
setSpan(ssb, new StyleSpan(Typeface.BOLD), start, ssb.length()); setSpan(ssb, new StyleSpan(Typeface.BOLD), start, ssb.length());
newline(start);
newline(ssb.length());
break; break;
case "hr": case "hr":
if (text_separators) { if (text_separators) {
@ -2365,6 +2297,37 @@ public class HtmlHelper {
} catch (Throwable ex) { } catch (Throwable ex) {
Log.e(ex); Log.e(ex);
} }
if (rows == 0) {
if ("true".equals(element.attr("x-block")))
if (ssb.length() > 1 && ssb.charAt(ssb.length() - 1) != '\n')
ssb.append('\n');
if ("true".equals(element.attr("x-paragraph")))
if (ssb.length() > 2 &&
(ssb.charAt(ssb.length() - 2) != '\n' ||
ssb.charAt(ssb.length() - 1) != '\n'))
ssb.append('\n');
}
if ("true".equals(element.attr("x-col"))) {
cols--;
if (ssb.length() > 0 &&
ssb.charAt(ssb.length() - 1) != '\n' &&
ssb.charAt(ssb.length() - 1) != '\u2003')
ssb.append('\u2003'); // emsp
}
if ("true".equals(element.attr("x-row"))) {
rows--;
if (ssb.length() > 1 && ssb.charAt(ssb.length() - 1) != '\n')
ssb.append('\n');
}
if ("true".equals(element.attr("x-line-after")) &&
ssb.length() > 0 && ssb.charAt(ssb.length() - 1) == '\n')
ssb.append('\n');
if (debug)
ssb.append("[/" + element.tagName() + "]");
} }
} }
@ -2381,25 +2344,6 @@ public class HtmlHelper {
else else
Log.e("Invalid span " + start + "..." + end + " len=" + len + " type=" + span.getClass().getName()); Log.e("Invalid span " + start + "..." + end + " len=" + len + " type=" + span.getClass().getName());
} }
private void newline(int index) {
int count = 0;
if (compress) {
int i = Math.min(index, ssb.length() - 1);
while (i >= 0) {
char kar = ssb.charAt(i);
if (kar == '\n')
count++;
else if (kar != ' ' && kar != '\u00A0')
break;
i--;
}
}
if (count < 2)
ssb.insert(index, "\n");
}
}, document.body()); }, document.body());
if (debug) if (debug)

Loading…
Cancel
Save