build(aio): implement the remark renderer

The implementation adds three plugins to the remark processor:

* remove support for code blocks triggered by indented
text - only gfm triple backticks are supported; and also adds support for
dgeni inline tags.

* ignore content within `code-example` and `code-tabs` elements. This prevents
the content being accidentally treated as markdown

* ignore dgeni inline tags, e.g. `{@link ... }` to prevent the content of
the links from being accidentally treated as markdown
This commit is contained in:
Peter Bacon Darwin 2017-04-11 18:24:08 +01:00 committed by Igor Minar
parent 540581da3e
commit 374bf1ed98
6 changed files with 659 additions and 5 deletions

View File

@ -72,6 +72,8 @@
"karma-jasmine-html-reporter": "^0.2.2",
"lodash": "^4.17.4",
"protractor": "~5.1.0",
"remark": "^7.0.0",
"remark-html": "^6.0.0",
"rho": "https://github.com/petebacondarwin/rho#master",
"rimraf": "^2.6.1",
"shelljs": "^0.7.7",

View File

@ -17,7 +17,7 @@ const linksPackage = require('../links-package');
const examplesPackage = require('../examples-package');
const targetPackage = require('../target-package');
const contentPackage = require('../content-package');
const rhoPackage = require('../rho-package');
const remarkPackage = require('../remark-package');
const PROJECT_ROOT = path.resolve(__dirname, '../../..');
const API_SOURCE_PATH = path.resolve(PROJECT_ROOT, 'packages');
@ -31,7 +31,7 @@ module.exports =
new Package(
'angular.io', [
jsdocPackage, nunjucksPackage, typescriptPackage, linksPackage, examplesPackage,
gitPackage, targetPackage, contentPackage, rhoPackage
gitPackage, targetPackage, contentPackage, remarkPackage
])
// Register the processors

View File

@ -0,0 +1,9 @@
var Package = require('dgeni').Package;
/**
* @dgPackage remark
* @description Overrides the renderMarkdown service with an implementation based on remark
*/
module.exports = new Package('remark', ['nunjucks'])
.factory(require('./services/renderMarkdown'));

View File

@ -0,0 +1,209 @@
const remark = require('remark');
const html = require('remark-html');
/**
* @dgService renderMarkdown
* @description
* Render the markdown in the given string as HTML.
*/
module.exports = function renderMarkdown() {
const renderer = remark()
.use(inlineTagDefs)
.use(noIndentedCodeBlocks)
.use(plainHTMLBlocks)
// USEFUL DEBUGGING CODE
// .use(() => tree => {
// console.log(require('util').inspect(tree, { colors: true, depth: 4 }));
// })
.use(html);
return function renderMarkdownImpl(content) {
return renderer.processSync(content).toString();
};
/**
* Teach remark not to render indented codeblocks
*/
function noIndentedCodeBlocks() {
const blockMethods = this.Parser.prototype.blockMethods;
blockMethods.splice(blockMethods.indexOf('indentedCode'), 1);
}
/**
* Teach remark about inline tags, so that it neither wraps block level
* tags in paragraphs nor processes the text within the tag.
*/
function inlineTagDefs() {
const Parser = this.Parser;
const inlineTokenizers = Parser.prototype.inlineTokenizers;
const inlineMethods = Parser.prototype.inlineMethods;
const blockTokenizers = Parser.prototype.blockTokenizers;
const blockMethods = Parser.prototype.blockMethods;
blockTokenizers.inlineTag = tokenizeInlineTag;
blockMethods.splice(blockMethods.indexOf('paragraph'), 0, 'inlineTag');
inlineTokenizers.inlineTag = tokenizeInlineTag;
inlineMethods.splice(blockMethods.indexOf('text'), 0, 'inlineTag');
tokenizeInlineTag.notInLink = true;
tokenizeInlineTag.locator = inlineTagLocator;
function tokenizeInlineTag(eat, value, silent) {
const match = /^\{@[^\s\}]+[^\}]*\}/.exec(value);
if (match) {
if (silent) {
return true;
}
return eat(match[0])({
'type': 'inlineTag',
'value': match[0]
});
}
}
function inlineTagLocator(value, fromIndex) {
return value.indexOf('{@', fromIndex);
}
}
/**
* Teach remark that some HTML blocks never include markdown
*/
function plainHTMLBlocks() {
const plainBlocks = ['code-example', 'code-tabs'];
// Create matchers for each block
const anyBlockMatcher = new RegExp('^' + createOpenMatcher(`(${plainBlocks.join('|')})`));
const Parser = this.Parser;
const blockTokenizers = Parser.prototype.blockTokenizers;
const blockMethods = Parser.prototype.blockMethods;
blockTokenizers.plainHTMLBlocks = tokenizePlainHTMLBlocks;
blockMethods.splice(blockMethods.indexOf('html'), 0, 'plainHTMLBlocks');
function tokenizePlainHTMLBlocks(eat, value, silent) {
const openMatch = anyBlockMatcher.exec(value);
if (openMatch) {
const blockName = openMatch[1];
const fullMatch = matchRecursiveRegExp(value, createOpenMatcher(blockName), createCloseMatcher(blockName))[0];
if (silent || !fullMatch) {
// either we are not eating (silent) or the match failed
return !!fullMatch;
}
return eat(fullMatch[0])({
type: 'html',
value: fullMatch[0]
});
}
}
}
};
/**
* matchRecursiveRegExp
*
* (c) 2007 Steven Levithan <stevenlevithan.com>
* MIT License
*
* Accepts a string to search, a left and right format delimiter
* as regex patterns, and optional regex flags. Returns an array
* of matches, allowing nested instances of left/right delimiters.
* Use the "g" flag to return all matches, otherwise only the
* first is returned. Be careful to ensure that the left and
* right format delimiters produce mutually exclusive matches.
* Backreferences are not supported within the right delimiter
* due to how it is internally combined with the left delimiter.
* When matching strings whose format delimiters are unbalanced
* to the left or right, the output is intentionally as a
* conventional regex library with recursion support would
* produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using
* "<" and ">" as the delimiters (both strings contain a single,
* balanced instance of "<x>").
*
* examples:
* matchRecursiveRegExp("test", "\\(", "\\)")
* returns: []
* matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g")
* returns: ["t<<e>><s>", ""]
* matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi")
* returns: ["test"]
*/
function matchRecursiveRegExp(str, left, right, flags) {
'use strict';
const matchPos = rgxFindMatchPos(str, left, right, flags);
const results = [];
for (var i = 0; i < matchPos.length; ++i) {
results.push([
str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
str.slice(matchPos[i].match.start, matchPos[i].match.end),
str.slice(matchPos[i].left.start, matchPos[i].left.end),
str.slice(matchPos[i].right.start, matchPos[i].right.end)
]);
}
return results;
}
function rgxFindMatchPos(str, left, right, flags) {
'use strict';
flags = flags || '';
const global = flags.indexOf('g') > -1;
const bothMatcher = new RegExp(left + '|' + right, 'g' + flags.replace(/g/g, ''));
const leftMatcher = new RegExp(left, flags.replace(/g/g, ''));
const pos = [];
let index, match, start, end;
let count = 0;
do {
while ((match = bothMatcher.exec(str))) {
if (leftMatcher.test(match[0])) {
if (!(count++)) {
index = bothMatcher.lastIndex;
start = index - match[0].length;
}
} else if (count) {
if (!--count) {
end = match.index + match[0].length;
var obj = {
left: {start: start, end: index},
match: {start: index, end: match.index},
right: {start: match.index, end: end},
wholeMatch: {start: start, end: end}
};
pos.push(obj);
if (!global) {
return pos;
}
}
}
}
} while (count && (bothMatcher.lastIndex = index));
return pos;
}
function createOpenMatcher(elementNameMatcher) {
const attributeName = '[a-zA-Z_:][a-zA-Z0-9:._-]*';
const unquoted = '[^"\'=<>`\\u0000-\\u0020]+';
const singleQuoted = '\'[^\']*\'';
const doubleQuoted = '"[^"]*"';
const attributeValue = '(?:' + unquoted + '|' + singleQuoted + '|' + doubleQuoted + ')';
const attribute = '(?:\\s+' + attributeName + '(?:\\s*=\\s*' + attributeValue + ')?)';
return `<${elementNameMatcher}${attribute}*\\s*>`;
}
function createCloseMatcher(elementNameMatcher) {
return `</${elementNameMatcher}>`;
}

View File

@ -0,0 +1,70 @@
const renderMarkdownFactory = require('./renderMarkdown');
describe('remark: renderMarkdown service', () => {
let renderMarkdown;
beforeEach(() => {
renderMarkdown = renderMarkdownFactory();
});
it('should convert markdown to HTML', () => {
const content = '# heading 1\n' +
'\n' +
'A paragraph with **bold** and _italic_.\n' +
'\n' +
'* List item 1\n' +
'* List item 2';
const output = renderMarkdown(content);
expect(output).toEqual(
'<h1>heading 1</h1>\n' +
'<p>A paragraph with <strong>bold</strong> and <em>italic</em>.</p>\n' +
'<ul>\n' +
'<li>List item 1</li>\n' +
'<li>List item 2</li>\n' +
'</ul>\n');
});
it('should not process markdown inside inline tags', () => {
const content = '# heading {@link some_url_path}';
const output = renderMarkdown(content);
expect(output).toEqual('<h1>heading {@link some_url_path}</h1>\n');
});
it('should not put block level inline tags inside paragraphs', () => {
const content = 'A paragraph.\n' +
'\n' +
'{@example blah **blah** blah }\n' +
'\n' +
'Another paragraph {@link _containing_ } an inline tag';
const output = renderMarkdown(content);
expect(output).toEqual(
'<p>A paragraph.</p>\n' +
'{@example blah **blah** blah }\n' +
'<p>Another paragraph {@link _containing_ } an inline tag</p>\n');
});
it('should not format the contents of tags marked as unformatted ', () => {
const content = '<code-example>\n\n **abc**\n\n def\n</code-example>\n\n<code-tabs><code-pane>\n\n **abc**\n\n def\n</code-pane></code-tabs>';
const output = renderMarkdown(content);
expect(output).toEqual('<code-example>\n\n **abc**\n\n def\n</code-example>\n<code-tabs><code-pane>\n\n **abc**\n\n def\n</code-pane></code-tabs>\n');
});
it('should not remove spaces after anchor tags', () => {
var input =
'A aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaa aaaaaaaaaa aaaaaaaaaaa\n' +
'[foo](path/to/foo) bbb.';
var output =
'<p>' +
'A aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaa aaaaaaaaaa aaaaaaaaaaa\n' +
'<a href="path/to/foo">foo</a> bbb.' +
'</p>\n';
expect(renderMarkdown(input)).toEqual(output);
});
it('should not format indented text as code', () => {
const content = 'some text\n\n indented text\n\nother text';
const output = renderMarkdown(content);
expect(output).toEqual('<p>some text</p>\n<p> indented text</p>\n<p>other text</p>\n');
});
});

View File

@ -364,6 +364,12 @@ array-flatten@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296"
array-iterate@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/array-iterate/-/array-iterate-1.1.0.tgz#4f13148ffffa5f2756b50460e5eac8eed31a14e6"
dependencies:
has "^1.0.1"
array-slice@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5"
@ -564,6 +570,10 @@ backo2@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
bail@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.1.tgz#912579de8b391aadf3c5fdf4cd2a0fc225df3bc2"
balanced-match@^0.4.1, balanced-match@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
@ -895,6 +905,10 @@ catharsis@^0.8.1:
dependencies:
underscore-contrib "~0.3.0"
ccount@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.1.tgz#665687945168c218ec77ff61a4155ae00227a96c"
center-align@^0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
@ -947,6 +961,22 @@ char-spinner@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/char-spinner/-/char-spinner-1.0.1.tgz#e6ea67bd247e107112983b7ab0479ed362800081"
character-entities-html4@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.0.tgz#1ab08551d3ce1fa1df08d00fb9ca1defb147a06c"
character-entities-legacy@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.0.tgz#b18aad98f6b7bcc646c1e4c81f9f1956376a561a"
character-entities@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.0.tgz#a683e2cf75dbe8b171963531364e58e18a1b155f"
character-reference-invalid@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.0.tgz#dec9ad1dfb9f8d06b4fcdaa2adc3c4fd97af1e68"
chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.6.0:
version "1.6.1"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2"
@ -1061,6 +1091,10 @@ codelyzer@~2.0.0:
source-map "^0.5.6"
sprintf-js "^1.0.3"
collapse-white-space@^1.0.0, collapse-white-space@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.2.tgz#9c463fb9c6d190d2dcae21a356a01bcae9eeef6d"
color-convert@^1.3.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
@ -1113,6 +1147,12 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
dependencies:
delayed-stream "~1.0.0"
comma-separated-tokens@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.2.tgz#4b64717a2ee363af6dd39878336bd95e42d063e7"
dependencies:
trim "0.0.1"
commander@2.9.x, commander@^2.8.1, commander@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
@ -1614,6 +1654,12 @@ destroy@^1.0.3, destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
detab@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.0.tgz#485bd7954d2348092e998f7ff1a79fd9869d9b50"
dependencies:
repeat-string "^1.5.4"
detect-indent@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
@ -2785,6 +2831,38 @@ hash.js@^1.0.0:
dependencies:
inherits "^2.0.1"
hast-util-is-element@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-1.0.0.tgz#3f7216978b2ae14d98749878782675f33be3ce00"
hast-util-sanitize@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/hast-util-sanitize/-/hast-util-sanitize-1.1.0.tgz#9b4bc3731043fe92e1253a9a4ca7bcc4148d06f2"
dependencies:
has "^1.0.1"
xtend "^4.0.1"
hast-util-to-html@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-3.0.0.tgz#19a257cd7af464777c1cccf4d2d53d33147466c1"
dependencies:
ccount "^1.0.0"
comma-separated-tokens "^1.0.1"
has "^1.0.1"
hast-util-is-element "^1.0.0"
hast-util-whitespace "^1.0.0"
html-void-elements "^1.0.0"
kebab-case "^1.0.0"
property-information "^3.1.0"
space-separated-tokens "^1.0.0"
stringify-entities "^1.0.1"
unist-util-is "^2.0.0"
xtend "^4.0.1"
hast-util-whitespace@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-1.0.0.tgz#bd096919625d2936e1ff17bc4df7fd727f17ece9"
hawk@~3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
@ -2853,6 +2931,10 @@ html-minifier@^3.2.3:
relateurl "0.2.x"
uglify-js "2.7.x"
html-void-elements@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.1.tgz#f929bea267a19e3535950502ca12c159f1b559af"
html-webpack-plugin@^2.19.0:
version "2.28.0"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-2.28.0.tgz#2e7863b57e5fd48fe263303e2ffc934c3064d009"
@ -3075,6 +3157,21 @@ is-absolute-url@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
is-alphabetical@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.0.tgz#e2544c13058255f2144cb757066cd3342a1c8c46"
is-alphanumeric@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz#4a9cef71daf4c001c1d81d63d140cf53fd6889f4"
is-alphanumerical@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.0.tgz#e06492e719c1bf15dec239e4f1af5f67b4d6e7bf"
dependencies:
is-alphabetical "^1.0.0"
is-decimal "^1.0.0"
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
@ -3085,7 +3182,7 @@ is-binary-path@^1.0.0:
dependencies:
binary-extensions "^1.0.0"
is-buffer@^1.0.2:
is-buffer@^1.0.2, is-buffer@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b"
@ -3095,6 +3192,10 @@ is-builtin-module@^1.0.0:
dependencies:
builtin-modules "^1.0.0"
is-decimal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.0.tgz#940579b6ea63c628080a69e62bda88c8470b4fe0"
is-dotfile@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d"
@ -3145,6 +3246,10 @@ is-glob@^3.1.0:
dependencies:
is-extglob "^2.1.0"
is-hexadecimal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.0.tgz#5c459771d2af9a2e3952781fd54fcb1bcfe4113c"
is-lower-case@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393"
@ -3194,7 +3299,7 @@ is-path-inside@^1.0.0:
dependencies:
path-is-inside "^1.0.1"
is-plain-obj@^1.0.0:
is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
@ -3256,6 +3361,14 @@ is-utf8@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
is-whitespace-character@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.0.tgz#bbf4a83764ead0d451bec2a55218e91961adc275"
is-word-character@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.0.tgz#a3a9e5ddad70c5c2ee36f4a9cfc9a53f44535247"
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
@ -3264,6 +3377,10 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isarray@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e"
isbinaryfile@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621"
@ -3614,6 +3731,10 @@ karma@~1.4.1:
tmp "0.0.28"
useragent "^2.1.10"
kebab-case@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/kebab-case/-/kebab-case-1.0.0.tgz#3f9e4990adcad0c686c0e701f7645868f75f91eb"
kind-of@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47"
@ -3818,6 +3939,10 @@ log4js@^0.6.31:
readable-stream "~1.0.2"
semver "~4.3.3"
longest-streak@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.1.tgz#42d291b5411e40365c00e63193497e2247316e35"
longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
@ -3878,6 +4003,14 @@ map-obj@^1.0.0, map-obj@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
markdown-escapes@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.0.tgz#c8ca19f1d94d682459e0a93c86db27a7ef716b23"
markdown-table@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.0.tgz#1f5ae61659ced8808d882554c32e8b3f38dd1143"
marked@^0.3.2:
version "0.3.6"
resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.6.tgz#b2c6c618fccece4ef86c4fc6cb8a7cbf5aeda8d7"
@ -3892,6 +4025,37 @@ math-expression-evaluator@^1.2.14:
version "1.2.16"
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.16.tgz#b357fa1ca9faefb8e48d10c14ef2bcb2d9f0a7c9"
mdast-util-compact@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.0.tgz#4c94dedfe35932d5457f29b650b330fdc73e994a"
dependencies:
unist-util-modify-children "^1.0.0"
unist-util-visit "^1.1.0"
mdast-util-definitions@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-1.2.0.tgz#00f67b4289ed36bafc0977b558414ac0c5023b24"
dependencies:
has "^1.0.1"
unist-util-visit "^1.0.0"
mdast-util-to-hast@^2.1.1:
version "2.4.0"
resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-2.4.0.tgz#63ce8e43c61d8e5728954a3515e0c936a3b26cea"
dependencies:
collapse-white-space "^1.0.0"
detab "^2.0.0"
has "^1.0.1"
mdast-util-definitions "^1.2.0"
normalize-uri "^1.0.0"
trim "0.0.1"
trim-lines "^1.0.0"
unist-builder "^1.0.1"
unist-util-generated "^1.1.0"
unist-util-position "^3.0.0"
unist-util-visit "^1.1.0"
xtend "^4.0.1"
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@ -4208,6 +4372,10 @@ normalize-range@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
normalize-uri@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/normalize-uri/-/normalize-uri-1.1.0.tgz#01fb440c7fd059b9d9be8645aac14341efd059dd"
normalize-url@^1.4.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.0.tgz#c2bb50035edee62cd81edb2d45da68dc25e3423e"
@ -4444,6 +4612,18 @@ parse-asn1@^5.0.0:
evp_bytestokey "^1.0.0"
pbkdf2 "^3.0.3"
parse-entities@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.0.tgz#4bc58f35fdc8e65dded35a12f2e40223ca24a3f7"
dependencies:
character-entities "^1.0.0"
character-entities-legacy "^1.0.0"
character-reference-invalid "^1.0.0"
has "^1.0.1"
is-alphanumerical "^1.0.0"
is-decimal "^1.0.0"
is-hexadecimal "^1.0.0"
parse-glob@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
@ -4885,6 +5065,10 @@ promise@^7.1.1:
dependencies:
asap "~2.0.3"
property-information@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/property-information/-/property-information-3.1.0.tgz#1581bf8a445dfbfef759775a86700e8dda18b4a1"
protractor@~5.1.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.1.1.tgz#10c4e336571b28875b8acc3ae3e4e1e40ef7e986"
@ -5180,6 +5364,63 @@ relateurl@0.2.x:
version "0.2.7"
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
remark-html@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/remark-html/-/remark-html-6.0.0.tgz#ade7d94b60e452158f28615218450682601dbfc1"
dependencies:
hast-util-sanitize "^1.0.0"
hast-util-to-html "^3.0.0"
mdast-util-to-hast "^2.1.1"
xtend "^4.0.1"
remark-parse@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-3.0.0.tgz#f078c8c9976efb0f2afd011c79f30708354593b1"
dependencies:
collapse-white-space "^1.0.2"
has "^1.0.1"
is-alphabetical "^1.0.0"
is-decimal "^1.0.0"
is-whitespace-character "^1.0.0"
is-word-character "^1.0.0"
markdown-escapes "^1.0.0"
parse-entities "^1.0.2"
repeat-string "^1.5.4"
state-toggle "^1.0.0"
trim "0.0.1"
trim-trailing-lines "^1.0.0"
unherit "^1.0.4"
unist-util-remove-position "^1.0.0"
vfile-location "^2.0.0"
xtend "^4.0.1"
remark-stringify@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-3.0.0.tgz#f1720893a3e7c845824d95bb573d628d1346ba2a"
dependencies:
ccount "^1.0.0"
is-alphanumeric "^1.0.0"
is-decimal "^1.0.0"
is-whitespace-character "^1.0.0"
longest-streak "^2.0.1"
markdown-escapes "^1.0.0"
markdown-table "^1.1.0"
mdast-util-compact "^1.0.0"
parse-entities "^1.0.2"
repeat-string "^1.5.4"
state-toggle "^1.0.0"
stringify-entities "^1.0.1"
unherit "^1.0.4"
xtend "^4.0.1"
remark@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/remark/-/remark-7.0.0.tgz#ce9c788c390d98d9a67cb7738e98246732e79144"
dependencies:
remark-parse "^3.0.0"
remark-stringify "^3.0.0"
unified "^6.0.0"
renderkid@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.0.tgz#1859753e7a5adbf35443aba0d4e4579e78abee85"
@ -5198,7 +5439,7 @@ repeat-string@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae"
repeat-string@^1.5.2:
repeat-string@^1.5.2, repeat-string@^1.5.4:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
@ -5214,6 +5455,10 @@ repeating@^2.0.0:
dependencies:
is-finite "^1.0.0"
replace-ext@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
request@2, request@2.x, request@^2.58.0, request@^2.61.0, request@^2.72.0, request@^2.78.0, request@^2.79.0:
version "2.79.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
@ -5660,6 +5905,12 @@ source-map@~0.2.0:
dependencies:
amdefine ">=0.0.4"
space-separated-tokens@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.0.tgz#9e8c60407aa527742cd9eaee2541dec639f1269b"
dependencies:
trim "0.0.1"
spdx-correct@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
@ -5721,6 +5972,10 @@ stack-trace@0.0.x:
version "0.0.9"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695"
state-toggle@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.0.tgz#d20f9a616bb4f0c3b98b91922d25b640aa2bc425"
"statuses@>= 1.3.1 < 2", statuses@~1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
@ -5781,6 +6036,16 @@ string_decoder@^0.10.25, string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
stringify-entities@^1.0.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-1.3.0.tgz#2244a516c4f1e8e01b73dad01023016776abd917"
dependencies:
character-entities-html4 "^1.0.0"
character-entities-legacy "^1.0.0"
has "^1.0.1"
is-alphanumerical "^1.0.0"
is-hexadecimal "^1.0.0"
stringmap@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/stringmap/-/stringmap-0.2.2.tgz#556c137b258f942b8776f5b2ef582aa069d7d1b1"
@ -6077,6 +6342,10 @@ tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
trim-lines@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-1.1.0.tgz#9926d03ede13ba18f7d42222631fb04c79ff26fe"
trim-newlines@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
@ -6085,6 +6354,18 @@ trim-right@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
trim-trailing-lines@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.0.tgz#7aefbb7808df9d669f6da2e438cac8c46ada7684"
trim@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd"
trough@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.0.tgz#6bdedfe7f2aa49a6f3c432257687555957f342fd"
try-require@^1.0.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/try-require/-/try-require-1.2.1.tgz#34489a2cac0c09c1cc10ed91ba011594d4333be2"
@ -6222,6 +6503,27 @@ underscore@1.6.0, underscore@1.x, underscore@~1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8"
unherit@^1.0.4:
version "1.1.0"
resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.0.tgz#6b9aaedfbf73df1756ad9e316dd981885840cd7d"
dependencies:
inherits "^2.0.1"
xtend "^4.0.1"
unified@^6.0.0:
version "6.1.2"
resolved "https://registry.yarnpkg.com/unified/-/unified-6.1.2.tgz#b3904c3254ffbea7ff6d806c5d5b6248838cecb6"
dependencies:
bail "^1.0.0"
extend "^3.0.0"
has "^1.0.1"
is-plain-obj "^1.1.0"
isarray "^2.0.1"
trough "^1.0.0"
vfile "^2.0.0"
x-is-function "^1.0.4"
x-is-string "^0.1.0"
uniq@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
@ -6242,6 +6544,46 @@ unique-string@^1.0.0:
dependencies:
crypto-random-string "^1.0.0"
unist-builder@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-1.0.2.tgz#8c3b9903ef64bcfb117dd7cf6a5d98fc1b3b27b6"
dependencies:
object-assign "^4.1.0"
unist-util-generated@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.0.tgz#8c95657ff12b32eaffe0731fbb37da6995fae01b"
unist-util-is@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.0.0.tgz#e536472c4f78739e164d0859fc3201b97cf46e7c"
unist-util-modify-children@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/unist-util-modify-children/-/unist-util-modify-children-1.1.0.tgz#559203ae85d7a76283277be1abfbaf595a177ead"
dependencies:
array-iterate "^1.0.0"
unist-util-position@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.0.0.tgz#e6e1e03eeeb81c5e1afe553e8d4adfbd7c0d8f82"
unist-util-remove-position@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.0.tgz#2444fedc344bc5f540dab6353e013b6d78101dc2"
dependencies:
unist-util-visit "^1.1.0"
unist-util-stringify-position@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.0.tgz#e8ba9d6b6af891b5f8336b3a31c63a9dc85c2af0"
dependencies:
has "^1.0.1"
unist-util-visit@^1.0.0, unist-util-visit@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.1.1.tgz#e917a3b137658b335cb4420c7da2e74d928e4e94"
universal-analytics@^0.3.9:
version "0.3.11"
resolved "https://registry.yarnpkg.com/universal-analytics/-/universal-analytics-0.3.11.tgz#512879193a12a66dcbd9185121389bab913cd4b6"
@ -6431,6 +6773,20 @@ verror@1.3.6:
dependencies:
extsprintf "1.0.2"
vfile-location@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.1.tgz#0bf8816f732b0f8bd902a56fda4c62c8e935dc52"
vfile@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.0.1.tgz#bd48e68e8a2322dff0d162a37f45e70d9bb30466"
dependencies:
has "^1.0.1"
is-buffer "^1.1.4"
replace-ext "1.0.0"
unist-util-stringify-position "^1.0.0"
x-is-string "^0.1.0"
vlq@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.1.tgz#14439d711891e682535467f8587c5630e4222a6c"
@ -6708,6 +7064,14 @@ wtf-8@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a"
x-is-function@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/x-is-function/-/x-is-function-1.0.4.tgz#5d294dc3d268cbdd062580e0c5df77a391d1fa1e"
x-is-string@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82"
xdg-basedir@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2"