From 1ac4a2594bf2ebe1fc80b93f1208343653892517 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Sat, 28 Mar 2015 22:16:57 +0800 Subject: scalatex 0.2.1 --- book/src/main/scala/book/BookData.scala | 29 ++++++-------- book/src/main/scala/book/Main.scala | 45 ++++++++-------------- book/src/main/scala/book/Utils.scala | 14 ------- book/src/main/scalatex/Index.scalatex | 2 +- book/src/main/scalatex/Intro.scalatex | 4 +- book/src/main/scalatex/handson/CanvasApp.scalatex | 10 ++--- .../main/scalatex/handson/ClientServer.scalatex | 4 +- .../src/main/scalatex/handson/CommandLine.scalatex | 26 ++++++------- .../main/scalatex/handson/GettingStarted.scalatex | 20 +++++----- .../scalatex/handson/PublishingModules.scalatex | 6 +-- book/src/main/scalatex/handson/WebPage.scalatex | 36 ++++++++--------- .../scalatex/indepth/AdvancedTechniques.scalatex | 2 +- .../scalatex/indepth/CompilationPipeline.scalatex | 8 ++-- .../src/main/scalatex/indepth/DesignSpace.scalatex | 16 ++++---- book/src/main/scalatex/indepth/JavaAPIs.scalatex | 2 +- 15 files changed, 96 insertions(+), 128 deletions(-) (limited to 'book') diff --git a/book/src/main/scala/book/BookData.scala b/book/src/main/scala/book/BookData.scala index 9fa4d5e..dc4d717 100644 --- a/book/src/main/scala/book/BookData.scala +++ b/book/src/main/scala/book/BookData.scala @@ -3,15 +3,18 @@ package book import java.io.File import acyclic.file -import ammonite.all._ +import ammonite.ops._ import ammonite.ops.Path import scalatags.Text.TypedTag import scalatags.Text.all._ +import scalatex.site +import scalatex.site.Highlighter + object BookData { - val wd = processWorkingDir + val wd = cwd val cloneRoot = Path(System.getProperty("clone.root")) - - + val lnk = book.lnk + val pureTable = book.pureTable lazy val javaAPIs = { import java.io.File @@ -48,23 +51,13 @@ object BookData { def less = div(cls:="pure-u-1 pure-u-md-11-24") def half = div(cls:="pure-u-1 pure-u-md-1-2") - - val hl = new scalatex.site.Highlighter { - override val pathMappings = Seq( + lazy val hl = new Highlighter { + override def pathMappings = Seq( cloneRoot/"scala-js" -> "https://github.com/scala-js/scala-js/blob/master", cloneRoot/"workbench-example-app" -> "https://github.com/lihaoyi/workbench-example-app/blob/master", wd -> "https://github.com/lihaoyi/hands-on-scala-js/blob/master" ) - 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") } + + val sect = new site.Section{} } diff --git a/book/src/main/scala/book/Main.scala b/book/src/main/scala/book/Main.scala index 737c130..7586e54 100644 --- a/book/src/main/scala/book/Main.scala +++ b/book/src/main/scala/book/Main.scala @@ -7,12 +7,14 @@ import ammonite.ops.Path import scalatags.Text.{attrs, tags2, all} import scalatags.Text.all._ -import scalatex.site.Section.Tree -import scalatex.site.Site -import ammonite.all.{rel => _, _} +import scalatex.site + +import scalatex.site.{Tree, Site} +import ammonite.ops._ object Main { - val wd = processWorkingDir + val wd = cwd + def main(args: Array[String]): Unit = { val googleAnalytics = """ @@ -25,12 +27,15 @@ object Main { | ga('send', 'pageview'); """.stripMargin - def data = upickle.write(sect.structure) + val s = new Site { - def content = Map("index.html" -> Index()) + def content = Map("index.html" -> scalatex.Index()) - override def autoResources = super.autoResources ++ Seq( + override def autoResources = + super.autoResources ++ + BookData.hl.autoResources ++ + site.Sidebar.autoResources ++ Seq( root/"META-INF"/'resources/'webjars/'pure/"0.5.0"/"grids-responsive-min.css", root/'css/"side-menu.css", root/"example-opt.js", @@ -56,25 +61,9 @@ object Main { script(raw(googleAnalytics)) ) override def bodyFrag(frag: Frag) = body( - - div(id:="layout")( - a(href:="#menu", id:="menuLink", cls:="menu-link")( - span - ), - div(id:="menu") - - ), - div( - id:="main", - div( - id:="main-box", - cls:="scalatex-content", - maxWidth:="840px", - lineHeight:="1.6em", - frag - ) - ), - onload:=s"scrollmenu.Controller().main($data)" + super.bodyFrag(frag), + site.Sidebar.snippet(BookData.sect.structure.children), + scalatex.site.Highlighter.snippet ) } @@ -85,7 +74,7 @@ object Main { def rec(n: Tree[String]): Seq[String] = { n.value +: n.children.flatMap(rec) } - rec(sect.structure).toSet + rec(BookData.sect.structure).toSet } val dupes = allNames.groupBy(x => x) .values @@ -95,7 +84,7 @@ object Main { assert(dupes.size == 0, s"Duplicate names: $dupes") - val dangling = sect.usedRefs -- allNames + val dangling = BookData.sect.usedRefs -- allNames assert(dangling.size == 0, s"Dangling Refs: $dangling") diff --git a/book/src/main/scala/book/Utils.scala b/book/src/main/scala/book/Utils.scala index c62f71f..5698dd8 100644 --- a/book/src/main/scala/book/Utils.scala +++ b/book/src/main/scala/book/Utils.scala @@ -13,20 +13,6 @@ case class pureTable(header: Frag*){ ) } } -object sect extends scalatex.site.Section{ - var indent = 0 - - override val headers: Seq[Header] = Seq( - Header( - (l, h, s) => div(cls:="header")(h1(h, l), br, h2(s)), - f => div(cls:="content", f) - ), - Header( - (l, h, s) => div(cls:="header")(h1(id:=munge(h), h, l), br)), - h1, h2, h3, h4, h5, h6 - ) -} - object lnk{ val usedLinks = mutable.Set.empty[String] diff --git a/book/src/main/scalatex/Index.scalatex b/book/src/main/scalatex/Index.scalatex index e9f65bb..72f9668 100644 --- a/book/src/main/scalatex/Index.scalatex +++ b/book/src/main/scalatex/Index.scalatex @@ -12,7 +12,7 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth @hl.ref(wd/'examples/'demos/'src/'main/'scala/"Splash.scala", "var x") @less - @BookData.example(canvas, "Splash().main") + @example(canvas, "Splash().main") @p @lnk("Scala.js", "http://www.scala-js.org/") is a compiler that compiles Scala source code to equivalent Javascript code. That lets you write Scala code that you can run in a web browser, or other environments (Chrome plugins, Node.js, etc.) where Javascript is supported. This book is an introduction to Scala.js, which aims to get you from knowing-nothing about it to being relatively proficient. diff --git a/book/src/main/scalatex/Intro.scalatex b/book/src/main/scalatex/Intro.scalatex index b72b6e2..e4ab5bd 100644 --- a/book/src/main/scalatex/Intro.scalatex +++ b/book/src/main/scalatex/Intro.scalatex @@ -15,7 +15,7 @@ } @half - @hl.javascript + @hl.js ScalaJS.c.LMain$.prototype.main__V = (function() { var x = 0; while ((x < 10)) { @@ -111,7 +111,7 @@ @p At a first approximation, Scala.js provides you a sane language to do development in the web browser. This saves you from an endless stream of Javascript warts like this one: - @hl.javascript + @hl.js javascript> ["10", "10", "10", "10"].map(parseInt) [10, NaN, 2, 3] // WTF diff --git a/book/src/main/scalatex/handson/CanvasApp.scalatex b/book/src/main/scalatex/handson/CanvasApp.scalatex index d008508..c485610 100644 --- a/book/src/main/scalatex/handson/CanvasApp.scalatex +++ b/book/src/main/scalatex/handson/CanvasApp.scalatex @@ -35,7 +35,7 @@ @hl.ref(canvasapp/"ScratchPad.scala", "/*code*/") @less - @BookData.example(canvas, "canvasapp.ScratchPad().main") + @book.BookData.example(canvas, "canvasapp.ScratchPad().main") @p This code sets up the @lnk.dom.mousedown and @lnk.dom.mouseup events to keep track of whether or not the mouse has currently been clicked. It then draws black squares any time you move the mouse while the button is down. This lets you basically click-and-drag to draw pictures on the canvas. Try it out! @@ -69,7 +69,7 @@ @hl.ref(canvasapp/"Clock.scala", "/*code*/") @less - @BookData.example(canvas, "canvasapp.Clock().main") + @book.BookData.example(canvas, "canvasapp.Clock().main") @p As you can see, we're using more @lnk("Canvas APIs", "https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D"), in this case dealing with rendering text on the canvas. Another thing we're using is the Javascript @lnk("Date", "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date") class, in Scala.js under the full name @hl.scala{scala.scalajs.js.Date}, here imported as @hl.scala{js.Date}. Again, click on the link @i(cls:="fa fa-link ") icon to view the full-code if you're having trouble here. @@ -151,7 +151,7 @@ At almost 100 lines of code, this is quite a meaty example! Nonetheless, when all is said and done, you will find that the example actually works! Try it out! @div - @BookData.example(canvas, "canvasapp.FlappyLine().main") + @book.BookData.example(canvas, "canvasapp.FlappyLine().main") @sect{Canvas Recap} @p @@ -180,9 +180,9 @@ @li @hl.scala{renderer} is a Javascript @lnk.dom.CanvasRenderingContext2D, and all the methods on it are Javascript method calls directly on the Javascript object @li - @hl.scala{frame} is a Scala @hl.scala{Int}, and obeys Scala semantics, though it is implemented as a Javascript @hl.javascript{Number} under the hood. + @hl.scala{frame} is a Scala @hl.scala{Int}, and obeys Scala semantics, though it is implemented as a Javascript @hl.js{Number} under the hood. @li - @hl.scala{playerY} and @hl.scala{playerV} are Scala @hl.scala{Double}s, implemented directly as Javascript @hl.javascript{Number}s + @hl.scala{playerY} and @hl.scala{playerV} are Scala @hl.scala{Double}s, implemented directly as Javascript @hl.js{Number}s @p This reveals something pretty interesting about Scala.js: even though Scala at-first-glance is a very different language from Javascript, the interoperation with Javascript is so seamless that you can't even tell from the code which values/methods are defined in Scala and which values/methods come from Javascript! diff --git a/book/src/main/scalatex/handson/ClientServer.scalatex b/book/src/main/scalatex/handson/ClientServer.scalatex index 4d15735..eef99b3 100644 --- a/book/src/main/scalatex/handson/ClientServer.scalatex +++ b/book/src/main/scalatex/handson/ClientServer.scalatex @@ -28,7 +28,7 @@ @p Getting started with client-server integration, let's go with the simplest configuration possible: a Spray server and a Scala.js client. Most of the other web-frameworks (@lnk.misc.Play, @lnk.misc.Scalatra, etc.) will have more complex configurations, but the basic mechanism of wiring up Scala.js to your web framework will be the same. Just like our project in @sect.ref{Cross Publishing Libraries}, our project will look like this: - @hl.bash + @hl.sh $ tree . ├── build.sbt @@ -68,7 +68,7 @@ @p This is a typical @lnk.github.Scalatags HTML snippet. Note that since we're serving it directly from the server in Scala code, we do not need to leave a @code{.html} file somewhere on the filesystem! We can declare all HTML, including the skeleton of the page, in Scalatags. Otherwise it's the same as what we saw in earlier chapters: A simple HTML page which includes a script tag to run our Scala.js application. @p - Lastly, we'll set up the Scala.js main method, which we are calling in the @hl.html{"} sneaks through and your users' accounts & data is compromised. @@ -49,7 +49,7 @@ @hl.ref(webpage/"HelloWorld1.scala") @less - @BookData.example(div, "webpage.HelloWorld1().main") + @book.BookData.example(div, "webpage.HelloWorld1().main") @p Scalatags has some nice advantages over plain HTML: it's type-safe, so typos like @hl.scala{dvi} get caught at compile-time. It's also secure, such that you don't need to worry about script-tags in strings or similar. The @lnk("Scalatags Readme", "https://github.com/lihaoyi/scalatags#scalatags") elaborates on these points and other advantages. As you can see, it takes just 1 import at the top of the file to bring it in scope, and then you can use all of Scalatags' functionality. @@ -63,7 +63,7 @@ @hl.ref(webpage/"Inputs.scala", "val box") @less - @BookData.example(div(height:="150px"), "webpage.Inputs().main") + @example(div(height:="150px"), "webpage.Inputs().main") @p In Scalatags, you build up fragments of type @hl.scala{Frag} using functions like @hl.scala{div}, @hl.scala{h1}, etc., and call @hl.scala{.render} on it to turn it into a real @lnk.dom.Element. Different fragments render to different things: e.g. @hl.scala{input.render} gives you a @lnk.dom.html.Input, @hl.scala{span.render} gives you a @lnk.dom.html.Span. You can then access the properties of these elements: adding callbacks, checking their value, anything you want. @@ -81,7 +81,7 @@ @hl.ref(webpage/"Search0.scala", "val listings", "def") @p - Next, let's think about how we want to render these fruits. One natural way would be as a list, which in HTML is represented by a @hl.html{