Markdown: break ties in table of contents
C++ and C# both hashed to the same "C_" token in the table of
contents. Break these kinds of ties by giving "C_" to the first
and "C_-$hash(C++)" to the second.
Change-Id: Ib568d2ab92a3a78b846ff6ad41ba4d754b8d48cc
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/TocFormatter.java b/gitiles-servlet/src/main/java/com/google/gitiles/doc/TocFormatter.java
index 9acf08b..5d428c7 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/doc/TocFormatter.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/doc/TocFormatter.java
@@ -14,6 +14,9 @@
package com.google.gitiles.doc;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import com.google.common.hash.Hashing;
import com.google.gitiles.doc.html.HtmlBuilder;
import org.apache.commons.lang3.StringUtils;
@@ -21,6 +24,8 @@
import org.pegdown.ast.Node;
import org.pegdown.ast.RootNode;
+import java.nio.charset.StandardCharsets;
+
/** Outputs outline from HeaderNodes in the AST. */
class TocFormatter {
private final HtmlBuilder html;
@@ -29,6 +34,7 @@
private RootNode root;
private Boolean hasToc;
private int countH1;
+ private BiMap<HeaderNode, String> ids;
private int level;
@@ -40,6 +46,7 @@
void setRoot(RootNode doc) {
root = doc;
hasToc = null;
+ ids = HashBiMap.create();
}
boolean include(HeaderNode h) {
@@ -53,8 +60,22 @@
}
String idFromHeader(HeaderNode header) {
- String t = MarkdownUtil.getInnerText(header);
- return t != null ? idFromTitle(t) : null;
+ String id = ids.get(header);
+ if (id == null) {
+ String title = MarkdownUtil.getInnerText(header);
+ if (title == null) {
+ return null;
+ }
+
+ id = idFromTitle(title);
+ if (ids.values().contains(id)) {
+ id = String.format("%s-%x",
+ id,
+ Hashing.md5().hashString(id, StandardCharsets.UTF_8).asInt());
+ }
+ ids.put(header, id);
+ }
+ return id;
}
void format() {
@@ -93,8 +114,8 @@
return;
}
- String title = MarkdownUtil.getInnerText(h);
- if (title == null) {
+ String id = idFromHeader(h);
+ if (id == null) {
return;
}
@@ -108,8 +129,8 @@
}
html.open("li")
- .open("a").attribute("href", "#" + idFromTitle(title))
- .appendAndEscape(title)
+ .open("a").attribute("href", "#" + id)
+ .appendAndEscape(MarkdownUtil.getInnerText(h))
.close("a")
.close("li");
}