markdown-it
Advanced tools
Comparing version 2.2.1 to 3.0.0
@@ -63,3 +63,3 @@ #!/usr/bin/env node | ||
md = require('..')('full', { | ||
md = require('..')({ | ||
html: true, | ||
@@ -66,0 +66,0 @@ xhtmlOut: true, |
@@ -0,1 +1,23 @@ | ||
3.0.0 / 2015-01-04 | ||
------------------ | ||
- Big split. All "rare" rules moved to external plugins (deflist, abbr, footnote, | ||
sub, sup, ins, mark). | ||
- Updated CM spec conformance to v0.15 (better unicode support). | ||
- Added `md` (parser instance) link to all state objects (instead of former | ||
options/parser). | ||
- References/Footnotes/Abbrs moved to `block` chain. | ||
- Input normalisation moved to `core` chain. | ||
- Splitted links and images to separate rules. | ||
- Renamed some rules. | ||
- Removed `full` preset. Not needed anymore. | ||
- enable/disable methods now throw by default on invalid rules (exceptions can | ||
be disabled). | ||
- Fixed inline html comments & cdata parse. | ||
- Replace NULL characters with 0xFFFD instead of strip. | ||
- Removed custom fences sugar (overcomplication). | ||
- Rewritten link components parse helpers. | ||
- More functions in `md.utils`. | ||
2.2.1 / 2014-12-29 | ||
@@ -2,0 +24,0 @@ ------------------ |
@@ -14,3 +14,3 @@ // Regexps to match html elements | ||
} | ||
val = val.source || val; | ||
val = val.source; | ||
regex = regex.replace(name, val); | ||
@@ -45,6 +45,8 @@ return self; | ||
var close_tag = /<\/[A-Za-z][A-Za-z0-9]*\s*>/; | ||
var comment = /<!--([^-]+|[-][^-]+)*-->/; | ||
// That's less strict than http://www.w3.org/TR/html5/syntax.html#comments | ||
// but we do the rest of check in "inline" rule. | ||
var comment = /<!--[\s\S]*?-->/; | ||
var processing = /<[?].*?[?]>/; | ||
var declaration = /<![A-Z]+\s+[^>]*>/; | ||
var cdata = /<!\[CDATA\[([^\]]+|\][^\]]|\]\][^>])*\]\]>/; | ||
var cdata = /<!\[CDATA\[[\s\S]*?\]\]>/; | ||
@@ -51,0 +53,0 @@ var HTML_TAG_RE = replace(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/) |
@@ -13,3 +13,3 @@ // Utilities | ||
function has(object, key) { | ||
return object ? _hasOwnProperty.call(object, key) : false; | ||
return _hasOwnProperty.call(object, key); | ||
} | ||
@@ -148,3 +148,43 @@ | ||
//////////////////////////////////////////////////////////////////////////////// | ||
var REGEXP_ESCAPE_RE = /[.?*+^$[\]\\(){}|-]/g; | ||
function escapeRE (str) { | ||
return str.replace(REGEXP_ESCAPE_RE, '\\$&'); | ||
} | ||
//////////////////////////////////////////////////////////////////////////////// | ||
// Zs (unicode class) || 09, 0A, 0D, 0C | ||
function isWhiteSpace(code) { | ||
if (code >= 0x2000 && code <= 0x200A) { return true; } | ||
switch (code) { | ||
case 0x09: | ||
case 0x0A: | ||
case 0x0D: | ||
case 0x0C: | ||
case 0x20: | ||
case 0xA0: | ||
case 0x1680: | ||
case 0x202F: | ||
case 0x205F: | ||
case 0x3000: | ||
return true; | ||
} | ||
return false; | ||
} | ||
//////////////////////////////////////////////////////////////////////////////// | ||
/*eslint-disable max-len*/ | ||
var BMP_PUNCT_RE = /[\x21-\x23\x25-\x2A\x2C-\x2F\x3A\x3B\x3F\x40\x5B-\x5D\x5F\x7B\x7D\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; | ||
// Currently without astral characters support. | ||
function isPunctChar(char) { | ||
return BMP_PUNCT_RE.test(char); | ||
} | ||
//////////////////////////////////////////////////////////////////////////////// | ||
exports.assign = assign; | ||
@@ -160,1 +200,4 @@ exports.isString = isString; | ||
exports.normalizeLink = normalizeLink; | ||
exports.isWhiteSpace = isWhiteSpace; | ||
exports.isPunctChar = isPunctChar; | ||
exports.escapeRE = escapeRE; |
// Parse link destination | ||
// | ||
// on success it returns a string and updates state.pos; | ||
// on failure it returns null | ||
// | ||
'use strict'; | ||
@@ -13,18 +10,23 @@ | ||
module.exports = function parseLinkDestination(state, pos) { | ||
var code, level, link, | ||
module.exports = function parseLinkDestination(str, pos, max) { | ||
var code, level, | ||
lines = 0, | ||
start = pos, | ||
max = state.posMax; | ||
result = { | ||
ok: false, | ||
pos: 0, | ||
lines: 0, | ||
str: '' | ||
}; | ||
if (state.src.charCodeAt(pos) === 0x3C /* < */) { | ||
if (str.charCodeAt(pos) === 0x3C /* < */) { | ||
pos++; | ||
while (pos < max) { | ||
code = state.src.charCodeAt(pos); | ||
if (code === 0x0A /* \n */) { return false; } | ||
code = str.charCodeAt(pos); | ||
if (code === 0x0A /* \n */) { return result; } | ||
if (code === 0x3E /* > */) { | ||
link = normalizeLink(unescapeMd(state.src.slice(start + 1, pos))); | ||
if (!state.parser.validateLink(link)) { return false; } | ||
state.pos = pos + 1; | ||
state.linkContent = link; | ||
return true; | ||
result.pos = pos + 1; | ||
result.str = normalizeLink(unescapeMd(str.slice(start + 1, pos))); | ||
result.ok = true; | ||
return result; | ||
} | ||
@@ -40,3 +42,3 @@ if (code === 0x5C /* \ */ && pos + 1 < max) { | ||
// no closing '>' | ||
return false; | ||
return result; | ||
} | ||
@@ -48,3 +50,3 @@ | ||
while (pos < max) { | ||
code = state.src.charCodeAt(pos); | ||
code = str.charCodeAt(pos); | ||
@@ -74,10 +76,9 @@ if (code === 0x20) { break; } | ||
if (start === pos) { return false; } | ||
if (start === pos) { return result; } | ||
link = normalizeLink(unescapeMd(state.src.slice(start, pos))); | ||
if (!state.parser.validateLink(link)) { return false; } | ||
state.linkContent = link; | ||
state.pos = pos; | ||
return true; | ||
result.str = normalizeLink(unescapeMd(str.slice(start, pos))); | ||
result.lines = lines; | ||
result.pos = pos; | ||
result.ok = true; | ||
return result; | ||
}; |
@@ -33,3 +33,3 @@ // Parse link label | ||
prevPos = state.pos; | ||
state.parser.skipToken(state); | ||
state.md.inline.skipToken(state); | ||
if (marker === 0x5B /* [ */) { | ||
@@ -36,0 +36,0 @@ if (prevPos === state.pos - 1) { |
// Parse link title | ||
// | ||
// on success it returns a string and updates state.pos; | ||
// on failure it returns null | ||
// | ||
'use strict'; | ||
@@ -12,10 +9,20 @@ | ||
module.exports = function parseLinkTitle(state, pos) { | ||
module.exports = function parseLinkTitle(str, pos, max) { | ||
var code, | ||
marker, | ||
lines = 0, | ||
start = pos, | ||
max = state.posMax, | ||
marker = state.src.charCodeAt(pos); | ||
result = { | ||
ok: false, | ||
pos: 0, | ||
lines: 0, | ||
str: '' | ||
}; | ||
if (marker !== 0x22 /* " */ && marker !== 0x27 /* ' */ && marker !== 0x28 /* ( */) { return false; } | ||
if (pos >= max) { return result; } | ||
marker = str.charCodeAt(pos); | ||
if (marker !== 0x22 /* " */ && marker !== 0x27 /* ' */ && marker !== 0x28 /* ( */) { return result; } | ||
pos++; | ||
@@ -27,12 +34,17 @@ | ||
while (pos < max) { | ||
code = state.src.charCodeAt(pos); | ||
code = str.charCodeAt(pos); | ||
if (code === marker) { | ||
state.pos = pos + 1; | ||
state.linkContent = unescapeMd(state.src.slice(start + 1, pos)); | ||
return true; | ||
result.pos = pos + 1; | ||
result.lines = lines; | ||
result.str = unescapeMd(str.slice(start + 1, pos)); | ||
result.ok = true; | ||
return result; | ||
} else if (code === 0x0A) { | ||
lines++; | ||
} else if (code === 0x5C /* \ */ && pos + 1 < max) { | ||
pos++; | ||
if (str.charCodeAt(pos) === 0x0A) { | ||
lines++; | ||
} | ||
} | ||
if (code === 0x5C /* \ */ && pos + 1 < max) { | ||
pos += 2; | ||
continue; | ||
} | ||
@@ -42,3 +54,3 @@ pos++; | ||
return false; | ||
return result; | ||
}; |
117
lib/index.js
@@ -16,3 +16,2 @@ // Main perser class | ||
zero: require('./presets/zero'), | ||
full: require('./presets/full'), | ||
commonmark: require('./presets/commonmark') | ||
@@ -22,15 +21,2 @@ }; | ||
function StateCore(self, src, env) { | ||
this.src = src; | ||
this.env = env; | ||
this.options = self.options; | ||
this.tokens = []; | ||
this.inlineMode = false; | ||
this.inline = self.inline; | ||
this.block = self.block; | ||
this.renderer = self.renderer; | ||
this.typographer = self.typographer; | ||
} | ||
/** | ||
@@ -69,3 +55,3 @@ * class MarkdownIt | ||
* new MarkdownIt([presetName, options]) | ||
* - presetName (String): optional, `commonmark` / `full` / `zero` | ||
* - presetName (String): optional, `commonmark` / `zero` | ||
* - options (Object) | ||
@@ -82,6 +68,5 @@ * | ||
* configures parser to strict [CommonMark](http://commonmark.org/) mode. | ||
* - ["full"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/full.js) - | ||
* enables all available rules, but still without html, typographer & autolinker. | ||
* - [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.js) - | ||
* similar to GFM, used when no preset name given. | ||
* similar to GFM, used when no preset name given. Enables all available rules, | ||
* but still without html, typographer & autolinker. | ||
* - ["zero"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.js) - | ||
@@ -123,3 +108,3 @@ * all rules disabled. Useful to quickly setup your config via `.enable()`. | ||
* // enable everything | ||
* var md = require('markdown-it')('full', { | ||
* var md = require('markdown-it')({ | ||
* html: true, | ||
@@ -223,3 +208,3 @@ * linkify: true, | ||
**/ | ||
this.utils = utils; | ||
this.utils = utils; | ||
@@ -232,7 +217,7 @@ /** | ||
**/ | ||
this.helpers = helpers; | ||
this.helpers = helpers; | ||
this.options = {}; | ||
this.configure(config[presetName]); | ||
this.options = {}; | ||
this.configure(presetName); | ||
@@ -274,8 +259,17 @@ if (options) { this.set(options); } | ||
* and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets) | ||
* | ||
* We strongly recommend to use presets instead of direct config loads. That | ||
* will give better compatibility with next versions. | ||
**/ | ||
MarkdownIt.prototype.configure = function (presets) { | ||
var self = this; | ||
var self = this, presetName; | ||
if (!presets) { throw new Error('Wrong `markdown-it` preset, check name/content'); } | ||
if (utils.isString(presets)) { | ||
presetName = presets; | ||
presets = config[presetName]; | ||
if (!presets) { throw new Error('Wrong `markdown-it` preset "' + presetName + '", check name'); } | ||
} | ||
if (!presets) { throw new Error('Wrong `markdown-it` preset, can\'t be empty'); } | ||
if (presets.options) { self.set(presets.options); } | ||
@@ -295,7 +289,9 @@ | ||
/** chainable | ||
* MarkdownIt.enable(list) | ||
* MarkdownIt.enable(list, ignoreInvalid) | ||
* - list (String|Array): rule name or list of rule names to enable | ||
* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found. | ||
* | ||
* Enable list or rules. It will automatically find appropriate components, | ||
* containing rules with given names. | ||
* containing rules with given names. If rule not found, and `ignoreInvalid` | ||
* not set - throws exception. | ||
* | ||
@@ -310,6 +306,17 @@ * ##### Example | ||
**/ | ||
MarkdownIt.prototype.enable = function (list) { | ||
MarkdownIt.prototype.enable = function (list, ignoreInvalid) { | ||
var result = []; | ||
if (!Array.isArray(list)) { list = [ list ]; } | ||
[ 'core', 'block', 'inline' ].forEach(function (chain) { | ||
this[chain].ruler.enable(list, true); | ||
result = result.concat(this[chain].ruler.enable(list, true)); | ||
}, this); | ||
var missed = list.filter(function (name) { return result.indexOf(name) < 0; }); | ||
if (missed.length && !ignoreInvalid) { | ||
throw new Error('MarkdownIt. Failed to enable unknown rule(s): ' + missed); | ||
} | ||
return this; | ||
@@ -320,11 +327,22 @@ }; | ||
/** chainable | ||
* MarkdownIt.disable(list) | ||
* MarkdownIt.disable(list, ignoreInvalid) | ||
* - list (String|Array): rule name or list of rule names to disable. | ||
* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found. | ||
* | ||
* The same as [[MarkdownIt.enable]], but turn specified rules off. | ||
**/ | ||
MarkdownIt.prototype.disable = function (list) { | ||
MarkdownIt.prototype.disable = function (list, ignoreInvalid) { | ||
var result = []; | ||
if (!Array.isArray(list)) { list = [ list ]; } | ||
[ 'core', 'block', 'inline' ].forEach(function (chain) { | ||
this[chain].ruler.disable(list, true); | ||
result = result.concat(this[chain].ruler.disable(list, true)); | ||
}, this); | ||
var missed = list.filter(function (name) { return result.indexOf(name) < 0; }); | ||
if (missed.length && !ignoreInvalid) { | ||
throw new Error('MarkdownIt. Failed to disable unknown rule(s): ' + missed); | ||
} | ||
return this; | ||
@@ -335,5 +353,6 @@ }; | ||
/** chainable | ||
* MarkdownIt.use(plugin, options) | ||
* MarkdownIt.use(plugin, params) | ||
* | ||
* Load specified plugin with given options into current parser instance. | ||
* Load specified plugin with given params into current parser instance. | ||
* It's just a sugar to call `plugin(md, params)` with curring. | ||
* | ||
@@ -343,7 +362,10 @@ * ##### Example | ||
* ```javascript | ||
* var iterator = require('markdown-it-for-inline'); | ||
* var md = require('markdown-it')() | ||
* .use(require('makkdown-it-emoji')); | ||
* .use(iterator, 'foo_replace', 'text', function (tokens, idx) { | ||
* tokens[idx].content = tokens[idx].content.replace(/foo/g, 'bar'); | ||
* }); | ||
* ``` | ||
**/ | ||
MarkdownIt.prototype.use = function (plugin /*, options, ... */) { | ||
MarkdownIt.prototype.use = function (plugin /*, params, ... */) { | ||
var args = [ this ].concat(Array.prototype.slice.call(arguments, 1)); | ||
@@ -358,3 +380,3 @@ plugin.apply(plugin, args); | ||
* - src (String): source string | ||
* - env (Object): enviroment variables | ||
* - env (Object): environment sandbox | ||
* | ||
@@ -366,7 +388,9 @@ * Parse input string and returns list of block tokens (special token type | ||
* | ||
* `env` is modified with additional info. For example, with references data. | ||
* Also `env` can be used to pass external info to plugins. | ||
* `env` is used to pass data between "distributed" rules (`{}` by default). | ||
* For example, references are parsed in different chains, and need sandbox | ||
* to store intermediate results. Can be used to inject data in specific cases. | ||
* You will not need it with high probability. | ||
**/ | ||
MarkdownIt.prototype.parse = function (src, env) { | ||
var state = new StateCore(this, src, env); | ||
var state = new this.core.State(src, this, env); | ||
@@ -382,8 +406,9 @@ this.core.process(state); | ||
* - src (String): source string | ||
* - env (Object): optional, enviroment variables | ||
* - env (Object): environment sandbox | ||
* | ||
* Render markdown string into html. It does all magic for you :). | ||
* | ||
* `env` is `{}` by default. It's not used now directly, but you can pass | ||
* with it any additional data to plugins. | ||
* `env` can be used to inject additional metadata (`{}` by default). | ||
* But you will not need it with high probability. See also comment | ||
* in [[MarkdownIt.parse]]. | ||
**/ | ||
@@ -400,3 +425,3 @@ MarkdownIt.prototype.render = function (src, env) { | ||
* - src (String): source string | ||
* - env (Object): enviroment variables | ||
* - env (Object): environment sandbox | ||
* | ||
@@ -408,3 +433,3 @@ * The same as [[MarkdownIt.parse]] but skip all block rules. It returns the | ||
MarkdownIt.prototype.parseInline = function (src, env) { | ||
var state = new StateCore(this, src, env); | ||
var state = new this.core.State(src, this, env); | ||
@@ -421,3 +446,3 @@ state.inlineMode = true; | ||
* - src (String): source string | ||
* - env (Object): optional, enviroment variables | ||
* - env (Object): environment sandbox | ||
* | ||
@@ -424,0 +449,0 @@ * Similar to [[MarkdownIt.render]] but for single paragraph content. Result |
@@ -10,3 +10,2 @@ /** internal | ||
var Ruler = require('./ruler'); | ||
var StateBlock = require('./rules_block/state_block'); | ||
@@ -16,12 +15,11 @@ | ||
[ 'code', require('./rules_block/code') ], | ||
[ 'fences', require('./rules_block/fences'), [ 'paragraph', 'blockquote', 'list' ] ], | ||
[ 'blockquote', require('./rules_block/blockquote'), [ 'paragraph', 'blockquote', 'list' ] ], | ||
[ 'hr', require('./rules_block/hr'), [ 'paragraph', 'blockquote', 'list' ] ], | ||
[ 'list', require('./rules_block/list'), [ 'paragraph', 'blockquote' ] ], | ||
[ 'footnote', require('./rules_block/footnote'), [ 'paragraph' ] ], | ||
[ 'heading', require('./rules_block/heading'), [ 'paragraph', 'blockquote' ] ], | ||
[ 'fence', require('./rules_block/fence'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ], | ||
[ 'blockquote', require('./rules_block/blockquote'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ], | ||
[ 'hr', require('./rules_block/hr'), [ 'paragraph', 'reference', 'blockquote', 'list' ] ], | ||
[ 'list', require('./rules_block/list'), [ 'paragraph', 'reference', 'blockquote' ] ], | ||
[ 'reference', require('./rules_block/reference'), [ 'reference' ] ], | ||
[ 'heading', require('./rules_block/heading'), [ 'paragraph', 'reference', 'blockquote' ] ], | ||
[ 'lheading', require('./rules_block/lheading') ], | ||
[ 'htmlblock', require('./rules_block/htmlblock'), [ 'paragraph', 'blockquote' ] ], | ||
[ 'table', require('./rules_block/table'), [ 'paragraph' ] ], | ||
[ 'deflist', require('./rules_block/deflist'), [ 'paragraph' ] ], | ||
[ 'html_block', require('./rules_block/html_block'), [ 'paragraph', 'reference', 'blockquote' ] ], | ||
[ 'table', require('./rules_block/table'), [ 'paragraph', 'reference' ] ], | ||
[ 'paragraph', require('./rules_block/paragraph') ] | ||
@@ -55,3 +53,4 @@ ]; | ||
line = startLine, | ||
hasEmptyLines = false; | ||
hasEmptyLines = false, | ||
maxNesting = state.md.options.maxNesting; | ||
@@ -66,2 +65,9 @@ while (line < endLine) { | ||
// If nesting level exceeded - skip tail to the end. That's not ordinary | ||
// situation and we should not care about content. | ||
if (state.level >= maxNesting) { | ||
state.line = endLine; | ||
break; | ||
} | ||
// Try all possible rules. | ||
@@ -101,53 +107,22 @@ // On success, rule should: | ||
var TABS_SCAN_RE = /[\n\t]/g; | ||
var NEWLINES_RE = /\r[\n\u0085]|[\u2424\u2028\u0085]/g; | ||
var SPACES_RE = /\u00a0/g; | ||
var NULL_RE = /\u0000/g; | ||
/** | ||
* ParserBlock.parse(str, options, env, outTokens) | ||
* ParserBlock.parse(str, md, env, outTokens) | ||
* | ||
* Process input string and push block tokens into `outTokens` | ||
**/ | ||
ParserBlock.prototype.parse = function (src, options, env, outTokens) { | ||
var state, lineStart = 0, lastTabPos = 0; | ||
ParserBlock.prototype.parse = function (src, md, env, outTokens) { | ||
var state; | ||
if (!src) { return []; } | ||
// Normalize spaces | ||
src = src.replace(SPACES_RE, ' '); | ||
state = new this.State(src, md, env, outTokens); | ||
// Normalize newlines | ||
src = src.replace(NEWLINES_RE, '\n'); | ||
this.tokenize(state, state.line, state.lineMax); | ||
}; | ||
// Strin NULL characters | ||
src = src.replace(NULL_RE, ''); | ||
// Replace tabs with proper number of spaces (1..4) | ||
if (src.indexOf('\t') >= 0) { | ||
src = src.replace(TABS_SCAN_RE, function (match, offset) { | ||
var result; | ||
if (src.charCodeAt(offset) === 0x0A) { | ||
lineStart = offset + 1; | ||
lastTabPos = 0; | ||
return match; | ||
} | ||
result = ' '.slice((offset - lineStart - lastTabPos) % 4); | ||
lastTabPos = offset - lineStart + 1; | ||
return result; | ||
}); | ||
} | ||
ParserBlock.prototype.State = require('./rules_block/state_block'); | ||
state = new StateBlock( | ||
src, | ||
this, | ||
options, | ||
env, | ||
outTokens | ||
); | ||
this.tokenize(state, state.line, state.lineMax); | ||
}; | ||
module.exports = ParserBlock; |
@@ -14,8 +14,5 @@ /** internal | ||
var _rules = [ | ||
[ 'normalize', require('./rules_core/normalize') ], | ||
[ 'block', require('./rules_core/block') ], | ||
[ 'abbr', require('./rules_core/abbr') ], | ||
[ 'references', require('./rules_core/references') ], | ||
[ 'inline', require('./rules_core/inline') ], | ||
[ 'footnote_tail', require('./rules_core/footnote_tail') ], | ||
[ 'abbr2', require('./rules_core/abbr2') ], | ||
[ 'replacements', require('./rules_core/replacements') ], | ||
@@ -59,3 +56,5 @@ [ 'smartquotes', require('./rules_core/smartquotes') ], | ||
Core.prototype.State = require('./rules_core/state_core'); | ||
module.exports = Core; |
@@ -10,3 +10,2 @@ /** internal | ||
var Ruler = require('./ruler'); | ||
var StateInline = require('./rules_inline/state_inline'); | ||
var replaceEntities = require('./common/utils').replaceEntities; | ||
@@ -22,13 +21,8 @@ | ||
[ 'backticks', require('./rules_inline/backticks') ], | ||
[ 'del', require('./rules_inline/del') ], | ||
[ 'ins', require('./rules_inline/ins') ], | ||
[ 'mark', require('./rules_inline/mark') ], | ||
[ 'strikethrough', require('./rules_inline/strikethrough') ], | ||
[ 'emphasis', require('./rules_inline/emphasis') ], | ||
[ 'sub', require('./rules_inline/sub') ], | ||
[ 'sup', require('./rules_inline/sup') ], | ||
[ 'links', require('./rules_inline/links') ], | ||
[ 'footnote_inline', require('./rules_inline/footnote_inline') ], | ||
[ 'footnote_ref', require('./rules_inline/footnote_ref') ], | ||
[ 'link', require('./rules_inline/link') ], | ||
[ 'image', require('./rules_inline/image') ], | ||
[ 'autolink', require('./rules_inline/autolink') ], | ||
[ 'htmltag', require('./rules_inline/htmltag') ], | ||
[ 'html_inline', require('./rules_inline/html_inline') ], | ||
[ 'entity', require('./rules_inline/entity') ] | ||
@@ -91,4 +85,6 @@ ]; | ||
rules = this.ruler.getRules(''), | ||
len = rules.length; | ||
len = rules.length, | ||
maxNesting = state.md.options.maxNesting; | ||
if ((cached_pos = state.cacheGet(pos)) > 0) { | ||
@@ -99,10 +95,17 @@ state.pos = cached_pos; | ||
for (i = 0; i < len; i++) { | ||
if (rules[i](state, true)) { | ||
state.cacheSet(pos, state.pos); | ||
return; | ||
if (state.level < maxNesting) { | ||
for (i = 0; i < len; i++) { | ||
if (rules[i](state, true)) { | ||
state.cacheSet(pos, state.pos); | ||
return; | ||
} | ||
} | ||
state.pos++; | ||
} else { | ||
// If nesting level exceeded - skip tail to the end. That's not ordinary | ||
// situation and we should not care about content. | ||
state.pos = state.max; | ||
} | ||
state.pos++; | ||
state.cacheSet(pos, state.pos); | ||
@@ -118,6 +121,13 @@ }; | ||
len = rules.length, | ||
end = state.posMax; | ||
end = state.posMax, | ||
maxNesting = state.md.options.maxNesting; | ||
while (state.pos < end) { | ||
// If nesting level exceeded - skip tail to the end. That's not ordinary | ||
// situation and we should not care about content. | ||
if (state.level >= maxNesting) { | ||
state.pos = end; | ||
break; | ||
} | ||
// Try all possible rules. | ||
@@ -150,8 +160,8 @@ // On success, rule should: | ||
/** | ||
* ParserInline.parse(str, options, env, outTokens) | ||
* ParserInline.parse(str, md, env, outTokens) | ||
* | ||
* Process input string and push inline tokens into `outTokens` | ||
**/ | ||
ParserInline.prototype.parse = function (str, options, env, outTokens) { | ||
var state = new StateInline(str, this, options, env, outTokens); | ||
ParserInline.prototype.parse = function (str, md, env, outTokens) { | ||
var state = new this.State(str, md, env, outTokens); | ||
@@ -162,2 +172,5 @@ this.tokenize(state); | ||
ParserInline.prototype.State = require('./rules_inline/state_inline'); | ||
module.exports = ParserInline; |
@@ -35,6 +35,5 @@ // Commonmark default options | ||
rules: [ | ||
'normalize', | ||
'block', | ||
'inline', | ||
'references', | ||
'abbr2' | ||
'inline' | ||
] | ||
@@ -47,8 +46,9 @@ }, | ||
'code', | ||
'fences', | ||
'fence', | ||
'heading', | ||
'hr', | ||
'htmlblock', | ||
'html_block', | ||
'lheading', | ||
'list', | ||
'reference', | ||
'paragraph' | ||
@@ -65,4 +65,5 @@ ] | ||
'escape', | ||
'htmltag', | ||
'links', | ||
'html_inline', | ||
'image', | ||
'link', | ||
'newline', | ||
@@ -69,0 +70,0 @@ 'text' |
@@ -33,47 +33,6 @@ // markdown-it default options | ||
core: { | ||
rules: [ | ||
'block', | ||
'inline', | ||
'references', | ||
'replacements', | ||
'linkify', | ||
'smartquotes', | ||
'references', | ||
'abbr2', | ||
'footnote_tail' | ||
] | ||
}, | ||
block: { | ||
rules: [ | ||
'blockquote', | ||
'code', | ||
'fences', | ||
'heading', | ||
'hr', | ||
'htmlblock', | ||
'lheading', | ||
'list', | ||
'paragraph', | ||
'table' | ||
] | ||
}, | ||
inline: { | ||
rules: [ | ||
'autolink', | ||
'backticks', | ||
'del', | ||
'emphasis', | ||
'entity', | ||
'escape', | ||
'footnote_ref', | ||
'htmltag', | ||
'links', | ||
'newline', | ||
'text' | ||
] | ||
} | ||
core: {}, | ||
block: {}, | ||
inline: {} | ||
} | ||
}; |
@@ -36,2 +36,3 @@ // "Zero" preset, with nothing enabled. Useful for manual configuring of simple | ||
rules: [ | ||
'normalize', | ||
'block', | ||
@@ -38,0 +39,0 @@ 'inline' |
@@ -12,3 +12,2 @@ /** | ||
var assign = require('./common/utils').assign; | ||
var has = require('./common/utils').has; | ||
var unescapeMd = require('./common/utils').unescapeMd; | ||
@@ -24,16 +23,10 @@ var replaceEntities = require('./common/utils').replaceEntities; | ||
rules.blockquote_open = function () { return '<blockquote>\n'; }; | ||
rules.blockquote_close = function () { return '</blockquote>\n'; }; | ||
rules.blockquote_open = function (/* tokens, idx, options, env */) { | ||
return '<blockquote>\n'; | ||
rules.code_block = function (tokens, idx /*, options, env */) { | ||
return '<pre><code>' + escapeHtml(tokens[idx].content) + '</code></pre>\n'; | ||
}; | ||
rules.blockquote_close = function (/* tokens, idx, options, env */) { | ||
return '</blockquote>\n'; | ||
}; | ||
rules.code = function (tokens, idx /*, options, env */) { | ||
if (tokens[idx].block) { | ||
return '<pre><code>' + escapeHtml(tokens[idx].content) + '</code></pre>\n'; | ||
} | ||
rules.code_inline = function (tokens, idx /*, options, env */) { | ||
return '<code>' + escapeHtml(tokens[idx].content) + '</code>'; | ||
@@ -43,25 +36,11 @@ }; | ||
rules.fence = function (tokens, idx, options, env, self) { | ||
rules.fence = function (tokens, idx, options /*, env, self*/) { | ||
var token = tokens[idx]; | ||
var langClass = ''; | ||
var langPrefix = options.langPrefix; | ||
var langName = '', fenceName; | ||
var langName = ''; | ||
var highlighted; | ||
if (token.params) { | ||
// | ||
// ```foo bar | ||
// | ||
// Try custom renderer "foo" first. That will simplify overwrite | ||
// for diagrams, latex, and any other fenced block with custom look | ||
// | ||
fenceName = token.params.split(/\s+/g)[0]; | ||
if (has(self.rules.fence_custom, fenceName)) { | ||
return self.rules.fence_custom[fenceName](tokens, idx, options, env, self); | ||
} | ||
langName = escapeHtml(replaceEntities(unescapeMd(fenceName))); | ||
langName = escapeHtml(replaceEntities(unescapeMd(token.params.split(/\s+/g)[0]))); | ||
langClass = ' class="' + langPrefix + langName + '"'; | ||
@@ -82,3 +61,2 @@ } | ||
rules.fence_custom = {}; | ||
@@ -98,9 +76,5 @@ rules.heading_open = function (tokens, idx /*, options, env */) { | ||
rules.bullet_list_open = function (/* tokens, idx, options, env */) { | ||
return '<ul>\n'; | ||
}; | ||
rules.bullet_list_close = function (/* tokens, idx, options, env */) { | ||
return '</ul>\n'; | ||
}; | ||
rules.list_item_open = function (tokens, idx /*, options, env */) { | ||
rules.bullet_list_open = function () { return '<ul>\n'; }; | ||
rules.bullet_list_close = function () { return '</ul>\n'; }; | ||
rules.list_item_open = function (tokens, idx /*, options, env */) { | ||
var next = tokens[idx + 1]; | ||
@@ -113,6 +87,4 @@ if ((next.type === 'list_item_close') || | ||
}; | ||
rules.list_item_close = function (/* tokens, idx, options, env */) { | ||
return '</li>\n'; | ||
}; | ||
rules.ordered_list_open = function (tokens, idx /*, options, env */) { | ||
rules.list_item_close = function () { return '</li>\n'; }; | ||
rules.ordered_list_open = function (tokens, idx /*, options, env */) { | ||
if (tokens[idx].order > 1) { | ||
@@ -123,5 +95,3 @@ return '<ol start="' + tokens[idx].order + '">\n'; | ||
}; | ||
rules.ordered_list_close = function (/* tokens, idx, options, env */) { | ||
return '</ol>\n'; | ||
}; | ||
rules.ordered_list_close = function () { return '</ol>\n'; }; | ||
@@ -170,27 +140,11 @@ | ||
rules.table_open = function (/* tokens, idx, options, env */) { | ||
return '<table>\n'; | ||
}; | ||
rules.table_close = function (/* tokens, idx, options, env */) { | ||
return '</table>\n'; | ||
}; | ||
rules.thead_open = function (/* tokens, idx, options, env */) { | ||
return '<thead>\n'; | ||
}; | ||
rules.thead_close = function (/* tokens, idx, options, env */) { | ||
return '</thead>\n'; | ||
}; | ||
rules.tbody_open = function (/* tokens, idx, options, env */) { | ||
return '<tbody>\n'; | ||
}; | ||
rules.tbody_close = function (/* tokens, idx, options, env */) { | ||
return '</tbody>\n'; | ||
}; | ||
rules.tr_open = function (/* tokens, idx, options, env */) { | ||
return '<tr>'; | ||
}; | ||
rules.tr_close = function (/* tokens, idx, options, env */) { | ||
return '</tr>\n'; | ||
}; | ||
rules.th_open = function (tokens, idx /*, options, env */) { | ||
rules.table_open = function () { return '<table>\n'; }; | ||
rules.table_close = function () { return '</table>\n'; }; | ||
rules.thead_open = function () { return '<thead>\n'; }; | ||
rules.thead_close = function () { return '</thead>\n'; }; | ||
rules.tbody_open = function () { return '<tbody>\n'; }; | ||
rules.tbody_close = function () { return '</tbody>\n'; }; | ||
rules.tr_open = function () { return '<tr>'; }; | ||
rules.tr_close = function () { return '</tr>\n'; }; | ||
rules.th_open = function (tokens, idx /*, options, env */) { | ||
if (tokens[idx].align) { | ||
@@ -201,6 +155,4 @@ return '<th style="text-align:' + tokens[idx].align + '">'; | ||
}; | ||
rules.th_close = function (/* tokens, idx, options, env */) { | ||
return '</th>'; | ||
}; | ||
rules.td_open = function (tokens, idx /*, options, env */) { | ||
rules.th_close = function () { return '</th>'; }; | ||
rules.td_open = function (tokens, idx /*, options, env */) { | ||
if (tokens[idx].align) { | ||
@@ -211,53 +163,17 @@ return '<td style="text-align:' + tokens[idx].align + '">'; | ||
}; | ||
rules.td_close = function (/* tokens, idx, options, env */) { | ||
return '</td>'; | ||
}; | ||
rules.td_close = function () { return '</td>'; }; | ||
rules.strong_open = function (/* tokens, idx, options, env */) { | ||
return '<strong>'; | ||
}; | ||
rules.strong_close = function (/* tokens, idx, options, env */) { | ||
return '</strong>'; | ||
}; | ||
rules.em_open = function (/* tokens, idx, options, env */) { | ||
return '<em>'; | ||
}; | ||
rules.em_close = function (/* tokens, idx, options, env */) { | ||
return '</em>'; | ||
}; | ||
rules.strong_open = function () { return '<strong>'; }; | ||
rules.strong_close = function () { return '</strong>'; }; | ||
rules.del_open = function (/* tokens, idx, options, env */) { | ||
return '<del>'; | ||
}; | ||
rules.del_close = function (/* tokens, idx, options, env */) { | ||
return '</del>'; | ||
}; | ||
rules.em_open = function () { return '<em>'; }; | ||
rules.em_close = function () { return '</em>'; }; | ||
rules.ins_open = function (/* tokens, idx, options, env */) { | ||
return '<ins>'; | ||
}; | ||
rules.ins_close = function (/* tokens, idx, options, env */) { | ||
return '</ins>'; | ||
}; | ||
rules.s_open = function () { return '<s>'; }; | ||
rules.s_close = function () { return '</s>'; }; | ||
rules.mark_open = function (/* tokens, idx, options, env */) { | ||
return '<mark>'; | ||
}; | ||
rules.mark_close = function (/* tokens, idx, options, env */) { | ||
return '</mark>'; | ||
}; | ||
rules.sub = function (tokens, idx /*, options, env */) { | ||
return '<sub>' + escapeHtml(tokens[idx].content) + '</sub>'; | ||
}; | ||
rules.sup = function (tokens, idx /*, options, env */) { | ||
return '<sup>' + escapeHtml(tokens[idx].content) + '</sup>'; | ||
}; | ||
rules.hardbreak = function (tokens, idx, options /*, env */) { | ||
@@ -276,6 +192,6 @@ return options.xhtmlOut ? '<br />\n' : '<br>\n'; | ||
rules.htmlblock = function (tokens, idx /*, options, env */) { | ||
rules.html_block = function (tokens, idx /*, options, env */) { | ||
return tokens[idx].content; | ||
}; | ||
rules.htmltag = function (tokens, idx /*, options, env */) { | ||
rules.html_inline = function (tokens, idx /*, options, env */) { | ||
return tokens[idx].content; | ||
@@ -285,63 +201,2 @@ }; | ||
rules.abbr_open = function (tokens, idx /*, options, env */) { | ||
return '<abbr title="' + escapeHtml(replaceEntities(tokens[idx].title)) + '">'; | ||
}; | ||
rules.abbr_close = function (/* tokens, idx, options, env */) { | ||
return '</abbr>'; | ||
}; | ||
rules.footnote_ref = function (tokens, idx) { | ||
var n = Number(tokens[idx].id + 1).toString(); | ||
var id = 'fnref' + n; | ||
if (tokens[idx].subId > 0) { | ||
id += ':' + tokens[idx].subId; | ||
} | ||
return '<sup class="footnote-ref"><a href="#fn' + n + '" id="' + id + '">[' + n + ']</a></sup>'; | ||
}; | ||
rules.footnote_block_open = function (tokens, idx, options) { | ||
return (options.xhtmlOut ? '<hr class="footnotes-sep" />\n' : '<hr class="footnotes-sep">\n') + | ||
'<section class="footnotes">\n' + | ||
'<ol class="footnotes-list">\n'; | ||
}; | ||
rules.footnote_block_close = function () { | ||
return '</ol>\n</section>\n'; | ||
}; | ||
rules.footnote_open = function (tokens, idx) { | ||
var id = Number(tokens[idx].id + 1).toString(); | ||
return '<li id="fn' + id + '" class="footnote-item">'; | ||
}; | ||
rules.footnote_close = function () { | ||
return '</li>\n'; | ||
}; | ||
rules.footnote_anchor = function (tokens, idx) { | ||
var n = Number(tokens[idx].id + 1).toString(); | ||
var id = 'fnref' + n; | ||
if (tokens[idx].subId > 0) { | ||
id += ':' + tokens[idx].subId; | ||
} | ||
return ' <a href="#' + id + '" class="footnote-backref">\u21a9</a>'; /* ↩ */ | ||
}; | ||
rules.dl_open = function() { | ||
return '<dl>\n'; | ||
}; | ||
rules.dt_open = function() { | ||
return '<dt>'; | ||
}; | ||
rules.dd_open = function() { | ||
return '<dd>'; | ||
}; | ||
rules.dl_close = function() { | ||
return '</dl>\n'; | ||
}; | ||
rules.dt_close = function() { | ||
return '</dt>\n'; | ||
}; | ||
rules.dd_close = function() { | ||
return '</dd>\n'; | ||
}; | ||
/** | ||
@@ -373,3 +228,3 @@ * new Renderer() | ||
* ```javascript | ||
* function my_token_render(tokens, idx, options, env, self) { | ||
* function my_token_render(tokens, idx, options, env, renderer) { | ||
* // ... | ||
@@ -376,0 +231,0 @@ * return renderedHTML; |
@@ -248,3 +248,3 @@ /** | ||
/** | ||
* Ruler.enable(list [, ignoreInvalid]) | ||
* Ruler.enable(list [, ignoreInvalid]) -> Array | ||
* - list (String|Array): list of rule names to enable. | ||
@@ -256,2 +256,4 @@ * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found. | ||
* | ||
* Returns list of found rule names (if no exception happened). | ||
* | ||
* See also [[Ruler.disable]], [[Ruler.enableOnly]]. | ||
@@ -262,2 +264,4 @@ **/ | ||
var result = []; | ||
// Search by name and enable | ||
@@ -272,5 +276,7 @@ list.forEach(function (name) { | ||
this.__rules__[idx].enabled = true; | ||
result.push(name); | ||
}, this); | ||
this.__cache__ = null; | ||
return result; | ||
}; | ||
@@ -299,3 +305,3 @@ | ||
/** | ||
* Ruler.disable(list [, ignoreInvalid]) | ||
* Ruler.disable(list [, ignoreInvalid]) -> Array | ||
* - list (String|Array): list of rule names to disable. | ||
@@ -307,9 +313,11 @@ * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found. | ||
* | ||
* Returns list of found rule names (if no exception happened). | ||
* | ||
* See also [[Ruler.enable]], [[Ruler.enableOnly]]. | ||
**/ | ||
Ruler.prototype.disable = function (list, ignoreInvalid) { | ||
if (!Array.isArray(list)) { | ||
list = [ list ]; | ||
} | ||
if (!Array.isArray(list)) { list = [ list ]; } | ||
var result = []; | ||
// Search by name and disable | ||
@@ -324,5 +332,7 @@ list.forEach(function (name) { | ||
this.__rules__[idx].enabled = false; | ||
result.push(name); | ||
}, this); | ||
this.__cache__ = null; | ||
return result; | ||
}; | ||
@@ -329,0 +339,0 @@ |
@@ -18,4 +18,2 @@ // Block quotes | ||
if (state.level >= state.options.maxNesting) { return false; } | ||
// we know that it's going to be a valid blockquote, | ||
@@ -41,3 +39,3 @@ // so no point trying to find the end of it in silent mode | ||
terminatorRules = state.parser.ruler.getRules('blockquote'); | ||
terminatorRules = state.md.block.ruler.getRules('blockquote'); | ||
@@ -118,3 +116,3 @@ // Search the end of the block | ||
}); | ||
state.parser.tokenize(state, startLine, nextLine); | ||
state.md.block.tokenize(state, startLine, nextLine); | ||
state.tokens.push({ | ||
@@ -121,0 +119,0 @@ type: 'blockquote_close', |
@@ -28,5 +28,4 @@ // Code block (4 spaces padded) | ||
state.tokens.push({ | ||
type: 'code', | ||
type: 'code_block', | ||
content: state.getLines(startLine, last, 4 + state.blkIndent, true), | ||
block: true, | ||
lines: [ startLine, state.line ], | ||
@@ -33,0 +32,0 @@ level: state.level |
@@ -117,4 +117,2 @@ // Lists | ||
if (state.level >= state.options.maxNesting) { return false; } | ||
// We should terminate list on style change. Remember first one to compare. | ||
@@ -154,3 +152,3 @@ markerCharCode = state.src.charCodeAt(posAfterMarker - 1); | ||
prevEmptyEnd = false; | ||
terminatorRules = state.parser.ruler.getRules('list'); | ||
terminatorRules = state.md.block.ruler.getRules('list'); | ||
@@ -196,3 +194,3 @@ while (nextLine < endLine) { | ||
state.parser.tokenize(state, startLine, endLine, true); | ||
state.md.block.tokenize(state, startLine, endLine, true); | ||
@@ -199,0 +197,0 @@ // If any of list item is tight, mark list as tight |
@@ -15,3 +15,3 @@ // Paragraph | ||
if (nextLine < endLine && !state.isEmpty(nextLine)) { | ||
terminatorRules = state.parser.ruler.getRules('paragraph'); | ||
terminatorRules = state.md.block.ruler.getRules('paragraph'); | ||
@@ -18,0 +18,0 @@ for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) { |
@@ -6,3 +6,3 @@ // Parser state class | ||
function StateBlock(src, parser, options, env, tokens) { | ||
function StateBlock(src, md, env, tokens) { | ||
var ch, s, start, pos, len, indent, indent_found; | ||
@@ -12,7 +12,5 @@ | ||
// Shortcuts to simplify nested calls | ||
this.parser = parser; | ||
// link to parser instance | ||
this.md = md; | ||
this.options = options; | ||
this.env = env; | ||
@@ -19,0 +17,0 @@ |
@@ -8,3 +8,3 @@ 'use strict'; | ||
type: 'inline', | ||
content: state.src.replace(/\n/g, ' ').trim(), | ||
content: state.src, | ||
level: 0, | ||
@@ -16,4 +16,4 @@ lines: [ 0, 1 ], | ||
} else { | ||
state.block.parse(state.src, state.options, state.env, state.tokens); | ||
state.md.block.parse(state.src, state.md, state.env, state.tokens); | ||
} | ||
}; |
@@ -10,5 +10,5 @@ 'use strict'; | ||
if (tok.type === 'inline') { | ||
state.inline.parse(tok.content, state.options, state.env, tok.children); | ||
state.md.inline.parse(tok.content, state.md, state.env, tok.children); | ||
} | ||
} | ||
}; |
@@ -66,3 +66,3 @@ // Replace link-like texts with link nodes. | ||
if (!state.options.linkify) { return; } | ||
if (!state.md.options.linkify) { return; } | ||
@@ -90,3 +90,3 @@ for (j = 0, l = blockTokens.length; j < l; j++) { | ||
// Skip content of html tag links | ||
if (token.type === 'htmltag') { | ||
if (token.type === 'html_inline') { | ||
if (isLinkOpen(token.content) && htmlLinkLevel > 0) { | ||
@@ -122,3 +122,3 @@ htmlLinkLevel--; | ||
if (!state.inline.validateLink(links[ln].url)) { continue; } | ||
if (!state.md.inline.validateLink(links[ln].url)) { continue; } | ||
@@ -125,0 +125,0 @@ pos = text.indexOf(links[ln].text); |
@@ -42,3 +42,3 @@ // Simple typographyc replacements | ||
if (!state.options.typographer) { return; } | ||
if (!state.md.options.typographer) { return; } | ||
@@ -45,0 +45,0 @@ for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) { |
@@ -30,3 +30,3 @@ // Convert straight quotation marks to typographic ones | ||
if (!state.options.typographer) { return; } | ||
if (!state.md.options.typographer) { return; } | ||
@@ -89,7 +89,10 @@ stack = []; | ||
if (isSingle) { | ||
tokens[item.token].content = replaceAt(tokens[item.token].content, item.pos, state.options.quotes[2]); | ||
token.content = replaceAt(token.content, t.index, state.options.quotes[3]); | ||
tokens[item.token].content = replaceAt( | ||
tokens[item.token].content, item.pos, state.md.options.quotes[2]); | ||
token.content = replaceAt( | ||
token.content, t.index, state.md.options.quotes[3]); | ||
} else { | ||
tokens[item.token].content = replaceAt(tokens[item.token].content, item.pos, state.options.quotes[0]); | ||
token.content = replaceAt(token.content, t.index, state.options.quotes[1]); | ||
tokens[item.token].content = replaceAt( | ||
tokens[item.token].content, item.pos, state.md.options.quotes[0]); | ||
token.content = replaceAt(token.content, t.index, state.md.options.quotes[1]); | ||
} | ||
@@ -96,0 +99,0 @@ stack.length = j; |
@@ -30,3 +30,3 @@ // Process autolinks '<protocol:...>' | ||
fullUrl = normalizeLink(url); | ||
if (!state.parser.validateLink(url)) { return false; } | ||
if (!state.md.inline.validateLink(url)) { return false; } | ||
@@ -59,3 +59,3 @@ if (!silent) { | ||
fullUrl = normalizeLink('mailto:' + url); | ||
if (!state.parser.validateLink(fullUrl)) { return false; } | ||
if (!state.md.inline.validateLink(fullUrl)) { return false; } | ||
@@ -62,0 +62,0 @@ if (!silent) { |
@@ -5,3 +5,3 @@ // Parse backticks | ||
module.exports = function backticks(state, silent) { | ||
module.exports = function backtick(state, silent) { | ||
var start, max, marker, matchStart, matchEnd, | ||
@@ -31,7 +31,6 @@ pos = state.pos, | ||
state.push({ | ||
type: 'code', | ||
type: 'code_inline', | ||
content: state.src.slice(pos, matchStart) | ||
.replace(/[ \n]+/g, ' ') | ||
.trim(), | ||
block: false, | ||
level: state.level | ||
@@ -38,0 +37,0 @@ }); |
@@ -5,3 +5,6 @@ // Process *this* and _that_ | ||
var isWhiteSpace = require('../common/utils').isWhiteSpace; | ||
var isPunctChar = require('../common/utils').isPunctChar; | ||
function isAlphaNum(code) { | ||
@@ -17,2 +20,4 @@ return (code >= 0x30 /* 0 */ && code <= 0x39 /* 9 */) || | ||
var pos = start, lastChar, nextChar, count, | ||
isLastWhiteSpace, isLastPunctChar, | ||
isNextWhiteSpace, isNextPunctChar, | ||
can_open = true, | ||
@@ -31,6 +36,23 @@ can_close = true, | ||
// check whitespace conditions | ||
if (nextChar === 0x20 || nextChar === 0x0A) { can_open = false; } | ||
if (lastChar === 0x20 || lastChar === 0x0A) { can_close = false; } | ||
isLastPunctChar = lastChar >= 0 && isPunctChar(String.fromCharCode(lastChar)); | ||
isNextPunctChar = nextChar >= 0 && isPunctChar(String.fromCharCode(nextChar)); | ||
isLastWhiteSpace = lastChar >= 0 && isWhiteSpace(lastChar); | ||
isNextWhiteSpace = nextChar >= 0 && isWhiteSpace(nextChar); | ||
if (isNextWhiteSpace) { | ||
can_open = false; | ||
} else if (isNextPunctChar) { | ||
if (!(isLastWhiteSpace || isLastPunctChar || lastChar === -1)) { | ||
can_open = false; | ||
} | ||
} | ||
if (isLastWhiteSpace) { | ||
can_close = false; | ||
} else if (isLastPunctChar) { | ||
if (!(isNextWhiteSpace || isNextPunctChar || nextChar === -1)) { | ||
can_close = false; | ||
} | ||
} | ||
if (marker === 0x5F /* _ */) { | ||
@@ -68,8 +90,7 @@ // check if we aren't inside the word | ||
state.pos += startCount; | ||
if (!silent) { state.pending += state.src.slice(start, state.pos); } | ||
// Earlier we checked !silent, but this implementation does not need it | ||
state.pending += state.src.slice(start, state.pos); | ||
return true; | ||
} | ||
if (state.level >= state.options.maxNesting) { return false; } | ||
state.pos = start + startCount; | ||
@@ -114,3 +135,3 @@ stack = [ startCount ]; | ||
state.parser.skipToken(state); | ||
state.md.inline.skipToken(state); | ||
} | ||
@@ -128,16 +149,16 @@ | ||
if (!silent) { | ||
// we have `startCount` starting and ending markers, | ||
// now trying to serialize them into tokens | ||
for (count = startCount; count > 1; count -= 2) { | ||
state.push({ type: 'strong_open', level: state.level++ }); | ||
} | ||
if (count % 2) { state.push({ type: 'em_open', level: state.level++ }); } | ||
// Earlier we checked !silent, but this implementation does not need it | ||
state.parser.tokenize(state); | ||
// we have `startCount` starting and ending markers, | ||
// now trying to serialize them into tokens | ||
for (count = startCount; count > 1; count -= 2) { | ||
state.push({ type: 'strong_open', level: state.level++ }); | ||
} | ||
if (count % 2) { state.push({ type: 'em_open', level: state.level++ }); } | ||
if (count % 2) { state.push({ type: 'em_close', level: --state.level }); } | ||
for (count = startCount; count > 1; count -= 2) { | ||
state.push({ type: 'strong_close', level: --state.level }); | ||
} | ||
state.md.inline.tokenize(state); | ||
if (count % 2) { state.push({ type: 'em_close', level: --state.level }); } | ||
for (count = startCount; count > 1; count -= 2) { | ||
state.push({ type: 'strong_close', level: --state.level }); | ||
} | ||
@@ -144,0 +165,0 @@ |
@@ -6,8 +6,8 @@ // Inline parser state | ||
function StateInline(src, parserInline, options, env, outTokens) { | ||
function StateInline(src, md, env, outTokens) { | ||
this.src = src; | ||
this.env = env; | ||
this.options = options; | ||
this.parser = parserInline; | ||
this.md = md; | ||
this.tokens = outTokens; | ||
this.pos = 0; | ||
@@ -24,4 +24,2 @@ this.posMax = this.src.length; | ||
this.linkContent = ''; // Temporary storage for link url | ||
this.labelUnmatchedScopes = 0; // Track unpaired `[` for link labels | ||
@@ -28,0 +26,0 @@ // (backtrack optimization) |
{ | ||
"name": "markdown-it", | ||
"version": "2.2.1", | ||
"version": "3.0.0", | ||
"description": "Markdown-it - modern pluggable markdown parser.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -5,3 +5,4 @@ # markdown-it | ||
[![NPM version](https://img.shields.io/npm/v/markdown-it.svg?style=flat)](https://www.npmjs.org/package/markdown-it) | ||
[![Coverage Status](https://img.shields.io/coveralls/markdown-it/markdown-it/master.svg?style=flat)](https://coveralls.io/r/markdown-it/markdown-it?branch=dev) | ||
[![Coverage Status](https://img.shields.io/coveralls/markdown-it/markdown-it/master.svg?style=flat)](https://coveralls.io/r/markdown-it/markdown-it?branch=master) | ||
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/markdown-it/markdown-it) | ||
@@ -40,2 +41,3 @@ > Markdown parser done right. Fast and easy to extend. | ||
- [jsDeliver CDN](http://www.jsdelivr.com/#!markdown-it "jsDelivr CDN") | ||
- [cdnjs.com CDN](https://cdnjs.com/libraries/markdown-it "cdnjs.com") | ||
@@ -82,3 +84,4 @@ | ||
(*) preset define combination of active rules and options. Can be | ||
`"full"`|`"commonmark"`|`"zero"` or `"default"` if skipped. | ||
`"commonmark"`, `"zero"` or `"default"` (if skipped). See | ||
[API docs](https://markdown-it.github.io/markdown-it/#MarkdownIt.new) for more details. | ||
@@ -93,3 +96,3 @@ ```js | ||
// enable everything | ||
var md = require('markdown-it')('full', { | ||
var md = require('markdown-it')({ | ||
html: true, | ||
@@ -128,3 +131,3 @@ linkify: true, | ||
.use(plugin1) | ||
.use(plugin2, opts) | ||
.use(plugin2, opts, ...) | ||
.use(plugin3); | ||
@@ -162,3 +165,3 @@ ``` | ||
[API documentation](https://markdown-it.github.io/markdown-it/) | ||
__[API documentation](https://markdown-it.github.io/markdown-it/)__ | ||
@@ -171,29 +174,29 @@ If you are going to write plugins - take a look at | ||
Enabled by default: | ||
Embedded (enabled by default): | ||
- [Tables](https://help.github.com/articles/github-flavored-markdown/#tables) (GFM) | ||
- [\<del>](https://help.github.com/articles/github-flavored-markdown/#strikethrough) | ||
(GFM strikethrough) - `~~deleted text~~` | ||
- [Strikethrough](https://help.github.com/articles/github-flavored-markdown/#strikethrough) (GFM) | ||
Disabled by default: | ||
Via plugins:: | ||
- [\<sup>](http://johnmacfarlane.net/pandoc/README.html#superscripts-and-subscripts) - `19^th^` | ||
- [\<sub>](http://johnmacfarlane.net/pandoc/README.html#superscripts-and-subscripts) - `H~2~0` | ||
- [abbreviations](https://michelf.ca/projects/php-markdown/extra/#abbr) | ||
- [footnotes](http://johnmacfarlane.net/pandoc/README.html#footnotes) | ||
- __\<ins>__ - `++inserted text++` (experimental) | ||
- __\<mark>__ - `==marked text==` (experimental) | ||
- [subscript](https://github.com/markdown-it/markdown-it-sub) | ||
- [superscript](https://github.com/markdown-it/markdown-it-sup) | ||
- [footnote](https://github.com/markdown-it/markdown-it-footnote) | ||
- [definition list](https://github.com/markdown-it/markdown-it-deflist) | ||
- [abbreviation](https://github.com/markdown-it/markdown-it-abbr) | ||
- [insert](https://github.com/markdown-it/markdown-it-ins) | ||
- [mark](https://github.com/markdown-it/markdown-it-mark) | ||
__*__ Experimental extensions can be changed later for something like | ||
[Critic Markup](http://criticmarkup.com/), but you will still be able to use | ||
old-style rules via external plugins if you prefer. | ||
### Manage rules | ||
By default all rules are enebled, but can be restricted by options. On plugin | ||
load all it's rules are enabled automatically. | ||
```js | ||
// Activate/deactivate rules | ||
// Activate/deactivate rules, with curring | ||
var md = require('markdown-it')() | ||
.enable([ 'ins', 'mark' ]) | ||
.disable([ 'table' ]); | ||
.disable([ 'link', 'image' ]) | ||
.enable([ 'link' ]) | ||
.enable('image'); | ||
@@ -206,18 +209,2 @@ // Enable everything | ||
}); | ||
// Manually enable rules, disabled by default: | ||
var md = require('markdown-it')() | ||
.enable([ | ||
/* core */ | ||
'abbr', | ||
/* block */ | ||
'footnote', | ||
'deflist', | ||
/* inline */ | ||
'footnote_inline', | ||
'ins', | ||
'mark', | ||
'sub', | ||
'sup' | ||
]); | ||
``` | ||
@@ -224,0 +211,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
543253
60
14600
250