From b064daa1628b7b961041b0f346161efdd860ff0c Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sun, 1 May 2016 16:07:29 +0200 Subject: [PATCH 01/20] tools: add mock-y js-yaml dependency to doctool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a hack js-yaml module to the doctool dependencies that simply loads the one that’s included with eslint. This helps avoiding to check in the whole dependency tree into the core repo. PR-URL: https://github.com/nodejs/node/pull/6495 Reviewed-By: Robert Jefe Lindstaedt Reviewed-By: James M Snell Reviewed-By: Jeremiah Senkpiel --- tools/doc/node_modules/js-yaml/index.js | 15 +++++++++++++++ tools/doc/package.json | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tools/doc/node_modules/js-yaml/index.js diff --git a/tools/doc/node_modules/js-yaml/index.js b/tools/doc/node_modules/js-yaml/index.js new file mode 100644 index 00000000000000..620bc293ffe032 --- /dev/null +++ b/tools/doc/node_modules/js-yaml/index.js @@ -0,0 +1,15 @@ +'use strict'; + +// Hack to load the js-yaml module from eslint. +// No other reason than that it’s huge. + +const path = require('path'); + +const realJSYaml = path.resolve( + __dirname, '..', '..', '..', // tools/ + 'eslint', + 'node_modules', + 'js-yaml' +); + +module.exports = require(realJSYaml); diff --git a/tools/doc/package.json b/tools/doc/package.json index d87c9345b33f2e..0dda4b971cf14f 100644 --- a/tools/doc/package.json +++ b/tools/doc/package.json @@ -7,7 +7,8 @@ "node": ">=0.6.10" }, "dependencies": { - "marked": "~0.1.9" + "marked": "~0.1.9", + "js-yaml": "^3.5.2" }, "devDependencies": {}, "optionalDependencies": {}, From f6b5db663885a95103626e21affcb21f3e704863 Mon Sep 17 00:00:00 2001 From: Tristian Flanagan Date: Fri, 13 Nov 2015 21:40:38 -0500 Subject: [PATCH 02/20] tools: parse documentation metadata This commit introduces the Documentation YAML metadata concept to the documentation. - Parses added or Added for HTML - Parses all data for JSON Ref: https://github.com/nodejs/node/pull/3867 Ref: https://github.com/nodejs/node/issues/3713 Ref: https://github.com/nodejs/node/issues/6470 PR-URL: https://github.com/nodejs/node/pull/6495 Reviewed-By: Robert Jefe Lindstaedt Reviewed-By: James M Snell Reviewed-By: Jeremiah Senkpiel --- doc/api_assets/style.css | 13 +++++++++++++ tools/doc/README.md | 27 +++++++++++++++++++++++++++ tools/doc/common.js | 21 +++++++++++++++++++++ tools/doc/generate.js | 12 ++++++------ tools/doc/html.js | 26 +++++++++++++++++++++----- tools/doc/json.js | 8 +++++++- 6 files changed, 95 insertions(+), 12 deletions(-) create mode 100644 tools/doc/common.js diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css index a8e4b32611164b..a9dec759fa85df 100644 --- a/doc/api_assets/style.css +++ b/doc/api_assets/style.css @@ -103,6 +103,19 @@ em code { background-color: #0084B6; } +.api_metadata { + font-size: .75em; + margin-bottom: 1em; +} + +.api_metadata span { + margin-right: 1em; +} + +.api_metadata span:last-child { + margin-right: 0px; +} + ul.plain { list-style: none; } diff --git a/tools/doc/README.md b/tools/doc/README.md index fd041f001e6931..22bd053ed1b058 100644 --- a/tools/doc/README.md +++ b/tools/doc/README.md @@ -6,18 +6,27 @@ Each type of heading has a description block. ## module + Stability: 3 - Stable description and examples. ### module.property + * Type description of the property. ### module.someFunction(x, y, [z=100]) + * `x` {String} the description of the string * `y` {Boolean} Should I stay or should I go? @@ -26,6 +35,9 @@ Each type of heading has a description block. A description of the function. ### Event: 'blerg' + * Argument: SomeClass object. @@ -33,10 +45,16 @@ Each type of heading has a description block. only exception. ## Class: SomeClass + description of the class. ### Class Method: SomeClass.classMethod(anArg) + * `anArg` {Object} Just an argument * `field` {String} anArg can have this field. @@ -46,16 +64,25 @@ Each type of heading has a description block. Description of the method for humans. ### someClass.nextSibling() + * Return: {SomeClass object | null} The next someClass in line. ### someClass.someProperty + * String The indication of what someProperty is. ### Event: 'grelb' + * `isBlerg` {Boolean} diff --git a/tools/doc/common.js b/tools/doc/common.js new file mode 100644 index 00000000000000..72bb1eb74946a0 --- /dev/null +++ b/tools/doc/common.js @@ -0,0 +1,21 @@ +'use strict'; + +const yaml = require('js-yaml'); + +function isYAMLBlock(text) { + return !!text.match(/^$/, ''); + + // js-yaml.safeLoad() throws on error + return yaml.safeLoad(text); +} + +exports.extractAndParseYAML = extractAndParseYAML; diff --git a/tools/doc/generate.js b/tools/doc/generate.js index ff14cbd5e8979b..9048b484ce4e07 100644 --- a/tools/doc/generate.js +++ b/tools/doc/generate.js @@ -1,15 +1,15 @@ 'use strict'; -var processIncludes = require('./preprocess.js'); -var fs = require('fs'); +const processIncludes = require('./preprocess.js'); +const fs = require('fs'); // parse the args. // Don't use nopt or whatever for this. It's simple enough. -var args = process.argv.slice(2); -var format = 'json'; -var template = null; -var inputFile = null; +const args = process.argv.slice(2); +let format = 'json'; +let template = null; +let inputFile = null; args.forEach(function(arg) { if (!arg.match(/^\-\-/)) { diff --git a/tools/doc/html.js b/tools/doc/html.js index 68ccf976b6c1f8..d31125caaa05e0 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -1,10 +1,11 @@ 'use strict'; -var fs = require('fs'); -var marked = require('marked'); -var path = require('path'); -var preprocess = require('./preprocess.js'); -var typeParser = require('./type-parser.js'); +const common = require('./common.js'); +const fs = require('fs'); +const marked = require('marked'); +const path = require('path'); +const preprocess = require('./preprocess.js'); +const typeParser = require('./type-parser.js'); module.exports = toHTML; @@ -148,6 +149,9 @@ function parseLists(input) { output.push(tok); return; } + if (tok.type === 'html' && common.isYAMLBlock(tok.text)) { + tok.text = parseYAML(tok.text); + } state = null; output.push(tok); return; @@ -174,6 +178,18 @@ function parseLists(input) { return output; } +function parseYAML(text) { + const meta = common.extractAndParseYAML(text); + let html = ''; +} // Syscalls which appear in the docs, but which only exist in BSD / OSX var BSD_ONLY_SYSCALLS = new Set(['lchmod']); diff --git a/tools/doc/json.js b/tools/doc/json.js index 3d08026daaabd8..84a042f4709375 100644 --- a/tools/doc/json.js +++ b/tools/doc/json.js @@ -5,7 +5,8 @@ module.exports = doJSON; // Take the lexed input, and return a JSON-encoded object // A module looks like this: https://gist.github.com/1777387 -var marked = require('marked'); +const common = require('./common.js'); +const marked = require('marked'); function doJSON(input, filename, cb) { var root = {source: filename}; @@ -91,6 +92,8 @@ function doJSON(input, filename, cb) { current.list = current.list || []; current.list.push(tok); current.list.level = 1; + } else if (type === 'html' && common.isYAMLBlock(tok.text)) { + current.meta = parseYAML(tok.text); } else { current.desc = current.desc || []; if (!Array.isArray(current.desc)) { @@ -274,6 +277,9 @@ function processList(section) { delete section.list; } +function parseYAML(text) { + return common.extractAndParseYAML(text); +} // textRaw = "someobject.someMethod(a[, b=100][, c])" function parseSignature(text, sig) { From de131cb106095834d43704dff80d06268c245c29 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sun, 1 May 2016 01:17:34 +0200 Subject: [PATCH 03/20] test,tools: test yaml parsing of doctool Add checks that make sure the doctool parses metadata correctly. PR-URL: https://github.com/nodejs/node/pull/6495 Reviewed-By: Robert Jefe Lindstaedt Reviewed-By: James M Snell Reviewed-By: Jeremiah Senkpiel --- test/doctool/test-doctool-html.js | 20 +++++++++++++ test/doctool/test-doctool-json.js | 47 +++++++++++++++++++++++++++++++ test/fixtures/doc_with_yaml.md | 21 ++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 test/fixtures/doc_with_yaml.md diff --git a/test/doctool/test-doctool-html.js b/test/doctool/test-doctool-html.js index afd89489f11ed4..7aa88414515681 100644 --- a/test/doctool/test-doctool-html.js +++ b/test/doctool/test-doctool-html.js @@ -27,6 +27,26 @@ const testData = [ 'Reference/Global_Objects/Array" class="type"><Array>' + '' }, + { + 'file': common.fixturesDir + '/doc_with_yaml.md', + 'html': '

Sample Markdown with YAML info' + + '#

' + + '

Foobar#

' + + ' ' + + '

Describe Foobar in more detail here.

' + + '

Deprecated thingy#' + + '

' + + '

Describe ' + + 'Deprecated thingy in more detail here.

' + + '

Something#

' + + ' ' + + '

Describe Something in more detail here. ' + + '

' + }, ]; testData.forEach(function(item) { diff --git a/test/doctool/test-doctool-json.js b/test/doctool/test-doctool-json.js index 31e260fcb02d43..ed7eb64a0e961d 100644 --- a/test/doctool/test-doctool-json.js +++ b/test/doctool/test-doctool-json.js @@ -64,6 +64,53 @@ var testData = [ 'displayName': 'Title' } ] } + }, + { + 'file': common.fixturesDir + '/doc_with_yaml.md', + 'json': { + 'source': 'foo', + 'modules': [ + { + 'textRaw': 'Sample Markdown with YAML info', + 'name': 'sample_markdown_with_yaml_info', + 'modules': [ + { + 'textRaw': 'Foobar', + 'name': 'foobar', + 'meta': { + 'added': 'v1.0.0' + }, + 'desc': '

Describe Foobar in more detail ' + + 'here.\n\n

\n', + 'type': 'module', + 'displayName': 'Foobar' + }, + { + 'textRaw': 'Deprecated thingy', + 'name': 'deprecated_thingy', + 'meta': { + 'added': 'v1.0.0', + 'deprecated': 'v2.0.0' + }, + 'desc': '

Describe Deprecated thingy in more ' + + 'detail here.\n\n

\n', + 'type': 'module', + 'displayName': 'Deprecated thingy' + }, + { + 'textRaw': 'Something', + 'name': 'something', + 'desc': '\n\n

' + + 'Describe Something in more detail here.\n

\n', + 'type': 'module', + 'displayName': 'Something' + } + ], + 'type': 'module', + 'displayName': 'Sample Markdown with YAML info' + } + ] + } } ]; diff --git a/test/fixtures/doc_with_yaml.md b/test/fixtures/doc_with_yaml.md new file mode 100644 index 00000000000000..03411d5bf7b295 --- /dev/null +++ b/test/fixtures/doc_with_yaml.md @@ -0,0 +1,21 @@ +# Sample Markdown with YAML info + +## Foobar + + +Describe `Foobar` in more detail here. + +## Deprecated thingy + + +Describe `Deprecated thingy` in more detail here. + +## Something + + +Describe `Something` in more detail here. From cab73be5bfebc2bedf05b018ad4e7246af8e1989 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sun, 1 May 2016 01:51:38 +0200 Subject: [PATCH 04/20] tools: allow multiple added: version entries Allow multiple `added:` version entries, since semver-minors can trickle down to previous major versions, and thus features may have been added in multiple versions. Also include `deprecated:` entries and apply the same logic to them for consistency. Stylize the added HTML as `Added in:` and `Deprecated since:`. PR-URL: https://github.com/nodejs/node/pull/6495 Reviewed-By: Robert Jefe Lindstaedt Reviewed-By: James M Snell Reviewed-By: Jeremiah Senkpiel --- test/doctool/test-doctool-html.js | 9 +++++++-- test/doctool/test-doctool-json.js | 17 ++++++++++++++--- test/fixtures/doc_with_yaml.md | 9 +++++++++ tools/doc/common.js | 21 ++++++++++++++++++++- tools/doc/html.js | 13 ++++++++----- 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/test/doctool/test-doctool-html.js b/test/doctool/test-doctool-html.js index 7aa88414515681..1eb96751cc0adb 100644 --- a/test/doctool/test-doctool-html.js +++ b/test/doctool/test-doctool-html.js @@ -34,12 +34,17 @@ const testData = [ ' id="foo_sample_markdown_with_yaml_info">#' + '

Foobar#

' + - ' ' + + ' ' + '

Describe Foobar in more detail here.

' + + '

Foobar II#

' + + ' ' + + '

Describe Foobar II in more detail here.

' + '

Deprecated thingy#' + '

' + - '

Describe ' + + '

Describe ' + 'Deprecated thingy in more detail here.

' + '

Something#

' + diff --git a/test/doctool/test-doctool-json.js b/test/doctool/test-doctool-json.js index ed7eb64a0e961d..83563cb2d2cdac 100644 --- a/test/doctool/test-doctool-json.js +++ b/test/doctool/test-doctool-json.js @@ -78,19 +78,30 @@ var testData = [ 'textRaw': 'Foobar', 'name': 'foobar', 'meta': { - 'added': 'v1.0.0' + 'added': ['v1.0.0'] }, 'desc': '

Describe Foobar in more detail ' + 'here.\n\n

\n', 'type': 'module', 'displayName': 'Foobar' }, + { + 'textRaw': 'Foobar II', + 'name': 'foobar_ii', + 'meta': { + 'added': ['v5.3.0', 'v4.2.0'] + }, + 'desc': '

Describe Foobar II in more detail ' + + 'here.\n\n

\n', + 'type': 'module', + 'displayName': 'Foobar II' + }, { 'textRaw': 'Deprecated thingy', 'name': 'deprecated_thingy', 'meta': { - 'added': 'v1.0.0', - 'deprecated': 'v2.0.0' + 'added': ['v1.0.0'], + 'deprecated': ['v2.0.0'] }, 'desc': '

Describe Deprecated thingy in more ' + 'detail here.\n\n

\n', diff --git a/test/fixtures/doc_with_yaml.md b/test/fixtures/doc_with_yaml.md index 03411d5bf7b295..493c2e7e4268b2 100644 --- a/test/fixtures/doc_with_yaml.md +++ b/test/fixtures/doc_with_yaml.md @@ -7,6 +7,15 @@ added: v1.0.0 Describe `Foobar` in more detail here. +## Foobar II + + +Describe `Foobar II` in more detail here. + ## Deprecated thingy $/, ''); // js-yaml.safeLoad() throws on error - return yaml.safeLoad(text); + const meta = yaml.safeLoad(text); + + const added = meta.added || meta.Added; + if (added) { + // Since semver-minors can trickle down to previous major versions, + // features may have been added in multiple versions. + meta.added = arrify(added); + } + + const deprecated = meta.deprecated || meta.Deprecated; + if (deprecated) { + // Treat deprecated like added for consistency. + meta.deprecated = arrify(deprecated); + } + + return meta; } exports.extractAndParseYAML = extractAndParseYAML; diff --git a/tools/doc/html.js b/tools/doc/html.js index d31125caaa05e0..977e0834d48304 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -180,15 +180,18 @@ function parseLists(input) { function parseYAML(text) { const meta = common.extractAndParseYAML(text); - let html = ''); + return html.join('\n'); } // Syscalls which appear in the docs, but which only exist in BSD / OSX From fcb2735af615d4505f809ee6961d6f8a3d991767 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Tue, 26 Apr 2016 07:44:37 +0800 Subject: [PATCH 05/20] tools: update marked dependency Update module marked. Customize renderer to remove id from heading. PR-URL: https://github.com/nodejs/node/pull/6396 Reviewed-By: Roman Reiss Reviewed-By: Anna Henningsen --- test/doctool/test-doctool-json.js | 10 +- tools/doc/html.js | 9 + tools/doc/json.js | 9 + tools/doc/node_modules/marked/.travis.yml | 5 + tools/doc/node_modules/marked/Gulpfile.js | 22 + tools/doc/node_modules/marked/LICENSE | 2 +- tools/doc/node_modules/marked/Makefile | 5 +- tools/doc/node_modules/marked/README.md | 413 +++++- tools/doc/node_modules/marked/bin/marked | 146 ++- tools/doc/node_modules/marked/bower.json | 24 + tools/doc/node_modules/marked/component.json | 10 + tools/doc/node_modules/marked/doc/broken.md | 426 ++++++ tools/doc/node_modules/marked/doc/todo.md | 2 + tools/doc/node_modules/marked/lib/marked.js | 1217 +++++++++++++----- tools/doc/node_modules/marked/man/marked.1 | 80 +- tools/doc/node_modules/marked/marked.min.js | 6 + tools/doc/node_modules/marked/package.json | 102 +- tools/doc/package.json | 2 +- 18 files changed, 2052 insertions(+), 438 deletions(-) create mode 100644 tools/doc/node_modules/marked/.travis.yml create mode 100644 tools/doc/node_modules/marked/Gulpfile.js create mode 100644 tools/doc/node_modules/marked/bower.json create mode 100644 tools/doc/node_modules/marked/component.json create mode 100644 tools/doc/node_modules/marked/doc/broken.md create mode 100644 tools/doc/node_modules/marked/doc/todo.md create mode 100644 tools/doc/node_modules/marked/marked.min.js diff --git a/test/doctool/test-doctool-json.js b/test/doctool/test-doctool-json.js index 83563cb2d2cdac..f57fcd94752871 100644 --- a/test/doctool/test-doctool-json.js +++ b/test/doctool/test-doctool-json.js @@ -81,7 +81,7 @@ var testData = [ 'added': ['v1.0.0'] }, 'desc': '

Describe Foobar in more detail ' + - 'here.\n\n

\n', + 'here.

\n', 'type': 'module', 'displayName': 'Foobar' }, @@ -92,7 +92,7 @@ var testData = [ 'added': ['v5.3.0', 'v4.2.0'] }, 'desc': '

Describe Foobar II in more detail ' + - 'here.\n\n

\n', + 'here.

\n', 'type': 'module', 'displayName': 'Foobar II' }, @@ -104,15 +104,15 @@ var testData = [ 'deprecated': ['v2.0.0'] }, 'desc': '

Describe Deprecated thingy in more ' + - 'detail here.\n\n

\n', + 'detail here.

\n', 'type': 'module', 'displayName': 'Deprecated thingy' }, { 'textRaw': 'Something', 'name': 'something', - 'desc': '\n\n

' + - 'Describe Something in more detail here.\n

\n', + 'desc': '\n

' + + 'Describe Something in more detail here.

\n', 'type': 'module', 'displayName': 'Something' } diff --git a/tools/doc/html.js b/tools/doc/html.js index 977e0834d48304..27e9bee17bccec 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -9,6 +9,15 @@ const typeParser = require('./type-parser.js'); module.exports = toHTML; +// customized heading without id attribute +var renderer = new marked.Renderer(); +renderer.heading = function(text, level) { + return '' + text + '\n'; +}; +marked.setOptions({ + renderer: renderer +}); + // TODO(chrisdickinson): never stop vomitting / fix this. var gtocPath = path.resolve(path.join( __dirname, diff --git a/tools/doc/json.js b/tools/doc/json.js index 84a042f4709375..33bde6515b1235 100644 --- a/tools/doc/json.js +++ b/tools/doc/json.js @@ -8,6 +8,15 @@ module.exports = doJSON; const common = require('./common.js'); const marked = require('marked'); +// customized heading without id attribute +var renderer = new marked.Renderer(); +renderer.heading = function(text, level) { + return '' + text + '\n'; +}; +marked.setOptions({ + renderer: renderer +}); + function doJSON(input, filename, cb) { var root = {source: filename}; var stack = [root]; diff --git a/tools/doc/node_modules/marked/.travis.yml b/tools/doc/node_modules/marked/.travis.yml new file mode 100644 index 00000000000000..60d00ce140f37d --- /dev/null +++ b/tools/doc/node_modules/marked/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.10" + - "0.8" + - "0.6" diff --git a/tools/doc/node_modules/marked/Gulpfile.js b/tools/doc/node_modules/marked/Gulpfile.js new file mode 100644 index 00000000000000..cebc16a650b0e9 --- /dev/null +++ b/tools/doc/node_modules/marked/Gulpfile.js @@ -0,0 +1,22 @@ +var gulp = require('gulp'); +var uglify = require('gulp-uglify'); +var concat = require('gulp-concat'); + +var preserveFirstComment = function() { + var set = false; + + return function() { + if (set) return false; + set = true; + return true; + }; +}; + +gulp.task('uglify', function() { + gulp.src('lib/marked.js') + .pipe(uglify({preserveComments: preserveFirstComment()})) + .pipe(concat('marked.min.js')) + .pipe(gulp.dest('.')); +}); + +gulp.task('default', ['uglify']); diff --git a/tools/doc/node_modules/marked/LICENSE b/tools/doc/node_modules/marked/LICENSE index 40597477c63bea..a7b812ed618f11 100644 --- a/tools/doc/node_modules/marked/LICENSE +++ b/tools/doc/node_modules/marked/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011-2012, Christopher Jeffrey (https://github.com/chjj/) +Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/tools/doc/node_modules/marked/Makefile b/tools/doc/node_modules/marked/Makefile index 76904000b5ee98..d9349f07996d34 100644 --- a/tools/doc/node_modules/marked/Makefile +++ b/tools/doc/node_modules/marked/Makefile @@ -1,9 +1,12 @@ all: @cp lib/marked.js marked.js - @uglifyjs -o marked.min.js marked.js + @uglifyjs --comments '/\*[^\0]+?Copyright[^\0]+?\*/' -o marked.min.js lib/marked.js clean: @rm marked.js @rm marked.min.js +bench: + @node test --bench + .PHONY: clean all diff --git a/tools/doc/node_modules/marked/README.md b/tools/doc/node_modules/marked/README.md index 1a0747c0d7e879..efa71aaaabc849 100644 --- a/tools/doc/node_modules/marked/README.md +++ b/tools/doc/node_modules/marked/README.md @@ -1,47 +1,299 @@ # marked -A full-featured markdown parser and compiler. -Built for speed. +> A full-featured markdown parser and compiler, written in JavaScript. Built +> for speed. -## Benchmarks +[![NPM version](https://badge.fury.io/js/marked.png)][badge] -node v0.4.x +## Install ``` bash -$ node test --bench -marked completed in 12071ms. -showdown (reuse converter) completed in 27387ms. -showdown (new converter) completed in 75617ms. -markdown-js completed in 70069ms. +npm install marked --save ``` -node v0.6.x +## Usage + +Minimal usage: -``` bash -$ node test --bench -marked completed in 6485ms. -marked (with gfm) completed in 7466ms. -discount completed in 7169ms. -showdown (reuse converter) completed in 15937ms. -showdown (new converter) completed in 18279ms. -markdown-js completed in 23572ms. +```js +var marked = require('marked'); +console.log(marked('I am using __markdown__.')); +// Outputs:

I am using markdown.

``` -__Marked is now faster than Discount, which is written in C.__ +Example setting options with default values: + +```js +var marked = require('marked'); +marked.setOptions({ + renderer: new marked.Renderer(), + gfm: true, + tables: true, + breaks: false, + pedantic: false, + sanitize: true, + smartLists: true, + smartypants: false +}); + +console.log(marked('I am using __markdown__.')); +``` -For those feeling skeptical: These benchmarks run the entire markdown test suite -1000 times. The test suite tests every feature. It doesn't cater to specific -aspects. +### Browser + +```html + + + + + Marked in the browser + + + +
+ + + +``` -Benchmarks for other engines to come (?). +## marked(markdownString [,options] [,callback]) -## Install +### markdownString + +Type: `string` + +String of markdown source to be compiled. + +### options + +Type: `object` + +Hash of options. Can also be set using the `marked.setOptions` method as seen +above. + +### callback + +Type: `function` + +Function called when the `markdownString` has been fully parsed when using +async highlighting. If the `options` argument is omitted, this can be used as +the second argument. + +## Options + +### highlight + +Type: `function` + +A function to highlight code blocks. The first example below uses async highlighting with +[node-pygmentize-bundled][pygmentize], and the second is a synchronous example using +[highlight.js][highlight]: + +```js +var marked = require('marked'); + +var markdownString = '```js\n console.log("hello"); \n```'; + +// Async highlighting with pygmentize-bundled +marked.setOptions({ + highlight: function (code, lang, callback) { + require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) { + callback(err, result.toString()); + }); + } +}); + +// Using async version of marked +marked(markdownString, function (err, content) { + if (err) throw err; + console.log(content); +}); + +// Synchronous highlighting with highlight.js +marked.setOptions({ + highlight: function (code) { + return require('highlight.js').highlightAuto(code).value; + } +}); + +console.log(marked(markdownString)); +``` + +#### highlight arguments + +`code` + +Type: `string` + +The section of code to pass to the highlighter. + +`lang` + +Type: `string` + +The programming language specified in the code block. + +`callback` + +Type: `function` + +The callback function to call when using an async highlighter. + +### renderer + +Type: `object` +Default: `new Renderer()` + +An object containing functions to render tokens to HTML. + +#### Overriding renderer methods + +The renderer option allows you to render tokens in a custom manner. Here is an +example of overriding the default heading token rendering by adding an embedded anchor tag like on GitHub: + +```javascript +var marked = require('marked'); +var renderer = new marked.Renderer(); + +renderer.heading = function (text, level) { + var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-'); + + return '' + + text + ''; +}, + +console.log(marked('# heading+', { renderer: renderer })); +``` +This code will output the following HTML: +```html +

+ + + + heading+ +

+``` + +#### Block level renderer methods + +- code(*string* code, *string* language) +- blockquote(*string* quote) +- html(*string* html) +- heading(*string* text, *number* level) +- hr() +- list(*string* body, *boolean* ordered) +- listitem(*string* text) +- paragraph(*string* text) +- table(*string* header, *string* body) +- tablerow(*string* content) +- tablecell(*string* content, *object* flags) + +`flags` has the following properties: + +```js +{ + header: true || false, + align: 'center' || 'left' || 'right' +} +``` + +#### Inline level renderer methods + +- strong(*string* text) +- em(*string* text) +- codespan(*string* code) +- br() +- del(*string* text) +- link(*string* href, *string* title, *string* text) +- image(*string* href, *string* title, *string* text) + +### gfm + +Type: `boolean` +Default: `true` + +Enable [GitHub flavored markdown][gfm]. + +### tables + +Type: `boolean` +Default: `true` + +Enable GFM [tables][tables]. +This option requires the `gfm` option to be true. + +### breaks + +Type: `boolean` +Default: `false` + +Enable GFM [line breaks][breaks]. +This option requires the `gfm` option to be true. + +### pedantic + +Type: `boolean` +Default: `false` + +Conform to obscure parts of `markdown.pl` as much as possible. Don't fix any of +the original markdown bugs or poor behavior. + +### sanitize + +Type: `boolean` +Default: `false` + +Sanitize the output. Ignore any HTML that has been input. + +### smartLists + +Type: `boolean` +Default: `true` + +Use smarter list behavior than the original markdown. May eventually be +default with the old behavior moved into `pedantic`. + +### smartypants + +Type: `boolean` +Default: `false` + +Use "smart" typograhic punctuation for things like quotes and dashes. + +## Access to lexer and parser + +You also have direct access to the lexer and parser if you so desire. + +``` js +var tokens = marked.lexer(text, options); +console.log(marked.parser(tokens)); +``` + +``` js +var lexer = new marked.Lexer(options); +var tokens = lexer.lex(text); +console.log(tokens); +console.log(lexer.rules); +``` + +## CLI ``` bash -$ npm install marked +$ marked -o hello.html +hello world +^D +$ cat hello.html +

hello world

``` -## Another javascript markdown parser +## Philosophy behind marked The point of marked was to create a markdown compiler where it was possible to frequently parse huge chunks of markdown without having to worry about @@ -58,78 +310,97 @@ of performance, but did not in order to be exactly what you expect in terms of a markdown rendering. In fact, this is why marked could be considered at a disadvantage in the benchmarks above. -Along with implementing every markdown feature, marked also implements -[GFM features](http://github.github.com/github-flavored-markdown/). +Along with implementing every markdown feature, marked also implements [GFM +features][gfmf]. -## Usage +## Benchmarks -``` js -var marked = require('marked'); -console.log(marked('i am using __markdown__.')); +node v0.8.x + +``` bash +$ node test --bench +marked completed in 3411ms. +marked (gfm) completed in 3727ms. +marked (pedantic) completed in 3201ms. +robotskirt completed in 808ms. +showdown (reuse converter) completed in 11954ms. +showdown (new converter) completed in 17774ms. +markdown-js completed in 17191ms. ``` +__Marked is now faster than Discount, which is written in C.__ + +For those feeling skeptical: These benchmarks run the entire markdown test suite 1000 times. The test suite tests every feature. It doesn't cater to specific aspects. + +### Pro level + You also have direct access to the lexer and parser if you so desire. ``` js -var tokens = marked.lexer(str); +var tokens = marked.lexer(text, options); console.log(marked.parser(tokens)); ``` +``` js +var lexer = new marked.Lexer(options); +var tokens = lexer.lex(text); +console.log(tokens); +console.log(lexer.rules); +``` + ``` bash $ node > require('marked').lexer('> i am using marked.') [ { type: 'blockquote_start' }, - { type: 'text', text: ' i am using marked.' }, + { type: 'paragraph', + text: 'i am using marked.' }, { type: 'blockquote_end' }, links: {} ] ``` -## CLI +## Running Tests & Contributing -``` bash -$ marked -o hello.html -hello world -^D -$ cat hello.html -

hello world

-``` +If you want to submit a pull request, make sure your changes pass the test +suite. If you're adding a new feature, be sure to add your own test. -## Syntax Highlighting +The marked test suite is set up slightly strangely: `test/new` is for all tests +that are not part of the original markdown.pl test suite (this is where your +test should go if you make one). `test/original` is only for the original +markdown.pl tests. `test/tests` houses both types of tests after they have been +combined and moved/generated by running `node test --fix` or `marked --test +--fix`. -Marked has an interface that allows for a syntax highlighter to highlight code -blocks before they're output. +In other words, if you have a test to add, add it to `test/new/` and then +regenerate the tests with `node test --fix`. Commit the result. If your test +uses a certain feature, for example, maybe it assumes GFM is *not* enabled, you +can add `.nogfm` to the filename. So, `my-test.text` becomes +`my-test.nogfm.text`. You can do this with any marked option. Say you want +line breaks and smartypants enabled, your filename should be: +`my-test.breaks.smartypants.text`. -Example implementation: +To run the tests: -``` js -var highlight = require('my-syntax-highlighter') - , marked_ = require('marked'); - -var marked = function(text) { - var tokens = marked_.lexer(text) - , l = tokens.length - , i = 0 - , token; - - for (; i < l; i++) { - token = tokens[i]; - if (token.type === 'code') { - token.text = highlight(token.text, token.lang); - // marked should not escape this - token.escaped = true; - } - } - - text = marked_.parser(tokens); +``` bash +cd marked/ +node test +``` - return text; -}; +### Contribution and License Agreement -module.exports = marked; -``` +If you contribute code to this project, you are implicitly allowing your code +to be distributed under the MIT license. You are also implicitly verifying that +all code is your original work. `` ## License -Copyright (c) 2011-2012, Christopher Jeffrey. (MIT License) +Copyright (c) 2011-2014, Christopher Jeffrey. (MIT License) See LICENSE for more info. + +[gfm]: https://help.github.com/articles/github-flavored-markdown +[gfmf]: http://github.github.com/github-flavored-markdown/ +[pygmentize]: https://github.com/rvagg/node-pygmentize-bundled +[highlight]: https://github.com/isagalaev/highlight.js +[badge]: http://badge.fury.io/js/marked +[tables]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables +[breaks]: https://help.github.com/articles/github-flavored-markdown#newlines diff --git a/tools/doc/node_modules/marked/bin/marked b/tools/doc/node_modules/marked/bin/marked index 7d00504ed16803..64254fc3eb2e08 100755 --- a/tools/doc/node_modules/marked/bin/marked +++ b/tools/doc/node_modules/marked/bin/marked @@ -2,7 +2,7 @@ /** * Marked CLI - * Copyright (c) 2011-2012, Christopher Jeffrey (MIT License) + * Copyright (c) 2011-2013, Christopher Jeffrey (MIT License) */ var fs = require('fs') @@ -13,7 +13,7 @@ var fs = require('fs') * Man Page */ -var help = function() { +function help() { var spawn = require('child_process').spawn; var options = { @@ -26,32 +26,54 @@ var help = function() { spawn('man', [__dirname + '/../man/marked.1'], options); -}; +} /** * Main */ -var main = function(argv) { +function main(argv, callback) { var files = [] - , data = '' + , options = {} , input , output , arg - , tokens; + , tokens + , opt; - var getarg = function() { + function getarg() { var arg = argv.shift(); - arg = arg.split('='); - if (arg.length > 1) { - argv.unshift(arg.slice(1).join('=')); + + if (arg.indexOf('--') === 0) { + // e.g. --opt + arg = arg.split('='); + if (arg.length > 1) { + // e.g. --opt=val + argv.unshift(arg.slice(1).join('=')); + } + arg = arg[0]; + } else if (arg[0] === '-') { + if (arg.length > 2) { + // e.g. -abc + argv = arg.substring(1).split('').map(function(ch) { + return '-' + ch; + }).concat(argv); + arg = argv.shift(); + } else { + // e.g. -a + } + } else { + // e.g. foo } - return arg[0]; - }; + + return arg; + } while (argv.length) { arg = getarg(); switch (arg) { + case '--test': + return require('../test').main(process.argv.slice()); case '-o': case '--output': output = argv.shift(); @@ -68,48 +90,98 @@ var main = function(argv) { case '--help': return help(); default: - files.push(arg); + if (arg.indexOf('--') === 0) { + opt = camelize(arg.replace(/^--(no-)?/, '')); + if (!marked.defaults.hasOwnProperty(opt)) { + continue; + } + if (arg.indexOf('--no-') === 0) { + options[opt] = typeof marked.defaults[opt] !== 'boolean' + ? null + : false; + } else { + options[opt] = typeof marked.defaults[opt] !== 'boolean' + ? argv.shift() + : true; + } + } else { + files.push(arg); + } break; } } - if (!input) { - if (files.length <= 2) { - var stdin = process.stdin; - - stdin.setEncoding('utf8'); - stdin.resume(); - - stdin.on('data', function(text) { - data += text; - }); - - stdin.on('end', write); - - return; + function getData(callback) { + if (!input) { + if (files.length <= 2) { + return getStdin(callback); + } + input = files.pop(); } - input = files.pop(); + return fs.readFile(input, 'utf8', callback); } - data = fs.readFileSync(input, 'utf8'); - write(); + return getData(function(err, data) { + if (err) return callback(err); - function write() { data = tokens - ? JSON.stringify(marked.lexer(data), null, 2) - : marked(data); + ? JSON.stringify(marked.lexer(data, options), null, 2) + : marked(data, options); if (!output) { process.stdout.write(data + '\n'); - } else { - fs.writeFileSync(output, data); + return callback(); } + + return fs.writeFile(output, data, callback); + }); +} + +/** + * Helpers + */ + +function getStdin(callback) { + var stdin = process.stdin + , buff = ''; + + stdin.setEncoding('utf8'); + + stdin.on('data', function(data) { + buff += data; + }); + + stdin.on('error', function(err) { + return callback(err); + }); + + stdin.on('end', function() { + return callback(null, buff); + }); + + try { + stdin.resume(); + } catch (e) { + callback(e); } -}; +} + +function camelize(text) { + return text.replace(/(\w)-(\w)/g, function(_, a, b) { + return a + b.toUpperCase(); + }); +} + +/** + * Expose / Entry Point + */ if (!module.parent) { process.title = 'marked'; - main(process.argv.slice()); + main(process.argv.slice(), function(err, code) { + if (err) throw err; + return process.exit(code || 0); + }); } else { module.exports = main; } diff --git a/tools/doc/node_modules/marked/bower.json b/tools/doc/node_modules/marked/bower.json new file mode 100644 index 00000000000000..a2a8187759f7c9 --- /dev/null +++ b/tools/doc/node_modules/marked/bower.json @@ -0,0 +1,24 @@ +{ + "name": "marked", + "version": "0.3.4", + "homepage": "https://github.com/chjj/marked", + "authors": [ + "Christopher Jeffrey " + ], + "description": "A markdown parser built for speed", + "keywords": [ + "markdown", + "markup", + "html" + ], + "main": "lib/marked.js", + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "app/bower_components", + "test", + "tests" + ] +} diff --git a/tools/doc/node_modules/marked/component.json b/tools/doc/node_modules/marked/component.json new file mode 100644 index 00000000000000..1d672877f6e712 --- /dev/null +++ b/tools/doc/node_modules/marked/component.json @@ -0,0 +1,10 @@ +{ + "name": "marked", + "version": "0.3.4", + "repo": "chjj/marked", + "description": "A markdown parser built for speed", + "keywords": ["markdown", "markup", "html"], + "scripts": ["lib/marked.js"], + "main": "lib/marked.js", + "license": "MIT" +} diff --git a/tools/doc/node_modules/marked/doc/broken.md b/tools/doc/node_modules/marked/doc/broken.md new file mode 100644 index 00000000000000..7bfa49e8a9adf9 --- /dev/null +++ b/tools/doc/node_modules/marked/doc/broken.md @@ -0,0 +1,426 @@ +# Markdown is broken + +I have a lot of scraps of markdown engine oddities that I've collected over the +years. What you see below is slightly messy, but it's what I've managed to +cobble together to illustrate the differences between markdown engines, and +why, if there ever is a markdown specification, it has to be absolutely +thorough. There are a lot more of these little differences I have documented +elsewhere. I know I will find them lingering on my disk one day, but until +then, I'll continue to add whatever strange nonsensical things I find. + +Some of these examples may only mention a particular engine compared to marked. +However, the examples with markdown.pl could easily be swapped out for +discount, upskirt, or markdown.js, and you would very easily see even more +inconsistencies. + +A lot of this was written when I was very unsatisfied with the inconsistencies +between markdown engines. Please excuse the frustration noticeable in my +writing. + +## Examples of markdown's "stupid" list parsing + +``` +$ markdown.pl + + * item1 + + * item2 + + text +^D +
    +
  • item1

    + +
      +
    • item2
    • +
    + +

    text

  • +

+``` + + +``` +$ marked + * item1 + + * item2 + + text +^D +
    +
  • item1

    +
      +
    • item2
    • +
    +

    text

    +
  • +
+``` + +Which looks correct to you? + +- - - + +``` +$ markdown.pl +* hello + > world +^D +

    +
  • hello

    + +
    +

    world

  • +

+ +``` + +``` +$ marked +* hello + > world +^D +
    +
  • hello
    +

    world

    +
    +
  • +
+``` + +Again, which looks correct to you? + +- - - + +EXAMPLE: + +``` +$ markdown.pl +* hello + * world + * hi + code +^D +
    +
  • hello +
      +
    • world
    • +
    • hi + code
    • +
  • +
+``` + +The code isn't a code block even though it's after the bullet margin. I know, +lets give it two more spaces, effectively making it 8 spaces past the bullet. + +``` +$ markdown.pl +* hello + * world + * hi + code +^D +
    +
  • hello +
      +
    • world
    • +
    • hi + code
    • +
  • +
+``` + +And, it's still not a code block. Did you also notice that the 3rd item isn't +even its own list? Markdown screws that up too because of its indentation +unaware parsing. + +- - - + +Let's look at some more examples of markdown's list parsing: + +``` +$ markdown.pl + + * item1 + + * item2 + + text +^D +
    +
  • item1

    + +
      +
    • item2
    • +
    + +

    text

  • +

+``` + +Misnested tags. + + +``` +$ marked + * item1 + + * item2 + + text +^D +
    +
  • item1

    +
      +
    • item2
    • +
    +

    text

    +
  • +
+``` + +Which looks correct to you? + +- - - + +``` +$ markdown.pl +* hello + > world +^D +

    +
  • hello

    + +
    +

    world

  • +

+ +``` + +More misnested tags. + + +``` +$ marked +* hello + > world +^D +
    +
  • hello
    +

    world

    +
    +
  • +
+``` + +Again, which looks correct to you? + +- - - + +# Why quality matters - Part 2 + +``` bash +$ markdown.pl +* hello + > world +^D +

    +
  • hello

    + +
    +

    world

  • +

+ +``` + +``` bash +$ sundown # upskirt +* hello + > world +^D +
    +
  • hello +> world
  • +
+``` + +``` bash +$ marked +* hello + > world +^D +
  • hello

    world

+``` + +Which looks correct to you? + +- - - + +See: https://github.com/evilstreak/markdown-js/issues/23 + +``` bash +$ markdown.pl # upskirt/markdown.js/discount +* hello + var a = 1; +* world +^D +
    +
  • hello +var a = 1;
  • +
  • world
  • +
+``` + +``` bash +$ marked +* hello + var a = 1; +* world +^D +
  • hello +
    code>var a = 1;
  • +
  • world
+``` + +Which looks more reasonable? Why shouldn't code blocks be able to appear in +list items in a sane way? + +- - - + +``` bash +$ markdown.js +
hello
+ +hello +^D +

<div>hello</div>

+ +

<span>hello</span>

+``` + +``` bash +$ marked +
hello
+ +hello +^D +
hello
+ + +

hello +

+``` + +- - - + +See: https://github.com/evilstreak/markdown-js/issues/27 + +``` bash +$ markdown.js +[![an image](/image)](/link) +^D +

![an image

+``` + +``` bash +$ marked +[![an image](/image)](/link) +^D +

an image +

+``` + +- - - + +See: https://github.com/evilstreak/markdown-js/issues/24 + +``` bash +$ markdown.js +> a + +> b + +> c +^D +

a

bundefined> c

+``` + +``` bash +$ marked +> a + +> b + +> c +^D +

a + +

+

b + +

+

c +

+``` + +- - - + +``` bash +$ markdown.pl +* hello + * world + how + + are + you + + * today +* hi +^D +
    +
  • hello

    + +
      +
    • world +how
    • +
    + +

    are +you

    + +
      +
    • today
    • +
  • +
  • hi
  • +
+``` + +``` bash +$ marked +* hello + * world + how + + are + you + + * today +* hi +^D +
    +
  • hello

    +
      +
    • world +how

      +

      are +you

      +
    • +
    • today

      +
    • +
    +
  • +
  • hi
  • +
+``` diff --git a/tools/doc/node_modules/marked/doc/todo.md b/tools/doc/node_modules/marked/doc/todo.md new file mode 100644 index 00000000000000..2e60b162aef82d --- /dev/null +++ b/tools/doc/node_modules/marked/doc/todo.md @@ -0,0 +1,2 @@ +# Todo + diff --git a/tools/doc/node_modules/marked/lib/marked.js b/tools/doc/node_modules/marked/lib/marked.js index e76178471a15bb..03251f3c58a761 100644 --- a/tools/doc/node_modules/marked/lib/marked.js +++ b/tools/doc/node_modules/marked/lib/marked.js @@ -1,6 +1,7 @@ /** - * marked - A markdown parser (https://github.com/chjj/marked) - * Copyright (c) 2011-2012, Christopher Jeffrey. (MIT Licensed) + * marked - a markdown parser + * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed) + * https://github.com/chjj/marked */ ;(function() { @@ -11,82 +12,148 @@ var block = { newline: /^\n+/, - code: /^ {4,}[^\n]*(?:\n {4,}[^\n]*|\n)*(?:\n+|$)/, - gfm_code: /^ *``` *(\w+)? *\n([^\0]+?)\s*``` *(?:\n+|$)/, - hr: /^( *[\-*_]){3,} *(?:\n+|$)/, + code: /^( {4}[^\n]+\n*)+/, + fences: noop, + hr: /^( *[-*_]){3,} *(?:\n+|$)/, heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/, - lheading: /^([^\n]+)\n *(=|-){3,} *\n*/, - blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/, - list: /^( *)([*+-]|\d+\.) [^\0]+?(?:\n{2,}(?! )|\s*$)(?!\1bullet)\n*/, - html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/, - def: /^ *\[([^\]]+)\]: *([^\s]+)(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, - paragraph: /^([^\n]+\n?(?!body))+\n*/, + nptable: noop, + lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/, + blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/, + list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, + html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/, + def: /^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, + table: noop, + paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/, text: /^[^\n]+/ }; -block.list = (function() { - var list = block.list.source; +block.bullet = /(?:[*+-]|\d+\.)/; +block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/; +block.item = replace(block.item, 'gm') + (/bull/g, block.bullet) + (); + +block.list = replace(block.list) + (/bull/g, block.bullet) + ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))') + ('def', '\\n+(?=' + block.def.source + ')') + (); + +block.blockquote = replace(block.blockquote) + ('def', block.def) + (); + +block._tag = '(?!(?:' + + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' + + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' + + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b'; + +block.html = replace(block.html) + ('comment', //) + ('closed', /<(tag)[\s\S]+?<\/\1>/) + ('closing', /])*?>/) + (/tag/g, block._tag) + (); + +block.paragraph = replace(block.paragraph) + ('hr', block.hr) + ('heading', block.heading) + ('lheading', block.lheading) + ('blockquote', block.blockquote) + ('tag', '<' + block._tag) + ('def', block.def) + (); - list = list - .replace('bullet', /(?:[*+-](?!(?: *[-*]){2,})|\d+\.)/.source); - - return new RegExp(list); -})(); +/** + * Normal Block Grammar + */ -block.html = (function() { - var html = block.html.source; +block.normal = merge({}, block); - html = html - .replace('comment', //.source) - .replace('closed', /<(tag)[^\0]+?<\/\1>/.source) - .replace('closing', /])*?>/.source) - .replace(/tag/g, tag()); +/** + * GFM Block Grammar + */ - return new RegExp(html); -})(); +block.gfm = merge({}, block.normal, { + fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/, + paragraph: /^/, + heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/ +}); -block.paragraph = (function() { - var paragraph = block.paragraph.source - , body = []; +block.gfm.paragraph = replace(block.paragraph) + ('(?!', '(?!' + + block.gfm.fences.source.replace('\\1', '\\2') + '|' + + block.list.source.replace('\\1', '\\3') + '|') + (); - (function push(rule) { - rule = block[rule] ? block[rule].source : rule; - body.push(rule.replace(/(^|[^\[])\^/g, '$1')); - return push; - }) - ('gfm_code') - ('hr') - ('heading') - ('lheading') - ('blockquote') - ('<' + tag()) - ('def'); +/** + * GFM + Tables Block Grammar + */ - return new - RegExp(paragraph.replace('body', body.join('|'))); -})(); +block.tables = merge({}, block.gfm, { + nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/, + table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/ +}); /** * Block Lexer */ -block.lexer = function(src) { - var tokens = []; +function Lexer(options) { + this.tokens = []; + this.tokens.links = {}; + this.options = options || marked.defaults; + this.rules = block.normal; + + if (this.options.gfm) { + if (this.options.tables) { + this.rules = block.tables; + } else { + this.rules = block.gfm; + } + } +} + +/** + * Expose Block Rules + */ + +Lexer.rules = block; + +/** + * Static Lex Method + */ - tokens.links = {}; +Lexer.lex = function(src, options) { + var lexer = new Lexer(options); + return lexer.lex(src); +}; +/** + * Preprocessing + */ + +Lexer.prototype.lex = function(src) { src = src .replace(/\r\n|\r/g, '\n') - .replace(/\t/g, ' '); + .replace(/\t/g, ' ') + .replace(/\u00a0/g, ' ') + .replace(/\u2424/g, '\n'); - return block.token(src, tokens, true); + return this.token(src, true); }; -block.token = function(src, tokens, top) { +/** + * Lexing + */ + +Lexer.prototype.token = function(src, top, bq) { var src = src.replace(/^ +$/gm, '') , next , loose , cap + , bull + , b , item , space , i @@ -94,41 +161,43 @@ block.token = function(src, tokens, top) { while (src) { // newline - if (cap = block.newline.exec(src)) { + if (cap = this.rules.newline.exec(src)) { src = src.substring(cap[0].length); if (cap[0].length > 1) { - tokens.push({ + this.tokens.push({ type: 'space' }); } } // code - if (cap = block.code.exec(src)) { + if (cap = this.rules.code.exec(src)) { src = src.substring(cap[0].length); cap = cap[0].replace(/^ {4}/gm, ''); - tokens.push({ + this.tokens.push({ type: 'code', - text: cap.replace(/\n+$/, '') + text: !this.options.pedantic + ? cap.replace(/\n+$/, '') + : cap }); continue; } - // gfm_code - if (cap = block.gfm_code.exec(src)) { + // fences (gfm) + if (cap = this.rules.fences.exec(src)) { src = src.substring(cap[0].length); - tokens.push({ + this.tokens.push({ type: 'code', - lang: cap[1], - text: cap[2] + lang: cap[2], + text: cap[3] || '' }); continue; } // heading - if (cap = block.heading.exec(src)) { + if (cap = this.rules.heading.exec(src)) { src = src.substring(cap[0].length); - tokens.push({ + this.tokens.push({ type: 'heading', depth: cap[1].length, text: cap[2] @@ -136,10 +205,42 @@ block.token = function(src, tokens, top) { continue; } + // table no leading pipe (gfm) + if (top && (cap = this.rules.nptable.exec(src))) { + src = src.substring(cap[0].length); + + item = { + type: 'table', + header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + cells: cap[3].replace(/\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i].split(/ *\| */); + } + + this.tokens.push(item); + + continue; + } + // lheading - if (cap = block.lheading.exec(src)) { + if (cap = this.rules.lheading.exec(src)) { src = src.substring(cap[0].length); - tokens.push({ + this.tokens.push({ type: 'heading', depth: cap[2] === '=' ? 1 : 2, text: cap[1] @@ -148,18 +249,19 @@ block.token = function(src, tokens, top) { } // hr - if (cap = block.hr.exec(src)) { + if (cap = this.rules.hr.exec(src)) { src = src.substring(cap[0].length); - tokens.push({ + this.tokens.push({ type: 'hr' }); continue; } // blockquote - if (cap = block.blockquote.exec(src)) { + if (cap = this.rules.blockquote.exec(src)) { src = src.substring(cap[0].length); - tokens.push({ + + this.tokens.push({ type: 'blockquote_start' }); @@ -168,27 +270,27 @@ block.token = function(src, tokens, top) { // Pass `top` to keep the current // "toplevel" state. This is exactly // how markdown.pl works. - block.token(cap, tokens, top); + this.token(cap, top, true); - tokens.push({ + this.tokens.push({ type: 'blockquote_end' }); + continue; } // list - if (cap = block.list.exec(src)) { + if (cap = this.rules.list.exec(src)) { src = src.substring(cap[0].length); + bull = cap[2]; - tokens.push({ + this.tokens.push({ type: 'list_start', - ordered: isFinite(cap[2]) + ordered: bull.length > 1 }); // Get each top-level item. - cap = cap[0].match( - /^( *)([*+-]|\d+\.)[^\n]*(?:\n(?!\1(?:[*+-]|\d+\.))[^\n]*)*/gm - ); + cap = cap[0].match(this.rules.item); next = false; l = cap.length; @@ -200,13 +302,25 @@ block.token = function(src, tokens, top) { // Remove the list item's bullet // so it is seen as the next token. space = item.length; - item = item.replace(/^ *([*+-]|\d+\.) */, ''); + item = item.replace(/^ *([*+-]|\d+\.) +/, ''); // Outdent whatever the // list item contains. Hacky. if (~item.indexOf('\n ')) { space -= item.length; - item = item.replace(new RegExp('^ {1,' + space + '}', 'gm'), ''); + item = !this.options.pedantic + ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') + : item.replace(/^ {1,4}/gm, ''); + } + + // Determine whether the next list item belongs here. + // Backpedal if it does not belong in this list. + if (this.options.smartLists && i !== l - 1) { + b = block.bullet.exec(cap[i + 1])[0]; + if (bull !== b && !(bull.length > 1 && b.length > 1)) { + src = cap.slice(i + 1).join('\n') + src; + i = l - 1; + } } // Determine whether item is loose or not. @@ -214,25 +328,25 @@ block.token = function(src, tokens, top) { // for discount behavior. loose = next || /\n\n(?!\s*$)/.test(item); if (i !== l - 1) { - next = item[item.length-1] === '\n'; + next = item.charAt(item.length - 1) === '\n'; if (!loose) loose = next; } - tokens.push({ + this.tokens.push({ type: loose ? 'loose_item_start' : 'list_item_start' }); // Recurse. - block.token(item, tokens); + this.token(item, false, bq); - tokens.push({ + this.tokens.push({ type: 'list_item_end' }); } - tokens.push({ + this.tokens.push({ type: 'list_end' }); @@ -240,76 +354,213 @@ block.token = function(src, tokens, top) { } // html - if (cap = block.html.exec(src)) { + if (cap = this.rules.html.exec(src)) { src = src.substring(cap[0].length); - tokens.push({ - type: 'html', + this.tokens.push({ + type: this.options.sanitize + ? 'paragraph' + : 'html', + pre: !this.options.sanitizer + && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), text: cap[0] }); continue; } // def - if (top && (cap = block.def.exec(src))) { + if ((!bq && top) && (cap = this.rules.def.exec(src))) { src = src.substring(cap[0].length); - tokens.links[cap[1].toLowerCase()] = { + this.tokens.links[cap[1].toLowerCase()] = { href: cap[2], title: cap[3] }; continue; } + // table (gfm) + if (top && (cap = this.rules.table.exec(src))) { + src = src.substring(cap[0].length); + + item = { + type: 'table', + header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i] + .replace(/^ *\| *| *\| *$/g, '') + .split(/ *\| */); + } + + this.tokens.push(item); + + continue; + } + // top-level paragraph - if (top && (cap = block.paragraph.exec(src))) { + if (top && (cap = this.rules.paragraph.exec(src))) { src = src.substring(cap[0].length); - tokens.push({ + this.tokens.push({ type: 'paragraph', - text: cap[0] + text: cap[1].charAt(cap[1].length - 1) === '\n' + ? cap[1].slice(0, -1) + : cap[1] }); continue; } // text - if (cap = block.text.exec(src)) { + if (cap = this.rules.text.exec(src)) { // Top-level should never reach here. src = src.substring(cap[0].length); - tokens.push({ + this.tokens.push({ type: 'text', text: cap[0] }); continue; } + + if (src) { + throw new + Error('Infinite loop on byte: ' + src.charCodeAt(0)); + } } - return tokens; + return this.tokens; }; /** - * Inline Processing + * Inline-Level Grammar */ var inline = { escape: /^\\([\\`*{}\[\]()#+\-.!_>])/, autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, - gfm_autolink: /^(\w+:\/\/[^\s]+[^.,:;"')\]\s])/, - tag: /^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, - link: /^!?\[((?:\[[^\]]*\]|[^\[\]]|\[|\](?=[^[\]]*\]))*)\]\(([^\)]*)\)/, - reflink: /^!?\[((?:\[[^\]]*\]|[^\[\]]|\[|\](?=[^[\]]*\]))*)\]\s*\[([^\]]*)\]/, + url: noop, + tag: /^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, + link: /^!?\[(inside)\]\(href\)/, + reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/, nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/, - strong: /^__([^\0]+?)__(?!_)|^\*\*([^\0]+?)\*\*(?!\*)/, - em: /^\b_([^\0]+?)_\b|^\*((?:\*\*|[^\0])+?)\*(?!\*)/, - code: /^(`+)([^\0]*?[^`])\1(?!`)/, + strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/, + em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, + code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/, br: /^ {2,}\n(?!\s*$)/, - text: /^[^\0]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/; + +inline.link = replace(inline.link) + ('inside', inline._inside) + ('href', inline._href) + (); + +inline.reflink = replace(inline.reflink) + ('inside', inline._inside) + (); + +/** + * Normal Inline Grammar + */ + +inline.normal = merge({}, inline); + +/** + * Pedantic Inline Grammar + */ + +inline.pedantic = merge({}, inline.normal, { + strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/ +}); + +/** + * GFM Inline Grammar + */ + +inline.gfm = merge({}, inline.normal, { + escape: replace(inline.escape)('])', '~|])')(), + url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, + del: /^~~(?=\S)([\s\S]*?\S)~~/, + text: replace(inline.text) + (']|', '~]|') + ('|', '|https?://|') + () +}); + +/** + * GFM + Line Breaks Inline Grammar + */ + +inline.breaks = merge({}, inline.gfm, { + br: replace(inline.br)('{2,}', '*')(), + text: replace(inline.gfm.text)('{2,}', '*')() +}); + /** - * Inline Lexer + * Inline Lexer & Compiler */ -inline.lexer = function(src) { +function InlineLexer(links, options) { + this.options = options || marked.defaults; + this.links = links; + this.rules = inline.normal; + this.renderer = this.options.renderer || new Renderer; + this.renderer.options = this.options; + + if (!this.links) { + throw new + Error('Tokens array requires a `links` property.'); + } + + if (this.options.gfm) { + if (this.options.breaks) { + this.rules = inline.breaks; + } else { + this.rules = inline.gfm; + } + } else if (this.options.pedantic) { + this.rules = inline.pedantic; + } +} + +/** + * Expose Inline Rules + */ + +InlineLexer.rules = inline; + +/** + * Static Lexing/Compiling Method + */ + +InlineLexer.output = function(src, links, options) { + var inline = new InlineLexer(links, options); + return inline.output(src); +}; + +/** + * Lexing/Compiling + */ + +InlineLexer.prototype.output = function(src) { var out = '' - , links = tokens.links , link , text , href @@ -317,346 +568,718 @@ inline.lexer = function(src) { while (src) { // escape - if (cap = inline.escape.exec(src)) { + if (cap = this.rules.escape.exec(src)) { src = src.substring(cap[0].length); out += cap[1]; continue; } // autolink - if (cap = inline.autolink.exec(src)) { + if (cap = this.rules.autolink.exec(src)) { src = src.substring(cap[0].length); if (cap[2] === '@') { - text = cap[1][6] === ':' - ? mangle(cap[1].substring(7)) - : mangle(cap[1]); - href = mangle('mailto:') + text; + text = cap[1].charAt(6) === ':' + ? this.mangle(cap[1].substring(7)) + : this.mangle(cap[1]); + href = this.mangle('mailto:') + text; } else { text = escape(cap[1]); href = text; } - out += '' - + text - + ''; + out += this.renderer.link(href, null, text); continue; } - // gfm_autolink - if (cap = inline.gfm_autolink.exec(src)) { + // url (gfm) + if (!this.inLink && (cap = this.rules.url.exec(src))) { src = src.substring(cap[0].length); text = escape(cap[1]); href = text; - out += '' - + text - + ''; + out += this.renderer.link(href, null, text); continue; } // tag - if (cap = inline.tag.exec(src)) { + if (cap = this.rules.tag.exec(src)) { + if (!this.inLink && /^/i.test(cap[0])) { + this.inLink = false; + } src = src.substring(cap[0].length); - out += cap[0]; + out += this.options.sanitize + ? this.options.sanitizer + ? this.options.sanitizer(cap[0]) + : escape(cap[0]) + : cap[0] continue; } // link - if (cap = inline.link.exec(src)) { + if (cap = this.rules.link.exec(src)) { src = src.substring(cap[0].length); - text = /^\s*?(?:\s+"([^\n]+)")?\s*$/.exec(cap[2]); - if (!text) { - out += cap[0][0]; - src = cap[0].substring(1) + src; - continue; - } - out += outputLink(cap, { - href: text[1], - title: text[2] + this.inLink = true; + out += this.outputLink(cap, { + href: cap[2], + title: cap[3] }); + this.inLink = false; continue; } // reflink, nolink - if ((cap = inline.reflink.exec(src)) - || (cap = inline.nolink.exec(src))) { + if ((cap = this.rules.reflink.exec(src)) + || (cap = this.rules.nolink.exec(src))) { src = src.substring(cap[0].length); link = (cap[2] || cap[1]).replace(/\s+/g, ' '); - link = links[link.toLowerCase()]; + link = this.links[link.toLowerCase()]; if (!link || !link.href) { - out += cap[0][0]; + out += cap[0].charAt(0); src = cap[0].substring(1) + src; continue; } - out += outputLink(cap, link); + this.inLink = true; + out += this.outputLink(cap, link); + this.inLink = false; continue; } // strong - if (cap = inline.strong.exec(src)) { + if (cap = this.rules.strong.exec(src)) { src = src.substring(cap[0].length); - out += '' - + inline.lexer(cap[2] || cap[1]) - + ''; + out += this.renderer.strong(this.output(cap[2] || cap[1])); continue; } // em - if (cap = inline.em.exec(src)) { + if (cap = this.rules.em.exec(src)) { src = src.substring(cap[0].length); - out += '' - + inline.lexer(cap[2] || cap[1]) - + ''; + out += this.renderer.em(this.output(cap[2] || cap[1])); continue; } // code - if (cap = inline.code.exec(src)) { + if (cap = this.rules.code.exec(src)) { src = src.substring(cap[0].length); - out += '' - + escape(cap[2], true) - + ''; + out += this.renderer.codespan(escape(cap[2], true)); continue; } // br - if (cap = inline.br.exec(src)) { + if (cap = this.rules.br.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.br(); + continue; + } + + // del (gfm) + if (cap = this.rules.del.exec(src)) { src = src.substring(cap[0].length); - out += '
'; + out += this.renderer.del(this.output(cap[1])); continue; } // text - if (cap = inline.text.exec(src)) { + if (cap = this.rules.text.exec(src)) { src = src.substring(cap[0].length); - out += escape(cap[0]); + out += this.renderer.text(escape(this.smartypants(cap[0]))); continue; } + + if (src) { + throw new + Error('Infinite loop on byte: ' + src.charCodeAt(0)); + } + } + + return out; +}; + +/** + * Compile Link + */ + +InlineLexer.prototype.outputLink = function(cap, link) { + var href = escape(link.href) + , title = link.title ? escape(link.title) : null; + + return cap[0].charAt(0) !== '!' + ? this.renderer.link(href, title, this.output(cap[1])) + : this.renderer.image(href, title, escape(cap[1])); +}; + +/** + * Smartypants Transformations + */ + +InlineLexer.prototype.smartypants = function(text) { + if (!this.options.smartypants) return text; + return text + // em-dashes + .replace(/---/g, '\u2014') + // en-dashes + .replace(/--/g, '\u2013') + // opening singles + .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018') + // closing singles & apostrophes + .replace(/'/g, '\u2019') + // opening doubles + .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c') + // closing doubles + .replace(/"/g, '\u201d') + // ellipses + .replace(/\.{3}/g, '\u2026'); +}; + +/** + * Mangle Links + */ + +InlineLexer.prototype.mangle = function(text) { + if (!this.options.mangle) return text; + var out = '' + , l = text.length + , i = 0 + , ch; + + for (; i < l; i++) { + ch = text.charCodeAt(i); + if (Math.random() > 0.5) { + ch = 'x' + ch.toString(16); + } + out += '&#' + ch + ';'; + } + + return out; +}; + +/** + * Renderer + */ + +function Renderer(options) { + this.options = options || {}; +} + +Renderer.prototype.code = function(code, lang, escaped) { + if (this.options.highlight) { + var out = this.options.highlight(code, lang); + if (out != null && out !== code) { + escaped = true; + code = out; + } + } + + if (!lang) { + return '
'
+      + (escaped ? code : escape(code, true))
+      + '\n
'; + } + + return '
'
+    + (escaped ? code : escape(code, true))
+    + '\n
\n'; +}; + +Renderer.prototype.blockquote = function(quote) { + return '
\n' + quote + '
\n'; +}; + +Renderer.prototype.html = function(html) { + return html; +}; + +Renderer.prototype.heading = function(text, level, raw) { + return '' + + text + + '\n'; +}; + +Renderer.prototype.hr = function() { + return this.options.xhtml ? '
\n' : '
\n'; +}; + +Renderer.prototype.list = function(body, ordered) { + var type = ordered ? 'ol' : 'ul'; + return '<' + type + '>\n' + body + '\n'; +}; + +Renderer.prototype.listitem = function(text) { + return '
  • ' + text + '
  • \n'; +}; + +Renderer.prototype.paragraph = function(text) { + return '

    ' + text + '

    \n'; +}; + +Renderer.prototype.table = function(header, body) { + return '\n' + + '\n' + + header + + '\n' + + '\n' + + body + + '\n' + + '
    \n'; +}; + +Renderer.prototype.tablerow = function(content) { + return '\n' + content + '\n'; +}; + +Renderer.prototype.tablecell = function(content, flags) { + var type = flags.header ? 'th' : 'td'; + var tag = flags.align + ? '<' + type + ' style="text-align:' + flags.align + '">' + : '<' + type + '>'; + return tag + content + '\n'; +}; + +// span level renderer +Renderer.prototype.strong = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.em = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.codespan = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.br = function() { + return this.options.xhtml ? '
    ' : '
    '; +}; + +Renderer.prototype.del = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.link = function(href, title, text) { + if (this.options.sanitize) { + try { + var prot = decodeURIComponent(unescape(href)) + .replace(/[^\w:]/g, '') + .toLowerCase(); + } catch (e) { + return ''; + } + if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) { + return ''; + } + } + var out = '
    '; + return out; +}; +Renderer.prototype.image = function(href, title, text) { + var out = '' + text + '' : '>'; return out; }; -var outputLink = function(cap, link) { - if (cap[0][0] !== '!') { - return '' - + inline.lexer(cap[1]) - + ''; - } else { - return ''
-      + escape(cap[1])
-      + ''; +Renderer.prototype.text = function(text) { + return text; +}; + +/** + * Parsing & Compiling + */ + +function Parser(options) { + this.tokens = []; + this.token = null; + this.options = options || marked.defaults; + this.options.renderer = this.options.renderer || new Renderer; + this.renderer = this.options.renderer; + this.renderer.options = this.options; +} + +/** + * Static Parse Method + */ + +Parser.parse = function(src, options, renderer) { + var parser = new Parser(options, renderer); + return parser.parse(src); +}; + +/** + * Parse Loop + */ + +Parser.prototype.parse = function(src) { + this.inline = new InlineLexer(src.links, this.options, this.renderer); + this.tokens = src.reverse(); + + var out = ''; + while (this.next()) { + out += this.tok(); } + + return out; }; /** - * Parsing + * Next Token */ -var tokens - , token; +Parser.prototype.next = function() { + return this.token = this.tokens.pop(); +}; + +/** + * Preview Next Token + */ -var next = function() { - return token = tokens.pop(); +Parser.prototype.peek = function() { + return this.tokens[this.tokens.length - 1] || 0; }; -var tok = function() { - switch (token.type) { +/** + * Parse Text Tokens + */ + +Parser.prototype.parseText = function() { + var body = this.token.text; + + while (this.peek().type === 'text') { + body += '\n' + this.next().text; + } + + return this.inline.output(body); +}; + +/** + * Parse Current Token + */ + +Parser.prototype.tok = function() { + switch (this.token.type) { case 'space': { return ''; } case 'hr': { - return '
    \n'; + return this.renderer.hr(); } case 'heading': { - return '' - + inline.lexer(token.text) - + '\n'; + return this.renderer.heading( + this.inline.output(this.token.text), + this.token.depth, + this.token.text); } case 'code': { - return '
    '
    -        + (token.escaped
    -        ? token.text
    -        : escape(token.text, true))
    -        + '
    \n'; + return this.renderer.code(this.token.text, + this.token.lang, + this.token.escaped); + } + case 'table': { + var header = '' + , body = '' + , i + , row + , cell + , flags + , j; + + // header + cell = ''; + for (i = 0; i < this.token.header.length; i++) { + flags = { header: true, align: this.token.align[i] }; + cell += this.renderer.tablecell( + this.inline.output(this.token.header[i]), + { header: true, align: this.token.align[i] } + ); + } + header += this.renderer.tablerow(cell); + + for (i = 0; i < this.token.cells.length; i++) { + row = this.token.cells[i]; + + cell = ''; + for (j = 0; j < row.length; j++) { + cell += this.renderer.tablecell( + this.inline.output(row[j]), + { header: false, align: this.token.align[j] } + ); + } + + body += this.renderer.tablerow(cell); + } + return this.renderer.table(header, body); } case 'blockquote_start': { var body = ''; - while (next().type !== 'blockquote_end') { - body += tok(); + while (this.next().type !== 'blockquote_end') { + body += this.tok(); } - return '
    \n' - + body - + '
    \n'; + return this.renderer.blockquote(body); } case 'list_start': { - var type = token.ordered ? 'ol' : 'ul' - , body = ''; + var body = '' + , ordered = this.token.ordered; - while (next().type !== 'list_end') { - body += tok(); + while (this.next().type !== 'list_end') { + body += this.tok(); } - return '<' - + type - + '>\n' - + body - + '\n'; + return this.renderer.list(body, ordered); } case 'list_item_start': { var body = ''; - while (next().type !== 'list_item_end') { - body += token.type === 'text' - ? parseText() - : tok(); + while (this.next().type !== 'list_item_end') { + body += this.token.type === 'text' + ? this.parseText() + : this.tok(); } - return '
  • ' - + body - + '
  • \n'; + return this.renderer.listitem(body); } case 'loose_item_start': { var body = ''; - while (next().type !== 'list_item_end') { - body += tok(); + while (this.next().type !== 'list_item_end') { + body += this.tok(); } - return '
  • ' - + body - + '
  • \n'; + return this.renderer.listitem(body); } case 'html': { - return inline.lexer(token.text); + var html = !this.token.pre && !this.options.pedantic + ? this.inline.output(this.token.text) + : this.token.text; + return this.renderer.html(html); } case 'paragraph': { - return '

    ' - + inline.lexer(token.text) - + '

    \n'; + return this.renderer.paragraph(this.inline.output(this.token.text)); } case 'text': { - return '

    ' - + parseText() - + '

    \n'; + return this.renderer.paragraph(this.parseText()); } } }; -var parseText = function() { - var body = token.text - , top; - - while ((top = tokens[tokens.length-1]) - && top.type === 'text') { - body += '\n' + next().text; - } - - return inline.lexer(body); -}; - -var parse = function(src) { - tokens = src.reverse(); - - var out = ''; - while (next()) { - out += tok(); - } - - tokens = null; - token = null; - - return out; -}; - /** * Helpers */ -var escape = function(html, encode) { +function escape(html, encode) { return html .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); -}; +} -var mangle = function(text) { - var out = '' - , l = text.length - , i = 0 - , ch; +function unescape(html) { + return html.replace(/&([#\w]+);/g, function(_, n) { + n = n.toLowerCase(); + if (n === 'colon') return ':'; + if (n.charAt(0) === '#') { + return n.charAt(1) === 'x' + ? String.fromCharCode(parseInt(n.substring(2), 16)) + : String.fromCharCode(+n.substring(1)); + } + return ''; + }); +} - for (; i < l; i++) { - ch = text.charCodeAt(i); - if (Math.random() > 0.5) { - ch = 'x' + ch.toString(16); +function replace(regex, opt) { + regex = regex.source; + opt = opt || ''; + return function self(name, val) { + if (!name) return new RegExp(regex, opt); + val = val.source || val; + val = val.replace(/(^|[^\[])\^/g, '$1'); + regex = regex.replace(name, val); + return self; + }; +} + +function noop() {} +noop.exec = noop; + +function merge(obj) { + var i = 1 + , target + , key; + + for (; i < arguments.length; i++) { + target = arguments[i]; + for (key in target) { + if (Object.prototype.hasOwnProperty.call(target, key)) { + obj[key] = target[key]; + } } - out += '&#' + ch + ';'; } - return out; -}; + return obj; +} -function tag() { - var tag = '(?!(?:' - + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' - + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' - + '|span|br|wbr|ins|del|img)\\b)\\w+'; - return tag; +/** + * Marked + */ + +function marked(src, opt, callback) { + if (callback || typeof opt === 'function') { + if (!callback) { + callback = opt; + opt = null; + } + + opt = merge({}, marked.defaults, opt || {}); + + var highlight = opt.highlight + , tokens + , pending + , i = 0; + + try { + tokens = Lexer.lex(src, opt) + } catch (e) { + return callback(e); + } + + pending = tokens.length; + + var done = function(err) { + if (err) { + opt.highlight = highlight; + return callback(err); + } + + var out; + + try { + out = Parser.parse(tokens, opt); + } catch (e) { + err = e; + } + + opt.highlight = highlight; + + return err + ? callback(err) + : callback(null, out); + }; + + if (!highlight || highlight.length < 3) { + return done(); + } + + delete opt.highlight; + + if (!pending) return done(); + + for (; i < tokens.length; i++) { + (function(token) { + if (token.type !== 'code') { + return --pending || done(); + } + return highlight(token.text, token.lang, function(err, code) { + if (err) return done(err); + if (code == null || code === token.text) { + return --pending || done(); + } + token.text = code; + token.escaped = true; + --pending || done(); + }); + })(tokens[i]); + } + + return; + } + try { + if (opt) opt = merge({}, marked.defaults, opt); + return Parser.parse(Lexer.lex(src, opt), opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/chjj/marked.'; + if ((opt || marked.defaults).silent) { + return '

    An error occured:

    '
    +        + escape(e.message + '', true)
    +        + '
    '; + } + throw e; + } } /** - * Expose + * Options */ -var marked = function(src) { - return parse(block.lexer(src)); +marked.options = +marked.setOptions = function(opt) { + merge(marked.defaults, opt); + return marked; }; -marked.parser = parse; -marked.lexer = block.lexer; +marked.defaults = { + gfm: true, + tables: true, + breaks: false, + pedantic: false, + sanitize: false, + sanitizer: null, + mangle: true, + smartLists: false, + silent: false, + highlight: null, + langPrefix: 'lang-', + smartypants: false, + headerPrefix: '', + renderer: new Renderer, + xhtml: false +}; + +/** + * Expose + */ + +marked.Parser = Parser; +marked.parser = Parser.parse; + +marked.Renderer = Renderer; + +marked.Lexer = Lexer; +marked.lexer = Lexer.lex; + +marked.InlineLexer = InlineLexer; +marked.inlineLexer = InlineLexer.output; marked.parse = marked; -if (typeof module !== 'undefined') { +if (typeof module !== 'undefined' && typeof exports === 'object') { module.exports = marked; +} else if (typeof define === 'function' && define.amd) { + define(function() { return marked; }); } else { this.marked = marked; } -}).call(this); +}).call(function() { + return this || (typeof window !== 'undefined' ? window : global); +}()); diff --git a/tools/doc/node_modules/marked/man/marked.1 b/tools/doc/node_modules/marked/man/marked.1 index 214533390ce41a..b9bdc8c2123e3b 100644 --- a/tools/doc/node_modules/marked/man/marked.1 +++ b/tools/doc/node_modules/marked/man/marked.1 @@ -1,39 +1,91 @@ .ds q \N'34' -.TH marked 1 +.TH marked 1 "2014-01-31" "v0.3.1" "marked.js" + .SH NAME marked \- a javascript markdown parser + .SH SYNOPSIS -.nf -.B marked [\-o output] [\-i input] [\-th] -.fi +.B marked +[\-o \fI\fP] [\-i \fI\fP] [\-\-help] +[\-\-tokens] [\-\-pedantic] [\-\-gfm] +[\-\-breaks] [\-\-tables] [\-\-sanitize] +[\-\-smart\-lists] [\-\-lang\-prefix \fI\fP] +[\-\-no\-etc...] [\-\-silent] [\fIfilename\fP] + .SH DESCRIPTION .B marked is a full-featured javascript markdown parser, built for speed. It also includes multiple GFM features. + +.SH EXAMPLES +.TP +cat in.md | marked > out.html +.TP +echo "hello *world*" | marked +.TP +marked \-o out.html in.md \-\-gfm +.TP +marked \-\-output="hello world.html" \-i in.md \-\-no-breaks + .SH OPTIONS .TP -.BI \-o,\ \-\-output\ [output] +.BI \-o,\ \-\-output\ [\fIoutput\fP] Specify file output. If none is specified, write to stdout. .TP -.BI \-i,\ \-\-input\ [input] +.BI \-i,\ \-\-input\ [\fIinput\fP] Specify file input, otherwise use last argument as input file. If no input file is specified, read from stdin. .TP .BI \-t,\ \-\-tokens Output a token stream instead of html. .TP -.BI \-h,\ \-\-help -Display help information. -.SH EXAMPLES +.BI \-\-pedantic +Conform to obscure parts of markdown.pl as much as possible. Don't fix original +markdown bugs. .TP -cat in.md | marked > out.html +.BI \-\-gfm +Enable github flavored markdown. .TP -echo "hello *world*" | marked +.BI \-\-breaks +Enable GFM line breaks. Only works with the gfm option. +.TP +.BI \-\-tables +Enable GFM tables. Only works with the gfm option. +.TP +.BI \-\-sanitize +Sanitize output. Ignore any HTML input. +.TP +.BI \-\-smart\-lists +Use smarter list behavior than the original markdown. .TP -marked -o out.html in.md +.BI \-\-lang\-prefix\ [\fIprefix\fP] +Set the prefix for code block classes. .TP -marked --output="hello world.html" -i in.md +.BI \-\-mangle +Mangle email addresses. +.TP +.BI \-\-no\-sanitize,\ \-no-etc... +The inverse of any of the marked options above. +.TP +.BI \-\-silent +Silence error output. +.TP +.BI \-h,\ \-\-help +Display help information. + +.SH CONFIGURATION +For configuring and running programmatically. + +.B Example + + require('marked')('*foo*', { gfm: true }); + .SH BUGS Please report any bugs to https://github.com/chjj/marked. + .SH LICENSE -Copyright (c) 2011-2012, Christopher Jeffrey (MIT License) +Copyright (c) 2011-2014, Christopher Jeffrey (MIT License). + +.SH "SEE ALSO" +.BR markdown(1), +.BR node.js(1) diff --git a/tools/doc/node_modules/marked/marked.min.js b/tools/doc/node_modules/marked/marked.min.js new file mode 100644 index 00000000000000..555c1dc1d9da18 --- /dev/null +++ b/tools/doc/node_modules/marked/marked.min.js @@ -0,0 +1,6 @@ +/** + * marked - a markdown parser + * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed) + * https://github.com/chjj/marked + */ +(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+block.def.source+")")();block.blockquote=replace(block.blockquote)("def",block.def)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b";block.html=replace(block.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1","\\2")+"|"+block.list.source.replace("\\1","\\3")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm){if(this.options.tables){this.rules=block.tables}else{this.rules=block.gfm}}}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top,bq){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1){this.tokens.push({type:"space"})}}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]||""});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i ?/gm,"");this.token(cap,top,true);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i1&&b.length>1)){src=cap.slice(i+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item.charAt(item.length-1)==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false,bq);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&(cap[1]==="pre"||cap[1]==="script"||cap[1]==="style"),text:cap[0]});continue}if(!bq&&top&&(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;this.renderer=this.options.renderer||new Renderer;this.renderer.options=this.options;if(!this.links){throw new Error("Tokens array requires a `links` property.")}if(this.options.gfm){if(this.options.breaks){this.rules=inline.breaks}else{this.rules=inline.gfm}}else if(this.options.pedantic){this.rules=inline.pedantic}}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1].charAt(6)===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+=this.renderer.link(href,null,text);continue}if(!this.inLink&&(cap=this.rules.url.exec(src))){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+=this.renderer.link(href,null,text);continue}if(cap=this.rules.tag.exec(src)){if(!this.inLink&&/^/i.test(cap[0])){this.inLink=false}src=src.substring(cap[0].length);out+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(cap[0]):escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);this.inLink=true;out+=this.outputLink(cap,{href:cap[2],title:cap[3]});this.inLink=false;continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0].charAt(0);src=cap[0].substring(1)+src;continue}this.inLink=true;out+=this.outputLink(cap,link);this.inLink=false;continue}if(cap=this.rules.strong.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.strong(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.em(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.codespan(escape(cap[2],true));continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.br();continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.del(this.output(cap[1]));continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.text(escape(this.smartypants(cap[0])));continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return out};InlineLexer.prototype.outputLink=function(cap,link){var href=escape(link.href),title=link.title?escape(link.title):null;return cap[0].charAt(0)!=="!"?this.renderer.link(href,title,this.output(cap[1])):this.renderer.image(href,title,escape(cap[1]))};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")};InlineLexer.prototype.mangle=function(text){if(!this.options.mangle)return text;var out="",l=text.length,i=0,ch;for(;i.5){ch="x"+ch.toString(16)}out+="&#"+ch+";"}return out};function Renderer(options){this.options=options||{}}Renderer.prototype.code=function(code,lang,escaped){if(this.options.highlight){var out=this.options.highlight(code,lang);if(out!=null&&out!==code){escaped=true;code=out}}if(!lang){return"
    "+(escaped?code:escape(code,true))+"\n
    "}return'
    '+(escaped?code:escape(code,true))+"\n
    \n"};Renderer.prototype.blockquote=function(quote){return"
    \n"+quote+"
    \n"};Renderer.prototype.html=function(html){return html};Renderer.prototype.heading=function(text,level,raw){return"'+text+"\n"};Renderer.prototype.hr=function(){return this.options.xhtml?"
    \n":"
    \n"};Renderer.prototype.list=function(body,ordered){var type=ordered?"ol":"ul";return"<"+type+">\n"+body+"\n"};Renderer.prototype.listitem=function(text){return"
  • "+text+"
  • \n"};Renderer.prototype.paragraph=function(text){return"

    "+text+"

    \n"};Renderer.prototype.table=function(header,body){return"\n"+"\n"+header+"\n"+"\n"+body+"\n"+"
    \n"};Renderer.prototype.tablerow=function(content){return"\n"+content+"\n"};Renderer.prototype.tablecell=function(content,flags){var type=flags.header?"th":"td";var tag=flags.align?"<"+type+' style="text-align:'+flags.align+'">':"<"+type+">";return tag+content+"\n"};Renderer.prototype.strong=function(text){return""+text+""};Renderer.prototype.em=function(text){return""+text+""};Renderer.prototype.codespan=function(text){return""+text+""};Renderer.prototype.br=function(){return this.options.xhtml?"
    ":"
    "};Renderer.prototype.del=function(text){return""+text+""};Renderer.prototype.link=function(href,title,text){if(this.options.sanitize){try{var prot=decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(prot.indexOf("javascript:")===0||prot.indexOf("vbscript:")===0){return""}}var out='
    ";return out};Renderer.prototype.image=function(href,title,text){var out=''+text+'":">";return out};Renderer.prototype.text=function(text){return text};function Parser(options){this.tokens=[];this.token=null;this.options=options||marked.defaults;this.options.renderer=this.options.renderer||new Renderer;this.renderer=this.options.renderer;this.renderer.options=this.options}Parser.parse=function(src,options,renderer){var parser=new Parser(options,renderer);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options,this.renderer);this.tokens=src.reverse();var out="";while(this.next()){out+=this.tok()}return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;while(this.peek().type==="text"){body+="\n"+this.next().text}return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case"space":{return""}case"hr":{return this.renderer.hr()}case"heading":{return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text)}case"code":{return this.renderer.code(this.token.text,this.token.lang,this.token.escaped)}case"table":{var header="",body="",i,row,cell,flags,j;cell="";for(i=0;i/g,">").replace(/"/g,""").replace(/'/g,"'")}function unescape(html){return html.replace(/&([#\w]+);/g,function(_,n){n=n.toLowerCase();if(n==="colon")return":";if(n.charAt(0)==="#"){return n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1))}return""})}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=1,target,key;for(;iAn error occured:

    "+escape(e.message+"",true)+"
    "}throw e}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,sanitizer:null,mangle:true,smartLists:false,silent:false,highlight:null,langPrefix:"lang-",smartypants:false,headerPrefix:"",renderer:new Renderer,xhtml:false};marked.Parser=Parser;marked.parser=Parser.parse;marked.Renderer=Renderer;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;marked.parse=marked;if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=marked}else if(typeof define==="function"&&define.amd){define(function(){return marked})}else{this.marked=marked}}).call(function(){return this||(typeof window!=="undefined"?window:global)}()); \ No newline at end of file diff --git a/tools/doc/node_modules/marked/package.json b/tools/doc/node_modules/marked/package.json index f47a9e12530731..d631092cb80f42 100644 --- a/tools/doc/node_modules/marked/package.json +++ b/tools/doc/node_modules/marked/package.json @@ -1,15 +1,95 @@ { - "name": "marked", + "_args": [ + [ + "marked", + "/Users/firedfox/git/node/tools/doc" + ] + ], + "_from": "marked@latest", + "_id": "marked@0.3.5", + "_inCache": true, + "_installable": true, + "_location": "/marked", + "_nodeVersion": "0.12.7", + "_npmUser": { + "email": "chjjeffrey@gmail.com", + "name": "chjj" + }, + "_npmVersion": "2.13.2", + "_phantomChildren": {}, + "_requested": { + "name": "marked", + "raw": "marked", + "rawSpec": "", + "scope": null, + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/marked/-/marked-0.3.5.tgz", + "_shasum": "4113a15ac5d7bca158a5aae07224587b9fa15b94", + "_shrinkwrap": null, + "_spec": "marked", + "_where": "/Users/firedfox/git/node/tools/doc", + "author": { + "name": "Christopher Jeffrey" + }, + "bin": { + "marked": "./bin/marked" + }, + "bugs": { + "url": "http://github.com/chjj/marked/issues" + }, + "dependencies": {}, "description": "A markdown parser built for speed", - "author": "Christopher Jeffrey", - "version": "0.1.9", - "main": "./lib/marked.js", - "bin": "./bin/marked", - "man": "./man/marked.1", - "preferGlobal": false, - "repository": "git://github.com/chjj/marked.git", + "devDependencies": { + "gulp": "^3.8.11", + "gulp-concat": "^2.5.2", + "gulp-uglify": "^1.1.0", + "markdown": "*", + "showdown": "*" + }, + "directories": {}, + "dist": { + "shasum": "4113a15ac5d7bca158a5aae07224587b9fa15b94", + "tarball": "https://registry.npmjs.org/marked/-/marked-0.3.5.tgz" + }, + "gitHead": "88ce4df47c4d994dc1b1df1477a21fb893e11ddc", "homepage": "https://github.com/chjj/marked", - "bugs": "http://github.com/chjj/marked/issues", - "keywords": [ "markdown", "markup", "html" ], - "tags": [ "markdown", "markup", "html" ] + "keywords": [ + "markdown", + "markup", + "html" + ], + "license": "MIT", + "main": "./lib/marked.js", + "maintainers": [ + { + "email": "chjjeffrey@gmail.com", + "name": "chjj" + } + ], + "man": [ + "./man/marked.1" + ], + "name": "marked", + "optionalDependencies": {}, + "preferGlobal": true, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/chjj/marked.git" + }, + "scripts": { + "bench": "node test --bench", + "test": "node test" + }, + "tags": [ + "markdown", + "markup", + "html" + ], + "version": "0.3.5" } diff --git a/tools/doc/package.json b/tools/doc/package.json index 0dda4b971cf14f..41a50ac04ed188 100644 --- a/tools/doc/package.json +++ b/tools/doc/package.json @@ -7,7 +7,7 @@ "node": ">=0.6.10" }, "dependencies": { - "marked": "~0.1.9", + "marked": "^0.3.5", "js-yaml": "^3.5.2" }, "devDependencies": {}, From 642f21402db905366384e1ec19cca1f0c5cbee16 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Wed, 4 May 2016 22:20:27 -0700 Subject: [PATCH 06/20] tools: lint for object literal spacing There has been occasional nits for spacing in object literals in PRs but the project does not lint for it and it is not always handled consistently in the existing code, even on adjacent lines of a file. This change enables a linting rule requiring no space between the key and the colon, and requiring at least one space (but allowing for more so property values can be lined up if desired) between the colon and the value. This appears to be the most common style used in the current code base. Example code the complies with lint rule: myObj = { foo: 'bar' }; Examples that do not comply with the lint rule: myObj = { foo : 'bar' }; myObj = { foo:'bar' }; PR-URL: https://github.com/nodejs/node/pull/6592 Reviewed-By: James M Snell Reviewed-By: Brian White --- .eslintrc | 1 + lib/_http_server.js | 122 +++++++++--------- lib/util.js | 26 ++-- test/doctool/test-doctool-json.js | 10 +- test/parallel/test-console.js | 4 +- test/parallel/test-crypto-binary-default.js | 8 +- test/parallel/test-crypto.js | 8 +- test/parallel/test-domain-http-server.js | 2 +- ...st-domain-top-level-error-handler-throw.js | 2 +- test/parallel/test-http-chunk-problem.js | 2 +- test/parallel/test-http-client-pipe-end.js | 2 +- ...ient-reject-chunked-with-content-length.js | 2 +- .../test-http-client-reject-cr-no-lf.js | 2 +- .../test-http-client-response-domain.js | 2 +- .../test-http-client-timeout-with-data.js | 2 +- test/parallel/test-http-expect-continue.js | 4 +- .../test-http-remove-header-stays-removed.js | 2 +- ...test-http-response-multi-content-length.js | 2 +- test/parallel/test-http-response-splitting.js | 4 +- .../parallel/test-http-server-multiheaders.js | 2 +- .../test-http-server-multiheaders2.js | 2 +- .../test-http-server-reject-cr-no-lf.js | 2 +- test/parallel/test-listen-fd-ebadf.js | 4 +- test/parallel/test-net-listen-fd0.js | 2 +- .../test-stream-transform-split-objectmode.js | 8 +- test/parallel/test-stream2-transform.js | 2 +- test/parallel/test-tls-alert.js | 2 +- test/parallel/test-url.js | 6 +- test/parallel/test-util.js | 14 +- test/parallel/test-vm-context.js | 2 +- test/pummel/test-crypto-dh.js | 16 +-- test/pummel/test-fs-watch-file-slow.js | 2 +- test/sequential/test-fs-watch.js | 2 +- tools/doc/html.js | 4 +- 34 files changed, 139 insertions(+), 138 deletions(-) diff --git a/.eslintrc b/.eslintrc index 59f9f06e8baa0d..ffb768217805b9 100644 --- a/.eslintrc +++ b/.eslintrc @@ -57,6 +57,7 @@ rules: comma-spacing: 2 eol-last: 2 indent: [2, 2, {SwitchCase: 1}] + key-spacing: [2, {mode: "minimum"}] keyword-spacing: 2 max-len: [2, 80, 2] new-parens: 2 diff --git a/lib/_http_server.js b/lib/_http_server.js index 399f9d49e1d4b0..827c9c346cb708 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -16,67 +16,67 @@ const httpSocketSetup = common.httpSocketSetup; const OutgoingMessage = require('_http_outgoing').OutgoingMessage; const STATUS_CODES = exports.STATUS_CODES = { - 100 : 'Continue', - 101 : 'Switching Protocols', - 102 : 'Processing', // RFC 2518, obsoleted by RFC 4918 - 200 : 'OK', - 201 : 'Created', - 202 : 'Accepted', - 203 : 'Non-Authoritative Information', - 204 : 'No Content', - 205 : 'Reset Content', - 206 : 'Partial Content', - 207 : 'Multi-Status', // RFC 4918 - 208 : 'Already Reported', - 226 : 'IM Used', - 300 : 'Multiple Choices', - 301 : 'Moved Permanently', - 302 : 'Found', - 303 : 'See Other', - 304 : 'Not Modified', - 305 : 'Use Proxy', - 307 : 'Temporary Redirect', - 308 : 'Permanent Redirect', // RFC 7238 - 400 : 'Bad Request', - 401 : 'Unauthorized', - 402 : 'Payment Required', - 403 : 'Forbidden', - 404 : 'Not Found', - 405 : 'Method Not Allowed', - 406 : 'Not Acceptable', - 407 : 'Proxy Authentication Required', - 408 : 'Request Timeout', - 409 : 'Conflict', - 410 : 'Gone', - 411 : 'Length Required', - 412 : 'Precondition Failed', - 413 : 'Payload Too Large', - 414 : 'URI Too Long', - 415 : 'Unsupported Media Type', - 416 : 'Range Not Satisfiable', - 417 : 'Expectation Failed', - 418 : 'I\'m a teapot', // RFC 2324 - 421 : 'Misdirected Request', - 422 : 'Unprocessable Entity', // RFC 4918 - 423 : 'Locked', // RFC 4918 - 424 : 'Failed Dependency', // RFC 4918 - 425 : 'Unordered Collection', // RFC 4918 - 426 : 'Upgrade Required', // RFC 2817 - 428 : 'Precondition Required', // RFC 6585 - 429 : 'Too Many Requests', // RFC 6585 - 431 : 'Request Header Fields Too Large', // RFC 6585 - 500 : 'Internal Server Error', - 501 : 'Not Implemented', - 502 : 'Bad Gateway', - 503 : 'Service Unavailable', - 504 : 'Gateway Timeout', - 505 : 'HTTP Version Not Supported', - 506 : 'Variant Also Negotiates', // RFC 2295 - 507 : 'Insufficient Storage', // RFC 4918 - 508 : 'Loop Detected', - 509 : 'Bandwidth Limit Exceeded', - 510 : 'Not Extended', // RFC 2774 - 511 : 'Network Authentication Required' // RFC 6585 + 100: 'Continue', + 101: 'Switching Protocols', + 102: 'Processing', // RFC 2518, obsoleted by RFC 4918 + 200: 'OK', + 201: 'Created', + 202: 'Accepted', + 203: 'Non-Authoritative Information', + 204: 'No Content', + 205: 'Reset Content', + 206: 'Partial Content', + 207: 'Multi-Status', // RFC 4918 + 208: 'Already Reported', + 226: 'IM Used', + 300: 'Multiple Choices', + 301: 'Moved Permanently', + 302: 'Found', + 303: 'See Other', + 304: 'Not Modified', + 305: 'Use Proxy', + 307: 'Temporary Redirect', + 308: 'Permanent Redirect', // RFC 7238 + 400: 'Bad Request', + 401: 'Unauthorized', + 402: 'Payment Required', + 403: 'Forbidden', + 404: 'Not Found', + 405: 'Method Not Allowed', + 406: 'Not Acceptable', + 407: 'Proxy Authentication Required', + 408: 'Request Timeout', + 409: 'Conflict', + 410: 'Gone', + 411: 'Length Required', + 412: 'Precondition Failed', + 413: 'Payload Too Large', + 414: 'URI Too Long', + 415: 'Unsupported Media Type', + 416: 'Range Not Satisfiable', + 417: 'Expectation Failed', + 418: 'I\'m a teapot', // RFC 2324 + 421: 'Misdirected Request', + 422: 'Unprocessable Entity', // RFC 4918 + 423: 'Locked', // RFC 4918 + 424: 'Failed Dependency', // RFC 4918 + 425: 'Unordered Collection', // RFC 4918 + 426: 'Upgrade Required', // RFC 2817 + 428: 'Precondition Required', // RFC 6585 + 429: 'Too Many Requests', // RFC 6585 + 431: 'Request Header Fields Too Large', // RFC 6585 + 500: 'Internal Server Error', + 501: 'Not Implemented', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + 504: 'Gateway Timeout', + 505: 'HTTP Version Not Supported', + 506: 'Variant Also Negotiates', // RFC 2295 + 507: 'Insufficient Storage', // RFC 4918 + 508: 'Loop Detected', + 509: 'Bandwidth Limit Exceeded', + 510: 'Not Extended', // RFC 2774 + 511: 'Network Authentication Required' // RFC 6585 }; const kOnExecute = HTTPParser.kOnExecute | 0; diff --git a/lib/util.js b/lib/util.js index 79fdb33326ebc9..cd643c3120714a 100644 --- a/lib/util.js +++ b/lib/util.js @@ -147,19 +147,19 @@ exports.inspect = inspect; // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] + 'bold': [1, 22], + 'italic': [3, 23], + 'underline': [4, 24], + 'inverse': [7, 27], + 'white': [37, 39], + 'grey': [90, 39], + 'black': [30, 39], + 'blue': [34, 39], + 'cyan': [36, 39], + 'green': [32, 39], + 'magenta': [35, 39], + 'red': [31, 39], + 'yellow': [33, 39] }; // Don't use 'blue' not visible on cmd.exe diff --git a/test/doctool/test-doctool-json.js b/test/doctool/test-doctool-json.js index f57fcd94752871..79cf4ce3c3ed47 100644 --- a/test/doctool/test-doctool-json.js +++ b/test/doctool/test-doctool-json.js @@ -17,7 +17,7 @@ var testData = [ 'source': 'foo', 'modules': [ { 'textRaw': 'Sample Markdown', 'name': 'sample_markdown', - 'modules': [ { 'textRaw':'Seussian Rhymes', + 'modules': [ { 'textRaw': 'Seussian Rhymes', 'name': 'seussian_rhymes', 'desc': '
      \n
    1. fish
    2. \n
    3. fish

      \n
    4. \n
    5. ' + '

      Red fish

      \n
    6. \n
    7. Blue fish
    8. \n
    \n', @@ -32,7 +32,7 @@ var testData = [ { 'file': common.fixturesDir + '/order_of_end_tags_5873.md', 'json': { - 'source':'foo', + 'source': 'foo', 'modules': [ { 'textRaw': 'Title', 'name': 'title', @@ -41,8 +41,8 @@ var testData = [ 'name': 'subsection', 'classMethods': [ { 'textRaw': 'Class Method: Buffer.from(array)', - 'type':'classMethod', - 'name':'from', + 'type': 'classMethod', + 'name': 'from', 'signatures': [ { 'params': [ { 'textRaw': '`array` {Array} ', @@ -51,7 +51,7 @@ var testData = [ } ] }, { - 'params' : [ { + 'params': [ { 'name': 'array' } ] } diff --git a/test/parallel/test-console.js b/test/parallel/test-console.js index 5f908442339e03..a396bda8cd3350 100644 --- a/test/parallel/test-console.js +++ b/test/parallel/test-console.js @@ -37,8 +37,8 @@ console.log(custom_inspect); // test console.dir() console.dir(custom_inspect); console.dir(custom_inspect, { showHidden: false }); -console.dir({ foo : { bar : { baz : true } } }, { depth: 0 }); -console.dir({ foo : { bar : { baz : true } } }, { depth: 1 }); +console.dir({ foo: { bar: { baz: true } } }, { depth: 0 }); +console.dir({ foo: { bar: { baz: true } } }, { depth: 1 }); // test console.trace() console.trace('This is a %j %d', { formatted: 'trace' }, 10, 'foo'); diff --git a/test/parallel/test-crypto-binary-default.js b/test/parallel/test-crypto-binary-default.js index 129bbcacef151e..da29d690645683 100644 --- a/test/parallel/test-crypto-binary-default.js +++ b/test/parallel/test-crypto-binary-default.js @@ -30,19 +30,19 @@ var rsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_rsa_privkey.pem', // PFX tests assert.doesNotThrow(function() { - tls.createSecureContext({pfx:certPfx, passphrase:'sample'}); + tls.createSecureContext({pfx: certPfx, passphrase: 'sample'}); }); assert.throws(function() { - tls.createSecureContext({pfx:certPfx}); + tls.createSecureContext({pfx: certPfx}); }, 'mac verify failure'); assert.throws(function() { - tls.createSecureContext({pfx:certPfx, passphrase:'test'}); + tls.createSecureContext({pfx: certPfx, passphrase: 'test'}); }, 'mac verify failure'); assert.throws(function() { - tls.createSecureContext({pfx:'sample', passphrase:'test'}); + tls.createSecureContext({pfx: 'sample', passphrase: 'test'}); }, 'not enough data'); // Test HMAC diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js index 271541d54a242d..bf87900875b7c4 100644 --- a/test/parallel/test-crypto.js +++ b/test/parallel/test-crypto.js @@ -32,19 +32,19 @@ assert.throws(function() { // PFX tests assert.doesNotThrow(function() { - tls.createSecureContext({pfx:certPfx, passphrase:'sample'}); + tls.createSecureContext({pfx: certPfx, passphrase: 'sample'}); }); assert.throws(function() { - tls.createSecureContext({pfx:certPfx}); + tls.createSecureContext({pfx: certPfx}); }, 'mac verify failure'); assert.throws(function() { - tls.createSecureContext({pfx:certPfx, passphrase:'test'}); + tls.createSecureContext({pfx: certPfx, passphrase: 'test'}); }, 'mac verify failure'); assert.throws(function() { - tls.createSecureContext({pfx:'sample', passphrase:'test'}); + tls.createSecureContext({pfx: 'sample', passphrase: 'test'}); }, 'not enough data'); diff --git a/test/parallel/test-domain-http-server.js b/test/parallel/test-domain-http-server.js index 37dbc30f4234d7..594c34aae8d201 100644 --- a/test/parallel/test-domain-http-server.js +++ b/test/parallel/test-domain-http-server.js @@ -20,7 +20,7 @@ var server = http.createServer(function(req, res) { serverCaught++; console.log('horray! got a server error', er); // try to send a 500. If that fails, oh well. - res.writeHead(500, {'content-type':'text/plain'}); + res.writeHead(500, {'content-type': 'text/plain'}); res.end(er.stack || er.message || 'Unknown error'); }); diff --git a/test/parallel/test-domain-top-level-error-handler-throw.js b/test/parallel/test-domain-top-level-error-handler-throw.js index 4bde30d17cb8c8..7933c5d052fe11 100644 --- a/test/parallel/test-domain-top-level-error-handler-throw.js +++ b/test/parallel/test-domain-top-level-error-handler-throw.js @@ -29,7 +29,7 @@ if (process.argv[2] === 'child') { var fork = require('child_process').fork; var assert = require('assert'); - var child = fork(process.argv[1], ['child'], {silent:true}); + var child = fork(process.argv[1], ['child'], {silent: true}); var stderrOutput = ''; if (child) { child.stderr.on('data', function onStderrData(data) { diff --git a/test/parallel/test-http-chunk-problem.js b/test/parallel/test-http-chunk-problem.js index 26df0b95e29572..23ec2d0263fa94 100644 --- a/test/parallel/test-http-chunk-problem.js +++ b/test/parallel/test-http-chunk-problem.js @@ -11,7 +11,7 @@ if (process.argv[2] === 'request') { const http = require('http'); const options = { port: common.PORT, - path : '/' + path: '/' }; http.get(options, (res) => { diff --git a/test/parallel/test-http-client-pipe-end.js b/test/parallel/test-http-client-pipe-end.js index 715f8ccf79df92..5b2db49435a1b6 100644 --- a/test/parallel/test-http-client-pipe-end.js +++ b/test/parallel/test-http-client-pipe-end.js @@ -18,7 +18,7 @@ common.refreshTmpDir(); server.listen(common.PIPE, function() { var req = http.request({ socketPath: common.PIPE, - headers: {'Content-Length':'1'}, + headers: {'Content-Length': '1'}, method: 'POST', path: '/' }); diff --git a/test/parallel/test-http-client-reject-chunked-with-content-length.js b/test/parallel/test-http-client-reject-chunked-with-content-length.js index a6639c90690da3..400a1d0ddbb991 100644 --- a/test/parallel/test-http-client-reject-chunked-with-content-length.js +++ b/test/parallel/test-http-client-reject-chunked-with-content-length.js @@ -17,7 +17,7 @@ server.listen(common.PORT, () => { // The callback should not be called because the server is sending // both a Content-Length header and a Transfer-Encoding: chunked // header, which is a violation of the HTTP spec. - const req = http.get({port:common.PORT}, (res) => { + const req = http.get({port: common.PORT}, (res) => { assert.fail(null, null, 'callback should not be called'); }); req.on('error', common.mustCall((err) => { diff --git a/test/parallel/test-http-client-reject-cr-no-lf.js b/test/parallel/test-http-client-reject-cr-no-lf.js index b60220cbb629b3..350d7f40e95b9b 100644 --- a/test/parallel/test-http-client-reject-cr-no-lf.js +++ b/test/parallel/test-http-client-reject-cr-no-lf.js @@ -16,7 +16,7 @@ const server = net.createServer((socket) => { server.listen(common.PORT, () => { // The callback should not be called because the server is sending a // header field that ends only in \r with no following \n - const req = http.get({port:common.PORT}, (res) => { + const req = http.get({port: common.PORT}, (res) => { assert.fail(null, null, 'callback should not be called'); }); req.on('error', common.mustCall((err) => { diff --git a/test/parallel/test-http-client-response-domain.js b/test/parallel/test-http-client-response-domain.js index 59b95144867538..3034b1087e4d33 100644 --- a/test/parallel/test-http-client-response-domain.js +++ b/test/parallel/test-http-client-response-domain.js @@ -34,7 +34,7 @@ function test() { var req = http.get({ socketPath: common.PIPE, - headers: {'Content-Length':'1'}, + headers: {'Content-Length': '1'}, method: 'POST', path: '/' }); diff --git a/test/parallel/test-http-client-timeout-with-data.js b/test/parallel/test-http-client-timeout-with-data.js index 673908fe6d465f..2fff91227d1984 100644 --- a/test/parallel/test-http-client-timeout-with-data.js +++ b/test/parallel/test-http-client-timeout-with-data.js @@ -19,7 +19,7 @@ const options = { }; const server = http.createServer(function(req, res) { - res.writeHead(200, {'Content-Length':'2'}); + res.writeHead(200, {'Content-Length': '2'}); res.write('*'); setTimeout(function() { res.end('*'); }, common.platformTimeout(100)); }); diff --git a/test/parallel/test-http-expect-continue.js b/test/parallel/test-http-expect-continue.js index 84c7d473efa108..247346a9ec81a4 100644 --- a/test/parallel/test-http-expect-continue.js +++ b/test/parallel/test-http-expect-continue.js @@ -13,8 +13,8 @@ function handler(req, res) { assert.equal(sent_continue, true, 'Full response sent before 100 Continue'); console.error('Server sending full response...'); res.writeHead(200, { - 'Content-Type' : 'text/plain', - 'ABCD' : '1' + 'Content-Type': 'text/plain', + 'ABCD': '1' }); res.end(test_res_body); } diff --git a/test/parallel/test-http-remove-header-stays-removed.js b/test/parallel/test-http-remove-header-stays-removed.js index 904b8210103ebf..20390ffb2060d6 100644 --- a/test/parallel/test-http-remove-header-stays-removed.js +++ b/test/parallel/test-http-remove-header-stays-removed.js @@ -30,7 +30,7 @@ process.on('exit', function() { server.listen(common.PORT, function() { http.get({ port: common.PORT }, function(res) { assert.equal(200, res.statusCode); - assert.deepEqual(res.headers, { date : 'coffee o clock' }); + assert.deepStrictEqual(res.headers, { date: 'coffee o clock' }); res.setEncoding('ascii'); res.on('data', function(chunk) { diff --git a/test/parallel/test-http-response-multi-content-length.js b/test/parallel/test-http-response-multi-content-length.js index 4b0f2c11e3e901..8c03332fb2b7d2 100644 --- a/test/parallel/test-http-response-multi-content-length.js +++ b/test/parallel/test-http-response-multi-content-length.js @@ -33,7 +33,7 @@ server.listen(common.PORT, common.mustCall(() => { // case, the error handler must be called because the client // is not allowed to accept multiple content-length headers. http.get( - {port:common.PORT, headers:{'x-num': n}}, + {port: common.PORT, headers: {'x-num': n}}, (res) => { assert(false, 'client allowed multiple content-length headers.'); } diff --git a/test/parallel/test-http-response-splitting.js b/test/parallel/test-http-response-splitting.js index 4c954bf90acc7e..3675f8182d21a5 100644 --- a/test/parallel/test-http-response-splitting.js +++ b/test/parallel/test-http-response-splitting.js @@ -29,12 +29,12 @@ const server = http.createServer((req, res) => { break; case 1: assert.throws(common.mustCall(() => { - res.writeHead(200, {'foo' : x}); + res.writeHead(200, {'foo': x}); })); break; case 2: assert.throws(common.mustCall(() => { - res.writeHead(200, {'foo' : y}); + res.writeHead(200, {'foo': y}); })); break; default: diff --git a/test/parallel/test-http-server-multiheaders.js b/test/parallel/test-http-server-multiheaders.js index 99d72988479928..132f3fc1ea047f 100644 --- a/test/parallel/test-http-server-multiheaders.js +++ b/test/parallel/test-http-server-multiheaders.js @@ -18,7 +18,7 @@ var srv = http.createServer(function(req, res) { assert.equal(req.headers['sec-websocket-extensions'], 'foo; 1, bar; 2, baz'); assert.equal(req.headers['constructor'], 'foo, bar, baz'); - res.writeHead(200, {'Content-Type' : 'text/plain'}); + res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('EOF'); srv.close(); diff --git a/test/parallel/test-http-server-multiheaders2.js b/test/parallel/test-http-server-multiheaders2.js index bf54af3465319e..80cc3416d60dae 100644 --- a/test/parallel/test-http-server-multiheaders2.js +++ b/test/parallel/test-http-server-multiheaders2.js @@ -58,7 +58,7 @@ var srv = http.createServer(function(req, res) { 'foo, bar', 'header parsed incorrectly: ' + header); }); - res.writeHead(200, {'Content-Type' : 'text/plain'}); + res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('EOF'); srv.close(); diff --git a/test/parallel/test-http-server-reject-cr-no-lf.js b/test/parallel/test-http-server-reject-cr-no-lf.js index fbb89f0ff3004d..9245dc2de54999 100644 --- a/test/parallel/test-http-server-reject-cr-no-lf.js +++ b/test/parallel/test-http-server-reject-cr-no-lf.js @@ -20,7 +20,7 @@ server.on('clientError', common.mustCall((err) => { server.close(); })); server.listen(common.PORT, () => { - const client = net.connect({port:common.PORT}, () => { + const client = net.connect({port: common.PORT}, () => { client.on('data', (chunk) => { assert.fail(null, null, 'this should not be called'); }); diff --git a/test/parallel/test-listen-fd-ebadf.js b/test/parallel/test-listen-fd-ebadf.js index 51e09a7907f18e..452eb7e14046d5 100644 --- a/test/parallel/test-listen-fd-ebadf.js +++ b/test/parallel/test-listen-fd-ebadf.js @@ -9,8 +9,8 @@ process.on('exit', function() { assert.equal(gotError, 2); }); -net.createServer(common.fail).listen({fd:2}).on('error', onError); -net.createServer(common.fail).listen({fd:42}).on('error', onError); +net.createServer(common.fail).listen({fd: 2}).on('error', onError); +net.createServer(common.fail).listen({fd: 42}).on('error', onError); function onError(ex) { assert.equal(ex.code, 'EINVAL'); diff --git a/test/parallel/test-net-listen-fd0.js b/test/parallel/test-net-listen-fd0.js index 1a6c4716eb6178..b484c6306f8463 100644 --- a/test/parallel/test-net-listen-fd0.js +++ b/test/parallel/test-net-listen-fd0.js @@ -10,7 +10,7 @@ process.on('exit', function() { }); // this should fail with an async EINVAL error, not throw an exception -net.createServer(common.fail).listen({fd:0}).on('error', function(e) { +net.createServer(common.fail).listen({fd: 0}).on('error', function(e) { switch (e.code) { case 'EINVAL': case 'ENOTSOCK': diff --git a/test/parallel/test-stream-transform-split-objectmode.js b/test/parallel/test-stream-transform-split-objectmode.js index 4e33028da2f7de..9d1b01c01b5f47 100644 --- a/test/parallel/test-stream-transform-split-objectmode.js +++ b/test/parallel/test-stream-transform-split-objectmode.js @@ -4,7 +4,7 @@ var assert = require('assert'); var Transform = require('stream').Transform; -var parser = new Transform({ readableObjectMode : true }); +var parser = new Transform({ readableObjectMode: true }); assert(parser._readableState.objectMode); assert(!parser._writableState.objectMode); @@ -12,7 +12,7 @@ assert(parser._readableState.highWaterMark === 16); assert(parser._writableState.highWaterMark === (16 * 1024)); parser._transform = function(chunk, enc, callback) { - callback(null, { val : chunk[0] }); + callback(null, { val: chunk[0] }); }; var parsed; @@ -28,7 +28,7 @@ process.on('exit', function() { }); -var serializer = new Transform({ writableObjectMode : true }); +var serializer = new Transform({ writableObjectMode: true }); assert(!serializer._readableState.objectMode); assert(serializer._writableState.objectMode); @@ -45,7 +45,7 @@ serializer.on('data', function(chunk) { serialized = chunk; }); -serializer.write({ val : 42 }); +serializer.write({ val: 42 }); process.on('exit', function() { assert(serialized[0] === 42); diff --git a/test/parallel/test-stream2-transform.js b/test/parallel/test-stream2-transform.js index 11ee45915c8395..8554c965e9481b 100644 --- a/test/parallel/test-stream2-transform.js +++ b/test/parallel/test-stream2-transform.js @@ -268,7 +268,7 @@ test('assymetric transform (compress)', function(t) { test('complex transform', function(t) { var count = 0; var saved = null; - var pt = new Transform({highWaterMark:3}); + var pt = new Transform({highWaterMark: 3}); pt._transform = function(c, e, cb) { if (count++ === 1) saved = c; diff --git a/test/parallel/test-tls-alert.js b/test/parallel/test-tls-alert.js index 6ebb1e9e0d704b..20e77afda4a4be 100644 --- a/test/parallel/test-tls-alert.js +++ b/test/parallel/test-tls-alert.js @@ -29,7 +29,7 @@ function loadPEM(n) { var server = tls.Server({ secureProtocol: 'TLSv1_2_server_method', key: loadPEM('agent2-key'), - cert:loadPEM('agent2-cert') + cert: loadPEM('agent2-cert') }, null).listen(common.PORT, function() { var args = ['s_client', '-quiet', '-tls1_1', '-connect', '127.0.0.1:' + common.PORT]; diff --git a/test/parallel/test-url.js b/test/parallel/test-url.js index 9aa2682cbcb523..170911b1f61307 100644 --- a/test/parallel/test-url.js +++ b/test/parallel/test-url.js @@ -822,7 +822,7 @@ var parseTests = { query: '@c' }, - 'http://a\r" \t\n<\'b:b@c\r\nd/e?f':{ + 'http://a\r" \t\n<\'b:b@c\r\nd/e?f': { protocol: 'http:', slashes: true, auth: 'a\r" \t\n<\'b:b', @@ -1091,7 +1091,7 @@ var formatTests = { // `#`,`?` in path '/path/to/%%23%3F+=&.txt?foo=theA1#bar': { - href : '/path/to/%%23%3F+=&.txt?foo=theA1#bar', + href: '/path/to/%%23%3F+=&.txt?foo=theA1#bar', pathname: '/path/to/%#?+=&.txt', query: { foo: 'theA1' @@ -1101,7 +1101,7 @@ var formatTests = { // `#`,`?` in path + `#` in query '/path/to/%%23%3F+=&.txt?foo=the%231#bar': { - href : '/path/to/%%23%3F+=&.txt?foo=the%231#bar', + href: '/path/to/%%23%3F+=&.txt?foo=the%231#bar', pathname: '/path/to/%#?+=&.txt', query: { foo: 'the#1' diff --git a/test/parallel/test-util.js b/test/parallel/test-util.js index 864361d80a6dfa..84cd058714df02 100644 --- a/test/parallel/test-util.js +++ b/test/parallel/test-util.js @@ -76,10 +76,10 @@ assert.equal(false, util.isBuffer('foo')); assert.equal(true, util.isBuffer(new Buffer('foo'))); // _extend -assert.deepEqual(util._extend({a:1}), {a:1}); -assert.deepEqual(util._extend({a:1}, []), {a:1}); -assert.deepEqual(util._extend({a:1}, null), {a:1}); -assert.deepEqual(util._extend({a:1}, true), {a:1}); -assert.deepEqual(util._extend({a:1}, false), {a:1}); -assert.deepEqual(util._extend({a:1}, {b:2}), {a:1, b:2}); -assert.deepEqual(util._extend({a:1, b:2}, {b:3}), {a:1, b:3}); +assert.deepStrictEqual(util._extend({a: 1}), {a: 1}); +assert.deepStrictEqual(util._extend({a: 1}, []), {a: 1}); +assert.deepStrictEqual(util._extend({a: 1}, null), {a: 1}); +assert.deepStrictEqual(util._extend({a: 1}, true), {a: 1}); +assert.deepStrictEqual(util._extend({a: 1}, false), {a: 1}); +assert.deepStrictEqual(util._extend({a: 1}, {b: 2}), {a: 1, b: 2}); +assert.deepStrictEqual(util._extend({a: 1, b: 2}, {b: 3}), {a: 1, b: 3}); diff --git a/test/parallel/test-vm-context.js b/test/parallel/test-vm-context.js index 3fe3cf1b66a88e..48bceb14593679 100644 --- a/test/parallel/test-vm-context.js +++ b/test/parallel/test-vm-context.js @@ -52,7 +52,7 @@ console.error('test RegExp as argument to assert.throws'); script = vm.createScript('var assert = require(\'assert\'); assert.throws(' + 'function() { throw "hello world"; }, /hello/);', 'some.js'); -script.runInNewContext({ require : require }); +script.runInNewContext({ require: require }); // Issue GH-7529 script = vm.createScript('delete b'); diff --git a/test/pummel/test-crypto-dh.js b/test/pummel/test-crypto-dh.js index dfef8c6a657cf2..302b645bdd52f2 100644 --- a/test/pummel/test-crypto-dh.js +++ b/test/pummel/test-crypto-dh.js @@ -20,14 +20,14 @@ assert.throws(function() { }); var hashes = { - modp1 : '630e9acd2cc63f7e80d8507624ba60ac0757201a', - modp2 : '18f7aa964484137f57bca64b21917a385b6a0b60', - modp5 : 'c0a8eec0c2c8a5ec2f9c26f9661eb339a010ec61', - modp14 : 'af5455606fe74cec49782bb374e4c63c9b1d132c', - modp15 : '7bdd39e5cdbb9748113933e5c2623b559c534e74', - modp16 : 'daea5277a7ad0116e734a8e0d2f297ef759d1161', - modp17 : '3b62aaf0142c2720f0bf26a9589b0432c00eadc1', - modp18 : 'a870b491bbbec9b131ae9878d07449d32e54f160' + modp1: '630e9acd2cc63f7e80d8507624ba60ac0757201a', + modp2: '18f7aa964484137f57bca64b21917a385b6a0b60', + modp5: 'c0a8eec0c2c8a5ec2f9c26f9661eb339a010ec61', + modp14: 'af5455606fe74cec49782bb374e4c63c9b1d132c', + modp15: '7bdd39e5cdbb9748113933e5c2623b559c534e74', + modp16: 'daea5277a7ad0116e734a8e0d2f297ef759d1161', + modp17: '3b62aaf0142c2720f0bf26a9589b0432c00eadc1', + modp18: 'a870b491bbbec9b131ae9878d07449d32e54f160' }; for (const name in hashes) { diff --git a/test/pummel/test-fs-watch-file-slow.js b/test/pummel/test-fs-watch-file-slow.js index c21785f233c58f..cb3bc5e579b86b 100644 --- a/test/pummel/test-fs-watch-file-slow.js +++ b/test/pummel/test-fs-watch-file-slow.js @@ -16,7 +16,7 @@ catch (e) { // swallow } -fs.watchFile(FILENAME, {interval:TIMEOUT - 250}, function(curr, prev) { +fs.watchFile(FILENAME, {interval: TIMEOUT - 250}, function(curr, prev) { console.log([curr, prev]); switch (++nevents) { case 1: diff --git a/test/sequential/test-fs-watch.js b/test/sequential/test-fs-watch.js index 51d737ddbeede8..249164c7e4e991 100644 --- a/test/sequential/test-fs-watch.js +++ b/test/sequential/test-fs-watch.js @@ -119,7 +119,7 @@ assert.throws(function() { oldhandle.close(); // clean up assert.throws(function() { - var w = fs.watchFile(__filename, {persistent:false}, function() {}); + var w = fs.watchFile(__filename, {persistent: false}, function() {}); oldhandle = w._handle; w._handle = { stop: w._handle.stop }; w.stop(); diff --git a/tools/doc/html.js b/tools/doc/html.js index 27e9bee17bccec..5f349abe7145b3 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -152,7 +152,7 @@ function parseLists(input) { if (tok.type === 'list_start') { state = 'LIST'; if (depth === 0) { - output.push({ type:'html', text: '
    ' }); + output.push({ type: 'html', text: '
    ' }); } depth++; output.push(tok); @@ -176,7 +176,7 @@ function parseLists(input) { output.push(tok); if (depth === 0) { state = null; - output.push({ type:'html', text: '
    ' }); + output.push({ type: 'html', text: '
    ' }); } return; } From bad9df9fc19ac5e6245b7121e0c398b4c951e4ce Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 12 Jul 2016 02:46:59 +0200 Subject: [PATCH 07/20] [SQUASH] extra v4.x-only fixes for object literal spacing spacing --- benchmark/path/format.js | 10 +++++----- test/parallel/test-fs-realpath.js | 12 ++++++------ test/parallel/test-url.js | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/benchmark/path/format.js b/benchmark/path/format.js index 478a30cbaedbd2..6c6f2106dd3fb7 100644 --- a/benchmark/path/format.js +++ b/benchmark/path/format.js @@ -18,11 +18,11 @@ function main(conf) { ext: '.html', name: 'index' } : { - root : '/', - dir : '/home/user/dir', - base : 'index.html', - ext : '.html', - name : 'index' + root: '/', + dir: '/home/user/dir', + base: 'index.html', + ext: '.html', + name: 'index' }; // Force optimization before starting the benchmark diff --git a/test/parallel/test-fs-realpath.js b/test/parallel/test-fs-realpath.js index d627c01487c2c2..46fbbd85877a81 100644 --- a/test/parallel/test-fs-realpath.js +++ b/test/parallel/test-fs-realpath.js @@ -464,12 +464,12 @@ function test_lying_cache_liar(cb) { // this should not require *any* stat calls, since everything // checked by realpath will be found in the cache. console.log('test_lying_cache_liar'); - var cache = { '/foo/bar/baz/bluff' : '/foo/bar/bluff', - '/1/2/3/4/5/6/7' : '/1', - '/a' : '/a', - '/a/b' : '/a/b', - '/a/b/c' : '/a/b', - '/a/b/d' : '/a/b/d' }; + var cache = { '/foo/bar/baz/bluff': '/foo/bar/bluff', + '/1/2/3/4/5/6/7': '/1', + '/a': '/a', + '/a/b': '/a/b', + '/a/b/c': '/a/b', + '/a/b/d': '/a/b/d' }; if (common.isWindows) { var wc = {}; Object.keys(cache).forEach(function(k) { diff --git a/test/parallel/test-url.js b/test/parallel/test-url.js index 170911b1f61307..08f13c809df51e 100644 --- a/test/parallel/test-url.js +++ b/test/parallel/test-url.js @@ -912,7 +912,7 @@ var parseTestsWithQueryString = { path: '/example', href: '/example' }, - '/example?query=value':{ + '/example?query=value': { protocol: null, slashes: null, auth: null, From 5b34603928b30ac29176db633e1e206349881098 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 9 May 2016 14:42:40 +0200 Subject: [PATCH 08/20] test: build addons with V8_DEPRECATION_WARNINGS=1 PR-URL: https://github.com/nodejs/node/pull/6652 Reviewed-By: Anna Henningsen --- test/addons/async-hello-world/binding.gyp | 1 + test/addons/at-exit/binding.gyp | 1 + test/addons/buffer-free-callback/binding.gyp | 1 + test/addons/heap-profiler/binding.gyp | 1 + test/addons/hello-world-function-export/binding.gyp | 1 + test/addons/hello-world/binding.gyp | 1 + test/addons/load-long-path/binding.gyp | 1 + test/addons/make-callback-recurse/binding.gyp | 1 + test/addons/make-callback/binding.gyp | 1 + test/addons/repl-domain-abort/binding.gyp | 1 + test/addons/stringbytes-external-exceed-max/binding.gyp | 1 + tools/doc/addon-verify.js | 1 + 12 files changed, 12 insertions(+) diff --git a/test/addons/async-hello-world/binding.gyp b/test/addons/async-hello-world/binding.gyp index 3bfb84493f3e87..7ede63d94a0d77 100644 --- a/test/addons/async-hello-world/binding.gyp +++ b/test/addons/async-hello-world/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ] } ] diff --git a/test/addons/at-exit/binding.gyp b/test/addons/at-exit/binding.gyp index 3bfb84493f3e87..7ede63d94a0d77 100644 --- a/test/addons/at-exit/binding.gyp +++ b/test/addons/at-exit/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ] } ] diff --git a/test/addons/buffer-free-callback/binding.gyp b/test/addons/buffer-free-callback/binding.gyp index 3bfb84493f3e87..7ede63d94a0d77 100644 --- a/test/addons/buffer-free-callback/binding.gyp +++ b/test/addons/buffer-free-callback/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ] } ] diff --git a/test/addons/heap-profiler/binding.gyp b/test/addons/heap-profiler/binding.gyp index b75f68fe3a4e84..ceb1d3e73415de 100644 --- a/test/addons/heap-profiler/binding.gyp +++ b/test/addons/heap-profiler/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ], 'win_delay_load_hook': 'false' } diff --git a/test/addons/hello-world-function-export/binding.gyp b/test/addons/hello-world-function-export/binding.gyp index 3bfb84493f3e87..7ede63d94a0d77 100644 --- a/test/addons/hello-world-function-export/binding.gyp +++ b/test/addons/hello-world-function-export/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ] } ] diff --git a/test/addons/hello-world/binding.gyp b/test/addons/hello-world/binding.gyp index 3bfb84493f3e87..7ede63d94a0d77 100644 --- a/test/addons/hello-world/binding.gyp +++ b/test/addons/hello-world/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ] } ] diff --git a/test/addons/load-long-path/binding.gyp b/test/addons/load-long-path/binding.gyp index 3bfb84493f3e87..7ede63d94a0d77 100644 --- a/test/addons/load-long-path/binding.gyp +++ b/test/addons/load-long-path/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ] } ] diff --git a/test/addons/make-callback-recurse/binding.gyp b/test/addons/make-callback-recurse/binding.gyp index 3bfb84493f3e87..7ede63d94a0d77 100644 --- a/test/addons/make-callback-recurse/binding.gyp +++ b/test/addons/make-callback-recurse/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ] } ] diff --git a/test/addons/make-callback/binding.gyp b/test/addons/make-callback/binding.gyp index 3bfb84493f3e87..7ede63d94a0d77 100644 --- a/test/addons/make-callback/binding.gyp +++ b/test/addons/make-callback/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ] } ] diff --git a/test/addons/repl-domain-abort/binding.gyp b/test/addons/repl-domain-abort/binding.gyp index 3bfb84493f3e87..7ede63d94a0d77 100644 --- a/test/addons/repl-domain-abort/binding.gyp +++ b/test/addons/repl-domain-abort/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ] } ] diff --git a/test/addons/stringbytes-external-exceed-max/binding.gyp b/test/addons/stringbytes-external-exceed-max/binding.gyp index 3bfb84493f3e87..7ede63d94a0d77 100644 --- a/test/addons/stringbytes-external-exceed-max/binding.gyp +++ b/test/addons/stringbytes-external-exceed-max/binding.gyp @@ -2,6 +2,7 @@ 'targets': [ { 'target_name': 'binding', + 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], 'sources': [ 'binding.cc' ] } ] diff --git a/tools/doc/addon-verify.js b/tools/doc/addon-verify.js index 2abd3574cffd7f..96e1db0ea4647e 100644 --- a/tools/doc/addon-verify.js +++ b/tools/doc/addon-verify.js @@ -82,6 +82,7 @@ ${files[name]} targets: [ { target_name: 'addon', + defines: [ 'V8_DEPRECATION_WARNINGS=1' ], sources: files.map(function(file) { return file.name; }) From 9929173adcd00b926fc81e13ae8f21bed7781782 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 9 May 2016 15:09:09 +0200 Subject: [PATCH 09/20] doc: fix deprecation warnings in addon examples Use the overload of `v8::Function::NewInstance()` that returns a `v8::MaybeLocal`. The overloads that return a simple `v8::Local` are deprecated. PR-URL: https://github.com/nodejs/node/pull/6652 Reviewed-By: Anna Henningsen --- doc/api/addons.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/doc/api/addons.md b/doc/api/addons.md index 9650329b0a5604..a4041637f2fcea 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -549,6 +549,7 @@ prototype: namespace demo { +using v8::Context; using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; @@ -597,8 +598,11 @@ void MyObject::New(const FunctionCallbackInfo& args) { // Invoked as plain function `MyObject(...)`, turn into construct call. const int argc = 1; Local argv[argc] = { args[0] }; + Local context = isolate->GetCurrentContext(); Local cons = Local::New(isolate, constructor); - args.GetReturnValue().Set(cons->NewInstance(argc, argv)); + Local result = + cons->NewInstance(context, argc, argv).ToLocalChecked(); + args.GetReturnValue().Set(result); } } @@ -728,6 +732,7 @@ The implementation in `myobject.cc` is similar to the previous example: namespace demo { +using v8::Context; using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; @@ -773,7 +778,10 @@ void MyObject::New(const FunctionCallbackInfo& args) { const int argc = 1; Local argv[argc] = { args[0] }; Local cons = Local::New(isolate, constructor); - args.GetReturnValue().Set(cons->NewInstance(argc, argv)); + Local context = isolate->GetCurrentContext(); + Local instance = + cons->NewInstance(context, argc, argv).ToLocalChecked(); + args.GetReturnValue().Set(instance); } } @@ -783,7 +791,9 @@ void MyObject::NewInstance(const FunctionCallbackInfo& args) { const unsigned argc = 1; Local argv[argc] = { args[0] }; Local cons = Local::New(isolate, constructor); - Local instance = cons->NewInstance(argc, argv); + Local context = isolate->GetCurrentContext(); + Local instance = + cons->NewInstance(context, argc, argv).ToLocalChecked(); args.GetReturnValue().Set(instance); } @@ -928,6 +938,7 @@ The implementation of `myobject.cc` is similar to before: namespace demo { +using v8::Context; using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; @@ -968,8 +979,11 @@ void MyObject::New(const FunctionCallbackInfo& args) { // Invoked as plain function `MyObject(...)`, turn into construct call. const int argc = 1; Local argv[argc] = { args[0] }; + Local context = isolate->GetCurrentContext(); Local cons = Local::New(isolate, constructor); - args.GetReturnValue().Set(cons->NewInstance(argc, argv)); + Local instance = + cons->NewInstance(context, argc, argv).ToLocalChecked(); + args.GetReturnValue().Set(instance); } } @@ -979,7 +993,9 @@ void MyObject::NewInstance(const FunctionCallbackInfo& args) { const unsigned argc = 1; Local argv[argc] = { args[0] }; Local cons = Local::New(isolate, constructor); - Local instance = cons->NewInstance(argc, argv); + Local context = isolate->GetCurrentContext(); + Local instance = + cons->NewInstance(context, argc, argv).ToLocalChecked(); args.GetReturnValue().Set(instance); } From 6faecba8adde128237e4cd1084a11c7c82491b40 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 9 May 2016 15:21:09 +0200 Subject: [PATCH 10/20] build,test: fix build-addons dependency chain * Make the 'extract embedded addons in the documentations' step a normal prerequisite. As an order-only prerequisite, it's sometimes skipped when it shouldn't be. * Make `tools/doc/addon-verify.js` a dependency of that step. Changes to that file should result in a rebuild. PR-URL: https://github.com/nodejs/node/pull/6652 Reviewed-By: Anna Henningsen --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 091dca717b5757..f6a6330e6020fc 100644 --- a/Makefile +++ b/Makefile @@ -128,9 +128,9 @@ test/gc/node_modules/weak/build/Release/weakref.node: $(NODE_EXE) --nodedir="$(shell pwd)" # Implicitly depends on $(NODE_EXE), see the build-addons rule for rationale. -test/addons/.docbuildstamp: doc/api/addons.md +test/addons/.docbuildstamp: tools/doc/addon-verify.js doc/api/addons.md $(RM) -r test/addons/??_*/ - $(NODE) tools/doc/addon-verify.js + $(NODE) $< touch $@ ADDONS_BINDING_GYPS := \ @@ -138,7 +138,7 @@ ADDONS_BINDING_GYPS := \ $(wildcard test/addons/*/binding.gyp)) # Implicitly depends on $(NODE_EXE), see the build-addons rule for rationale. -test/addons/.buildstamp: $(ADDONS_BINDING_GYPS) | test/addons/.docbuildstamp +test/addons/.buildstamp: $(ADDONS_BINDING_GYPS) test/addons/.docbuildstamp # Cannot use $(wildcard test/addons/*/) here, it's evaluated before # embedded addons have been generated from the documentation. for dirname in test/addons/*/; do \ From 4e8e59ba6cc7f9b000d4abad80e6ba693916e612 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 9 May 2016 15:15:23 +0200 Subject: [PATCH 11/20] tools: fix tools/doc/addon-verify.js regression Introduced in commit 3f69ea5 ("tools: update marked dependency"), it stopped the embedded addons in the documentation from getting built. PR-URL: https://github.com/nodejs/node/pull/6652 Reviewed-By: Ben Noordhuis --- tools/doc/addon-verify.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/doc/addon-verify.js b/tools/doc/addon-verify.js index 96e1db0ea4647e..299d4847ef3eb3 100644 --- a/tools/doc/addon-verify.js +++ b/tools/doc/addon-verify.js @@ -10,7 +10,7 @@ const verifyDir = path.resolve(rootDir, 'test', 'addons'); const contents = fs.readFileSync(doc).toString(); -const tokens = marked.lexer(contents, {}); +const tokens = marked.lexer(contents); let files = null; let id = 0; From ace5efece0dfd545e9751cb0a6a97235876d4809 Mon Sep 17 00:00:00 2001 From: Jesse McCarthy Date: Wed, 18 Nov 2015 17:40:03 -0500 Subject: [PATCH 12/20] build: add Make `doc-only` target Allows building just docs using existing Node instead of building Node first. PR-URL: https://github.com/nodejs/node/pull/3888 Reviewed-By: Chris Dickinson Reviewed-By: Rod Vagg Reviewed-By: James M Snell Reviewed-By: Myles Borins --- BUILDING.md | 10 ++++++++++ Makefile | 14 ++++++++------ tools/doc/generate.js | 13 +++++++++---- tools/doc/html.js | 27 ++++++++++++++++++++++----- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index fa5fbe2c050c81..b634d34b6d1cca 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -67,10 +67,20 @@ $ make test-npm To build the documentation: +This will build Node.js first (if necessary) and then use it to build the docs: + ```text $ make doc ``` +If you have an existing Node.js you can build just the docs with: + +```text +$ NODE=node make doc-only +``` + +(Where `node` is the path to your executable.) + To read the documentation: ```text diff --git a/Makefile b/Makefile index f6a6330e6020fc..c10858f4efc6d5 100644 --- a/Makefile +++ b/Makefile @@ -32,8 +32,8 @@ BUILDTYPE_LOWER := $(shell echo $(BUILDTYPE) | tr '[A-Z]' '[a-z]') EXEEXT := $(shell $(PYTHON) -c \ "import sys; print('.exe' if sys.platform == 'win32' else '')") -NODE ?= ./node$(EXEEXT) NODE_EXE = node$(EXEEXT) +NODE ?= ./$(NODE_EXE) NODE_G_EXE = node_g$(EXEEXT) # Flags for packaging. @@ -259,7 +259,9 @@ apidoc_dirs = out/doc out/doc/api/ out/doc/api/assets apiassets = $(subst api_assets,api/assets,$(addprefix out/,$(wildcard doc/api_assets/*))) -doc: $(apidoc_dirs) $(apiassets) $(apidocs) tools/doc/ $(NODE_EXE) +doc-only: $(apidoc_dirs) $(apiassets) $(apidocs) tools/doc/ + +doc: $(NODE_EXE) doc-only $(apidoc_dirs): mkdir -p $@ @@ -270,11 +272,11 @@ out/doc/api/assets/%: doc/api_assets/% out/doc/api/assets/ out/doc/%: doc/% cp -r $< $@ -out/doc/api/%.json: doc/api/%.md $(NODE_EXE) +out/doc/api/%.json: doc/api/%.md $(NODE) tools/doc/generate.js --format=json $< > $@ -out/doc/api/%.html: doc/api/%.md $(NODE_EXE) - $(NODE) tools/doc/generate.js --format=html --template=doc/template.html $< > $@ +out/doc/api/%.html: doc/api/%.md + $(NODE) tools/doc/generate.js --node-version=$(FULLVERSION) --format=html --template=doc/template.html $< > $@ docopen: out/doc/api/all.html -google-chrome out/doc/api/all.html @@ -664,4 +666,4 @@ lint-ci: lint bench-all bench bench-misc bench-array bench-buffer bench-net \ bench-http bench-fs bench-tls cctest run-ci lint-ci bench-ci \ test-v8 test-v8-intl test-v8-benchmarks test-v8-all v8 \ - $(TARBALL)-headers test-ci test-ci-native test-ci-js build-ci + $(TARBALL)-headers test-ci test-ci-native test-ci-js build-ci doc-only diff --git a/tools/doc/generate.js b/tools/doc/generate.js index 9048b484ce4e07..94c0905468f862 100644 --- a/tools/doc/generate.js +++ b/tools/doc/generate.js @@ -10,6 +10,7 @@ const args = process.argv.slice(2); let format = 'json'; let template = null; let inputFile = null; +let nodeVersion = null; args.forEach(function(arg) { if (!arg.match(/^\-\-/)) { @@ -18,15 +19,15 @@ args.forEach(function(arg) { format = arg.replace(/^\-\-format=/, ''); } else if (arg.match(/^\-\-template=/)) { template = arg.replace(/^\-\-template=/, ''); + } else if (arg.match(/^\-\-node\-version=/)) { + nodeVersion = arg.replace(/^\-\-node\-version=/, ''); } }); - if (!inputFile) { throw new Error('No input file specified'); } - console.error('Input file = %s', inputFile); fs.readFile(inputFile, 'utf8', function(er, input) { if (er) throw er; @@ -34,7 +35,6 @@ fs.readFile(inputFile, 'utf8', function(er, input) { processIncludes(inputFile, input, next); }); - function next(er, input) { if (er) throw er; switch (format) { @@ -46,7 +46,12 @@ function next(er, input) { break; case 'html': - require('./html.js')(input, inputFile, template, function(er, html) { + require('./html.js')({ + input: input, + filename: inputFile, + template: template, + nodeVersion: nodeVersion, + }, function(er, html) { if (er) throw er; console.log(html); }); diff --git a/tools/doc/html.js b/tools/doc/html.js index 5f349abe7145b3..45d0a809143a8f 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -30,7 +30,12 @@ var gtocPath = path.resolve(path.join( var gtocLoading = null; var gtocData = null; -function toHTML(input, filename, template, cb) { +/** + * opts: input, filename, template, nodeVersion. + */ +function toHTML(opts, cb) { + var template = opts.template; + if (gtocData) { return onGtocLoaded(); } @@ -51,10 +56,15 @@ function toHTML(input, filename, template, cb) { } function onGtocLoaded() { - var lexed = marked.lexer(input); + var lexed = marked.lexer(opts.input); fs.readFile(template, 'utf8', function(er, template) { if (er) return cb(er); - render(lexed, filename, template, cb); + render({ + lexed: lexed, + filename: opts.filename, + template: template, + nodeVersion: opts.nodeVersion, + }, cb); }); } } @@ -81,7 +91,14 @@ function toID(filename) { .replace(/-+/g, '-'); } -function render(lexed, filename, template, cb) { +/** + * opts: lexed, filename, template, nodeVersion. + */ +function render(opts, cb) { + var lexed = opts.lexed; + var filename = opts.filename; + var template = opts.template; + // get the section var section = getSection(lexed); @@ -100,7 +117,7 @@ function render(lexed, filename, template, cb) { template = template.replace(/__ID__/g, id); template = template.replace(/__FILENAME__/g, filename); template = template.replace(/__SECTION__/g, section); - template = template.replace(/__VERSION__/g, process.version); + template = template.replace(/__VERSION__/g, opts.nodeVersion); template = template.replace(/__TOC__/g, toc); template = template.replace( /__GTOC__/g, From 9c4838f6460364e4664487ab33aea1cafc7afae8 Mon Sep 17 00:00:00 2001 From: Myles Borins Date: Tue, 10 May 2016 11:56:56 -0700 Subject: [PATCH 13/20] tools: fix regression in doctool 101dd1e introduced a regression in the doctool. This commit reverts the changes that were made to the function signature of the various doctool functions while maintaining support for passing in specific node versions. Refs: https://github.com/nodejs/node/commit/101dd1e PR-URL: https://github.com/nodejs/node/pull/6680 Reviewed-By: Jeremiah Senkpiel Reviewed-By: Robert Lindstaedt --- tools/doc/generate.js | 16 +++++++--------- tools/doc/html.js | 36 ++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/tools/doc/generate.js b/tools/doc/generate.js index 94c0905468f862..7df987e1cf78f9 100644 --- a/tools/doc/generate.js +++ b/tools/doc/generate.js @@ -24,6 +24,8 @@ args.forEach(function(arg) { } }); +nodeVersion = nodeVersion || process.version; + if (!inputFile) { throw new Error('No input file specified'); } @@ -46,15 +48,11 @@ function next(er, input) { break; case 'html': - require('./html.js')({ - input: input, - filename: inputFile, - template: template, - nodeVersion: nodeVersion, - }, function(er, html) { - if (er) throw er; - console.log(html); - }); + require('./html.js')(input, inputFile, template, nodeVersion, + function(er, html) { + if (er) throw er; + console.log(html); + }); break; default: diff --git a/tools/doc/html.js b/tools/doc/html.js index 45d0a809143a8f..ef7d78d5b70ab3 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -30,11 +30,12 @@ var gtocPath = path.resolve(path.join( var gtocLoading = null; var gtocData = null; -/** - * opts: input, filename, template, nodeVersion. - */ -function toHTML(opts, cb) { - var template = opts.template; +function toHTML(input, filename, template, nodeVersion, cb) { + if (typeof nodeVersion === 'function') { + cb = nodeVersion; + nodeVersion = null; + } + nodeVersion = nodeVersion || process.version; if (gtocData) { return onGtocLoaded(); @@ -56,15 +57,10 @@ function toHTML(opts, cb) { } function onGtocLoaded() { - var lexed = marked.lexer(opts.input); + var lexed = marked.lexer(input); fs.readFile(template, 'utf8', function(er, template) { if (er) return cb(er); - render({ - lexed: lexed, - filename: opts.filename, - template: template, - nodeVersion: opts.nodeVersion, - }, cb); + render(lexed, filename, template, nodeVersion, cb); }); } } @@ -91,13 +87,13 @@ function toID(filename) { .replace(/-+/g, '-'); } -/** - * opts: lexed, filename, template, nodeVersion. - */ -function render(opts, cb) { - var lexed = opts.lexed; - var filename = opts.filename; - var template = opts.template; +function render(lexed, filename, template, nodeVersion, cb) { + if (typeof nodeVersion === 'function') { + cb = nodeVersion; + nodeVersion = null; + } + + nodeVersion = nodeVersion || process.version; // get the section var section = getSection(lexed); @@ -117,7 +113,7 @@ function render(opts, cb) { template = template.replace(/__ID__/g, id); template = template.replace(/__FILENAME__/g, filename); template = template.replace(/__SECTION__/g, section); - template = template.replace(/__VERSION__/g, opts.nodeVersion); + template = template.replace(/__VERSION__/g, nodeVersion); template = template.replace(/__TOC__/g, toc); template = template.replace( /__GTOC__/g, From 71819735424e4f4a249b31a1f755291418e27b73 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Thu, 12 May 2016 13:23:07 -0700 Subject: [PATCH 14/20] test: refactor doctool tests Adjust style in doctool tests to conform with predominant style of the rest of the project. The biggest changes are: * Replace string concatenation with `path.join()` * Remove unnecessary quotes from property names PR-URL: https://github.com/nodejs/node/pull/6719 Reviewed-By: James M Snell --- test/doctool/test-doctool-html.js | 13 +-- test/doctool/test-doctool-json.js | 164 +++++++++++++++--------------- 2 files changed, 91 insertions(+), 86 deletions(-) diff --git a/test/doctool/test-doctool-html.js b/test/doctool/test-doctool-html.js index 1eb96751cc0adb..a8476b7234c9fa 100644 --- a/test/doctool/test-doctool-html.js +++ b/test/doctool/test-doctool-html.js @@ -3,6 +3,7 @@ const common = require('../common'); const assert = require('assert'); const fs = require('fs'); +const path = require('path'); const html = require('../../tools/doc/html.js'); @@ -13,13 +14,13 @@ const html = require('../../tools/doc/html.js'); // have an html parser. const testData = [ { - 'file': common.fixturesDir + '/sample_document.md', - 'html': '
    1. fish
    2. fish

    3. Redfish

    4. ' + + file: path.join(common.fixturesDir, 'sample_document.md'), + html: '
      1. fish
      2. fish

      3. Redfish

      4. ' + '
      5. Bluefish
      ' }, { - 'file': common.fixturesDir + '/order_of_end_tags_5873.md', - 'html': '

      ClassMethod: Buffer.from(array) ' + + file: path.join(common.fixturesDir, 'order_of_end_tags_5873.md'), + html: '

      ClassMethod: Buffer.from(array) ' + '#