All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dotty.tools.dottydoc.model.comment.MarkdownShortener.scala Maven / Gradle / Ivy

There is a newer version: 3.0.0-M1-bin-20201029-1f433d5-NIGHTLY
Show newest version
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.util.ast._
  import com.vladsch.flexmark.ast._

  def shorten(node: Node, maxLen: Int = 150): Node = {
    var len = 0
    var didUnlink = false

    def count(node: Node, length: => Int, shortenOrUnlink: Int => Unit) = {
      val remaining = math.max(maxLen - len, 0)
      if (didUnlink || 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())
      }),
      new VisitHandler(classOf[FencedCodeBlock], new Visitor[FencedCodeBlock] {
        override def visit(node: FencedCodeBlock) = count(node, maxLen, _ => node.unlink())
      }),
      new VisitHandler(classOf[BulletListItem], new Visitor[BulletListItem] {
        override def visit(node: BulletListItem) = count(
          node,
          if (didUnlink) maxLen
          else node.getSegments.map(_.length).reduceLeft(_ + _),
          _ => {
            node.unlink()
            didUnlink = true // unlink all following bullets
          }
        )
      }),
      new VisitHandler(classOf[OrderedListItem], new Visitor[OrderedListItem] {
        override def visit(node: OrderedListItem) = count(
          node,
          if (didUnlink) maxLen
          else node.getSegments.map(_.length).reduceLeft(_ + _),
          _ => {
            node.unlink()
            didUnlink = true // unlink all following bullets
          }
        )
      })
    )

    nodeVisitor.visit(node)
    node
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy