From e620434a2e1f913153a93656aab869453a536cd4 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 15 Dec 2016 21:05:44 -0800 Subject: [PATCH] Docs improvements: content in Markdown, organization into subtemplates, fixed tests (#4401) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Replace tiny bitmaps with base64-encoded URIs * Optimize SVGs; replace logo PNG with SVG * Modernize favicon * Embed CSS; a bit unorthodox, but we’re a single page so there’s no point in separate .css files and their separate HTTP requests * Documentation is now markdown, converted to HTML on compilation * Render the examples when we’re rendering index.html; they compile so quickly that there’s no need to pre-render them and save the intermediate .js files * Split apart index.html into components that Cakefile assembles, so that we can add in logic to include different files for v1 versus v2 * Split building index.html and building test.html into two tasks; collapse the parts of `releaseHeader` into one compact function * Move include logic into templates * Get error messages tests to work in the browser * Update output index.html * Split body into nav and body * Watch subtemplates * Revert "Split body into nav and body" This reverts commit ec9e559ec0c3f350bd009afd437652347789b180. * Add marked * Update gitignore * Use idiomatic markdown output for code blocks (
)

* Handle ids within the template, not in the Cakefile; remove marked’s auto-generated and conflicting ids

* Move the `codeFor` function into versioned folders, so that v1 and v2 docs can have different example code blocks/editors

* Update packages, including new highlight.js which supports our newer keywords and triple backticks (docs output is unchanged)
---
 .gitignore                                    |    4 +-
 Cakefile                                      |  169 +-
 docs/v1/.gitignore                            |    1 -
 docs/v1/index.html                            | 3792 +++++------------
 docs/v1/test.html                             | 1197 ++++++
 documentation/index.html                      | 2540 +----------
 documentation/sections/books.md               |   13 +
 documentation/sections/cake.md                |   11 +
 documentation/sections/changelog.md           |  508 +++
 documentation/sections/chat.md                |    5 +
 documentation/sections/classes.md             |   20 +
 documentation/sections/comparisons.md         |    7 +
 documentation/sections/conditionals.md        |    9 +
 documentation/sections/destructuring.md       |   39 +
 documentation/sections/embedded.md            |   21 +
 documentation/sections/examples.md            |   11 +
 .../sections/existential_operator.md          |   17 +
 documentation/sections/expressions.md         |   29 +
 documentation/sections/fat_arrow.md           |   27 +
 documentation/sections/functions.md           |   13 +
 documentation/sections/heregexes.md           |    7 +
 documentation/sections/installation.md        |   27 +
 documentation/sections/introduction.md        |   11 +
 documentation/sections/language.md            |   10 +
 documentation/sections/lexical_scope.md       |   15 +
 documentation/sections/literate.md            |    7 +
 documentation/sections/loops.md               |   47 +
 documentation/sections/modules.md             |   11 +
 documentation/sections/objects_and_arrays.md  |   19 +
 documentation/sections/operators.md           |  149 +
 documentation/sections/overview.md            |    7 +
 documentation/sections/resources.md           |   23 +
 documentation/sections/screencasts.md         |    5 +
 documentation/sections/scripts.md             |    7 +
 documentation/sections/slices.md              |   15 +
 documentation/sections/source_maps.md         |    5 +
 documentation/sections/splats.md              |    7 +
 documentation/sections/strings.md             |   27 +
 documentation/sections/switch.md              |   15 +
 .../sections/tagged_template_literals.md      |    9 +
 documentation/sections/try.md                 |    7 +
 documentation/sections/usage.md               |  179 +
 documentation/test.html                       |    2 +
 documentation/v1/body.html                    |  155 +
 documentation/v1/code.coffee                  |   25 +
 documentation/v1/docs.coffee                  |   92 +
 documentation/{css => v1}/docs.css            |   21 +-
 documentation/v1/scripts.html                 |    6 +
 documentation/v1/styles.html                  |    4 +
 documentation/{css => v1}/tomorrow.css        |   10 +-
 package.json                                  |    5 +-
 51 files changed, 4058 insertions(+), 5304 deletions(-)
 delete mode 100644 docs/v1/.gitignore
 create mode 100644 documentation/sections/books.md
 create mode 100644 documentation/sections/cake.md
 create mode 100644 documentation/sections/changelog.md
 create mode 100644 documentation/sections/chat.md
 create mode 100644 documentation/sections/classes.md
 create mode 100644 documentation/sections/comparisons.md
 create mode 100644 documentation/sections/conditionals.md
 create mode 100644 documentation/sections/destructuring.md
 create mode 100644 documentation/sections/embedded.md
 create mode 100644 documentation/sections/examples.md
 create mode 100644 documentation/sections/existential_operator.md
 create mode 100644 documentation/sections/expressions.md
 create mode 100644 documentation/sections/fat_arrow.md
 create mode 100644 documentation/sections/functions.md
 create mode 100644 documentation/sections/heregexes.md
 create mode 100644 documentation/sections/installation.md
 create mode 100644 documentation/sections/introduction.md
 create mode 100644 documentation/sections/language.md
 create mode 100644 documentation/sections/lexical_scope.md
 create mode 100644 documentation/sections/literate.md
 create mode 100644 documentation/sections/loops.md
 create mode 100644 documentation/sections/modules.md
 create mode 100644 documentation/sections/objects_and_arrays.md
 create mode 100644 documentation/sections/operators.md
 create mode 100644 documentation/sections/overview.md
 create mode 100644 documentation/sections/resources.md
 create mode 100644 documentation/sections/screencasts.md
 create mode 100644 documentation/sections/scripts.md
 create mode 100644 documentation/sections/slices.md
 create mode 100644 documentation/sections/source_maps.md
 create mode 100644 documentation/sections/splats.md
 create mode 100644 documentation/sections/strings.md
 create mode 100644 documentation/sections/switch.md
 create mode 100644 documentation/sections/tagged_template_literals.md
 create mode 100644 documentation/sections/try.md
 create mode 100644 documentation/sections/usage.md
 create mode 100644 documentation/v1/body.html
 create mode 100644 documentation/v1/code.coffee
 create mode 100644 documentation/v1/docs.coffee
 rename documentation/{css => v1}/docs.css (99%)
 create mode 100644 documentation/v1/scripts.html
 create mode 100644 documentation/v1/styles.html
 rename documentation/{css => v1}/tomorrow.css (87%)

diff --git a/.gitignore b/.gitignore
index 4ed75b7f..3749e736 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,8 +3,6 @@ presentation
 test.coffee
 test.litcoffee
 parser.output
-test/fixtures/underscore
 test/*.js
-examples/beautiful_code/parse.coffee
-*.gem
 /node_modules
+npm-debug.log
diff --git a/Cakefile b/Cakefile
index add7c9a7..be3f9cd3 100644
--- a/Cakefile
+++ b/Cakefile
@@ -25,7 +25,7 @@ header = """
 """
 
 # Used in folder names like docs/v1
-majorVersion = CoffeeScript.VERSION.split('.')[0]
+majorVersion = parseInt CoffeeScript.VERSION.split('.')[0], 10
 
 # Build the CoffeeScript language from source.
 build = (cb) ->
@@ -132,74 +132,96 @@ task 'build:browser', 'rebuild the merged script for inclusion in the browser',
 
 
 task 'doc:site', 'watch and continually rebuild the documentation for the website', ->
+  # Constants
+  indexFile = 'documentation/index.html'
+  versionedSourceFolder = "documentation/v#{majorVersion}"
+  sectionsSourceFolder = 'documentation/sections'
+  examplesSourceFolder = 'documentation/examples'
+  outputFolder = "docs/v#{majorVersion}"
+
   # Helpers
-  css = fs.readFileSync('./documentation/css/docs.css', 'utf-8') + '\n' +
-        fs.readFileSync('./documentation/css/tomorrow.css', 'utf-8')
+  releaseHeader = (date, version, prevVersion) ->
+    monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
 
-  logo = fs.readFileSync './documentation/images/logo.svg', 'utf-8'
+    formatDate = (date) ->
+      date.replace /^(\d\d\d\d)-(\d\d)-(\d\d)$/, (match, $1, $2, $3) ->
+        "#{monthNames[$2 - 1]} #{+$3}, #{$1}"
 
-  codeFor = ->
-    counter = 0
-    hljs = require 'highlight.js'
-    hljs.configure classPrefix: ''
-    (file, executable = false, showLoad = true) ->
-      counter++
-      return unless fs.existsSync "docs/v#{majorVersion}/examples/#{file}.js"
-      cs = fs.readFileSync "documentation/examples/#{file}.coffee", 'utf-8'
-      js = fs.readFileSync "docs/v#{majorVersion}/examples/#{file}.js", 'utf-8'
-      js = js.replace /^\/\/ generated.*?\n/i, ''
+    """
+      
+

+ #{prevVersion and "#{version}" or version} + +

+ """ - cshtml = "
#{hljs.highlight('coffeescript', cs).value}
" - # Temporary fix until highlight.js adds support for newer CoffeeScript keywords - # Added in https://github.com/isagalaev/highlight.js/pull/1357, awaiting release - if file in ['generator_iteration', 'generators', 'modules'] - cshtml = cshtml.replace /(yield|import|export|from|as|default) /g, '$1 ' - jshtml = "
#{hljs.highlight('javascript', js).value}
" - append = if executable is yes then '' else "alert(#{executable});".replace /"/g, '"' - if executable and executable isnt yes - cs.replace /(\S)\s*\Z/m, "$1\n\nalert #{executable}" - run = if executable is true then 'run' else "run: #{executable}" - name = "example#{counter}" - script = "" - load = if showLoad then "
load
" else '' - button = if executable then """
#{run}
""" else '' - "
#{cshtml}#{jshtml}#{script}#{load}#{button}
" + codeFor = require "./documentation/v#{majorVersion}/code.coffee" - monthNames = [ - 'January' - 'February' - 'March' - 'April' - 'May' - 'June' - 'July' - 'August' - 'September' - 'October' - 'November' - 'December' - ] + htmlFor = -> + marked = require 'marked' + markdownRenderer = new marked.Renderer() + markdownRenderer.heading = (text, level) -> + "#{text}" # Don’t let marked add an id + markdownRenderer.code = (code) -> + if code.indexOf('codeFor(') is 0 or code.indexOf('releaseHeader(') is 0 + "<%= #{code} %>" + else + "
#{code}
" # Default - formatDate = (date) -> - date.replace /^(\d\d\d\d)-(\d\d)-(\d\d)$/, (match, $1, $2, $3) -> - "#{monthNames[$2 - 1]} #{+$3}, #{$1}" + (file, bookmark) -> + md = fs.readFileSync "#{sectionsSourceFolder}/#{file}.md", 'utf-8' + md = md.replace /<%= releaseHeader %>/g, releaseHeader + md = md.replace /<%= majorVersion %>/g, majorVersion + md = md.replace /<%= fullVersion %>/g, CoffeeScript.VERSION + html = marked md, renderer: markdownRenderer + html = _.template(html) + codeFor: codeFor() + releaseHeader: releaseHeader - releaseHeader = (date, version, prevVersion) -> """ -
- - #{prevVersion and "#{version}" or version} - - - """ + include = -> + (file) -> + file = "#{versionedSourceFolder}/#{file}" if file.indexOf('/') is -1 + output = fs.readFileSync file, 'utf-8' + if /\.html$/.test(file) + render = _.template output + output = render + releaseHeader: releaseHeader + majorVersion: majorVersion + fullVersion: CoffeeScript.VERSION + htmlFor: htmlFor() + codeFor: codeFor() + include: include() + output + # Task + do renderIndex = -> + render = _.template fs.readFileSync(indexFile, 'utf-8') + output = render + include: include() + fs.writeFileSync "#{outputFolder}/index.html", output + log 'compiled', green, "#{indexFile} → #{outputFolder}/index.html" + try + fs.symlinkSync "v#{majorVersion}/index.html", 'docs/index.html' + catch exception + + for target in [indexFile, versionedSourceFolder, examplesSourceFolder, sectionsSourceFolder] + fs.watch target, interval: 200, renderIndex + log 'watching...' , green + + +task 'doc:test', 'watch and continually rebuild the browser-based tests', -> + # Constants + testFile = 'documentation/test.html' + testsSourceFolder = 'test' + outputFolder = "docs/v#{majorVersion}" + + # Included in test.html testHelpers = fs.readFileSync('test/support/helpers.coffee', 'utf-8').replace /exports\./g, '@' + # Helpers testsInScriptBlocks = -> output = '' - excludedTestFiles = ['error_messages.coffee'] - for filename in fs.readdirSync 'test' - continue if filename in excludedTestFiles - + for filename in fs.readdirSync testsSourceFolder if filename.indexOf('.coffee') isnt -1 type = 'coffeescript' else if filename.indexOf('.litcoffee') isnt -1 @@ -217,41 +239,16 @@ task 'doc:site', 'watch and continually rebuild the documentation for the websit output # Task - examplesSourceFolder = 'documentation/examples' - examplesOutputFolder = "docs/v#{majorVersion}/examples" - fs.mkdirSync examplesOutputFolder unless fs.existsSync examplesOutputFolder - do renderExamples = -> - execSync "bin/coffee -bc -o #{examplesOutputFolder} #{examplesSourceFolder}/*.coffee" - - indexFile = 'documentation/index.html' - do renderIndex = -> - render = _.template fs.readFileSync(indexFile, 'utf-8') - output = render - css: css - logo: logo - codeFor: codeFor() - releaseHeader: releaseHeader - majorVersion: majorVersion - fullVersion: CoffeeScript.VERSION - fs.writeFileSync "docs/v#{majorVersion}/index.html", output - log 'compiled', green, "#{indexFile} → docs/v#{majorVersion}/index.html" - - testFile = 'documentation/test.html' do renderTest = -> render = _.template fs.readFileSync(testFile, 'utf-8') output = render testHelpers: testHelpers tests: testsInScriptBlocks() - majorVersion: majorVersion - fs.writeFileSync "docs/v#{majorVersion}/test.html", output - log 'compiled', green, "#{testFile} → docs/v#{majorVersion}/test.html" + fs.writeFileSync "#{outputFolder}/test.html", output + log 'compiled', green, "#{testFile} → #{outputFolder}/test.html" - fs.watch examplesSourceFolder, interval: 200, -> - renderExamples() - renderIndex() - fs.watch indexFile, interval: 200, renderIndex - fs.watch testFile, interval: 200, renderTest - fs.watch 'test', interval: 200, renderTest + for target in [testFile, testsSourceFolder] + fs.watch target, interval: 200, renderTest log 'watching...' , green diff --git a/docs/v1/.gitignore b/docs/v1/.gitignore deleted file mode 100644 index d838da98..00000000 --- a/docs/v1/.gitignore +++ /dev/null @@ -1 +0,0 @@ -examples/ diff --git a/docs/v1/index.html b/docs/v1/index.html index 644fe035..61c5e485 100644 --- a/docs/v1/index.html +++ b/docs/v1/index.html @@ -1,20 +1,20 @@ - - CoffeeScript - - + +CoffeeScript + + - - - - - - + + + + + + - + + -
+
-
-
-