diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..940b19081 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +coverage/ +remark.js +remark.min.js diff --git a/package.json b/package.json index 08d632bf3..177af894e 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "mdast-util-compact": "^1.0.0", "mdast-zone": "^3.0.1", "nyc": "^13.0.0", + "prettier": "^1.14.3", "remark-preset-wooorm": "^4.0.0", "tape": "^4.5.1", "tinyify": "^2.4.3", @@ -30,16 +31,15 @@ }, "scripts": { "postinstall": "lerna bootstrap --no-ci", - "build-md": "packages/remark-cli/cli.js . -qfo", + "format": "packages/remark-cli/cli.js . -qfo && prettier --write '**/*.js' && xo --fix", "build-bundle": "browserify packages/remark -s remark > remark.js", "build-mangle": "browserify packages/remark -s remark -p tinyify > remark.min.js", - "build": "npm run build-md && npm run build-bundle && npm run build-mangle", - "lint": "xo", + "build": "npm run build-bundle && npm run build-mangle", "test-api": "node test/api", "test-api-extensive": "TEST_EXTENDED=true node test/api", "test-cli": "node test/cli.js", "test-coverage": "nyc --reporter lcov tape test", - "test": "npm run build && npm run lint && npm run test-coverage" + "test": "npm run format && npm run build && npm run test-coverage" }, "nyc": { "check-coverage": true, @@ -47,8 +47,16 @@ "functions": 100, "branches": 100 }, + "prettier": { + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "bracketSpacing": false, + "semi": false, + "trailingComma": "none" + }, "xo": { - "space": true, + "prettier": true, "esnext": false, "rules": { "import/no-unassigned-import": "off", diff --git a/packages/remark-cli/cli.js b/packages/remark-cli/cli.js index fb4ac4ae2..c5621dd09 100755 --- a/packages/remark-cli/cli.js +++ b/packages/remark-cli/cli.js @@ -1,11 +1,11 @@ #!/usr/bin/env node -'use strict'; +'use strict' -var start = require('unified-args'); -var extensions = require('markdown-extensions'); -var processor = require('remark'); -var proc = require('remark/package.json'); -var cli = require('./package.json'); +var start = require('unified-args') +var extensions = require('markdown-extensions') +var processor = require('remark') +var proc = require('remark/package.json') +var cli = require('./package.json') start({ processor: processor, @@ -21,4 +21,4 @@ start({ rcName: '.' + proc.name + 'rc', ignoreName: '.' + proc.name + 'ignore', extensions: extensions -}); +}) diff --git a/packages/remark-parse/index.js b/packages/remark-parse/index.js index 1579e3551..39cc24a23 100644 --- a/packages/remark-parse/index.js +++ b/packages/remark-parse/index.js @@ -1,14 +1,17 @@ -'use strict'; +'use strict' -var unherit = require('unherit'); -var xtend = require('xtend'); -var Parser = require('./lib/parser.js'); +var unherit = require('unherit') +var xtend = require('xtend') +var Parser = require('./lib/parser.js') -module.exports = parse; -parse.Parser = Parser; +module.exports = parse +parse.Parser = Parser function parse(options) { - var Local = unherit(Parser); - Local.prototype.options = xtend(Local.prototype.options, this.data('settings'), options); - this.Parser = Local; + var settings = this.data('settings') + var Local = unherit(Parser) + + Local.prototype.options = xtend(Local.prototype.options, settings, options) + + this.Parser = Local } diff --git a/packages/remark-parse/lib/decode.js b/packages/remark-parse/lib/decode.js index fd45b729d..3a1edc0be 100644 --- a/packages/remark-parse/lib/decode.js +++ b/packages/remark-parse/lib/decode.js @@ -1,48 +1,34 @@ -'use strict'; +'use strict' -var xtend = require('xtend'); -var entities = require('parse-entities'); +var xtend = require('xtend') +var entities = require('parse-entities') -module.exports = factory; +module.exports = factory -/* Factory to create an entity decoder. */ +// Factory to create an entity decoder. function factory(ctx) { - decoder.raw = decodeRaw; + decoder.raw = decodeRaw - return decoder; + return decoder - /* Normalize `position` to add an `indent`. */ + // Normalize `position` to add an `indent`. function normalize(position) { - var offsets = ctx.offset; - var line = position.line; - var result = []; + var offsets = ctx.offset + var line = position.line + var result = [] while (++line) { if (!(line in offsets)) { - break; + break } - result.push((offsets[line] || 0) + 1); + result.push((offsets[line] || 0) + 1) } - return { - start: position, - indent: result - }; + return {start: position, indent: result} } - /* Handle a warning. - * See https://github.com/wooorm/parse-entities - * for the warnings. */ - function handleWarning(reason, position, code) { - if (code === 3) { - return; - } - - ctx.file.message(reason, position); - } - - /* Decode `value` (at `position`) into text-nodes. */ + // Decode `value` (at `position`) into text-nodes. function decoder(value, position, handler) { entities(value, { position: normalize(position), @@ -51,14 +37,22 @@ function factory(ctx) { reference: handler, textContext: ctx, referenceContext: ctx - }); + }) } - /* Decode `value` (at `position`) into a string. */ + // Decode `value` (at `position`) into a string. function decodeRaw(value, position, options) { - return entities(value, xtend(options, { - position: normalize(position), - warning: handleWarning - })); + return entities( + value, + xtend(options, {position: normalize(position), warning: handleWarning}) + ) + } + + // Handle a warning. + // See for the warnings. + function handleWarning(reason, position, code) { + if (code !== 3) { + ctx.file.message(reason, position) + } } } diff --git a/packages/remark-parse/lib/defaults.js b/packages/remark-parse/lib/defaults.js index 37846f393..ec4fd6a7b 100644 --- a/packages/remark-parse/lib/defaults.js +++ b/packages/remark-parse/lib/defaults.js @@ -1,4 +1,4 @@ -'use strict'; +'use strict' module.exports = { position: true, @@ -7,4 +7,4 @@ module.exports = { footnotes: false, pedantic: false, blocks: require('./block-elements.json') -}; +} diff --git a/packages/remark-parse/lib/locate/break.js b/packages/remark-parse/lib/locate/break.js index 295bdc985..f5479e7c6 100644 --- a/packages/remark-parse/lib/locate/break.js +++ b/packages/remark-parse/lib/locate/break.js @@ -1,17 +1,17 @@ -'use strict'; +'use strict' -module.exports = locate; +module.exports = locate function locate(value, fromIndex) { - var index = value.indexOf('\n', fromIndex); + var index = value.indexOf('\n', fromIndex) while (index > fromIndex) { if (value.charAt(index - 1) !== ' ') { - break; + break } - index--; + index-- } - return index; + return index } diff --git a/packages/remark-parse/lib/locate/code-inline.js b/packages/remark-parse/lib/locate/code-inline.js index 981c81698..241971709 100644 --- a/packages/remark-parse/lib/locate/code-inline.js +++ b/packages/remark-parse/lib/locate/code-inline.js @@ -1,7 +1,7 @@ -'use strict'; +'use strict' -module.exports = locate; +module.exports = locate function locate(value, fromIndex) { - return value.indexOf('`', fromIndex); + return value.indexOf('`', fromIndex) } diff --git a/packages/remark-parse/lib/locate/delete.js b/packages/remark-parse/lib/locate/delete.js index d208aef2f..18b2f6305 100644 --- a/packages/remark-parse/lib/locate/delete.js +++ b/packages/remark-parse/lib/locate/delete.js @@ -1,7 +1,7 @@ -'use strict'; +'use strict' -module.exports = locate; +module.exports = locate function locate(value, fromIndex) { - return value.indexOf('~~', fromIndex); + return value.indexOf('~~', fromIndex) } diff --git a/packages/remark-parse/lib/locate/emphasis.js b/packages/remark-parse/lib/locate/emphasis.js index 6a1f24227..afec4ff89 100644 --- a/packages/remark-parse/lib/locate/emphasis.js +++ b/packages/remark-parse/lib/locate/emphasis.js @@ -1,18 +1,18 @@ -'use strict'; +'use strict' -module.exports = locate; +module.exports = locate function locate(value, fromIndex) { - var asterisk = value.indexOf('*', fromIndex); - var underscore = value.indexOf('_', fromIndex); + var asterisk = value.indexOf('*', fromIndex) + var underscore = value.indexOf('_', fromIndex) if (underscore === -1) { - return asterisk; + return asterisk } if (asterisk === -1) { - return underscore; + return underscore } - return underscore < asterisk ? underscore : asterisk; + return underscore < asterisk ? underscore : asterisk } diff --git a/packages/remark-parse/lib/locate/escape.js b/packages/remark-parse/lib/locate/escape.js index f6c637158..9f61acff2 100644 --- a/packages/remark-parse/lib/locate/escape.js +++ b/packages/remark-parse/lib/locate/escape.js @@ -1,7 +1,7 @@ -'use strict'; +'use strict' -module.exports = locate; +module.exports = locate function locate(value, fromIndex) { - return value.indexOf('\\', fromIndex); + return value.indexOf('\\', fromIndex) } diff --git a/packages/remark-parse/lib/locate/link.js b/packages/remark-parse/lib/locate/link.js index 0f16fd801..df7b33bcf 100644 --- a/packages/remark-parse/lib/locate/link.js +++ b/packages/remark-parse/lib/locate/link.js @@ -1,16 +1,16 @@ -'use strict'; +'use strict' -module.exports = locate; +module.exports = locate function locate(value, fromIndex) { - var link = value.indexOf('[', fromIndex); - var image = value.indexOf('![', fromIndex); + var link = value.indexOf('[', fromIndex) + var image = value.indexOf('![', fromIndex) if (image === -1) { - return link; + return link } - /* Link can never be `-1` if an image is found, so we don’t need - * to check for that :) */ - return link < image ? link : image; + // Link can never be `-1` if an image is found, so we don’t need to check + // for that :) + return link < image ? link : image } diff --git a/packages/remark-parse/lib/locate/strong.js b/packages/remark-parse/lib/locate/strong.js index da1cac0a4..44b95cd02 100644 --- a/packages/remark-parse/lib/locate/strong.js +++ b/packages/remark-parse/lib/locate/strong.js @@ -1,18 +1,18 @@ -'use strict'; +'use strict' -module.exports = locate; +module.exports = locate function locate(value, fromIndex) { - var asterisk = value.indexOf('**', fromIndex); - var underscore = value.indexOf('__', fromIndex); + var asterisk = value.indexOf('**', fromIndex) + var underscore = value.indexOf('__', fromIndex) if (underscore === -1) { - return asterisk; + return asterisk } if (asterisk === -1) { - return underscore; + return underscore } - return underscore < asterisk ? underscore : asterisk; + return underscore < asterisk ? underscore : asterisk } diff --git a/packages/remark-parse/lib/locate/tag.js b/packages/remark-parse/lib/locate/tag.js index 3c5534268..6a5d210b4 100644 --- a/packages/remark-parse/lib/locate/tag.js +++ b/packages/remark-parse/lib/locate/tag.js @@ -1,7 +1,7 @@ -'use strict'; +'use strict' -module.exports = locate; +module.exports = locate function locate(value, fromIndex) { - return value.indexOf('<', fromIndex); + return value.indexOf('<', fromIndex) } diff --git a/packages/remark-parse/lib/locate/url.js b/packages/remark-parse/lib/locate/url.js index 59b63e256..e5bf5bfa4 100644 --- a/packages/remark-parse/lib/locate/url.js +++ b/packages/remark-parse/lib/locate/url.js @@ -1,26 +1,26 @@ -'use strict'; +'use strict' -module.exports = locate; +module.exports = locate -var PROTOCOLS = ['https://', 'http://', 'mailto:']; +var protocols = ['https://', 'http://', 'mailto:'] function locate(value, fromIndex) { - var length = PROTOCOLS.length; - var index = -1; - var min = -1; - var position; + var length = protocols.length + var index = -1 + var min = -1 + var position if (!this.options.gfm) { - return -1; + return -1 } while (++index < length) { - position = value.indexOf(PROTOCOLS[index], fromIndex); + position = value.indexOf(protocols[index], fromIndex) if (position !== -1 && (position < min || min === -1)) { - min = position; + min = position } } - return min; + return min } diff --git a/packages/remark-parse/lib/parse.js b/packages/remark-parse/lib/parse.js index 5a8d81195..59aac694b 100644 --- a/packages/remark-parse/lib/parse.js +++ b/packages/remark-parse/lib/parse.js @@ -1,45 +1,42 @@ -'use strict'; +'use strict' -var xtend = require('xtend'); -var removePosition = require('unist-util-remove-position'); +var xtend = require('xtend') +var removePosition = require('unist-util-remove-position') -module.exports = parse; +module.exports = parse -var C_NEWLINE = '\n'; -var EXPRESSION_LINE_BREAKS = /\r\n|\r/g; +var lineFeed = '\n' +var lineBreaksExpression = /\r\n|\r/g -/* Parse the bound file. */ +// Parse the bound file. function parse() { - var self = this; - var value = String(self.file); - var start = {line: 1, column: 1, offset: 0}; - var content = xtend(start); - var node; - - /* Clean non-unix newlines: `\r\n` and `\r` are all - * changed to `\n`. This should not affect positional - * information. */ - value = value.replace(EXPRESSION_LINE_BREAKS, C_NEWLINE); - - if (value.charCodeAt(0) === 0xFEFF) { - value = value.slice(1); - - content.column++; - content.offset++; + var self = this + var value = String(self.file) + var start = {line: 1, column: 1, offset: 0} + var content = xtend(start) + var node + + // Clean non-unix newlines: `\r\n` and `\r` are all changed to `\n`. + // This should not affect positional information. + value = value.replace(lineBreaksExpression, lineFeed) + + // BOM. + if (value.charCodeAt(0) === 0xfeff) { + value = value.slice(1) + + content.column++ + content.offset++ } node = { type: 'root', children: self.tokenizeBlock(value, content), - position: { - start: start, - end: self.eof || xtend(start) - } - }; + position: {start: start, end: self.eof || xtend(start)} + } if (!self.options.position) { - removePosition(node, true); + removePosition(node, true) } - return node; + return node } diff --git a/packages/remark-parse/lib/parser.js b/packages/remark-parse/lib/parser.js index 9291109f1..4add90e01 100644 --- a/packages/remark-parse/lib/parser.js +++ b/packages/remark-parse/lib/parser.js @@ -1,54 +1,53 @@ -'use strict'; +'use strict' -var xtend = require('xtend'); -var toggle = require('state-toggle'); -var vfileLocation = require('vfile-location'); -var unescape = require('./unescape'); -var decode = require('./decode'); -var tokenizer = require('./tokenizer'); +var xtend = require('xtend') +var toggle = require('state-toggle') +var vfileLocation = require('vfile-location') +var unescape = require('./unescape') +var decode = require('./decode') +var tokenizer = require('./tokenizer') -module.exports = Parser; +module.exports = Parser function Parser(doc, file) { - this.file = file; - this.offset = {}; - this.options = xtend(this.options); - this.setOptions({}); - - this.inList = false; - this.inBlock = false; - this.inLink = false; - this.atStart = true; - - this.toOffset = vfileLocation(file).toOffset; - this.unescape = unescape(this, 'escape'); - this.decode = decode(this); + this.file = file + this.offset = {} + this.options = xtend(this.options) + this.setOptions({}) + + this.inList = false + this.inBlock = false + this.inLink = false + this.atStart = true + + this.toOffset = vfileLocation(file).toOffset + this.unescape = unescape(this, 'escape') + this.decode = decode(this) } -var proto = Parser.prototype; - -/* Expose core. */ -proto.setOptions = require('./set-options'); -proto.parse = require('./parse'); - -/* Expose `defaults`. */ -proto.options = require('./defaults'); - -/* Enter and exit helpers. */ -proto.exitStart = toggle('atStart', true); -proto.enterList = toggle('inList', false); -proto.enterLink = toggle('inLink', false); -proto.enterBlock = toggle('inBlock', false); - -/* Nodes that can interupt a paragraph: - * - * ```markdown - * A paragraph, followed by a thematic break. - * ___ - * ``` - * - * In the above example, the thematic break “interupts” - * the paragraph. */ +var proto = Parser.prototype + +// Expose core. +proto.setOptions = require('./set-options') +proto.parse = require('./parse') + +// Expose `defaults`. +proto.options = require('./defaults') + +// Enter and exit helpers. +proto.exitStart = toggle('atStart', true) +proto.enterList = toggle('inList', false) +proto.enterLink = toggle('inLink', false) +proto.enterBlock = toggle('inBlock', false) + +// Nodes that can interupt a paragraph: +// +// ```markdown +// A paragraph, followed by a thematic break. +// ___ +// ``` +// +// In the above example, the thematic break “interupts” the paragraph. proto.interruptParagraph = [ ['thematicBreak'], ['atxHeading'], @@ -58,34 +57,32 @@ proto.interruptParagraph = [ ['setextHeading', {commonmark: false}], ['definition', {commonmark: false}], ['footnote', {commonmark: false}] -]; - -/* Nodes that can interupt a list: - * - * ```markdown - * - One - * ___ - * ``` - * - * In the above example, the thematic break “interupts” - * the list. */ +] + +// Nodes that can interupt a list: +// +// ```markdown +// - One +// ___ +// ``` +// +// In the above example, the thematic break “interupts” the list. proto.interruptList = [ ['atxHeading', {pedantic: false}], ['fencedCode', {pedantic: false}], ['thematicBreak', {pedantic: false}], ['definition', {commonmark: false}], ['footnote', {commonmark: false}] -]; - -/* Nodes that can interupt a blockquote: - * - * ```markdown - * > A paragraph. - * ___ - * ``` - * - * In the above example, the thematic break “interupts” - * the blockquote. */ +] + +// Nodes that can interupt a blockquote: +// +// ```markdown +// > A paragraph. +// ___ +// ``` +// +// In the above example, the thematic break “interupts” the blockquote. proto.interruptBlockquote = [ ['indentedCode', {commonmark: true}], ['fencedCode', {commonmark: true}], @@ -96,9 +93,9 @@ proto.interruptBlockquote = [ ['list', {commonmark: true}], ['definition', {commonmark: false}], ['footnote', {commonmark: false}] -]; +] -/* Handlers. */ +// Handlers. proto.blockTokenizers = { newline: require('./tokenize/newline'), indentedCode: require('./tokenize/code-indented'), @@ -113,7 +110,7 @@ proto.blockTokenizers = { definition: require('./tokenize/definition'), table: require('./tokenize/table'), paragraph: require('./tokenize/paragraph') -}; +} proto.inlineTokenizers = { escape: require('./tokenize/escape'), @@ -128,25 +125,25 @@ proto.inlineTokenizers = { code: require('./tokenize/code-inline'), break: require('./tokenize/break'), text: require('./tokenize/text') -}; +} -/* Expose precedence. */ -proto.blockMethods = keys(proto.blockTokenizers); -proto.inlineMethods = keys(proto.inlineTokenizers); +// Expose precedence. +proto.blockMethods = keys(proto.blockTokenizers) +proto.inlineMethods = keys(proto.inlineTokenizers) -/* Tokenizers. */ -proto.tokenizeBlock = tokenizer('block'); -proto.tokenizeInline = tokenizer('inline'); -proto.tokenizeFactory = tokenizer; +// Tokenizers. +proto.tokenizeBlock = tokenizer('block') +proto.tokenizeInline = tokenizer('inline') +proto.tokenizeFactory = tokenizer -/* Get all keys in `value`. */ +// Get all keys in `value`. function keys(value) { - var result = []; - var key; + var result = [] + var key for (key in value) { - result.push(key); + result.push(key) } - return result; + return result } diff --git a/packages/remark-parse/lib/set-options.js b/packages/remark-parse/lib/set-options.js index c55f7f32f..5877099e3 100644 --- a/packages/remark-parse/lib/set-options.js +++ b/packages/remark-parse/lib/set-options.js @@ -1,47 +1,46 @@ -'use strict'; +'use strict' -var xtend = require('xtend'); -var escapes = require('markdown-escapes'); -var defaults = require('./defaults'); +var xtend = require('xtend') +var escapes = require('markdown-escapes') +var defaults = require('./defaults') -module.exports = setOptions; +module.exports = setOptions function setOptions(options) { - var self = this; - var current = self.options; - var key; - var value; + var self = this + var current = self.options + var key + var value if (options == null) { - options = {}; + options = {} } else if (typeof options === 'object') { - options = xtend(options); + options = xtend(options) } else { - throw new Error( - 'Invalid value `' + options + '` ' + - 'for setting `options`' - ); + throw new Error('Invalid value `' + options + '` for setting `options`') } for (key in defaults) { - value = options[key]; + value = options[key] if (value == null) { - value = current[key]; + value = current[key] } if ( (key !== 'blocks' && typeof value !== 'boolean') || (key === 'blocks' && typeof value !== 'object') ) { - throw new Error('Invalid value `' + value + '` for setting `options.' + key + '`'); + throw new Error( + 'Invalid value `' + value + '` for setting `options.' + key + '`' + ) } - options[key] = value; + options[key] = value } - self.options = options; - self.escape = escapes(options); + self.options = options + self.escape = escapes(options) - return self; + return self } diff --git a/packages/remark-parse/lib/tokenize/auto-link.js b/packages/remark-parse/lib/tokenize/auto-link.js index c945a2c1f..c73480f41 100644 --- a/packages/remark-parse/lib/tokenize/auto-link.js +++ b/packages/remark-parse/lib/tokenize/auto-link.js @@ -1,145 +1,133 @@ -'use strict'; +'use strict' -var whitespace = require('is-whitespace-character'); -var decode = require('parse-entities'); -var locate = require('../locate/tag'); +var whitespace = require('is-whitespace-character') +var decode = require('parse-entities') +var locate = require('../locate/tag') -module.exports = autoLink; -autoLink.locator = locate; -autoLink.notInLink = true; +module.exports = autoLink +autoLink.locator = locate +autoLink.notInLink = true -var C_LT = '<'; -var C_GT = '>'; -var C_AT_SIGN = '@'; -var C_SLASH = '/'; -var MAILTO = 'mailto:'; -var MAILTO_LENGTH = MAILTO.length; +var lessThan = '<' +var greaterThan = '>' +var atSign = '@' +var slash = '/' +var mailto = 'mailto:' +var mailtoLength = mailto.length -/* Tokenise a link. */ function autoLink(eat, value, silent) { - var self; - var subvalue; - var length; - var index; - var queue; - var character; - var hasAtCharacter; - var link; - var now; - var content; - var tokenizers; - var exit; - - if (value.charAt(0) !== C_LT) { - return; + var self = this + var subvalue = '' + var length = value.length + var index = 0 + var queue = '' + var hasAtCharacter = false + var link = '' + var character + var now + var content + var tokenizers + var exit + + if (value.charAt(0) !== lessThan) { + return } - self = this; - subvalue = ''; - length = value.length; - index = 0; - queue = ''; - hasAtCharacter = false; - link = ''; - - index++; - subvalue = C_LT; + index++ + subvalue = lessThan while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if ( whitespace(character) || - character === C_GT || - character === C_AT_SIGN || - (character === ':' && value.charAt(index + 1) === C_SLASH) + character === greaterThan || + character === atSign || + (character === ':' && value.charAt(index + 1) === slash) ) { - break; + break } - queue += character; - index++; + queue += character + index++ } if (!queue) { - return; + return } - link += queue; - queue = ''; + link += queue + queue = '' - character = value.charAt(index); - link += character; - index++; + character = value.charAt(index) + link += character + index++ - if (character === C_AT_SIGN) { - hasAtCharacter = true; + if (character === atSign) { + hasAtCharacter = true } else { - if ( - character !== ':' || - value.charAt(index + 1) !== C_SLASH - ) { - return; + if (character !== ':' || value.charAt(index + 1) !== slash) { + return } - link += C_SLASH; - index++; + link += slash + index++ } while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (whitespace(character) || character === C_GT) { - break; + if (whitespace(character) || character === greaterThan) { + break } - queue += character; - index++; + queue += character + index++ } - character = value.charAt(index); + character = value.charAt(index) - if (!queue || character !== C_GT) { - return; + if (!queue || character !== greaterThan) { + return } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - link += queue; - content = link; - subvalue += link + character; - now = eat.now(); - now.column++; - now.offset++; + link += queue + content = link + subvalue += link + character + now = eat.now() + now.column++ + now.offset++ if (hasAtCharacter) { - if (link.slice(0, MAILTO_LENGTH).toLowerCase() === MAILTO) { - content = content.substr(MAILTO_LENGTH); - now.column += MAILTO_LENGTH; - now.offset += MAILTO_LENGTH; + if (link.slice(0, mailtoLength).toLowerCase() === mailto) { + content = content.substr(mailtoLength) + now.column += mailtoLength + now.offset += mailtoLength } else { - link = MAILTO + link; + link = mailto + link } } - /* Temporarily remove all tokenizers except text in autolinks. */ - tokenizers = self.inlineTokenizers; - self.inlineTokenizers = {text: tokenizers.text}; + // Temporarily remove all tokenizers except text in autolinks. + tokenizers = self.inlineTokenizers + self.inlineTokenizers = {text: tokenizers.text} - exit = self.enterLink(); + exit = self.enterLink() - content = self.tokenizeInline(content, now); + content = self.tokenizeInline(content, now) - self.inlineTokenizers = tokenizers; - exit(); + self.inlineTokenizers = tokenizers + exit() return eat(subvalue)({ type: 'link', title: null, url: decode(link, {nonTerminated: false}), children: content - }); + }) } diff --git a/packages/remark-parse/lib/tokenize/blockquote.js b/packages/remark-parse/lib/tokenize/blockquote.js index bd700d6a6..2960e85af 100644 --- a/packages/remark-parse/lib/tokenize/blockquote.js +++ b/packages/remark-parse/lib/tokenize/blockquote.js @@ -1,129 +1,124 @@ -'use strict'; +'use strict' -var trim = require('trim'); -var interrupt = require('../util/interrupt'); +var trim = require('trim') +var interrupt = require('../util/interrupt') -module.exports = blockquote; +module.exports = blockquote -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_GT = '>'; +var lineFeed = '\n' +var tab = '\t' +var space = ' ' +var greaterThan = '>' -/* Tokenise a blockquote. */ function blockquote(eat, value, silent) { - var self = this; - var offsets = self.offset; - var tokenizers = self.blockTokenizers; - var interruptors = self.interruptBlockquote; - var now = eat.now(); - var currentLine = now.line; - var length = value.length; - var values = []; - var contents = []; - var indents = []; - var add; - var index = 0; - var character; - var rest; - var nextIndex; - var content; - var line; - var startIndex; - var prefixed; - var exit; + var self = this + var offsets = self.offset + var tokenizers = self.blockTokenizers + var interruptors = self.interruptBlockquote + var now = eat.now() + var currentLine = now.line + var length = value.length + var values = [] + var contents = [] + var indents = [] + var add + var index = 0 + var character + var rest + var nextIndex + var content + var line + var startIndex + var prefixed + var exit while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE && character !== C_TAB) { - break; + if (character !== space && character !== tab) { + break } - index++; + index++ } - if (value.charAt(index) !== C_GT) { - return; + if (value.charAt(index) !== greaterThan) { + return } if (silent) { - return true; + return true } - index = 0; + index = 0 while (index < length) { - nextIndex = value.indexOf(C_NEWLINE, index); - startIndex = index; - prefixed = false; + nextIndex = value.indexOf(lineFeed, index) + startIndex = index + prefixed = false if (nextIndex === -1) { - nextIndex = length; + nextIndex = length } while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE && character !== C_TAB) { - break; + if (character !== space && character !== tab) { + break } - index++; + index++ } - if (value.charAt(index) === C_GT) { - index++; - prefixed = true; + if (value.charAt(index) === greaterThan) { + index++ + prefixed = true - if (value.charAt(index) === C_SPACE) { - index++; + if (value.charAt(index) === space) { + index++ } } else { - index = startIndex; + index = startIndex } - content = value.slice(index, nextIndex); + content = value.slice(index, nextIndex) if (!prefixed && !trim(content)) { - index = startIndex; - break; + index = startIndex + break } if (!prefixed) { - rest = value.slice(index); + rest = value.slice(index) - /* Check if the following code contains a possible - * block. */ + // Check if the following code contains a possible block. if (interrupt(interruptors, tokenizers, self, [eat, rest, true])) { - break; + break } } - line = startIndex === index ? content : value.slice(startIndex, nextIndex); + line = startIndex === index ? content : value.slice(startIndex, nextIndex) - indents.push(index - startIndex); - values.push(line); - contents.push(content); + indents.push(index - startIndex) + values.push(line) + contents.push(content) - index = nextIndex + 1; + index = nextIndex + 1 } - index = -1; - length = indents.length; - add = eat(values.join(C_NEWLINE)); + index = -1 + length = indents.length + add = eat(values.join(lineFeed)) while (++index < length) { - offsets[currentLine] = (offsets[currentLine] || 0) + indents[index]; - currentLine++; + offsets[currentLine] = (offsets[currentLine] || 0) + indents[index] + currentLine++ } - exit = self.enterBlock(); - contents = self.tokenizeBlock(contents.join(C_NEWLINE), now); - exit(); + exit = self.enterBlock() + contents = self.tokenizeBlock(contents.join(lineFeed), now) + exit() - return add({ - type: 'blockquote', - children: contents - }); + return add({type: 'blockquote', children: contents}) } diff --git a/packages/remark-parse/lib/tokenize/break.js b/packages/remark-parse/lib/tokenize/break.js index eb531342b..b68ca6d7e 100644 --- a/packages/remark-parse/lib/tokenize/break.js +++ b/packages/remark-parse/lib/tokenize/break.js @@ -1,40 +1,42 @@ -'use strict'; +'use strict' -var locate = require('../locate/break'); +var locate = require('../locate/break') -module.exports = hardBreak; -hardBreak.locator = locate; +module.exports = hardBreak +hardBreak.locator = locate -var MIN_BREAK_LENGTH = 2; +var space = ' ' +var lineFeed = '\n' +var minBreakLength = 2 function hardBreak(eat, value, silent) { - var length = value.length; - var index = -1; - var queue = ''; - var character; + var length = value.length + var index = -1 + var queue = '' + var character while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character === '\n') { - if (index < MIN_BREAK_LENGTH) { - return; + if (character === lineFeed) { + if (index < minBreakLength) { + return } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - queue += character; + queue += character - return eat(queue)({type: 'break'}); + return eat(queue)({type: 'break'}) } - if (character !== ' ') { - return; + if (character !== space) { + return } - queue += character; + queue += character } } diff --git a/packages/remark-parse/lib/tokenize/code-fenced.js b/packages/remark-parse/lib/tokenize/code-fenced.js index ac5eb388b..53a7629be 100644 --- a/packages/remark-parse/lib/tokenize/code-fenced.js +++ b/packages/remark-parse/lib/tokenize/code-fenced.js @@ -1,248 +1,248 @@ -'use strict'; +'use strict' -var trim = require('trim-trailing-lines'); +var trim = require('trim-trailing-lines') -module.exports = fencedCode; +module.exports = fencedCode -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_TILDE = '~'; -var C_TICK = '`'; +var lineFeed = '\n' +var tab = '\t' +var space = ' ' +var tilde = '~' +var graveAccent = '`' -var MIN_FENCE_COUNT = 3; -var CODE_INDENT_COUNT = 4; +var minFenceCount = 3 +var tabSize = 4 function fencedCode(eat, value, silent) { - var self = this; - var settings = self.options; - var length = value.length + 1; - var index = 0; - var subvalue = ''; - var fenceCount; - var marker; - var character; - var flag; - var lang; - var meta; - var queue; - var content; - var exdentedContent; - var closing; - var exdentedClosing; - var indent; - var now; - - if (!settings.gfm) { - return; + var self = this + var gfm = self.options.gfm + var length = value.length + 1 + var index = 0 + var subvalue = '' + var fenceCount + var marker + var character + var flag + var lang + var meta + var queue + var content + var exdentedContent + var closing + var exdentedClosing + var indent + var now + + if (!gfm) { + return } - /* Eat initial spacing. */ + // Eat initial spacing. while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE && character !== C_TAB) { - break; + if (character !== space && character !== tab) { + break } - subvalue += character; - index++; + subvalue += character + index++ } - indent = index; + indent = index - /* Eat the fence. */ - character = value.charAt(index); + // Eat the fence. + character = value.charAt(index) - if (character !== C_TILDE && character !== C_TICK) { - return; + if (character !== tilde && character !== graveAccent) { + return } - index++; - marker = character; - fenceCount = 1; - subvalue += character; + index++ + marker = character + fenceCount = 1 + subvalue += character while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (character !== marker) { - break; + break } - subvalue += character; - fenceCount++; - index++; + subvalue += character + fenceCount++ + index++ } - if (fenceCount < MIN_FENCE_COUNT) { - return; + if (fenceCount < minFenceCount) { + return } - /* Eat spacing before flag. */ + // Eat spacing before flag. while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE && character !== C_TAB) { - break; + if (character !== space && character !== tab) { + break } - subvalue += character; - index++; + subvalue += character + index++ } - /* Eat flag. */ - flag = ''; - queue = ''; + // Eat flag. + flag = '' + queue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if ( - character === C_NEWLINE || - character === C_TILDE || - character === C_TICK + character === lineFeed || + character === tilde || + character === graveAccent ) { - break; + break } - if (character === C_SPACE || character === C_TAB) { - queue += character; + if (character === space || character === tab) { + queue += character } else { - flag += queue + character; - queue = ''; + flag += queue + character + queue = '' } - index++; + index++ } - character = value.charAt(index); + character = value.charAt(index) - if (character && character !== C_NEWLINE) { - return; + if (character && character !== lineFeed) { + return } if (silent) { - return true; + return true } - now = eat.now(); - now.column += subvalue.length; - now.offset += subvalue.length; + now = eat.now() + now.column += subvalue.length + now.offset += subvalue.length - subvalue += flag; - flag = self.decode.raw(self.unescape(flag), now); + subvalue += flag + flag = self.decode.raw(self.unescape(flag), now) if (queue) { - subvalue += queue; + subvalue += queue } - queue = ''; - closing = ''; - exdentedClosing = ''; - content = ''; - exdentedContent = ''; + queue = '' + closing = '' + exdentedClosing = '' + content = '' + exdentedContent = '' - /* Eat content. */ + // Eat content. while (index < length) { - character = value.charAt(index); - content += closing; - exdentedContent += exdentedClosing; - closing = ''; - exdentedClosing = ''; - - if (character !== C_NEWLINE) { - content += character; - exdentedClosing += character; - index++; - continue; + character = value.charAt(index) + content += closing + exdentedContent += exdentedClosing + closing = '' + exdentedClosing = '' + + if (character !== lineFeed) { + content += character + exdentedClosing += character + index++ + continue } - /* Add the newline to `subvalue` if its the first - * character. Otherwise, add it to the `closing` - * queue. */ + // Add the newline to `subvalue` if its the first character. Otherwise, + // add it to the `closing` queue. if (content) { - closing += character; - exdentedClosing += character; + closing += character + exdentedClosing += character } else { - subvalue += character; + subvalue += character } - queue = ''; - index++; + queue = '' + index++ while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE) { - break; + if (character !== space) { + break } - queue += character; - index++; + queue += character + index++ } - closing += queue; - exdentedClosing += queue.slice(indent); + closing += queue + exdentedClosing += queue.slice(indent) - if (queue.length >= CODE_INDENT_COUNT) { - continue; + if (queue.length >= tabSize) { + continue } - queue = ''; + queue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (character !== marker) { - break; + break } - queue += character; - index++; + queue += character + index++ } - closing += queue; - exdentedClosing += queue; + closing += queue + exdentedClosing += queue if (queue.length < fenceCount) { - continue; + continue } - queue = ''; + queue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE && character !== C_TAB) { - break; + if (character !== space && character !== tab) { + break } - closing += character; - exdentedClosing += character; - index++; + closing += character + exdentedClosing += character + index++ } - if (!character || character === C_NEWLINE) { - break; + if (!character || character === lineFeed) { + break } } - subvalue += content + closing; + subvalue += content + closing - index = -1; - length = flag.length; + // Get lang and meta from the flag. + index = -1 + length = flag.length while (++index < length) { - character = flag.charAt(index); + character = flag.charAt(index) - if (character === C_SPACE || character === C_TAB) { + if (character === space || character === tab) { if (!lang) { - lang = flag.slice(0, index); + lang = flag.slice(0, index) } } else if (lang) { - meta = flag.slice(index); - break; + meta = flag.slice(index) + break } } @@ -251,5 +251,5 @@ function fencedCode(eat, value, silent) { lang: lang || flag || null, meta: meta || null, value: trim(exdentedContent) - }); + }) } diff --git a/packages/remark-parse/lib/tokenize/code-indented.js b/packages/remark-parse/lib/tokenize/code-indented.js index a7371e4fa..53a666fb6 100644 --- a/packages/remark-parse/lib/tokenize/code-indented.js +++ b/packages/remark-parse/lib/tokenize/code-indented.js @@ -1,92 +1,91 @@ -'use strict'; +'use strict' -var repeat = require('repeat-string'); -var trim = require('trim-trailing-lines'); +var repeat = require('repeat-string') +var trim = require('trim-trailing-lines') -module.exports = indentedCode; +module.exports = indentedCode -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; +var lineFeed = '\n' +var tab = '\t' +var space = ' ' -var CODE_INDENT_COUNT = 4; -var CODE_INDENT = repeat(C_SPACE, CODE_INDENT_COUNT); +var tabSize = 4 +var codeIndent = repeat(space, tabSize) -/* Tokenise indented code. */ function indentedCode(eat, value, silent) { - var index = -1; - var length = value.length; - var subvalue = ''; - var content = ''; - var subvalueQueue = ''; - var contentQueue = ''; - var character; - var blankQueue; - var indent; + var index = -1 + var length = value.length + var subvalue = '' + var content = '' + var subvalueQueue = '' + var contentQueue = '' + var character + var blankQueue + var indent while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) if (indent) { - indent = false; + indent = false - subvalue += subvalueQueue; - content += contentQueue; - subvalueQueue = ''; - contentQueue = ''; + subvalue += subvalueQueue + content += contentQueue + subvalueQueue = '' + contentQueue = '' - if (character === C_NEWLINE) { - subvalueQueue = character; - contentQueue = character; + if (character === lineFeed) { + subvalueQueue = character + contentQueue = character } else { - subvalue += character; - content += character; + subvalue += character + content += character while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (!character || character === C_NEWLINE) { - contentQueue = character; - subvalueQueue = character; - break; + if (!character || character === lineFeed) { + contentQueue = character + subvalueQueue = character + break } - subvalue += character; - content += character; + subvalue += character + content += character } } } else if ( - character === C_SPACE && + character === space && value.charAt(index + 1) === character && value.charAt(index + 2) === character && value.charAt(index + 3) === character ) { - subvalueQueue += CODE_INDENT; - index += 3; - indent = true; - } else if (character === C_TAB) { - subvalueQueue += character; - indent = true; + subvalueQueue += codeIndent + index += 3 + indent = true + } else if (character === tab) { + subvalueQueue += character + indent = true } else { - blankQueue = ''; + blankQueue = '' - while (character === C_TAB || character === C_SPACE) { - blankQueue += character; - character = value.charAt(++index); + while (character === tab || character === space) { + blankQueue += character + character = value.charAt(++index) } - if (character !== C_NEWLINE) { - break; + if (character !== lineFeed) { + break } - subvalueQueue += blankQueue + character; - contentQueue += character; + subvalueQueue += blankQueue + character + contentQueue += character } } if (content) { if (silent) { - return true; + return true } return eat(subvalue)({ @@ -94,6 +93,6 @@ function indentedCode(eat, value, silent) { lang: null, meta: null, value: trim(content) - }); + }) } } diff --git a/packages/remark-parse/lib/tokenize/code-inline.js b/packages/remark-parse/lib/tokenize/code-inline.js index c0a496b49..eef27e65e 100644 --- a/packages/remark-parse/lib/tokenize/code-inline.js +++ b/packages/remark-parse/lib/tokenize/code-inline.js @@ -1,112 +1,108 @@ -'use strict'; +'use strict' -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/code-inline'); +var whitespace = require('is-whitespace-character') +var locate = require('../locate/code-inline') -module.exports = inlineCode; -inlineCode.locator = locate; +module.exports = inlineCode +inlineCode.locator = locate -var C_TICK = '`'; +var graveAccent = '`' -/* Tokenise inline code. */ function inlineCode(eat, value, silent) { - var length = value.length; - var index = 0; - var queue = ''; - var tickQueue = ''; - var contentQueue; - var subqueue; - var count; - var openingCount; - var subvalue; - var character; - var found; - var next; + var length = value.length + var index = 0 + var queue = '' + var tickQueue = '' + var contentQueue + var subqueue + var count + var openingCount + var subvalue + var character + var found + var next while (index < length) { - if (value.charAt(index) !== C_TICK) { - break; + if (value.charAt(index) !== graveAccent) { + break } - queue += C_TICK; - index++; + queue += graveAccent + index++ } if (!queue) { - return; + return } - subvalue = queue; - openingCount = index; - queue = ''; - next = value.charAt(index); - count = 0; + subvalue = queue + openingCount = index + queue = '' + next = value.charAt(index) + count = 0 while (index < length) { - character = next; - next = value.charAt(index + 1); + character = next + next = value.charAt(index + 1) - if (character === C_TICK) { - count++; - tickQueue += character; + if (character === graveAccent) { + count++ + tickQueue += character } else { - count = 0; - queue += character; + count = 0 + queue += character } - if (count && next !== C_TICK) { + if (count && next !== graveAccent) { if (count === openingCount) { - subvalue += queue + tickQueue; - found = true; - break; + subvalue += queue + tickQueue + found = true + break } - queue += tickQueue; - tickQueue = ''; + queue += tickQueue + tickQueue = '' } - index++; + index++ } if (!found) { if (openingCount % 2 !== 0) { - return; + return } - queue = ''; + queue = '' } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - contentQueue = ''; - subqueue = ''; - length = queue.length; - index = -1; + contentQueue = '' + subqueue = '' + length = queue.length + index = -1 while (++index < length) { - character = queue.charAt(index); + character = queue.charAt(index) if (whitespace(character)) { - subqueue += character; - continue; + subqueue += character + continue } if (subqueue) { if (contentQueue) { - contentQueue += subqueue; + contentQueue += subqueue } - subqueue = ''; + subqueue = '' } - contentQueue += character; + contentQueue += character } - return eat(subvalue)({ - type: 'inlineCode', - value: contentQueue - }); + return eat(subvalue)({type: 'inlineCode', value: contentQueue}) } diff --git a/packages/remark-parse/lib/tokenize/definition.js b/packages/remark-parse/lib/tokenize/definition.js index 3f9e51a64..9c7dcbb67 100644 --- a/packages/remark-parse/lib/tokenize/definition.js +++ b/packages/remark-parse/lib/tokenize/definition.js @@ -1,255 +1,247 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); -var normalize = require('../util/normalize'); - -module.exports = definition; -definition.notInList = true; -definition.notInBlock = true; - -var C_DOUBLE_QUOTE = '"'; -var C_SINGLE_QUOTE = '\''; -var C_BACKSLASH = '\\'; -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; -var C_PAREN_OPEN = '('; -var C_PAREN_CLOSE = ')'; -var C_COLON = ':'; -var C_LT = '<'; -var C_GT = '>'; +'use strict' + +var whitespace = require('is-whitespace-character') +var normalize = require('../util/normalize') + +module.exports = definition +definition.notInList = true +definition.notInBlock = true + +var quotationMark = '"' +var apostrophe = "'" +var backslash = '\\' +var lineFeed = '\n' +var tab = '\t' +var space = ' ' +var leftSquareBracket = '[' +var rightSquareBracket = ']' +var leftParenthesis = '(' +var rightParenthesis = ')' +var colon = ':' +var lessThan = '<' +var greaterThan = '>' function definition(eat, value, silent) { - var self = this; - var commonmark = self.options.commonmark; - var index = 0; - var length = value.length; - var subvalue = ''; - var beforeURL; - var beforeTitle; - var queue; - var character; - var test; - var identifier; - var url; - var title; + var self = this + var commonmark = self.options.commonmark + var index = 0 + var length = value.length + var subvalue = '' + var beforeURL + var beforeTitle + var queue + var character + var test + var identifier + var url + var title while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE && character !== C_TAB) { - break; + if (character !== space && character !== tab) { + break } - subvalue += character; - index++; + subvalue += character + index++ } - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_BRACKET_OPEN) { - return; + if (character !== leftSquareBracket) { + return } - index++; - subvalue += character; - queue = ''; + index++ + subvalue += character + queue = '' while (index < length) { - character = value.charAt(index); - - if (character === C_BRACKET_CLOSE) { - break; - } else if (character === C_BACKSLASH) { - queue += character; - index++; - character = value.charAt(index); + character = value.charAt(index) + + if (character === rightSquareBracket) { + break + } else if (character === backslash) { + queue += character + index++ + character = value.charAt(index) } - queue += character; - index++; + queue += character + index++ } if ( !queue || - value.charAt(index) !== C_BRACKET_CLOSE || - value.charAt(index + 1) !== C_COLON + value.charAt(index) !== rightSquareBracket || + value.charAt(index + 1) !== colon ) { - return; + return } - identifier = queue; - subvalue += queue + C_BRACKET_CLOSE + C_COLON; - index = subvalue.length; - queue = ''; + identifier = queue + subvalue += queue + rightSquareBracket + colon + index = subvalue.length + queue = '' while (index < length) { - character = value.charAt(index); - - if ( - character !== C_TAB && - character !== C_SPACE && - character !== C_NEWLINE - ) { - break; + character = value.charAt(index) + + if (character !== tab && character !== space && character !== lineFeed) { + break } - subvalue += character; - index++; + subvalue += character + index++ } - character = value.charAt(index); - queue = ''; - beforeURL = subvalue; + character = value.charAt(index) + queue = '' + beforeURL = subvalue - if (character === C_LT) { - index++; + if (character === lessThan) { + index++ while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (!isEnclosedURLCharacter(character)) { - break; + break } - queue += character; - index++; + queue += character + index++ } - character = value.charAt(index); + character = value.charAt(index) if (character === isEnclosedURLCharacter.delimiter) { - subvalue += C_LT + queue + character; - index++; + subvalue += lessThan + queue + character + index++ } else { if (commonmark) { - return; + return } - index -= queue.length + 1; - queue = ''; + index -= queue.length + 1 + queue = '' } } if (!queue) { while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (!isUnclosedURLCharacter(character)) { - break; + break } - queue += character; - index++; + queue += character + index++ } - subvalue += queue; + subvalue += queue } if (!queue) { - return; + return } - url = queue; - queue = ''; + url = queue + queue = '' while (index < length) { - character = value.charAt(index); - - if ( - character !== C_TAB && - character !== C_SPACE && - character !== C_NEWLINE - ) { - break; + character = value.charAt(index) + + if (character !== tab && character !== space && character !== lineFeed) { + break } - queue += character; - index++; + queue += character + index++ } - character = value.charAt(index); - test = null; + character = value.charAt(index) + test = null - if (character === C_DOUBLE_QUOTE) { - test = C_DOUBLE_QUOTE; - } else if (character === C_SINGLE_QUOTE) { - test = C_SINGLE_QUOTE; - } else if (character === C_PAREN_OPEN) { - test = C_PAREN_CLOSE; + if (character === quotationMark) { + test = quotationMark + } else if (character === apostrophe) { + test = apostrophe + } else if (character === leftParenthesis) { + test = rightParenthesis } if (!test) { - queue = ''; - index = subvalue.length; + queue = '' + index = subvalue.length } else if (queue) { - subvalue += queue + character; - index = subvalue.length; - queue = ''; + subvalue += queue + character + index = subvalue.length + queue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (character === test) { - break; + break } - if (character === C_NEWLINE) { - index++; - character = value.charAt(index); + if (character === lineFeed) { + index++ + character = value.charAt(index) - if (character === C_NEWLINE || character === test) { - return; + if (character === lineFeed || character === test) { + return } - queue += C_NEWLINE; + queue += lineFeed } - queue += character; - index++; + queue += character + index++ } - character = value.charAt(index); + character = value.charAt(index) if (character !== test) { - return; + return } - beforeTitle = subvalue; - subvalue += queue + character; - index++; - title = queue; - queue = ''; + beforeTitle = subvalue + subvalue += queue + character + index++ + title = queue + queue = '' } else { - return; + return } while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_TAB && character !== C_SPACE) { - break; + if (character !== tab && character !== space) { + break } - subvalue += character; - index++; + subvalue += character + index++ } - character = value.charAt(index); + character = value.charAt(index) - if (!character || character === C_NEWLINE) { + if (!character || character === lineFeed) { if (silent) { - return true; + return true } - beforeURL = eat(beforeURL).test().end; - url = self.decode.raw(self.unescape(url), beforeURL, {nonTerminated: false}); + beforeURL = eat(beforeURL).test().end + url = self.decode.raw(self.unescape(url), beforeURL, {nonTerminated: false}) if (title) { - beforeTitle = eat(beforeTitle).test().end; - title = self.decode.raw(self.unescape(title), beforeTitle); + beforeTitle = eat(beforeTitle).test().end + title = self.decode.raw(self.unescape(title), beforeTitle) } return eat(subvalue)({ @@ -258,22 +250,26 @@ function definition(eat, value, silent) { label: identifier, title: title || null, url: url - }); + }) } } -/* Check if `character` can be inside an enclosed URI. */ +// Check if `character` can be inside an enclosed URI. function isEnclosedURLCharacter(character) { - return character !== C_GT && - character !== C_BRACKET_OPEN && - character !== C_BRACKET_CLOSE; + return ( + character !== greaterThan && + character !== leftSquareBracket && + character !== rightSquareBracket + ) } -isEnclosedURLCharacter.delimiter = C_GT; +isEnclosedURLCharacter.delimiter = greaterThan -/* Check if `character` can be inside an unclosed URI. */ +// Check if `character` can be inside an unclosed URI. function isUnclosedURLCharacter(character) { - return character !== C_BRACKET_OPEN && - character !== C_BRACKET_CLOSE && - !whitespace(character); + return ( + character !== leftSquareBracket && + character !== rightSquareBracket && + !whitespace(character) + ) } diff --git a/packages/remark-parse/lib/tokenize/delete.js b/packages/remark-parse/lib/tokenize/delete.js index ca7c68a8c..3513634b9 100644 --- a/packages/remark-parse/lib/tokenize/delete.js +++ b/packages/remark-parse/lib/tokenize/delete.js @@ -1,60 +1,60 @@ -'use strict'; +'use strict' -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/delete'); +var whitespace = require('is-whitespace-character') +var locate = require('../locate/delete') -module.exports = strikethrough; -strikethrough.locator = locate; +module.exports = strikethrough +strikethrough.locator = locate -var C_TILDE = '~'; -var DOUBLE = '~~'; +var tilde = '~' +var fence = '~~' function strikethrough(eat, value, silent) { - var self = this; - var character = ''; - var previous = ''; - var preceding = ''; - var subvalue = ''; - var index; - var length; - var now; + var self = this + var character = '' + var previous = '' + var preceding = '' + var subvalue = '' + var index + var length + var now if ( !self.options.gfm || - value.charAt(0) !== C_TILDE || - value.charAt(1) !== C_TILDE || + value.charAt(0) !== tilde || + value.charAt(1) !== tilde || whitespace(value.charAt(2)) ) { - return; + return } - index = 1; - length = value.length; - now = eat.now(); - now.column += 2; - now.offset += 2; + index = 1 + length = value.length + now = eat.now() + now.column += 2 + now.offset += 2 while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) if ( - character === C_TILDE && - previous === C_TILDE && + character === tilde && + previous === tilde && (!preceding || !whitespace(preceding)) ) { /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - return eat(DOUBLE + subvalue + DOUBLE)({ + return eat(fence + subvalue + fence)({ type: 'delete', children: self.tokenizeInline(subvalue, now) - }); + }) } - subvalue += previous; - preceding = previous; - previous = character; + subvalue += previous + preceding = previous + previous = character } } diff --git a/packages/remark-parse/lib/tokenize/emphasis.js b/packages/remark-parse/lib/tokenize/emphasis.js index b2c87b449..2cbfd314a 100644 --- a/packages/remark-parse/lib/tokenize/emphasis.js +++ b/packages/remark-parse/lib/tokenize/emphasis.js @@ -1,85 +1,86 @@ -'use strict'; +'use strict' -var trim = require('trim'); -var word = require('is-word-character'); -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/emphasis'); +var trim = require('trim') +var word = require('is-word-character') +var whitespace = require('is-whitespace-character') +var locate = require('../locate/emphasis') -module.exports = emphasis; -emphasis.locator = locate; +module.exports = emphasis +emphasis.locator = locate -var C_ASTERISK = '*'; -var C_UNDERSCORE = '_'; +var asterisk = '*' +var underscore = '_' +var backslash = '\\' function emphasis(eat, value, silent) { - var self = this; - var index = 0; - var character = value.charAt(index); - var now; - var pedantic; - var marker; - var queue; - var subvalue; - var length; - var prev; - - if (character !== C_ASTERISK && character !== C_UNDERSCORE) { - return; + var self = this + var index = 0 + var character = value.charAt(index) + var now + var pedantic + var marker + var queue + var subvalue + var length + var prev + + if (character !== asterisk && character !== underscore) { + return } - pedantic = self.options.pedantic; - subvalue = character; - marker = character; - length = value.length; - index++; - queue = ''; - character = ''; + pedantic = self.options.pedantic + subvalue = character + marker = character + length = value.length + index++ + queue = '' + character = '' if (pedantic && whitespace(value.charAt(index))) { - return; + return } while (index < length) { - prev = character; - character = value.charAt(index); + prev = character + character = value.charAt(index) if (character === marker && (!pedantic || !whitespace(prev))) { - character = value.charAt(++index); + character = value.charAt(++index) if (character !== marker) { if (!trim(queue) || prev === marker) { - return; + return } - if (!pedantic && marker === C_UNDERSCORE && word(character)) { - queue += marker; - continue; + if (!pedantic && marker === underscore && word(character)) { + queue += marker + continue } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - now = eat.now(); - now.column++; - now.offset++; + now = eat.now() + now.column++ + now.offset++ return eat(subvalue + queue + marker)({ type: 'emphasis', children: self.tokenizeInline(queue, now) - }); + }) } - queue += marker; + queue += marker } - if (!pedantic && character === '\\') { - queue += character; - character = value.charAt(++index); + if (!pedantic && character === backslash) { + queue += character + character = value.charAt(++index) } - queue += character; - index++; + queue += character + index++ } } diff --git a/packages/remark-parse/lib/tokenize/escape.js b/packages/remark-parse/lib/tokenize/escape.js index d6f99bcc1..1cac3532a 100644 --- a/packages/remark-parse/lib/tokenize/escape.js +++ b/packages/remark-parse/lib/tokenize/escape.js @@ -1,34 +1,34 @@ -'use strict'; +'use strict' -var locate = require('../locate/escape'); +var locate = require('../locate/escape') -module.exports = escape; -escape.locator = locate; +module.exports = escape +escape.locator = locate + +var lineFeed = '\n' +var backslash = '\\' function escape(eat, value, silent) { - var self = this; - var character; - var node; + var self = this + var character + var node - if (value.charAt(0) === '\\') { - character = value.charAt(1); + if (value.charAt(0) === backslash) { + character = value.charAt(1) if (self.escape.indexOf(character) !== -1) { /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - if (character === '\n') { - node = {type: 'break'}; + if (character === lineFeed) { + node = {type: 'break'} } else { - node = { - type: 'text', - value: character - }; + node = {type: 'text', value: character} } - return eat('\\' + character)(node); + return eat(backslash + character)(node) } } } diff --git a/packages/remark-parse/lib/tokenize/footnote-definition.js b/packages/remark-parse/lib/tokenize/footnote-definition.js index 4174a129f..62d8ce7b2 100644 --- a/packages/remark-parse/lib/tokenize/footnote-definition.js +++ b/packages/remark-parse/lib/tokenize/footnote-definition.js @@ -1,186 +1,186 @@ -'use strict'; +'use strict' -var whitespace = require('is-whitespace-character'); -var normalize = require('../util/normalize'); +var whitespace = require('is-whitespace-character') +var normalize = require('../util/normalize') -module.exports = footnoteDefinition; -footnoteDefinition.notInList = true; -footnoteDefinition.notInBlock = true; +module.exports = footnoteDefinition +footnoteDefinition.notInList = true +footnoteDefinition.notInBlock = true -var C_BACKSLASH = '\\'; -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; -var C_CARET = '^'; -var C_COLON = ':'; +var backslash = '\\' +var lineFeed = '\n' +var tab = '\t' +var space = ' ' +var leftSquareBracket = '[' +var rightSquareBracket = ']' +var caret = '^' +var colon = ':' -var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm; +var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm function footnoteDefinition(eat, value, silent) { - var self = this; - var offsets = self.offset; - var index; - var length; - var subvalue; - var now; - var currentLine; - var content; - var queue; - var subqueue; - var character; - var identifier; - var add; - var exit; + var self = this + var offsets = self.offset + var index + var length + var subvalue + var now + var currentLine + var content + var queue + var subqueue + var character + var identifier + var add + var exit if (!self.options.footnotes) { - return; + return } - index = 0; - length = value.length; - subvalue = ''; - now = eat.now(); - currentLine = now.line; + index = 0 + length = value.length + subvalue = '' + now = eat.now() + currentLine = now.line while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (!whitespace(character)) { - break; + break } - subvalue += character; - index++; + subvalue += character + index++ } if ( - value.charAt(index) !== C_BRACKET_OPEN || - value.charAt(index + 1) !== C_CARET + value.charAt(index) !== leftSquareBracket || + value.charAt(index + 1) !== caret ) { - return; + return } - subvalue += C_BRACKET_OPEN + C_CARET; - index = subvalue.length; - queue = ''; + subvalue += leftSquareBracket + caret + index = subvalue.length + queue = '' while (index < length) { - character = value.charAt(index); - - if (character === C_BRACKET_CLOSE) { - break; - } else if (character === C_BACKSLASH) { - queue += character; - index++; - character = value.charAt(index); + character = value.charAt(index) + + if (character === rightSquareBracket) { + break + } else if (character === backslash) { + queue += character + index++ + character = value.charAt(index) } - queue += character; - index++; + queue += character + index++ } if ( !queue || - value.charAt(index) !== C_BRACKET_CLOSE || - value.charAt(index + 1) !== C_COLON + value.charAt(index) !== rightSquareBracket || + value.charAt(index + 1) !== colon ) { - return; + return } if (silent) { - return true; + return true } - identifier = queue; - subvalue += queue + C_BRACKET_CLOSE + C_COLON; - index = subvalue.length; + identifier = queue + subvalue += queue + rightSquareBracket + colon + index = subvalue.length while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_TAB && character !== C_SPACE) { - break; + if (character !== tab && character !== space) { + break } - subvalue += character; - index++; + subvalue += character + index++ } - now.column += subvalue.length; - now.offset += subvalue.length; - queue = ''; - content = ''; - subqueue = ''; + now.column += subvalue.length + now.offset += subvalue.length + queue = '' + content = '' + subqueue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character === C_NEWLINE) { - subqueue = character; - index++; + if (character === lineFeed) { + subqueue = character + index++ while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_NEWLINE) { - break; + if (character !== lineFeed) { + break } - subqueue += character; - index++; + subqueue += character + index++ } - queue += subqueue; - subqueue = ''; + queue += subqueue + subqueue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE) { - break; + if (character !== space) { + break } - subqueue += character; - index++; + subqueue += character + index++ } if (subqueue.length === 0) { - break; + break } - queue += subqueue; + queue += subqueue } if (queue) { - content += queue; - queue = ''; + content += queue + queue = '' } - content += character; - index++; + content += character + index++ } - subvalue += content; + subvalue += content - content = content.replace(EXPRESSION_INITIAL_TAB, function (line) { - offsets[currentLine] = (offsets[currentLine] || 0) + line.length; - currentLine++; + content = content.replace(EXPRESSION_INITIAL_TAB, function(line) { + offsets[currentLine] = (offsets[currentLine] || 0) + line.length + currentLine++ - return ''; - }); + return '' + }) - add = eat(subvalue); + add = eat(subvalue) - exit = self.enterBlock(); - content = self.tokenizeBlock(content, now); - exit(); + exit = self.enterBlock() + content = self.tokenizeBlock(content, now) + exit() return add({ type: 'footnoteDefinition', identifier: normalize(identifier), label: identifier, children: content - }); + }) } diff --git a/packages/remark-parse/lib/tokenize/heading-atx.js b/packages/remark-parse/lib/tokenize/heading-atx.js index aafeabb54..934c6f2b3 100644 --- a/packages/remark-parse/lib/tokenize/heading-atx.js +++ b/packages/remark-parse/lib/tokenize/heading-atx.js @@ -1,141 +1,129 @@ -'use strict'; +'use strict' -module.exports = atxHeading; +module.exports = atxHeading -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_HASH = '#'; +var lineFeed = '\n' +var tab = '\t' +var space = ' ' +var numberSign = '#' -var MAX_ATX_COUNT = 6; +var maxFenceCount = 6 function atxHeading(eat, value, silent) { - var self = this; - var settings = self.options; - var length = value.length + 1; - var index = -1; - var now = eat.now(); - var subvalue = ''; - var content = ''; - var character; - var queue; - var depth; - - /* Eat initial spacing. */ + var self = this + var pedantic = self.options.pedantic + var length = value.length + 1 + var index = -1 + var now = eat.now() + var subvalue = '' + var content = '' + var character + var queue + var depth + + // Eat initial spacing. while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE && character !== C_TAB) { - index--; - break; + if (character !== space && character !== tab) { + index-- + break } - subvalue += character; + subvalue += character } - /* Eat hashes. */ - depth = 0; + // Eat hashes. + depth = 0 while (++index <= length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_HASH) { - index--; - break; + if (character !== numberSign) { + index-- + break } - subvalue += character; - depth++; + subvalue += character + depth++ } - if (depth > MAX_ATX_COUNT) { - return; + if (depth > maxFenceCount) { + return } - if ( - !depth || - (!settings.pedantic && value.charAt(index + 1) === C_HASH) - ) { - return; + if (!depth || (!pedantic && value.charAt(index + 1) === numberSign)) { + return } - length = value.length + 1; + length = value.length + 1 - /* Eat intermediate white-space. */ - queue = ''; + // Eat intermediate white-space. + queue = '' while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE && character !== C_TAB) { - index--; - break; + if (character !== space && character !== tab) { + index-- + break } - queue += character; + queue += character } - /* Exit when not in pedantic mode without spacing. */ - if ( - !settings.pedantic && - queue.length === 0 && - character && - character !== C_NEWLINE - ) { - return; + // Exit when not in pedantic mode without spacing. + if (!pedantic && queue.length === 0 && character && character !== lineFeed) { + return } if (silent) { - return true; + return true } - /* Eat content. */ - subvalue += queue; - queue = ''; - content = ''; + // Eat content. + subvalue += queue + queue = '' + content = '' while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (!character || character === C_NEWLINE) { - break; + if (!character || character === lineFeed) { + break } - if ( - character !== C_SPACE && - character !== C_TAB && - character !== C_HASH - ) { - content += queue + character; - queue = ''; - continue; + if (character !== space && character !== tab && character !== numberSign) { + content += queue + character + queue = '' + continue } - while (character === C_SPACE || character === C_TAB) { - queue += character; - character = value.charAt(++index); + while (character === space || character === tab) { + queue += character + character = value.charAt(++index) } - while (character === C_HASH) { - queue += character; - character = value.charAt(++index); + while (character === numberSign) { + queue += character + character = value.charAt(++index) } - while (character === C_SPACE || character === C_TAB) { - queue += character; - character = value.charAt(++index); + while (character === space || character === tab) { + queue += character + character = value.charAt(++index) } - index--; + index-- } - now.column += subvalue.length; - now.offset += subvalue.length; - subvalue += content + queue; + now.column += subvalue.length + now.offset += subvalue.length + subvalue += content + queue return eat(subvalue)({ type: 'heading', depth: depth, children: self.tokenizeInline(content, now) - }); + }) } diff --git a/packages/remark-parse/lib/tokenize/heading-setext.js b/packages/remark-parse/lib/tokenize/heading-setext.js index 96c6130da..142762345 100644 --- a/packages/remark-parse/lib/tokenize/heading-setext.js +++ b/packages/remark-parse/lib/tokenize/heading-setext.js @@ -1,107 +1,102 @@ -'use strict'; +'use strict' -module.exports = setextHeading; +module.exports = setextHeading -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_EQUALS = '='; -var C_DASH = '-'; +var lineFeed = '\n' +var tab = '\t' +var space = ' ' +var equalsTo = '=' +var dash = '-' -var MAX_HEADING_INDENT = 3; +var maxIndent = 3 -/* Map of characters which can be used to mark setext - * headers, mapping to their corresponding depth. */ -var SETEXT_MARKERS = {}; - -SETEXT_MARKERS[C_EQUALS] = 1; -SETEXT_MARKERS[C_DASH] = 2; +var equalsToDepth = 1 +var dashDepth = 2 function setextHeading(eat, value, silent) { - var self = this; - var now = eat.now(); - var length = value.length; - var index = -1; - var subvalue = ''; - var content; - var queue; - var character; - var marker; - var depth; - - /* Eat initial indentation. */ + var self = this + var now = eat.now() + var length = value.length + var index = -1 + var subvalue = '' + var content + var queue + var character + var marker + var depth + + // Eat initial indentation. while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_SPACE || index >= MAX_HEADING_INDENT) { - index--; - break; + if (character !== space || index >= maxIndent) { + index-- + break } - subvalue += character; + subvalue += character } - /* Eat content. */ - content = ''; - queue = ''; + // Eat content. + content = '' + queue = '' while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character === C_NEWLINE) { - index--; - break; + if (character === lineFeed) { + index-- + break } - if (character === C_SPACE || character === C_TAB) { - queue += character; + if (character === space || character === tab) { + queue += character } else { - content += queue + character; - queue = ''; + content += queue + character + queue = '' } } - now.column += subvalue.length; - now.offset += subvalue.length; - subvalue += content + queue; + now.column += subvalue.length + now.offset += subvalue.length + subvalue += content + queue - /* Ensure the content is followed by a newline and a - * valid marker. */ - character = value.charAt(++index); - marker = value.charAt(++index); + // Ensure the content is followed by a newline and a valid marker. + character = value.charAt(++index) + marker = value.charAt(++index) - if (character !== C_NEWLINE || !SETEXT_MARKERS[marker]) { - return; + if (character !== lineFeed || (marker !== equalsTo && marker !== dash)) { + return } - subvalue += character; + subvalue += character - /* Eat Setext-line. */ - queue = marker; - depth = SETEXT_MARKERS[marker]; + // Eat Setext-line. + queue = marker + depth = marker === equalsTo ? equalsToDepth : dashDepth while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) if (character !== marker) { - if (character !== C_NEWLINE) { - return; + if (character !== lineFeed) { + return } - index--; - break; + index-- + break } - queue += character; + queue += character } if (silent) { - return true; + return true } return eat(subvalue + queue)({ type: 'heading', depth: depth, children: self.tokenizeInline(content, now) - }); + }) } diff --git a/packages/remark-parse/lib/tokenize/html-block.js b/packages/remark-parse/lib/tokenize/html-block.js index 6e81eb290..149a71860 100644 --- a/packages/remark-parse/lib/tokenize/html-block.js +++ b/packages/remark-parse/lib/tokenize/html-block.js @@ -1,94 +1,111 @@ -'use strict'; - -var openCloseTag = require('../util/html').openCloseTag; - -module.exports = blockHTML; - -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_NEWLINE = '\n'; -var C_LT = '<'; - -function blockHTML(eat, value, silent) { - var self = this; - var blocks = self.options.blocks; - var length = value.length; - var index = 0; - var next; - var line; - var offset; - var character; - var count; - var sequence; - var subvalue; +'use strict' + +var openCloseTag = require('../util/html').openCloseTag + +module.exports = blockHtml + +var tab = '\t' +var space = ' ' +var lineFeed = '\n' +var lessThan = '<' + +var rawOpenExpression = /^<(script|pre|style)(?=(\s|>|$))/i +var rawCloseExpression = /<\/(script|pre|style)>/i +var commentOpenExpression = /^/ +var instructionOpenExpression = /^<\?/ +var instructionCloseExpression = /\?>/ +var directiveOpenExpression = /^/ +var cdataOpenExpression = /^/ +var elementCloseExpression = /^$/ +var otherElementOpenExpression = new RegExp(openCloseTag.source + '\\s*$') + +function blockHtml(eat, value, silent) { + var self = this + var blocks = self.options.blocks.join('|') + var elementOpenExpression = new RegExp( + '^|$))', + 'i' + ) + var length = value.length + var index = 0 + var next + var line + var offset + var character + var count + var sequence + var subvalue var sequences = [ - [/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true], - [/^/, true], - [/^<\?/, /\?>/, true], - [/^/, true], - [/^/, true], - [new RegExp('^|$))', 'i'), /^$/, true], - [new RegExp(openCloseTag.source + '\\s*$'), /^$/, false] - ]; - - /* Eat initial spacing. */ + [rawOpenExpression, rawCloseExpression, true], + [commentOpenExpression, commentCloseExpression, true], + [instructionOpenExpression, instructionCloseExpression, true], + [directiveOpenExpression, directiveCloseExpression, true], + [cdataOpenExpression, cdataCloseExpression, true], + [elementOpenExpression, elementCloseExpression, true], + [otherElementOpenExpression, elementCloseExpression, false] + ] + + // Eat initial spacing. while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_TAB && character !== C_SPACE) { - break; + if (character !== tab && character !== space) { + break } - index++; + index++ } - if (value.charAt(index) !== C_LT) { - return; + if (value.charAt(index) !== lessThan) { + return } - next = value.indexOf(C_NEWLINE, index + 1); - next = next === -1 ? length : next; - line = value.slice(index, next); - offset = -1; - count = sequences.length; + next = value.indexOf(lineFeed, index + 1) + next = next === -1 ? length : next + line = value.slice(index, next) + offset = -1 + count = sequences.length while (++offset < count) { if (sequences[offset][0].test(line)) { - sequence = sequences[offset]; - break; + sequence = sequences[offset] + break } } if (!sequence) { - return; + return } if (silent) { - return sequence[2]; + return sequence[2] } - index = next; + index = next if (!sequence[1].test(line)) { while (index < length) { - next = value.indexOf(C_NEWLINE, index + 1); - next = next === -1 ? length : next; - line = value.slice(index + 1, next); + next = value.indexOf(lineFeed, index + 1) + next = next === -1 ? length : next + line = value.slice(index + 1, next) if (sequence[1].test(line)) { if (line) { - index = next; + index = next } - break; + break } - index = next; + index = next } } - subvalue = value.slice(0, index); + subvalue = value.slice(0, index) - return eat(subvalue)({type: 'html', value: subvalue}); + return eat(subvalue)({type: 'html', value: subvalue}) } diff --git a/packages/remark-parse/lib/tokenize/html-inline.js b/packages/remark-parse/lib/tokenize/html-inline.js index c204e962b..cca4fb40a 100644 --- a/packages/remark-parse/lib/tokenize/html-inline.js +++ b/packages/remark-parse/lib/tokenize/html-inline.js @@ -1,54 +1,59 @@ -'use strict'; +'use strict' -var alphabetical = require('is-alphabetical'); -var locate = require('../locate/tag'); -var tag = require('../util/html').tag; +var alphabetical = require('is-alphabetical') +var locate = require('../locate/tag') +var tag = require('../util/html').tag -module.exports = inlineHTML; -inlineHTML.locator = locate; +module.exports = inlineHTML +inlineHTML.locator = locate -var EXPRESSION_HTML_LINK_OPEN = /^/i; +var lessThan = '<' +var questionMark = '?' +var exclamationMark = '!' +var slash = '/' + +var htmlLinkOpenExpression = /^/i function inlineHTML(eat, value, silent) { - var self = this; - var length = value.length; - var character; - var subvalue; + var self = this + var length = value.length + var character + var subvalue - if (value.charAt(0) !== '<' || length < 3) { - return; + if (value.charAt(0) !== lessThan || length < 3) { + return } - character = value.charAt(1); + character = value.charAt(1) if ( !alphabetical(character) && - character !== '?' && - character !== '!' && - character !== '/' + character !== questionMark && + character !== exclamationMark && + character !== slash ) { - return; + return } - subvalue = value.match(tag); + subvalue = value.match(tag) if (!subvalue) { - return; + return } /* istanbul ignore if - not used yet. */ if (silent) { - return true; + return true } - subvalue = subvalue[0]; + subvalue = subvalue[0] - if (!self.inLink && EXPRESSION_HTML_LINK_OPEN.test(subvalue)) { - self.inLink = true; - } else if (self.inLink && EXPRESSION_HTML_LINK_CLOSE.test(subvalue)) { - self.inLink = false; + if (!self.inLink && htmlLinkOpenExpression.test(subvalue)) { + self.inLink = true + } else if (self.inLink && htmlLinkCloseExpression.test(subvalue)) { + self.inLink = false } - return eat(subvalue)({type: 'html', value: subvalue}); + return eat(subvalue)({type: 'html', value: subvalue}) } diff --git a/packages/remark-parse/lib/tokenize/link.js b/packages/remark-parse/lib/tokenize/link.js index 3ef5e1ba3..ab4d3fa3c 100644 --- a/packages/remark-parse/lib/tokenize/link.js +++ b/packages/remark-parse/lib/tokenize/link.js @@ -1,392 +1,381 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/link'); - -module.exports = link; -link.locator = locate; - -var own = {}.hasOwnProperty; - -var C_BACKSLASH = '\\'; -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; -var C_PAREN_OPEN = '('; -var C_PAREN_CLOSE = ')'; -var C_LT = '<'; -var C_GT = '>'; -var C_TICK = '`'; -var C_DOUBLE_QUOTE = '"'; -var C_SINGLE_QUOTE = '\''; - -/* Map of characters, which can be used to mark link - * and image titles. */ -var LINK_MARKERS = {}; - -LINK_MARKERS[C_DOUBLE_QUOTE] = C_DOUBLE_QUOTE; -LINK_MARKERS[C_SINGLE_QUOTE] = C_SINGLE_QUOTE; - -/* Map of characters, which can be used to mark link - * and image titles in commonmark-mode. */ -var COMMONMARK_LINK_MARKERS = {}; - -COMMONMARK_LINK_MARKERS[C_DOUBLE_QUOTE] = C_DOUBLE_QUOTE; -COMMONMARK_LINK_MARKERS[C_SINGLE_QUOTE] = C_SINGLE_QUOTE; -COMMONMARK_LINK_MARKERS[C_PAREN_OPEN] = C_PAREN_CLOSE; +'use strict' + +var whitespace = require('is-whitespace-character') +var locate = require('../locate/link') + +module.exports = link +link.locator = locate + +var lineFeed = '\n' +var exclamationMark = '!' +var quotationMark = '"' +var apostrophe = "'" +var leftParenthesis = '(' +var rightParenthesis = ')' +var lessThan = '<' +var greaterThan = '>' +var leftSquareBracket = '[' +var backslash = '\\' +var rightSquareBracket = ']' +var graveAccent = '`' function link(eat, value, silent) { - var self = this; - var subvalue = ''; - var index = 0; - var character = value.charAt(0); - var pedantic = self.options.pedantic; - var commonmark = self.options.commonmark; - var gfm = self.options.gfm; - var closed; - var count; - var opening; - var beforeURL; - var beforeTitle; - var subqueue; - var hasMarker; - var markers; - var isImage; - var content; - var marker; - var length; - var title; - var depth; - var queue; - var url; - var now; - var exit; - var node; - - /* Detect whether this is an image. */ - if (character === '!') { - isImage = true; - subvalue = character; - character = value.charAt(++index); + var self = this + var subvalue = '' + var index = 0 + var character = value.charAt(0) + var pedantic = self.options.pedantic + var commonmark = self.options.commonmark + var gfm = self.options.gfm + var closed + var count + var opening + var beforeURL + var beforeTitle + var subqueue + var hasMarker + var isImage + var content + var marker + var length + var title + var depth + var queue + var url + var now + var exit + var node + + // Detect whether this is an image. + if (character === exclamationMark) { + isImage = true + subvalue = character + character = value.charAt(++index) } - /* Eat the opening. */ - if (character !== C_BRACKET_OPEN) { - return; + // Eat the opening. + if (character !== leftSquareBracket) { + return } - /* Exit when this is a link and we’re already inside - * a link. */ + // Exit when this is a link and we’re already inside a link. if (!isImage && self.inLink) { - return; + return } - subvalue += character; - queue = ''; - index++; + subvalue += character + queue = '' + index++ - /* Eat the content. */ - length = value.length; - now = eat.now(); - depth = 0; + // Eat the content. + length = value.length + now = eat.now() + depth = 0 - now.column += index; - now.offset += index; + now.column += index + now.offset += index while (index < length) { - character = value.charAt(index); - subqueue = character; + character = value.charAt(index) + subqueue = character - if (character === C_TICK) { - /* Inline-code in link content. */ - count = 1; + if (character === graveAccent) { + // Inline-code in link content. + count = 1 - while (value.charAt(index + 1) === C_TICK) { - subqueue += character; - index++; - count++; + while (value.charAt(index + 1) === graveAccent) { + subqueue += character + index++ + count++ } if (!opening) { - opening = count; + opening = count } else if (count >= opening) { - opening = 0; + opening = 0 } - } else if (character === C_BACKSLASH) { - /* Allow brackets to be escaped. */ - index++; - subqueue += value.charAt(index); - /* In GFM mode, brackets in code still count. - * In all other modes, they don’t. This empty - * block prevents the next statements are - * entered. */ - } else if ((!opening || gfm) && character === C_BRACKET_OPEN) { - depth++; - } else if ((!opening || gfm) && character === C_BRACKET_CLOSE) { + } else if (character === backslash) { + // Allow brackets to be escaped. + index++ + subqueue += value.charAt(index) + } else if ((!opening || gfm) && character === leftSquareBracket) { + // In GFM mode, brackets in code still count. In all other modes, + // they don’t. + depth++ + } else if ((!opening || gfm) && character === rightSquareBracket) { if (depth) { - depth--; + depth-- } else { - /* Allow white-space between content and - * url in GFM mode. */ + // Allow white-space between content and url in GFM mode. if (!pedantic) { while (index < length) { - character = value.charAt(index + 1); + character = value.charAt(index + 1) if (!whitespace(character)) { - break; + break } - subqueue += character; - index++; + subqueue += character + index++ } } - if (value.charAt(index + 1) !== C_PAREN_OPEN) { - return; + if (value.charAt(index + 1) !== leftParenthesis) { + return } - subqueue += C_PAREN_OPEN; - closed = true; - index++; + subqueue += leftParenthesis + closed = true + index++ - break; + break } } - queue += subqueue; - subqueue = ''; - index++; + queue += subqueue + subqueue = '' + index++ } - /* Eat the content closing. */ + // Eat the content closing. if (!closed) { - return; + return } - content = queue; - subvalue += queue + subqueue; - index++; + content = queue + subvalue += queue + subqueue + index++ - /* Eat white-space. */ + // Eat white-space. while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (!whitespace(character)) { - break; + break } - subvalue += character; - index++; + subvalue += character + index++ } - /* Eat the URL. */ - character = value.charAt(index); - markers = commonmark ? COMMONMARK_LINK_MARKERS : LINK_MARKERS; - queue = ''; - beforeURL = subvalue; + // Eat the URL. + character = value.charAt(index) + queue = '' + beforeURL = subvalue - if (character === C_LT) { - index++; - beforeURL += C_LT; + if (character === lessThan) { + index++ + beforeURL += lessThan while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character === C_GT) { - break; + if (character === greaterThan) { + break } - if (commonmark && character === '\n') { - return; + if (commonmark && character === lineFeed) { + return } - queue += character; - index++; + queue += character + index++ } - if (value.charAt(index) !== C_GT) { - return; + if (value.charAt(index) !== greaterThan) { + return } - subvalue += C_LT + queue + C_GT; - url = queue; - index++; + subvalue += lessThan + queue + greaterThan + url = queue + index++ } else { - character = null; - subqueue = ''; + character = null + subqueue = '' while (index < length) { - character = value.charAt(index); - - if (subqueue && own.call(markers, character)) { - break; + character = value.charAt(index) + + if ( + subqueue && + (character === quotationMark || + character === apostrophe || + (commonmark && character === leftParenthesis)) + ) { + break } if (whitespace(character)) { if (!pedantic) { - break; + break } - subqueue += character; + subqueue += character } else { - if (character === C_PAREN_OPEN) { - depth++; - } else if (character === C_PAREN_CLOSE) { + if (character === leftParenthesis) { + depth++ + } else if (character === rightParenthesis) { if (depth === 0) { - break; + break } - depth--; + depth-- } - queue += subqueue; - subqueue = ''; + queue += subqueue + subqueue = '' - if (character === C_BACKSLASH) { - queue += C_BACKSLASH; - character = value.charAt(++index); + if (character === backslash) { + queue += backslash + character = value.charAt(++index) } - queue += character; + queue += character } - index++; + index++ } - subvalue += queue; - url = queue; - index = subvalue.length; + subvalue += queue + url = queue + index = subvalue.length } - /* Eat white-space. */ - queue = ''; + // Eat white-space. + queue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (!whitespace(character)) { - break; + break } - queue += character; - index++; + queue += character + index++ } - character = value.charAt(index); - subvalue += queue; - - /* Eat the title. */ - if (queue && own.call(markers, character)) { - index++; - subvalue += character; - queue = ''; - marker = markers[character]; - beforeTitle = subvalue; - - /* In commonmark-mode, things are pretty easy: the - * marker cannot occur inside the title. - * - * Non-commonmark does, however, support nested - * delimiters. */ + character = value.charAt(index) + subvalue += queue + + // Eat the title. + if ( + queue && + (character === quotationMark || + character === apostrophe || + (commonmark && character === leftParenthesis)) + ) { + index++ + subvalue += character + queue = '' + marker = character === leftParenthesis ? rightParenthesis : character + beforeTitle = subvalue + + // In commonmark-mode, things are pretty easy: the marker cannot occur + // inside the title. Non-commonmark does, however, support nested + // delimiters. if (commonmark) { while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (character === marker) { - break; + break } - if (character === C_BACKSLASH) { - queue += C_BACKSLASH; - character = value.charAt(++index); + if (character === backslash) { + queue += backslash + character = value.charAt(++index) } - index++; - queue += character; + index++ + queue += character } - character = value.charAt(index); + character = value.charAt(index) if (character !== marker) { - return; + return } - title = queue; - subvalue += queue + character; - index++; + title = queue + subvalue += queue + character + index++ while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (!whitespace(character)) { - break; + break } - subvalue += character; - index++; + subvalue += character + index++ } } else { - subqueue = ''; + subqueue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (character === marker) { if (hasMarker) { - queue += marker + subqueue; - subqueue = ''; + queue += marker + subqueue + subqueue = '' } - hasMarker = true; + hasMarker = true } else if (!hasMarker) { - queue += character; - } else if (character === C_PAREN_CLOSE) { - subvalue += queue + marker + subqueue; - title = queue; - break; + queue += character + } else if (character === rightParenthesis) { + subvalue += queue + marker + subqueue + title = queue + break } else if (whitespace(character)) { - subqueue += character; + subqueue += character } else { - queue += marker + subqueue + character; - subqueue = ''; - hasMarker = false; + queue += marker + subqueue + character + subqueue = '' + hasMarker = false } - index++; + index++ } } } - if (value.charAt(index) !== C_PAREN_CLOSE) { - return; + if (value.charAt(index) !== rightParenthesis) { + return } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - subvalue += C_PAREN_CLOSE; + subvalue += rightParenthesis - url = self.decode.raw(self.unescape(url), eat(beforeURL).test().end, {nonTerminated: false}); + url = self.decode.raw(self.unescape(url), eat(beforeURL).test().end, { + nonTerminated: false + }) if (title) { - beforeTitle = eat(beforeTitle).test().end; - title = self.decode.raw(self.unescape(title), beforeTitle); + beforeTitle = eat(beforeTitle).test().end + title = self.decode.raw(self.unescape(title), beforeTitle) } node = { type: isImage ? 'image' : 'link', title: title || null, url: url - }; + } if (isImage) { - node.alt = self.decode.raw(self.unescape(content), now) || null; + node.alt = self.decode.raw(self.unescape(content), now) || null } else { - exit = self.enterLink(); - node.children = self.tokenizeInline(content, now); - exit(); + exit = self.enterLink() + node.children = self.tokenizeInline(content, now) + exit() } - return eat(subvalue)(node); + return eat(subvalue)(node) } diff --git a/packages/remark-parse/lib/tokenize/list.js b/packages/remark-parse/lib/tokenize/list.js index c80421871..8cdefdc9c 100644 --- a/packages/remark-parse/lib/tokenize/list.js +++ b/packages/remark-parse/lib/tokenize/list.js @@ -1,472 +1,452 @@ -'use strict'; +'use strict' /* eslint-disable max-params */ -var trim = require('trim'); -var repeat = require('repeat-string'); -var decimal = require('is-decimal'); -var getIndent = require('../util/get-indentation'); -var removeIndent = require('../util/remove-indentation'); -var interrupt = require('../util/interrupt'); - -module.exports = list; - -var C_ASTERISK = '*'; -var C_UNDERSCORE = '_'; -var C_PLUS = '+'; -var C_DASH = '-'; -var C_DOT = '.'; -var C_SPACE = ' '; -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_PAREN_CLOSE = ')'; -var C_X_LOWER = 'x'; -var C_EMPTY = ''; - -var TAB_SIZE = 4; -var EXPRESSION_LOOSE_LIST_ITEM = /\n\n(?!\s*$)/; -var EXPRESSION_TASK_ITEM = /^\[([ \t]|x|X)][ \t]/; -var EXPRESSION_BULLET = /^([ \t]*)([*+-]|\d+[.)])( {1,4}(?! )| |\t|$|(?=\n))([^\n]*)/; -var EXPRESSION_PEDANTIC_BULLET = /^([ \t]*)([*+-]|\d+[.)])([ \t]+)/; -var EXPRESSION_INITIAL_INDENT = /^( {1,4}|\t)?/gm; - -/* Map of characters which can be used to mark - * list-items. */ -var LIST_UNORDERED_MARKERS = {}; - -LIST_UNORDERED_MARKERS[C_ASTERISK] = true; -LIST_UNORDERED_MARKERS[C_PLUS] = true; -LIST_UNORDERED_MARKERS[C_DASH] = true; - -/* Map of characters which can be used to mark - * list-items after a digit. */ -var LIST_ORDERED_MARKERS = {}; - -LIST_ORDERED_MARKERS[C_DOT] = true; - -/* Map of characters which can be used to mark - * list-items after a digit. */ -var LIST_ORDERED_COMMONMARK_MARKERS = {}; - -LIST_ORDERED_COMMONMARK_MARKERS[C_DOT] = true; -LIST_ORDERED_COMMONMARK_MARKERS[C_PAREN_CLOSE] = true; +var trim = require('trim') +var repeat = require('repeat-string') +var decimal = require('is-decimal') +var getIndent = require('../util/get-indentation') +var removeIndent = require('../util/remove-indentation') +var interrupt = require('../util/interrupt') + +module.exports = list + +var asterisk = '*' +var underscore = '_' +var plusSign = '+' +var dash = '-' +var dot = '.' +var space = ' ' +var lineFeed = '\n' +var tab = '\t' +var rightParenthesis = ')' +var lowercaseX = 'x' + +var tabSize = 4 +var looseListItemExpression = /\n\n(?!\s*$)/ +var taskItemExpression = /^\[([ \t]|x|X)][ \t]/ +var bulletExpression = /^([ \t]*)([*+-]|\d+[.)])( {1,4}(?! )| |\t|$|(?=\n))([^\n]*)/ +var pedanticBulletExpression = /^([ \t]*)([*+-]|\d+[.)])([ \t]+)/ +var initialIndentExpression = /^( {1,4}|\t)?/gm function list(eat, value, silent) { - var self = this; - var commonmark = self.options.commonmark; - var pedantic = self.options.pedantic; - var tokenizers = self.blockTokenizers; - var interuptors = self.interruptList; - var markers; - var index = 0; - var length = value.length; - var start = null; - var size = 0; - var queue; - var ordered; - var character; - var marker; - var nextIndex; - var startIndex; - var prefixed; - var currentMarker; - var content; - var line; - var prevEmpty; - var empty; - var items; - var allLines; - var emptyLines; - var item; - var enterTop; - var exitBlockquote; - var spread = false; - var node; - var now; - var end; - var indented; + var self = this + var commonmark = self.options.commonmark + var pedantic = self.options.pedantic + var tokenizers = self.blockTokenizers + var interuptors = self.interruptList + var index = 0 + var length = value.length + var start = null + var size = 0 + var queue + var ordered + var character + var marker + var nextIndex + var startIndex + var prefixed + var currentMarker + var content + var line + var prevEmpty + var empty + var items + var allLines + var emptyLines + var item + var enterTop + var exitBlockquote + var spread = false + var node + var now + var end + var indented while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character === C_TAB) { - size += TAB_SIZE - (size % TAB_SIZE); - } else if (character === C_SPACE) { - size++; + if (character === tab) { + size += tabSize - (size % tabSize) + } else if (character === space) { + size++ } else { - break; + break } - index++; + index++ } - if (size >= TAB_SIZE) { - return; + if (size >= tabSize) { + return } - character = value.charAt(index); + character = value.charAt(index) - markers = commonmark ? - LIST_ORDERED_COMMONMARK_MARKERS : - LIST_ORDERED_MARKERS; - - if (LIST_UNORDERED_MARKERS[character] === true) { - marker = character; - ordered = false; + if (character === asterisk || character === plusSign || character === dash) { + marker = character + ordered = false } else { - ordered = true; - queue = ''; + ordered = true + queue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (!decimal(character)) { - break; + break } - queue += character; - index++; + queue += character + index++ } - character = value.charAt(index); + character = value.charAt(index) - if (!queue || markers[character] !== true) { - return; + if ( + !queue || + !(character === dot || (commonmark && character === rightParenthesis)) + ) { + return } - start = parseInt(queue, 10); - marker = character; + start = parseInt(queue, 10) + marker = character } - character = value.charAt(++index); + character = value.charAt(++index) if ( - character !== C_SPACE && - character !== C_TAB && - (pedantic || (character !== C_NEWLINE && character !== C_EMPTY)) + character !== space && + character !== tab && + (pedantic || (character !== lineFeed && character !== '')) ) { - return; + return } if (silent) { - return true; + return true } - index = 0; - items = []; - allLines = []; - emptyLines = []; + index = 0 + items = [] + allLines = [] + emptyLines = [] while (index < length) { - nextIndex = value.indexOf(C_NEWLINE, index); - startIndex = index; - prefixed = false; - indented = false; + nextIndex = value.indexOf(lineFeed, index) + startIndex = index + prefixed = false + indented = false if (nextIndex === -1) { - nextIndex = length; + nextIndex = length } - end = index + TAB_SIZE; - size = 0; + end = index + tabSize + size = 0 while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character === C_TAB) { - size += TAB_SIZE - (size % TAB_SIZE); - } else if (character === C_SPACE) { - size++; + if (character === tab) { + size += tabSize - (size % tabSize) + } else if (character === space) { + size++ } else { - break; + break } - index++; + index++ } - if (size >= TAB_SIZE) { - indented = true; + if (size >= tabSize) { + indented = true } if (item && size >= item.indent) { - indented = true; + indented = true } - character = value.charAt(index); - currentMarker = null; + character = value.charAt(index) + currentMarker = null if (!indented) { - if (LIST_UNORDERED_MARKERS[character] === true) { - currentMarker = character; - index++; - size++; + if ( + character === asterisk || + character === plusSign || + character === dash + ) { + currentMarker = character + index++ + size++ } else { - queue = ''; + queue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (!decimal(character)) { - break; + break } - queue += character; - index++; + queue += character + index++ } - character = value.charAt(index); - index++; + character = value.charAt(index) + index++ - if (queue && markers[character] === true) { - currentMarker = character; - size += queue.length + 1; + if ( + queue && + (character === dot || (commonmark && character === rightParenthesis)) + ) { + currentMarker = character + size += queue.length + 1 } } if (currentMarker) { - character = value.charAt(index); + character = value.charAt(index) - if (character === C_TAB) { - size += TAB_SIZE - (size % TAB_SIZE); - index++; - } else if (character === C_SPACE) { - end = index + TAB_SIZE; + if (character === tab) { + size += tabSize - (size % tabSize) + index++ + } else if (character === space) { + end = index + tabSize while (index < end) { - if (value.charAt(index) !== C_SPACE) { - break; + if (value.charAt(index) !== space) { + break } - index++; - size++; + index++ + size++ } - if (index === end && value.charAt(index) === C_SPACE) { - index -= TAB_SIZE - 1; - size -= TAB_SIZE - 1; + if (index === end && value.charAt(index) === space) { + index -= tabSize - 1 + size -= tabSize - 1 } - } else if (character !== C_NEWLINE && character !== '') { - currentMarker = null; + } else if (character !== lineFeed && character !== '') { + currentMarker = null } } } if (currentMarker) { if (!pedantic && marker !== currentMarker) { - break; + break } - prefixed = true; + prefixed = true } else { - if (!commonmark && !indented && value.charAt(startIndex) === C_SPACE) { - indented = true; + if (!commonmark && !indented && value.charAt(startIndex) === space) { + indented = true } else if (commonmark && item) { - indented = size >= item.indent || size > TAB_SIZE; + indented = size >= item.indent || size > tabSize } - prefixed = false; - index = startIndex; + prefixed = false + index = startIndex } - line = value.slice(startIndex, nextIndex); - content = startIndex === index ? line : value.slice(index, nextIndex); + line = value.slice(startIndex, nextIndex) + content = startIndex === index ? line : value.slice(index, nextIndex) if ( - currentMarker === C_ASTERISK || - currentMarker === C_UNDERSCORE || - currentMarker === C_DASH + currentMarker === asterisk || + currentMarker === underscore || + currentMarker === dash ) { if (tokenizers.thematicBreak.call(self, eat, line, true)) { - break; + break } } - prevEmpty = empty; - empty = !prefixed && !trim(content).length; + prevEmpty = empty + empty = !prefixed && !trim(content).length if (indented && item) { - item.value = item.value.concat(emptyLines, line); - allLines = allLines.concat(emptyLines, line); - emptyLines = []; + item.value = item.value.concat(emptyLines, line) + allLines = allLines.concat(emptyLines, line) + emptyLines = [] } else if (prefixed) { if (emptyLines.length !== 0) { - spread = true; - item.value.push(''); - item.trail = emptyLines.concat(); + spread = true + item.value.push('') + item.trail = emptyLines.concat() } item = { value: [line], indent: size, trail: [] - }; + } - items.push(item); - allLines = allLines.concat(emptyLines, line); - emptyLines = []; + items.push(item) + allLines = allLines.concat(emptyLines, line) + emptyLines = [] } else if (empty) { if (prevEmpty && !commonmark) { - break; + break } - emptyLines.push(line); + emptyLines.push(line) } else { if (prevEmpty) { - break; + break } if (interrupt(interuptors, tokenizers, self, [eat, line, true])) { - break; + break } - item.value = item.value.concat(emptyLines, line); - allLines = allLines.concat(emptyLines, line); - emptyLines = []; + item.value = item.value.concat(emptyLines, line) + allLines = allLines.concat(emptyLines, line) + emptyLines = [] } - index = nextIndex + 1; + index = nextIndex + 1 } - node = eat(allLines.join(C_NEWLINE)).reset({ + node = eat(allLines.join(lineFeed)).reset({ type: 'list', ordered: ordered, start: start, spread: spread, children: [] - }); + }) - enterTop = self.enterList(); - exitBlockquote = self.enterBlock(); - index = -1; - length = items.length; + enterTop = self.enterList() + exitBlockquote = self.enterBlock() + index = -1 + length = items.length while (++index < length) { - item = items[index].value.join(C_NEWLINE); - now = eat.now(); + item = items[index].value.join(lineFeed) + now = eat.now() - eat(item)(listItem(self, item, now), node); + eat(item)(listItem(self, item, now), node) - item = items[index].trail.join(C_NEWLINE); + item = items[index].trail.join(lineFeed) if (index !== length - 1) { - item += C_NEWLINE; + item += lineFeed } - eat(item); + eat(item) } - enterTop(); - exitBlockquote(); + enterTop() + exitBlockquote() - return node; + return node } function listItem(ctx, value, position) { - var offsets = ctx.offset; - var fn = ctx.options.pedantic ? pedanticListItem : normalListItem; - var checked = null; - var task; - var indent; + var offsets = ctx.offset + var fn = ctx.options.pedantic ? pedanticListItem : normalListItem + var checked = null + var task + var indent - value = fn.apply(null, arguments); + value = fn.apply(null, arguments) if (ctx.options.gfm) { - task = value.match(EXPRESSION_TASK_ITEM); + task = value.match(taskItemExpression) if (task) { - indent = task[0].length; - checked = task[1].toLowerCase() === C_X_LOWER; - offsets[position.line] += indent; - value = value.slice(indent); + indent = task[0].length + checked = task[1].toLowerCase() === lowercaseX + offsets[position.line] += indent + value = value.slice(indent) } } return { type: 'listItem', - spread: EXPRESSION_LOOSE_LIST_ITEM.test(value), + spread: looseListItemExpression.test(value), checked: checked, children: ctx.tokenizeBlock(value, position) - }; + } } -/* Create a list-item using overly simple mechanics. */ +// Create a list-item using overly simple mechanics. function pedanticListItem(ctx, value, position) { - var offsets = ctx.offset; - var line = position.line; + var offsets = ctx.offset + var line = position.line - /* Remove the list-item’s bullet. */ - value = value.replace(EXPRESSION_PEDANTIC_BULLET, replacer); + // Remove the list-item’s bullet. + value = value.replace(pedanticBulletExpression, replacer) - /* The initial line was also matched by the below, so - * we reset the `line`. */ - line = position.line; + // The initial line was also matched by the below, so we reset the `line`. + line = position.line - return value.replace(EXPRESSION_INITIAL_INDENT, replacer); + return value.replace(initialIndentExpression, replacer) - /* A simple replacer which removed all matches, - * and adds their length to `offset`. */ + // A simple replacer which removed all matches, and adds their length to + // `offset`. function replacer($0) { - offsets[line] = (offsets[line] || 0) + $0.length; - line++; + offsets[line] = (offsets[line] || 0) + $0.length + line++ - return ''; + return '' } } -/* Create a list-item using sane mechanics. */ +// Create a list-item using sane mechanics. function normalListItem(ctx, value, position) { - var offsets = ctx.offset; - var line = position.line; - var max; - var bullet; - var rest; - var lines; - var trimmedLines; - var index; - var length; + var offsets = ctx.offset + var line = position.line + var max + var bullet + var rest + var lines + var trimmedLines + var index + var length - /* Remove the list-item’s bullet. */ - value = value.replace(EXPRESSION_BULLET, replacer); + // Remove the list-item’s bullet. + value = value.replace(bulletExpression, replacer) - lines = value.split(C_NEWLINE); + lines = value.split(lineFeed) - trimmedLines = removeIndent(value, getIndent(max).indent).split(C_NEWLINE); + trimmedLines = removeIndent(value, getIndent(max).indent).split(lineFeed) - /* We replaced the initial bullet with something - * else above, which was used to trick - * `removeIndentation` into removing some more - * characters when possible. However, that could - * result in the initial line to be stripped more - * than it should be. */ - trimmedLines[0] = rest; + // We replaced the initial bullet with something else above, which was used + // to trick `removeIndentation` into removing some more characters when + // possible. However, that could result in the initial line to be stripped + // more than it should be. + trimmedLines[0] = rest - offsets[line] = (offsets[line] || 0) + bullet.length; - line++; + offsets[line] = (offsets[line] || 0) + bullet.length + line++ - index = 0; - length = lines.length; + index = 0 + length = lines.length while (++index < length) { - offsets[line] = (offsets[line] || 0) + - lines[index].length - trimmedLines[index].length; - line++; + offsets[line] = + (offsets[line] || 0) + lines[index].length - trimmedLines[index].length + line++ } - return trimmedLines.join(C_NEWLINE); + return trimmedLines.join(lineFeed) function replacer($0, $1, $2, $3, $4) { - bullet = $1 + $2 + $3; - rest = $4; + bullet = $1 + $2 + $3 + rest = $4 - /* Make sure that the first nine numbered list items - * can indent with an extra space. That is, when - * the bullet did not receive an extra final space. */ + // Make sure that the first nine numbered list items can indent with an + // extra space. That is, when the bullet did not receive an extra final + // space. if (Number($2) < 10 && bullet.length % 2 === 1) { - $2 = C_SPACE + $2; + $2 = space + $2 } - max = $1 + repeat(C_SPACE, $2.length) + $3; + max = $1 + repeat(space, $2.length) + $3 - return max + rest; + return max + rest } } diff --git a/packages/remark-parse/lib/tokenize/newline.js b/packages/remark-parse/lib/tokenize/newline.js index 6008670cc..680020cf0 100644 --- a/packages/remark-parse/lib/tokenize/newline.js +++ b/packages/remark-parse/lib/tokenize/newline.js @@ -1,47 +1,48 @@ -'use strict'; +'use strict' -var whitespace = require('is-whitespace-character'); +var whitespace = require('is-whitespace-character') -module.exports = newline; +module.exports = newline + +var lineFeed = '\n' -/* Tokenise newline. */ function newline(eat, value, silent) { - var character = value.charAt(0); - var length; - var subvalue; - var queue; - var index; - - if (character !== '\n') { - return; + var character = value.charAt(0) + var length + var subvalue + var queue + var index + + if (character !== lineFeed) { + return } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - index = 1; - length = value.length; - subvalue = character; - queue = ''; + index = 1 + length = value.length + subvalue = character + queue = '' while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (!whitespace(character)) { - break; + break } - queue += character; + queue += character - if (character === '\n') { - subvalue += queue; - queue = ''; + if (character === lineFeed) { + subvalue += queue + queue = '' } - index++; + index++ } - eat(subvalue); + eat(subvalue) } diff --git a/packages/remark-parse/lib/tokenize/paragraph.js b/packages/remark-parse/lib/tokenize/paragraph.js index b9a633cd1..13db0ff40 100644 --- a/packages/remark-parse/lib/tokenize/paragraph.js +++ b/packages/remark-parse/lib/tokenize/paragraph.js @@ -1,122 +1,117 @@ -'use strict'; +'use strict' -var trim = require('trim'); -var decimal = require('is-decimal'); -var trimTrailingLines = require('trim-trailing-lines'); -var interrupt = require('../util/interrupt'); +var trim = require('trim') +var decimal = require('is-decimal') +var trimTrailingLines = require('trim-trailing-lines') +var interrupt = require('../util/interrupt') -module.exports = paragraph; +module.exports = paragraph -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; +var tab = '\t' +var lineFeed = '\n' +var space = ' ' -var TAB_SIZE = 4; +var tabSize = 4 -/* Tokenise paragraph. */ +// Tokenise paragraph. function paragraph(eat, value, silent) { - var self = this; - var settings = self.options; - var commonmark = settings.commonmark; - var gfm = settings.gfm; - var tokenizers = self.blockTokenizers; - var interruptors = self.interruptParagraph; - var index = value.indexOf(C_NEWLINE); - var length = value.length; - var position; - var subvalue; - var character; - var size; - var now; + var self = this + var settings = self.options + var commonmark = settings.commonmark + var gfm = settings.gfm + var tokenizers = self.blockTokenizers + var interruptors = self.interruptParagraph + var index = value.indexOf(lineFeed) + var length = value.length + var position + var subvalue + var character + var size + var now while (index < length) { - /* Eat everything if there’s no following newline. */ + // Eat everything if there’s no following newline. if (index === -1) { - index = length; - break; + index = length + break } - /* Stop if the next character is NEWLINE. */ - if (value.charAt(index + 1) === C_NEWLINE) { - break; + // Stop if the next character is NEWLINE. + if (value.charAt(index + 1) === lineFeed) { + break } - /* In commonmark-mode, following indented lines - * are part of the paragraph. */ + // In commonmark-mode, following indented lines are part of the paragraph. if (commonmark) { - size = 0; - position = index + 1; + size = 0 + position = index + 1 while (position < length) { - character = value.charAt(position); + character = value.charAt(position) - if (character === C_TAB) { - size = TAB_SIZE; - break; - } else if (character === C_SPACE) { - size++; + if (character === tab) { + size = tabSize + break + } else if (character === space) { + size++ } else { - break; + break } - position++; + position++ } - if (size >= TAB_SIZE && character !== C_NEWLINE) { - index = value.indexOf(C_NEWLINE, index + 1); - continue; + if (size >= tabSize && character !== lineFeed) { + index = value.indexOf(lineFeed, index + 1) + continue } } - subvalue = value.slice(index + 1); + subvalue = value.slice(index + 1) - /* Check if the following code contains a possible - * block. */ + // Check if the following code contains a possible block. if (interrupt(interruptors, tokenizers, self, [eat, subvalue, true])) { - break; + break } - /* Break if the following line starts a list, when - * already in a list, or when in commonmark, or when - * in gfm mode and the bullet is *not* numeric. */ + // Break if the following line starts a list, when already in a list, or + // when in commonmark, or when in gfm mode and the bullet is *not* numeric. if ( tokenizers.list.call(self, eat, subvalue, true) && - ( - self.inList || + (self.inList || commonmark || - (gfm && !decimal(trim.left(subvalue).charAt(0))) - ) + (gfm && !decimal(trim.left(subvalue).charAt(0)))) ) { - break; + break } - position = index; - index = value.indexOf(C_NEWLINE, index + 1); + position = index + index = value.indexOf(lineFeed, index + 1) if (index !== -1 && trim(value.slice(position, index)) === '') { - index = position; - break; + index = position + break } } - subvalue = value.slice(0, index); + subvalue = value.slice(0, index) if (trim(subvalue) === '') { - eat(subvalue); + eat(subvalue) - return null; + return null } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - now = eat.now(); - subvalue = trimTrailingLines(subvalue); + now = eat.now() + subvalue = trimTrailingLines(subvalue) return eat(subvalue)({ type: 'paragraph', children: self.tokenizeInline(subvalue, now) - }); + }) } diff --git a/packages/remark-parse/lib/tokenize/reference.js b/packages/remark-parse/lib/tokenize/reference.js index 27947dbe4..911e35b9f 100644 --- a/packages/remark-parse/lib/tokenize/reference.js +++ b/packages/remark-parse/lib/tokenize/reference.js @@ -1,213 +1,215 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/link'); -var normalize = require('../util/normalize'); - -module.exports = reference; -reference.locator = locate; - -var T_LINK = 'link'; -var T_IMAGE = 'image'; -var T_FOOTNOTE = 'footnote'; -var REFERENCE_TYPE_SHORTCUT = 'shortcut'; -var REFERENCE_TYPE_COLLAPSED = 'collapsed'; -var REFERENCE_TYPE_FULL = 'full'; -var C_CARET = '^'; -var C_BACKSLASH = '\\'; -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; +'use strict' + +var whitespace = require('is-whitespace-character') +var locate = require('../locate/link') +var normalize = require('../util/normalize') + +module.exports = reference +reference.locator = locate + +var link = 'link' +var image = 'image' +var footnote = 'footnote' +var shortcut = 'shortcut' +var collapsed = 'collapsed' +var full = 'full' +var space = ' ' +var exclamationMark = '!' +var leftSquareBracket = '[' +var backslash = '\\' +var rightSquareBracket = ']' +var caret = '^' function reference(eat, value, silent) { - var self = this; - var commonmark = self.options.commonmark; - var character = value.charAt(0); - var index = 0; - var length = value.length; - var subvalue = ''; - var intro = ''; - var type = T_LINK; - var referenceType = REFERENCE_TYPE_SHORTCUT; - var content; - var identifier; - var now; - var node; - var exit; - var queue; - var bracketed; - var depth; - - /* Check whether we’re eating an image. */ - if (character === '!') { - type = T_IMAGE; - intro = character; - character = value.charAt(++index); + var self = this + var commonmark = self.options.commonmark + var character = value.charAt(0) + var index = 0 + var length = value.length + var subvalue = '' + var intro = '' + var type = link + var referenceType = shortcut + var content + var identifier + var now + var node + var exit + var queue + var bracketed + var depth + + // Check whether we’re eating an image. + if (character === exclamationMark) { + type = image + intro = character + character = value.charAt(++index) } - if (character !== C_BRACKET_OPEN) { - return; + if (character !== leftSquareBracket) { + return } - index++; - intro += character; - queue = ''; + index++ + intro += character + queue = '' - /* Check whether we’re eating a footnote. */ - if (self.options.footnotes && value.charAt(index) === C_CARET) { - /* Exit if `![^` is found, so the `!` will be seen as text after this, - * and we’ll enter this function again when `[^` is found. */ - if (type === T_IMAGE) { - return; + // Check whether we’re eating a footnote. + if (self.options.footnotes && value.charAt(index) === caret) { + // Exit if `![^` is found, so the `!` will be seen as text after this, + // and we’ll enter this function again when `[^` is found. + if (type === image) { + return } - intro += C_CARET; - index++; - type = T_FOOTNOTE; + intro += caret + index++ + type = footnote } - /* Eat the text. */ - depth = 0; + // Eat the text. + depth = 0 while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character === C_BRACKET_OPEN) { - bracketed = true; - depth++; - } else if (character === C_BRACKET_CLOSE) { + if (character === leftSquareBracket) { + bracketed = true + depth++ + } else if (character === rightSquareBracket) { if (!depth) { - break; + break } - depth--; + depth-- } - if (character === C_BACKSLASH) { - queue += C_BACKSLASH; - character = value.charAt(++index); + if (character === backslash) { + queue += backslash + character = value.charAt(++index) } - queue += character; - index++; + queue += character + index++ } - subvalue = queue; - content = queue; - character = value.charAt(index); + subvalue = queue + content = queue + character = value.charAt(index) - if (character !== C_BRACKET_CLOSE) { - return; + if (character !== rightSquareBracket) { + return } - index++; - subvalue += character; - queue = ''; + index++ + subvalue += character + queue = '' if (!commonmark) { - /* The original markdown syntax definition explicitly allows for whitespace - * between the link text and link label; commonmark departs from this, in - * part to improve support for shortcut reference links */ + // The original markdown syntax definition explicitly allows for whitespace + // between the link text and link label; commonmark departs from this, in + // part to improve support for shortcut reference links while (index < length) { - character = value.charAt(index); + character = value.charAt(index) if (!whitespace(character)) { - break; + break } - queue += character; - index++; + queue += character + index++ } } - character = value.charAt(index); + character = value.charAt(index) - /* Inline footnotes cannot have an identifier. */ - if (type !== T_FOOTNOTE && character === C_BRACKET_OPEN) { - identifier = ''; - queue += character; - index++; + // Inline footnotes cannot have an identifier. + if (type !== footnote && character === leftSquareBracket) { + identifier = '' + queue += character + index++ while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character === C_BRACKET_OPEN || character === C_BRACKET_CLOSE) { - break; + if (character === leftSquareBracket || character === rightSquareBracket) { + break } - if (character === C_BACKSLASH) { - identifier += C_BACKSLASH; - character = value.charAt(++index); + if (character === backslash) { + identifier += backslash + character = value.charAt(++index) } - identifier += character; - index++; + identifier += character + index++ } - character = value.charAt(index); + character = value.charAt(index) - if (character === C_BRACKET_CLOSE) { - referenceType = identifier ? REFERENCE_TYPE_FULL : REFERENCE_TYPE_COLLAPSED; - queue += identifier + character; - index++; + if (character === rightSquareBracket) { + referenceType = identifier ? full : collapsed + queue += identifier + character + index++ } else { - identifier = ''; + identifier = '' } - subvalue += queue; - queue = ''; + subvalue += queue + queue = '' } else { if (!content) { - return; + return } - identifier = content; + identifier = content } - /* Brackets cannot be inside the identifier. */ - if (referenceType !== REFERENCE_TYPE_FULL && bracketed) { - return; + // Brackets cannot be inside the identifier. + if (referenceType !== full && bracketed) { + return } - subvalue = intro + subvalue; + subvalue = intro + subvalue - if (type === T_LINK && self.inLink) { - return null; + if (type === link && self.inLink) { + return null } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - if (type === T_FOOTNOTE && content.indexOf(' ') !== -1) { + if (type === footnote && content.indexOf(space) !== -1) { return eat(subvalue)({ - type: 'footnote', + type: footnote, children: this.tokenizeInline(content, eat.now()) - }); + }) } - now = eat.now(); - now.column += intro.length; - now.offset += intro.length; - identifier = referenceType === REFERENCE_TYPE_FULL ? identifier : content; + now = eat.now() + now.column += intro.length + now.offset += intro.length + identifier = referenceType === full ? identifier : content node = { type: type + 'Reference', identifier: normalize(identifier), label: identifier - }; + } - if (type === T_LINK || type === T_IMAGE) { - node.referenceType = referenceType; + if (type === link || type === image) { + node.referenceType = referenceType } - if (type === T_LINK) { - exit = self.enterLink(); - node.children = self.tokenizeInline(content, now); - exit(); - } else if (type === T_IMAGE) { - node.alt = self.decode.raw(self.unescape(content), now) || null; + if (type === link) { + exit = self.enterLink() + node.children = self.tokenizeInline(content, now) + exit() + } else if (type === image) { + node.alt = self.decode.raw(self.unescape(content), now) || null } - return eat(subvalue)(node); + return eat(subvalue)(node) } diff --git a/packages/remark-parse/lib/tokenize/strong.js b/packages/remark-parse/lib/tokenize/strong.js index 12d5785bc..3e36462a7 100644 --- a/packages/remark-parse/lib/tokenize/strong.js +++ b/packages/remark-parse/lib/tokenize/strong.js @@ -1,84 +1,85 @@ -'use strict'; +'use strict' -var trim = require('trim'); -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/strong'); +var trim = require('trim') +var whitespace = require('is-whitespace-character') +var locate = require('../locate/strong') -module.exports = strong; -strong.locator = locate; +module.exports = strong +strong.locator = locate -var C_ASTERISK = '*'; -var C_UNDERSCORE = '_'; +var backslash = '\\' +var asterisk = '*' +var underscore = '_' function strong(eat, value, silent) { - var self = this; - var index = 0; - var character = value.charAt(index); - var now; - var pedantic; - var marker; - var queue; - var subvalue; - var length; - var prev; + var self = this + var index = 0 + var character = value.charAt(index) + var now + var pedantic + var marker + var queue + var subvalue + var length + var prev if ( - (character !== C_ASTERISK && character !== C_UNDERSCORE) || + (character !== asterisk && character !== underscore) || value.charAt(++index) !== character ) { - return; + return } - pedantic = self.options.pedantic; - marker = character; - subvalue = marker + marker; - length = value.length; - index++; - queue = ''; - character = ''; + pedantic = self.options.pedantic + marker = character + subvalue = marker + marker + length = value.length + index++ + queue = '' + character = '' if (pedantic && whitespace(value.charAt(index))) { - return; + return } while (index < length) { - prev = character; - character = value.charAt(index); + prev = character + character = value.charAt(index) if ( character === marker && value.charAt(index + 1) === marker && (!pedantic || !whitespace(prev)) ) { - character = value.charAt(index + 2); + character = value.charAt(index + 2) if (character !== marker) { if (!trim(queue)) { - return; + return } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - now = eat.now(); - now.column += 2; - now.offset += 2; + now = eat.now() + now.column += 2 + now.offset += 2 return eat(subvalue + queue + subvalue)({ type: 'strong', children: self.tokenizeInline(queue, now) - }); + }) } } - if (!pedantic && character === '\\') { - queue += character; - character = value.charAt(++index); + if (!pedantic && character === backslash) { + queue += character + character = value.charAt(++index) } - queue += character; - index++; + queue += character + index++ } } diff --git a/packages/remark-parse/lib/tokenize/table.js b/packages/remark-parse/lib/tokenize/table.js index ce93b1d22..8a7b4346a 100644 --- a/packages/remark-parse/lib/tokenize/table.js +++ b/packages/remark-parse/lib/tokenize/table.js @@ -1,266 +1,259 @@ -'use strict'; +'use strict' -var whitespace = require('is-whitespace-character'); +var whitespace = require('is-whitespace-character') -module.exports = table; +module.exports = table -var C_BACKSLASH = '\\'; -var C_TICK = '`'; -var C_DASH = '-'; -var C_PIPE = '|'; -var C_COLON = ':'; -var C_SPACE = ' '; -var C_NEWLINE = '\n'; -var C_TAB = '\t'; +var tab = '\t' +var lineFeed = '\n' +var space = ' ' +var dash = '-' +var colon = ':' +var backslash = '\\' +var graveAccent = '`' +var verticalBar = '|' -var MIN_TABLE_COLUMNS = 1; -var MIN_TABLE_ROWS = 2; +var minColumns = 1 +var minRows = 2 -var TABLE_ALIGN_LEFT = 'left'; -var TABLE_ALIGN_CENTER = 'center'; -var TABLE_ALIGN_RIGHT = 'right'; -var TABLE_ALIGN_NONE = null; +var left = 'left' +var center = 'center' +var right = 'right' function table(eat, value, silent) { - var self = this; - var index; - var alignments; - var alignment; - var subvalue; - var row; - var length; - var lines; - var queue; - var character; - var hasDash; - var align; - var cell; - var preamble; - var count; - var opening; - var now; - var position; - var lineCount; - var line; - var rows; - var table; - var lineIndex; - var pipeIndex; - var first; - - /* Exit when not in gfm-mode. */ + var self = this + var index + var alignments + var alignment + var subvalue + var row + var length + var lines + var queue + var character + var hasDash + var align + var cell + var preamble + var count + var opening + var now + var position + var lineCount + var line + var rows + var table + var lineIndex + var pipeIndex + var first + + // Exit when not in gfm-mode. if (!self.options.gfm) { - return; + return } - /* Get the rows. - * Detecting tables soon is hard, so there are some - * checks for performance here, such as the minimum - * number of rows, and allowed characters in the - * alignment row. */ - index = 0; - lineCount = 0; - length = value.length + 1; - lines = []; + // Get the rows. + // Detecting tables soon is hard, so there are some checks for performance + // here, such as the minimum number of rows, and allowed characters in the + // alignment row. + index = 0 + lineCount = 0 + length = value.length + 1 + lines = [] while (index < length) { - lineIndex = value.indexOf(C_NEWLINE, index); - pipeIndex = value.indexOf(C_PIPE, index + 1); + lineIndex = value.indexOf(lineFeed, index) + pipeIndex = value.indexOf(verticalBar, index + 1) if (lineIndex === -1) { - lineIndex = value.length; + lineIndex = value.length } if (pipeIndex === -1 || pipeIndex > lineIndex) { - if (lineCount < MIN_TABLE_ROWS) { - return; + if (lineCount < minRows) { + return } - break; + break } - lines.push(value.slice(index, lineIndex)); - lineCount++; - index = lineIndex + 1; + lines.push(value.slice(index, lineIndex)) + lineCount++ + index = lineIndex + 1 } - /* Parse the alignment row. */ - subvalue = lines.join(C_NEWLINE); - alignments = lines.splice(1, 1)[0] || []; - index = 0; - length = alignments.length; - lineCount--; - alignment = false; - align = []; + // Parse the alignment row. + subvalue = lines.join(lineFeed) + alignments = lines.splice(1, 1)[0] || [] + index = 0 + length = alignments.length + lineCount-- + alignment = false + align = [] while (index < length) { - character = alignments.charAt(index); + character = alignments.charAt(index) - if (character === C_PIPE) { - hasDash = null; + if (character === verticalBar) { + hasDash = null if (alignment === false) { if (first === false) { - return; + return } } else { - align.push(alignment); - alignment = false; + align.push(alignment) + alignment = false } - first = false; - } else if (character === C_DASH) { - hasDash = true; - alignment = alignment || TABLE_ALIGN_NONE; - } else if (character === C_COLON) { - if (alignment === TABLE_ALIGN_LEFT) { - alignment = TABLE_ALIGN_CENTER; - } else if (hasDash && alignment === TABLE_ALIGN_NONE) { - alignment = TABLE_ALIGN_RIGHT; + first = false + } else if (character === dash) { + hasDash = true + alignment = alignment || null + } else if (character === colon) { + if (alignment === left) { + alignment = center + } else if (hasDash && alignment === null) { + alignment = right } else { - alignment = TABLE_ALIGN_LEFT; + alignment = left } } else if (!whitespace(character)) { - return; + return } - index++; + index++ } if (alignment !== false) { - align.push(alignment); + align.push(alignment) } - /* Exit when without enough columns. */ - if (align.length < MIN_TABLE_COLUMNS) { - return; + // Exit when without enough columns. + if (align.length < minColumns) { + return } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - /* Parse the rows. */ - position = -1; - rows = []; + // Parse the rows. + position = -1 + rows = [] - table = eat(subvalue).reset({ - type: 'table', - align: align, - children: rows - }); + table = eat(subvalue).reset({type: 'table', align: align, children: rows}) while (++position < lineCount) { - line = lines[position]; - row = {type: 'tableRow', children: []}; + line = lines[position] + row = {type: 'tableRow', children: []} - /* Eat a newline character when this is not the - * first row. */ + // Eat a newline character when this is not the first row. if (position) { - eat(C_NEWLINE); + eat(lineFeed) } - /* Eat the row. */ - eat(line).reset(row, table); + // Eat the row. + eat(line).reset(row, table) - length = line.length + 1; - index = 0; - queue = ''; - cell = ''; - preamble = true; - count = null; - opening = null; + length = line.length + 1 + index = 0 + queue = '' + cell = '' + preamble = true + count = null + opening = null while (index < length) { - character = line.charAt(index); + character = line.charAt(index) - if (character === C_TAB || character === C_SPACE) { + if (character === tab || character === space) { if (cell) { - queue += character; + queue += character } else { - eat(character); + eat(character) } - index++; - continue; + index++ + continue } - if (character === '' || character === C_PIPE) { + if (character === '' || character === verticalBar) { if (preamble) { - eat(character); + eat(character) } else { if (character && opening) { - queue += character; - index++; - continue; + queue += character + index++ + continue } if ((cell || character) && !preamble) { - subvalue = cell; + subvalue = cell if (queue.length > 1) { if (character) { - subvalue += queue.slice(0, queue.length - 1); - queue = queue.charAt(queue.length - 1); + subvalue += queue.slice(0, queue.length - 1) + queue = queue.charAt(queue.length - 1) } else { - subvalue += queue; - queue = ''; + subvalue += queue + queue = '' } } - now = eat.now(); + now = eat.now() - eat(subvalue)({ - type: 'tableCell', - children: self.tokenizeInline(cell, now) - }, row); + eat(subvalue)( + {type: 'tableCell', children: self.tokenizeInline(cell, now)}, + row + ) } - eat(queue + character); + eat(queue + character) - queue = ''; - cell = ''; + queue = '' + cell = '' } } else { if (queue) { - cell += queue; - queue = ''; + cell += queue + queue = '' } - cell += character; + cell += character - if (character === C_BACKSLASH && index !== length - 2) { - cell += line.charAt(index + 1); - index++; + if (character === backslash && index !== length - 2) { + cell += line.charAt(index + 1) + index++ } - if (character === C_TICK) { - count = 1; + if (character === graveAccent) { + count = 1 while (line.charAt(index + 1) === character) { - cell += character; - index++; - count++; + cell += character + index++ + count++ } if (!opening) { - opening = count; + opening = count } else if (count >= opening) { - opening = 0; + opening = 0 } } } - preamble = false; - index++; + preamble = false + index++ } - /* Eat the alignment row. */ + // Eat the alignment row. if (!position) { - eat(C_NEWLINE + alignments); + eat(lineFeed + alignments) } } - return table; + return table } diff --git a/packages/remark-parse/lib/tokenize/text.js b/packages/remark-parse/lib/tokenize/text.js index 4aedfa90d..c9085ee30 100644 --- a/packages/remark-parse/lib/tokenize/text.js +++ b/packages/remark-parse/lib/tokenize/text.js @@ -1,58 +1,57 @@ -'use strict'; +'use strict' -module.exports = text; +module.exports = text function text(eat, value, silent) { - var self = this; - var methods; - var tokenizers; - var index; - var length; - var subvalue; - var position; - var tokenizer; - var name; - var min; - var now; + var self = this + var methods + var tokenizers + var index + var length + var subvalue + var position + var tokenizer + var name + var min + var now /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - methods = self.inlineMethods; - length = methods.length; - tokenizers = self.inlineTokenizers; - index = -1; - min = value.length; + methods = self.inlineMethods + length = methods.length + tokenizers = self.inlineTokenizers + index = -1 + min = value.length while (++index < length) { - name = methods[index]; + name = methods[index] if (name === 'text' || !tokenizers[name]) { - continue; + continue } - tokenizer = tokenizers[name].locator; + tokenizer = tokenizers[name].locator if (!tokenizer) { - eat.file.fail('Missing locator: `' + name + '`'); + eat.file.fail('Missing locator: `' + name + '`') } - position = tokenizer.call(self, value, 1); + position = tokenizer.call(self, value, 1) if (position !== -1 && position < min) { - min = position; + min = position } } - subvalue = value.slice(0, min); - now = eat.now(); + subvalue = value.slice(0, min) + now = eat.now() - self.decode(subvalue, now, function (content, position, source) { - eat(source || content)({ - type: 'text', - value: content - }); - }); + self.decode(subvalue, now, handler) + + function handler(content, position, source) { + eat(source || content)({type: 'text', value: content}) + } } diff --git a/packages/remark-parse/lib/tokenize/thematic-break.js b/packages/remark-parse/lib/tokenize/thematic-break.js index 2391e3f59..6844c8c70 100644 --- a/packages/remark-parse/lib/tokenize/thematic-break.js +++ b/packages/remark-parse/lib/tokenize/thematic-break.js @@ -1,70 +1,70 @@ -'use strict'; +'use strict' -module.exports = thematicBreak; +module.exports = thematicBreak -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_ASTERISK = '*'; -var C_UNDERSCORE = '_'; -var C_DASH = '-'; +var tab = '\t' +var lineFeed = '\n' +var space = ' ' +var asterisk = '*' +var dash = '-' +var underscore = '_' -var THEMATIC_BREAK_MARKER_COUNT = 3; +var maxCount = 3 function thematicBreak(eat, value, silent) { - var index = -1; - var length = value.length + 1; - var subvalue = ''; - var character; - var marker; - var markerCount; - var queue; + var index = -1 + var length = value.length + 1 + var subvalue = '' + var character + var marker + var markerCount + var queue while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (character !== C_TAB && character !== C_SPACE) { - break; + if (character !== tab && character !== space) { + break } - subvalue += character; + subvalue += character } if ( - character !== C_ASTERISK && - character !== C_DASH && - character !== C_UNDERSCORE + character !== asterisk && + character !== dash && + character !== underscore ) { - return; + return } - marker = character; - subvalue += character; - markerCount = 1; - queue = ''; + marker = character + subvalue += character + markerCount = 1 + queue = '' while (++index < length) { - character = value.charAt(index); + character = value.charAt(index) if (character === marker) { - markerCount++; - subvalue += queue + marker; - queue = ''; - } else if (character === C_SPACE) { - queue += character; + markerCount++ + subvalue += queue + marker + queue = '' + } else if (character === space) { + queue += character } else if ( - markerCount >= THEMATIC_BREAK_MARKER_COUNT && - (!character || character === C_NEWLINE) + markerCount >= maxCount && + (!character || character === lineFeed) ) { - subvalue += queue; + subvalue += queue if (silent) { - return true; + return true } - return eat(subvalue)({type: 'thematicBreak'}); + return eat(subvalue)({type: 'thematicBreak'}) } else { - return; + return } } } diff --git a/packages/remark-parse/lib/tokenize/url.js b/packages/remark-parse/lib/tokenize/url.js index a0afaca88..ee72e6638 100644 --- a/packages/remark-parse/lib/tokenize/url.js +++ b/packages/remark-parse/lib/tokenize/url.js @@ -1,152 +1,153 @@ -'use strict'; +'use strict' -var decode = require('parse-entities'); -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/url'); +var decode = require('parse-entities') +var whitespace = require('is-whitespace-character') +var locate = require('../locate/url') -module.exports = url; -url.locator = locate; -url.notInLink = true; +module.exports = url +url.locator = locate +url.notInLink = true -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; -var C_PAREN_OPEN = '('; -var C_PAREN_CLOSE = ')'; -var C_LT = '<'; -var C_AT_SIGN = '@'; +var quotationMark = '"' +var apostrophe = "'" +var leftParenthesis = '(' +var rightParenthesis = ')' +var comma = ',' +var dot = '.' +var colon = ':' +var semicolon = ';' +var lessThan = '<' +var atSign = '@' +var leftSquareBracket = '[' +var rightSquareBracket = ']' -var HTTP_PROTOCOL = 'http://'; -var HTTPS_PROTOCOL = 'https://'; -var MAILTO_PROTOCOL = 'mailto:'; +var http = 'http://' +var https = 'https://' +var mailto = 'mailto:' -var PROTOCOLS = [ - HTTP_PROTOCOL, - HTTPS_PROTOCOL, - MAILTO_PROTOCOL -]; +var protocols = [http, https, mailto] -var PROTOCOLS_LENGTH = PROTOCOLS.length; +var protocolsLength = protocols.length function url(eat, value, silent) { - var self = this; - var subvalue; - var content; - var character; - var index; - var position; - var protocol; - var match; - var length; - var queue; - var parenCount; - var nextCharacter; - var tokenizers; - var exit; + var self = this + var subvalue + var content + var character + var index + var position + var protocol + var match + var length + var queue + var parenCount + var nextCharacter + var tokenizers + var exit if (!self.options.gfm) { - return; + return } - subvalue = ''; - index = -1; - length = PROTOCOLS_LENGTH; + subvalue = '' + index = -1 - while (++index < length) { - protocol = PROTOCOLS[index]; - match = value.slice(0, protocol.length); + while (++index < protocolsLength) { + protocol = protocols[index] + match = value.slice(0, protocol.length) if (match.toLowerCase() === protocol) { - subvalue = match; - break; + subvalue = match + break } } if (!subvalue) { - return; + return } - index = subvalue.length; - length = value.length; - queue = ''; - parenCount = 0; + index = subvalue.length + length = value.length + queue = '' + parenCount = 0 while (index < length) { - character = value.charAt(index); + character = value.charAt(index) - if (whitespace(character) || character === C_LT) { - break; + if (whitespace(character) || character === lessThan) { + break } if ( - character === '.' || - character === ',' || - character === ':' || - character === ';' || - character === '"' || - character === '\'' || - character === ')' || - character === ']' + character === dot || + character === comma || + character === colon || + character === semicolon || + character === quotationMark || + character === apostrophe || + character === rightParenthesis || + character === rightSquareBracket ) { - nextCharacter = value.charAt(index + 1); + nextCharacter = value.charAt(index + 1) if (!nextCharacter || whitespace(nextCharacter)) { - break; + break } } - if (character === C_PAREN_OPEN || character === C_BRACKET_OPEN) { - parenCount++; + if (character === leftParenthesis || character === leftSquareBracket) { + parenCount++ } - if (character === C_PAREN_CLOSE || character === C_BRACKET_CLOSE) { - parenCount--; + if (character === rightParenthesis || character === rightSquareBracket) { + parenCount-- if (parenCount < 0) { - break; + break } } - queue += character; - index++; + queue += character + index++ } if (!queue) { - return; + return } - subvalue += queue; - content = subvalue; + subvalue += queue + content = subvalue - if (protocol === MAILTO_PROTOCOL) { - position = queue.indexOf(C_AT_SIGN); + if (protocol === mailto) { + position = queue.indexOf(atSign) if (position === -1 || position === length - 1) { - return; + return } - content = content.substr(MAILTO_PROTOCOL.length); + content = content.substr(mailto.length) } /* istanbul ignore if - never used (yet) */ if (silent) { - return true; + return true } - exit = self.enterLink(); + exit = self.enterLink() - /* Temporarily remove all tokenizers except text in url. */ - tokenizers = self.inlineTokenizers; - self.inlineTokenizers = {text: tokenizers.text}; + // Temporarily remove all tokenizers except text in url. + tokenizers = self.inlineTokenizers + self.inlineTokenizers = {text: tokenizers.text} - content = self.tokenizeInline(content, eat.now()); + content = self.tokenizeInline(content, eat.now()) - self.inlineTokenizers = tokenizers; - exit(); + self.inlineTokenizers = tokenizers + exit() return eat(subvalue)({ type: 'link', title: null, url: decode(subvalue, {nonTerminated: false}), children: content - }); + }) } diff --git a/packages/remark-parse/lib/tokenizer.js b/packages/remark-parse/lib/tokenizer.js index 498ef22ad..259da8675 100644 --- a/packages/remark-parse/lib/tokenizer.js +++ b/packages/remark-parse/lib/tokenizer.js @@ -1,95 +1,50 @@ -'use strict'; +'use strict' -module.exports = factory; +module.exports = factory -var MERGEABLE_NODES = { - text: mergeText, - blockquote: mergeBlockquote -}; - -/* Check whether a node is mergeable with adjacent nodes. */ -function mergeable(node) { - var start; - var end; - - if (node.type !== 'text' || !node.position) { - return true; - } - - start = node.position.start; - end = node.position.end; - - /* Only merge nodes which occupy the same size as their - * `value`. */ - return start.line !== end.line || - end.column - start.column === node.value.length; -} - -/* Merge two text nodes: `node` into `prev`. */ -function mergeText(prev, node) { - prev.value += node.value; - - return prev; -} - -/* Merge two blockquotes: `node` into `prev`, unless in - * CommonMark mode. */ -function mergeBlockquote(prev, node) { - if (this.options.commonmark) { - return node; - } - - prev.children = prev.children.concat(node.children); - - return prev; -} - -/* Construct a tokenizer. This creates both - * `tokenizeInline` and `tokenizeBlock`. */ +// Construct a tokenizer. This creates both `tokenizeInline` and `tokenizeBlock`. function factory(type) { - return tokenize; + return tokenize - /* Tokenizer for a bound `type`. */ + // Tokenizer for a bound `type`. function tokenize(value, location) { - var self = this; - var offset = self.offset; - var tokens = []; - var methods = self[type + 'Methods']; - var tokenizers = self[type + 'Tokenizers']; - var line = location.line; - var column = location.column; - var index; - var length; - var method; - var name; - var matched; - var valueLength; - - /* Trim white space only lines. */ + var self = this + var offset = self.offset + var tokens = [] + var methods = self[type + 'Methods'] + var tokenizers = self[type + 'Tokenizers'] + var line = location.line + var column = location.column + var index + var length + var method + var name + var matched + var valueLength + + // Trim white space only lines. if (!value) { - return tokens; + return tokens } - /* Expose on `eat`. */ - eat.now = now; - eat.file = self.file; + // Expose on `eat`. + eat.now = now + eat.file = self.file - /* Sync initial offset. */ - updatePosition(''); + // Sync initial offset. + updatePosition('') - /* Iterate over `value`, and iterate over all - * tokenizers. When one eats something, re-iterate - * with the remaining value. If no tokenizer eats, - * something failed (should not happen) and an - * exception is thrown. */ + // Iterate over `value`, and iterate over all tokenizers. When one eats + // something, re-iterate with the remaining value. If no tokenizer eats, + // something failed (should not happen) and an exception is thrown. while (value) { - index = -1; - length = methods.length; - matched = false; + index = -1 + length = methods.length + matched = false while (++index < length) { - name = methods[index]; - method = tokenizers[name]; + name = methods[index] + method = tokenizers[name] if ( method && @@ -98,234 +53,262 @@ function factory(type) { (!method.notInBlock || !self.inBlock) && (!method.notInLink || !self.inLink) ) { - valueLength = value.length; + valueLength = value.length - method.apply(self, [eat, value]); + method.apply(self, [eat, value]) - matched = valueLength !== value.length; + matched = valueLength !== value.length if (matched) { - break; + break } } } /* istanbul ignore if */ if (!matched) { - self.file.fail(new Error('Infinite loop'), eat.now()); + self.file.fail(new Error('Infinite loop'), eat.now()) } } - self.eof = now(); + self.eof = now() - return tokens; + return tokens - /* Update line, column, and offset based on - * `value`. */ + // Update line, column, and offset based on `value`. function updatePosition(subvalue) { - var lastIndex = -1; - var index = subvalue.indexOf('\n'); + var lastIndex = -1 + var index = subvalue.indexOf('\n') while (index !== -1) { - line++; - lastIndex = index; - index = subvalue.indexOf('\n', index + 1); + line++ + lastIndex = index + index = subvalue.indexOf('\n', index + 1) } if (lastIndex === -1) { - column += subvalue.length; + column += subvalue.length } else { - column = subvalue.length - lastIndex; + column = subvalue.length - lastIndex } if (line in offset) { if (lastIndex !== -1) { - column += offset[line]; + column += offset[line] } else if (column <= offset[line]) { - column = offset[line] + 1; + column = offset[line] + 1 } } } - /* Get offset. Called before the first character is - * eaten to retrieve the range's offsets. */ + // Get offset. Called before the first character is eaten to retrieve the + // range’s offsets. function getOffset() { - var indentation = []; - var pos = line + 1; + var indentation = [] + var pos = line + 1 - /* Done. Called when the last character is - * eaten to retrieve the range’s offsets. */ - return function () { - var last = line + 1; + // Done. Called when the last character is eaten to retrieve the range’s + // offsets. + return function() { + var last = line + 1 while (pos < last) { - indentation.push((offset[pos] || 0) + 1); + indentation.push((offset[pos] || 0) + 1) - pos++; + pos++ } - return indentation; - }; + return indentation + } } - /* Get the current position. */ + // Get the current position. function now() { - var pos = {line: line, column: column}; + var pos = {line: line, column: column} - pos.offset = self.toOffset(pos); + pos.offset = self.toOffset(pos) - return pos; + return pos } - /* Store position information for a node. */ + // Store position information for a node. function Position(start) { - this.start = start; - this.end = now(); + this.start = start + this.end = now() } - /* Throw when a value is incorrectly eaten. - * This shouldn’t happen but will throw on new, - * incorrect rules. */ + // Throw when a value is incorrectly eaten. This shouldn’t happen but will + // throw on new, incorrect rules. function validateEat(subvalue) { /* istanbul ignore if */ if (value.substring(0, subvalue.length) !== subvalue) { - /* Capture stack-trace. */ + // Capture stack-trace. self.file.fail( new Error( - 'Incorrectly eaten value: please report this ' + - 'warning on http://git.io/vg5Ft' + 'Incorrectly eaten value: please report this warning on http://git.io/vg5Ft' ), now() - ); + ) } } - /* Mark position and patch `node.position`. */ + // Mark position and patch `node.position`. function position() { - var before = now(); + var before = now() - return update; + return update - /* Add the position to a node. */ + // Add the position to a node. function update(node, indent) { - var prev = node.position; - var start = prev ? prev.start : before; - var combined = []; - var n = prev && prev.end.line; - var l = before.line; - - node.position = new Position(start); - - /* If there was already a `position`, this - * node was merged. Fixing `start` wasn’t - * hard, but the indent is different. - * Especially because some information, the - * indent between `n` and `l` wasn’t - * tracked. Luckily, that space is - * (should be?) empty, so we can safely - * check for it now. */ + var prev = node.position + var start = prev ? prev.start : before + var combined = [] + var n = prev && prev.end.line + var l = before.line + + node.position = new Position(start) + + // If there was already a `position`, this node was merged. Fixing + // `start` wasn’t hard, but the indent is different. Especially + // because some information, the indent between `n` and `l` wasn’t + // tracked. Luckily, that space is (should be?) empty, so we can + // safely check for it now. if (prev && indent && prev.indent) { - combined = prev.indent; + combined = prev.indent if (n < l) { while (++n < l) { - combined.push((offset[n] || 0) + 1); + combined.push((offset[n] || 0) + 1) } - combined.push(before.column); + combined.push(before.column) } - indent = combined.concat(indent); + indent = combined.concat(indent) } - node.position.indent = indent || []; + node.position.indent = indent || [] - return node; + return node } } - /* Add `node` to `parent`s children or to `tokens`. - * Performs merges where possible. */ + // Add `node` to `parent`s children or to `tokens`. Performs merges where + // possible. function add(node, parent) { - var children = parent ? parent.children : tokens; - var prev = children[children.length - 1]; + var children = parent ? parent.children : tokens + var prev = children[children.length - 1] + var fn if ( prev && node.type === prev.type && - node.type in MERGEABLE_NODES && + (node.type === 'text' || node.type === 'blockquote') && mergeable(prev) && mergeable(node) ) { - node = MERGEABLE_NODES[node.type].call(self, prev, node); + fn = node.type === 'text' ? mergeText : mergeBlockquote + node = fn.call(self, prev, node) } if (node !== prev) { - children.push(node); + children.push(node) } if (self.atStart && tokens.length !== 0) { - self.exitStart(); + self.exitStart() } - return node; + return node } - /* Remove `subvalue` from `value`. - * `subvalue` must be at the start of `value`. */ + // Remove `subvalue` from `value`. `subvalue` must be at the start of + // `value`. function eat(subvalue) { - var indent = getOffset(); - var pos = position(); - var current = now(); + var indent = getOffset() + var pos = position() + var current = now() - validateEat(subvalue); + validateEat(subvalue) - apply.reset = reset; - reset.test = test; - apply.test = test; + apply.reset = reset + reset.test = test + apply.test = test - value = value.substring(subvalue.length); + value = value.substring(subvalue.length) - updatePosition(subvalue); + updatePosition(subvalue) - indent = indent(); + indent = indent() - return apply; + return apply - /* Add the given arguments, add `position` to - * the returned node, and return the node. */ + // Add the given arguments, add `position` to the returned node, and + // return the node. function apply(node, parent) { - return pos(add(pos(node), parent), indent); + return pos(add(pos(node), parent), indent) } - /* Functions just like apply, but resets the - * content: the line and column are reversed, - * and the eaten value is re-added. - * This is useful for nodes with a single - * type of content, such as lists and tables. - * See `apply` above for what parameters are - * expected. */ + // Functions just like apply, but resets the content: the line and + // column are reversed, and the eaten value is re-added. This is + // useful for nodes with a single type of content, such as lists and + // tables. See `apply` above for what parameters are expected. function reset() { - var node = apply.apply(null, arguments); + var node = apply.apply(null, arguments) - line = current.line; - column = current.column; - value = subvalue + value; + line = current.line + column = current.column + value = subvalue + value - return node; + return node } - /* Test the position, after eating, and reverse - * to a not-eaten state. */ + // Test the position, after eating, and reverse to a not-eaten state. function test() { - var result = pos({}); + var result = pos({}) - line = current.line; - column = current.column; - value = subvalue + value; + line = current.line + column = current.column + value = subvalue + value - return result.position; + return result.position } } } } + +// Check whether a node is mergeable with adjacent nodes. +function mergeable(node) { + var start + var end + + if (node.type !== 'text' || !node.position) { + return true + } + + start = node.position.start + end = node.position.end + + // Only merge nodes which occupy the same size as their `value`. + return ( + start.line !== end.line || end.column - start.column === node.value.length + ) +} + +// Merge two text nodes: `node` into `prev`. +function mergeText(prev, node) { + prev.value += node.value + + return prev +} + +// Merge two blockquotes: `node` into `prev`, unless in CommonMark mode. +function mergeBlockquote(prev, node) { + if (this.options.commonmark) { + return node + } + + prev.children = prev.children.concat(node.children) + + return prev +} diff --git a/packages/remark-parse/lib/unescape.js b/packages/remark-parse/lib/unescape.js index 321900e7e..aa54188b9 100644 --- a/packages/remark-parse/lib/unescape.js +++ b/packages/remark-parse/lib/unescape.js @@ -1,37 +1,36 @@ -'use strict'; +'use strict' -module.exports = factory; +module.exports = factory -/* Factory to de-escape a value, based on a list at `key` - * in `ctx`. */ +var backslash = '\\' + +// Factory to de-escape a value, based on a list at `key` in `ctx`. function factory(ctx, key) { - return unescape; + return unescape - /* De-escape a string using the expression at `key` - * in `ctx`. */ + // De-escape a string using the expression at `key` in `ctx`. function unescape(value) { - var prev = 0; - var index = value.indexOf('\\'); - var escape = ctx[key]; - var queue = []; - var character; + var prev = 0 + var index = value.indexOf(backslash) + var escape = ctx[key] + var queue = [] + var character while (index !== -1) { - queue.push(value.slice(prev, index)); - prev = index + 1; - character = value.charAt(prev); + queue.push(value.slice(prev, index)) + prev = index + 1 + character = value.charAt(prev) - /* If the following character is not a valid escape, - * add the slash. */ + // If the following character is not a valid escape, add the slash. if (!character || escape.indexOf(character) === -1) { - queue.push('\\'); + queue.push(backslash) } - index = value.indexOf('\\', prev); + index = value.indexOf(backslash, prev) } - queue.push(value.slice(prev)); + queue.push(value.slice(prev)) - return queue.join(''); + return queue.join('') } } diff --git a/packages/remark-parse/lib/util/get-indentation.js b/packages/remark-parse/lib/util/get-indentation.js index 3e09e1411..5ab3efd73 100644 --- a/packages/remark-parse/lib/util/get-indentation.js +++ b/packages/remark-parse/lib/util/get-indentation.js @@ -1,32 +1,33 @@ -'use strict'; +'use strict' -module.exports = indentation; +module.exports = indentation -/* Map of characters, and their column length, - * which can be used as indentation. */ -var characters = {' ': 1, '\t': 4}; +var tab = '\t' +var space = ' ' -/* Gets indentation information for a line. */ +var spaceSize = 1 +var tabSize = 4 + +// Gets indentation information for a line. function indentation(value) { - var index = 0; - var indent = 0; - var character = value.charAt(index); - var stops = {}; - var size; + var index = 0 + var indent = 0 + var character = value.charAt(index) + var stops = {} + var size - while (character in characters) { - size = characters[character]; + while (character === tab || character === space) { + size = character === tab ? tabSize : spaceSize - indent += size; + indent += size if (size > 1) { - indent = Math.floor(indent / size) * size; + indent = Math.floor(indent / size) * size } - stops[indent] = index; - - character = value.charAt(++index); + stops[indent] = index + character = value.charAt(++index) } - return {indent: indent, stops: stops}; + return {indent: indent, stops: stops} } diff --git a/packages/remark-parse/lib/util/html.js b/packages/remark-parse/lib/util/html.js index 5f211f13f..49b7a38fc 100644 --- a/packages/remark-parse/lib/util/html.js +++ b/packages/remark-parse/lib/util/html.js @@ -1,25 +1,34 @@ -'use strict'; +'use strict' -var attributeName = '[a-zA-Z_:][a-zA-Z0-9:._-]*'; -var unquoted = '[^"\'=<>`\\u0000-\\u0020]+'; -var singleQuoted = '\'[^\']*\''; -var doubleQuoted = '"[^"]*"'; -var attributeValue = '(?:' + unquoted + '|' + singleQuoted + '|' + doubleQuoted + ')'; -var attribute = '(?:\\s+' + attributeName + '(?:\\s*=\\s*' + attributeValue + ')?)'; -var openTag = '<[A-Za-z][A-Za-z0-9\\-]*' + attribute + '*\\s*\\/?>'; -var closeTag = '<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>'; -var comment = '|'; -var processing = '<[?].*?[?]>'; -var declaration = ']*>'; -var cdata = ''; +var attributeName = '[a-zA-Z_:][a-zA-Z0-9:._-]*' +var unquoted = '[^"\'=<>`\\u0000-\\u0020]+' +var singleQuoted = "'[^']*'" +var doubleQuoted = '"[^"]*"' +var attributeValue = + '(?:' + unquoted + '|' + singleQuoted + '|' + doubleQuoted + ')' +var attribute = + '(?:\\s+' + attributeName + '(?:\\s*=\\s*' + attributeValue + ')?)' +var openTag = '<[A-Za-z][A-Za-z0-9\\-]*' + attribute + '*\\s*\\/?>' +var closeTag = '<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>' +var comment = '|' +var processing = '<[?].*?[?]>' +var declaration = ']*>' +var cdata = '' -exports.openCloseTag = new RegExp('^(?:' + openTag + '|' + closeTag + ')'); +exports.openCloseTag = new RegExp('^(?:' + openTag + '|' + closeTag + ')') -exports.tag = new RegExp('^(?:' + - openTag + '|' + - closeTag + '|' + - comment + '|' + - processing + '|' + - declaration + '|' + - cdata + -')'); +exports.tag = new RegExp( + '^(?:' + + openTag + + '|' + + closeTag + + '|' + + comment + + '|' + + processing + + '|' + + declaration + + '|' + + cdata + + ')' +) diff --git a/packages/remark-parse/lib/util/interrupt.js b/packages/remark-parse/lib/util/interrupt.js index e3178ab45..e707c8b13 100644 --- a/packages/remark-parse/lib/util/interrupt.js +++ b/packages/remark-parse/lib/util/interrupt.js @@ -1,43 +1,35 @@ -'use strict'; +'use strict' -module.exports = interrupt; +module.exports = interrupt function interrupt(interruptors, tokenizers, ctx, params) { - var bools = ['pedantic', 'commonmark']; - var count = bools.length; - var length = interruptors.length; - var index = -1; - var interruptor; - var config; - var fn; - var offset; - var bool; - var ignore; + var length = interruptors.length + var index = -1 + var interruptor + var config while (++index < length) { - interruptor = interruptors[index]; - config = interruptor[1] || {}; - fn = interruptor[0]; - offset = -1; - ignore = false; - - while (++offset < count) { - bool = bools[offset]; - - if (config[bool] !== undefined && config[bool] !== ctx.options[bool]) { - ignore = true; - break; - } + interruptor = interruptors[index] + config = interruptor[1] || {} + + if ( + config.pedantic !== undefined && + config.pedantic !== ctx.options.pedantic + ) { + continue } - if (ignore) { - continue; + if ( + config.commonmark !== undefined && + config.commonmark !== ctx.options.commonmark + ) { + continue } - if (tokenizers[fn].apply(ctx, params)) { - return true; + if (tokenizers[interruptor[0]].apply(ctx, params)) { + return true } } - return false; + return false } diff --git a/packages/remark-parse/lib/util/normalize.js b/packages/remark-parse/lib/util/normalize.js index 846ceeeca..7057c0a1e 100644 --- a/packages/remark-parse/lib/util/normalize.js +++ b/packages/remark-parse/lib/util/normalize.js @@ -1,11 +1,11 @@ -'use strict'; +'use strict' -var collapseWhiteSpace = require('collapse-white-space'); +var collapseWhiteSpace = require('collapse-white-space') -module.exports = normalize; +module.exports = normalize -/* Normalize an identifier. Collapses multiple white space - * characters into a single space, and removes casing. */ +// Normalize an identifier. Collapses multiple white space characters into a +// single space, and removes casing. function normalize(value) { - return collapseWhiteSpace(value).toLowerCase(); + return collapseWhiteSpace(value).toLowerCase() } diff --git a/packages/remark-parse/lib/util/remove-indentation.js b/packages/remark-parse/lib/util/remove-indentation.js index 20f18be74..06b6a781d 100644 --- a/packages/remark-parse/lib/util/remove-indentation.js +++ b/packages/remark-parse/lib/util/remove-indentation.js @@ -1,59 +1,59 @@ -'use strict'; +'use strict' -var trim = require('trim'); -var repeat = require('repeat-string'); -var getIndent = require('./get-indentation'); +var trim = require('trim') +var repeat = require('repeat-string') +var getIndent = require('./get-indentation') -module.exports = indentation; +module.exports = indentation -var C_SPACE = ' '; -var C_NEWLINE = '\n'; -var C_TAB = '\t'; +var tab = '\t' +var lineFeed = '\n' +var space = ' ' +var exclamationMark = '!' -/* Remove the minimum indent from every line in `value`. - * Supports both tab, spaced, and mixed indentation (as - * well as possible). */ +// Remove the minimum indent from every line in `value`. Supports both tab, +// spaced, and mixed indentation (as well as possible). function indentation(value, maximum) { - var values = value.split(C_NEWLINE); - var position = values.length + 1; - var minIndent = Infinity; - var matrix = []; - var index; - var indentation; - var stops; - var padding; + var values = value.split(lineFeed) + var position = values.length + 1 + var minIndent = Infinity + var matrix = [] + var index + var indentation + var stops + var padding - values.unshift(repeat(C_SPACE, maximum) + '!'); + values.unshift(repeat(space, maximum) + exclamationMark) while (position--) { - indentation = getIndent(values[position]); + indentation = getIndent(values[position]) - matrix[position] = indentation.stops; + matrix[position] = indentation.stops if (trim(values[position]).length === 0) { - continue; + continue } if (indentation.indent) { if (indentation.indent > 0 && indentation.indent < minIndent) { - minIndent = indentation.indent; + minIndent = indentation.indent } } else { - minIndent = Infinity; + minIndent = Infinity - break; + break } } if (minIndent !== Infinity) { - position = values.length; + position = values.length while (position--) { - stops = matrix[position]; - index = minIndent; + stops = matrix[position] + index = minIndent while (index && !(index in stops)) { - index--; + index-- } if ( @@ -61,18 +61,17 @@ function indentation(value, maximum) { minIndent && index !== minIndent ) { - padding = C_TAB; + padding = tab } else { - padding = ''; + padding = '' } - values[position] = padding + values[position].slice( - index in stops ? stops[index] + 1 : 0 - ); + values[position] = + padding + values[position].slice(index in stops ? stops[index] + 1 : 0) } } - values.shift(); + values.shift() - return values.join(C_NEWLINE); + return values.join(lineFeed) } diff --git a/packages/remark-parse/readme.md b/packages/remark-parse/readme.md index 44a95a5a9..509f082e8 100644 --- a/packages/remark-parse/readme.md +++ b/packages/remark-parse/readme.md @@ -16,18 +16,16 @@ npm install remark-parse ## Usage ```js -var unified = require('unified'); -var createStream = require('unified-stream'); -var markdown = require('remark-parse'); -var html = require('remark-html'); +var unified = require('unified') +var createStream = require('unified-stream') +var markdown = require('remark-parse') +var html = require('remark-html') var processor = unified() .use(markdown, {commonmark: true}) .use(html) -process.stdin - .pipe(createStream(processor)) - .pipe(process.stdout); +process.stdin.pipe(createStream(processor)).pipe(process.stdout) ``` ## Table of Contents @@ -163,18 +161,18 @@ to change how markdown is parsed. The below plugin adds a [tokenizer][] for at-mentions. ```js -module.exports = mentions; +module.exports = mentions function mentions() { - var Parser = this.Parser; - var tokenizers = Parser.prototype.inlineTokenizers; - var methods = Parser.prototype.inlineMethods; + var Parser = this.Parser + var tokenizers = Parser.prototype.inlineTokenizers + var methods = Parser.prototype.inlineMethods - /* Add an inline tokenizer (defined in the following example). */ - tokenizers.mention = tokenizeMention; + // Add an inline tokenizer (defined in the following example). + tokenizers.mention = tokenizeMention - /* Run it just before `text`. */ - methods.splice(methods.indexOf('text'), 0, 'mention'); + // Run it just before `text`. + methods.splice(methods.indexOf('text'), 0, 'mention') } ``` @@ -244,22 +242,22 @@ which they run. ### `function tokenizer(eat, value, silent)` ```js -tokenizeMention.notInLink = true; -tokenizeMention.locator = locateMention; +tokenizeMention.notInLink = true +tokenizeMention.locator = locateMention function tokenizeMention(eat, value, silent) { - var match = /^@(\w+)/.exec(value); + var match = /^@(\w+)/.exec(value) if (match) { if (silent) { - return true; + return true } return eat(match[0])({ type: 'link', url: 'https://social-network/' + match[1], children: [{type: 'text', value: match[0]}] - }); + }) } } ``` @@ -308,7 +306,7 @@ information on where the next entity may occur. ```js function locateMention(value, fromIndex) { - return value.indexOf('@', fromIndex); + return value.indexOf('@', fromIndex) } ``` @@ -330,7 +328,7 @@ Index at which an entity may start, and `-1` otherwise. ### `eat(subvalue)` ```js -var add = eat('foo'); +var add = eat('foo') ``` Eat `subvalue`, which is a string at the start of the @@ -348,8 +346,9 @@ value is eaten). ### `add(node[, parent])` ```js -var add = eat('foo'); -add({type: 'text', value: 'foo'}); +var add = eat('foo') + +add({type: 'text', value: 'foo'}) ``` Add [positional information][location] to `node` and add it to `parent`. @@ -399,7 +398,11 @@ your Parser’s `blockTokenizers` (or `blockMethods`) or `inlineTokenizers` The following example turns off indented code blocks: ```js -remarkParse.Parser.prototype.blockTokenizers.indentedCode = function () { return true }; +remarkParse.Parser.prototype.blockTokenizers.indentedCode = indentedCode + +function indentedCode() { + return true +} ``` Preferably, just use [this plugin](https://github.com/zestedesavoir/zmarkdown/tree/master/packages/remark-disable-tokenizers). diff --git a/packages/remark-stringify/index.js b/packages/remark-stringify/index.js index 23e64f2e6..baf7ca411 100644 --- a/packages/remark-stringify/index.js +++ b/packages/remark-stringify/index.js @@ -1,14 +1,18 @@ -'use strict'; +'use strict' -var unherit = require('unherit'); -var xtend = require('xtend'); -var Compiler = require('./lib/compiler.js'); +var unherit = require('unherit') +var xtend = require('xtend') +var Compiler = require('./lib/compiler.js') -module.exports = stringify; -stringify.Compiler = Compiler; +module.exports = stringify +stringify.Compiler = Compiler function stringify(options) { - var Local = unherit(Compiler); - Local.prototype.options = xtend(Local.prototype.options, this.data('settings'), options); - this.Compiler = Local; + var Local = unherit(Compiler) + Local.prototype.options = xtend( + Local.prototype.options, + this.data('settings'), + options + ) + this.Compiler = Local } diff --git a/packages/remark-stringify/lib/compiler.js b/packages/remark-stringify/lib/compiler.js index 0afb486c3..213314f9c 100644 --- a/packages/remark-stringify/lib/compiler.js +++ b/packages/remark-stringify/lib/compiler.js @@ -1,39 +1,39 @@ -'use strict'; +'use strict' -var xtend = require('xtend'); -var toggle = require('state-toggle'); +var xtend = require('xtend') +var toggle = require('state-toggle') -module.exports = Compiler; +module.exports = Compiler -/* Construct a new compiler. */ +// Construct a new compiler. function Compiler(tree, file) { - this.inLink = false; - this.inTable = false; - this.tree = tree; - this.file = file; - this.options = xtend(this.options); - this.setOptions({}); + this.inLink = false + this.inTable = false + this.tree = tree + this.file = file + this.options = xtend(this.options) + this.setOptions({}) } -var proto = Compiler.prototype; +var proto = Compiler.prototype -/* Enter and exit helpers. */ -proto.enterLink = toggle('inLink', false); -proto.enterTable = toggle('inTable', false); -proto.enterLinkReference = require('./util/enter-link-reference'); +// Enter and exit helpers. */ +proto.enterLink = toggle('inLink', false) +proto.enterTable = toggle('inTable', false) +proto.enterLinkReference = require('./util/enter-link-reference') -/* Configuration. */ -proto.options = require('./defaults'); -proto.setOptions = require('./set-options'); +// Configuration. +proto.options = require('./defaults') +proto.setOptions = require('./set-options') -proto.compile = require('./macro/compile'); -proto.visit = require('./macro/one'); -proto.all = require('./macro/all'); -proto.block = require('./macro/block'); -proto.visitOrderedItems = require('./macro/ordered-items'); -proto.visitUnorderedItems = require('./macro/unordered-items'); +proto.compile = require('./macro/compile') +proto.visit = require('./macro/one') +proto.all = require('./macro/all') +proto.block = require('./macro/block') +proto.visitOrderedItems = require('./macro/ordered-items') +proto.visitUnorderedItems = require('./macro/unordered-items') -/* Expose visitors. */ +// Expose visitors. proto.visitors = { root: require('./visitors/root'), text: require('./visitors/text'), @@ -60,4 +60,4 @@ proto.visitors = { footnoteDefinition: require('./visitors/footnote-definition'), table: require('./visitors/table'), tableCell: require('./visitors/table-cell') -}; +} diff --git a/packages/remark-stringify/lib/defaults.js b/packages/remark-stringify/lib/defaults.js index 5dcb72d31..fa19a368b 100644 --- a/packages/remark-stringify/lib/defaults.js +++ b/packages/remark-stringify/lib/defaults.js @@ -1,4 +1,4 @@ -'use strict'; +'use strict' module.exports = { gfm: true, @@ -21,8 +21,8 @@ module.exports = { ruleRepetition: 3, strong: '*', emphasis: '_' -}; +} function stringLength(value) { - return value.length; + return value.length } diff --git a/packages/remark-stringify/lib/escape.js b/packages/remark-stringify/lib/escape.js index 2831db603..249a31a9c 100644 --- a/packages/remark-stringify/lib/escape.js +++ b/packages/remark-stringify/lib/escape.js @@ -1,247 +1,287 @@ -'use strict'; - -var decimal = require('is-decimal'); -var alphanumeric = require('is-alphanumeric'); -var whitespace = require('is-whitespace-character'); -var escapes = require('markdown-escapes'); -var prefix = require('./util/entity-prefix-length'); +'use strict' + +var decimal = require('is-decimal') +var alphanumeric = require('is-alphanumeric') +var whitespace = require('is-whitespace-character') +var escapes = require('markdown-escapes') +var prefix = require('./util/entity-prefix-length') + +module.exports = factory + +var tab = '\t' +var lineFeed = '\n' +var space = ' ' +var numberSign = '#' +var ampersand = '&' +var leftParenthesis = '(' +var rightParenthesis = ')' +var asterisk = '*' +var plusSign = '+' +var dash = '-' +var dot = '.' +var colon = ':' +var lessThan = '<' +var greaterThan = '>' +var leftSquareBracket = '[' +var backslash = '\\' +var rightSquareBracket = ']' +var underscore = '_' +var graveAccent = '`' +var verticalBar = '|' +var tilde = '~' + +var entities = { + '<': '<', + ':': ':', + '&': '&', + '|': '|', + '~': '~' +} -module.exports = factory; +var shortcut = 'shortcut' +var mailto = 'mailto' +var https = 'https' +var http = 'http' -var BACKSLASH = '\\'; -var BULLETS = ['*', '-', '+']; -var ALLIGNMENT = [':', '-', ' ', '|']; -var entities = {'<': '<', ':': ':', '&': '&', '|': '|', '~': '~'}; +var blankExpression = /\n\s*$/ -/* Factory to escape characters. */ +// Factory to escape characters. function factory(options) { - return escape; + return escape - /* Escape punctuation characters in a node's value. */ + // Escape punctuation characters in a node’s value. function escape(value, node, parent) { - var self = this; - var gfm = options.gfm; - var commonmark = options.commonmark; - var pedantic = options.pedantic; - var markers = commonmark ? ['.', ')'] : ['.']; - var siblings = parent && parent.children; - var index = siblings && siblings.indexOf(node); - var prev = siblings && siblings[index - 1]; - var next = siblings && siblings[index + 1]; - var length = value.length; - var escapable = escapes(options); - var position = -1; - var queue = []; - var escaped = queue; - var afterNewLine; - var character; - var wordCharBefore; - var wordCharAfter; - var offset; - var replace; + var self = this + var gfm = options.gfm + var commonmark = options.commonmark + var pedantic = options.pedantic + var markers = commonmark ? [dot, rightParenthesis] : [dot] + var siblings = parent && parent.children + var index = siblings && siblings.indexOf(node) + var prev = siblings && siblings[index - 1] + var next = siblings && siblings[index + 1] + var length = value.length + var escapable = escapes(options) + var position = -1 + var queue = [] + var escaped = queue + var afterNewLine + var character + var wordCharBefore + var wordCharAfter + var offset + var replace if (prev) { - afterNewLine = text(prev) && /\n\s*$/.test(prev.value); + afterNewLine = text(prev) && blankExpression.test(prev.value) } else { - afterNewLine = !parent || parent.type === 'root' || parent.type === 'paragraph'; - } - - function one(character) { - return escapable.indexOf(character) === -1 ? - entities[character] : BACKSLASH + character; + afterNewLine = + !parent || parent.type === 'root' || parent.type === 'paragraph' } while (++position < length) { - character = value.charAt(position); - replace = false; + character = value.charAt(position) + replace = false if (character === '\n') { - afterNewLine = true; + afterNewLine = true } else if ( - character === BACKSLASH || - character === '`' || - character === '*' || - character === '[' || - character === '<' || - (character === '&' && prefix(value.slice(position)) > 0) || - (character === ']' && self.inLink) || - (gfm && character === '~' && value.charAt(position + 1) === '~') || - (gfm && character === '|' && (self.inTable || alignment(value, position))) || - ( - character === '_' && - /* Delegate leading/trailing underscores - * to the multinode version below. */ + character === backslash || + character === graveAccent || + character === asterisk || + character === leftSquareBracket || + character === lessThan || + (character === ampersand && prefix(value.slice(position)) > 0) || + (character === rightSquareBracket && self.inLink) || + (gfm && character === tilde && value.charAt(position + 1) === tilde) || + (gfm && + character === verticalBar && + (self.inTable || alignment(value, position))) || + (character === underscore && + // Delegate leading/trailing underscores to the multinode version below. position > 0 && position < length - 1 && - ( - pedantic || + (pedantic || !alphanumeric(value.charAt(position - 1)) || - !alphanumeric(value.charAt(position + 1)) - ) - ) || - (gfm && !self.inLink && character === ':' && protocol(queue.join(''))) + !alphanumeric(value.charAt(position + 1)))) || + (gfm && !self.inLink && character === colon && protocol(queue.join(''))) ) { - replace = true; + replace = true } else if (afterNewLine) { if ( - character === '>' || - character === '#' || - BULLETS.indexOf(character) !== -1 + character === greaterThan || + character === numberSign || + character === asterisk || + character === dash || + character === plusSign ) { - replace = true; + replace = true } else if (decimal(character)) { - offset = position + 1; + offset = position + 1 while (offset < length) { if (!decimal(value.charAt(offset))) { - break; + break } - offset++; + offset++ } if (markers.indexOf(value.charAt(offset)) !== -1) { - next = value.charAt(offset + 1); + next = value.charAt(offset + 1) - if (!next || next === ' ' || next === '\t' || next === '\n') { - queue.push(value.slice(position, offset)); - position = offset; - character = value.charAt(position); - replace = true; + if (!next || next === space || next === tab || next === lineFeed) { + queue.push(value.slice(position, offset)) + position = offset + character = value.charAt(position) + replace = true } } } } if (afterNewLine && !whitespace(character)) { - afterNewLine = false; + afterNewLine = false } - queue.push(replace ? one(character) : character); + queue.push(replace ? one(character) : character) } - /* Multi-node versions. */ + // Multi-node versions. if (siblings && text(node)) { - /* Check for an opening parentheses after a - * link-reference (which can be joined by - * white-space). */ - if (prev && prev.referenceType === 'shortcut') { - position = -1; - length = escaped.length; + // Check for an opening parentheses after a link-reference (which can be + // joined by white-space). + if (prev && prev.referenceType === shortcut) { + position = -1 + length = escaped.length while (++position < length) { - character = escaped[position]; + character = escaped[position] - if (character === ' ' || character === '\t') { - continue; + if (character === space || character === tab) { + continue } - if (character === '(' || character === ':') { - escaped[position] = one(character); + if (character === leftParenthesis || character === colon) { + escaped[position] = one(character) } - break; + break } - /* If the current node is all spaces / tabs, - * preceded by a shortcut, and followed by - * a text starting with `(`, escape it. */ + // If the current node is all spaces / tabs, preceded by a shortcut, + // and followed by a text starting with `(`, escape it. if ( text(next) && position === length && - next.value.charAt(0) === '(' + next.value.charAt(0) === leftParenthesis ) { - escaped.push(BACKSLASH); + escaped.push(backslash) } } - /* Ensure non-auto-links are not seen as links. - * This pattern needs to check the preceding - * nodes too. */ + // Ensure non-auto-links are not seen as links. This pattern needs to + // check the preceding nodes too. if ( gfm && !self.inLink && text(prev) && - value.charAt(0) === ':' && + value.charAt(0) === colon && protocol(prev.value.slice(-6)) ) { - escaped[0] = one(':'); + escaped[0] = one(colon) } - /* Escape ampersand if it would otherwise - * start an entity. */ + // Escape ampersand if it would otherwise start an entity. if ( text(next) && - value.charAt(length - 1) === '&' && - prefix('&' + next.value) !== 0 + value.charAt(length - 1) === ampersand && + prefix(ampersand + next.value) !== 0 ) { - escaped[escaped.length - 1] = one('&'); + escaped[escaped.length - 1] = one(ampersand) } - /* Escape double tildes in GFM. */ + // Escape double tildes in GFM. if ( gfm && text(next) && - value.charAt(length - 1) === '~' && - next.value.charAt(0) === '~' + value.charAt(length - 1) === tilde && + next.value.charAt(0) === tilde ) { - escaped.splice(escaped.length - 1, 0, BACKSLASH); + escaped.splice(escaped.length - 1, 0, backslash) } - /* Escape underscores, but not mid-word (unless - * in pedantic mode). */ - wordCharBefore = text(prev) && alphanumeric(prev.value.slice(-1)); - wordCharAfter = text(next) && alphanumeric(next.value.charAt(0)); + // Escape underscores, but not mid-word (unless in pedantic mode). + wordCharBefore = text(prev) && alphanumeric(prev.value.slice(-1)) + wordCharAfter = text(next) && alphanumeric(next.value.charAt(0)) if (length === 1) { - if (value === '_' && (pedantic || !wordCharBefore || !wordCharAfter)) { - escaped.unshift(BACKSLASH); + if ( + value === underscore && + (pedantic || !wordCharBefore || !wordCharAfter) + ) { + escaped.unshift(backslash) } } else { if ( - value.charAt(0) === '_' && + value.charAt(0) === underscore && (pedantic || !wordCharBefore || !alphanumeric(value.charAt(1))) ) { - escaped.unshift(BACKSLASH); + escaped.unshift(backslash) } if ( - value.charAt(length - 1) === '_' && - (pedantic || !wordCharAfter || !alphanumeric(value.charAt(length - 2))) + value.charAt(length - 1) === underscore && + (pedantic || + !wordCharAfter || + !alphanumeric(value.charAt(length - 2))) ) { - escaped.splice(escaped.length - 1, 0, BACKSLASH); + escaped.splice(escaped.length - 1, 0, backslash) } } } - return escaped.join(''); + return escaped.join('') + + function one(character) { + return escapable.indexOf(character) === -1 + ? entities[character] + : backslash + character + } } } -/* Check if `index` in `value` is inside an alignment row. */ +// Check if `index` in `value` is inside an alignment row. function alignment(value, index) { - var start = value.lastIndexOf('\n', index); - var end = value.indexOf('\n', index); + var start = value.lastIndexOf(lineFeed, index) + var end = value.indexOf(lineFeed, index) + var char - start = start === -1 ? -1 : start; - end = end === -1 ? value.length : end; + end = end === -1 ? value.length : end while (++start < end) { - if (ALLIGNMENT.indexOf(value.charAt(start)) === -1) { - return false; + char = value.charAt(start) + + if ( + char !== colon && + char !== dash && + char !== space && + char !== verticalBar + ) { + return false } } - return true; + return true } -/* Check if `node` is a text node. */ +// Check if `node` is a text node. function text(node) { - return node && node.type === 'text'; + return node && node.type === 'text' } -/* Check if `value` ends in a protocol. */ +// Check if `value` ends in a protocol. function protocol(value) { - var val = value.slice(-6).toLowerCase(); - return val === 'mailto' || val.slice(-5) === 'https' || val.slice(-4) === 'http'; + var val = value.slice(-6).toLowerCase() + return val === mailto || val.slice(-5) === https || val.slice(-4) === http } diff --git a/packages/remark-stringify/lib/macro/all.js b/packages/remark-stringify/lib/macro/all.js index 4aa7adaca..ae470ee86 100644 --- a/packages/remark-stringify/lib/macro/all.js +++ b/packages/remark-stringify/lib/macro/all.js @@ -1,18 +1,18 @@ -'use strict'; +'use strict' -module.exports = all; +module.exports = all -/* Visit all children of `parent`. */ +// Visit all children of `parent`. function all(parent) { - var self = this; - var children = parent.children; - var length = children.length; - var results = []; - var index = -1; + var self = this + var children = parent.children + var length = children.length + var results = [] + var index = -1 while (++index < length) { - results[index] = self.visit(children[index], parent); + results[index] = self.visit(children[index], parent) } - return results; + return results } diff --git a/packages/remark-stringify/lib/macro/block.js b/packages/remark-stringify/lib/macro/block.js index e365cafe1..ede130e80 100644 --- a/packages/remark-stringify/lib/macro/block.js +++ b/packages/remark-stringify/lib/macro/block.js @@ -1,32 +1,31 @@ -'use strict'; +'use strict' -module.exports = block; +module.exports = block -var newline = '\n'; -var double = newline + newline; -var triple = double + newline; -var comment = double + '' + double; +var lineFeed = '\n' -/* Stringify a block node with block children (e.g., `root` - * or `blockquote`). - * Knows about code following a list, or adjacent lists - * with similar bullets, and places an extra newline - * between them. */ +var blank = lineFeed + lineFeed +var triple = blank + lineFeed +var comment = blank + '' + blank + +// Stringify a block node with block children (e.g., `root` or `blockquote`). +// Knows about code following a list, or adjacent lists with similar bullets, +// and places an extra line feed between them. function block(node) { - var self = this; - var options = self.options; - var fences = options.fences; - var gap = options.commonmark ? comment : triple; - var values = []; - var children = node.children; - var length = children.length; - var index = -1; - var prev; - var child; + var self = this + var options = self.options + var fences = options.fences + var gap = options.commonmark ? comment : triple + var values = [] + var children = node.children + var length = children.length + var index = -1 + var prev + var child while (++index < length) { - prev = child; - child = children[index]; + prev = child + child = children[index] if (prev) { // A list preceding another list that are equally ordered, or a @@ -39,19 +38,17 @@ function block(node) { // two blank lines are fine. if ( prev.type === 'list' && - ( - (child.type === 'list' && prev.ordered === child.ordered) || - (child.type === 'code' && (!child.lang && !fences)) - ) + ((child.type === 'list' && prev.ordered === child.ordered) || + (child.type === 'code' && (!child.lang && !fences))) ) { - values.push(gap); + values.push(gap) } else { - values.push(double); + values.push(blank) } } - values.push(self.visit(child, node)); + values.push(self.visit(child, node)) } - return values.join(''); + return values.join('') } diff --git a/packages/remark-stringify/lib/macro/compile.js b/packages/remark-stringify/lib/macro/compile.js index fef82f229..8c8530471 100644 --- a/packages/remark-stringify/lib/macro/compile.js +++ b/packages/remark-stringify/lib/macro/compile.js @@ -1,10 +1,10 @@ -'use strict'; +'use strict' -var compact = require('mdast-util-compact'); +var compact = require('mdast-util-compact') -module.exports = compile; +module.exports = compile -/* Stringify the given tree. */ +// Stringify the given tree. function compile() { - return this.visit(compact(this.tree, this.options.commonmark)); + return this.visit(compact(this.tree, this.options.commonmark)) } diff --git a/packages/remark-stringify/lib/macro/one.js b/packages/remark-stringify/lib/macro/one.js index f6a5d4a67..38e5782b4 100644 --- a/packages/remark-stringify/lib/macro/one.js +++ b/packages/remark-stringify/lib/macro/one.js @@ -1,21 +1,20 @@ -'use strict'; +'use strict' -module.exports = one; +module.exports = one function one(node, parent) { - var self = this; - var visitors = self.visitors; + var self = this + var visitors = self.visitors - /* Fail on unknown nodes. */ + // Fail on unknown nodes. if (typeof visitors[node.type] !== 'function') { self.file.fail( new Error( - 'Missing compiler for node of type `' + - node.type + '`: `' + node + '`' + 'Missing compiler for node of type `' + node.type + '`: `' + node + '`' ), node - ); + ) } - return visitors[node.type].call(self, node, parent); + return visitors[node.type].call(self, node, parent) } diff --git a/packages/remark-stringify/lib/macro/ordered-items.js b/packages/remark-stringify/lib/macro/ordered-items.js index 5b5369967..2e2fee2b3 100644 --- a/packages/remark-stringify/lib/macro/ordered-items.js +++ b/packages/remark-stringify/lib/macro/ordered-items.js @@ -1,39 +1,43 @@ -'use strict'; +'use strict' -module.exports = orderedItems; +module.exports = orderedItems -/* Visit ordered list items. - * - * Starts the list with - * `node.start` and increments each following list item - * bullet by one: - * - * 2. foo - * 3. bar - * - * In `incrementListMarker: false` mode, does not increment - * each marker and stays on `node.start`: - * - * 1. foo - * 1. bar - */ +var lineFeed = '\n' +var dot = '.' + +var blank = lineFeed + lineFeed + +// Visit ordered list items. +// +// Starts the list with +// `node.start` and increments each following list item +// bullet by one: +// +// 2. foo +// 3. bar +// +// In `incrementListMarker: false` mode, does not increment +// each marker and stays on `node.start`: +// +// 1. foo +// 1. bar function orderedItems(node) { - var self = this; - var fn = self.visitors.listItem; - var increment = self.options.incrementListMarker; - var values = []; - var start = node.start; - var children = node.children; - var length = children.length; - var index = -1; - var bullet; + var self = this + var fn = self.visitors.listItem + var increment = self.options.incrementListMarker + var values = [] + var start = node.start + var children = node.children + var length = children.length + var index = -1 + var bullet - start = start == null ? 1 : start; + start = start == null ? 1 : start while (++index < length) { - bullet = (increment ? start + index : start) + '.'; - values[index] = fn.call(self, children[index], node, index, bullet); + bullet = (increment ? start + index : start) + dot + values[index] = fn.call(self, children[index], node, index, bullet) } - return values.join(node.spread ? '\n\n' : '\n'); + return values.join(node.spread ? blank : lineFeed) } diff --git a/packages/remark-stringify/lib/macro/unordered-items.js b/packages/remark-stringify/lib/macro/unordered-items.js index 87548c049..4780014f4 100644 --- a/packages/remark-stringify/lib/macro/unordered-items.js +++ b/packages/remark-stringify/lib/macro/unordered-items.js @@ -1,22 +1,24 @@ -'use strict'; +'use strict' -module.exports = unorderedItems; +module.exports = unorderedItems -/* Visit unordered list items. - * Uses `options.bullet` as each item's bullet. - */ +var lineFeed = '\n' + +var blank = lineFeed + lineFeed + +// Visit unordered list items. Uses `options.bullet` as each item’s bullet. function unorderedItems(node) { - var self = this; - var bullet = self.options.bullet; - var fn = self.visitors.listItem; - var children = node.children; - var length = children.length; - var index = -1; - var values = []; + var self = this + var bullet = self.options.bullet + var fn = self.visitors.listItem + var children = node.children + var length = children.length + var index = -1 + var values = [] while (++index < length) { - values[index] = fn.call(self, children[index], node, index, bullet); + values[index] = fn.call(self, children[index], node, index, bullet) } - return values.join(node.spread ? '\n\n' : '\n'); + return values.join(node.spread ? blank : lineFeed) } diff --git a/packages/remark-stringify/lib/set-options.js b/packages/remark-stringify/lib/set-options.js index 8d873cae2..1f5c343b6 100644 --- a/packages/remark-stringify/lib/set-options.js +++ b/packages/remark-stringify/lib/set-options.js @@ -1,14 +1,14 @@ -'use strict'; +'use strict' -var xtend = require('xtend'); -var encode = require('stringify-entities'); -var defaults = require('./defaults'); -var escapeFactory = require('./escape'); -var returner = require('./util/returner'); +var xtend = require('xtend') +var encode = require('stringify-entities') +var defaults = require('./defaults') +var escapeFactory = require('./escape') +var identity = require('./util/identity') -module.exports = setOptions; +module.exports = setOptions -/* Map of applicable enum's. */ +// Map of applicable enums. var maps = { entities: {true: true, false: true, numbers: true, escape: true}, bullet: {'*': true, '-': true, '+': true}, @@ -17,152 +17,144 @@ var maps = { emphasis: {_: true, '*': true}, strong: {_: true, '*': true}, fence: {'`': true, '~': true} -}; +} -/* Expose `validate`. */ +// Expose `validate`. var validate = { boolean: validateBoolean, string: validateString, number: validateNumber, function: validateFunction -}; +} -/* Set options. Does not overwrite previously set - * options. */ +// Set options. Does not overwrite previously set options. function setOptions(options) { - var self = this; - var current = self.options; - var ruleRepetition; - var key; + var self = this + var current = self.options + var ruleRepetition + var key if (options == null) { - options = {}; + options = {} } else if (typeof options === 'object') { - options = xtend(options); + options = xtend(options) } else { - throw new Error('Invalid value `' + options + '` for setting `options`'); + throw new Error('Invalid value `' + options + '` for setting `options`') } for (key in defaults) { - validate[typeof defaults[key]](options, key, current[key], maps[key]); + validate[typeof defaults[key]](options, key, current[key], maps[key]) } - ruleRepetition = options.ruleRepetition; + ruleRepetition = options.ruleRepetition if (ruleRepetition && ruleRepetition < 3) { - raise(ruleRepetition, 'options.ruleRepetition'); + raise(ruleRepetition, 'options.ruleRepetition') } - self.encode = encodeFactory(String(options.entities)); - self.escape = escapeFactory(options); + self.encode = encodeFactory(String(options.entities)) + self.escape = escapeFactory(options) - self.options = options; - - return self; -} + self.options = options -/* Throw an exception with in its `message` `value` - * and `name`. */ -function raise(value, name) { - throw new Error('Invalid value `' + value + '` for setting `' + name + '`'); + return self } -/* Validate a value to be boolean. Defaults to `def`. - * Raises an exception with `context[name]` when not - * a boolean. */ +// Validate a value to be boolean. Defaults to `def`. Raises an exception with +// `context[name]` when not a boolean. function validateBoolean(context, name, def) { - var value = context[name]; + var value = context[name] if (value == null) { - value = def; + value = def } if (typeof value !== 'boolean') { - raise(value, 'options.' + name); + raise(value, 'options.' + name) } - context[name] = value; + context[name] = value } -/* Validate a value to be boolean. Defaults to `def`. - * Raises an exception with `context[name]` when not - * a boolean. */ +// Validate a value to be boolean. Defaults to `def`. Raises an exception with +// `context[name]` when not a boolean. function validateNumber(context, name, def) { - var value = context[name]; + var value = context[name] if (value == null) { - value = def; + value = def } if (isNaN(value)) { - raise(value, 'options.' + name); + raise(value, 'options.' + name) } - context[name] = value; + context[name] = value } -/* Validate a value to be in `map`. Defaults to `def`. - * Raises an exception with `context[name]` when not - * in `map`. */ +// Validate a value to be in `map`. Defaults to `def`. Raises an exception +// with `context[name]` when not in `map`. function validateString(context, name, def, map) { - var value = context[name]; + var value = context[name] if (value == null) { - value = def; + value = def } - value = String(value); + value = String(value) if (!(value in map)) { - raise(value, 'options.' + name); + raise(value, 'options.' + name) } - context[name] = value; + context[name] = value } -/* Validate a value to be function. Defaults to `def`. - * Raises an exception with `context[name]` when not - * a function. */ +// Validate a value to be function. Defaults to `def`. Raises an exception +// with `context[name]` when not a function. function validateFunction(context, name, def) { - var value = context[name]; + var value = context[name] if (value == null) { - value = def; + value = def } if (typeof value !== 'function') { - raise(value, 'options.' + name); + raise(value, 'options.' + name) } - context[name] = value; + context[name] = value } -/* Factory to encode HTML entities. - * Creates a no-operation function when `type` is - * `'false'`, a function which encodes using named - * references when `type` is `'true'`, and a function - * which encodes using numbered references when `type` is - * `'numbers'`. */ +// Factory to encode HTML entities. Creates a no-operation function when +// `type` is `'false'`, a function which encodes using named references when +// `type` is `'true'`, and a function which encodes using numbered references +// when `type` is `'numbers'`. function encodeFactory(type) { - var options = {}; + var options = {} if (type === 'false') { - return returner; + return identity } if (type === 'true') { - options.useNamedReferences = true; + options.useNamedReferences = true } if (type === 'escape') { - options.escapeOnly = true; - options.useNamedReferences = true; + options.escapeOnly = true + options.useNamedReferences = true } - return wrapped; + return wrapped - /* Encode HTML entities using the bound options. */ + // Encode HTML entities using the bound options. function wrapped(value) { - return encode(value, options); + return encode(value, options) } } + +// Throw an exception with in its `message` `value` and `name`. +function raise(value, name) { + throw new Error('Invalid value `' + value + '` for setting `' + name + '`') +} diff --git a/packages/remark-stringify/lib/util/copy-identifier-encoding.js b/packages/remark-stringify/lib/util/copy-identifier-encoding.js index 6cc014fee..a3de26972 100644 --- a/packages/remark-stringify/lib/util/copy-identifier-encoding.js +++ b/packages/remark-stringify/lib/util/copy-identifier-encoding.js @@ -1,60 +1,67 @@ -'use strict'; +'use strict' -var entityPrefixLength = require('./entity-prefix-length'); +var entityPrefixLength = require('./entity-prefix-length') -module.exports = copy; +module.exports = copy -var PUNCTUATION = /[-!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~_]/; +var ampersand = '&' -/* For shortcut and collapsed reference links, the contents - * is also an identifier, so we need to restore the original - * encoding and escaping that were present in the source - * string. - * - * This function takes the unescaped & unencoded value from - * shortcut's child nodes and the identifier and encodes - * the former according to the latter. */ +var punctuationExppresion = /[-!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~_]/ + +// For shortcut and collapsed reference links, the contents is also an +// identifier, so we need to restore the original encoding and escaping +// that were present in the source string. +// +// This function takes the unescaped & unencoded value from shortcut’s +// child nodes and the identifier and encodes the former according to +// the latter. function copy(value, identifier) { - var length = value.length; - var count = identifier.length; - var result = []; - var position = 0; - var index = 0; - var start; + var length = value.length + var count = identifier.length + var result = [] + var position = 0 + var index = 0 + var start while (index < length) { - /* Take next non-punctuation characters from `value`. */ - start = index; + // Take next non-punctuation characters from `value`. + start = index - while (index < length && !PUNCTUATION.test(value.charAt(index))) { - index += 1; + while (index < length && !punctuationExppresion.test(value.charAt(index))) { + index += 1 } - result.push(value.slice(start, index)); + result.push(value.slice(start, index)) - /* Advance `position` to the next punctuation character. */ - while (position < count && !PUNCTUATION.test(identifier.charAt(position))) { - position += 1; + // Advance `position` to the next punctuation character. + while ( + position < count && + !punctuationExppresion.test(identifier.charAt(position)) + ) { + position += 1 } - /* Take next punctuation characters from `identifier`. */ - start = position; + // Take next punctuation characters from `identifier`. + start = position - while (position < count && PUNCTUATION.test(identifier.charAt(position))) { - if (identifier.charAt(position) === '&') { - position += entityPrefixLength(identifier.slice(position)); + while ( + position < count && + punctuationExppresion.test(identifier.charAt(position)) + ) { + if (identifier.charAt(position) === ampersand) { + position += entityPrefixLength(identifier.slice(position)) } - position += 1; + position += 1 } - result.push(identifier.slice(start, position)); + result.push(identifier.slice(start, position)) - /* Advance `index` to the next non-punctuation character. */ - while (index < length && PUNCTUATION.test(value.charAt(index))) { - index += 1; + // Advance `index` to the next non-punctuation character. + while (index < length && punctuationExppresion.test(value.charAt(index))) { + index += 1 } } - return result.join(''); + return result.join('') } diff --git a/packages/remark-stringify/lib/util/enclose-title.js b/packages/remark-stringify/lib/util/enclose-title.js index 9e641b729..f11639ffc 100644 --- a/packages/remark-stringify/lib/util/enclose-title.js +++ b/packages/remark-stringify/lib/util/enclose-title.js @@ -1,13 +1,17 @@ -'use strict'; +'use strict' -module.exports = enclose; +module.exports = enclose -/* There is currently no way to support nested delimiters - * across Markdown.pl, CommonMark, and GitHub (RedCarpet). - * The following code supports Markdown.pl and GitHub. - * CommonMark is not supported when mixing double- and - * single quotes inside a title. */ +var quotationMark = '"' +var apostrophe = "'" + +// There is currently no way to support nested delimiters across Markdown.pl, +// CommonMark, and GitHub (RedCarpet). The following code supports Markdown.pl +// and GitHub. +// CommonMark is not supported when mixing double- and single quotes inside a +// title. function enclose(title) { - var delimiter = title.indexOf('"') === -1 ? '"' : '\''; - return delimiter + title + delimiter; + var delimiter = + title.indexOf(quotationMark) === -1 ? quotationMark : apostrophe + return delimiter + title + delimiter } diff --git a/packages/remark-stringify/lib/util/enclose-uri.js b/packages/remark-stringify/lib/util/enclose-uri.js index 9a53ae61a..d162de948 100644 --- a/packages/remark-stringify/lib/util/enclose-uri.js +++ b/packages/remark-stringify/lib/util/enclose-uri.js @@ -1,24 +1,33 @@ -'use strict'; +'use strict' -var count = require('ccount'); +var count = require('ccount') -module.exports = enclose; +module.exports = enclose -var re = /\s/; +var leftParenthesis = '(' +var rightParenthesis = ')' +var lessThan = '<' +var greaterThan = '>' -/* Wrap `url` in angle brackets when needed, or when - * forced. - * In links, images, and definitions, the URL part needs - * to be enclosed when it: - * - * - has a length of `0`; - * - contains white-space; - * - has more or less opening than closing parentheses. - */ +var expression = /\s/ + +// Wrap `url` in angle brackets when needed, or when +// forced. +// In links, images, and definitions, the URL part needs +// to be enclosed when it: +// +// - has a length of `0` +// - contains white-space +// - has more or less opening than closing parentheses function enclose(uri, always) { - if (always || uri.length === 0 || re.test(uri) || count(uri, '(') !== count(uri, ')')) { - return '<' + uri + '>'; + if ( + always || + uri.length === 0 || + expression.test(uri) || + count(uri, leftParenthesis) !== count(uri, rightParenthesis) + ) { + return lessThan + uri + greaterThan } - return uri; + return uri } diff --git a/packages/remark-stringify/lib/util/enter-link-reference.js b/packages/remark-stringify/lib/util/enter-link-reference.js index a77053bca..d0fe5573b 100644 --- a/packages/remark-stringify/lib/util/enter-link-reference.js +++ b/packages/remark-stringify/lib/util/enter-link-reference.js @@ -1,36 +1,33 @@ -'use strict'; +'use strict' -var returner = require('./returner'); +var identity = require('./identity') -module.exports = enter; +module.exports = enter -/* Shortcut and collapsed link references need no escaping - * and encoding during the processing of child nodes (it - * must be implied from identifier). - * - * This toggler turns encoding and escaping off for shortcut - * and collapsed references. - * - * Implies `enterLink`. - */ +// Shortcut and collapsed link references need no escaping and encoding during +// the processing of child nodes (it must be implied from identifier). +// +// This toggler turns encoding and escaping off for shortcut and collapsed +// references. +// +// Implies `enterLink`. function enter(compiler, node) { - var encode = compiler.encode; - var escape = compiler.escape; - var exit = compiler.enterLink(); + var encode = compiler.encode + var escape = compiler.escape + var exitLink = compiler.enterLink() - if ( - node.referenceType !== 'shortcut' && - node.referenceType !== 'collapsed' - ) { - return exit; + if (node.referenceType !== 'shortcut' && node.referenceType !== 'collapsed') { + return exitLink } - compiler.escape = returner; - compiler.encode = returner; + compiler.escape = identity + compiler.encode = identity - return function () { - compiler.encode = encode; - compiler.escape = escape; - exit(); - }; + return exit + + function exit() { + compiler.encode = encode + compiler.escape = escape + exitLink() + } } diff --git a/packages/remark-stringify/lib/util/entity-prefix-length.js b/packages/remark-stringify/lib/util/entity-prefix-length.js index 488bb1213..2ba771cee 100644 --- a/packages/remark-stringify/lib/util/entity-prefix-length.js +++ b/packages/remark-stringify/lib/util/entity-prefix-length.js @@ -1,23 +1,23 @@ -'use strict'; +'use strict' -var decode = require('parse-entities'); +var decode = require('parse-entities') -module.exports = length; +module.exports = length -/* Returns the length of HTML entity that is a prefix of - * the given string (excluding the ampersand), 0 if it - * does not start with an entity. */ +var ampersand = '&' + +// Returns the length of HTML entity that is a prefix of the given string +// (excluding the ampersand), 0 if it does not start with an entity. function length(value) { - var prefix; + var prefix - /* istanbul ignore if - Currently also tested for at - * implemention, but we keep it here because that’s - * proper. */ - if (value.charAt(0) !== '&') { - return 0; + /* istanbul ignore if - Currently also tested for at implemention, but we + * keep it here because that’s proper. */ + if (value.charAt(0) !== ampersand) { + return 0 } - prefix = value.split('&', 2).join('&'); + prefix = value.split(ampersand, 2).join(ampersand) - return prefix.length - decode(prefix).length; + return prefix.length - decode(prefix).length } diff --git a/packages/remark-stringify/lib/util/identity.js b/packages/remark-stringify/lib/util/identity.js new file mode 100644 index 000000000..45a34f7d8 --- /dev/null +++ b/packages/remark-stringify/lib/util/identity.js @@ -0,0 +1,7 @@ +'use strict' + +module.exports = identity + +function identity(value) { + return value +} diff --git a/packages/remark-stringify/lib/util/label.js b/packages/remark-stringify/lib/util/label.js index e4fe8460e..5718d7927 100644 --- a/packages/remark-stringify/lib/util/label.js +++ b/packages/remark-stringify/lib/util/label.js @@ -1,19 +1,27 @@ -'use strict'; +'use strict' -module.exports = label; +module.exports = label -/* Stringify a reference label. - * Because link references are easily, mistakingly, - * created (for example, `[foo]`), reference nodes have - * an extra property depicting how it looked in the - * original document, so stringification can cause minimal - * changes. */ +var leftSquareBracket = '[' +var rightSquareBracket = ']' + +var shortcut = 'shortcut' +var collapsed = 'collapsed' + +// Stringify a reference label. +// Because link references are easily, mistakingly, created (for example, +// `[foo]`), reference nodes have an extra property depicting how it looked in +// the original document, so stringification can cause minimal changes. function label(node) { - var type = node.referenceType; + var type = node.referenceType - if (type === 'shortcut') { - return ''; + if (type === shortcut) { + return '' } - return type === 'collapsed' ? '[]' : '[' + (node.label || node.identifier) + ']'; + return ( + leftSquareBracket + + (type === collapsed ? '' : node.label || node.identifier) + + rightSquareBracket + ) } diff --git a/packages/remark-stringify/lib/util/pad.js b/packages/remark-stringify/lib/util/pad.js index 14b9b1b70..8f9d085ec 100644 --- a/packages/remark-stringify/lib/util/pad.js +++ b/packages/remark-stringify/lib/util/pad.js @@ -1,27 +1,26 @@ -'use strict'; +'use strict' -var repeat = require('repeat-string'); +var repeat = require('repeat-string') -module.exports = pad; +module.exports = pad -var INDENT = 4; +var lineFeed = '\n' +var space = ' ' -/* Pad `value` with `level * INDENT` spaces. Respects - * lines. Ignores empty lines. */ -function pad(value, level) { - var index; - var padding; - - value = value.split('\n'); +var tabSize = 4 - index = value.length; - padding = repeat(' ', level * INDENT); +// Pad `value` with `level * tabSize` spaces. Respects lines. Ignores empty +// lines. +function pad(value, level) { + var values = value.split(lineFeed) + var index = values.length + var padding = repeat(space, level * tabSize) while (index--) { - if (value[index].length !== 0) { - value[index] = padding + value[index]; + if (values[index].length !== 0) { + values[index] = padding + values[index] } } - return value.join('\n'); + return values.join(lineFeed) } diff --git a/packages/remark-stringify/lib/util/returner.js b/packages/remark-stringify/lib/util/returner.js deleted file mode 100644 index 09f674ac9..000000000 --- a/packages/remark-stringify/lib/util/returner.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -module.exports = returner; - -function returner(value) { - return value; -} diff --git a/packages/remark-stringify/lib/visitors/blockquote.js b/packages/remark-stringify/lib/visitors/blockquote.js index 4f2c4a0a2..6b5187ae8 100644 --- a/packages/remark-stringify/lib/visitors/blockquote.js +++ b/packages/remark-stringify/lib/visitors/blockquote.js @@ -1,18 +1,22 @@ -'use strict'; +'use strict' -module.exports = blockquote; +module.exports = blockquote + +var lineFeed = '\n' +var space = ' ' +var greaterThan = '>' function blockquote(node) { - var values = this.block(node).split('\n'); - var result = []; - var length = values.length; - var index = -1; - var value; + var values = this.block(node).split(lineFeed) + var result = [] + var length = values.length + var index = -1 + var value while (++index < length) { - value = values[index]; - result[index] = (value ? ' ' : '') + value; + value = values[index] + result[index] = (value ? space : '') + value } - return '>' + result.join('\n>'); + return greaterThan + result.join(lineFeed + greaterThan) } diff --git a/packages/remark-stringify/lib/visitors/break.js b/packages/remark-stringify/lib/visitors/break.js index 5e6326ee2..86e8c16c1 100644 --- a/packages/remark-stringify/lib/visitors/break.js +++ b/packages/remark-stringify/lib/visitors/break.js @@ -1,9 +1,14 @@ -'use strict'; +'use strict' -module.exports = lineBreak; +module.exports = lineBreak -var map = {true: '\\\n', false: ' \n'}; +var backslash = '\\' +var lineFeed = '\n' +var space = ' ' + +var commonmark = backslash + lineFeed +var normal = space + space + lineFeed function lineBreak() { - return map[this.options.commonmark]; + return this.options.commonmark ? commonmark : normal } diff --git a/packages/remark-stringify/lib/visitors/code.js b/packages/remark-stringify/lib/visitors/code.js index ee59c339d..2a0480840 100644 --- a/packages/remark-stringify/lib/visitors/code.js +++ b/packages/remark-stringify/lib/visitors/code.js @@ -1,69 +1,79 @@ -'use strict'; +'use strict' -var streak = require('longest-streak'); -var repeat = require('repeat-string'); -var pad = require('../util/pad'); +var streak = require('longest-streak') +var repeat = require('repeat-string') +var pad = require('../util/pad') -module.exports = code; +module.exports = code -/* Stringify code. - * Creates indented code when: - * - * - No language tag exists; - * - Not in `fences: true` mode; - * - A non-empty value exists. - * - * Otherwise, GFM fenced code is created: - * - * ```js - * foo(); - * ``` - * - * When in ``fence: `~` `` mode, uses tildes as fences: - * - * ~~~js - * foo(); - * ~~~ - * - * Knows about internal fences: - * - * ````markdown - * ```javascript - * foo(); - * ``` - * ```` - */ +var lineFeed = '\n' +var space = ' ' + +// Stringify code. +// Creates indented code when: +// +// - No language tag exists +// - Not in `fences: true` mode +// - A non-empty value exists +// +// Otherwise, GFM fenced code is created: +// +// ````markdown +// ```js +// foo(); +// ``` +// ```` +// +// When in ``fence: `~` `` mode, uses tildes as fences: +// +// ```markdown +// ~~~js +// foo(); +// ~~~ +// ``` +// +// Knows about internal fences: +// +// `````markdown +// ````markdown +// ```javascript +// foo(); +// ``` +// ```` +// ````` function code(node, parent) { - var self = this; - var value = node.value; - var options = self.options; - var marker = options.fence; - var info = node.lang || ''; - var fence; + var self = this + var value = node.value + var options = self.options + var marker = options.fence + var info = node.lang || '' + var fence if (info && node.meta) { - info += ' ' + node.meta; + info += space + node.meta } - info = self.encode(info, node); + info = self.encode(info, node) - /* Without (needed) fences. */ + // Without (needed) fences. if (!info && !options.fences && value) { - /* Throw when pedantic, in a list item which - * isn’t compiled using a tab. */ + // Throw when pedantic, in a list item which isn’t compiled using a tab. if ( parent && parent.type === 'listItem' && options.listItemIndent !== 'tab' && options.pedantic ) { - self.file.fail('Cannot indent code properly. See http://git.io/vgFvT', node.position); + self.file.fail( + 'Cannot indent code properly. See http://git.io/vgFvT', + node.position + ) } - return pad(value, 1); + return pad(value, 1) } - fence = repeat(marker, Math.max(streak(value, marker) + 1, 3)); + fence = repeat(marker, Math.max(streak(value, marker) + 1, 3)) - return fence + info + '\n' + value + '\n' + fence; + return fence + info + lineFeed + value + lineFeed + fence } diff --git a/packages/remark-stringify/lib/visitors/definition.js b/packages/remark-stringify/lib/visitors/definition.js index d6abb2ab4..11bd7afef 100644 --- a/packages/remark-stringify/lib/visitors/definition.js +++ b/packages/remark-stringify/lib/visitors/definition.js @@ -1,23 +1,36 @@ -'use strict'; +'use strict' -var uri = require('../util/enclose-uri'); -var title = require('../util/enclose-title'); +var uri = require('../util/enclose-uri') +var title = require('../util/enclose-title') -module.exports = definition; +module.exports = definition -/* Stringify an URL definition. - * - * Is smart about enclosing `url` (see `encloseURI()`) and - * `title` (see `encloseTitle()`). - * - * [foo]: 'An "example" e-mail' - */ +var space = ' ' +var colon = ':' +var leftSquareBracket = '[' +var rightSquareBracket = ']' + +// Stringify an URL definition. +// +// Is smart about enclosing `url` (see `encloseURI()`) and `title` (see +// `encloseTitle()`). +// +// ```markdown +// [foo]: 'An "example" e-mail' +// ``` function definition(node) { - var content = uri(node.url); + var content = uri(node.url) if (node.title) { - content += ' ' + title(node.title); + content += space + title(node.title) } - return '[' + (node.label || node.identifier) + ']: ' + content; + return ( + leftSquareBracket + + (node.label || node.identifier) + + rightSquareBracket + + colon + + space + + content + ) } diff --git a/packages/remark-stringify/lib/visitors/delete.js b/packages/remark-stringify/lib/visitors/delete.js index 68fbedc58..0586a9832 100644 --- a/packages/remark-stringify/lib/visitors/delete.js +++ b/packages/remark-stringify/lib/visitors/delete.js @@ -1,7 +1,11 @@ -'use strict'; +'use strict' -module.exports = strikethrough; +module.exports = strikethrough + +var tilde = '~' + +var fence = tilde + tilde function strikethrough(node) { - return '~~' + this.all(node).join('') + '~~'; + return fence + this.all(node).join('') + fence } diff --git a/packages/remark-stringify/lib/visitors/emphasis.js b/packages/remark-stringify/lib/visitors/emphasis.js index fc2c0d924..d2fec567b 100644 --- a/packages/remark-stringify/lib/visitors/emphasis.js +++ b/packages/remark-stringify/lib/visitors/emphasis.js @@ -1,34 +1,38 @@ -'use strict'; +'use strict' -module.exports = emphasis; +module.exports = emphasis -/* Stringify an `emphasis`. - * - * The marker used is configurable through `emphasis`, which - * defaults to an underscore (`'_'`) but also accepts an - * asterisk (`'*'`): - * - * *foo* - * - * In `pedantic` mode, text which itself contains an underscore - * will cause the marker to default to an asterisk instead: - * - * *foo_bar* - */ +var underscore = '_' +var asterisk = '*' + +// Stringify an `emphasis`. +// +// The marker used is configurable through `emphasis`, which defaults to an +// underscore (`'_'`) but also accepts an asterisk (`'*'`): +// +// ```markdown +// *foo* +// ``` +// +// In `pedantic` mode, text which itself contains an underscore will cause the +// marker to default to an asterisk instead: +// +// ```markdown +// *foo_bar* +// ``` function emphasis(node) { - var marker = this.options.emphasis; - var content = this.all(node).join(''); + var marker = this.options.emphasis + var content = this.all(node).join('') - /* When in pedantic mode, prevent using underscore as the marker when - * there are underscores in the content. - */ + // When in pedantic mode, prevent using underscore as the marker when there + // are underscores in the content. if ( this.options.pedantic && - marker === '_' && + marker === underscore && content.indexOf(marker) !== -1 ) { - marker = '*'; + marker = asterisk } - return marker + content + marker; + return marker + content + marker } diff --git a/packages/remark-stringify/lib/visitors/footnote-definition.js b/packages/remark-stringify/lib/visitors/footnote-definition.js index a2e5daad8..42d27f4df 100644 --- a/packages/remark-stringify/lib/visitors/footnote-definition.js +++ b/packages/remark-stringify/lib/visitors/footnote-definition.js @@ -1,11 +1,30 @@ -'use strict'; +'use strict' -var repeat = require('repeat-string'); +var repeat = require('repeat-string') -module.exports = footnoteDefinition; +var lineFeed = '\n' +var space = ' ' +var colon = ':' +var leftSquareBracket = '[' +var rightSquareBracket = ']' +var caret = '^' + +var tabSize = 4 +var blank = lineFeed + lineFeed +var indent = repeat(space, tabSize) + +module.exports = footnoteDefinition function footnoteDefinition(node) { - var content = this.all(node).join('\n\n' + repeat(' ', 4)); + var content = this.all(node).join(blank + indent) - return '[^' + (node.label || node.identifier) + ']: ' + content; + return ( + leftSquareBracket + + caret + + (node.label || node.identifier) + + rightSquareBracket + + colon + + space + + content + ) } diff --git a/packages/remark-stringify/lib/visitors/footnote-reference.js b/packages/remark-stringify/lib/visitors/footnote-reference.js index b1273b447..1ee9b4c38 100644 --- a/packages/remark-stringify/lib/visitors/footnote-reference.js +++ b/packages/remark-stringify/lib/visitors/footnote-reference.js @@ -1,7 +1,16 @@ -'use strict'; +'use strict' -module.exports = footnoteReference; +module.exports = footnoteReference + +var leftSquareBracket = '[' +var rightSquareBracket = ']' +var caret = '^' function footnoteReference(node) { - return '[^' + (node.label || node.identifier) + ']'; + return ( + leftSquareBracket + + caret + + (node.label || node.identifier) + + rightSquareBracket + ) } diff --git a/packages/remark-stringify/lib/visitors/footnote.js b/packages/remark-stringify/lib/visitors/footnote.js index 154e3580c..9269bd4c5 100644 --- a/packages/remark-stringify/lib/visitors/footnote.js +++ b/packages/remark-stringify/lib/visitors/footnote.js @@ -1,7 +1,13 @@ -'use strict'; +'use strict' -module.exports = footnote; +module.exports = footnote + +var leftSquareBracket = '[' +var rightSquareBracket = ']' +var caret = '^' function footnote(node) { - return '[^' + this.all(node).join('') + ']'; + return ( + leftSquareBracket + caret + this.all(node).join('') + rightSquareBracket + ) } diff --git a/packages/remark-stringify/lib/visitors/heading.js b/packages/remark-stringify/lib/visitors/heading.js index 67789e22b..9f432d2f5 100644 --- a/packages/remark-stringify/lib/visitors/heading.js +++ b/packages/remark-stringify/lib/visitors/heading.js @@ -1,39 +1,51 @@ -'use strict'; +'use strict' -var repeat = require('repeat-string'); +var repeat = require('repeat-string') -module.exports = heading; +module.exports = heading -/* Stringify a heading. - * - * In `setext: true` mode and when `depth` is smaller than - * three, creates a setext header: - * - * Foo - * === - * - * Otherwise, an ATX header is generated: - * - * ### Foo - * - * In `closeAtx: true` mode, the header is closed with - * hashes: - * - * ### Foo ### - */ +var lineFeed = '\n' +var space = ' ' +var numberSign = '#' +var dash = '-' +var equalsTo = '=' + +// Stringify a heading. +// +// In `setext: true` mode and when `depth` is smaller than three, creates a +// setext header: +// +// ```markdown +// Foo +// === +// ``` +// +// Otherwise, an ATX header is generated: +// +// ```markdown +// ### Foo +// ``` +// +// In `closeAtx: true` mode, the header is closed with hashes: +// +// ```markdown +// ### Foo ### +// ``` function heading(node) { - var self = this; - var depth = node.depth; - var setext = self.options.setext; - var closeAtx = self.options.closeAtx; - var content = self.all(node).join(''); - var prefix; + var self = this + var depth = node.depth + var setext = self.options.setext + var closeAtx = self.options.closeAtx + var content = self.all(node).join('') + var prefix if (setext && depth < 3) { - return content + '\n' + repeat(depth === 1 ? '=' : '-', content.length); + return ( + content + lineFeed + repeat(depth === 1 ? equalsTo : dash, content.length) + ) } - prefix = repeat('#', node.depth); + prefix = repeat(numberSign, node.depth) - return prefix + ' ' + content + (closeAtx ? ' ' + prefix : ''); + return prefix + space + content + (closeAtx ? space + prefix : '') } diff --git a/packages/remark-stringify/lib/visitors/html.js b/packages/remark-stringify/lib/visitors/html.js index e4990214d..105cb3760 100644 --- a/packages/remark-stringify/lib/visitors/html.js +++ b/packages/remark-stringify/lib/visitors/html.js @@ -1,7 +1,7 @@ -'use strict'; +'use strict' -module.exports = html; +module.exports = html function html(node) { - return node.value; + return node.value } diff --git a/packages/remark-stringify/lib/visitors/image-reference.js b/packages/remark-stringify/lib/visitors/image-reference.js index 841558e0b..f78be47a0 100644 --- a/packages/remark-stringify/lib/visitors/image-reference.js +++ b/packages/remark-stringify/lib/visitors/image-reference.js @@ -1,9 +1,19 @@ -'use strict'; +'use strict' -var label = require('../util/label'); +var label = require('../util/label') -module.exports = imageReference; +module.exports = imageReference + +var leftSquareBracket = '[' +var rightSquareBracket = ']' +var exclamationMark = '!' function imageReference(node) { - return '![' + (this.encode(node.alt, node) || '') + ']' + label(node); + return ( + exclamationMark + + leftSquareBracket + + (this.encode(node.alt, node) || '') + + rightSquareBracket + + label(node) + ) } diff --git a/packages/remark-stringify/lib/visitors/image.js b/packages/remark-stringify/lib/visitors/image.js index f8adb0b9e..cc5cebb63 100644 --- a/packages/remark-stringify/lib/visitors/image.js +++ b/packages/remark-stringify/lib/visitors/image.js @@ -1,31 +1,47 @@ -'use strict'; +'use strict' -var uri = require('../util/enclose-uri'); -var title = require('../util/enclose-title'); +var uri = require('../util/enclose-uri') +var title = require('../util/enclose-title') -module.exports = image; +module.exports = image -/* Stringify an image. - * - * Is smart about enclosing `url` (see `encloseURI()`) and - * `title` (see `encloseTitle()`). - * - * ![foo]( 'My "favourite" icon') - * - * Supports named entities in `url`, `alt`, and `title` - * when in `settings.encode` mode. - */ +var space = ' ' +var leftParenthesis = '(' +var rightParenthesis = ')' +var leftSquareBracket = '[' +var rightSquareBracket = ']' +var exclamationMark = '!' + +// Stringify an image. +// +// Is smart about enclosing `url` (see `encloseURI()`) and `title` (see +// `encloseTitle()`). +// +// ```markdown +// ![foo]( 'My "favourite" icon') +// ``` +// +// Supports named entities in `url`, `alt`, and `title` when in +// `settings.encode` mode. function image(node) { - var self = this; - var content = uri(self.encode(node.url || '', node)); - var exit = self.enterLink(); - var alt = self.encode(self.escape(node.alt || '', node)); + var self = this + var content = uri(self.encode(node.url || '', node)) + var exit = self.enterLink() + var alt = self.encode(self.escape(node.alt || '', node)) - exit(); + exit() if (node.title) { - content += ' ' + title(self.encode(node.title, node)); + content += space + title(self.encode(node.title, node)) } - return '![' + alt + '](' + content + ')'; + return ( + exclamationMark + + leftSquareBracket + + alt + + rightSquareBracket + + leftParenthesis + + content + + rightParenthesis + ) } diff --git a/packages/remark-stringify/lib/visitors/inline-code.js b/packages/remark-stringify/lib/visitors/inline-code.js index 21666ba39..6586a858b 100644 --- a/packages/remark-stringify/lib/visitors/inline-code.js +++ b/packages/remark-stringify/lib/visitors/inline-code.js @@ -1,35 +1,41 @@ -'use strict'; +'use strict' -var streak = require('longest-streak'); -var repeat = require('repeat-string'); +var streak = require('longest-streak') +var repeat = require('repeat-string') -module.exports = inlineCode; +module.exports = inlineCode -/* Stringify inline code. - * - * Knows about internal ticks (`\``), and ensures one more - * tick is used to enclose the inline code: - * - * ```foo ``bar`` baz``` - * - * Even knows about inital and final ticks: - * - * `` `foo `` - * `` foo` `` - */ +var space = ' ' +var graveAccent = '`' + +// Stringify inline code. +// +// Knows about internal ticks (`\``), and ensures one more tick is used to +// enclose the inline code: +// +// ````markdown +// ```foo ``bar`` baz``` +// ```` +// +// Even knows about inital and final ticks: +// +// ``markdown +// `` `foo `` +// `` foo` `` +// ``` function inlineCode(node) { - var value = node.value; - var ticks = repeat('`', streak(value, '`') + 1); - var start = ticks; - var end = ticks; + var value = node.value + var ticks = repeat(graveAccent, streak(value, graveAccent) + 1) + var start = ticks + var end = ticks - if (value.charAt(0) === '`') { - start += ' '; + if (value.charAt(0) === graveAccent) { + start += space } - if (value.charAt(value.length - 1) === '`') { - end = ' ' + end; + if (value.charAt(value.length - 1) === graveAccent) { + end = space + end } - return start + value + end; + return start + value + end } diff --git a/packages/remark-stringify/lib/visitors/link-reference.js b/packages/remark-stringify/lib/visitors/link-reference.js index b8b7cc9d3..2785bc6eb 100644 --- a/packages/remark-stringify/lib/visitors/link-reference.js +++ b/packages/remark-stringify/lib/visitors/link-reference.js @@ -1,21 +1,27 @@ -'use strict'; +'use strict' -var copy = require('../util/copy-identifier-encoding'); -var label = require('../util/label'); +var copy = require('../util/copy-identifier-encoding') +var label = require('../util/label') -module.exports = linkReference; +module.exports = linkReference + +var leftSquareBracket = '[' +var rightSquareBracket = ']' + +var shortcut = 'shortcut' +var collapsed = 'collapsed' function linkReference(node) { - var self = this; - var type = node.referenceType; - var exit = self.enterLinkReference(self, node); - var value = self.all(node).join(''); + var self = this + var type = node.referenceType + var exit = self.enterLinkReference(self, node) + var value = self.all(node).join('') - exit(); + exit() - if (type === 'shortcut' || type === 'collapsed') { - value = copy(value, node.label || node.identifier); + if (type === shortcut || type === collapsed) { + value = copy(value, node.label || node.identifier) } - return '[' + value + ']' + label(node); + return leftSquareBracket + value + rightSquareBracket + label(node) } diff --git a/packages/remark-stringify/lib/visitors/link.js b/packages/remark-stringify/lib/visitors/link.js index 7e435905a..f9358dba6 100644 --- a/packages/remark-stringify/lib/visitors/link.js +++ b/packages/remark-stringify/lib/visitors/link.js @@ -1,53 +1,71 @@ -'use strict'; - -var uri = require('../util/enclose-uri'); -var title = require('../util/enclose-title'); - -module.exports = link; - -/* Expression for a protocol: - * http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax */ -var PROTOCOL = /^[a-z][a-z+.-]+:\/?/i; - -/* Stringify a link. - * - * When no title exists, the compiled `children` equal - * `url`, and `url` starts with a protocol, an auto - * link is created: - * - * - * - * Otherwise, is smart about enclosing `url` (see - * `encloseURI()`) and `title` (see `encloseTitle()`). - * - * [foo]( 'An "example" e-mail') - * - * Supports named entities in the `url` and `title` when - * in `settings.encode` mode. */ +'use strict' + +var uri = require('../util/enclose-uri') +var title = require('../util/enclose-title') + +module.exports = link + +var space = ' ' +var leftSquareBracket = '[' +var rightSquareBracket = ']' +var leftParenthesis = '(' +var rightParenthesis = ')' + +var mailto = 'mailto:' + +// Expression for a protocol: +// See . +var protocol = /^[a-z][a-z+.-]+:\/?/i + +// Stringify a link. +// +// When no title exists, the compiled `children` equal `url`, and `url` starts +// with a protocol, an auto link is created: +// +// ```markdown +// +// ``` +// +// Otherwise, is smart about enclosing `url` (see `encloseURI()`) and `title` +// (see `encloseTitle()`). +// ``` +// +// ```markdown +// [foo]( 'An "example" e-mail') +// ``` +// +// Supports named entities in the `url` and `title` when in `settings.encode` +// mode. function link(node) { - var self = this; - var content = self.encode(node.url || '', node); - var exit = self.enterLink(); - var escaped = self.encode(self.escape(node.url || '', node)); - var value = self.all(node).join(''); + var self = this + var content = self.encode(node.url || '', node) + var exit = self.enterLink() + var escaped = self.encode(self.escape(node.url || '', node)) + var value = self.all(node).join('') - exit(); + exit() if ( node.title == null && - PROTOCOL.test(content) && - (escaped === value || escaped === 'mailto:' + value) + protocol.test(content) && + (escaped === value || escaped === mailto + value) ) { - /* Backslash escapes do not work in autolinks, - * so we do not escape. */ - return uri(self.encode(node.url), true); + // Backslash escapes do not work in autolinks, so we do not escape. + return uri(self.encode(node.url), true) } - content = uri(content); + content = uri(content) if (node.title) { - content += ' ' + title(self.encode(self.escape(node.title, node), node)); + content += space + title(self.encode(self.escape(node.title, node), node)) } - return '[' + value + '](' + content + ')'; + return ( + leftSquareBracket + + value + + rightSquareBracket + + leftParenthesis + + content + + rightParenthesis + ) } diff --git a/packages/remark-stringify/lib/visitors/list-item.js b/packages/remark-stringify/lib/visitors/list-item.js index 80d6eaa03..15de8f81d 100644 --- a/packages/remark-stringify/lib/visitors/list-item.js +++ b/packages/remark-stringify/lib/visitors/list-item.js @@ -1,56 +1,75 @@ -'use strict'; - -var repeat = require('repeat-string'); -var pad = require('../util/pad'); - -module.exports = listItem; - -/* Stringify a list item. - * - * Prefixes the content with a checked checkbox when - * `checked: true`: - * - * [x] foo - * - * Prefixes the content with an unchecked checkbox when - * `checked: false`: - * - * [ ] foo - */ +'use strict' + +var repeat = require('repeat-string') +var pad = require('../util/pad') + +module.exports = listItem + +var lineFeed = '\n' +var space = ' ' +var leftSquareBracket = '[' +var rightSquareBracket = ']' +var lowercaseX = 'x' + +var ceil = Math.ceil +var blank = lineFeed + lineFeed + +var tabSize = 4 + +// Stringify a list item. +// +// Prefixes the content with a checked checkbox when `checked: true`: +// +// ```markdown +// [x] foo +// ``` +// +// Prefixes the content with an unchecked checkbox when `checked: false`: +// +// ```markdown +// [ ] foo +// ``` function listItem(node, parent, position, bullet) { - var self = this; - var style = self.options.listItemIndent; - var marker = bullet || self.options.bullet; - var spread = node.spread == null ? true : node.spread; - var checked = node.checked; - var children = node.children; - var length = children.length; - var values = []; - var index = -1; - var value; - var indent; - var spacing; + var self = this + var style = self.options.listItemIndent + var marker = bullet || self.options.bullet + var spread = node.spread == null ? true : node.spread + var checked = node.checked + var children = node.children + var length = children.length + var values = [] + var index = -1 + var value + var indent + var spacing while (++index < length) { - values[index] = self.visit(children[index], node); + values[index] = self.visit(children[index], node) } - value = values.join(spread ? '\n\n' : '\n'); + value = values.join(spread ? blank : lineFeed) if (typeof checked === 'boolean') { // Note: I’d like to be able to only add the space between the check and // the value, but unfortunately github does not support empty list-items // with a checkbox :( - value = '[' + (checked ? 'x' : ' ') + '] ' + value; + value = + leftSquareBracket + + (checked ? lowercaseX : space) + + rightSquareBracket + + space + + value } - if (style === '1' || (style === 'mixed' && value.indexOf('\n') === -1)) { - indent = marker.length + 1; - spacing = ' '; + if (style === '1' || (style === 'mixed' && value.indexOf(lineFeed) === -1)) { + indent = marker.length + 1 + spacing = space } else { - indent = Math.ceil((marker.length + 1) / 4) * 4; - spacing = repeat(' ', indent - marker.length); + indent = ceil((marker.length + 1) / tabSize) * tabSize + spacing = repeat(space, indent - marker.length) } - return value ? marker + spacing + pad(value, indent / 4).slice(indent) : marker; + return value + ? marker + spacing + pad(value, indent / tabSize).slice(indent) + : marker } diff --git a/packages/remark-stringify/lib/visitors/list.js b/packages/remark-stringify/lib/visitors/list.js index f434db86b..a394ab873 100644 --- a/packages/remark-stringify/lib/visitors/list.js +++ b/packages/remark-stringify/lib/visitors/list.js @@ -1,14 +1,8 @@ -'use strict'; +'use strict' -module.exports = list; - -/* Which method to use based on `list.ordered`. */ -var ORDERED_MAP = { - true: 'visitOrderedItems', - false: 'visitUnorderedItems' -}; +module.exports = list function list(node) { - var ordered = node.ordered; - return this[ORDERED_MAP[ordered == null ? false : ordered]](node); + var fn = node.ordered ? this.visitOrderedItems : this.visitUnorderedItems + return fn.call(this, node) } diff --git a/packages/remark-stringify/lib/visitors/paragraph.js b/packages/remark-stringify/lib/visitors/paragraph.js index 56a984580..a9654e398 100644 --- a/packages/remark-stringify/lib/visitors/paragraph.js +++ b/packages/remark-stringify/lib/visitors/paragraph.js @@ -1,7 +1,7 @@ -'use strict'; +'use strict' -module.exports = paragraph; +module.exports = paragraph function paragraph(node) { - return this.all(node).join(''); + return this.all(node).join('') } diff --git a/packages/remark-stringify/lib/visitors/root.js b/packages/remark-stringify/lib/visitors/root.js index 1ef1508cd..33f30feb0 100644 --- a/packages/remark-stringify/lib/visitors/root.js +++ b/packages/remark-stringify/lib/visitors/root.js @@ -1,9 +1,11 @@ -'use strict'; +'use strict' -module.exports = root; +module.exports = root -/* Stringify a root. - * Adds a final newline to ensure valid POSIX files. */ +var lineFeed = '\n' + +// Stringify a root. +// Adds a final newline to ensure valid POSIX files. */ function root(node) { - return this.block(node) + '\n'; + return this.block(node) + lineFeed } diff --git a/packages/remark-stringify/lib/visitors/strong.js b/packages/remark-stringify/lib/visitors/strong.js index 18d5dd3d0..b7445ac83 100644 --- a/packages/remark-stringify/lib/visitors/strong.js +++ b/packages/remark-stringify/lib/visitors/strong.js @@ -1,18 +1,18 @@ -'use strict'; +'use strict' -var repeat = require('repeat-string'); +var repeat = require('repeat-string') -module.exports = strong; +module.exports = strong -/* Stringify a `strong`. - * - * The marker used is configurable by `strong`, which - * defaults to an asterisk (`'*'`) but also accepts an - * underscore (`'_'`): - * - * __foo__ - */ +// Stringify a `strong`. +// +// The marker used is configurable by `strong`, which defaults to an asterisk +// (`'*'`) but also accepts an underscore (`'_'`): +// +// ```markdown +// __foo__ +// ``` function strong(node) { - var marker = repeat(this.options.strong, 2); - return marker + this.all(node).join('') + marker; + var marker = repeat(this.options.strong, 2) + return marker + this.all(node).join('') + marker } diff --git a/packages/remark-stringify/lib/visitors/table-cell.js b/packages/remark-stringify/lib/visitors/table-cell.js index 07e8ed602..cd9d3feec 100644 --- a/packages/remark-stringify/lib/visitors/table-cell.js +++ b/packages/remark-stringify/lib/visitors/table-cell.js @@ -1,7 +1,7 @@ -'use strict'; +'use strict' -module.exports = tableCell; +module.exports = tableCell function tableCell(node) { - return this.all(node).join(''); + return this.all(node).join('') } diff --git a/packages/remark-stringify/lib/visitors/table.js b/packages/remark-stringify/lib/visitors/table.js index fc0c18c82..e246103b6 100644 --- a/packages/remark-stringify/lib/visitors/table.js +++ b/packages/remark-stringify/lib/visitors/table.js @@ -1,58 +1,60 @@ -'use strict'; +'use strict' -var markdownTable = require('markdown-table'); +var markdownTable = require('markdown-table') -module.exports = table; +module.exports = table -/* Stringify table. - * - * Creates a fenced table by default, but not in - * `looseTable: true` mode: - * - * Foo | Bar - * :-: | --- - * Baz | Qux - * - * NOTE: Be careful with `looseTable: true` mode, as a - * loose table inside an indented code block on GitHub - * renders as an actual table! - * - * Creates a spaced table by default, but not in - * `spacedTable: false`: - * - * |Foo|Bar| - * |:-:|---| - * |Baz|Qux| - */ +var space = ' ' +var verticalBar = '|' + +// Stringify table. +// +// Creates a fenced table by default, but not in `looseTable: true` mode: +// +// ```markdown +// Foo | Bar +// :-: | --- +// Baz | Qux +// +// NOTE: Be careful with `looseTable: true` mode, as a loose table inside an +// indented code block on GitHub renders as an actual table! +// +// Creates a spaced table by default, but not in `spacedTable: false`: +// +// ```markdown +// |Foo|Bar| +// |:-:|---| +// |Baz|Qux| +// ``` function table(node) { - var self = this; - var options = self.options; - var loose = options.looseTable; - var spaced = options.spacedTable; - var pad = options.paddedTable; - var stringLength = options.stringLength; - var rows = node.children; - var index = rows.length; - var exit = self.enterTable(); - var result = []; - var start; - var end; + var self = this + var options = self.options + var loose = options.looseTable + var spaced = options.spacedTable + var pad = options.paddedTable + var stringLength = options.stringLength + var rows = node.children + var index = rows.length + var exit = self.enterTable() + var result = [] + var start + var end while (index--) { - result[index] = self.all(rows[index]); + result[index] = self.all(rows[index]) } - exit(); + exit() if (loose) { - start = ''; - end = ''; + start = '' + end = '' } else if (spaced) { - start = '| '; - end = ' |'; + start = verticalBar + space + end = space + verticalBar } else { - start = '|'; - end = '|'; + start = verticalBar + end = verticalBar } return markdownTable(result, { @@ -61,6 +63,6 @@ function table(node) { start: start, end: end, stringLength: stringLength, - delimiter: spaced ? ' | ' : '|' - }); + delimiter: spaced ? space + verticalBar + space : verticalBar + }) } diff --git a/packages/remark-stringify/lib/visitors/text.js b/packages/remark-stringify/lib/visitors/text.js index 90fd7f963..53d0affff 100644 --- a/packages/remark-stringify/lib/visitors/text.js +++ b/packages/remark-stringify/lib/visitors/text.js @@ -1,17 +1,19 @@ -'use strict'; +'use strict' -module.exports = text; +module.exports = text -/* Stringify text. - * Supports named entities in `settings.encode: true` mode: - * - * AT&T - * - * Supports numbered entities in `settings.encode: numbers` - * mode: - * - * AT&T - */ +// Stringify text. +// Supports named entities in `settings.encode: true` mode: +// +// ```markdown +// AT&T +// ``` +// +// Supports numbered entities in `settings.encode: numbers` mode: +// +// ```markdown +// AT&T +// ``` function text(node, parent) { - return this.encode(this.escape(node.value, node, parent), node); + return this.encode(this.escape(node.value, node, parent), node) } diff --git a/packages/remark-stringify/lib/visitors/thematic-break.js b/packages/remark-stringify/lib/visitors/thematic-break.js index 329cfe39d..4cd249f8c 100644 --- a/packages/remark-stringify/lib/visitors/thematic-break.js +++ b/packages/remark-stringify/lib/visitors/thematic-break.js @@ -1,26 +1,31 @@ -'use strict'; +'use strict' -var repeat = require('repeat-string'); +var repeat = require('repeat-string') -module.exports = thematic; +module.exports = thematic -/* Stringify a `thematic-break`. - * The character used is configurable through `rule`: (`'_'`) - * - * ___ - * - * The number of repititions is defined through - * `ruleRepetition`: (`6`) - * - * ****** - * - * Whether spaces delimit each character, is configured - * through `ruleSpaces`: (`true`) - * - * * * * - */ +var space = ' ' + +// Stringify a `thematic-break`. +// The character used is configurable through `rule`: (`'_'`): +// +// ```markdown +// ___ +// ``` +// +// The number of repititions is defined through `ruleRepetition` (`6`): +// +// ```markdown +// ****** +// ``` +// +// Whether spaces delimit each character, is configured through `ruleSpaces` +// (`true`): +// ```markdown +// * * * +// ``` function thematic() { - var options = this.options; - var rule = repeat(options.rule, options.ruleRepetition); - return options.ruleSpaces ? rule.split('').join(' ') : rule; + var options = this.options + var rule = repeat(options.rule, options.ruleRepetition) + return options.ruleSpaces ? rule.split('').join(space) : rule } diff --git a/packages/remark-stringify/readme.md b/packages/remark-stringify/readme.md index 93340185a..ea16f484f 100644 --- a/packages/remark-stringify/readme.md +++ b/packages/remark-stringify/readme.md @@ -16,11 +16,11 @@ npm install remark-stringify ## Usage ```js -var unified = require('unified'); -var createStream = require('unified-stream'); -var parse = require('remark-parse'); -var toc = require('remark-toc'); -var stringify = require('remark-stringify'); +var unified = require('unified') +var createStream = require('unified-stream') +var parse = require('remark-parse') +var toc = require('remark-toc') +var stringify = require('remark-stringify') var processor = unified() .use(parse) @@ -30,11 +30,9 @@ var processor = unified() fence: '~', fences: true, incrementListMarker: false - }); + }) -process.stdin - .pipe(createStream(processor)) - .pipe(process.stdout); +process.stdin.pipe(createStream(processor)).pipe(process.stdout) ``` ## Table of Contents @@ -190,15 +188,17 @@ The below plugin modifies a [visitor][] to add an extra blank line before level two headings. ```js -module.exports = gap; +module.exports = gap function gap() { - var Compiler = this.Compiler; - var visitors = Compiler.prototype.visitors; - var original = visitors.heading; + var Compiler = this.Compiler + var visitors = Compiler.prototype.visitors + var original = visitors.heading - visitors.heading = function heading(node) { - return (node.depth === 2 ? '\n' : '') + original.apply(this, arguments); + visitors.heading = heading + + function heading(node) { + return (node.depth === 2 ? '\n' : '') + original.apply(this, arguments) } } ``` diff --git a/packages/remark/index.js b/packages/remark/index.js index a315ad148..148d2de84 100644 --- a/packages/remark/index.js +++ b/packages/remark/index.js @@ -1,7 +1,10 @@ -'use strict'; +'use strict' -var unified = require('unified'); -var parse = require('remark-parse'); -var stringify = require('remark-stringify'); +var unified = require('unified') +var parse = require('remark-parse') +var stringify = require('remark-stringify') -module.exports = unified().use(parse).use(stringify).freeze(); +module.exports = unified() + .use(parse) + .use(stringify) + .freeze() diff --git a/packages/remark/readme.md b/packages/remark/readme.md index 5ec215ccb..5edd5152a 100644 --- a/packages/remark/readme.md +++ b/packages/remark/readme.md @@ -26,18 +26,18 @@ npm install remark This example lints markdown and turns it into HTML. ```js -var remark = require('remark'); -var recommended = require('remark-preset-lint-recommended'); -var html = require('remark-html'); -var report = require('vfile-reporter'); +var remark = require('remark') +var recommended = require('remark-preset-lint-recommended') +var html = require('remark-html') +var report = require('vfile-reporter') remark() .use(recommended) .use(html) - .process('## Hello world!', function (err, file) { - console.error(report(err || file)); - console.log(String(file)); - }); + .process('## Hello world!', function(err, file) { + console.error(report(err || file)) + console.log(String(file)) + }) ``` Yields: @@ -58,14 +58,14 @@ This example prettifies markdown and configures [`remark-parse`][parse] and [`remark-stringify`][stringify] through [data][]. ```js -var remark = require('remark'); +var remark = require('remark') remark() .data('settings', {commonmark: true, emphasis: '*', strong: '*'}) - .process('_Emphasis_ and __importance__', function (err, file) { - if (err) throw err; - console.log(String(file)); - }); + .process('_Emphasis_ and __importance__', function(err, file) { + if (err) throw err + console.log(String(file)) + }) ``` Yields: @@ -80,16 +80,16 @@ This example prettifies markdown and configures [`remark-parse`][parse] and [`remark-stringify`][stringify] through a [preset][]. ```js -var remark = require('remark'); +var remark = require('remark') remark() .use({ settings: {commonmark: true, emphasis: '*', strong: '*'} }) - .process('_Emphasis_ and __importance__', function (err, file) { - if (err) throw err; - console.log(String(file)); - }); + .process('_Emphasis_ and __importance__', function(err, file) { + if (err) throw err + console.log(String(file)) + }) ``` Yields: diff --git a/script/list-of-methods.js b/script/list-of-methods.js index 167be1a4d..97b715a36 100644 --- a/script/list-of-methods.js +++ b/script/list-of-methods.js @@ -1,36 +1,36 @@ -'use strict'; +'use strict' -var zone = require('mdast-zone'); -var u = require('unist-builder'); -var proto = require('../packages/remark-parse').Parser.prototype; +var zone = require('mdast-zone') +var u = require('unist-builder') +var proto = require('../packages/remark-parse').Parser.prototype -module.exports = listOfMethods; +module.exports = listOfMethods function listOfMethods() { - return transformer; + return transformer } function transformer(tree) { - zone(tree, 'methods-block', replace('blockMethods')); - zone(tree, 'methods-inline', replace('inlineMethods')); + zone(tree, 'methods-block', replace('blockMethods')) + zone(tree, 'methods-inline', replace('inlineMethods')) } function replace(name) { - var list = proto[name]; + var list = proto[name] - return replace; + return replace function replace(start, nodes, end) { return [ start, - u('list', {ordered: false}, list.map(function (name) { - return u('listItem', [ - u('paragraph', [ - u('inlineCode', name) - ]) - ]); - })), + u( + 'list', + {ordered: false}, + list.map(function(name) { + return u('listItem', [u('paragraph', [u('inlineCode', name)])]) + }) + ), end - ]; + ] } } diff --git a/script/regenerate-fixtures.js b/script/regenerate-fixtures.js index c1f43aa9c..97727b974 100644 --- a/script/regenerate-fixtures.js +++ b/script/regenerate-fixtures.js @@ -1,35 +1,32 @@ -'use strict'; +'use strict' -var fs = require('fs'); -var path = require('path'); -var remark = require('../packages/remark'); -var fixtures = require('../test/fixtures'); +var fs = require('fs') +var path = require('path') +var remark = require('../packages/remark') +var fixtures = require('../test/fixtures') -fixtures.forEach(function (fixture) { - var input = fixture.input; - var name = fixture.name; - var mapping = fixture.mapping; +fixtures.forEach(function(fixture) { + var input = fixture.input + var name = fixture.name + var mapping = fixture.mapping - Object.keys(mapping).forEach(function (key) { - var filename = name + (key ? '.' + key : key) + '.json'; - var result; + Object.keys(mapping).forEach(function(key) { + var filename = name + (key ? '.' + key : key) + '.json' + var result try { result = remark() .data('settings', fixture.possibilities[key]) - .parse(input); + .parse(input) } catch (error) { - console.log('Could not regenerate `' + filename + '`'); - throw error; + console.log('Cannot regenerate `' + filename + '`') + throw error } - result = JSON.stringify(result, null, 2) + '\n'; + result = JSON.stringify(result, null, 2) + '\n' - filename = filename.replace(/\*/g, '-asterisk-'); + filename = filename.replace(/\*/g, '-asterisk-') - fs.writeFileSync( - path.join('test', 'fixtures', 'tree', filename), - result - ); - }); -}); + fs.writeFileSync(path.join('test', 'fixtures', 'tree', filename), result) + }) +}) diff --git a/test/api.js b/test/api.js index 8cf181ea1..f1f29fbe5 100644 --- a/test/api.js +++ b/test/api.js @@ -1,7 +1,7 @@ -'use strict'; +'use strict' -require('./remark-parse'); -require('./remark-stringify'); -require('./remark-stringify-escapes'); -require('./remark-process'); -require('./remark'); +require('./remark-parse') +require('./remark-stringify') +require('./remark-stringify-escapes') +require('./remark-process') +require('./remark') diff --git a/test/cli.js b/test/cli.js index c6e376c96..54715ba28 100644 --- a/test/cli.js +++ b/test/cli.js @@ -1,20 +1,20 @@ -'use strict'; +'use strict' -var path = require('path'); -var execa = require('execa'); -var test = require('tape'); +var path = require('path') +var execa = require('execa') +var test = require('tape') -var join = path.join; +var join = path.join -test('remark-cli', function (t) { - t.plan(2); +test('remark-cli', function(t) { + t.plan(2) - t.test('should show help on `--help`', function (st) { - var bin = join('packages', 'remark-cli', 'cli.js'); + t.test('should show help on `--help`', function(st) { + var bin = join('packages', 'remark-cli', 'cli.js') - st.plan(1); + st.plan(1) - execa.stdout(bin, ['--help']).then(function (result) { + execa.stdout(bin, ['--help']).then(function(result) { st.equal( result, [ @@ -59,25 +59,25 @@ test('remark-cli', function (t) { ' $ remark . -o' ].join('\n'), 'should show help' - ); - }); - }); + ) + }) + }) - t.test('should show version on `--version`', function (st) { - var bin = join('packages', 'remark-cli', 'cli.js'); + t.test('should show version on `--version`', function(st) { + var bin = join('packages', 'remark-cli', 'cli.js') - st.plan(2); + st.plan(2) - execa.stdout(bin, ['--version']).then(function (result) { + execa.stdout(bin, ['--version']).then(function(result) { st.ok( /remark: \d+\.\d+\.\d+/.test(result), 'should include remark version' - ); + ) st.ok( /remark-cli: \d+\.\d+\.\d+/.test(result), 'should include remark-cli version' - ); - }); - }); -}); + ) + }) + }) +}) diff --git a/test/fixtures/index.js b/test/fixtures/index.js index f849b39a9..3f4c06c7f 100644 --- a/test/fixtures/index.js +++ b/test/fixtures/index.js @@ -1,241 +1,236 @@ -'use strict'; +'use strict' -var fs = require('fs'); -var path = require('path'); -var camelcase = require('camelcase'); -var clone = require('clone'); -var parseDefaults = require('../../packages/remark-parse/lib/defaults.js'); -var stringifyDefaults = require('../../packages/remark-stringify/lib/defaults.js'); +var fs = require('fs') +var path = require('path') +var camelcase = require('camelcase') +var clone = require('clone') +var parseDefaults = require('../../packages/remark-parse/lib/defaults.js') +var stringifyDefaults = require('../../packages/remark-stringify/lib/defaults.js') -var own = {}.hasOwnProperty; -var read = fs.readFileSync; -var exists = fs.existsSync; -var stat = fs.statSync; -var join = path.join; +var own = {}.hasOwnProperty +var read = fs.readFileSync +var exists = fs.existsSync +var stat = fs.statSync +var join = path.join var defaults = { parse: parseDefaults, stringify: stringifyDefaults -}; +} var typeMap = { true: 'all', false: 'physical' -}; - -var TYPE = typeMap[Boolean(process.env.TEST_EXTENDED)]; - -/* Defaults. */ -var keys = Object.keys(defaults.parse); -keys.splice(keys.indexOf('blocks'), 1); - -/* Create a single source with all parse options turned - * to their default values. */ -var sources = [keys.join('.')]; - -/* Create all possible `parse` values. */ -keys.forEach(function (key) { - sources = [].concat.apply(sources, sources.map(function (source) { - return source.split('.').map(function (subkey) { - return subkey === key ? 'no' + key : subkey; - }).join('.'); - })); -}); +} -/* Parse a `string` `value` into a javascript value. */ +var TYPE = typeMap[Boolean(process.env.TEST_EXTENDED)] + +// Defaults. +var keys = Object.keys(defaults.parse) +keys.splice(keys.indexOf('blocks'), 1) + +// Create a single source with all parse options turned to their default values. +var sources = [keys.join('.')] + +// Create all possible `parse` values. +keys.forEach(function(key) { + sources = [].concat.apply( + sources, + sources.map(function(source) { + return source + .split('.') + .map(function(subkey) { + return subkey === key ? 'no' + key : subkey + }) + .join('.') + }) + ) +}) + +// Parse a `string` `value` into a javascript value. function augment(key, value) { if (!value) { - value = key.slice(0, 2) !== 'no'; + value = key.slice(0, 2) !== 'no' if (!value) { - key = key.slice(2); + key = key.slice(2) } } - key = camelcase(key); + key = camelcase(key) if (own.call(augment, key)) { - value = augment[key](value); + value = augment[key](value) } - return {key: key, value: value}; + return {key: key, value: value} } -augment.ruleRepetition = Number; +augment.ruleRepetition = Number -/* Parse options from a filename. */ +// Parse options from a filename. function parseOptions(name) { - var index = -1; - var parts = name.split('.'); - var results = []; - var length = parts.length; - var options = clone(defaults); - var part; - var augmented; - var key; - var value; + var index = -1 + var parts = name.split('.') + var results = [] + var length = parts.length + var options = clone(defaults) + var part + var augmented + var key + var value while (++index < length) { - part = parts[index].split('='); - augmented = augment(part[0], part.slice(1).join('=')); - key = augmented.key; - value = augmented.value; + part = parts[index].split('=') + augmented = augment(part[0], part.slice(1).join('=')) + key = augmented.key + value = augmented.value if (key === 'output') { - options[key] = value; + options[key] = value } else { if (key in defaults.parse && value !== options.parse[key]) { - options.parse[key] = value; + options.parse[key] = value - results.push(parts[index]); + results.push(parts[index]) } - if ( - key in defaults.stringify && - value !== options.stringify[key] - ) { - options.stringify[key] = value; + if (key in defaults.stringify && value !== options.stringify[key]) { + options.stringify[key] = value // Protect common options from `parse` and `stringify` from // appearing twice. if (results.indexOf(parts[index]) < 0) { - results.push(parts[index]); + results.push(parts[index]) } } } } - options.source = results.join('.'); + options.source = results.join('.') - return options; + return options } -/* Cache all possible options. - * - * Virtual options are generated when no fixtures exist, - * whereas physical options are only used whn a file - * exists. */ -var virtual = {}; -var physical = {}; -var all = {}; +// Cache all possible options. +// +// Virtual options are generated when no fixtures exist, whereas physical +// options are only used whn a file exists. +var virtual = {} +var physical = {} +var all = {} -sources.forEach(function (source) { - var options = parseOptions(source); +sources.forEach(function(source) { + var options = parseOptions(source) - source = options.source; + source = options.source - /* `position` and `blocks` are such a tiny feature, but result in lots of - * duplicate fixtures, that I've ignored it for the virtual options. */ + // `position` and `blocks` are such a tiny feature, but result in lots of + // duplicate fixtures, that I've ignored it for the virtual options. if ( options.parse.position !== defaults.parse.position || options.parse.blocks !== defaults.parse.blocks ) { - physical[source] = options.parse; + physical[source] = options.parse } else { - virtual[source] = options.parse; + virtual[source] = options.parse } - all[source] = options.parse; -}); + all[source] = options.parse +}) -/* Get the difference between two objects. Greatly - * simplified because `options` and `compate` consist - * solely of booleans, and all properties exist in - * both. */ +// Get the difference between two objects. Greatly simplified because `options` +// and `compate` consist solely of booleans, and all properties exist in both. function difference(options, compare) { - var count = 0; + var count = 0 - Object.keys(options).forEach(function (key) { + Object.keys(options).forEach(function(key) { if (options[key] !== compare[key]) { - count++; + count++ } - }); + }) - return count; + return count } -/* Find the closest fixture for a `source` in all - * `fixtures`. Returns a key of a fixture. */ +// Find the closest fixture for a `source` in all `fixtures`. Returns a key of +// a fixture. function resolveFixture(source, fixtures, options) { - var minimum = Infinity; - var resolved; - var offset; + var minimum = Infinity + var resolved + var offset - Object.keys(fixtures).forEach(function (key) { - offset = difference(options[source], options[key]); + Object.keys(fixtures).forEach(function(key) { + offset = difference(options[source], options[key]) if (offset < minimum) { - minimum = offset; - resolved = key; + minimum = offset + resolved = key } - }); + }) - return resolved; + return resolved } -/* Find the closest fixture for all `options`. Returns - * an object mapping options sources to fixture names. */ +// Find the closest fixture for all `options`. Returns an object mapping +// options sources to fixture names. function resolveFixtures(fixtures, options) { - var resolved = {}; + var resolved = {} - Object.keys(options).forEach(function (source) { - resolved[source] = resolveFixture(source, fixtures, options); - }); + Object.keys(options).forEach(function(source) { + resolved[source] = resolveFixture(source, fixtures, options) + }) - return resolved; + return resolved } -/* Gather fixtures. */ +// Gather fixtures. var tests = fs .readdirSync(join(__dirname, 'input')) - .filter(function (filepath) { - return filepath.indexOf('.') !== 0; + .filter(function(filepath) { + return filepath.indexOf('.') !== 0 }) - .map(function (filepath) { - var filename = filepath.split('.').slice(0, -1); - var name = filename.join('.').replace(/-asterisk-/g, '*'); - var settings = parseOptions(name); - var input = read(join(__dirname, 'input', filepath), 'utf-8'); - var fixtures = {}; - var possibilities = {}; - var resolved; - - Object.keys(all).forEach(function (source) { - var treename; - var tree; - - treename = [ - filename.join('.'), - source ? '.' + source : '', - '.json' - ].join(''); - - tree = join(__dirname, 'tree', treename); + .map(function(filepath) { + var filename = filepath.split('.').slice(0, -1) + var name = filename.join('.').replace(/-asterisk-/g, '*') + var settings = parseOptions(name) + var input = read(join(__dirname, 'input', filepath), 'utf-8') + var fixtures = {} + var possibilities = {} + var resolved + + Object.keys(all).forEach(function(source) { + var treename + var tree + + treename = [filename.join('.'), source ? '.' + source : '', '.json'].join( + '' + ) + + tree = join(__dirname, 'tree', treename) if (exists(tree)) { - fixtures[source] = JSON.parse(read(tree, 'utf-8')); + fixtures[source] = JSON.parse(read(tree, 'utf-8')) - possibilities[source] = all[source]; + possibilities[source] = all[source] } else if ( TYPE === typeMap.true && source in virtual && !settings.output ) { - possibilities[source] = all[source]; + possibilities[source] = all[source] } - }); + }) if (Object.keys(fixtures).length === 0) { - throw new Error('Missing fixture for `' + name + '`'); + throw new Error('Missing fixture for `' + name + '`') } - resolved = resolveFixtures(fixtures, possibilities); + resolved = resolveFixtures(fixtures, possibilities) if (settings.output) { if (Object.keys(fixtures).length > 1) { - throw new Error( - 'Multiple fixtures for output `' + name + '`' - ); + throw new Error('Multiple fixtures for output `' + name + '`') } } @@ -248,8 +243,7 @@ var tests = fs output: settings.output, size: stat(join(__dirname, 'input', filepath)).size, name: name - }; - }); + } + }) -/* Expose tests. */ -module.exports = tests; +module.exports = tests diff --git a/test/fixtures/tree/links-title-parentheses.commonmark.pedantic.json b/test/fixtures/tree/links-title-parentheses.commonmark.pedantic.json new file mode 100644 index 000000000..399b1522e --- /dev/null +++ b/test/fixtures/tree/links-title-parentheses.commonmark.pedantic.json @@ -0,0 +1,269 @@ +{ + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": "Hello World!", + "url": "./world.html", + "children": [ + { + "type": "text", + "value": "Hello", + "position": { + "start": { + "line": 1, + "column": 2, + "offset": 1 + }, + "end": { + "line": 1, + "column": 7, + "offset": 6 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 37, + "offset": 36 + }, + "indent": [] + } + }, + { + "type": "text", + "value": ".", + "position": { + "start": { + "line": 1, + "column": 37, + "offset": 36 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + }, + "indent": [] + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "link", + "title": "Hello World!", + "url": "./world.html", + "children": [ + { + "type": "text", + "value": "Hello", + "position": { + "start": { + "line": 3, + "column": 2, + "offset": 40 + }, + "end": { + "line": 3, + "column": 7, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 3, + "column": 1, + "offset": 39 + }, + "end": { + "line": 3, + "column": 39, + "offset": 77 + }, + "indent": [] + } + }, + { + "type": "text", + "value": ".", + "position": { + "start": { + "line": 3, + "column": 39, + "offset": 77 + }, + "end": { + "line": 3, + "column": 40, + "offset": 78 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 3, + "column": 1, + "offset": 39 + }, + "end": { + "line": 3, + "column": 40, + "offset": 78 + }, + "indent": [] + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "image", + "title": "Hello World!", + "url": "./world.html", + "alt": "Hello", + "position": { + "start": { + "line": 5, + "column": 1, + "offset": 80 + }, + "end": { + "line": 5, + "column": 38, + "offset": 117 + }, + "indent": [] + } + }, + { + "type": "text", + "value": ".", + "position": { + "start": { + "line": 5, + "column": 38, + "offset": 117 + }, + "end": { + "line": 5, + "column": 39, + "offset": 118 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 5, + "column": 1, + "offset": 80 + }, + "end": { + "line": 5, + "column": 39, + "offset": 118 + }, + "indent": [] + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "image", + "title": "Hello World!", + "url": "./world.html", + "alt": "Hello", + "position": { + "start": { + "line": 7, + "column": 1, + "offset": 120 + }, + "end": { + "line": 7, + "column": 40, + "offset": 159 + }, + "indent": [] + } + }, + { + "type": "text", + "value": ".", + "position": { + "start": { + "line": 7, + "column": 40, + "offset": 159 + }, + "end": { + "line": 7, + "column": 41, + "offset": 160 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 7, + "column": 1, + "offset": 120 + }, + "end": { + "line": 7, + "column": 41, + "offset": 160 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 8, + "column": 1, + "offset": 161 + } + } +} diff --git a/test/index.js b/test/index.js index d6db598e9..2492a768a 100644 --- a/test/index.js +++ b/test/index.js @@ -1,4 +1,4 @@ -'use strict'; +'use strict' -require('./api'); -require('./cli'); +require('./api') +require('./cli') diff --git a/test/remark-parse.js b/test/remark-parse.js index efd9e494f..a8821d61c 100644 --- a/test/remark-parse.js +++ b/test/remark-parse.js @@ -1,213 +1,220 @@ -'use strict'; +'use strict' -var path = require('path'); -var fs = require('fs'); -var test = require('tape'); -var vfile = require('vfile'); -var remark = require('../packages/remark'); -var Parser = require('../packages/remark-parse').Parser; +var path = require('path') +var fs = require('fs') +var test = require('tape') +var vfile = require('vfile') +var remark = require('../packages/remark') +var Parser = require('../packages/remark-parse').Parser -test('remark().parse(file)', function (t) { +test('remark().parse(file)', function(t) { t.equal( remark().parse('Alfred').children.length, 1, 'should accept a `string`' - ); + ) t.throws( - function () { - remark().data('settings', {position: 0}).parse(''); + function() { + remark() + .data('settings', {position: 0}) + .parse('') }, /options.position/, 'should throw when `options.position` is not a boolean' - ); + ) - t.doesNotThrow( - function () { - var parser = new Parser(); - parser.setOptions(); - }, - 'should not throw when setting nothing' - ); + t.doesNotThrow(function() { + var parser = new Parser() + parser.setOptions() + }, 'should not throw when setting nothing') t.throws( - function () { - var parser = new Parser(); - parser.setOptions(true); + function() { + var parser = new Parser() + parser.setOptions(true) }, /^Error: Invalid value `true` for setting `options`$/, 'should throw when setting invalid values' - ); + ) t.throws( - function () { - remark().data('settings', {gfm: Infinity}).parse(''); + function() { + remark() + .data('settings', {gfm: Infinity}) + .parse('') }, /options.gfm/, 'should throw when `options.gfm` is not a boolean' - ); + ) t.throws( - function () { - remark().data('settings', {footnotes: 1}).parse(''); + function() { + remark() + .data('settings', {footnotes: 1}) + .parse('') }, /options.footnotes/, 'should throw when `options.footnotes` is not a boolean' - ); + ) t.throws( - function () { - remark().data('settings', {pedantic: {}}).parse(''); + function() { + remark() + .data('settings', {pedantic: {}}) + .parse('') }, /options.pedantic/, 'should throw when `options.pedantic` is not a boolean' - ); + ) t.deepEqual( - remark().data('settings', {position: false}).parse(''), + remark() + .data('settings', {position: false}) + .parse(''), { type: 'root', - children: [{ - type: 'paragraph', - children: [ - {type: 'html', value: ''}, - {type: 'html', value: ''} - ] - }] + children: [ + { + type: 'paragraph', + children: [ + {type: 'html', value: ''}, + {type: 'html', value: ''} + ] + } + ] }, 'should work without `blocks`' - ); + ) t.deepEqual( - remark().data('settings', {position: false, blocks: ['foo']}).parse(''), + remark() + .data('settings', {position: false, blocks: ['foo']}) + .parse(''), { type: 'root', children: [{type: 'html', value: ''}] }, 'should support given `blocks`' - ); + ) - t.test('should throw parse errors', function (st) { - var processor = remark().use(plugin); + t.test('should throw parse errors', function(st) { + var processor = remark().use(plugin) - st.plan(5); + st.plan(5) try { - processor.parse('Hello *World*!'); + processor.parse('Hello *World*!') } catch (error) { - st.equal(error.file, '', 'should pass a filename'); - st.equal(error.line, 1, 'should set `line`'); - st.equal(error.column, 7, 'should set `column`'); - st.equal(error.reason, 'Found it!', 'should set `reason`'); - st.equal(error.toString(), '1:7: Found it!', 'should set `message`'); + st.equal(error.file, '', 'should pass a filename') + st.equal(error.line, 1, 'should set `line`') + st.equal(error.column, 7, 'should set `column`') + st.equal(error.reason, 'Found it!', 'should set `reason`') + st.equal(error.toString(), '1:7: Found it!', 'should set `message`') } function plugin() { - emphasis.locator = locator; - this.Parser.prototype.inlineTokenizers.emphasis = emphasis; + emphasis.locator = locator + this.Parser.prototype.inlineTokenizers.emphasis = emphasis function emphasis(eat, value) { if (value.charAt(0) === '*') { - eat.file.fail('Found it!', eat.now()); + eat.file.fail('Found it!', eat.now()) } } function locator(value, fromIndex) { - return value.indexOf('*', fromIndex); + return value.indexOf('*', fromIndex) } } - }); + }) - t.test('should warn when missing locators', function (st) { - var processor = remark().use(plugin); + t.test('should warn when missing locators', function(st) { + var processor = remark().use(plugin) - st.throws( - function () { - processor.parse(vfile('Hello *World*!')); - }, - /1:1: Missing locator: `foo`/ - ); + st.throws(function() { + processor.parse(vfile('Hello *World*!')) + }, /1:1: Missing locator: `foo`/) - st.end(); + st.end() function plugin() { - var proto = this.Parser.prototype; - var methods = proto.inlineMethods; + var proto = this.Parser.prototype + var methods = proto.inlineMethods - /* Tokenizer. */ + // Tokenizer. function noop() {} - proto.inlineTokenizers.foo = noop; - methods.splice(methods.indexOf('inlineText'), 0, 'foo'); + proto.inlineTokenizers.foo = noop + methods.splice(methods.indexOf('inlineText'), 0, 'foo') } - }); - - t.test('should warn about entities', function (st) { - var filePath = path.join('test', 'fixtures', 'input', 'entities-advanced.text'); - var file = vfile(fs.readFileSync(filePath)); - var notTerminated = 'Named character references must be ' + - 'terminated by a semicolon'; - - remark().parse(file); - - st.deepEqual( - file.messages.map(String), - [ - '1:13: Named character references must be known', - '5:15: ' + notTerminated, - '9:44: ' + notTerminated, - '11:38: ' + notTerminated, - '14:37: ' + notTerminated, - '13:16: ' + notTerminated, - '18:21: ' + notTerminated, - '16:16: ' + notTerminated, - '23:37: ' + notTerminated, - '21:11: ' + notTerminated, - '29:21: ' + notTerminated, - '27:17: ' + notTerminated, - '32:11: ' + notTerminated, - '35:27: ' + notTerminated, - '36:10: ' + notTerminated, - '40:25: ' + notTerminated, - '41:10: ' + notTerminated - ] - ); - - st.end(); - }); - - t.test('should be able to set options', function (st) { - var tree = remark().use(plugin).parse([ - '', - '', - '1) Hello World', - '' - ].join('\n')); - - st.equal(tree.children[1].type, 'list'); - - st.end(); + }) + + t.test('should warn about entities', function(st) { + var filePath = path.join( + 'test', + 'fixtures', + 'input', + 'entities-advanced.text' + ) + var file = vfile(fs.readFileSync(filePath)) + var notTerminated = + 'Named character references must be terminated by a semicolon' + + remark().parse(file) + + st.deepEqual(file.messages.map(String), [ + '1:13: Named character references must be known', + '5:15: ' + notTerminated, + '9:44: ' + notTerminated, + '11:38: ' + notTerminated, + '14:37: ' + notTerminated, + '13:16: ' + notTerminated, + '18:21: ' + notTerminated, + '16:16: ' + notTerminated, + '23:37: ' + notTerminated, + '21:11: ' + notTerminated, + '29:21: ' + notTerminated, + '27:17: ' + notTerminated, + '32:11: ' + notTerminated, + '35:27: ' + notTerminated, + '36:10: ' + notTerminated, + '40:25: ' + notTerminated, + '41:10: ' + notTerminated + ]) + + st.end() + }) + + t.test('should be able to set options', function(st) { + var tree = remark() + .use(plugin) + .parse(['', '', '1) Hello World', ''].join('\n')) + + st.equal(tree.children[1].type, 'list') + + st.end() function plugin() { - var html = this.Parser.prototype.blockTokenizers.html; + var html = this.Parser.prototype.blockTokenizers.html - this.Parser.prototype.blockTokenizers.html = replacement; + this.Parser.prototype.blockTokenizers.html = replacement - /* Set option when an HMTL comment occurs. */ + // Set option when an HMTL comment occurs. function replacement(eat, value) { - var node = //g.exec(value); - var options = {}; + var node = //g.exec(value) + var options = {} if (node) { - options[node[1]] = true; + options[node[1]] = true - this.setOptions(options); + this.setOptions(options) } - return html.apply(this, arguments); + return html.apply(this, arguments) } } - }); + }) - t.end(); -}); + t.end() +}) diff --git a/test/remark-process.js b/test/remark-process.js index 80edc74e2..ad2fd5210 100644 --- a/test/remark-process.js +++ b/test/remark-process.js @@ -1,39 +1,44 @@ -'use strict'; +'use strict' -var test = require('tape'); -var remark = require('../packages/remark'); +var test = require('tape') +var remark = require('../packages/remark') -test('remark().processSync(value)', function (t) { +test('remark().processSync(value)', function(t) { t.equal( - remark().processSync('*foo*').toString(), + remark() + .processSync('*foo*') + .toString(), '_foo_\n', 'should parse and stringify a file' - ); + ) t.equal( - remark().data('settings', {commonmark: true}).processSync('1) foo').toString(), + remark() + .data('settings', {commonmark: true}) + .processSync('1) foo') + .toString(), '1. foo\n', 'should accept parse options' - ); + ) t.equal( - remark().data('settings', {closeAtx: true}).processSync('# foo').toString(), + remark() + .data('settings', {closeAtx: true}) + .processSync('# foo') + .toString(), '# foo #\n', 'should accept stringify options' - ); + ) t.throws( - function () { - remark().data('settings', {pedantic: true, listItemIndent: '1'}).processSync([ - '* List', - '', - ' code()' - ].join('\n')); + function() { + remark() + .data('settings', {pedantic: true, listItemIndent: '1'}) + .processSync(['* List', '', ' code()'].join('\n')) }, /Cannot indent code properly. See http:\/\/git.io\/vgFvT/, - 'should throw when `pedantic` is `true`, `listItemIndent` ' + - 'is not `tab`, and compiling code in a list-item' - ); + 'should throw when `pedantic` is `true`, `listItemIndent` is not `tab`, and compiling code in a list-item' + ) - t.end(); -}); + t.end() +}) diff --git a/test/remark-stringify-escapes.js b/test/remark-stringify-escapes.js index df53274d1..2f0fbaf16 100644 --- a/test/remark-stringify-escapes.js +++ b/test/remark-stringify-escapes.js @@ -1,208 +1,444 @@ -'use strict'; - -var test = require('tape'); -var u = require('unist-builder'); -var visit = require('unist-util-visit'); -var remark = require('../packages/remark'); - -var commonmark = {commonmark: true}; -var pedantic = {pedantic: true}; -var uncollapsable = {start: {line: 1, column: NaN}, end: {line: 1, column: NaN}}; - -test('stringify escapes', function (t) { - t.equal(stringify('a\\b'), 'a\\\\b', '`\\`'); - t.equal(stringify('a`b'), 'a\\`b', '`` ` ``'); - t.equal(stringify('a*b'), 'a\\*b', '`*`'); - t.equal(stringify('a[b'), 'a\\[b', '`[`'); - t.equal(stringify('a)', '`]` (in links)' - ); + ) t.equal( stringify(u('image', {alt: 'a]b'})), '![a\\]b](<>)', '`]` (in images)' - ); + ) - t.equal(stringify('a~b'), 'a~b', '`~`'); - t.equal(stringify('a~~b'), 'a\\~~b', '`~~`'); + t.equal(stringify('a~b'), 'a~b', '`~`') + t.equal(stringify('a~~b'), 'a\\~~b', '`~~`') - t.equal(stringify('a|b'), 'a|b', '`|`'); - t.equal(stringify('| -- |'), '\\| -- \\|', '`|` (table-like)'); + t.equal(stringify('a|b'), 'a|b', '`|`') + t.equal(stringify('| -- |'), '\\| -- \\|', '`|` (table-like)') t.equal( - stringify(u('table', [ - u('tableRow', [u('tableCell', [u('text', 'a|b')])]) - ])), + stringify( + u('table', [u('tableRow', [u('tableCell', [u('text', 'a|b')])])]) + ), '| a\\|b |\n| ---- |', '`|` (in cells)' - ); - - t.equal(stringify('a_b'), 'a_b', '`_` (in words)'); - t.equal(stringify('a_b', pedantic), 'a\\_b', '`_` (in words, pedantic)'); - t.equal(stringify(' _b'), ' \\_b', '`_` after `\\b`'); - t.equal(stringify('a_ '), 'a\\_ ', '`_` before `\\b`'); - - t.equal(stringify('a:b'), 'a:b', '`:`'); - t.equal(stringify('http:b'), 'http:b', '`:` (in `http:`)'); - t.equal(stringify('http:b', commonmark), 'http\\:b', '`:` (in `http:`, commonmark)'); - t.equal(stringify('https:b'), 'https:b', '`:` (in `https:`)'); - t.equal(stringify('https:b', commonmark), 'https\\:b', '`:` (in `https:`, commonmark)'); - t.equal(stringify('mailto:b'), 'mailto:b', '`:` (in `mailto:`)'); - t.equal(stringify('mailto:b', commonmark), 'mailto\\:b', '`:` (in `mailto:`, commonmark)'); - - t.equal(stringify('>a'), '\\>a', '`>` (without parent)'); - t.equal(stringify(u('paragraph', [u('text', '>a')])), '\\>a', '`>` (in paragraph)'); - t.equal(stringify(u('strong', [u('text', '>a')])), '**>a**', '`>` (in non-paragraph)'); - t.equal(stringify(u('strong', [u('text', 'a'), u('text', '>b')])), '**a>b**', '`>` (after sibling)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '>b')])), '**\n\\>b**', '`>` (after newline)'); - - t.equal(stringify('#a'), '\\#a', '`#` (without parent)'); - t.equal(stringify(u('paragraph', [u('text', '#a')])), '\\#a', '`#` (in paragraph)'); - t.equal(stringify(u('strong', [u('text', '#a')])), '**#a**', '`#` (in non-paragraph)'); - t.equal(stringify(u('strong', [u('text', 'a'), u('text', '#b')])), '**a#b**', '`#` (after sibling)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '#b')])), '**\n\\#b**', '`#` (after newline)'); - - /* Both bullet and emphasis marker. */ - t.equal(stringify('*a'), '\\*a', '`*` (without parent)'); - t.equal(stringify(u('paragraph', [u('text', '*a')])), '\\*a', '`*` (in paragraph)'); - t.equal(stringify(u('strong', [u('text', '*a')])), '**\\*a**', '`*` (in non-paragraph)'); - t.equal(stringify(u('strong', [u('text', 'a'), u('text', '*b')])), '**a\\*b**', '`*` (after sibling)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '*b')])), '**\n\\*b**', '`*` (after newline)'); - - t.equal(stringify('-a'), '\\-a', '`-` (without parent)'); - t.equal(stringify(u('paragraph', [u('text', '-a')])), '\\-a', '`-` (in paragraph)'); - t.equal(stringify(u('strong', [u('text', '-a')])), '**-a**', '`-` (in non-paragraph)'); - t.equal(stringify(u('strong', [u('text', 'a'), u('text', '-b')])), '**a-b**', '`-` (after sibling)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '-b')])), '**\n\\-b**', '`-` (after newline)'); - - t.equal(stringify('+a'), '\\+a', '`+` (without parent)'); - t.equal(stringify(u('paragraph', [u('text', '+a')])), '\\+a', '`+` (in paragraph)'); - t.equal(stringify(u('strong', [u('text', '+a')])), '**+a**', '`+` (in non-paragraph)'); - t.equal(stringify(u('strong', [u('text', 'a'), u('text', '+b')])), '**a+b**', '`+` (after sibling)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '+b')])), '**\n\\+b**', '`+` (after newline)'); - - t.equal(stringify('.a'), '.a', '`.`'); - t.equal(stringify('1.a'), '1.a', '`.` (without parent, without space)'); - t.equal(stringify('1. '), '1\\. ', '`.` (without parent, with space)'); - t.equal(stringify('1.\t'), '1\\.\t', '`.` (without parent, with tab)'); - t.equal(stringify('1.\n'), '1\\.\n', '`.` (without parent, with newline)'); - t.equal(stringify('1.'), '1\\.', '`.` (without parent, with EOF)'); - t.equal(stringify(u('paragraph', [u('text', '1.a')])), '1.a', '`1.` (in paragraph, without space)'); - t.equal(stringify(u('paragraph', [u('text', '1. ')])), '1\\. ', '`1.` (in paragraph, with space)'); - t.equal(stringify(u('paragraph', [u('text', '1.\t')])), '1\\.\t', '`1.` (in paragraph, with tab)'); - t.equal(stringify(u('paragraph', [u('text', '1.\n')])), '1\\.\n', '`1.` (in paragraph, with newline)'); - t.equal(stringify(u('paragraph', [u('text', '1.')])), '1\\.', '`1.` (in paragraph, with EOF)'); - t.equal(stringify(u('strong', [u('text', '1.a')])), '**1.a**', '`1.` (in non-paragraph)'); - t.equal(stringify(u('strong', [u('text', 'a'), u('text', '1.b')])), '**a1.b**', '`1.` (after sibling)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '1.b')])), '**\n1.b**', '`1.` (after newline)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '1. ')])), '**\n1\\. **', '`1.` (after newline, with space)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '1.\t')])), '**\n1\\.\t**', '`1.` (after newline, with tab)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '1.\n')])), '**\n1\\.\n**', '`1.` (after newline, with newline)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '1.')])), '**\n1\\.**', '`1.` (after newline, with EOL)'); - - t.equal(stringify(')a'), ')a', '`)`'); - t.equal(stringify('1)a'), '1)a', '`)` (default)'); - t.equal(stringify('1)a', commonmark), '1)a', '`)` (commonmark, without parent)'); - t.equal(stringify('1) ', commonmark), '1\\) ', '`)` (commonmark, without parent, with space)'); - t.equal(stringify('1)\t', commonmark), '1\\)\t', '`)` (commonmark, without parent, with tab)'); - t.equal(stringify('1)\n', commonmark), '1\\)\n', '`)` (commonmark, without parent, with newline)'); - t.equal(stringify('1)', commonmark), '1\\)', '`)` (commonmark, without parent, with EOL)'); - t.equal(stringify(u('paragraph', [u('text', '1)a')]), commonmark), '1)a', '`1)` (in paragraph)'); - t.equal(stringify(u('paragraph', [u('text', '1) ')]), commonmark), '1\\) ', '`1)` (in paragraph, with space)'); - t.equal(stringify(u('paragraph', [u('text', '1)\t')]), commonmark), '1\\)\t', '`1)` (in paragraph, with tab)'); - t.equal(stringify(u('paragraph', [u('text', '1)\n')]), commonmark), '1\\)\n', '`1)` (in paragraph, with newline)'); - t.equal(stringify(u('paragraph', [u('text', '1)')]), commonmark), '1\\)', '`1)` (in paragraph, with EOL)'); - t.equal(stringify(u('strong', [u('text', '1)a')]), commonmark), '**1)a**', '`1)` (in non-paragraph)'); - t.equal(stringify(u('strong', [u('text', 'a'), u('text', '1)b')]), commonmark), '**a1)b**', '`1)` (after sibling)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '1)b')]), commonmark), '**\n1)b**', '`1)` (after newline)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '1) ')]), commonmark), '**\n1\\) **', '`1)` (after newline, with space)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '1)\t')]), commonmark), '**\n1\\)\t**', '`1)` (after newline, with tab)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '1)\n')]), commonmark), '**\n1\\)\n**', '`1)` (after newline, with newline)'); - t.equal(stringify(u('strong', [u('text', '\n'), u('text', '1)')]), commonmark), '**\n1\\)**', '`1)` (after newline, with EOL)'); - - t.equal( - stringify(u('paragraph', [ - u('linkReference', { - identifier: 'foo', - referenceType: 'shortcut' - }, [u('text', 'a')]), - u('text', '(b') - ])), + ) + + t.equal(stringify('a_b'), 'a_b', '`_` (in words)') + t.equal(stringify('a_b', pedantic), 'a\\_b', '`_` (in words, pedantic)') + t.equal(stringify(' _b'), ' \\_b', '`_` after `\\b`') + t.equal(stringify('a_ '), 'a\\_ ', '`_` before `\\b`') + + t.equal(stringify('a:b'), 'a:b', '`:`') + t.equal(stringify('http:b'), 'http:b', '`:` (in `http:`)') + t.equal( + stringify('http:b', commonmark), + 'http\\:b', + '`:` (in `http:`, commonmark)' + ) + t.equal(stringify('https:b'), 'https:b', '`:` (in `https:`)') + t.equal( + stringify('https:b', commonmark), + 'https\\:b', + '`:` (in `https:`, commonmark)' + ) + t.equal(stringify('mailto:b'), 'mailto:b', '`:` (in `mailto:`)') + t.equal( + stringify('mailto:b', commonmark), + 'mailto\\:b', + '`:` (in `mailto:`, commonmark)' + ) + + t.equal(stringify('>a'), '\\>a', '`>` (without parent)') + t.equal( + stringify(u('paragraph', [u('text', '>a')])), + '\\>a', + '`>` (in paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', '>a')])), + '**>a**', + '`>` (in non-paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', 'a'), u('text', '>b')])), + '**a>b**', + '`>` (after sibling)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '>b')])), + '**\n\\>b**', + '`>` (after newline)' + ) + + t.equal(stringify('#a'), '\\#a', '`#` (without parent)') + t.equal( + stringify(u('paragraph', [u('text', '#a')])), + '\\#a', + '`#` (in paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', '#a')])), + '**#a**', + '`#` (in non-paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', 'a'), u('text', '#b')])), + '**a#b**', + '`#` (after sibling)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '#b')])), + '**\n\\#b**', + '`#` (after newline)' + ) + + // Both bullet and emphasis marker. + t.equal(stringify('*a'), '\\*a', '`*` (without parent)') + t.equal( + stringify(u('paragraph', [u('text', '*a')])), + '\\*a', + '`*` (in paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', '*a')])), + '**\\*a**', + '`*` (in non-paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', 'a'), u('text', '*b')])), + '**a\\*b**', + '`*` (after sibling)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '*b')])), + '**\n\\*b**', + '`*` (after newline)' + ) + + t.equal(stringify('-a'), '\\-a', '`-` (without parent)') + t.equal( + stringify(u('paragraph', [u('text', '-a')])), + '\\-a', + '`-` (in paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', '-a')])), + '**-a**', + '`-` (in non-paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', 'a'), u('text', '-b')])), + '**a-b**', + '`-` (after sibling)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '-b')])), + '**\n\\-b**', + '`-` (after newline)' + ) + + t.equal(stringify('+a'), '\\+a', '`+` (without parent)') + t.equal( + stringify(u('paragraph', [u('text', '+a')])), + '\\+a', + '`+` (in paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', '+a')])), + '**+a**', + '`+` (in non-paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', 'a'), u('text', '+b')])), + '**a+b**', + '`+` (after sibling)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '+b')])), + '**\n\\+b**', + '`+` (after newline)' + ) + + t.equal(stringify('.a'), '.a', '`.`') + t.equal(stringify('1.a'), '1.a', '`.` (without parent, without space)') + t.equal(stringify('1. '), '1\\. ', '`.` (without parent, with space)') + t.equal(stringify('1.\t'), '1\\.\t', '`.` (without parent, with tab)') + t.equal(stringify('1.\n'), '1\\.\n', '`.` (without parent, with newline)') + t.equal(stringify('1.'), '1\\.', '`.` (without parent, with EOF)') + t.equal( + stringify(u('paragraph', [u('text', '1.a')])), + '1.a', + '`1.` (in paragraph, without space)' + ) + t.equal( + stringify(u('paragraph', [u('text', '1. ')])), + '1\\. ', + '`1.` (in paragraph, with space)' + ) + t.equal( + stringify(u('paragraph', [u('text', '1.\t')])), + '1\\.\t', + '`1.` (in paragraph, with tab)' + ) + t.equal( + stringify(u('paragraph', [u('text', '1.\n')])), + '1\\.\n', + '`1.` (in paragraph, with newline)' + ) + t.equal( + stringify(u('paragraph', [u('text', '1.')])), + '1\\.', + '`1.` (in paragraph, with EOF)' + ) + t.equal( + stringify(u('strong', [u('text', '1.a')])), + '**1.a**', + '`1.` (in non-paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', 'a'), u('text', '1.b')])), + '**a1.b**', + '`1.` (after sibling)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '1.b')])), + '**\n1.b**', + '`1.` (after newline)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '1. ')])), + '**\n1\\. **', + '`1.` (after newline, with space)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '1.\t')])), + '**\n1\\.\t**', + '`1.` (after newline, with tab)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '1.\n')])), + '**\n1\\.\n**', + '`1.` (after newline, with newline)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '1.')])), + '**\n1\\.**', + '`1.` (after newline, with EOL)' + ) + + t.equal(stringify(')a'), ')a', '`)`') + t.equal(stringify('1)a'), '1)a', '`)` (default)') + t.equal( + stringify('1)a', commonmark), + '1)a', + '`)` (commonmark, without parent)' + ) + t.equal( + stringify('1) ', commonmark), + '1\\) ', + '`)` (commonmark, without parent, with space)' + ) + t.equal( + stringify('1)\t', commonmark), + '1\\)\t', + '`)` (commonmark, without parent, with tab)' + ) + t.equal( + stringify('1)\n', commonmark), + '1\\)\n', + '`)` (commonmark, without parent, with newline)' + ) + t.equal( + stringify('1)', commonmark), + '1\\)', + '`)` (commonmark, without parent, with EOL)' + ) + t.equal( + stringify(u('paragraph', [u('text', '1)a')]), commonmark), + '1)a', + '`1)` (in paragraph)' + ) + t.equal( + stringify(u('paragraph', [u('text', '1) ')]), commonmark), + '1\\) ', + '`1)` (in paragraph, with space)' + ) + t.equal( + stringify(u('paragraph', [u('text', '1)\t')]), commonmark), + '1\\)\t', + '`1)` (in paragraph, with tab)' + ) + t.equal( + stringify(u('paragraph', [u('text', '1)\n')]), commonmark), + '1\\)\n', + '`1)` (in paragraph, with newline)' + ) + t.equal( + stringify(u('paragraph', [u('text', '1)')]), commonmark), + '1\\)', + '`1)` (in paragraph, with EOL)' + ) + t.equal( + stringify(u('strong', [u('text', '1)a')]), commonmark), + '**1)a**', + '`1)` (in non-paragraph)' + ) + t.equal( + stringify(u('strong', [u('text', 'a'), u('text', '1)b')]), commonmark), + '**a1)b**', + '`1)` (after sibling)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '1)b')]), commonmark), + '**\n1)b**', + '`1)` (after newline)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '1) ')]), commonmark), + '**\n1\\) **', + '`1)` (after newline, with space)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '1)\t')]), commonmark), + '**\n1\\)\t**', + '`1)` (after newline, with tab)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '1)\n')]), commonmark), + '**\n1\\)\n**', + '`1)` (after newline, with newline)' + ) + t.equal( + stringify(u('strong', [u('text', '\n'), u('text', '1)')]), commonmark), + '**\n1\\)**', + '`1)` (after newline, with EOL)' + ) + + t.equal( + stringify( + u('paragraph', [ + u( + 'linkReference', + { + identifier: 'foo', + referenceType: 'shortcut' + }, + [u('text', 'a')] + ), + u('text', '(b') + ]) + ), '[a]\\(b', '`(` after shortcut link-reference' - ); + ) t.equal( - stringify(u('paragraph', [ - u('linkReference', { - identifier: 'foo', - referenceType: 'shortcut' - }, [u('text', 'a')]), - u('text', ' \t(b') - ])), + stringify( + u('paragraph', [ + u( + 'linkReference', + { + identifier: 'foo', + referenceType: 'shortcut' + }, + [u('text', 'a')] + ), + u('text', ' \t(b') + ]) + ), '[a] \t\\(b', '`(` after spaced shortcut link-reference' - ); + ) t.equal( - stringify(u('paragraph', [ - u('linkReference', { - identifier: 'foo', - referenceType: 'shortcut' - }, [u('text', 'a')]), - u('text', ':b') - ])), + stringify( + u('paragraph', [ + u( + 'linkReference', + { + identifier: 'foo', + referenceType: 'shortcut' + }, + [u('text', 'a')] + ), + u('text', ':b') + ]) + ), '[a]:b', '`:` after shortcut link-reference' - ); + ) t.equal( - stringify(u('paragraph', [ - u('linkReference', { - identifier: 'foo', - referenceType: 'shortcut' - }, [u('text', 'a')]), - u('text', ' \t:b') - ])), + stringify( + u('paragraph', [ + u( + 'linkReference', + { + identifier: 'foo', + referenceType: 'shortcut' + }, + [u('text', 'a')] + ), + u('text', ' \t:b') + ]) + ), '[a] \t:b', '`:` after spaced shortcut link-reference' - ); + ) t.equal( stringify(u('paragraph', [u('text', 'http'), u('text', ':')])), 'http:', '`:` with protocol in previous node' - ); + ) t.equal( stringify(u('paragraph', [u('text', '&'), u('text', 'amp;')])), '&amp;', '`&` with entity in next node' - ); + ) t.equal( stringify(u('paragraph', [u('text', 'a~'), u('text', '~b')])), 'a\\~~b', '`~~` split over two nodes' - ); + ) t.equal( stringify(u('paragraph', [u('text', 'a'), u('text', '_'), u('text', 'b')])), 'a_b', '`_` split over nodes' - ); + ) t.equal( stringify( @@ -211,41 +447,43 @@ test('stringify escapes', function (t) { ), 'a\\_b', '`_` split over nodes (pedantic)' - ); + ) t.equal( stringify(u('paragraph', [u('text', ' '), u('text', '_'), u('text', 'b')])), ' \\_b', '`_` split over nodes (no word character before)' - ); + ) t.equal( stringify(u('paragraph', [u('text', ' _'), u('text', 'b')])), ' \\_b', '`_` split over nodes (no word character before, #2)' - ); + ) t.equal( stringify(u('paragraph', [u('text', 'a'), u('text', '_'), u('text', ' ')])), 'a\\_ ', '`_` split over nodes (no word character after)' - ); + ) t.equal( stringify(u('paragraph', [u('text', 'a'), u('text', '_ ')])), 'a\\_ ', '`_` split over nodes (no word character after, #2)' - ); + ) - t.end(); -}); + t.end() +}) function stringify(value, options) { - var tree = typeof value === 'string' ? u('text', value) : value; + var tree = typeof value === 'string' ? u('text', value) : value - visit(tree, function (node) { - node.position = uncollapsable; - }); + visit(tree, function(node) { + node.position = uncollapsable + }) - return remark().data('settings', options || {}).stringify(tree); + return remark() + .data('settings', options || {}) + .stringify(tree) } diff --git a/test/remark-stringify.js b/test/remark-stringify.js index 792f29670..17993a48b 100644 --- a/test/remark-stringify.js +++ b/test/remark-stringify.js @@ -1,265 +1,306 @@ -'use strict'; +'use strict' -var test = require('tape'); -var wcwidth = require('wcwidth'); -var remark = require('../packages/remark'); -var Compiler = require('../packages/remark-stringify').Compiler; +var test = require('tape') +var wcwidth = require('wcwidth') +var remark = require('../packages/remark') +var Compiler = require('../packages/remark-stringify').Compiler function empty() { - return {type: 'root', children: []}; + return {type: 'root', children: []} } -test('remark().stringify(ast, file)', function (t) { +test('remark().stringify(ast, file)', function(t) { t.throws( - function () { - remark().stringify(false); + function() { + remark().stringify(false) }, /false/, 'should throw when `ast` is not an object' - ); + ) - t.doesNotThrow( - function () { - var compiler = new Compiler(); - compiler.setOptions(); - }, - 'should not throw when setting nothing' - ); + t.doesNotThrow(function() { + var compiler = new Compiler() + compiler.setOptions() + }, 'should not throw when setting nothing') t.throws( - function () { - var compiler = new Compiler(); - compiler.setOptions(true); + function() { + var compiler = new Compiler() + compiler.setOptions(true) }, /^Error: Invalid value `true` for setting `options`$/, 'should throw when setting invalid values' - ); - - t.test('should ignore nully numbers', function (st) { - var compiler = new Compiler(); - compiler.setOptions({ruleRepetition: null}); - st.equal(compiler.options.ruleRepetition, 3); - st.end(); - }); - - t.test('should ignore nully strings', function (st) { - var compiler = new Compiler(); - compiler.setOptions({listItemIndent: null}); - st.equal(compiler.options.listItemIndent, 'tab'); - st.end(); - }); + ) + + t.test('should ignore nully numbers', function(st) { + var compiler = new Compiler() + compiler.setOptions({ruleRepetition: null}) + st.equal(compiler.options.ruleRepetition, 3) + st.end() + }) + + t.test('should ignore nully strings', function(st) { + var compiler = new Compiler() + compiler.setOptions({listItemIndent: null}) + st.equal(compiler.options.listItemIndent, 'tab') + st.end() + }) t.throws( - function () { - remark().stringify({type: 'unicorn'}); + function() { + remark().stringify({type: 'unicorn'}) }, /unicorn/, 'should throw when `ast` is not a valid node' - ); + ) t.throws( - function () { - remark().data('settings', {bullet: true}).stringify(empty()); + function() { + remark() + .data('settings', {bullet: true}) + .stringify(empty()) }, /options\.bullet/, 'should throw when `options.bullet` is not a valid list bullet' - ); + ) t.throws( - function () { - remark().data('settings', {listItemIndent: 'foo'}).stringify(empty()); + function() { + remark() + .data('settings', {listItemIndent: 'foo'}) + .stringify(empty()) }, /options\.listItemIndent/, - 'should throw when `options.listItemIndent` is not a valid ' + - 'constant' - ); + 'should throw when `options.listItemIndent` is not a valid constant' + ) t.throws( - function () { - remark().data('settings', {rule: true}).stringify(empty()); + function() { + remark() + .data('settings', {rule: true}) + .stringify(empty()) }, /options\.rule/, - 'should throw when `options.rule` is not a valid ' + - 'horizontal rule bullet' - ); + 'should throw when `options.rule` is not a valid horizontal rule bullet' + ) t.throws( - function () { - remark().data('settings', {ruleSpaces: 1}).stringify(empty()); + function() { + remark() + .data('settings', {ruleSpaces: 1}) + .stringify(empty()) }, /options\.ruleSpaces/, 'should throw when `options.ruleSpaces` is not a boolean' - ); + ) t.throws( - function () { - remark().data('settings', {ruleRepetition: 1}).stringify(empty()); + function() { + remark() + .data('settings', {ruleRepetition: 1}) + .stringify(empty()) }, /options\.ruleRepetition/, 'should throw when `options.ruleRepetition` is too low' - ); + ) t.throws( - function () { - remark().data('settings', {ruleRepetition: NaN}).stringify(empty()); + function() { + remark() + .data('settings', {ruleRepetition: NaN}) + .stringify(empty()) }, /options\.ruleRepetition/, 'should throw when `options.ruleRepetition` is `NaN`' - ); + ) t.throws( - function () { - remark().data('settings', {ruleRepetition: true}).stringify(empty()); + function() { + remark() + .data('settings', {ruleRepetition: true}) + .stringify(empty()) }, /options\.ruleRepetition/, 'should throw when `options.ruleRepetition` is not a number' - ); + ) t.throws( - function () { - remark().data('settings', {emphasis: '-'}).stringify(empty()); + function() { + remark() + .data('settings', {emphasis: '-'}) + .stringify(empty()) }, /options\.emphasis/, - 'should throw when `options.emphasis` is not a ' + - 'valid emphasis marker' - ); + 'should throw when `options.emphasis` is not a valid emphasis marker' + ) t.throws( - function () { - remark().data('settings', {strong: '-'}).stringify(empty()); + function() { + remark() + .data('settings', {strong: '-'}) + .stringify(empty()) }, /options\.strong/, - 'should throw when `options.strong` is not a ' + - 'valid emphasis marker' - ); + 'should throw when `options.strong` is not a valid emphasis marker' + ) t.throws( - function () { - remark().data('settings', {setext: 0}).stringify(empty()); + function() { + remark() + .data('settings', {setext: 0}) + .stringify(empty()) }, /options\.setext/, 'should throw when `options.setext` is not a boolean' - ); + ) t.throws( - function () { - remark().data('settings', {incrementListMarker: -1}).stringify(empty()); + function() { + remark() + .data('settings', {incrementListMarker: -1}) + .stringify(empty()) }, /options\.incrementListMarker/, - 'should throw when `options.incrementListMarker` is not a ' + - 'boolean' - ); + 'should throw when `options.incrementListMarker` is not a boolean' + ) t.throws( - function () { - remark().data('settings', {fences: NaN}).stringify(empty()); + function() { + remark() + .data('settings', {fences: NaN}) + .stringify(empty()) }, /options\.fences/, 'should throw when `options.fences` is not a boolean' - ); + ) t.throws( - function () { - remark().data('settings', {fence: '-'}).stringify(empty()); + function() { + remark() + .data('settings', {fence: '-'}) + .stringify(empty()) }, /options\.fence/, - 'should throw when `options.fence` is not a ' + - 'valid fence marker' - ); + 'should throw when `options.fence` is not a valid fence marker' + ) t.throws( - function () { - remark().data('settings', {closeAtx: NaN}).stringify(empty()); + function() { + remark() + .data('settings', {closeAtx: NaN}) + .stringify(empty()) }, /options\.closeAtx/, 'should throw when `options.closeAtx` is not a boolean' - ); + ) t.throws( - function () { - remark().data('settings', {looseTable: '!'}).stringify(empty()); + function() { + remark() + .data('settings', {looseTable: '!'}) + .stringify(empty()) }, /options\.looseTable/, 'should throw when `options.looseTable` is not a boolean' - ); + ) t.throws( - function () { - remark().data('settings', {spacedTable: '?'}).stringify(empty()); + function() { + remark() + .data('settings', {spacedTable: '?'}) + .stringify(empty()) }, /options\.spacedTable/, 'should throw when `options.spacedTable` is not a boolean' - ); + ) t.throws( - function () { - remark().data('settings', {paddedTable: '.'}).stringify(empty()); + function() { + remark() + .data('settings', {paddedTable: '.'}) + .stringify(empty()) }, /options\.paddedTable/, 'should throw when `options.paddedTable` is not a boolean' - ); + ) t.throws( - function () { - remark().data('settings', {stringLength: 1}).stringify(empty()); + function() { + remark() + .data('settings', {stringLength: 1}) + .stringify(empty()) }, /options\.stringLength/, 'should throw when `options.stringLength` is not a function' - ); + ) - t.test('should handle underscores in emphasis in pedantic mode', function (st) { - st.plan(2); + t.test('should handle underscores in emphasis in pedantic mode', function( + st + ) { + st.plan(2) - var example = '*alpha_bravo*\n'; + var example = '*alpha_bravo*\n' - /* Without pedantic mode, emphasis always defaults to underscores */ + // Without pedantic mode, emphasis always defaults to underscores. st.equal( - remark().processSync(example).toString(), + remark() + .processSync(example) + .toString(), '_alpha_bravo_\n', 'baseline' - ); + ) - /* With pedantic mode, emphasis will default to asterisks if the text to be - * emphasized contains underscores - */ + // With pedantic mode, emphasis will default to asterisks if the text to be + // emphasized contains underscores. st.equal( - remark().use({settings: {pedantic: true}}).processSync(example).toString(), + remark() + .use({settings: {pedantic: true}}) + .processSync(example) + .toString(), '*alpha\\_bravo*\n', 'pedantic' - ); - }); + ) + }) - t.test('should support optional list fields', function (st) { + t.test('should support optional list fields', function(st) { st.equal( stringify({ type: 'list', - children: [{ - type: 'listItem', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'alpha'}] - }] - }] + children: [ + { + type: 'listItem', + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'alpha'}] + } + ] + } + ] }), '- alpha', 'no ordered, start, or spread' - ); + ) st.equal( stringify({ type: 'list', start: 2, - children: [{ - type: 'listItem', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'bravo'}] - }] - }] + children: [ + { + type: 'listItem', + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'bravo'}] + } + ] + } + ] }), '- bravo', 'start; no ordered or spread' - ); + ) st.equal( stringify({ @@ -268,39 +309,47 @@ test('remark().stringify(ast, file)', function (t) { children: [ { type: 'listItem', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'charlie'}] - }] + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'charlie'}] + } + ] }, { type: 'listItem', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'delta'}] - }] + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'delta'}] + } + ] } ] }), '- charlie\n\n- delta', 'spread; no ordered or start' - ); + ) st.equal( stringify({ type: 'list', ordered: true, - children: [{ - type: 'listItem', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'echo'}] - }] - }] + children: [ + { + type: 'listItem', + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'echo'}] + } + ] + } + ] }), '1. echo', 'ordered; no start or spread' - ); + ) st.equal( stringify({ @@ -310,23 +359,27 @@ test('remark().stringify(ast, file)', function (t) { children: [ { type: 'listItem', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'foxtrot'}] - }] + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'foxtrot'}] + } + ] }, { type: 'listItem', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'golf'}] - }] + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'golf'}] + } + ] } ] }), '1. foxtrot\n\n2. golf', 'ordered and spread; no start' - ); + ) st.equal( stringify({ @@ -337,32 +390,36 @@ test('remark().stringify(ast, file)', function (t) { children: [ { type: 'listItem', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'hotel'}] - }] + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'hotel'}] + } + ] }, { type: 'listItem', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'india'}] - }] + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'india'}] + } + ] } ] }), '3. hotel\n\n4. india', 'ordered, spread, and start' - ); + ) - st.end(); + st.end() function stringify(value) { - return String(remark().stringify(value)); + return String(remark().stringify(value)) } - }); + }) - t.test('should support optional list item fields', function (st) { + t.test('should support optional list item fields', function(st) { var children = [ { type: 'paragraph', @@ -370,98 +427,124 @@ test('remark().stringify(ast, file)', function (t) { }, { type: 'blockquote', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'bravo'}] - }] + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'bravo'}] + } + ] } - ]; + ] st.equal( stringify({type: 'listItem', children: children}), '- alpha\n\n > bravo', 'no checked or spread' - ); + ) st.equal( stringify({type: 'listItem', checked: true, children: children}), '- [x] alpha\n\n > bravo', 'checked; no spread' - ); + ) st.equal( stringify({type: 'listItem', spread: true, children: children}), '- alpha\n\n > bravo', 'spread: true; no checked' - ); + ) st.equal( stringify({type: 'listItem', spread: false, children: children}), '- alpha\n > bravo', 'spread: false; no checked' - ); + ) st.equal( - stringify({type: 'listItem', checked: false, spread: false, children: children}), + stringify({ + type: 'listItem', + checked: false, + spread: false, + children: children + }), '- [ ] alpha\n > bravo', 'spread and checked' - ); + ) - st.end(); + st.end() function stringify(value) { - return String(remark().stringify(value)); + return String(remark().stringify(value)) } - }); + }) - t.test('should support empty list items', function (st) { - st.equal( - stringify({type: 'listItem', children: []}), - '-', - 'no checked' - ); + t.test('should support empty list items', function(st) { + st.equal(stringify({type: 'listItem', children: []}), '-', 'no checked') st.equal( stringify({type: 'listItem', checked: true, children: []}), '- [x] ', 'checked' - ); + ) - st.end(); + st.end() function stringify(value) { - return String(remark().stringify(value)); + return String(remark().stringify(value)) } - }); - - t.test('emphasis in pedantic mode should support a variety of contained inline content', function (st) { - /* Data-driven tests in the format: [name, input, expected] */ - var tests = [ - ['words with asterisks', '*inner content*', '_inner content_\n'], - ['words with underscores', '_inner content_', '_inner content_\n'], - ['links', '*[](http://some_url.com)*', '*[](http://some_url.com)*\n'], - ['underscores inside asterisks', '*inner content _with_ emphasis*', '*inner content _with_ emphasis*\n'], - ['asterisks inside underscores', '_inner content *with* emphasis_', '*inner content _with_ emphasis*\n'], - ['images', '*![](http://some_url.com/img.jpg)*', '*![](http://some_url.com/img.jpg)*\n'], - ['inline code with asterisks', '*content `with` code*', '_content `with` code_\n'], - ['inline code with underscores', '_content `with` code_', '_content `with` code_\n'] - ]; - - st.plan(tests.length); - tests.forEach(function (test) { - st.equal( - remark() - .use({settings: {pedantic: true}}) - .processSync(test[1]) - .toString(), - test[2], - test[0] - ); - }); - }); + }) + + t.test( + 'emphasis in pedantic mode should support a variety of contained inline content', + function(st) { + // Data-driven tests in the format: [name, input, expected] + var tests = [ + ['words with asterisks', '*inner content*', '_inner content_\n'], + ['words with underscores', '_inner content_', '_inner content_\n'], + ['links', '*[](http://some_url.com)*', '*[](http://some_url.com)*\n'], + [ + 'underscores inside asterisks', + '*inner content _with_ emphasis*', + '*inner content _with_ emphasis*\n' + ], + [ + 'asterisks inside underscores', + '_inner content *with* emphasis_', + '*inner content _with_ emphasis*\n' + ], + [ + 'images', + '*![](http://some_url.com/img.jpg)*', + '*![](http://some_url.com/img.jpg)*\n' + ], + [ + 'inline code with asterisks', + '*content `with` code*', + '_content `with` code_\n' + ], + [ + 'inline code with underscores', + '_content `with` code_', + '_content `with` code_\n' + ] + ] + + st.plan(tests.length) + tests.forEach(function(test) { + st.equal( + remark() + .use({settings: {pedantic: true}}) + .processSync(test[1]) + .toString(), + test[2], + test[0] + ) + }) + } + ) - t.test('should process references with casing properly', function (st) { - /* Data-driven tests in the format: [name, value] */ + t.test('should process references with casing properly', function(st) { + // Data-driven tests in the format: [name, value] var tests = [ ['capitalized link references - full', '[alpha][Bravo]'], ['capitalized link references - collapsed', '[Bravo][]'], @@ -470,11 +553,11 @@ test('remark().stringify(ast, file)', function (t) { ['capitalized image references - collapsed', '![Bravo][]'], ['capitalized image references - shortcut', '![Bravo]'], ['capitalized footnote references', '[^Alpha]'] - ]; + ] - tests.forEach(each); + tests.forEach(each) - st.end(); + st.end() function each(test) { st.equal( @@ -483,11 +566,11 @@ test('remark().stringify(ast, file)', function (t) { .toString(), test[1] + '\n', test[0] - ); + ) } - }); + }) - t.test('should process associations without label', function (st) { + t.test('should process associations without label', function(st) { st.equal( stringify({ type: 'definition', @@ -496,20 +579,22 @@ test('remark().stringify(ast, file)', function (t) { }), '[a]: example.com', 'definition' - ); + ) st.equal( stringify({ type: 'footnoteDefinition', identifier: 'a', - children: [{ - type: 'paragraph', - children: [{type: 'text', value: 'b'}] - }] + children: [ + { + type: 'paragraph', + children: [{type: 'text', value: 'b'}] + } + ] }), '[^a]: b', 'footnote definition' - ); + ) st.equal( stringify({ @@ -519,7 +604,7 @@ test('remark().stringify(ast, file)', function (t) { }), '[b][a]', 'link reference' - ); + ) st.equal( stringify({ @@ -529,7 +614,7 @@ test('remark().stringify(ast, file)', function (t) { }), '![b][a]', 'image reference' - ); + ) st.equal( stringify({ @@ -538,27 +623,29 @@ test('remark().stringify(ast, file)', function (t) { }), '[^a]', 'footnote reference' - ); + ) - st.end(); + st.end() function stringify(value) { - return String(remark().stringify(value)); + return String(remark().stringify(value)) } - }); + }) - t.test('should support `stringLength`', function (st) { - st.plan(2); + t.test('should support `stringLength`', function(st) { + st.plan(2) var example = [ '| alpha | bravo |', '| ----- | ------- |', '| 中文 | charlie |', '' - ].join('\n'); + ].join('\n') st.equal( - remark().processSync(example).toString(), + remark() + .processSync(example) + .toString(), [ '| alpha | bravo |', '| ----- | ------- |', @@ -566,10 +653,13 @@ test('remark().stringify(ast, file)', function (t) { '' ].join('\n'), 'baseline' - ); + ) st.equal( - remark().use({settings: {stringLength: wcwidth}}).processSync(example).toString(), + remark() + .use({settings: {stringLength: wcwidth}}) + .processSync(example) + .toString(), [ '| alpha | bravo |', '| ----- | ------- |', @@ -577,93 +667,84 @@ test('remark().stringify(ast, file)', function (t) { '' ].join('\n'), 'custom `stringLength`' - ); - }); - - t.test('should support valid strings', function (st) { - var compiler = new Compiler(); - st.equal(compiler.options.listItemIndent, 'tab'); - compiler.setOptions({listItemIndent: 'mixed'}); - st.equal(compiler.options.listItemIndent, 'mixed'); - st.end(); - }); - - t.test('should support valid numbers', function (st) { - var compiler = new Compiler(); - st.equal(compiler.options.ruleRepetition, 3); - compiler.setOptions({ruleRepetition: 5}); - st.equal(compiler.options.ruleRepetition, 5); - st.end(); - }); - - t.test('should support valid booleans', function (st) { - var compiler = new Compiler(); - st.equal(compiler.options.looseTable, false); - compiler.setOptions({looseTable: true}); - st.equal(compiler.options.looseTable, true); - st.end(); - }); - - t.test('should support valid enums', function (st) { - var compiler = new Compiler(); - st.equal(compiler.options.strong, '*'); - compiler.setOptions({strong: '_'}); - st.equal(compiler.options.strong, '_'); - st.end(); - }); - - t.test('should support valid functions', function (st) { - var compiler = new Compiler(); - compiler.setOptions({stringLength: stringLength}); - st.equal(compiler.options.stringLength, stringLength); - st.end(); + ) + }) + + t.test('should support valid strings', function(st) { + var compiler = new Compiler() + st.equal(compiler.options.listItemIndent, 'tab') + compiler.setOptions({listItemIndent: 'mixed'}) + st.equal(compiler.options.listItemIndent, 'mixed') + st.end() + }) + + t.test('should support valid numbers', function(st) { + var compiler = new Compiler() + st.equal(compiler.options.ruleRepetition, 3) + compiler.setOptions({ruleRepetition: 5}) + st.equal(compiler.options.ruleRepetition, 5) + st.end() + }) + + t.test('should support valid booleans', function(st) { + var compiler = new Compiler() + st.equal(compiler.options.looseTable, false) + compiler.setOptions({looseTable: true}) + st.equal(compiler.options.looseTable, true) + st.end() + }) + + t.test('should support valid enums', function(st) { + var compiler = new Compiler() + st.equal(compiler.options.strong, '*') + compiler.setOptions({strong: '_'}) + st.equal(compiler.options.strong, '_') + st.end() + }) + + t.test('should support valid functions', function(st) { + var compiler = new Compiler() + compiler.setOptions({stringLength: stringLength}) + st.equal(compiler.options.stringLength, stringLength) + st.end() function stringLength() {} - }); - - t.test('should be able to set options', function (st) { - var processor = remark().use(plugin); - var tree = processor.parse([ - '', - '', - '# Hello World', - '' - ].join('\n')); + }) + + t.test('should be able to set options', function(st) { + var processor = remark().use(plugin) + var tree = processor.parse( + ['', '', '# Hello World', ''].join('\n') + ) st.equal( processor.stringify(tree), - [ - '', - '', - 'Hello World', - '===========', - '' - ].join('\n') - ); + ['', '', 'Hello World', '===========', ''].join('\n') + ) function plugin() { - var html = processor.Compiler.prototype.visitors.html; + var html = processor.Compiler.prototype.visitors.html - processor.Compiler.prototype.visitors.html = replacement; + processor.Compiler.prototype.visitors.html = replacement - /* Set option when an HTML comment occurs */ + // Set option when an HTML comment occurs. function replacement(node) { - var value = node.value; - var result = //g.exec(value); - var options = {}; + var value = node.value + var result = //g.exec(value) + var options = {} if (result) { - options[result[1]] = true; + options[result[1]] = true - this.setOptions(options); + this.setOptions(options) } - return html.apply(this, arguments); + return html.apply(this, arguments) } } - st.end(); - }); + st.end() + }) - t.end(); -}); + t.end() +}) diff --git a/test/remark.js b/test/remark.js index 68e2e0f55..9b875838a 100644 --- a/test/remark.js +++ b/test/remark.js @@ -1,69 +1,69 @@ -'use strict'; +'use strict' -var test = require('tape'); -var extend = require('extend'); -var remove = require('unist-util-remove-position'); -var compact = require('mdast-util-compact'); -var mdast = require('mdast-util-assert'); -var remark = require('../packages/remark'); -var fixtures = require('./fixtures'); +var test = require('tape') +var extend = require('extend') +var remove = require('unist-util-remove-position') +var compact = require('mdast-util-compact') +var mdast = require('mdast-util-assert') +var remark = require('../packages/remark') +var fixtures = require('./fixtures') -test('fixtures', function (t) { - var index = -1; +test('fixtures', function(t) { + var index = -1 - /* Check the next fixture. */ + // Check the next fixture. function next() { - var fixture = fixtures[++index]; + var fixture = fixtures[++index] if (!fixture) { - t.end(); - return; + t.end() + return } - setImmediate(next); // Queue next. + setImmediate(next) // Queue next. - t.test(fixture.name, function (st) { - var input = fixture.input; - var possibilities = fixture.possibilities; - var mapping = fixture.mapping; - var trees = fixture.trees; - var output = fixture.output; + t.test(fixture.name, function(st) { + var input = fixture.input + var possibilities = fixture.possibilities + var mapping = fixture.mapping + var trees = fixture.trees + var output = fixture.output - Object.keys(possibilities).forEach(function (key) { - var name = key || 'default'; - var parse = possibilities[key]; - var node; - var markdown; - var recompiled; + Object.keys(possibilities).forEach(function(key) { + var name = key || 'default' + var parse = possibilities[key] + var node + var markdown + var recompiled node = remark() .data('settings', parse) - .parse(input); + .parse(input) - mdast(node); + mdast(node) st.deepEqual( compact(node), compact(trees[mapping[key]]), 'should parse `' + name + '` correctly' - ); + ) markdown = remark() .data('settings', extend({}, fixture.stringify, parse)) - .stringify(node); + .stringify(node) if (output !== false) { recompiled = remark() .data('settings', parse) - .parse(markdown); + .parse(markdown) - mdast(recompiled); + mdast(recompiled) st.deepEqual( compact(remove(node, true)), compact(remove(recompiled, true)), 'should stringify `' + name + '`' - ); + ) } if (output === true) { @@ -71,13 +71,13 @@ test('fixtures', function (t) { fixture.input, markdown, 'should stringify `' + name + '` exact' - ); + ) } - }); + }) - st.end(); - }); + st.end() + }) } - next(); -}); + next() +})