diff options
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.scala | 57 |
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 + } +} |