New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

remarkable

Package Overview
Dependencies
Maintainers
3
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

remarkable - npm Package Compare versions

Comparing version 1.3.0 to 1.4.0

lib/helpers/normalize_reference.js

13

CHANGELOG.md

@@ -0,1 +1,14 @@

1.4.0 / WIP
------------------
- Added `core` chain, to better organize code and improve pluggability.
- Added `renderInline()` and `parseInline()` methods.
- Added abbreviations support.
- Fixed problem with tables, having single column.
- Fixed rendered rules rewrite for inline tags.
- Changed internal api (ruler, inline, block classes).
- Removed typographer chain (rules moved to `core`).
- Removed all typographer options. Quote chars defs moved to `options.quotes`.
1.3.0 / 2014-10-29

@@ -2,0 +15,0 @@ ------------------

47

lib/common/utils.js

@@ -14,17 +14,15 @@ // Utilities

var sources = Array.prototype.slice.call(arguments, 1);
while (sources.length) {
var source = sources.shift();
if (!source) { continue; }
if (typeof(source) !== 'object') {
throw new TypeError(source + 'must be non-object');
}
sources.forEach(function (source) {
if (!source) { return; }
for (var p in source) {
if (source.hasOwnProperty(p)) {
obj[p] = source[p];
}
if (typeof source !== 'object') {
throw new TypeError(source + 'must be object');
}
}
Object.keys(source).forEach(function (key) {
obj[key] = source[key];
});
});
return obj;

@@ -70,14 +68,27 @@ }

var NAMED_ENTITY_RE = /&([a-z][a-z0-9]{1,31});/gi;
var NAMED_ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi;
var DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i;
var entities = require('./entities');
function replaceEntityPattern(match, name) {
var code = 0;
if (entities.hasOwnProperty(name)) {
return entities[name];
} else if (name.charCodeAt(0) === 0x23/* # */ && DIGITAL_ENTITY_TEST_RE.test(name)) {
code = name[1].toLowerCase() === 'x' ?
parseInt(name.slice(2), 16)
:
parseInt(name.slice(1), 10);
if (isValidEntityCode(code)) {
return fromCodePoint(code);
}
}
return match;
}
function replaceEntities(str) {
if (str.indexOf('&') < 0) { return str; }
return str.replace(NAMED_ENTITY_RE, function(match, name) {
if (entities.hasOwnProperty(name)) {
return entities[name];
}
return match;
});
return str.replace(NAMED_ENTITY_RE, replaceEntityPattern);
}

@@ -84,0 +95,0 @@

@@ -13,7 +13,16 @@ // Commonmark default options

linkify: false, // autoconvert URL-like texts to links
typographer: false, // Enable smartypants and other sweet transforms
// Enable some language-neutral replacements + quotes beautification
typographer: false,
// Double + single quotes replacement pairs, when typographer enabled,
// and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.
quotes: '“”‘’',
// Highlighter function. Should return escaped HTML,
// or '' if input not changed
highlight: function (/*str, lang*/) { return ''; },
//
// function (/*str, lang*/) { return ''; }
//
highlight: null,

@@ -25,2 +34,11 @@ maxNesting: 20 // Internal protection, recursion limit

core: {
rules: [
'block',
'inline',
'references',
'abbr2'
]
},
block: {

@@ -52,19 +70,4 @@ rules: [

]
},
typographer: {
options: {
singleQuotes: '‘’', // set empty to disable
doubleQuotes: '“”', // set '«»' for Russian, '„“' for German, empty to disable
copyright: true, // (c) (C) → ©
trademark: true, // (tm) (TM) → ™
registered: true, // (r) (R) → ®
plusminus: true, // +- → ±
paragraph: true, // (p) (P) → §
ellipsis: true, // ... → …
dupes: true, // ???????? → ???, !!!!! → !!!, `,,` → `,`
dashes: true // -- → —
}
}
}
};

@@ -13,7 +13,16 @@ // Remarkable default options

linkify: false, // autoconvert URL-like texts to links
typographer: false, // Enable smartypants and other sweet transforms
// Enable some language-neutral replacements + quotes beautification
typographer: false,
// Double + single quotes replacement pairs, when typographer enabled,
// and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.
quotes: '“”‘’',
// Highlighter function. Should return escaped HTML,
// or '' if input not changed
highlight: function (/*str, lang*/) { return ''; },
//
// function (/*str, lang*/) { return ''; }
//
highlight: null,

@@ -25,2 +34,15 @@ maxNesting: 20 // Internal protection, recursion limit

core: {
rules: [
'block',
'inline',
'references',
'replacements',
'linkify',
'smartquotes',
'references',
'abbr2'
]
},
block: {

@@ -54,19 +76,4 @@ rules: [

]
},
typographer: {
options: {
singleQuotes: '‘’', // set empty to disable
doubleQuotes: '“”', // set '«»' for Russian, '„“' for German, empty to disable
copyright: true, // (c) (C) → ©
trademark: true, // (tm) (TM) → ™
registered: true, // (r) (R) → ®
plusminus: true, // +- → ±
paragraph: true, // (p) (P) → §
ellipsis: true, // ... → …
dupes: true, // ???????? → ???, !!!!! → !!!, `,,` → `,`
dashes: true // -- → —
}
}
}
};

@@ -13,7 +13,16 @@ // Remarkable default options

linkify: false, // autoconvert URL-like texts to links
typographer: false, // Enable smartypants and other sweet transforms
// Enable some language-neutral replacements + quotes beautification
typographer: false,
// Double + single quotes replacement pairs, when typographer enabled,
// and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.
quotes: '“”‘’',
// Highlighter function. Should return escaped HTML,
// or '' if input not changed
highlight: function (/*str, lang*/) { return ''; },
//
// function (/*str, lang*/) { return ''; }
//
highlight: null,

@@ -25,21 +34,7 @@ maxNesting: 20 // Internal protection, recursion limit

// Don't restrict block/inline rules
// Don't restrict core/block/inline rules
core: {},
block: {},
inline: {},
typographer: {
options: {
singleQuotes: '‘’', // set empty to disable
doubleQuotes: '“”', // set '«»' for Russian, '„“' for German, empty to disable
copyright: true, // (c) (C) → ©
trademark: true, // (tm) (TM) → ™
registered: true, // (r) (R) → ®
plusminus: true, // +- → ±
paragraph: true, // (p) (P) → §
ellipsis: true, // ... → …
dupes: true, // ???????? → ???, !!!!! → !!!, `,,` → `,`
dashes: true // -- → —
}
}
inline: {}
}
};

@@ -9,8 +9,7 @@ // Main perser class

var Renderer = require('./renderer');
var ParserCore = require('./parser_core');
var ParserBlock = require('./parser_block');
var ParserInline = require('./parser_inline');
var Typographer = require('./typographer');
var Linkifier = require('./linkifier');
var Ruler = require('./ruler');
var config = {

@@ -23,2 +22,15 @@ 'default': require('./configs/default'),

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;
}
// Main class

@@ -34,16 +46,9 @@ //

this.options = {};
this.state = null;
this.inline = new ParserInline();
this.block = new ParserBlock();
this.core = new ParserCore();
this.renderer = new Renderer();
this.typographer = new Typographer();
this.linkifier = new Linkifier();
this.ruler = new Ruler();
// Cross-references to simplify code (a bit dirty, but easy).
this.block.inline = this.inline;
this.inline.typographer = this.typographer;
this.inline.linkifier = this.linkifier;
this.options = {};
this.configure(config[presetName]);

@@ -67,3 +72,3 @@

if (!presets) { throw new Error('Wrong config name'); }
if (!presets) { throw new Error('Wrong `remarkable` preset, check name/content'); }

@@ -77,5 +82,2 @@ if (presets.options) { self.set(presets.options); }

}
if (presets.components[name].options) {
self[name].set(presets.components[name].options);
}
});

@@ -104,15 +106,7 @@ }

Remarkable.prototype.parse = function (src, env) {
var tokens, tok, i, l;
// Parse blocks
tokens = this.block.parse(src, this.options, env);
var state = new StateCore(this, src, env);
// Parse inlines
for (i = 0, l = tokens.length; i < l; i++) {
tok = tokens[i];
if (tok.type === 'inline') {
tok.children = this.inline.parse(tok.content, this.options, env);
}
}
this.core.process(state);
return tokens;
return state.tokens;
};

@@ -122,4 +116,4 @@

//
Remarkable.prototype.render = function (src) {
var env = { references: {} };
Remarkable.prototype.render = function (src, env) {
env = env || {};

@@ -130,2 +124,22 @@ return this.renderer.render(this.parse(src, env), this.options, env);

// Parse content as single string
//
Remarkable.prototype.parseInline = function (src, env) {
var state = new StateCore(this, src, env);
state.inlineMode = true;
this.core.process(state);
return state.tokens;
};
// Render single string, without wrapping it to paragraphs
//
Remarkable.prototype.renderInline = function (src, env) {
env = env || {};
return this.renderer.render(this.parseInline(src, env), this.options, env);
};
module.exports = Remarkable;

@@ -8,3 +8,3 @@ // Block parser

var Ruler = require('./ruler');
var State = require('./rules_block/state_block');
var StateBlock = require('./rules_block/state_block');

@@ -29,9 +29,4 @@

function ParserBlock() {
this._rules = [];
this._rulesParagraphTerm = [];
this._rulesBlockquoteTerm = [];
this._rulesListTerm = [];
this.ruler = new Ruler();
this.ruler = new Ruler(this.rulesUpdate.bind(this));
for (var i = 0; i < _rules.length; i++) {

@@ -43,10 +38,2 @@ this.ruler.push(_rules[i][0], _rules[i][1], { alt: (_rules[i][2] || []).slice() });

ParserBlock.prototype.rulesUpdate = function () {
this._rules = this.ruler.getRules();
this._rulesParagraphTerm = this.ruler.getRules('paragraph');
this._rulesBlockquoteTerm = this.ruler.getRules('blockquote');
this._rulesListTerm = this.ruler.getRules('list');
};
// Generate tokens for input range

@@ -56,4 +43,4 @@ //

var ok, i,
rules = this._rules,
len = this._rules.length,
rules = this.ruler.getRules(''),
len = rules.length,
line = startLine,

@@ -82,8 +69,2 @@ hasEmptyLines = false;

if (!ok) { throw new Error('No matching rules found'); }
if (line === state.line) {
throw new Error('None of rules updated state.line');
}
// set state.tight iff we had an empty line before current tag

@@ -115,3 +96,3 @@ // i.e. latest empty line should not count

ParserBlock.prototype.parse = function (src, options, env) {
ParserBlock.prototype.parse = function (src, options, env, outTokens) {
var state, lineStart = 0, lastTabPos = 0;

@@ -142,13 +123,11 @@

state = new State(
state = new StateBlock(
src,
this,
[],
options,
env
env,
outTokens
);
this.tokenize(state, state.line, state.lineMax);
return state.tokens;
};

@@ -155,0 +134,0 @@

@@ -33,10 +33,4 @@ // Inline parser

function validateLink(url) {
var str = '';
var str = decodeURI(url).trim().toLowerCase();
try {
str = decodeURI(url).trim().toLowerCase();
} catch (_) {}
if (!str) { return false; }
if (str.indexOf(':') >= 0 && BAD_PROTOCOLS.indexOf(str.split(':')[0]) >= 0) {

@@ -51,8 +45,2 @@ return false;

function ParserInline() {
this._rules = [];
// Rule to skip pure text
// - '{}$%@+=:' reserved for extentions
this.textMatch = /[\n\\`*_^\[\]!&<{}$%@~+=:]/;
// By default CommonMark allows too much in links

@@ -62,3 +50,3 @@ // If you need to restrict it - override this with your validator.

this.ruler = new Ruler(this.rulesUpdate.bind(this));
this.ruler = new Ruler();

@@ -71,7 +59,2 @@ for (var i = 0; i < _rules.length; i++) {

ParserInline.prototype.rulesUpdate = function () {
this._rules = this.ruler.getRules();
};
// Skip single token by running all rules in validation mode;

@@ -82,3 +65,4 @@ // returns `true` if any rule reported success

var i, cached_pos, pos = state.pos,
len = this._rules.length;
rules = this.ruler.getRules(''),
len = rules.length;

@@ -91,3 +75,3 @@ if ((cached_pos = state.cacheGet(pos)) > 0) {

for (i = 0; i < len; i++) {
if (this._rules[i](state, true)) {
if (rules[i](state, true)) {
state.cacheSet(pos, state.pos);

@@ -107,3 +91,4 @@ return;

var ok, i,
len = this._rules.length,
rules = this.ruler.getRules(''),
len = rules.length,
end = state.posMax;

@@ -121,3 +106,3 @@

for (i = 0; i < len; i++) {
ok = this._rules[i](state, false);
ok = rules[i](state, false);
if (ok) { break; }

@@ -137,4 +122,2 @@ }

}
return state.tokens;
};

@@ -145,15 +128,6 @@

//
ParserInline.prototype.parse = function (str, options, env) {
var state = new StateInline(str, this, options, env);
ParserInline.prototype.parse = function (str, options, env, outTokens) {
var state = new StateInline(str, this, options, env, outTokens);
this.tokenize(state);
if (options.linkify) {
this.linkifier.process(state);
}
if (options.typographer) {
this.typographer.process(state);
}
return state.tokens;
};

@@ -160,0 +134,0 @@

@@ -12,15 +12,2 @@ 'use strict';

function escapeUrl(str) {
try {
return encodeURI(str);
} catch (__) {}
return '';
}
function unescapeUrl(str) {
try {
return decodeURI(str);
} catch (__) {}
return '';
}
var HTML_ESCAPE_TEST_RE = /[&<>"]/;

@@ -46,6 +33,17 @@ var HTML_ESCAPE_REPLACE_RE = /[&<>"]/g;

function nextToken(tokens, idx) {
if (++idx >= tokens.length - 2) { return idx; }
if ((tokens[idx].type === 'paragraph_open' && tokens[idx].tight) &&
(tokens[idx + 1].type === 'inline' && tokens[idx + 1].content.length === 0) &&
(tokens[idx + 2].type === 'paragraph_close' && tokens[idx + 2].tight)) {
return nextToken(tokens, idx + 2);
}
return idx;
}
// check if we need to hide '\n' before next token
function getBreak(tokens, idx) {
if (++idx < tokens.length &&
idx = nextToken(tokens, idx);
if (idx < tokens.length &&
tokens[idx].type === 'list_item_close') {

@@ -63,6 +61,7 @@ return '';

rules.blockquote_open = function (/*tokens, idx, options*/) {
rules.blockquote_open = function (/* tokens, idx, options, env */) {
return '<blockquote>\n';
};
rules.blockquote_close = function (tokens, idx /*, options*/) {
rules.blockquote_close = function (tokens, idx /*, options, env */) {
return '</blockquote>' + getBreak(tokens, idx);

@@ -72,3 +71,3 @@ };

rules.code = function (tokens, idx /*, options*/) {
rules.code = function (tokens, idx /*, options, env */) {
if (tokens[idx].block) {

@@ -82,6 +81,6 @@ return '<pre><code>' + escapeHtml(tokens[idx].content) + '</code></pre>' + getBreak(tokens, idx);

rules.fence = function (tokens, idx, options) {
rules.fence = function (tokens, idx, options /*, env */) {
var token = tokens[idx];
var langClass = '';
var langPrefix = options.langPrefix || '';
var langPrefix = options.langPrefix;
var params, langName = '';

@@ -96,4 +95,9 @@ var highlighted;

highlighted = options.highlight(token.content, langName) || escapeHtml(token.content);
if (options.highlight) {
highlighted = options.highlight(token.content, langName) || escapeHtml(token.content);
} else {
highlighted = escapeHtml(token.content);
}
return '<pre><code' + langClass + '>'

@@ -105,6 +109,6 @@ + highlighted

rules.heading_open = function (tokens, idx /*, options*/) {
rules.heading_open = function (tokens, idx /*, options, env */) {
return '<h' + tokens[idx].hLevel + '>';
};
rules.heading_close = function (tokens, idx /*, options*/) {
rules.heading_close = function (tokens, idx /*, options, env */) {
return '</h' + tokens[idx].hLevel + '>\n';

@@ -114,3 +118,3 @@ };

rules.hr = function (tokens, idx, options) {
rules.hr = function (tokens, idx, options /*, env */) {
return (options.xhtmlOut ? '<hr />' : '<hr>') + getBreak(tokens, idx);

@@ -120,15 +124,15 @@ };

rules.bullet_list_open = function (/*tokens, idx, options*/) {
rules.bullet_list_open = function (/* tokens, idx, options, env */) {
return '<ul>\n';
};
rules.bullet_list_close = function (tokens, idx /*, options*/) {
rules.bullet_list_close = function (tokens, idx /*, options, env */) {
return '</ul>' + getBreak(tokens, idx);
};
rules.list_item_open = function (/*tokens, idx, options*/) {
rules.list_item_open = function (/* tokens, idx, options, env */) {
return '<li>';
};
rules.list_item_close = function (/*tokens, idx, options*/) {
rules.list_item_close = function (/* tokens, idx, options, env */) {
return '</li>\n';
};
rules.ordered_list_open = function (tokens, idx /*, options*/) {
rules.ordered_list_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx];

@@ -139,3 +143,3 @@ return '<ol'

};
rules.ordered_list_close = function (tokens, idx /*, options*/) {
rules.ordered_list_close = function (tokens, idx /*, options, env */) {
return '</ol>' + getBreak(tokens, idx);

@@ -145,15 +149,16 @@ };

rules.paragraph_open = function (tokens, idx/*, options*/) {
rules.paragraph_open = function (tokens, idx /*, options, env */) {
return tokens[idx].tight ? '' : '<p>';
};
rules.paragraph_close = function (tokens, idx /*, options*/) {
return (tokens[idx].tight ? '' : '</p>') + getBreak(tokens, idx);
rules.paragraph_close = function (tokens, idx /*, options, env */) {
var addBreak = !(tokens[idx].tight && idx && tokens[idx - 1].type === 'inline' && !tokens[idx - 1].content);
return (tokens[idx].tight ? '' : '</p>') + (addBreak ? getBreak(tokens, idx) : '');
};
rules.link_open = function (tokens, idx /*, options*/) {
rules.link_open = function (tokens, idx /*, options, env */) {
var title = tokens[idx].title ? (' title="' + escapeHtml(replaceEntities(tokens[idx].title)) + '"') : '';
return '<a href="' + escapeHtml(escapeUrl(unescapeUrl(replaceEntities(tokens[idx].href)))) + '"' + title + '>';
return '<a href="' + escapeHtml(encodeURI(decodeURI(replaceEntities(tokens[idx].href)))) + '"' + title + '>';
};
rules.link_close = function (/*tokens, idx, options*/) {
rules.link_close = function (/* tokens, idx, options, env */) {
return '</a>';

@@ -163,4 +168,4 @@ };

rules.image = function (tokens, idx, options) {
var src = ' src="' + escapeHtml(escapeUrl(tokens[idx].src)) + '"';
rules.image = function (tokens, idx, options /*, env */) {
var src = ' src="' + escapeHtml(encodeURI(tokens[idx].src)) + '"';
var title = tokens[idx].title ? (' title="' + escapeHtml(replaceEntities(tokens[idx].title)) + '"') : '';

@@ -173,27 +178,27 @@ var alt = ' alt="' + (tokens[idx].alt ? escapeHtml(replaceEntities(tokens[idx].alt)) : '') + '"';

rules.table_open = function (/*tokens, idx, options*/) {
rules.table_open = function (/* tokens, idx, options, env */) {
return '<table>\n';
};
rules.table_close = function (/*tokens, idx, options*/) {
rules.table_close = function (/* tokens, idx, options, env */) {
return '</table>\n';
};
rules.thead_open = function (/*tokens, idx, options*/) {
rules.thead_open = function (/* tokens, idx, options, env */) {
return '<thead>\n';
};
rules.thead_close = function (/*tokens, idx, options*/) {
rules.thead_close = function (/* tokens, idx, options, env */) {
return '</thead>\n';
};
rules.tbody_open = function (/*tokens, idx, options*/) {
rules.tbody_open = function (/* tokens, idx, options, env */) {
return '<tbody>\n';
};
rules.tbody_close = function (/*tokens, idx, options*/) {
rules.tbody_close = function (/* tokens, idx, options, env */) {
return '</tbody>\n';
};
rules.tr_open = function (/*tokens, idx, options*/) {
rules.tr_open = function (/* tokens, idx, options, env */) {
return '<tr>';
};
rules.tr_close = function (/*tokens, idx, options*/) {
rules.tr_close = function (/* tokens, idx, options, env */) {
return '</tr>\n';
};
rules.th_open = function (tokens, idx /*, options*/) {
rules.th_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx];

@@ -204,6 +209,6 @@ return '<th'

};
rules.th_close = function (/*tokens, idx, options*/) {
rules.th_close = function (/* tokens, idx, options, env */) {
return '</th>';
};
rules.td_open = function (tokens, idx /*, options*/) {
rules.td_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx];

@@ -214,3 +219,3 @@ return '<td'

};
rules.td_close = function (/*tokens, idx, options*/) {
rules.td_close = function (/* tokens, idx, options, env */) {
return '</td>';

@@ -220,12 +225,12 @@ };

rules.strong_open = function(/*tokens, idx, options*/) {
rules.strong_open = function (/* tokens, idx, options, env */) {
return '<strong>';
};
rules.strong_close = function(/*tokens, idx, options*/) {
rules.strong_close = function (/* tokens, idx, options, env */) {
return '</strong>';
};
rules.em_open = function(/*tokens, idx, options*/) {
rules.em_open = function (/* tokens, idx, options, env */) {
return '<em>';
};
rules.em_close = function(/*tokens, idx, options*/) {
rules.em_close = function (/* tokens, idx, options, env */) {
return '</em>';

@@ -235,6 +240,6 @@ };

rules.del_open = function(/*tokens, idx, options*/) {
rules.del_open = function (/* tokens, idx, options, env */) {
return '<del>';
};
rules.del_close = function(/*tokens, idx, options*/) {
rules.del_close = function (/* tokens, idx, options, env */) {
return '</del>';

@@ -244,6 +249,6 @@ };

rules.ins_open = function(/*tokens, idx, options*/) {
rules.ins_open = function (/* tokens, idx, options, env */) {
return '<ins>';
};
rules.ins_close = function(/*tokens, idx, options*/) {
rules.ins_close = function (/* tokens, idx, options, env */) {
return '</ins>';

@@ -253,6 +258,6 @@ };

rules.mark_open = function(/*tokens, idx, options*/) {
rules.mark_open = function (/* tokens, idx, options, env */) {
return '<mark>';
};
rules.mark_close = function(/*tokens, idx, options*/) {
rules.mark_close = function (/* tokens, idx, options, env */) {
return '</mark>';

@@ -262,6 +267,6 @@ };

rules.sub = function(tokens, idx/*, options*/) {
rules.sub = function (tokens, idx /*, options, env */) {
return '<sub>' + escapeHtml(tokens[idx].content) + '</sub>';
};
rules.sup = function(tokens, idx/*, options*/) {
rules.sup = function (tokens, idx /*, options, env */) {
return '<sup>' + escapeHtml(tokens[idx].content) + '</sup>';

@@ -271,6 +276,6 @@ };

rules.hardbreak = function (tokens, idx, options) {
rules.hardbreak = function (tokens, idx, options /*, env */) {
return options.xhtmlOut ? '<br />\n' : '<br>\n';
};
rules.softbreak = function (tokens, idx, options) {
rules.softbreak = function (tokens, idx, options /*, env */) {
return options.breaks ? (options.xhtmlOut ? '<br />\n' : '<br>\n') : '\n';

@@ -280,3 +285,3 @@ };

rules.text = function (tokens, idx /*, options*/) {
rules.text = function (tokens, idx /*, options, env */) {
return escapeHtml(tokens[idx].content);

@@ -286,6 +291,6 @@ };

rules.htmlblock = function (tokens, idx /*, options*/) {
rules.htmlblock = function (tokens, idx /*, options, env */) {
return tokens[idx].content;
};
rules.htmltag = function (tokens, idx /*, options*/) {
rules.htmltag = function (tokens, idx /*, options, env */) {
return tokens[idx].content;

@@ -295,2 +300,10 @@ };

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>';
};
// Renderer class

@@ -303,7 +316,8 @@ function Renderer() {

Renderer.prototype.renderInline = function (tokens, options) {
var result = '';
Renderer.prototype.renderInline = function (tokens, options, env) {
var result = '',
_rules = this.rules;
for (var i = 0, len = tokens.length; i < len; i++) {
result += rules[tokens[i].type](tokens, i, options);
result += _rules[tokens[i].type](tokens, i, options, env);
}

@@ -315,3 +329,3 @@

Renderer.prototype.render = function (tokens, options) {
Renderer.prototype.render = function (tokens, options, env) {
var i, len,

@@ -323,5 +337,5 @@ result = '',

if (tokens[i].type === 'inline') {
result += this.renderInline(tokens[i].children, options);
result += this.renderInline(tokens[i].children, options, env);
} else {
result += _rules[tokens[i].type](tokens, i, options);
result += _rules[tokens[i].type](tokens, i, options, env);
}

@@ -328,0 +342,0 @@ }

@@ -12,5 +12,3 @@ // Ruler is helper class to build responsibility chains from parse rules.

function Ruler(compileFn) {
this.compile = compileFn; // callback to call after each change
function Ruler() {
// List of added rules. Each element is:

@@ -26,2 +24,9 @@ //

this.rules = [];
// Cached rule chains.
//
// First level - chain name, '' for default.
// Second level - diginal anchor for fast filtering by charcodes.
//
this.cache = null;
}

@@ -52,3 +57,3 @@

this.rules[index].alt = opt.alt || [];
this.compile();
this.cache = null;
};

@@ -72,3 +77,3 @@

this.compile();
this.cache = null;
};

@@ -92,3 +97,3 @@

this.compile();
this.cache = null;
};

@@ -108,29 +113,6 @@

this.compile();
this.cache = null;
};
// Get rules list as array of functions. By default returns main chain
//
Ruler.prototype.getRules = function (chainName) {
var result = [];
if (!chainName) {
this.rules.forEach(function (rule) {
if (rule.enabled) {
result.push(rule.fn);
}
});
return result;
}
this.rules.forEach(function (rule) {
if (rule.alt.indexOf(chainName) >= 0 && rule.enabled) {
result.push(rule.fn);
}
});
return result;
};
// Enable list of rules by names. If `strict` is true, then all non listed

@@ -160,3 +142,3 @@ // rules will be disabled.

this.compile();
this.cache = null;
};

@@ -181,6 +163,48 @@

this.compile();
this.cache = null;
};
// Build rules lookup cache
//
Ruler.prototype.compile = function () {
var self = this;
var chains = [ '' ];
// collect unique names
self.rules.forEach(function (rule) {
if (!rule.enabled) { return; }
rule.alt.forEach(function (altName) {
if (chains.indexOf(altName) < 0) {
chains.push(altName);
}
});
});
self.cache = {};
chains.forEach(function (chain) {
self.cache[chain] = [];
self.rules.forEach(function (rule) {
if (!rule.enabled) { return; }
if (chain && rule.alt.indexOf(chain) < 0) { return; }
self.cache[chain].push(rule.fn);
});
});
};
// Get rules list as array of functions.
//
Ruler.prototype.getRules = function (chainName) {
if (this.cache === null) {
this.compile();
}
return this.cache[chainName];
};
module.exports = Ruler;

@@ -8,3 +8,4 @@ // Block quotes

var nextLine, lastLineEmpty, oldTShift, oldBMarks, oldIndent, oldParentType, lines,
terminatorRules = state.parser._rulesBlockquoteTerm, i, l, terminate,
terminatorRules,
i, l, terminate,
pos = state.bMarks[startLine] + state.tShift[startLine],

@@ -40,2 +41,4 @@ max = state.eMarks[startLine];

terminatorRules = state.parser.ruler.getRules('blockquote');
// Search the end of the block

@@ -42,0 +45,0 @@ //

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

module.exports = function code(state, startLine, endLine, silent) {
module.exports = function code(state, startLine, endLine/*, silent*/) {
var nextLine, last;

@@ -27,4 +27,2 @@

if (silent) { return true; }
state.line = nextLine;

@@ -31,0 +29,0 @@ state.tokens.push({

@@ -6,3 +6,3 @@ // lheading (---, ===)

module.exports = function lheading(state, startLine, endLine, silent) {
module.exports = function lheading(state, startLine, endLine/*, silent*/) {
var marker, pos, max,

@@ -33,4 +33,2 @@ next = startLine + 1;

if (silent) { return true; }
pos = state.bMarks[startLine] + state.tShift[startLine];

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

@@ -105,3 +105,3 @@ // Lists

tight = true,
terminatorRules = state.parser._rulesListTerm,
terminatorRules,
i, l, terminate;

@@ -154,2 +154,3 @@

prevEmptyEnd = false;
terminatorRules = state.parser.ruler.getRules('list');

@@ -156,0 +157,0 @@ while (nextLine < endLine) {

@@ -6,9 +6,6 @@ // Paragraph

var parseRef = require('../parser_ref');
module.exports = function paragraph(state, startLine/*, endLine*/) {
var endLine, content, pos, terminate, i, l,
var endLine, content, terminate, i, l,
nextLine = startLine + 1,
terminatorRules = state.parser._rulesParagraphTerm;
terminatorRules;

@@ -18,16 +15,20 @@ endLine = state.lineMax;

// jump line-by-line until empty one or EOF
for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {
// this would be a code block normally, but after paragraph
// it's considered a lazy continuation regardless of what's there
if (state.tShift[nextLine] - state.blkIndent > 3) { continue; }
if (nextLine < endLine && !state.isEmpty(nextLine)) {
terminatorRules = state.parser.ruler.getRules('paragraph');
// Some tags can terminate paragraph without empty line.
terminate = false;
for (i = 0, l = terminatorRules.length; i < l; i++) {
if (terminatorRules[i](state, nextLine, endLine, true)) {
terminate = true;
break;
for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {
// this would be a code block normally, but after paragraph
// it's considered a lazy continuation regardless of what's there
if (state.tShift[nextLine] - state.blkIndent > 3) { continue; }
// Some tags can terminate paragraph without empty line.
terminate = false;
for (i = 0, l = terminatorRules.length; i < l; i++) {
if (terminatorRules[i](state, nextLine, endLine, true)) {
terminate = true;
break;
}
}
if (terminate) { break; }
}
if (terminate) { break; }
}

@@ -37,8 +38,2 @@

while (content.length) {
pos = parseRef(content, state.parser.inline, state.options, state.env);
if (pos < 0) { break; }
content = content.slice(pos).trim();
}
state.line = nextLine;

@@ -45,0 +40,0 @@ if (content.length) {

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

function StateBlock(src, parser, tokens, options, env) {
function StateBlock(src, parser, options, env, tokens) {
var ch, s, start, pos, len, indent, indent_found;

@@ -9,0 +9,0 @@

@@ -6,7 +6,7 @@ // GFM table, non-standard

function lineMatch(state, line, reg) {
function getLine(state, line) {
var pos = state.bMarks[line] + state.blkIndent,
max = state.eMarks[line];
return state.src.substr(pos, max - pos).match(reg);
return state.src.substr(pos, max - pos);
}

@@ -16,3 +16,3 @@

module.exports = function table(state, startLine, endLine, silent) {
var ch, firstLineMatch, secondLineMatch, pos, i, nextLine, m, rows,
var ch, lineText, pos, i, nextLine, rows,
aligns, t, tableLines, tbodyLines;

@@ -35,23 +35,33 @@

secondLineMatch = lineMatch(state, startLine + 1,
/^ *\|?(( *[:-]-+[:-] *\|)+( *[:-]-+[:-] *))\|? *$/);
if (!secondLineMatch) { return false; }
lineText = getLine(state, startLine + 1);
if (!/^[-:| ]+$/.test(lineText)) { return false; }
rows = secondLineMatch[1].split('|');
rows = lineText.split('|');
if (rows <= 2) { return false; }
aligns = [];
for (i = 0; i < rows.length; i++) {
t = rows[i].trim();
if (!t) {
// allow empty columns before and after table, but not in between columns;
// e.g. allow ` |---| `, disallow ` ---||--- `
if (i === 0 || i === rows.length - 1) {
continue;
} else {
return false;
}
}
if (!/^:?-+:?$/.test(t)) { return false; }
if (t.charCodeAt(t.length - 1) === 0x3A/* : */) {
aligns[i] = t.charCodeAt(0) === 0x3A/* : */ ? 'center' : 'right';
aligns.push(t.charCodeAt(0) === 0x3A/* : */ ? 'center' : 'right');
} else if (t.charCodeAt(0) === 0x3A/* : */) {
aligns[i] = 'left';
aligns.push('left');
} else {
aligns[i] = '';
aligns.push('');
}
}
firstLineMatch = lineMatch(state, startLine, /^ *\|?(.*?\|.*?)\|? *$/);
if (!firstLineMatch) { return false; }
rows = firstLineMatch[1].split('|');
lineText = getLine(state, startLine).trim();
if (lineText.indexOf('|') === -1) { return false; }
rows = lineText.replace(/^\||\|$/g, '').split('|');
if (aligns.length !== rows.length) { return false; }

@@ -104,5 +114,5 @@ if (silent) { return true; }

m = lineMatch(state, nextLine, /^ *\|?(.*?\|.*?)\|? *$/);
if (!m) { break; }
rows = m[1].split('|');
lineText = getLine(state, nextLine).trim();
if (lineText.indexOf('|') === -1) { break; }
rows = lineText.replace(/^\||\|$/g, '').split('|');

@@ -109,0 +119,0 @@ state.tokens.push({ type: 'tr_open', level: state.level++ });

@@ -5,6 +5,6 @@ // Process [links](<to> "stuff")

var parseLinkLabel = require('../links').parseLinkLabel;
var parseLinkDestination = require('../links').parseLinkDestination;
var parseLinkTitle = require('../links').parseLinkTitle;
var normalizeReference = require('../links').normalizeReference;
var parseLinkLabel = require('../helpers/parse_link_label');
var parseLinkDestination = require('../helpers/parse_link_destination');
var parseLinkTitle = require('../helpers/parse_link_title');
var normalizeReference = require('../helpers/normalize_reference');

@@ -11,0 +11,0 @@

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

function StateInline(src, parser, options, env) {
function StateInline(src, parserInline, options, env, outTokens) {
this.src = src;
this.env = env;
this.options = options;
this.parser = parser;
this.tokens = [];
this.parser = parserInline;
this.tokens = outTokens;
this.pos = 0;

@@ -14,0 +14,0 @@ this.posMax = this.src.length;

@@ -6,14 +6,49 @@ // Skip text characters for text token, place those to pending buffer

// Rule to skip pure text
// '{}$%@~+=:' reserved for extentions
function isTerminatorChar(ch) {
switch (ch) {
case 0x0A/* \n */:
case 0x5C/* \ */:
case 0x60/* ` */:
case 0x2A/* * */:
case 0x5F/* _ */:
case 0x5E/* ^ */:
case 0x5B/* [ */:
case 0x5D/* ] */:
case 0x21/* ! */:
case 0x26/* & */:
case 0x3C/* < */:
case 0x3E/* > */:
case 0x7B/* { */:
case 0x7D/* } */:
case 0x24/* $ */:
case 0x25/* % */:
case 0x40/* @ */:
case 0x7E/* ~ */:
case 0x2B/* + */:
case 0x3D/* = */:
case 0x3A/* : */:
return true;
default:
return false;
}
}
module.exports = function text(state, silent) {
var str = state.src.slice(state.pos),
next = str.search(state.parser.textMatch);
var pos = state.pos;
if (next === 0) { return false; }
while (pos < state.posMax && !isTerminatorChar(state.src.charCodeAt(pos))) {
pos++;
}
if (next < 0) { next = str.length; }
if (pos === state.pos) { return false; }
if (!silent) { state.pending += str.slice(0, next); }
state.pos += next;
if (!silent) { state.pending += state.src.slice(state.pos, pos); }
state.pos = pos;
return true;
};
{
"name": "remarkable",
"version": "1.3.0",
"version": "1.4.0",
"description": "Markdown parser, done right. Commonmark support, extensions, syntax plugins, high speed - all in one.",

@@ -5,0 +5,0 @@ "keywords": [

@@ -11,6 +11,6 @@ # remarkable

- Supports the [CommonMark](http://commonmark.org/) spec + extentions
(URL autolinking, typographer).
- Supports the [CommonMark](http://commonmark.org/) spec +
[syntax extensions](#syntax-extensions) + sugar (URL autolinking, typographer).
- Configurable syntax! You can add new rules and even replace existing ones.
- High speed! See the [benchmarks](./benchmark).
- [High speed](#benchmark)!

@@ -67,4 +67,10 @@

linkify: false, // Autoconvert URL-like text to links
typographer: false, // Enable smartypants and other sweet transforms
// Enable some language-neutral replacement + quotes beautification
typographer: false,
// Double + single quotes replacement pairs, when typographer enabled,
// and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.
quotes: '“”‘’',
// Highlighter function. Should return escaped HTML,

@@ -157,3 +163,3 @@ // or '' if the source string is not changed

### Syntax extentions
### Syntax extensions

@@ -168,8 +174,9 @@ Enabled by default:

- [\<sup](http://johnmacfarlane.net/pandoc/README.html#superscripts-and-subscripts) - `19^th^`
- [\<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)
- __\<ins>__ - `++inserted text++` (experimental)
- __\<mark>__ - `==marked text==` (experimental)
__*__ Experimental extentions can be changed later for something like
__*__ Experimental extensions can be changed later for something like
[Critic Markup](http://criticmarkup.com/), but you will still be able to use

@@ -202,17 +209,23 @@ old-style rules via external plugins if you prefer.

var Remarkable = require('remarkable');
var md = new Remarkable({ typographer: true });
var md = new Remarkable({
typographer: true,
quotes: '“”‘’'
});
// Actual default values
md.typographer.set({
singleQuotes: '‘’', // set empty to disable
doubleQuotes: '“”', // set '«»' for Russian, '„“' for German, empty to disable
copyright: true, // (c) (C) → ©
trademark: true, // (tm) (TM) → ™
registered: true, // (r) (R) → ®
plusminus: true, // +- → ±
paragraph: true, // (p) (P) -> §
ellipsis: true, // ... → … (also ?.... → ?.., !.... → !..)
dupes: true, // ???????? → ???, !!!!! → !!!, `,,` → `,`
dashes: true // -- → &ndash;, --- → &mdash;
})
// Disable rules at all:
md.core.ruler.disable([ 'replacements', 'smartquotes' ]);
// Actual default replacements:
//
// '' → ‘’
// "" → “”. Set '«»' for Russian, '„“' for German, empty to disable
// (c) (C) → ©
// (tm) (TM) → ™
// (r) (R) → ®
// +- → ±
// (p) (P) -> §
// ... → … (also ?.... → ?.., !.... → !..)
// ???????? → ???, !!!!! → !!!, `,,` → `,`
// -- → &ndash;, --- → &mdash;
//
```

@@ -258,2 +271,4 @@

```js
Remarkable.core
Remarkable.core.ruler
Remarkable.block

@@ -263,6 +278,2 @@ Remarkable.block.ruler

Remarkable.inline.ruler
Remarkable.typographer
Remarkable.typographer.ruler
Remarkable.linkifier
Remarkable.linkifier.ruler
Remarkable.renderer

@@ -272,3 +283,22 @@ Remarkable.renderer.rules

## Benchmark
Here is result of CommonMark spec parse at Core i5 2.4 GHz (i5-4258U):
```bash
$ benchmark/benchmark.js spec
Selected samples: (1 of 27)
> spec
Sample: spec.txt (110610 bytes)
> commonmark-reference x 40.42 ops/sec ±4.07% (51 runs sampled)
> current x 74.99 ops/sec ±4.69% (67 runs sampled)
> current-commonmark x 93.76 ops/sec ±1.23% (79 runs sampled)
> marked-0.3.2 x 22.92 ops/sec ±0.79% (41 runs sampled)
```
As you can see, `remarkabe` doesn't pay with speed for it's flexibility. Because
it's written in monomorphyc style and use JIT inline caches effectively.
## Authors

@@ -275,0 +305,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