diff options
Diffstat (limited to 'doc-tool/src')
4 files changed, 91 insertions, 28 deletions
diff --git a/doc-tool/src/dotty/tools/dottydoc/staticsite/LiquidTemplate.scala b/doc-tool/src/dotty/tools/dottydoc/staticsite/LiquidTemplate.scala new file mode 100644 index 000000000..18ef9ef2a --- /dev/null +++ b/doc-tool/src/dotty/tools/dottydoc/staticsite/LiquidTemplate.scala @@ -0,0 +1,46 @@ +package dotty.tools +package dottydoc +package staticsite + +import dotc.config.Printers.dottydoc + +case class LiquidTemplate(contents: String) extends ResourceFinder { + import scala.collection.JavaConverters._ + import liqp.{ Template, TemplateContext } + import liqp.nodes.LNode + import liqp.tags.Tag + + def render(params: Map[String, AnyRef], includes: Map[String, String]): String = { + Template.parse(contents).`with`(ResourceInclude(params, includes)).render(params.asJava) + } + + 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 = { + val origInclude = asString(nodes(0).render(ctx)) + val incResource = origInclude match { + case fileWithExt if fileWithExt.indexOf('.') > 0 => fileWithExt + case file => file + DefaultExtension + } + + includes + .get(incResource) + .map { template => + val additionalParams = + // include has `with` clause: + if (nodes.length > 1) params + (origInclude -> nodes(1).render(ctx)) + else params + + Template.parse(template, ctx.flavor).render(additionalParams.asJava) + } + .getOrElse { + /*dottydoc.*/println(s"couldn't find include file '$origInclude'") + "" + } + } + } +} diff --git a/doc-tool/src/dotty/tools/dottydoc/staticsite/Page.scala b/doc-tool/src/dotty/tools/dottydoc/staticsite/Page.scala index 0293c3367..c8148c627 100644 --- a/doc-tool/src/dotty/tools/dottydoc/staticsite/Page.scala +++ b/doc-tool/src/dotty/tools/dottydoc/staticsite/Page.scala @@ -9,7 +9,6 @@ import dotc.config.Printers.dottydoc import com.vladsch.flexmark.html.HtmlRenderer import com.vladsch.flexmark.parser.Parser import com.vladsch.flexmark.ext.front.matter.AbstractYamlFrontMatterVisitor -import liqp.{ Template => LiquidTemplate } import _root_.java.util.{ Map => JMap } case class IllegalFrontMatter(message: String) extends Exception(message) @@ -17,7 +16,7 @@ case class IllegalFrontMatter(message: String) extends Exception(message) trait Page { import scala.collection.JavaConverters._ - + def includes: Map[String, String] def pageContent: String def params: Map[String, AnyRef] @@ -61,9 +60,7 @@ trait Page { // make accessible via "{{ page.title }}" in templates val page = Map("page" -> _yaml.asJava) - _html = LiquidTemplate - .parse(withoutYaml) - .render((params ++ page).asJava) + _html = LiquidTemplate(withoutYaml).render(params ++ page, includes) } /** Takes "page" from `params` map in case this is a second expansion, and @@ -81,11 +78,11 @@ trait Page { .getOrElse(newYaml) } -class HtmlPage(fileContents: => String, val params: Map[String, AnyRef]) extends Page { +class HtmlPage(fileContents: => String, val params: Map[String, AnyRef], val includes: Map[String, String]) extends Page { lazy val pageContent = fileContents } -class MarkdownPage(fileContents: => String, val params: Map[String, AnyRef]) extends Page { +class MarkdownPage(fileContents: => String, val params: Map[String, AnyRef], val includes: Map[String, String]) extends Page { lazy val pageContent = fileContents override protected[this] def initFields()(implicit ctx: Context) = { diff --git a/doc-tool/src/dotty/tools/dottydoc/staticsite/ResourceFinder.scala b/doc-tool/src/dotty/tools/dottydoc/staticsite/ResourceFinder.scala new file mode 100644 index 000000000..66d31fa18 --- /dev/null +++ b/doc-tool/src/dotty/tools/dottydoc/staticsite/ResourceFinder.scala @@ -0,0 +1,16 @@ +package dotty.tools +package dottydoc +package staticsite + +trait ResourceFinder { + /** If, for some reason, the supplied default files cannot be found - this + * exception will be thrown in `layouts`. + */ + final case class ResourceNotFoundException(message: String) extends Exception(message) + + protected def getResource(r: String): String = + Option(getClass.getResourceAsStream(r)).map(scala.io.Source.fromInputStream) + .map(_.mkString) + .getOrElse(throw ResourceNotFoundException(r)) + +} diff --git a/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala b/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala index ac609e6b6..b1962735f 100644 --- a/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala +++ b/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala @@ -7,12 +7,7 @@ import dotc.config.Printers.dottydoc import dotc.core.Contexts.Context import scala.io.Source -class Site(val root: JFile) { - - /** If, for some reason, the supplied default files cannot be found - this - * exception will be thrown in `layouts`. - */ - final case class ResourceNotFoundException(message: String) extends Exception(message) +class Site(val root: JFile) extends ResourceFinder { /** Files that define a layout then referred to by `layout: filename-no-ext` * in yaml front-matter. @@ -24,19 +19,10 @@ class Site(val root: JFile) { * defaults, the user-defined one will take precedence. */ val layouts: Map[String, String] = { - def collectLayouts(dir: JFile): Map[String, String] = - dir - .listFiles - .filter(f => f.getName.endsWith(".md") || f.getName.endsWith(".html")) - .map { f => - (f.getName.substring(0, f.getName.lastIndexOf('.')), Source.fromFile(f).mkString) - } - .toMap - val userDefinedLayouts = root .listFiles.find(d => d.getName == "_layouts" && d.isDirectory) - .map(collectLayouts) + .map(collectFiles(_, f => f.endsWith(".md") || f.endsWith(".html"))) .getOrElse(Map.empty) val defaultLayouts: Map[String, String] = Map( @@ -47,10 +33,28 @@ class Site(val root: JFile) { defaultLayouts ++ userDefinedLayouts } - private def getResource(r: String): String = - Option(getClass.getResourceAsStream(r)).map(scala.io.Source.fromInputStream) - .map(_.mkString) - .getOrElse(throw ResourceNotFoundException(r)) + val includes: Map[String, String] = { + val userDefinedIncludes = + root + .listFiles.find(d => d.getName == "_includes" && d.isDirectory) + .map(collectFiles(_, f => f.endsWith(".md") || f.endsWith(".html"))) + .getOrElse(Map.empty) + + val defaultIncludes: Map[String, String] = Map( + "header.html" -> "/_includes/header.html" + ).mapValues(getResource) + + defaultIncludes ++ userDefinedIncludes + } + + private def collectFiles(dir: JFile, includes: String => Boolean): Map[String, String] = + dir + .listFiles + .filter(f => includes(f.getName)) + .map { f => + (f.getName.substring(0, f.getName.lastIndexOf('.')), Source.fromFile(f).mkString) + } + .toMap def render(page: Page, params: Map[String, AnyRef])(implicit ctx: Context): String = { page.yaml.get("layout").flatMap(layouts.get(_)) match { @@ -58,7 +62,7 @@ class Site(val root: JFile) { page.html case Some(layout) => val newParams = Map("content" -> page.html) ++ params ++ Map("page" -> page.yaml) - val expandedTemplate = new HtmlPage(layout, newParams) + val expandedTemplate = new HtmlPage(layout, newParams, includes) render(expandedTemplate, params) } } |