Switch to commonmark 0.5.0
Reasons to switch:
* Supports the CommonMark[1] "standard"
* Fewer dependencies
* BSD 2-clause license
* Fast (claims 10-20 times faster than pegdown)
* Cleaner extension API than Pegdown
* No timeout limit required
Testing with Documentation/markdown.md:
| cold vm | hot vm |
+---------+--------|
prior | 2.29s | 279ms |
this | 1.64s | 139ms |
Testing with Chromium's botmap.md:
| cold vm | hot vm |
+---------+--------|
prior | 3.47s | 946ms |
this | 1.83s | 257ms |
Changes in Markdown from Pegdown:
* No <<double angle>> quotes (confused with HTML).
* No table captions (no [caption after table]).
* Table columns are same width (no multi-column spans).
* Smart quotes can no longer be disabled by \'.
* Horizontal rule should be at least 3 -, e.g. ---.
(However GitHub Flavor -- is still accepted.)
[1] http://commonmark.org
Change-Id: Ief189d0226901a284d9b86d9798310786ae1e983
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownUtil.java b/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownUtil.java
index 5130216..6392cd0 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownUtil.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownUtil.java
@@ -14,21 +14,17 @@
package com.google.gitiles.doc;
+import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
-import org.pegdown.ast.HeaderNode;
-import org.pegdown.ast.Node;
-import org.pegdown.ast.TextNode;
+import org.commonmark.node.Heading;
+import org.commonmark.node.Node;
+import org.commonmark.node.Text;
class MarkdownUtil {
- /** Check if anchor URL is like {@code /top.md}. */
- static boolean isAbsolutePathToMarkdown(String url) {
- return url.length() >= 5 && url.charAt(0) == '/' && url.charAt(1) != '/' && url.endsWith(".md");
- }
-
/** Combine child nodes as string; this must be escaped for HTML. */
static String getInnerText(Node node) {
- if (node == null || node.getChildren().isEmpty()) {
+ if (node == null || node.getFirstChild() == null) {
return null;
}
@@ -38,25 +34,25 @@
}
private static void appendTextFromChildren(StringBuilder b, Node node) {
- for (Node child : node.getChildren()) {
- if (child instanceof TextNode) {
- b.append(((TextNode) child).getText());
+ for (Node c = node.getFirstChild(); c != null; c = c.getNext()) {
+ if (c instanceof Text) {
+ b.append(((Text) c).getLiteral());
} else {
- appendTextFromChildren(b, child);
+ appendTextFromChildren(b, c);
}
}
}
static String getTitle(Node node) {
- if (node instanceof HeaderNode) {
- if (((HeaderNode) node).getLevel() == 1) {
+ if (node instanceof Heading) {
+ if (((Heading) node).getLevel() == 1) {
return getInnerText(node);
}
return null;
}
- for (Node child : node.getChildren()) {
- String title = getTitle(child);
+ for (Node c = node.getFirstChild(); c != null; c = c.getNext()) {
+ String title = getTitle(c);
if (title != null) {
return title;
}
@@ -64,5 +60,14 @@
return null;
}
+ static void trimPreviousWhitespace(Node node) {
+ Node prev = node.getPrevious();
+ if (prev instanceof Text) {
+ Text prevText = (Text) prev;
+ String s = prevText.getLiteral();
+ prevText.setLiteral(CharMatcher.whitespace().trimTrailingFrom(s));
+ }
+ }
+
private MarkdownUtil() {}
}