diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2017-01-10 17:53:05 +0100 |
---|---|---|
committer | Felix Mulder <felix.mulder@gmail.com> | 2017-01-31 14:31:05 +0100 |
commit | 48db40565b84ac4a3181bdc95533d28180edb10b (patch) | |
tree | 2b1454ae3bd6df01e4ac827cf57ee51d40d5327b /doc-tool/src | |
parent | 7b3588fbff791679fc82c4fe21085eb97a97cf0a (diff) | |
download | dotty-48db40565b84ac4a3181bdc95533d28180edb10b.tar.gz dotty-48db40565b84ac4a3181bdc95533d28180edb10b.tar.bz2 dotty-48db40565b84ac4a3181bdc95533d28180edb10b.zip |
Add initial defaults to page generation
Diffstat (limited to 'doc-tool/src')
6 files changed, 142 insertions, 59 deletions
diff --git a/doc-tool/src/dotty/tools/dottydoc/DocDriver.scala b/doc-tool/src/dotty/tools/dottydoc/DocDriver.scala index 18480c94f..8ca4522c0 100644 --- a/doc-tool/src/dotty/tools/dottydoc/DocDriver.scala +++ b/doc-tool/src/dotty/tools/dottydoc/DocDriver.scala @@ -16,7 +16,7 @@ import staticsite.Site */ class DocDriver extends Driver { import _root_.java.util.{ Map => JMap } - import scala.collection.JavaConverters._ + import model.java._ override def setup(args: Array[String], rootCtx: Context): (List[String], Context) = { val ctx = rootCtx.fresh @@ -40,29 +40,32 @@ class DocDriver extends Driver { ctx.docbase.packages } - def compiledDocsJava(args: Array[String]): JMap[String, Package] = - compiledDocs(args).asJava + def compiledDocsJava(args: Array[String]): JMap[String, Package] = { + scala.collection.JavaConverters.mapAsJavaMapConverter(compiledDocs(args)).asJava + } def indexToJson(index: collection.Map[String, Package]): String = index.json - def indexToJsonJava(index: JMap[String, Package]): String = + def indexToJsonJava(index: JMap[String, Package]): String = { + import scala.collection.JavaConverters._ indexToJson(index.asScala) + } override def main(args: Array[String]): Unit = { implicit val (filesToDocument, ctx) = setup(args, initCtx.fresh) - //doCompile(newCompiler(ctx), fileNames)(ctx) + doCompile(newCompiler(ctx), filesToDocument)(ctx) + val docs = ctx.docbase.packages.toJavaList val siteRoot = new java.io.File(ctx.settings.siteRoot.value) if (!siteRoot.exists || !siteRoot.isDirectory) ctx.error(s"Site root does not exist: $siteRoot") else { - Site(siteRoot) + Site(siteRoot, docs) .copyStaticFiles() .generateHtmlFiles() - // FIXME: liqp templates are compiled by threadpools, for some reason it // is not shutting down :-( System.exit(0) diff --git a/doc-tool/src/dotty/tools/dottydoc/model/java.scala b/doc-tool/src/dotty/tools/dottydoc/model/java.scala index 410085061..30e884ce3 100644 --- a/doc-tool/src/dotty/tools/dottydoc/model/java.scala +++ b/doc-tool/src/dotty/tools/dottydoc/model/java.scala @@ -4,6 +4,9 @@ package model import comment._ import references._ +import _root_.java.util.HashMap +import _root_.java.util.LinkedList + object java { import scala.collection.JavaConverters._ import _root_.java.util.{ Optional => JOptional, Map => JMap } @@ -15,36 +18,36 @@ object java { implicit class JavaComment(val cmt: Comment) extends AnyVal { def asJava: JMap[String, _] = Map( - "body" -> cmt.body, - "short" -> cmt.short, - "authors" -> cmt.authors.asJava, - "see" -> cmt.see.asJava, - "result" -> cmt.result.asJava, - "throws" -> cmt.throws.asJava, - "valueParams" -> cmt.valueParams.asJava, - "typeParams" -> cmt.typeParams.asJava, - "version" -> cmt.version.asJava, - "since" -> cmt.since.asJava, - "todo" -> cmt.todo.asJava, - "deprecated" -> cmt.deprecated.asJava, - "note" -> cmt.note.asJava, - "example" -> cmt.example.asJava, - "constructor" -> cmt.constructor.asJava, - "group" -> cmt.group.asJava, - "groupDesc" -> cmt.groupDesc.asJava, - "groupNames" -> cmt.groupNames.asJava, - "groupPrio" -> cmt.groupPrio.asJava, - "hideImplicitConversions" -> cmt.hideImplicitConversions.asJava + "body" -> cmt.body, + "short" -> cmt.short, + "authors" -> cmt.authors.asJava, + "see" -> cmt.see.asJava, + "result" -> cmt.result.asJava, + "throws" -> cmt.throws.asJava, + "valueParams" -> cmt.valueParams.asJava, + "typeParams" -> cmt.typeParams.asJava, + "version" -> cmt.version.asJava, + "since" -> cmt.since.asJava, + "todo" -> cmt.todo.asJava, + "deprecated" -> cmt.deprecated.asJava, + "note" -> cmt.note.asJava, + "example" -> cmt.example.asJava, + "constructor" -> cmt.constructor.asJava, + "group" -> cmt.group.asJava, + "groupDesc" -> cmt.groupDesc.asJava, + "groupNames" -> cmt.groupNames.asJava, + "groupPrio" -> cmt.groupPrio.asJava, + "hideImplicitConversions" -> cmt.hideImplicitConversions.asJava ).asJava } implicit class JavaPackage(val ent: Package) extends AnyVal { def asJava(extras: Map[String, _] = Map.empty): JMap[String, _] = (Map( - "kind" -> ent.kind, - "name" -> ent.name, - "path" -> ent.path.asJava, - "members" -> ent.members.map(_.asJava()).asJava, - "comment" -> ent.comment.map(_.asJava).asJava + "kind" -> ent.kind, + "name" -> ent.name, + "path" -> ent.path.asJava, + "members" -> ent.members.map(_.asJava()).asJava, + "comment" -> ent.comment.map(_.asJava).asJava ) ++ extras).asJava } @@ -220,4 +223,15 @@ object java { case ent: Def => ent.asJava case ent: Val => ent.asJava } + + implicit class JavaMap(val map: collection.Map[String, Package]) extends AnyVal { + def toJavaList: LinkedList[AnyRef] = { + map.toList + .sortBy(_._1) + .foldLeft(new LinkedList[AnyRef]()) { case (list, (_, pkg)) => + list.add(pkg.asJava()) + list + } + } + } } diff --git a/doc-tool/src/dotty/tools/dottydoc/staticsite/LiquidTemplate.scala b/doc-tool/src/dotty/tools/dottydoc/staticsite/LiquidTemplate.scala index 18ef9ef2a..b3d497ee5 100644 --- a/doc-tool/src/dotty/tools/dottydoc/staticsite/LiquidTemplate.scala +++ b/doc-tool/src/dotty/tools/dottydoc/staticsite/LiquidTemplate.scala @@ -9,18 +9,27 @@ case class LiquidTemplate(contents: String) extends ResourceFinder { import liqp.{ Template, TemplateContext } import liqp.nodes.LNode import liqp.tags.Tag + import liqp.filters.Filter + import liqp.parser.Flavor.JEKYLL + import java.util.{ HashMap, Map => JMap } + + // For some reason, liqp rejects a straight conversion using `.asJava` + private def toJavaMap(map: Map[String, AnyRef]): HashMap[String, Object] = + map.foldLeft(new HashMap[String, Object]()) { case (map, (k, v)) => + map.put(k, v) + map + } - def render(params: Map[String, AnyRef], includes: Map[String, String]): String = { - Template.parse(contents).`with`(ResourceInclude(params, includes)).render(params.asJava) - } + def render(params: Map[String, AnyRef], includes: Map[String, String]): String = + Template.parse(contents, JEKYLL) + .`with`(ResourceInclude(params, includes)) + .render(toJavaMap(params)) private case class ResourceInclude(params: Map[String, AnyRef], includes: Map[String, String]) extends Tag("include") { val DefaultExtension = ".html" - private def renderTemplate(template: String) = "dude" - - override def render(ctx: TemplateContext, nodes: LNode*): AnyRef = { + override def render(ctx: TemplateContext, nodes: LNode*): AnyRef = try { val origInclude = asString(nodes(0).render(ctx)) val incResource = origInclude match { case fileWithExt if fileWithExt.indexOf('.') > 0 => fileWithExt @@ -35,12 +44,16 @@ case class LiquidTemplate(contents: String) extends ResourceFinder { if (nodes.length > 1) params + (origInclude -> nodes(1).render(ctx)) else params - Template.parse(template, ctx.flavor).render(additionalParams.asJava) + Template.parse(template, JEKYLL).render(toJavaMap(additionalParams)) } .getOrElse { /*dottydoc.*/println(s"couldn't find include file '$origInclude'") "" } + } catch { + case t: Throwable => + println(s"got error: ${t.getMessage}") + throw t } } } diff --git a/doc-tool/src/dotty/tools/dottydoc/staticsite/MarkdownLinkVisitor.scala b/doc-tool/src/dotty/tools/dottydoc/staticsite/MarkdownLinkVisitor.scala new file mode 100644 index 000000000..ac2b6fc6d --- /dev/null +++ b/doc-tool/src/dotty/tools/dottydoc/staticsite/MarkdownLinkVisitor.scala @@ -0,0 +1,20 @@ +package dotty.tools +package dottydoc +package staticsite + +import com.vladsch.flexmark.ast._ + +object MarkdownLinkVisitor { + def apply(node: Node): Unit = + (new NodeVisitor( + new VisitHandler(classOf[Link], new Visitor[Link] { + override def visit(node: Link): Unit = { + val url = node.getUrl + if (url.endsWith(".md")) node.setUrl { + url.subSequence(0, url.lastIndexOf('.')).append(".html") + } + } + }) + )) + .visit(node) +} diff --git a/doc-tool/src/dotty/tools/dottydoc/staticsite/Page.scala b/doc-tool/src/dotty/tools/dottydoc/staticsite/Page.scala index c8148c627..556818007 100644 --- a/doc-tool/src/dotty/tools/dottydoc/staticsite/Page.scala +++ b/doc-tool/src/dotty/tools/dottydoc/staticsite/Page.scala @@ -88,6 +88,8 @@ class MarkdownPage(fileContents: => String, val params: Map[String, AnyRef], val override protected[this] def initFields()(implicit ctx: Context) = { super.initFields() val md = Parser.builder(ctx.docbase.markdownOptions).build.parse(_html) + // fix markdown linking + MarkdownLinkVisitor(md) _html = HtmlRenderer .builder(ctx.docbase.markdownOptions) .escapeHtml(false) diff --git a/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala b/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala index 3bc4db76d..226ac5bf6 100644 --- a/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala +++ b/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala @@ -2,19 +2,20 @@ package dotty.tools package dottydoc package staticsite -import _root_.java.nio.file.{ Files, FileSystems } -import _root_.java.nio.file.StandardCopyOption.REPLACE_EXISTING -import _root_.java.io.{ File => JFile } -import _root_.java.nio.file.Path -import _root_.java.io.ByteArrayInputStream -import _root_.java.nio.charset.StandardCharsets +import java.nio.file.{ Files, FileSystems } +import java.nio.file.StandardCopyOption.REPLACE_EXISTING +import java.io.{ File => JFile } +import java.util.{ List => JList } +import java.nio.file.Path +import java.io.ByteArrayInputStream +import java.nio.charset.StandardCharsets import dotc.config.Printers.dottydoc import dotc.core.Contexts.Context import scala.io.Source import scala.collection.mutable.ArrayBuffer -case class Site(val root: JFile) extends ResourceFinder { +case class Site(val root: JFile, val docs: JList[_]) extends ResourceFinder { /** All files that are considered static in this context, this can be * anything from CSS, JS to images and other files. * @@ -43,10 +44,26 @@ case class Site(val root: JFile) extends ResourceFinder { def copyStaticFiles(outDir: JFile = new JFile(root.getAbsolutePath + "/_site")): this.type = { if (!outDir.isDirectory) outDir.mkdirs() if (!outDir.isDirectory) /*dottydoc.*/println(s"couldn't create output folder: $outDir") - else staticAssets.foreach { asset => - val target = mkdirs(fs.getPath(outDir.getAbsolutePath, stripRoot(asset))) - val source = mkdirs(fs.getPath(asset.getAbsolutePath)) - Files.copy(source, target, REPLACE_EXISTING) + else { + // Copy user-defined static assets + staticAssets.foreach { asset => + val target = mkdirs(fs.getPath(outDir.getAbsolutePath, stripRoot(asset))) + val source = mkdirs(fs.getPath(asset.getAbsolutePath)) + Files.copy(source, target, REPLACE_EXISTING) + } + + // Copy statics included in resources + Map( + "css/dottydoc.css" -> "/css/dottydoc.css", + "css/color-brewer.css" -> "/css/color-brewer.css", + "js/highlight.pack.js" -> "/js/highlight.pack.js" + ) + .mapValues(getResource) + .foreach { case (path, resource) => + val source = new ByteArrayInputStream(resource.getBytes(StandardCharsets.UTF_8)) + val target = mkdirs(fs.getPath(outDir.getAbsolutePath, path)) + Files.copy(source, target, REPLACE_EXISTING) + } } this } @@ -56,10 +73,21 @@ case class Site(val root: JFile) extends ResourceFinder { if (!outDir.isDirectory) outDir.mkdirs() if (!outDir.isDirectory) /*dottydoc.*/println(s"couldn't create output folder: $outDir") else compilableFiles.foreach { asset => + import scala.collection.JavaConverters._ + val baseUrl: String = { + val rootLen = root.getAbsolutePath.split('/').length + val assetLen = asset.getAbsolutePath.split('/').length + "../" * (assetLen - rootLen - 1) + "." + } + val defaultParams = Map( + "docs" -> docs, + "page" -> Map("url" -> stripRoot(asset)), + "site" -> Map("baseUrl" -> baseUrl).asJava + ) val fileContents = Source.fromFile(asset).mkString val page = - if (asset.getName.endsWith(".md")) new MarkdownPage(fileContents, Map.empty, includes) - else new HtmlPage(fileContents, Map.empty, includes) + if (asset.getName.endsWith(".md")) new MarkdownPage(fileContents, defaultParams, includes) + else new HtmlPage(fileContents, defaultParams, includes) val renderedPage = render(page) val source = new ByteArrayInputStream(renderedPage.getBytes(StandardCharsets.UTF_8)) @@ -131,9 +159,12 @@ case class Site(val root: JFile) extends ResourceFinder { .listFiles.find(d => d.getName == "_layouts" && d.isDirectory) .map(collectFiles(_, f => f.endsWith(".md") || f.endsWith(".html"))) .getOrElse(Map.empty) + .map { case (k, v) => (k.substring(0, k.lastIndexOf('.')), v) } val defaultLayouts: Map[String, String] = Map( "main" -> "/_layouts/main.html", + "doc" -> "/_layouts/doc.html", + "doc-page" -> "/_layouts/doc-page.html", "index" -> "/_layouts/index.html" ).mapValues(getResource) @@ -161,9 +192,11 @@ case class Site(val root: JFile) extends ResourceFinder { .getOrElse(Map.empty) val defaultIncludes: Map[String, String] = Map( - "header.html" -> "/_includes/header.html" + "header.html" -> "/_includes/header.html", + "toc.html" -> "/_includes/toc.html" ).mapValues(getResource) + defaultIncludes ++ userDefinedIncludes } @@ -171,22 +204,20 @@ case class Site(val root: JFile) extends ResourceFinder { dir .listFiles .filter(f => includes(f.getName)) - .map { f => - (f.getName.substring(0, f.getName.lastIndexOf('.')), Source.fromFile(f).mkString) - } + .map(f => (f.getName, Source.fromFile(f).mkString)) .toMap /** Render a page to html, the resulting string is the result of the complete * expansion of the template with all its layouts and includes. */ - def render(page: Page, params: Map[String, AnyRef] = Map.empty)(implicit ctx: Context): String = { + def render(page: Page, params: Map[String, AnyRef] = Map.empty)(implicit ctx: Context): String = page.yaml.get("layout").flatMap(layouts.get(_)) match { case None => page.html case Some(layout) => - val newParams = Map("content" -> page.html) ++ params ++ Map("page" -> page.yaml) + import scala.collection.JavaConverters._ + val newParams = page.params ++ params ++ Map("page" -> page.yaml) ++ Map("content" -> page.html) val expandedTemplate = new HtmlPage(layout, newParams, includes) render(expandedTemplate, params) } - } } |