summaryrefslogtreecommitdiff
path: root/book
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2014-12-28 09:09:39 +0100
committerLi Haoyi <haoyi@dropbox.com>2014-12-28 09:09:39 +0100
commita84c09efcb2d843ee04ee3299ceb592a00a42267 (patch)
treef0fd2cf8cadd7bc4bf91ebd31bd41d34a170a7f3 /book
parent7d14b23dbbdaf66b222839874a29fff4a34e1762 (diff)
downloadhands-on-scala-js-a84c09efcb2d843ee04ee3299ceb592a00a42267.tar.gz
hands-on-scala-js-a84c09efcb2d843ee04ee3299ceb592a00a42267.tar.bz2
hands-on-scala-js-a84c09efcb2d843ee04ee3299ceb592a00a42267.zip
wip
Diffstat (limited to 'book')
-rw-r--r--book/src/main/scala/book/Book.scala91
-rw-r--r--book/src/main/scala/book/BookData.scala17
-rw-r--r--book/src/main/scala/book/Main.scala87
-rw-r--r--book/src/main/scala/book/Utils.scala149
-rw-r--r--book/src/main/scalatex/book/Index.scalatex2
5 files changed, 82 insertions, 264 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
diff --git a/book/src/main/scalatex/book/Index.scalatex b/book/src/main/scalatex/book/Index.scalatex
index 7a7e2b8..1a10aa0 100644
--- a/book/src/main/scalatex/book/Index.scalatex
+++ b/book/src/main/scalatex/book/Index.scalatex
@@ -80,4 +80,4 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
@indepth.DesignSpace()
@sect{Java APIs}
- @indepth.JavaAPIs() \ No newline at end of file
+ @indepth.JavaAPIs()