Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

markdown-it

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

markdown-it - npm Package Compare versions

Comparing version 4.4.0 to 5.0.0

lib/rules_inline/balance_pairs.js

14

CHANGELOG.md

@@ -0,1 +1,15 @@

5.0.0 / 2015-10-05
------------------
- Internal API change. Due to new CM spec requirements, we had to update
internals. That should not touch ordinary users, but can affect some external
plugins. If you are plugin developper - see migration guide:
https://github.com/markdown-it/markdown-it/blob/master/docs/5.0_migration.md.
- Updated CM spec compatibility to 0.22:
- Keep tabs (don't replace with spaces).
- Don't wrap iframes with paragraphs.
- Rewritten emphasis algorithm.
- Fix closure compiler collisions (don't use reserved words), #159.
4.4.0 / 2015-07-18

@@ -2,0 +16,0 @@ ------------------

1

lib/common/html_blocks.js

@@ -38,2 +38,3 @@ // List of valid html blocks names, accorting to commonmark spec

'html',
'iframe',
'legend',

@@ -40,0 +41,0 @@ 'li',

@@ -154,2 +154,11 @@ // Utilities

function isSpace(code) {
switch (code) {
case 0x09:
case 0x20:
return true;
}
return false;
}
// Zs (unicode class) || [\t\f\v\r\n]

@@ -181,4 +190,4 @@ function isWhiteSpace(code) {

// Currently without astral characters support.
function isPunctChar(char) {
return UNICODE_PUNCT_RE.test(char);
function isPunctChar(ch) {
return UNICODE_PUNCT_RE.test(ch);
}

@@ -263,2 +272,3 @@

exports.arrayReplaceAt = arrayReplaceAt;
exports.isSpace = isSpace;
exports.isWhiteSpace = isWhiteSpace;

@@ -265,0 +275,0 @@ exports.isMdAsciiPunct = isMdAsciiPunct;

13

lib/index.js

@@ -60,3 +60,3 @@ // Main perser class

parsed.hostname = punycode.toASCII(parsed.hostname);
} catch(er) {}
} catch (er) { /**/ }
}

@@ -81,3 +81,3 @@ }

parsed.hostname = punycode.toUnicode(parsed.hostname);
} catch(er) {}
} catch (er) { /**/ }
}

@@ -387,2 +387,5 @@ }

}
if (presets.components[name].rules2) {
self[name].ruler2.enableOnly(presets.components[name].rules2);
}
});

@@ -420,2 +423,4 @@ }

result = result.concat(this.inline.ruler2.enable(list, true));
var missed = list.filter(function (name) { return result.indexOf(name) < 0; });

@@ -447,2 +452,4 @@

result = result.concat(this.inline.ruler2.disable(list, true));
var missed = list.filter(function (name) { return result.indexOf(name) < 0; });

@@ -491,3 +498,3 @@

* `env` is used to pass data between "distributed" rules and return additional
* metadata like reference info, needed for for renderer. It also can be used to
* metadata like reference info, needed for the renderer. It also can be used to
* inject data in specific cases. Usually, you will be ok to pass `{}`,

@@ -494,0 +501,0 @@ * and then pass updated object to renderer.

@@ -62,3 +62,3 @@ /** internal

// Nested calls currently used for blockquotes & lists
if (state.tShift[line] < state.blkIndent) { break; }
if (state.sCount[line] < state.blkIndent) { break; }

@@ -65,0 +65,0 @@ // If nesting level exceeded - skip tail to the end. That's not ordinary

@@ -20,4 +20,4 @@ /** internal

[ 'backticks', require('./rules_inline/backticks') ],
[ 'strikethrough', require('./rules_inline/strikethrough') ],
[ 'emphasis', require('./rules_inline/emphasis') ],
[ 'strikethrough', require('./rules_inline/strikethrough').tokenize ],
[ 'emphasis', require('./rules_inline/emphasis').tokenize ],
[ 'link', require('./rules_inline/link') ],

@@ -30,3 +30,10 @@ [ 'image', require('./rules_inline/image') ],

var _rules2 = [
[ 'balance_pairs', require('./rules_inline/balance_pairs') ],
[ 'strikethrough', require('./rules_inline/strikethrough').postProcess ],
[ 'emphasis', require('./rules_inline/emphasis').postProcess ],
[ 'text_collapse', require('./rules_inline/text_collapse') ]
];
/**

@@ -36,2 +43,4 @@ * new ParserInline()

function ParserInline() {
var i;
/**

@@ -44,5 +53,17 @@ * ParserInline#ruler -> Ruler

for (var i = 0; i < _rules.length; i++) {
for (i = 0; i < _rules.length; i++) {
this.ruler.push(_rules[i][0], _rules[i][1]);
}
/**
* ParserInline#ruler2 -> Ruler
*
* [[Ruler]] instance. Second ruler used for post-processing
* (e.g. in emphasis-like rules).
**/
this.ruler2 = new Ruler();
for (i = 0; i < _rules2.length; i++) {
this.ruler2.push(_rules2[i][0], _rules2[i][1]);
}
}

@@ -126,5 +147,13 @@

ParserInline.prototype.parse = function (str, md, env, outTokens) {
var i, rules, len;
var state = new this.State(str, md, env, outTokens);
this.tokenize(state);
rules = this.ruler2.getRules('');
len = rules.length;
for (i = 0; i < len; i++) {
rules[i](state);
}
};

@@ -131,0 +160,0 @@

@@ -22,3 +22,3 @@ // Commonmark default options

// and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp).
quotes: '\u201c\u201d\u2018\u2019' /* “”‘’ */,
quotes: '\u201c\u201d\u2018\u2019', /* “”‘’ */

@@ -72,2 +72,7 @@ // Highlighter function. Should return escaped HTML,

'text'
],
rules2: [
'balance_pairs',
'emphasis',
'text_collapse'
]

@@ -74,0 +79,0 @@ }

@@ -22,3 +22,3 @@ // markdown-it default options

// and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp).
quotes: '\u201c\u201d\u2018\u2019' /* “”‘’ */,
quotes: '\u201c\u201d\u2018\u2019', /* “”‘’ */

@@ -25,0 +25,0 @@ // Highlighter function. Should return escaped HTML,

@@ -23,3 +23,3 @@ // "Zero" preset, with nothing enabled. Useful for manual configuring of simple

// and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp).
quotes: '\u201c\u201d\u2018\u2019' /* “”‘’ */,
quotes: '\u201c\u201d\u2018\u2019', /* “”‘’ */

@@ -55,2 +55,6 @@ // Highlighter function. Should return escaped HTML,

'text'
],
rules2: [
'balance_pairs',
'text_collapse'
]

@@ -57,0 +61,0 @@ }

@@ -31,3 +31,3 @@ /**

default_rules.fence = function (tokens, idx, options, env, self) {
default_rules.fence = function (tokens, idx, options, env, slf) {
var token = tokens[idx],

@@ -49,3 +49,3 @@ info = token.info ? unescapeAll(token.info).trim() : '',

return '<pre><code' + self.renderAttrs(token) + '>'
return '<pre><code' + slf.renderAttrs(token) + '>'
+ highlighted

@@ -56,3 +56,3 @@ + '</code></pre>\n';

default_rules.image = function (tokens, idx, options, env, self) {
default_rules.image = function (tokens, idx, options, env, slf) {
var token = tokens[idx];

@@ -66,5 +66,5 @@

token.attrs[token.attrIndex('alt')][1] =
self.renderInlineAsText(token.children, options, env);
slf.renderInlineAsText(token.children, options, env);
return self.renderToken(tokens, idx, options);
return slf.renderToken(tokens, idx, options);
};

@@ -71,0 +71,0 @@

@@ -5,5 +5,7 @@ // Block quotes

var isSpace = require('../common/utils').isSpace;
module.exports = function blockquote(state, startLine, endLine, silent) {
var nextLine, lastLineEmpty, oldTShift, oldBMarks, oldIndent, oldParentType, lines,
var nextLine, lastLineEmpty, oldTShift, oldSCount, oldBMarks, oldIndent, oldParentType, lines, initial, offset, ch,
terminatorRules, token,

@@ -21,3 +23,3 @@ i, l, terminate,

// skip one optional space after '>'
// skip one optional space (but not tab, check cmark impl) after '>'
if (state.src.charCodeAt(pos) === 0x20) { pos++; }

@@ -28,9 +30,29 @@

// skip spaces after ">" and re-calculate offset
initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]);
oldBMarks = [ state.bMarks[startLine] ];
state.bMarks[startLine] = pos;
// check if we have an empty blockquote
pos = pos < max ? state.skipSpaces(pos) : pos;
while (pos < max) {
ch = state.src.charCodeAt(pos);
if (isSpace(ch)) {
if (ch === 0x09) {
offset += 4 - offset % 4;
} else {
offset++;
}
} else {
break;
}
pos++;
}
lastLineEmpty = pos >= max;
oldSCount = [ state.sCount[startLine] ];
state.sCount[startLine] = offset - initial;
oldTShift = [ state.tShift[startLine] ];

@@ -60,3 +82,3 @@ state.tShift[startLine] = pos - state.bMarks[startLine];

for (nextLine = startLine + 1; nextLine < endLine; nextLine++) {
if (state.tShift[nextLine] < oldIndent) { break; }
if (state.sCount[nextLine] < oldIndent) { break; }

@@ -74,11 +96,32 @@ pos = state.bMarks[nextLine] + state.tShift[nextLine];

// skip one optional space after '>'
// skip one optional space (but not tab, check cmark impl) after '>'
if (state.src.charCodeAt(pos) === 0x20) { pos++; }
// skip spaces after ">" and re-calculate offset
initial = offset = state.sCount[nextLine] + pos - (state.bMarks[nextLine] + state.tShift[nextLine]);
oldBMarks.push(state.bMarks[nextLine]);
state.bMarks[nextLine] = pos;
pos = pos < max ? state.skipSpaces(pos) : pos;
while (pos < max) {
ch = state.src.charCodeAt(pos);
if (isSpace(ch)) {
if (ch === 0x09) {
offset += 4 - offset % 4;
} else {
offset++;
}
} else {
break;
}
pos++;
}
lastLineEmpty = pos >= max;
oldSCount.push(state.sCount[nextLine]);
state.sCount[nextLine] = offset - initial;
oldTShift.push(state.tShift[nextLine]);

@@ -104,8 +147,7 @@ state.tShift[nextLine] = pos - state.bMarks[nextLine];

oldTShift.push(state.tShift[nextLine]);
oldSCount.push(state.sCount[nextLine]);
// A negative number means that this is a paragraph continuation;
// A negative indentation means that this is a paragraph continuation
//
// Any negative number will do the job here, but it's better for it
// to be large enough to make any bugs obvious.
state.tShift[nextLine] = -1;
state.sCount[nextLine] = -1;
}

@@ -133,2 +175,3 @@

state.tShift[i + startLine] = oldTShift[i];
state.sCount[i + startLine] = oldSCount[i];
}

@@ -135,0 +178,0 @@ state.blkIndent = oldIndent;

@@ -9,3 +9,3 @@ // Code block (4 spaces padded)

if (state.tShift[startLine] - state.blkIndent < 4) { return false; }
if (state.sCount[startLine] - state.blkIndent < 4) { return false; }

@@ -19,3 +19,3 @@ last = nextLine = startLine + 1;

}
if (state.tShift[nextLine] - state.blkIndent >= 4) {
if (state.sCount[nextLine] - state.blkIndent >= 4) {
nextLine++;

@@ -22,0 +22,0 @@ last = nextLine;

@@ -50,3 +50,3 @@ // fences (``` lang, ~~~ lang)

if (pos < max && state.tShift[nextLine] < state.blkIndent) {
if (pos < max && state.sCount[nextLine] < state.blkIndent) {
// non-empty line with negative indent should stop the list:

@@ -60,3 +60,3 @@ // - ```

if (state.tShift[nextLine] - state.blkIndent >= 4) {
if (state.sCount[nextLine] - state.blkIndent >= 4) {
// closing fence should be indented less than 4 spaces

@@ -82,3 +82,3 @@ continue;

// If a fence has heading spaces, they should be removed from its inner block
len = state.tShift[startLine];
len = state.sCount[startLine];

@@ -85,0 +85,0 @@ state.line = nextLine + (haveEndMarker ? 1 : 0);

@@ -5,3 +5,5 @@ // heading (#, ##, ...)

var isSpace = require('../common/utils').isSpace;
module.exports = function heading(state, startLine, endLine, silent) {

@@ -30,5 +32,5 @@ var ch, level, tmp, token,

max = state.skipCharsBack(max, 0x20, pos); // space
max = state.skipSpacesBack(max, pos);
tmp = state.skipCharsBack(max, 0x23, pos); // #
if (tmp > pos && state.src.charCodeAt(tmp - 1) === 0x20/* space */) {
if (tmp > pos && isSpace(state.src.charCodeAt(tmp - 1))) {
max = tmp;

@@ -35,0 +37,0 @@ }

@@ -5,3 +5,5 @@ // Horizontal rule

var isSpace = require('../common/utils').isSpace;
module.exports = function hr(state, startLine, endLine, silent) {

@@ -21,3 +23,3 @@ var marker, cnt, ch, token,

// markers can be mixed with spaces, but there should be at least 3 one
// markers can be mixed with spaces, but there should be at least 3 of them

@@ -27,3 +29,3 @@ cnt = 1;

ch = state.src.charCodeAt(pos++);
if (ch !== marker && ch !== 0x20/* space */) { return false; }
if (ch !== marker && !isSpace(ch)) { return false; }
if (ch === marker) { cnt++; }

@@ -30,0 +32,0 @@ }

@@ -51,3 +51,3 @@ // HTML block

for (; nextLine < endLine; nextLine++) {
if (state.tShift[nextLine] < state.blkIndent) { break; }
if (state.sCount[nextLine] < state.blkIndent) { break; }

@@ -54,0 +54,0 @@ pos = state.bMarks[nextLine] + state.tShift[nextLine];

@@ -11,7 +11,7 @@ // lheading (---, ===)

if (next >= endLine) { return false; }
if (state.tShift[next] < state.blkIndent) { return false; }
if (state.sCount[next] < state.blkIndent) { return false; }
// Scan next line
if (state.tShift[next] - state.blkIndent > 3) { return false; }
if (state.sCount[next] - state.blkIndent > 3) { return false; }

@@ -18,0 +18,0 @@ pos = state.bMarks[next] + state.tShift[next];

@@ -5,7 +5,9 @@ // Lists

var isSpace = require('../common/utils').isSpace;
// Search `[-+*][\n ]`, returns next pos arter marker on success
// or -1 on fail.
function skipBulletListMarker(state, startLine) {
var marker, pos, max;
var marker, pos, max, ch;

@@ -23,5 +25,9 @@ pos = state.bMarks[startLine] + state.tShift[startLine];

if (pos < max && state.src.charCodeAt(pos) !== 0x20) {
// " 1.test " - is not a list item
return -1;
if (pos < max) {
ch = state.src.charCodeAt(pos);
if (!isSpace(ch)) {
// " -test " - is not a list item
return -1;
}
}

@@ -71,5 +77,9 @@

if (pos < max && state.src.charCodeAt(pos) !== 0x20/* space */) {
// " 1.test " - is not a list item
return -1;
if (pos < max) {
ch = state.src.charCodeAt(pos);
if (!isSpace(ch)) {
// " 1.test " - is not a list item
return -1;
}
}

@@ -95,5 +105,8 @@ return pos;

var nextLine,
initial,
offset,
indent,
oldTShift,
oldIndent,
oldLIndent,
oldTight,

@@ -103,2 +116,4 @@ oldParentType,

posAfterMarker,
ch,
pos,
max,

@@ -162,5 +177,25 @@ indentAfterMarker,

while (nextLine < endLine) {
contentStart = state.skipSpaces(posAfterMarker);
pos = posAfterMarker;
max = state.eMarks[nextLine];
initial = offset = state.sCount[nextLine] + posAfterMarker - (state.bMarks[startLine] + state.tShift[startLine]);
while (pos < max) {
ch = state.src.charCodeAt(pos);
if (isSpace(ch)) {
if (ch === 0x09) {
offset += 4 - offset % 4;
} else {
offset++;
}
} else {
break;
}
pos++;
}
contentStart = pos;
if (contentStart >= max) {

@@ -170,3 +205,3 @@ // trimming space in "- \n 3" case, indent is 1 here

} else {
indentAfterMarker = contentStart - posAfterMarker;
indentAfterMarker = offset - initial;
}

@@ -180,3 +215,3 @@

// ^^^^^ - calculating total length of this thing
indent = (posAfterMarker - state.bMarks[nextLine]) + indentAfterMarker;
indent = initial + indentAfterMarker;

@@ -191,7 +226,9 @@ // Run subparser & write tokens

oldTShift = state.tShift[startLine];
oldLIndent = state.sCount[startLine];
oldParentType = state.parentType;
state.tShift[startLine] = contentStart - state.bMarks[startLine];
state.blkIndent = indent;
state.tight = true;
state.parentType = 'list';
state.tShift[startLine] = contentStart - state.bMarks[startLine];
state.sCount[startLine] = offset;

@@ -210,2 +247,3 @@ state.md.block.tokenize(state, startLine, endLine, true);

state.tShift[startLine] = oldTShift;
state.sCount[startLine] = oldLIndent;
state.tight = oldTight;

@@ -230,3 +268,3 @@ state.parentType = oldParentType;

//
if (state.tShift[nextLine] < state.blkIndent) { break; }
if (state.sCount[nextLine] < state.blkIndent) { break; }

@@ -233,0 +271,0 @@ // fail if terminating block found

@@ -16,6 +16,6 @@ // Paragraph

// it's considered a lazy continuation regardless of what's there
if (state.tShift[nextLine] - state.blkIndent > 3) { continue; }
if (state.sCount[nextLine] - state.blkIndent > 3) { continue; }
// quirk for blockquotes, this line should already be checked by that rule
if (state.tShift[nextLine] < 0) { continue; }
if (state.sCount[nextLine] < 0) { continue; }

@@ -22,0 +22,0 @@ // Some tags can terminate paragraph without empty line.

@@ -7,2 +7,3 @@ 'use strict';

var normalizeReference = require('../common/utils').normalizeReference;
var isSpace = require('../common/utils').isSpace;

@@ -52,6 +53,6 @@

// it's considered a lazy continuation regardless of what's there
if (state.tShift[nextLine] - state.blkIndent > 3) { continue; }
if (state.sCount[nextLine] - state.blkIndent > 3) { continue; }
// quirk for blockquotes, this line should already be checked by that rule
if (state.tShift[nextLine] < 0) { continue; }
if (state.sCount[nextLine] < 0) { continue; }

@@ -97,3 +98,3 @@ // Some tags can terminate paragraph without empty line.

lines++;
} else if (ch === 0x20) {
} else if (isSpace(ch)) {
/*eslint no-empty:0*/

@@ -127,3 +128,3 @@ } else {

lines++;
} else if (ch === 0x20) {
} else if (isSpace(ch)) {
/*eslint no-empty:0*/

@@ -149,3 +150,7 @@ } else {

// skip trailing spaces until the rest of the line
while (pos < max && str.charCodeAt(pos) === 0x20/* space */) { pos++; }
while (pos < max) {
ch = str.charCodeAt(pos);
if (!isSpace(ch)) { break; }
pos++;
}

@@ -159,3 +164,7 @@ if (pos < max && str.charCodeAt(pos) !== 0x0A) {

lines = destEndLineNo;
while (pos < max && str.charCodeAt(pos) === 0x20/* space */) { pos++; }
while (pos < max) {
ch = str.charCodeAt(pos);
if (!isSpace(ch)) { break; }
pos++;
}
}

@@ -162,0 +171,0 @@ }

@@ -6,6 +6,7 @@ // Parser state class

var Token = require('../token');
var isSpace = require('../common/utils').isSpace;
function StateBlock(src, md, env, tokens) {
var ch, s, start, pos, len, indent, indent_found;
var ch, s, start, pos, len, indent, offset, indent_found;

@@ -27,3 +28,4 @@ this.src = src;

this.eMarks = []; // line end offsets for fast jumps
this.tShift = []; // indent for each line
this.tShift = []; // offsets of the first non-space characters (tabs not expanded)
this.sCount = []; // indents for each line (tabs expanded)

@@ -47,11 +49,16 @@ // block parser variables

s = this.src;
indent = 0;
indent_found = false;
for (start = pos = indent = 0, len = s.length; pos < len; pos++) {
for (start = pos = indent = offset = 0, len = s.length; pos < len; pos++) {
ch = s.charCodeAt(pos);
if (!indent_found) {
if (ch === 0x20/* space */) {
if (isSpace(ch)) {
indent++;
if (ch === 0x09) {
offset += 4 - offset % 4;
} else {
offset++;
}
continue;

@@ -68,5 +75,7 @@ } else {

this.tShift.push(indent);
this.sCount.push(offset);
indent_found = false;
indent = 0;
offset = 0;
start = pos + 1;

@@ -80,2 +89,3 @@ }

this.tShift.push(0);
this.sCount.push(0);

@@ -114,4 +124,7 @@ this.lineMax = this.bMarks.length - 1; // don't count last fake line

StateBlock.prototype.skipSpaces = function skipSpaces(pos) {
var ch;
for (var max = this.src.length; pos < max; pos++) {
if (this.src.charCodeAt(pos) !== 0x20/* space */) { break; }
ch = this.src.charCodeAt(pos);
if (!isSpace(ch)) { break; }
}

@@ -121,2 +134,12 @@ return pos;

// Skip spaces from given position in reverse.
StateBlock.prototype.skipSpacesBack = function skipSpacesBack(pos, min) {
if (pos <= min) { return pos; }
while (pos > min) {
if (!isSpace(this.src.charCodeAt(--pos))) { return pos + 1; }
}
return pos;
};
// Skip char codes from given position

@@ -142,3 +165,3 @@ StateBlock.prototype.skipChars = function skipChars(pos, code) {

StateBlock.prototype.getLines = function getLines(begin, end, indent, keepLastLF) {
var i, first, last, queue, shift,
var i, lineIndent, ch, first, last, queue, lineStart,
line = begin;

@@ -150,18 +173,8 @@

// Opt: don't use push queue for single line;
if (line + 1 === end) {
first = this.bMarks[line] + Math.min(this.tShift[line], indent);
last = this.eMarks[end - 1] + (keepLastLF ? 1 : 0);
return this.src.slice(first, last);
}
queue = new Array(end - begin);
for (i = 0; line < end; line++, i++) {
shift = this.tShift[line];
if (shift > indent) { shift = indent; }
if (shift < 0) { shift = 0; }
lineIndent = 0;
lineStart = first = this.bMarks[line];
first = this.bMarks[line] + shift;
if (line + 1 < end || keepLastLF) {

@@ -174,2 +187,21 @@ // No need for bounds check because we have fake entry on tail.

while (first < last && lineIndent < indent) {
ch = this.src.charCodeAt(first);
if (isSpace(ch)) {
if (ch === 0x09) {
lineIndent += 4 - lineIndent % 4;
} else {
lineIndent++;
}
} else if (first - lineStart < this.tShift[line]) {
// patched tShift masked characters to look like spaces (blockquotes, list markers)
lineIndent++;
} else {
break;
}
first++;
}
queue[i] = this.src.slice(first, last);

@@ -176,0 +208,0 @@ }

@@ -65,3 +65,3 @@ // GFM table, non-standard

if (state.tShift[nextLine] < state.blkIndent) { return false; }
if (state.sCount[nextLine] < state.blkIndent) { return false; }

@@ -141,3 +141,3 @@ // first character of the second line should be '|' or '-'

for (nextLine = startLine + 2; nextLine < endLine; nextLine++) {
if (state.tShift[nextLine] < state.blkIndent) { break; }
if (state.sCount[nextLine] < state.blkIndent) { break; }

@@ -144,0 +144,0 @@ lineText = getLine(state, nextLine).trim();

@@ -6,3 +6,2 @@ // Normalize input string

var TABS_SCAN_RE = /[\n\t]/g;
var NEWLINES_RE = /\r[\n\u0085]|[\u2424\u2028\u0085]/g;

@@ -13,3 +12,3 @@ var NULL_RE = /\u0000/g;

module.exports = function inline(state) {
var str, lineStart, lastTabPos;
var str;

@@ -22,21 +21,3 @@ // Normalize newlines

// Replace tabs with proper number of spaces (1..4)
if (str.indexOf('\t') >= 0) {
lineStart = 0;
lastTabPos = 0;
str = str.replace(TABS_SCAN_RE, function (match, offset) {
var result;
if (str.charCodeAt(offset) === 0x0A) {
lineStart = offset + 1;
lastTabPos = 0;
return match;
}
result = ' '.slice((offset - lineStart - lastTabPos) % 4);
lastTabPos = offset - lineStart + 1;
return result;
});
}
state.src = str;
};

@@ -6,170 +6,119 @@ // Process *this* and _that_

var isWhiteSpace = require('../common/utils').isWhiteSpace;
var isPunctChar = require('../common/utils').isPunctChar;
var isMdAsciiPunct = require('../common/utils').isMdAsciiPunct;
// parse sequence of emphasis markers,
// "start" should point at a valid marker
function scanDelims(state, start) {
var pos = start, lastChar, nextChar, count, can_open, can_close,
isLastWhiteSpace, isLastPunctChar,
isNextWhiteSpace, isNextPunctChar,
left_flanking = true,
right_flanking = true,
max = state.posMax,
// Insert each marker as a separate text token, and add it to delimiter list
//
module.exports.tokenize = function emphasis(state, silent) {
var i, scanned, token,
start = state.pos,
marker = state.src.charCodeAt(start);
// treat beginning of the line as a whitespace
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : 0x20;
if (silent) { return false; }
while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
if (marker !== 0x5F /* _ */ && marker !== 0x2A /* * */) { return false; }
count = pos - start;
scanned = state.scanDelims(state.pos, marker === 0x2A);
// treat end of the line as a whitespace
nextChar = pos < max ? state.src.charCodeAt(pos) : 0x20;
for (i = 0; i < scanned.length; i++) {
token = state.push('text', '', 0);
token.content = String.fromCharCode(marker);
isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
state.delimiters.push({
// Char code of the starting marker (number).
//
marker: marker,
isLastWhiteSpace = isWhiteSpace(lastChar);
isNextWhiteSpace = isWhiteSpace(nextChar);
// An amount of characters before this one that's equivalent to
// current one. In plain English: if this delimiter does not open
// an emphasis, neither do previous `jump` characters.
//
// Used to skip sequences like "*****" in one step, for 1st asterisk
// value will be 0, for 2nd it's 1 and so on.
//
jump: i,
if (isNextWhiteSpace) {
left_flanking = false;
} else if (isNextPunctChar) {
if (!(isLastWhiteSpace || isLastPunctChar)) {
left_flanking = false;
}
}
// A position of the token this delimiter corresponds to.
//
token: state.tokens.length - 1,
if (isLastWhiteSpace) {
right_flanking = false;
} else if (isLastPunctChar) {
if (!(isNextWhiteSpace || isNextPunctChar)) {
right_flanking = false;
}
}
// Token level.
//
level: state.level,
if (marker === 0x5F /* _ */) {
// "_" inside a word can neither open nor close an emphasis
can_open = left_flanking && (!right_flanking || isLastPunctChar);
can_close = right_flanking && (!left_flanking || isNextPunctChar);
} else {
can_open = left_flanking;
can_close = right_flanking;
}
// If this delimiter is matched as a valid opener, `end` will be
// equal to its position, otherwise it's `-1`.
//
end: -1,
return {
can_open: can_open,
can_close: can_close,
delims: count
};
}
module.exports = function emphasis(state, silent) {
var startCount,
count,
found,
oldCount,
newCount,
stack,
res,
token,
max = state.posMax,
start = state.pos,
marker = state.src.charCodeAt(start);
if (marker !== 0x5F/* _ */ && marker !== 0x2A /* * */) { return false; }
if (silent) { return false; } // don't run any pairs in validation mode
res = scanDelims(state, start);
startCount = res.delims;
if (!res.can_open) {
state.pos += startCount;
// Earlier we checked !silent, but this implementation does not need it
state.pending += state.src.slice(start, state.pos);
return true;
// Boolean flags that determine if this delimiter could open or close
// an emphasis.
//
open: scanned.can_open,
close: scanned.can_close
});
}
state.pos = start + startCount;
stack = [ startCount ];
state.pos += scanned.length;
while (state.pos < max) {
if (state.src.charCodeAt(state.pos) === marker) {
res = scanDelims(state, state.pos);
count = res.delims;
if (res.can_close) {
oldCount = stack.pop();
newCount = count;
return true;
};
while (oldCount !== newCount) {
if (newCount < oldCount) {
stack.push(oldCount - newCount);
break;
}
// assert(newCount > oldCount)
newCount -= oldCount;
// Walk through delimiter list and replace text tokens with tags
//
module.exports.postProcess = function emphasis(state) {
var i,
startDelim,
endDelim,
token,
ch,
isStrong,
delimiters = state.delimiters,
max = state.delimiters.length;
if (stack.length === 0) { break; }
state.pos += oldCount;
oldCount = stack.pop();
}
for (i = 0; i < max; i++) {
startDelim = delimiters[i];
if (stack.length === 0) {
startCount = oldCount;
found = true;
break;
}
state.pos += count;
continue;
}
if (startDelim.marker !== 0x5F/* _ */ && startDelim.marker !== 0x2A/* * */) {
continue;
}
if (res.can_open) { stack.push(count); }
state.pos += count;
// Process only opening markers
if (startDelim.end === -1) {
continue;
}
state.md.inline.skipToken(state);
}
endDelim = delimiters[startDelim.end];
if (!found) {
// parser failed to find ending tag, so it's not valid emphasis
state.pos = start;
return false;
}
// If the next delimiter has the same marker and is adjacent to this one,
// merge those into one strong delimiter.
//
// `<em><em>whatever</em></em>` -> `<strong>whatever</strong>`
//
isStrong = i + 1 < max &&
delimiters[i + 1].end === startDelim.end - 1 &&
delimiters[i + 1].token === startDelim.token + 1 &&
delimiters[startDelim.end - 1].token === endDelim.token - 1 &&
delimiters[i + 1].marker === startDelim.marker;
// found!
state.posMax = state.pos;
state.pos = start + startCount;
ch = String.fromCharCode(startDelim.marker);
// Earlier we checked !silent, but this implementation does not need it
token = state.tokens[startDelim.token];
token.type = isStrong ? 'strong_open' : 'em_open';
token.tag = isStrong ? 'strong' : 'em';
token.nesting = 1;
token.markup = isStrong ? ch + ch : ch;
token.content = '';
// we have `startCount` starting and ending markers,
// now trying to serialize them into tokens
for (count = startCount; count > 1; count -= 2) {
token = state.push('strong_open', 'strong', 1);
token.markup = String.fromCharCode(marker) + String.fromCharCode(marker);
}
if (count % 2) {
token = state.push('em_open', 'em', 1);
token.markup = String.fromCharCode(marker);
}
token = state.tokens[endDelim.token];
token.type = isStrong ? 'strong_close' : 'em_close';
token.tag = isStrong ? 'strong' : 'em';
token.nesting = -1;
token.markup = isStrong ? ch + ch : ch;
token.content = '';
state.md.inline.tokenize(state);
if (count % 2) {
token = state.push('em_close', 'em', -1);
token.markup = String.fromCharCode(marker);
if (isStrong) {
state.tokens[delimiters[i + 1].token].content = '';
state.tokens[delimiters[startDelim.end - 1].token].content = '';
i++;
}
}
for (count = startCount; count > 1; count -= 2) {
token = state.push('strong_close', 'strong', -1);
token.markup = String.fromCharCode(marker) + String.fromCharCode(marker);
}
state.pos = state.posMax + startCount;
state.posMax = max;
return true;
};

@@ -5,2 +5,4 @@ // Proceess escaped chars and hardbreaks

var isSpace = require('../common/utils').isSpace;
var ESCAPED = [];

@@ -37,3 +39,7 @@

// skip leading whitespaces from next line
while (pos < max && state.src.charCodeAt(pos) === 0x20) { pos++; }
while (pos < max) {
ch = state.src.charCodeAt(pos);
if (!isSpace(ch)) { break; }
pos++;
}

@@ -40,0 +46,0 @@ state.pos = pos;

@@ -9,2 +9,3 @@ // Process ![image](<src> "title")

var normalizeReference = require('../common/utils').normalizeReference;
var isSpace = require('../common/utils').isSpace;

@@ -49,3 +50,3 @@

code = state.src.charCodeAt(pos);
if (code !== 0x20 && code !== 0x0A) { break; }
if (!isSpace(code) && code !== 0x0A) { break; }
}

@@ -72,3 +73,3 @@ if (pos >= max) { return false; }

code = state.src.charCodeAt(pos);
if (code !== 0x20 && code !== 0x0A) { break; }
if (!isSpace(code) && code !== 0x0A) { break; }
}

@@ -87,3 +88,3 @@

code = state.src.charCodeAt(pos);
if (code !== 0x20 && code !== 0x0A) { break; }
if (!isSpace(code) && code !== 0x0A) { break; }
}

@@ -109,3 +110,3 @@ } else {

code = state.src.charCodeAt(pos);
if (code !== 0x20 && code !== 0x0A) { break; }
if (!isSpace(code) && code !== 0x0A) { break; }
}

@@ -143,6 +144,3 @@

if (!silent) {
state.pos = labelStart;
state.posMax = labelEnd;
var newState = new state.md.inline.State(
state.md.inline.parse(
state.src.slice(labelStart, labelEnd),

@@ -153,3 +151,2 @@ state.md,

);
newState.md.inline.tokenize(newState);

@@ -156,0 +153,0 @@ token = state.push('image', 'img', 0);

@@ -9,2 +9,3 @@ // Process [link](<to> "stuff")

var normalizeReference = require('../common/utils').normalizeReference;
var isSpace = require('../common/utils').isSpace;

@@ -47,3 +48,3 @@

code = state.src.charCodeAt(pos);
if (code !== 0x20 && code !== 0x0A) { break; }
if (!isSpace(code) && code !== 0x0A) { break; }
}

@@ -70,3 +71,3 @@ if (pos >= max) { return false; }

code = state.src.charCodeAt(pos);
if (code !== 0x20 && code !== 0x0A) { break; }
if (!isSpace(code) && code !== 0x0A) { break; }
}

@@ -85,3 +86,3 @@

code = state.src.charCodeAt(pos);
if (code !== 0x20 && code !== 0x0A) { break; }
if (!isSpace(code) && code !== 0x0A) { break; }
}

@@ -107,3 +108,3 @@ } else {

code = state.src.charCodeAt(pos);
if (code !== 0x20 && code !== 0x0A) { break; }
if (!isSpace(code) && code !== 0x0A) { break; }
}

@@ -110,0 +111,0 @@

@@ -6,4 +6,8 @@ // Inline parser state

var Token = require('../token');
var Token = require('../token');
var isWhiteSpace = require('../common/utils').isWhiteSpace;
var isPunctChar = require('../common/utils').isPunctChar;
var isMdAsciiPunct = require('../common/utils').isMdAsciiPunct;
function StateInline(src, md, env, outTokens) {

@@ -23,2 +27,4 @@ this.src = src;

// optimization of pairs parse (emphasis, strikes).
this.delimiters = []; // Emphasis-like delimiters
}

@@ -58,2 +64,66 @@

// Scan a sequence of emphasis-like markers, and determine whether
// it can start an emphasis sequence or end an emphasis sequence.
//
// - start - position to scan from (it should point at a valid marker);
// - canSplitWord - determine if these markers can be found inside a word
//
StateInline.prototype.scanDelims = function (start, canSplitWord) {
var pos = start, lastChar, nextChar, count, can_open, can_close,
isLastWhiteSpace, isLastPunctChar,
isNextWhiteSpace, isNextPunctChar,
left_flanking = true,
right_flanking = true,
max = this.posMax,
marker = this.src.charCodeAt(start);
// treat beginning of the line as a whitespace
lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 0x20;
while (pos < max && this.src.charCodeAt(pos) === marker) { pos++; }
count = pos - start;
// treat end of the line as a whitespace
nextChar = pos < max ? this.src.charCodeAt(pos) : 0x20;
isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
isLastWhiteSpace = isWhiteSpace(lastChar);
isNextWhiteSpace = isWhiteSpace(nextChar);
if (isNextWhiteSpace) {
left_flanking = false;
} else if (isNextPunctChar) {
if (!(isLastWhiteSpace || isLastPunctChar)) {
left_flanking = false;
}
}
if (isLastWhiteSpace) {
right_flanking = false;
} else if (isLastPunctChar) {
if (!(isNextWhiteSpace || isNextPunctChar)) {
right_flanking = false;
}
}
if (!canSplitWord) {
can_open = left_flanking && (!right_flanking || isLastPunctChar);
can_close = right_flanking && (!left_flanking || isNextPunctChar);
} else {
can_open = left_flanking;
can_close = right_flanking;
}
return {
can_open: can_open,
can_close: can_close,
length: count
};
};
// re-export Token class to use in block rules

@@ -60,0 +130,0 @@ StateInline.prototype.Token = Token;

@@ -6,136 +6,113 @@ // ~~strike through~~

var isWhiteSpace = require('../common/utils').isWhiteSpace;
var isPunctChar = require('../common/utils').isPunctChar;
var isMdAsciiPunct = require('../common/utils').isMdAsciiPunct;
// Insert each marker as a separate text token, and add it to delimiter list
//
module.exports.tokenize = function strikethrough(state, silent) {
var i, scanned, token, len, ch,
start = state.pos,
marker = state.src.charCodeAt(start);
if (silent) { return false; }
// parse sequence of markers,
// "start" should point at a valid marker
function scanDelims(state, start) {
var pos = start, lastChar, nextChar, count,
isLastWhiteSpace, isLastPunctChar,
isNextWhiteSpace, isNextPunctChar,
can_open = true,
can_close = true,
max = state.posMax,
marker = state.src.charCodeAt(start);
if (marker !== 0x7E/* ~ */) { return false; }
// treat beginning of the line as a whitespace
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : 0x20;
scanned = state.scanDelims(state.pos, true);
len = scanned.length;
ch = String.fromCharCode(marker);
while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
if (len < 2) { return false; }
if (pos >= max) {
can_open = false;
if (len % 2) {
token = state.push('text', '', 0);
token.content = ch;
len--;
}
count = pos - start;
for (i = 0; i < len; i += 2) {
token = state.push('text', '', 0);
token.content = ch + ch;
// treat end of the line as a whitespace
nextChar = pos < max ? state.src.charCodeAt(pos) : 0x20;
state.delimiters.push({
marker: marker,
jump: i,
token: state.tokens.length - 1,
level: state.level,
end: -1,
open: scanned.can_open,
close: scanned.can_close
});
}
isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
state.pos += scanned.length;
isLastWhiteSpace = isWhiteSpace(lastChar);
isNextWhiteSpace = isWhiteSpace(nextChar);
return true;
};
if (isNextWhiteSpace) {
can_open = false;
} else if (isNextPunctChar) {
if (!(isLastWhiteSpace || isLastPunctChar)) {
can_open = false;
// Walk through delimiter list and replace text tokens with tags
//
module.exports.postProcess = function strikethrough(state) {
var i, j,
startDelim,
endDelim,
token,
loneMarkers = [],
delimiters = state.delimiters,
max = state.delimiters.length;
for (i = 0; i < max; i++) {
startDelim = delimiters[i];
if (startDelim.marker !== 0x7E/* ~ */) {
continue;
}
}
if (isLastWhiteSpace) {
can_close = false;
} else if (isLastPunctChar) {
if (!(isNextWhiteSpace || isNextPunctChar)) {
can_close = false;
if (startDelim.end === -1) {
continue;
}
}
return {
can_open: can_open,
can_close: can_close,
delims: count
};
}
endDelim = delimiters[startDelim.end];
token = state.tokens[startDelim.token];
token.type = 's_open';
token.tag = 's';
token.nesting = 1;
token.markup = '~~';
token.content = '';
module.exports = function strikethrough(state, silent) {
var startCount,
count,
tagCount,
found,
stack,
res,
token,
max = state.posMax,
start = state.pos,
marker = state.src.charCodeAt(start);
token = state.tokens[endDelim.token];
token.type = 's_close';
token.tag = 's';
token.nesting = -1;
token.markup = '~~';
token.content = '';
if (marker !== 0x7E/* ~ */) { return false; }
if (silent) { return false; } // don't run any pairs in validation mode
if (state.tokens[endDelim.token - 1].type === 'text' &&
state.tokens[endDelim.token - 1].content === '~') {
res = scanDelims(state, start);
startCount = res.delims;
if (!res.can_open) {
state.pos += startCount;
// Earlier we checked !silent, but this implementation does not need it
state.pending += state.src.slice(start, state.pos);
return true;
loneMarkers.push(endDelim.token - 1);
}
}
stack = Math.floor(startCount / 2);
if (stack <= 0) { return false; }
state.pos = start + startCount;
// If a marker sequence has an odd number of characters, it's splitted
// like this: `~~~~~` -> `~` + `~~` + `~~`, leaving one marker at the
// start of the sequence.
//
// So, we have to move all those markers after subsequent s_close tags.
//
while (loneMarkers.length) {
i = loneMarkers.pop();
j = i + 1;
while (state.pos < max) {
if (state.src.charCodeAt(state.pos) === marker) {
res = scanDelims(state, state.pos);
count = res.delims;
tagCount = Math.floor(count / 2);
if (res.can_close) {
if (tagCount >= stack) {
state.pos += count - 2;
found = true;
break;
}
stack -= tagCount;
state.pos += count;
continue;
}
if (res.can_open) { stack += tagCount; }
state.pos += count;
continue;
while (j < state.tokens.length && state.tokens[j].type === 's_close') {
j++;
}
state.md.inline.skipToken(state);
}
j--;
if (!found) {
// parser failed to find ending tag, so it's not valid emphasis
state.pos = start;
return false;
if (i !== j) {
token = state.tokens[j];
state.tokens[j] = state.tokens[i];
state.tokens[i] = token;
}
}
// found!
state.posMax = state.pos;
state.pos = start + 2;
// Earlier we checked !silent, but this implementation does not need it
token = state.push('s_open', 's', 1);
token.markup = '~~';
state.md.inline.tokenize(state);
token = state.push('s_close', 's', -1);
token.markup = '~~';
state.pos = state.posMax + 2;
state.posMax = max;
return true;
};
{
"name": "markdown-it",
"version": "4.4.0",
"version": "5.0.0",
"description": "Markdown-it - modern pluggable markdown parser.",

@@ -20,2 +20,8 @@ "keywords": [

},
"files": [
"index.js",
"bin/",
"lib/",
"dist/"
],
"dependencies": {

@@ -25,3 +31,3 @@ "argparse": "~1.0.2",

"linkify-it": "~1.2.0",
"mdurl": "~1.0.0",
"mdurl": "~1.0.1",
"uc.micro": "^1.0.0"

@@ -31,9 +37,10 @@ },

"ansi": "~0.3.0",
"autolinker": "^0.18.1",
"autoprefixer-stylus": "~0.5.0",
"benchmark": "~1.0.0",
"browserify": "*",
"chai": "^2.2.0",
"commonmark": "~0.18.1",
"chai": "^3.2.0",
"commonmark": "~0.22.0",
"coveralls": "~2.11.2",
"eslint": "0.13.0",
"eslint": "0.24.0",
"eslint-plugin-nodeca": "^1.0.0",

@@ -43,13 +50,13 @@ "istanbul": "*",

"markdown-it-abbr": "^1.0.0",
"markdown-it-container": "^1.0.0",
"markdown-it-deflist": "^1.0.0",
"markdown-it-container": "^2.0.0",
"markdown-it-deflist": "^2.0.0",
"markdown-it-emoji": "^1.0.0",
"markdown-it-footnote": "^1.0.0",
"markdown-it-footnote": "^2.0.0",
"markdown-it-for-inline": "~0.1.0",
"markdown-it-ins": "^1.0.0",
"markdown-it-mark": "^1.0.0",
"markdown-it-ins": "^2.0.0",
"markdown-it-mark": "^2.0.0",
"markdown-it-sub": "^1.0.0",
"markdown-it-sup": "^1.0.0",
"markdown-it-testgen": "~0.1.3",
"marked": "0.3.3",
"marked": "0.3.5",
"stylus": "~0.50.0",

@@ -56,0 +63,0 @@ "mocha": "*",

@@ -5,3 +5,3 @@ # 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=master)
[![Coverage Status](https://coveralls.io/repos/markdown-it/markdown-it/badge.svg?branch=master&service=github)](https://coveralls.io/github/markdown-it/markdown-it?branch=master)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/markdown-it/markdown-it)

@@ -8,0 +8,0 @@

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc