diff options
Diffstat (limited to 'doc-tool')
-rw-r--r-- | doc-tool/resources/_layouts/main.html | 37 | ||||
-rw-r--r-- | doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala | 62 | ||||
-rw-r--r-- | doc-tool/test/StaticSiteTests.scala | 40 |
3 files changed, 139 insertions, 0 deletions
diff --git a/doc-tool/resources/_layouts/main.html b/doc-tool/resources/_layouts/main.html new file mode 100644 index 000000000..1920f9ce7 --- /dev/null +++ b/doc-tool/resources/_layouts/main.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <meta http-equiv="x-ua-compatible" content="ie=edge"> + + <title>{{ page.title }}</title> + + <link + rel="stylesheet" + href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" + integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" + crossorigin="anonymous" + > + </head> + <body> + + {{ content }} + + <script + src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js" + integrity="sha384-3ceskX3iaEnIogmQchP8opvBy3Mi7Ce34nWjpBIwVTHfGYWQS9jwHDVRnpKKHJg7" + crossorigin="anonymous" + ></script> + <script + src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.7/js/tether.min.js" + integrity="sha384-XTs3FgkjiBgo8qjEjBk0tGmf3wPrWtA6coPfQDfFEY8AnYJwjalXCiosYRBIBZX8" + crossorigin="anonymous" + ></script> + <script + src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js" + integrity="sha384-BLiI7JTZm+JWlgKa0M0kGRpJbF2J8q+qreVrKBC47e3K6BW78kGLrCkeRX6I9RoK" + crossorigin="anonymous" + ></script> + </body> +</html> 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 + } + } +} diff --git a/doc-tool/test/StaticSiteTests.scala b/doc-tool/test/StaticSiteTests.scala new file mode 100644 index 000000000..a2f174eb3 --- /dev/null +++ b/doc-tool/test/StaticSiteTests.scala @@ -0,0 +1,40 @@ +package dotty.tools +package dottydoc + +import org.junit.Test +import org.junit.Assert._ + +import staticsite.{ Site, HtmlPage } + +class StaticSiteTests extends DottyDocTest { + @Test def hasCorrectLayoutFiles = { + val site = new Site(new java.io.File("../doc-tool/resources/")) + + assert(site.root.exists && site.root.isDirectory, + s"'${site.root.getName}' is not a directory") + + val expectedLayouts = Set("main") + assert(site.layouts.keys == expectedLayouts, + s"Incorrect layouts in: ${site.layouts.keys}, expected: $expectedLayouts") + } + + @Test def renderHelloInMainLayout = { + val site = new Site(new java.io.File("../doc-tool/resources/")) + + val renderedPage = site.render(new HtmlPage( + """|--- + |layout: main + |--- + | + |Hello, world!""".stripMargin, + Map.empty + ), Map.empty) + + assert( + renderedPage.contains("Hello, world!") && + !renderedPage.contains("---\nlayout: main\n---\n") && + renderedPage.contains("<!DOCTYPE html>"), + "html page did not render properly" + ) + } +} |