aboutsummaryrefslogtreecommitdiff
path: root/doc-tool/src
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2017-01-04 17:52:48 +0100
committerFelix Mulder <felix.mulder@gmail.com>2017-01-31 14:29:17 +0100
commit08dce0704570ae8346fc28019ef5264f1e12ce25 (patch)
treef4681aa5e6736f7eb8e2a8f6575771d9b8472b9d /doc-tool/src
parent877e934697cf9468add92cfca40eb9943e2ea164 (diff)
downloaddotty-08dce0704570ae8346fc28019ef5264f1e12ce25.tar.gz
dotty-08dce0704570ae8346fc28019ef5264f1e12ce25.tar.bz2
dotty-08dce0704570ae8346fc28019ef5264f1e12ce25.zip
Add ability to completely parse docstring with md or wiki
Diffstat (limited to 'doc-tool/src')
-rw-r--r--doc-tool/src/dotty/tools/dottydoc/core/DocstringPhase.scala5
-rw-r--r--doc-tool/src/dotty/tools/dottydoc/model/comment/Comment.scala125
-rw-r--r--doc-tool/src/dotty/tools/dottydoc/model/comment/HtmlParsers.scala19
3 files changed, 142 insertions, 7 deletions
diff --git a/doc-tool/src/dotty/tools/dottydoc/core/DocstringPhase.scala b/doc-tool/src/dotty/tools/dottydoc/core/DocstringPhase.scala
index be6e3b0e8..d5b59426d 100644
--- a/doc-tool/src/dotty/tools/dottydoc/core/DocstringPhase.scala
+++ b/doc-tool/src/dotty/tools/dottydoc/core/DocstringPhase.scala
@@ -13,8 +13,9 @@ import util.syntax._
class DocstringPhase extends DocMiniPhase with CommentParser with CommentCleaner {
private def parsedComment[E <: Entity](ent: E)(implicit ctx: Context): Option[Comment] =
ctx.docbase.docstring(ent.symbol).map { cmt =>
- parse(ent, ctx.docbase.packages, clean(cmt.raw), cmt.raw, cmt.pos)
- .toComment(_.fromBody(ent), _.fromMarkdown(ent))
+ val parsed = parse(ent, ctx.docbase.packages, clean(cmt.raw), cmt.raw, cmt.pos)
+ if (ctx.settings.wikiSyntax.value) WikiComment(parsed, ent, cmt.pos)
+ else MarkdownComment(parsed, ent)
}
override def transformPackage(implicit ctx: Context) = { case ent: PackageImpl =>
diff --git a/doc-tool/src/dotty/tools/dottydoc/model/comment/Comment.scala b/doc-tool/src/dotty/tools/dottydoc/model/comment/Comment.scala
index 2c48a4050..8d927cb28 100644
--- a/doc-tool/src/dotty/tools/dottydoc/model/comment/Comment.scala
+++ b/doc-tool/src/dotty/tools/dottydoc/model/comment/Comment.scala
@@ -3,6 +3,11 @@ package dottydoc
package model
package comment
+import dotty.tools.dottydoc.util.syntax._
+import dotty.tools.dotc.core.Contexts.Context
+import dotty.tools.dotc.util.Positions.Position
+import dotty.tools.dotc.config.Printers.dottydoc
+
case class Comment (
body: String,
short: String,
@@ -49,3 +54,123 @@ private[comment] case class ParsedComment (
hideImplicitConversions: List[String],
shortDescription: List[String]
)
+
+object MarkdownComment extends util.MemberLookup {
+ import HtmlParsers._
+
+ def apply(parsed: ParsedComment, ent: Entity)(implicit ctx: Context): Comment = {
+ val inlineToHtml = InlineToHtml(ent)
+ def linkedExceptions(m: Map[String, String]): Map[String, String] = {
+ m.map { case (targetStr, body) =>
+ val link = lookup(ent, ctx.docbase.packages, targetStr)
+ val entityLink = EntityLink(Monospace(Text(targetStr)), link)
+ (targetStr, inlineToHtml(entityLink))
+ }
+ }
+
+ val parsedBody = parsed.body.fromMarkdown(ent)
+ Comment(
+ body = parsedBody,
+ short = parsedBody,
+ authors = filterEmpty(parsed.authors).map(_.fromMarkdown(ent)),
+ see = filterEmpty(parsed.see).map(_.fromMarkdown(ent)),
+ result = single("@result", parsed.result).map(_.fromMarkdown(ent)),
+ throws = linkedExceptions(parsed.throws).mapValues(_.fromMarkdown(ent)),
+ valueParams = filterEmpty(parsed.valueParams).mapValues(_.fromMarkdown(ent)),
+ typeParams = filterEmpty(parsed.typeParams).mapValues(_.fromMarkdown(ent)),
+ version = single("@version", parsed.version).map(_.fromMarkdown(ent)),
+ since = single("@since", parsed.since).map(_.fromMarkdown(ent)),
+ todo = filterEmpty(parsed.todo).map(_.fromMarkdown(ent)),
+ deprecated = single("@deprecated", parsed.deprecated, filter = false).map(_.fromMarkdown(ent)),
+ note = filterEmpty(parsed.note).map(_.fromMarkdown(ent)),
+ example = filterEmpty(parsed.example).map(_.fromMarkdown(ent)),
+ constructor = single("@constructor", parsed.constructor).map(_.fromMarkdown(ent)),
+ group = single("@group", parsed.group).map(_.fromMarkdown(ent)),
+ groupDesc = filterEmpty(parsed.groupDesc).mapValues(_.fromMarkdown(ent)),
+ groupNames = filterEmpty(parsed.groupNames).mapValues(_.fromMarkdown(ent)),
+ groupPrio = filterEmpty(parsed.groupPrio).mapValues(_.fromMarkdown(ent)),
+ hideImplicitConversions = filterEmpty(parsed.hideImplicitConversions).map(_.fromMarkdown(ent))
+ )
+ }
+
+ private def filterEmpty(xs: List[String]) =
+ xs.map(_.trim).filterNot(_.isEmpty)
+
+ private def filterEmpty(xs: Map[String, String]) =
+ xs.mapValues(_.trim).filterNot { case (_, v) => v.isEmpty }
+
+ private def single(annot: String, xs: List[String], filter: Boolean = true): Option[String] =
+ (if (filter) filterEmpty(xs) else xs) match {
+ case x :: xs =>
+ if (xs.nonEmpty) dottydoc.println(s"Only allowed to have a single annotation for $annot")
+ Some(x)
+ case _ => None
+ }
+}
+
+object WikiComment extends util.MemberLookup {
+ import HtmlParsers._
+
+ def apply(parsed: ParsedComment, ent: Entity, pos: Position)(implicit ctx: Context): Comment = {
+ val inlineToHtml = InlineToHtml(ent)
+ val packages = ctx.docbase.packages
+ val parsedBody = parsed.body.toWiki(ent, packages, pos).wikiToString(ent)
+
+ def linkedExceptions(m: Map[String, Body]): Map[String, Body] = {
+ m.map { case (targetStr, body) =>
+ val link = lookup(ent, ctx.docbase.packages, targetStr)
+ val newBody = body match {
+ case Body(List(Paragraph(Chain(content)))) =>
+ val descr = Text(" ") +: content
+ val entityLink = EntityLink(Monospace(Text(targetStr)), link)
+ Body(List(Paragraph(Chain(entityLink +: descr))))
+ case _ => body
+ }
+ (targetStr, newBody)
+ }
+ }
+
+ def toWiki(str: String): Body = str.toWiki(ent, packages, pos)
+ def toString(body: Body): String = body.wikiToString(ent)
+
+ def filterEmpty(xs: List[String]): List[Body] =
+ xs.map(toWiki).filterNot(_.blocks.isEmpty)
+
+ def filterEmptyMap(xs: Map[String, String]): Map[String, Body] =
+ xs.mapValues(toWiki).filterNot { case (_, v) => v.blocks.isEmpty }
+
+ def single(annot: String, xs: List[String], filter: Boolean = false): Option[String] = {
+ val head = (if (filter) filterEmpty(xs) else xs.map(toWiki)) match {
+ case x :: xs =>
+ if (xs.nonEmpty) dottydoc.println(s"Only allowed to have a single annotation for $annot")
+ Some(x)
+ case _ => None
+ }
+
+ head.map(toString)
+ }
+
+ Comment(
+ body = parsedBody,
+ short = parsedBody,
+ authors = filterEmpty(parsed.authors).map(toString),
+ see = filterEmpty(parsed.see).map(toString),
+ result = single("@result", parsed.result),
+ throws = linkedExceptions(parsed.throws.mapValues(toWiki)).mapValues(toString),
+ valueParams = filterEmptyMap(parsed.valueParams).mapValues(toString),
+ typeParams = filterEmptyMap(parsed.typeParams).mapValues(toString),
+ version = single("@version", parsed.version),
+ since = single("@since", parsed.since),
+ todo = filterEmpty(parsed.todo).map(toString),
+ deprecated = single("@deprecated", parsed.deprecated, filter = false),
+ note = filterEmpty(parsed.note).map(toString),
+ example = filterEmpty(parsed.example).map(toString),
+ constructor = single("@constructor", parsed.constructor),
+ group = single("@group", parsed.group),
+ groupDesc = filterEmptyMap(parsed.groupDesc).mapValues(toString),
+ groupNames = filterEmptyMap(parsed.groupNames).mapValues(toString),
+ groupPrio = filterEmptyMap(parsed.groupPrio).mapValues(toString),
+ hideImplicitConversions = filterEmpty(parsed.hideImplicitConversions).map(toString)
+ )
+ }
+}
diff --git a/doc-tool/src/dotty/tools/dottydoc/model/comment/HtmlParsers.scala b/doc-tool/src/dotty/tools/dottydoc/model/comment/HtmlParsers.scala
index 27a2c2587..24572925c 100644
--- a/doc-tool/src/dotty/tools/dottydoc/model/comment/HtmlParsers.scala
+++ b/doc-tool/src/dotty/tools/dottydoc/model/comment/HtmlParsers.scala
@@ -4,23 +4,27 @@ package model
package comment
import dotc.core.Contexts.Context
-import com.vladsch.flexmark.ast.{ Node => MarkdownNode }
+import dotc.util.Positions._
import dotty.tools.dottydoc.util.syntax._
import util.MemberLookup
object HtmlParsers {
- implicit class MarkdownToHtml(val node: MarkdownNode) extends AnyVal {
+ implicit class MarkdownToHtml(val text: String) extends AnyVal {
def fromMarkdown(origin: Entity)(implicit ctx: Context): String = {
import com.vladsch.flexmark.util.sequence.CharSubSequence
import com.vladsch.flexmark.ast.{ Link, Visitor, VisitHandler, NodeVisitor }
import com.vladsch.flexmark.parser.Parser
import com.vladsch.flexmark.html.HtmlRenderer
- implicit def toCharSeq(str: String) = CharSubSequence.of(str)
-
val inlineToHtml = InlineToHtml(origin)
+ // TODO: split out into different step so that we can get a short summary
+ val node = Parser.builder(ctx.docbase.markdownOptions)
+ .build.parse(text)
+
+ implicit def toCharSeq(str: String) = CharSubSequence.of(str)
+
def isOuter(url: String) =
url.startsWith("http://") ||
url.startsWith("https://") ||
@@ -55,8 +59,13 @@ object HtmlParsers {
}
}
+ implicit class StringToWiki(val text: String) extends AnyVal {
+ def toWiki(origin: Entity, packages: Map[String, Package], pos: Position): Body =
+ new WikiParser(origin, packages, text, pos, origin.symbol).document()
+ }
+
implicit class BodyToHtml(val body: Body) extends AnyVal {
- def fromBody(origin: Entity): String = {
+ def wikiToString(origin: Entity): String = {
val inlineToHtml = InlineToHtml(origin)
def bodyToHtml(body: Body): String =