diff options
Diffstat (limited to 'doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala')
-rw-r--r-- | doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala b/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala new file mode 100644 index 000000000..d51b881e5 --- /dev/null +++ b/doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala @@ -0,0 +1,62 @@ +package dotty.tools +package dottydoc +package staticsite + +import _root_.java.io.{ File => JFile } +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) + + /** Files that define a layout then referred to by `layout: filename-no-ext` + * in yaml front-matter. + * + * The compiler will look in two locations, `<root>/_layouts/` and + * in the bundled jar file's resources `/_layouts`. + * + * If the user supplies a layout that has the same name as one of the + * 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 + + def getResource(p: String): String = + Option(getClass.getResourceAsStream(p)).map(scala.io.Source.fromInputStream) + .map(_.mkString) + .getOrElse(throw ResourceNotFoundException(p)) + + val userDefinedLayouts = + root + .listFiles.find(d => d.getName == "_layouts" && d.isDirectory) + .map(collectLayouts) + .getOrElse(Map.empty) + + val defaultLayouts: Map[String, String] = Map( + "main" -> "/_layouts/main.html" + ).mapValues(getResource) + + defaultLayouts ++ userDefinedLayouts + } + + def render(page: Page, params: Map[String, AnyRef])(implicit ctx: Context): String = { + page.yaml.get("layout").flatMap(layouts.get(_)) match { + case Some(layout) => + (new HtmlPage(layout, Map("content" -> page.html) ++ params)).html + case None => + page.html + } + } +} |