diff options
Diffstat (limited to 'book/src/main/scala')
-rw-r--r-- | book/src/main/scala/book/Book.scala | 91 | ||||
-rw-r--r-- | book/src/main/scala/book/BookData.scala | 17 | ||||
-rw-r--r-- | book/src/main/scala/book/Main.scala | 87 | ||||
-rw-r--r-- | book/src/main/scala/book/Utils.scala | 149 |
4 files changed, 81 insertions, 263 deletions
diff --git a/book/src/main/scala/book/Book.scala b/book/src/main/scala/book/Book.scala deleted file mode 100644 index 71c0d65..0000000 --- a/book/src/main/scala/book/Book.scala +++ /dev/null @@ -1,91 +0,0 @@ -package book -import acyclic.file - -import scalatags.Text.tags2 -import scalatags.Text.all._ - -/** - * Created by haoyi on 10/26/14. - */ -object Book { - val autoResources = Set( - "META-INF/resources/webjars/highlightjs/8.2-1/highlight.min.js", - "META-INF/resources/webjars/highlightjs/8.2-1/styles/idea.min.css", - "META-INF/resources/webjars/highlightjs/8.2-1/languages/scala.min.js", - "META-INF/resources/webjars/highlightjs/8.2-1/languages/javascript.min.js", - "META-INF/resources/webjars/highlightjs/8.2-1/languages/bash.min.js", - "META-INF/resources/webjars/highlightjs/8.2-1/languages/diff.min.js", - "META-INF/resources/webjars/highlightjs/8.2-1/languages/xml.min.js", - "META-INF/resources/webjars/pure/0.5.0/pure-min.css", - "META-INF/resources/webjars/pure/0.5.0/grids-responsive-min.css", - "META-INF/resources/webjars/font-awesome/4.2.0/fonts/FontAwesome.otf", - "META-INF/resources/webjars/font-awesome/4.2.0/fonts/fontawesome-webfont.eot", - "META-INF/resources/webjars/font-awesome/4.2.0/fonts/fontawesome-webfont.svg", - "META-INF/resources/webjars/font-awesome/4.2.0/fonts/fontawesome-webfont.ttf", - "META-INF/resources/webjars/font-awesome/4.2.0/fonts/fontawesome-webfont.woff", - "css/side-menu.css", - "example-opt.js", -// "example-opt.js.map", - "webpage/weather.js", - "favicon.svg", - "favicon.png" - ) - - val fontAwesomeCss = - "META-INF/resources/webjars/font-awesome/4.2.0/css/font-awesome.min.css" - - val manualResources = Set( - "images/javascript-the-good-parts-the-definitive-guide.jpg", - "images/Hello World.png", - "images/Hello World White.png", - "images/Hello World Console.png", - "images/IntelliJ Hello.png", - "images/Dropdown.png", - "images/Scalatags Downloads.png", - fontAwesomeCss - ) - - - val txt = Index() - val data = upickle.write(sect.structure) - val googleAnalytics = - """ - |(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ - | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), - | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) - | })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - | - | ga('create', 'UA-27464920-4', 'auto'); - | ga('send', 'pageview'); - """.stripMargin - val site = Seq( - raw("<!doctype html>"), - html( - head( - meta(charset:="utf-8"), - meta(name:="viewport", content:="width=device-width, initial-scale=1.0"), - link(rel:="shortcut icon", `type`:="image/png", href:="favicon.png"), - link(rel:="stylesheet", href:=fontAwesomeCss), - link(rel:="stylesheet", href:="styles.css"), - tags2.title("Hands-on Scala.js"), - script(src:="scripts.js"), - script(raw(googleAnalytics)) - ), - body( - onload:=s"Controller().main($data)", - div(id:="layout")( - a(href:="#menu", id:="menuLink", cls:="menu-link")( - span - ), - div(id:="menu") - - ), - div(id:="main", - div(id:="main-box")( - txt - ) - ) - ) - ) - ).render -} diff --git a/book/src/main/scala/book/BookData.scala b/book/src/main/scala/book/BookData.scala index ff1f23a..8484f10 100644 --- a/book/src/main/scala/book/BookData.scala +++ b/book/src/main/scala/book/BookData.scala @@ -50,11 +50,22 @@ object BookData { def half = div(cls:="pure-u-1 pure-u-md-1-2") - val hl = new Highlighter( - Seq( + val hl = new scalatex.site.Highlighter { + override val pathMappings = Seq( s"$cloneRoot/scala-js" -> "https://github.com/scala-js/scala-js", s"$cloneRoot/workbench-example-app" -> "https://github.com/lihaoyi/workbench-example-app", "" -> "https://github.com/lihaoyi/hands-on-scala-js" ) - ) + override val suffixMappings = Map( + "scala" -> "scala", + "sbt" -> "scala", + "js" -> "javascript" + ) + def scala(s: String) = this.highlight(s, "scala") + def bash(s: String) = this.highlight(s, "bash") + def html(s: String) = this.highlight(s, "html") + def xml(s: String) = this.highlight(s, "xml") + def diff(s: String) = this.highlight(s, "diff") + def javascript(s: String) = this.highlight(s, "javascript") + } } diff --git a/book/src/main/scala/book/Main.scala b/book/src/main/scala/book/Main.scala index 4b862d0..3bae7b8 100644 --- a/book/src/main/scala/book/Main.scala +++ b/book/src/main/scala/book/Main.scala @@ -3,40 +3,74 @@ import acyclic.file import java.io.InputStream import java.nio.file.{Paths, Files} +import scalatags.Text.{attrs, tags2, all} +import scalatags.Text.all._ +import scalatex.site.Section.Tree +import scalatex.site.Site object Main { - def write(txt: String, dest: String) = { - Paths.get(dest).toFile.getParentFile.mkdirs() - Files.deleteIfExists(Paths.get(dest)) - Files.write(Paths.get(dest), txt.getBytes) - } - def copy(src: InputStream, dest: String) = { - Paths.get(dest).toFile.getParentFile.mkdirs() - Files.deleteIfExists(Paths.get(dest)) - Files.copy(src, Paths.get(dest)) - } - def main(args: Array[String]): Unit = { - println("Writing Book") - val outputRoot = System.getProperty("output.root") + "/" - write(Book.site, s"$outputRoot/index.html") - - val jsFiles = Book.autoResources.filter(_.endsWith(".js")).toSet - val cssFiles = Book.autoResources.filter(_.endsWith(".css")).toSet - val miscFiles = Book.autoResources -- cssFiles -- jsFiles + val googleAnalytics = + """ + |(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + | })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); + | + | ga('create', 'UA-27464920-4', 'auto'); + | ga('send', 'pageview'); + """.stripMargin + + val data = upickle.write(sect.structure) + + val s = new Site { + def content = Map("index.html" -> Index()) + + override def autoResources = super.autoResources | Set( + "META-INF/resources/webjars/pure/0.5.0/grids-responsive-min.css", + "css/side-menu.css", + "example-opt.js", + "webpage/weather.js", + "favicon.svg", + "favicon.png" + ) + override def manualResources = super.manualResources | Set( + "images/javascript-the-good-parts-the-definitive-guide.jpg", + "images/Hello World.png", + "images/Hello World White.png", + "images/Hello World Console.png", + "images/IntelliJ Hello.png", + "images/Dropdown.png", + "images/Scalatags Downloads.png" + ) + override def headFrags = super.headFrags ++ Seq( + meta(charset:="utf-8"), + meta(name:="viewport", attrs.content:="width=device-width, initial-scale=1.0"), + link(rel:="shortcut icon", `type`:="image/png", href:="favicon.png"), + tags2.title("Hands-on Scala.js"), + script(raw(googleAnalytics)) + ) + override def bodyFrag(frag: Frag) = body( + onload:=s"Controller().main($data)", + div(id:="layout")( + a(href:="#menu", id:="menuLink", cls:="menu-link")( + span + ), + div(id:="menu") + + ), + div(id:="main", + div(id:="main-box")( + frag + ) + ) + ) - for(res <- Book.manualResources ++ miscFiles) { - copy(getClass.getResourceAsStream("/" + res), outputRoot + res) } - for((resources, dest) <- Seq(jsFiles -> "scripts.js", cssFiles -> "styles.css")) { - val blobs = for(res <- resources.iterator) yield { - io.Source.fromInputStream(getClass.getResourceAsStream("/"+res)).mkString - } + s.renderTo(System.getProperty("output.root") + "/") - write(blobs.mkString("\n"), outputRoot + dest) - } val allNames = { def rec(n: Tree[String]): Seq[String] = { @@ -62,5 +96,4 @@ object Main { // lnk.usedLinks } - } diff --git a/book/src/main/scala/book/Utils.scala b/book/src/main/scala/book/Utils.scala index 2c861d0..e551621 100644 --- a/book/src/main/scala/book/Utils.scala +++ b/book/src/main/scala/book/Utils.scala @@ -13,69 +13,18 @@ case class pureTable(header: Frag*){ ) } } -object sect{ - +object sect extends scalatex.site.Section{ var indent = 0 - val headers = Seq[((String, String, Frag) => scalatags.Text.Tag, Option[Frag => Frag])]( - ((h, s, l) => div(cls:="header")( - h1(h, l), - h2(s) - ), Some(f => div(cls:="content", f))), - ((h, s, l) => div(cls:="header")( - h1(id:=munge(h), h, l), - br - ), None), - (h1(_, _, _), None), - (h2(_, _, _), None), - (h3(_, _, _), None), - (h4(_, _, _), None), - (h5(_, _, _), None), - (h6(_, _, _), None) - ) - - var structure = Tree[String]("root", mutable.Buffer.empty) - - val usedRefs = mutable.Set.empty[String] - def ref(s: String, txt: String = "") = { - usedRefs += s - a(if (txt == "") s else txt, href:=s"#${munge(s)}") - } - - def munge(name: String) = { - name.replace(" ", "") - } + override val headers: Seq[Header] = Seq( + Header((h, s, l) => div(cls:="header")(h1(h, l), h2(s)), f => div(cls:="content", f)), + Header((h, s, l) => div(cls:="header")(h1(id:=munge(h), h, l), br)), + h1, h2, h3, h4, h5, h6 + ) } -case class sect(name: String, subname: String = ""){ - sect.indent += 1 - val newNode = Tree[String](name, mutable.Buffer.empty) - val (headerWrap, contentWrap) = sect.headers(sect.indent-1) - sect.structure.children.append(newNode) - val prev = sect.structure - sect.structure = newNode - def apply(args: Frag*) = { - val wrappedContents = contentWrap.getOrElse((x: Frag) => x)(args) - val headingAnchor = a( - cls:="header-link", - href:=s"#${sect.munge(name)}", - " ", - i(cls:="fa fa-link") - ) - val res = Seq[Frag]( - headerWrap(name, subname, headingAnchor)( - cls:="content-subhead", - id:=sect.munge(name) - ), - wrappedContents - ) - sect.indent -= 1 - sect.structure = prev - res - } -} -case class Tree[T](value: T, children: mutable.Buffer[Tree[T]]) + object lnk{ val usedLinks = mutable.Set.empty[String] def apply(name: String, url: String) = { @@ -122,87 +71,3 @@ object lnk{ val scalaPickling = lnk("scala-pickling", "https://github.com/scala/pickling") } } - -class Highlighter(mappings: Seq[(String, String)]){ - def highlight(snippet: Seq[String], lang: String) = { - val string = snippet.mkString - val lines = string.split("\n", -1) - if (lines.length == 1){ - code(cls:=lang + " highlight-me", lines(0), padding:=0, display:="inline") - }else{ - val minIndent = lines.map(_.takeWhile(_ == ' ').length) - .filter(_ > 0) - .min - val stripped = lines.map(_.drop(minIndent)) - .dropWhile(_ == "") - .mkString("\n") - - pre(code(cls:=lang + " highlight-me hljs", stripped)) - } - } - - def javascript(code: String*) = highlight(code, "javascript") - def scala(code: String*) = highlight(code, "scala") - def bash(code: String*) = highlight(code, "bash") - def diff(code: String*) = highlight(code, "diff") - def html(code: String*) = highlight(code, "xml") - - def ref(filepath: String, start: String = "", end: String = "\n") = { - - val lang = filepath.split('.').last match { - case "js" => "javascript" - case "scala" => "scala" - case "sbt" => "scala" - case "sh" => "bash" - case "html" => "xml" - case x => - println("??? " + x) - ??? - } - - val lines = io.Source.fromFile(filepath).getLines().toVector - - def indent(line: String) = line.takeWhile(_.isWhitespace).length - - val startLine = lines.indexWhere(_.contains(start)) - if (startLine == -1){ - throw new Exception("Can't find marker: " + start) - } - val whitespace = indent(lines(startLine)) - val endLine = lines.indexWhere( - line => line.contains(end) || (indent(line) < whitespace && line.trim != ""), - startLine + 1 - ) - val sliced = - if (endLine == -1) lines.drop(startLine) - else lines.slice(startLine, endLine) - - val blob = sliced.map(_.drop(whitespace)).mkString("\n") - - val (prefix, url) = - mappings.iterator - .find{case (prefix, path) => filepath.startsWith(prefix)} - .get - - val hash = - if (endLine == -1) "" - else s"#L$startLine-L$endLine" - - val linkUrl = - s"$url/tree/master/${filepath.drop(prefix.length)}$hash" - pre( - code(cls:=lang + " highlight-me hljs", blob), - a( - cls:="header-link", - i(cls:="fa fa-link "), - position.absolute, - right:="0.5em", - bottom:="0.5em", - display.block, - fontSize:="24px", - href:=linkUrl, - target:="_blank" - ) - ) - } -}
\ No newline at end of file |