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/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 091dca717b5757..28f8f808808123 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.
@@ -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 \
@@ -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,15 @@ 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)
- $(NODE) tools/doc/generate.js --format=json $< > $@
+# check if ./node is actually set, else use user pre-installed binary
+gen-json = tools/doc/generate.js --format=json $< > $@
+out/doc/api/%.json: doc/api/%.md
+ [ -x $(NODE) ] && $(NODE) $(gen-json) || node $(gen-json)
-out/doc/api/%.html: doc/api/%.md $(NODE_EXE)
- $(NODE) tools/doc/generate.js --format=html --template=doc/template.html $< > $@
+# check if ./node is actually set, else use user pre-installed binary
+gen-html = tools/doc/generate.js --node-version=$(FULLVERSION) --format=html --template=doc/template.html $< > $@
+out/doc/api/%.html: doc/api/%.md
+ [ -x $(NODE) ] && $(NODE) $(gen-html) || node $(gen-html)
docopen: out/doc/api/all.html
-google-chrome out/doc/api/all.html
@@ -423,6 +429,10 @@ PACKAGEMAKER ?= /Developer/Applications/Utilities/PackageMaker.app/Contents/MacO
PKGDIR=out/dist-osx
release-only:
+ @if `grep -q REPLACEME doc/api/*.md`; then \
+ echo 'Please update Added: tags in the documentation first.' ; \
+ exit 1 ; \
+ fi
@if [ "$(shell git status --porcelain | egrep -v '^\?\? ')" = "" ]; then \
exit 0 ; \
else \
@@ -664,4 +674,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/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/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);
}
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/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/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/test/doctool/test-doctool-html.js b/test/doctool/test-doctool-html.js
index afd89489f11ed4..bd21e21d9563d2 100644
--- a/test/doctool/test-doctool-html.js
+++ b/test/doctool/test-doctool-html.js
@@ -3,7 +3,16 @@
const common = require('../common');
const assert = require('assert');
const fs = require('fs');
+const path = require('path');
+// The doctool currently uses js-yaml from the tool/eslint/ tree.
+try {
+ require('../../tools/eslint/node_modules/js-yaml');
+} catch (e) {
+ return common.skip('missing js-yaml (eslint not present)');
+}
+
+const processIncludes = require('../../tools/doc/preprocess.js');
const html = require('../../tools/doc/html.js');
// Test data is a list of objects with two properties.
@@ -13,13 +22,13 @@ const html = require('../../tools/doc/html.js');
// have an html parser.
const testData = [
{
- 'file': common.fixturesDir + '/sample_document.md',
- 'html': 'fish fish
Redfish
' +
+ file: path.join(common.fixturesDir, 'sample_document.md'),
+ html: 'fish fish
Redfish
' +
'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) ' +
'# '
},
+ {
+ file: path.join(common.fixturesDir, 'doc_with_yaml.md'),
+ html: 'Sample Markdown with YAML info' +
+ '# ' +
+ 'Foobar# ' +
+ 'Added in: v1.0.0
' +
+ 'Describe Foobar
in more detail here.
' +
+ 'Foobar II# ' +
+ 'Added in: v5.3.0, v4.2.0
' +
+ 'Describe Foobar II
in more detail here.
' +
+ 'Deprecated thingy# ' +
+ ' ' +
+ 'Added in: v1.0.0 ' +
+ 'Deprecated since: v2.0.0
Describe ' +
+ 'Deprecated thingy
in more detail here.
' +
+ 'Something# ' +
+ ' ' +
+ 'Describe Something
in more detail here. ' +
+ '
'
+ },
+ {
+ file: path.join(common.fixturesDir, 'doc_with_includes.md'),
+ html: '' +
+ 'Look here !
' +
+ '' +
+ '' +
+ 'foobar# ' +
+ 'I exist and am being linked to.
' +
+ ''
+ },
];
testData.forEach(function(item) {
// Normalize expected data by stripping whitespace
const expected = item.html.replace(/\s/g, '');
- fs.readFile(item.file, 'utf8', common.mustCall(function(err, input) {
+ fs.readFile(item.file, 'utf8', common.mustCall((err, input) => {
assert.ifError(err);
- html(input, 'foo', 'doc/template.html',
- common.mustCall(function(err, output) {
- assert.ifError(err);
-
- const actual = output.replace(/\s/g, '');
- // Assert that the input stripped of all whitespace contains the
- // expected list
- assert.notEqual(actual.indexOf(expected), -1);
- }));
+ processIncludes(item.file, input, common.mustCall((err, preprocessed) => {
+ assert.ifError(err);
+
+ html(
+ {
+ input: preprocessed,
+ filename: 'foo',
+ template: 'doc/template.html',
+ nodeVersion: process.version,
+ },
+ common.mustCall((err, output) => {
+ assert.ifError(err);
+
+ const actual = output.replace(/\s/g, '');
+ // Assert that the input stripped of all whitespace contains the
+ // expected list
+ assert.notEqual(actual.indexOf(expected), -1);
+ }));
+ }));
}));
});
diff --git a/test/doctool/test-doctool-json.js b/test/doctool/test-doctool-json.js
index 31e260fcb02d43..520c79bef8bcda 100644
--- a/test/doctool/test-doctool-json.js
+++ b/test/doctool/test-doctool-json.js
@@ -3,6 +3,14 @@
const common = require('../common');
const assert = require('assert');
const fs = require('fs');
+const path = require('path');
+
+// The doctool currently uses js-yaml from the tool/eslint/ tree.
+try {
+ require('../../tools/eslint/node_modules/js-yaml');
+} catch (e) {
+ return common.skip('missing js-yaml (eslint not present)');
+}
const json = require('../../tools/doc/json.js');
@@ -12,57 +20,118 @@ const json = require('../../tools/doc/json.js');
// The json property is some json which will be generated by the doctool.
var testData = [
{
- 'file': common.fixturesDir + '/sample_document.md',
- 'json': {
- 'source': 'foo',
- 'modules': [ { 'textRaw': 'Sample Markdown',
- 'name': 'sample_markdown',
- 'modules': [ { 'textRaw':'Seussian Rhymes',
- 'name': 'seussian_rhymes',
- 'desc': '\nfish \nfish
\n \n' +
+ file: path.join(common.fixturesDir, 'sample_document.md'),
+ json: {
+ source: 'foo',
+ modules: [{
+ textRaw: 'Sample Markdown',
+ name: 'sample_markdown',
+ modules: [{
+ textRaw: 'Seussian Rhymes',
+ name: 'seussian_rhymes',
+ desc: '\nfish \nfish
\n \n' +
'Red fish
\n \nBlue fish \n \n',
- 'type': 'module',
- 'displayName': 'Seussian Rhymes'
- } ],
- 'type': 'module',
- 'displayName': 'Sample Markdown'
- } ]
+ type: 'module',
+ displayName: 'Seussian Rhymes'
+ }],
+ type: 'module',
+ displayName: 'Sample Markdown'
+ }]
}
},
{
- 'file': common.fixturesDir + '/order_of_end_tags_5873.md',
- 'json': {
- 'source':'foo',
- 'modules': [ {
- 'textRaw': 'Title',
- 'name': 'title',
- 'modules': [ {
- 'textRaw': 'Subsection',
- 'name': 'subsection',
- 'classMethods': [ {
- 'textRaw': 'Class Method: Buffer.from(array)',
- 'type':'classMethod',
- 'name':'from',
- 'signatures': [ {
- 'params': [ {
- 'textRaw': '`array` {Array} ',
- 'name': 'array',
- 'type': 'Array'
- } ]
- },
+ file: path.join(common.fixturesDir, 'order_of_end_tags_5873.md'),
+ json: {
+ source: 'foo',
+ modules: [{
+ textRaw: 'Title',
+ name: 'title',
+ modules: [{
+ textRaw: 'Subsection',
+ name: 'subsection',
+ classMethods: [{
+ textRaw: 'Class Method: Buffer.from(array)',
+ type: 'classMethod',
+ name: 'from',
+ signatures: [
+ {
+ params: [{
+ textRaw: '`array` {Array} ',
+ name: 'array',
+ type: 'Array'
+ }]
+ },
{
- 'params' : [ {
- 'name': 'array'
- } ]
+ params: [{
+ name: 'array'
+ }]
}
]
- } ],
- 'type': 'module',
- 'displayName': 'Subsection'
- } ],
- 'type': 'module',
- 'displayName': 'Title'
- } ]
+ }],
+ type: 'module',
+ displayName: 'Subsection'
+ }],
+ type: 'module',
+ displayName: 'Title'
+ }]
+ }
+ },
+ {
+ file: path.join(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',
+ 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',
+ type: 'module',
+ displayName: 'Foobar II'
+ },
+ {
+ textRaw: 'Deprecated thingy',
+ name: 'deprecated_thingy',
+ meta: {
+ added: ['v1.0.0'],
+ deprecated: ['v2.0.0']
+ },
+ desc: 'Describe Deprecated thingy
in more ' +
+ 'detail here.
\n',
+ type: 'module',
+ displayName: 'Deprecated thingy'
+ },
+ {
+ textRaw: 'Something',
+ name: 'something',
+ desc: '\n' +
+ 'Describe Something
in more detail here.
\n',
+ type: 'module',
+ displayName: 'Something'
+ }
+ ],
+ type: 'module',
+ displayName: 'Sample Markdown with YAML info'
+ }
+ ]
}
}
];
diff --git a/test/fixtures/doc_inc_1.md b/test/fixtures/doc_inc_1.md
new file mode 100644
index 00000000000000..92858d0200c237
--- /dev/null
+++ b/test/fixtures/doc_inc_1.md
@@ -0,0 +1,3 @@
+Look [here][]!
+
+[here]: doc_inc_2.html#doc_inc_2_foobar
diff --git a/test/fixtures/doc_inc_2.md b/test/fixtures/doc_inc_2.md
new file mode 100644
index 00000000000000..17d0b86a0cc51f
--- /dev/null
+++ b/test/fixtures/doc_inc_2.md
@@ -0,0 +1,3 @@
+# foobar
+
+I exist and am being linked to.
diff --git a/test/fixtures/doc_with_includes.md b/test/fixtures/doc_with_includes.md
new file mode 100644
index 00000000000000..901bf0f1b0bf3b
--- /dev/null
+++ b/test/fixtures/doc_with_includes.md
@@ -0,0 +1,2 @@
+@include doc_inc_1
+@include doc_inc_2.md
diff --git a/test/fixtures/doc_with_yaml.md b/test/fixtures/doc_with_yaml.md
new file mode 100644
index 00000000000000..493c2e7e4268b2
--- /dev/null
+++ b/test/fixtures/doc_with_yaml.md
@@ -0,0 +1,30 @@
+# Sample Markdown with YAML info
+
+## Foobar
+
+
+Describe `Foobar` in more detail here.
+
+## Foobar II
+
+
+Describe `Foobar II` in more detail here.
+
+## Deprecated thingy
+
+
+Describe `Deprecated thingy` in more detail here.
+
+## Something
+
+
+Describe `Something` in more detail here.
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-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-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..08f13c809df51e 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',
@@ -912,7 +912,7 @@ var parseTestsWithQueryString = {
path: '/example',
href: '/example'
},
- '/example?query=value':{
+ '/example?query=value': {
protocol: null,
slashes: null,
auth: null,
@@ -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/README.md b/tools/doc/README.md
index fd041f001e6931..1620d6c25acbc9 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?
@@ -25,7 +34,19 @@ Each type of heading has a description block.
A description of the function.
+ ### module.someNewFunction(x)
+
+
+ * `x` {String} the description of the string
+
+ This feature is not in a release yet.
+
### Event: 'blerg'
+
* Argument: SomeClass object.
@@ -33,10 +54,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 +73,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/addon-verify.js b/tools/doc/addon-verify.js
index 2abd3574cffd7f..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;
@@ -82,6 +82,7 @@ ${files[name]}
targets: [
{
target_name: 'addon',
+ defines: [ 'V8_DEPRECATION_WARNINGS=1' ],
sources: files.map(function(file) {
return file.name;
})
diff --git a/tools/doc/common.js b/tools/doc/common.js
new file mode 100644
index 00000000000000..c2f561da806577
--- /dev/null
+++ b/tools/doc/common.js
@@ -0,0 +1,40 @@
+'use strict';
+
+const yaml = require('js-yaml');
+
+function isYAMLBlock(text) {
+ return !!text.match(/^$/, '');
+
+ // js-yaml.safeLoad() throws on error
+ 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/generate.js b/tools/doc/generate.js
index ff14cbd5e8979b..077e740432c837 100644
--- a/tools/doc/generate.js
+++ b/tools/doc/generate.js
@@ -1,15 +1,16 @@
'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;
+let nodeVersion = null;
args.forEach(function(arg) {
if (!arg.match(/^\-\-/)) {
@@ -18,15 +19,17 @@ 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=/, '');
}
});
+nodeVersion = nodeVersion || process.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 +37,6 @@ fs.readFile(inputFile, 'utf8', function(er, input) {
processIncludes(inputFile, input, next);
});
-
function next(er, input) {
if (er) throw er;
switch (format) {
@@ -46,10 +48,19 @@ function next(er, input) {
break;
case 'html':
- require('./html.js')(input, inputFile, template, function(er, html) {
- if (er) throw er;
- console.log(html);
- });
+ require('./html.js')(
+ {
+ input: input,
+ filename: inputFile,
+ template: template,
+ nodeVersion: 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 68ccf976b6c1f8..769d601e26c800 100644
--- a/tools/doc/html.js
+++ b/tools/doc/html.js
@@ -1,13 +1,23 @@
'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;
+// 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,
@@ -20,7 +30,13 @@ 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;
+ var nodeVersion = opts.nodeVersion || process.version;
+
if (gtocData) {
return onGtocLoaded();
}
@@ -41,10 +57,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: nodeVersion,
+ }, cb);
});
}
}
@@ -71,7 +92,15 @@ 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;
+ var nodeVersion = opts.nodeVersion || process.version;
+
// get the section
var section = getSection(lexed);
@@ -90,7 +119,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, nodeVersion);
template = template.replace(/__TOC__/g, toc);
template = template.replace(
/__GTOC__/g,
@@ -142,12 +171,15 @@ 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);
return;
}
+ if (tok.type === 'html' && common.isYAMLBlock(tok.text)) {
+ tok.text = parseYAML(tok.text);
+ }
state = null;
output.push(tok);
return;
@@ -163,7 +195,7 @@ function parseLists(input) {
output.push(tok);
if (depth === 0) {
state = null;
- output.push({ type:'html', text: '
' });
+ output.push({ type: 'html', text: '
' });
}
return;
}
@@ -174,6 +206,21 @@ function parseLists(input) {
return output;
}
+function parseYAML(text) {
+ const meta = common.extractAndParseYAML(text);
+ const html = [''];
+
+ if (meta.added) {
+ html.push(`Added in: ${meta.added.join(', ')} `);
+ }
+
+ if (meta.deprecated) {
+ html.push(`Deprecated since: ${meta.deprecated.join(', ')} `);
+ }
+
+ html.push('
');
+ return html.join('\n');
+}
// Syscalls which appear in the docs, but which only exist in BSD / OSX
var BSD_ONLY_SYSCALLS = new Set(['lchmod']);
@@ -236,7 +283,21 @@ function getSection(lexed) {
function buildToc(lexed, filename, cb) {
var toc = [];
var depth = 0;
+
+ const startIncludeRefRE = /^\s*\s*$/;
+ const endIncludeRefRE = /^\s*\s*$/;
+ const realFilenames = [filename];
+
lexed.forEach(function(tok) {
+ // Keep track of the current filename along @include directives.
+ if (tok.type === 'html') {
+ let match;
+ if ((match = tok.text.match(startIncludeRefRE)) !== null)
+ realFilenames.unshift(match[1]);
+ else if (tok.text.match(endIncludeRefRE))
+ realFilenames.shift();
+ }
+
if (tok.type !== 'heading') return;
if (tok.depth - depth > 1) {
return cb(new Error('Inappropriate heading level\n' +
@@ -244,7 +305,8 @@ function buildToc(lexed, filename, cb) {
}
depth = tok.depth;
- var id = getId(filename + '_' + tok.text.trim());
+ const realFilename = path.basename(realFilenames[0], '.md');
+ const id = getId(realFilename + '_' + tok.text.trim());
toc.push(new Array((depth - 1) * 2 + 1).join(' ') +
'* ' +
tok.text + ' ');
diff --git a/tools/doc/json.js b/tools/doc/json.js
index 3d08026daaabd8..33bde6515b1235 100644
--- a/tools/doc/json.js
+++ b/tools/doc/json.js
@@ -5,7 +5,17 @@ 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');
+
+// 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};
@@ -91,6 +101,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 +286,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) {
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/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
+
+```
+
+
+```
+$ marked
+ * item1
+
+ * item2
+
+ text
+^D
+
+```
+
+Which looks correct to you?
+
+- - -
+
+```
+$ markdown.pl
+* hello
+ > world
+^D
+
+
+```
+
+```
+$ marked
+* hello
+ > world
+^D
+
+```
+
+Again, which looks correct to you?
+
+- - -
+
+EXAMPLE:
+
+```
+$ markdown.pl
+* hello
+ * world
+ * hi
+ code
+^D
+
+```
+
+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
+
+```
+
+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
+
+```
+
+Misnested tags.
+
+
+```
+$ marked
+ * item1
+
+ * item2
+
+ text
+^D
+
+```
+
+Which looks correct to you?
+
+- - -
+
+```
+$ markdown.pl
+* hello
+ > world
+^D
+
+
+```
+
+More misnested tags.
+
+
+```
+$ marked
+* hello
+ > world
+^D
+
+```
+
+Again, which looks correct to you?
+
+- - -
+
+# Why quality matters - Part 2
+
+``` bash
+$ markdown.pl
+* hello
+ > world
+^D
+
+
+```
+
+``` bash
+$ sundown # upskirt
+* hello
+ > world
+^D
+
+```
+
+``` bash
+$ marked
+* hello
+ > world
+^D
+
+```
+
+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
+
+
+```
+
+- - -
+
+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
+
+
+
+are
+you
+
+
+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: /^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +["(]([^\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]*?)>?(?:\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 '\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 + '' + type + '>\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 + '' + type + '>\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 = '' + text + ' ';
+ return out;
+};
+Renderer.prototype.image = function(href, title, text) {
+ var out = ' ' : '>';
return out;
};
-var outputLink = function(cap, link) {
- if (cap[0][0] !== '!') {
- return ''
- + inline.lexer(cap[1])
- + ' ';
- } else {
- return ' ';
+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
- + ''
- + type
- + '>\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:/^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +["(]([^\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"\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+""+type+">\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+""+type+">\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='"+text+" ";return out};Renderer.prototype.image=function(href,title,text){var out=' ":">";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 d87c9345b33f2e..41a50ac04ed188 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.3.5",
+ "js-yaml": "^3.5.2"
},
"devDependencies": {},
"optionalDependencies": {},
diff --git a/tools/doc/preprocess.js b/tools/doc/preprocess.js
index 295737a2a53aee..55d90996f71c13 100644
--- a/tools/doc/preprocess.js
+++ b/tools/doc/preprocess.js
@@ -48,7 +48,11 @@ function processIncludes(inputFile, input, cb) {
if (errState) return;
if (er) return cb(errState = er);
incCount--;
- includeData[fname] = inc;
+
+ // Add comments to let the HTML generator know how the anchors for
+ // headings should look like.
+ includeData[fname] = `\n` +
+ inc + `\n\n`;
input = input.split(include + '\n').join(includeData[fname] + '\n');
if (incCount === 0) {
return cb(null, input);