Mailspring/build/tasks/docs-render-task.coffee
Evan Morikawa 51602f69a5 refactor(env): new NylasEnv global
Converted all references of global atom to NylasEnv

Temporary rename atom.io

find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.io/temporaryAtomIoReplacement/g'

atom.config to NylasEnv.config

find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.config/NylasEnv.config/g'

atom.packages -> NylasEnv.packages

atom.commands -> NylasEnv.commands atom.getLoadSettings

find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.commands/NylasEnv.commands/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.getLoadSettings/NylasEnv.getLoadSettings/g'

More common atom methods

find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.styles/NylasEnv.styles/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.emitError/NylasEnv.emitError/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.inSpecMode/NylasEnv.inSpecMode/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.inDevMode/NylasEnv.inDevMode/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.getWindowType/NylasEnv.getWindowType/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.displayWindow/NylasEnv.displayWindow/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.quit/NylasEnv.quit/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.close/NylasEnv.close/g'

More atom method changes

find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.keymaps/NylasEnv.keymaps/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.hide/NylasEnv.hide/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.getCurrentWindow/NylasEnv.getCurrentWindow/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.menu/NylasEnv.menu/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.getConfigDirPath/NylasEnv.getConfigDirPath/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.isMainWindow/NylasEnv.isMainWindow/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.finishUnload/NylasEnv.finishUnload/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.isWorkWindow/NylasEnv.isWorkWindow/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.showSaveDialog/NylasEnv.showSaveDialog/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.append/NylasEnv.append/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.confirm/NylasEnv.confirm/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.clipboard/NylasEnv.clipboard/g'
find -E . -regex ".*\.(coffee|cjsx|js|md|cmd|es6)" -print0 | xargs -0 sed
-i "" 's/atom.getVersion/NylasEnv.getVersion/g'

More atom renaming

Rename atom methods

More atom methods

Fix grunt config variable

Change atom.cmd to N1.cmd

Rename atom.coffee and atom.js to nylas-env.coffee nylas-env.js

Fix atom global reference in specs manually

Fix atom requires

Change engine from atom to nylas

got rid of global/nylas-env

rename to nylas-win-bootup

Fix onWindowPropsChanged to onWindowPropsReceived

fix nylas-workspace

atom-text-editor to nylas-theme-wrap

atom-text-editor -> nylas-theme-wrap

Replacing atom keyword

AtomWindow -> NylasWindow

Replace Atom -> N1

Rename atom items

nylas.asar -> atom.asar

Remove more atom references

Remove 6to5 references

Remove license exception for atom
2015-11-17 16:41:20 -08:00

248 lines
7.7 KiB
CoffeeScript

path = require 'path'
Handlebars = require 'handlebars'
marked = require 'meta-marked'
fs = require 'fs-plus'
_ = require 'underscore'
marked.setOptions
highlight: (code) ->
require('highlight.js').highlightAuto(code).value
standardClassURLRoot = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/'
standardClasses = [
'string',
'object',
'array',
'function',
'number',
'date',
'error',
'boolean',
'null',
'undefined',
'json',
'set',
'map',
'typeerror',
'syntaxerror',
'referenceerror',
'rangeerror'
]
thirdPartyClasses = {
'react.component': 'https://facebook.github.io/react/docs/component-api.html',
'promise': 'https://github.com/petkaantonov/bluebird/blob/master/API.md',
'range': 'https://developer.mozilla.org/en-US/docs/Web/API/Range',
'selection': 'https://developer.mozilla.org/en-US/docs/Web/API/Selection',
'node': 'https://developer.mozilla.org/en-US/docs/Web/API/Node',
}
module.exports = (grunt) ->
{cp, mkdir, rm} = require('./task-helpers')(grunt)
relativePathForGuide = (filename) ->
filename[0..-4]+'.html'
relativePathForClass = (classname) ->
classname+'.html'
outputPathFor = (relativePath) ->
docsOutputDir = grunt.config.get('docsOutputDir')
path.join(docsOutputDir, relativePath)
processFields = (json, fields = [], tasks = []) ->
if json instanceof Array
for val in json
processFields(val, fields, tasks)
else
for key, val of json
if key in fields
for task in tasks
val = task(val)
json[key] = val
if _.isObject(val)
processFields(val, fields, tasks)
grunt.registerTask 'render-docs', 'Builds html from the API docs', ->
docsOutputDir = grunt.config.get('docsOutputDir')
# Parse API reference Markdown
classes = []
apiJsonPath = path.join(docsOutputDir, 'api.json')
apiJSON = JSON.parse(grunt.file.read(apiJsonPath))
for classname, contents of apiJSON.classes
# Parse a "@Section" out of the description if one is present
sectionRegex = /Section: ?([\w ]*)(?:$|\n)/
section = 'General'
match = sectionRegex.exec(contents.description)
if match
contents.description = contents.description.replace(match[0], '')
section = match[1].trim()
# Replace superClass "React" with "React.Component". The Coffeescript Lexer
# is so bad.
if contents.superClass is "React"
contents.superClass = "React.Component"
classes.push({
name: classname
documentation: contents
section: section
})
# Parse guide Markdown
guides = []
guidesPath = path.resolve(__dirname, '..', '..', 'docs')
fs.traverseTreeSync guidesPath, (file) ->
if path.extname(file) is '.md'
{html, meta} = marked(grunt.file.read(file))
filename = path.basename(file)
meta ||= {title: filename}
for key, val of meta
meta[key.toLowerCase()] = val
guides.push({
html: html
meta: meta
name: meta.title
filename: filename
link: relativePathForGuide(filename)
})
# Sort guides by the `Order` flag when present. Lower order, higher in list.
guides.sort (a, b) ->
(a.meta?.order ? 1000)/1 - (b.meta?.order ? 1000)/1
# Build Sidebar metadata we can hand off to each of the templates to
# generate the sidebar
sidebar = {sections: []}
sidebar.sections.push
name: 'Getting Started'
items: guides.filter ({meta}) -> meta.section is 'Getting Started'
sidebar.sections.push
name: 'Guides'
items: guides.filter ({meta}) -> meta.section is 'Guides'
sidebar.sections.push
name: 'Sample Code'
link: 'https://nylas.com/N1/examples'
external: true
referenceSections = {}
for klass in classes
section = referenceSections[klass.section]
if not section
section = {name: klass.section, classes: []}
referenceSections[klass.section] = section
section.classes.push(klass)
preferredSectionOrdering = ['General', 'Component Kit', 'Models', 'Stores', 'Database', 'Drafts', 'NylasEnv']
sorted = []
for key in preferredSectionOrdering
if referenceSections[key]
sorted.push(referenceSections[key])
delete referenceSections[key]
for key, val of referenceSections
sorted.push(val)
sidebar.sections.push
name: 'API Reference'
items: sorted.map ({name, classes}) ->
name: name
items: classes.map ({name}) -> {name: name, link: relativePathForClass(name) }
# Prepare to render by loading handlebars partials
templatesPath = path.resolve(__dirname, '..', '..', 'docs', 'templates')
grunt.file.recurse templatesPath, (abspath, root, subdir, filename) ->
if filename[0] is '_' and path.extname(filename) is '.html'
Handlebars.registerPartial(filename[0..-6], grunt.file.read(abspath))
# Render Helpers
knownClassnames = {}
for classname, val of apiJSON.classes
knownClassnames[classname.toLowerCase()] = val
knownGuides = {}
for guide in guides
knownGuides[guide.filename.toLowerCase()] = guide
expandTypeReferences = (val) ->
refRegex = /{([\w.]*)}/g
while (match = refRegex.exec(val)) isnt null
term = match[1].toLowerCase()
label = match[1]
url = false
if term in standardClasses
url = standardClassURLRoot+term
else if thirdPartyClasses[term]
url = thirdPartyClasses[term]
else if knownClassnames[term]
url = relativePathForClass(knownClassnames[term].name)
else if knownGuides[term]
label = knownGuides[term].meta.title
url = relativePathForGuide(knownGuides[term].filename)
else
console.warn("Cannot find class named #{term}")
if url
val = val.replace(match[0], "<a href='#{url}'>#{label}</a>")
val
expandFuncReferences = (val) ->
refRegex = /{([\w]*)?::([\w]*)}/g
while (match = refRegex.exec(val)) isnt null
[text, a, b] = match
url = false
if a and b
url = "#{relativePathForClass(a)}##{b}"
label = "#{a}::#{b}"
else
url = "##{b}"
label = "#{b}"
if url
val = val.replace(text, "<a href='#{url}'>#{label}</a>")
val
# Render sidebar json
grunt.file.write(outputPathFor('sidebar.json'), JSON.stringify(sidebar, null, 2))
# Render Class Pages
classTemplatePath = path.join(templatesPath, 'class.html')
classTemplate = Handlebars.compile(grunt.file.read(classTemplatePath))
for {name, documentation, section} in classes
# Recursively process `description` and `type` fields to process markdown,
# expand references to types, functions and other files.
processFields(documentation, ['description'], [marked.noMeta, expandTypeReferences, expandFuncReferences])
processFields(documentation, ['type'], [expandTypeReferences])
result = classTemplate({name, documentation, section, sidebar})
grunt.file.write(outputPathFor(relativePathForClass(name)), result)
# Render Guide Pages
guideTemplatePath = path.join(templatesPath, 'guide.html')
guideTemplate = Handlebars.compile(grunt.file.read(guideTemplatePath))
for {name, meta, html, filename} in guides
# Process the guide content to expand references to types, functions
for task in [expandTypeReferences, expandFuncReferences]
html = task(html)
result = guideTemplate({name, meta, html, sidebar})
grunt.file.write(outputPathFor(relativePathForGuide(filename)), result)
# Remove temp cjsx output
rm(outputPathFor("temp-cjsx"))