aboutsummaryrefslogtreecommitdiff
path: root/doc-tool/src/dotty/tools/dottydoc/model/comment/MarkdownShortener.scala
diff options
context:
space:
mode:
Diffstat (limited to 'doc-tool/src/dotty/tools/dottydoc/model/comment/MarkdownShortener.scala')
-rw-r--r--doc-tool/src/dotty/tools/dottydoc/model/comment/MarkdownShortener.scala57
1 files changed, 57 insertions, 0 deletions
diff --git a/doc-tool/src/dotty/tools/dottydoc/model/comment/MarkdownShortener.scala b/doc-tool/src/dotty/tools/dottydoc/model/comment/MarkdownShortener.scala
new file mode 100644
index 000000000..841232e52
--- /dev/null
+++ b/doc-tool/src/dotty/tools/dottydoc/model/comment/MarkdownShortener.scala
@@ -0,0 +1,57 @@
+package dotty.tools
+package dottydoc
+package model
+package comment
+
+/** The `MarkdownShortener` takes a node and *mutates* it and all children so
+ * that the displayed length of the generated HTML doesn't exceeed `maxLen`.
+ * This number defaults to 150 characters.
+ *
+ * @note calling `shorten` **will** mutate the Markdown AST node.
+ */
+class MarkdownShortener {
+ import com.vladsch.flexmark.ast._
+
+ def shorten(node: Node, maxLen: Int = 150): Node = {
+ var len = 0
+
+ def count(node: Node, length: => Int, shortenOrUnlink: Int => Unit) = {
+ val remaining = math.max(maxLen - len, 0)
+ if (remaining == 0) node.unlink()
+ else {
+ if (length <= remaining) len += length
+ else {
+ shortenOrUnlink(remaining)
+ len = maxLen
+ }
+ }
+ }
+
+ val nodeVisitor = new NodeVisitor(
+ new VisitHandler(classOf[Text], new Visitor[Text] {
+ override def visit(node: Text) = count(
+ node,
+ node.getChars.length,
+ remaining => node.setChars(
+ node.getChars.subSequence(0, remaining).trimEnd.append("...")
+ )
+ )
+ }),
+ new VisitHandler(classOf[Code], new Visitor[Code] {
+ override def visit(node: Code) = count(
+ node,
+ node.getText.length,
+ remaining => node.setText(
+ node.getText.subSequence(0, remaining).trimEnd.append("...")
+ )
+ )
+ }),
+ new VisitHandler(classOf[Image], new Visitor[Image] {
+ override def visit(node: Image) = count(node, maxLen, _ => node.unlink())
+ })
+ )
+
+ nodeVisitor.visit(node)
+ node
+ }
+}