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 3.0.7 to 3.1.0

12

CHANGELOG.md

@@ -0,1 +1,13 @@

3.1.0 / 2015-03-05
------------------
- Significantly improved autolinking quality (use `linkify-it` package), #2.
- Rewritten links normalizer to solve different edge cases (use `mdurl`
package), #29.
- Moved link title entities replace out of renderer.
- Fixed escaped entities in links (`foo\&/bar`).
- Improved smartquotes logic, #61.
- Spec conformance update to 0.18.
3.0.7 / 2015-02-22

@@ -2,0 +14,0 @@ ------------------

86

lib/common/utils.js

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

var UNESCAPE_MD_RE = /\\([!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])/g;
function unescapeMd(str) {
if (str.indexOf('\\') < 0) { return str; }
return str.replace(UNESCAPE_MD_RE, '$1');
}
////////////////////////////////////////////////////////////////////////////////
function isValidEntityCode(c) {

@@ -83,4 +74,9 @@ /*eslint no-bitwise:0*/

var NAMED_ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi;
var UNESCAPE_MD_RE = /\\([!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])/g;
var ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi;
var UNESCAPE_ALL_RE = new RegExp(UNESCAPE_MD_RE.source + '|' + ENTITY_RE.source, 'gi');
var DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i;
var entities = require('./entities');

@@ -108,5 +104,19 @@

return str.replace(NAMED_ENTITY_RE, replaceEntityPattern);
return str.replace(ENTITY_RE, replaceEntityPattern);
}
function unescapeMd(str) {
if (str.indexOf('\\') < 0) { return str; }
return str.replace(UNESCAPE_MD_RE, '$1');
}
function unescapeAll(str) {
if (str.indexOf('\\') < 0 && str.indexOf('&') < 0) { return str; }
return str.replace(UNESCAPE_ALL_RE, function(match, escaped, entity) {
if (escaped) { return escaped; }
return replaceEntityPattern(match, entity);
});
}
////////////////////////////////////////////////////////////////////////////////

@@ -136,33 +146,4 @@

var SURRORATE_TEST_RE = /[\uD800-\uDFFF]/;
var SURRORATE_SEARCH_RE = /[\uD800-\uDFFF]/g;
var encode = require('mdurl/encode');
function replaceBadSurrogate(ch, pos, orig) {
var code = ch.charCodeAt(0);
if (code >= 0xD800 && code <= 0xDBFF) {
// high surrogate
if (pos >= orig.length - 1) { return '\uFFFD'; }
code = orig.charCodeAt(pos + 1);
if (code < 0xDC00 || code > 0xDFFF) { return '\uFFFD'; }
return ch;
}
// low surrogate
if (pos === 0) { return '\uFFFD'; }
code = orig.charCodeAt(pos - 1);
if (code < 0xD800 || code > 0xDBFF) { return '\uFFFD'; }
return ch;
}
function fixBrokenSurrogates(str) {
if (!SURRORATE_TEST_RE.test(str)) { return str; }
return str.replace(SURRORATE_SEARCH_RE, replaceBadSurrogate);
}
////////////////////////////////////////////////////////////////////////////////
// Incoming link can be partially encoded. Convert possible combinations to

@@ -178,20 +159,3 @@ // unified form.

function normalizeLink(url) {
var normalized = replaceEntities(url);
// We don't care much about result of mailformed URIs,
// but shoud not throw exception.
try {
normalized = decodeURI(normalized);
} catch (__) {}
// Encoder throws exception on broken surrogate pairs.
// Fix those first.
try {
return encodeURI(fixBrokenSurrogates(normalized));
} catch (__) {
// This should never happen and left for safety only.
/*istanbul ignore next*/
return '';
}
return encode(url);
}

@@ -302,2 +266,3 @@

exports.unescapeMd = unescapeMd;
exports.unescapeAll = unescapeAll;
exports.isValidEntityCode = isValidEntityCode;

@@ -314,4 +279,1 @@ exports.fromCodePoint = fromCodePoint;

exports.normalizeReference = normalizeReference;
// for testing only
exports.fixBrokenSurrogates = fixBrokenSurrogates;

@@ -7,3 +7,3 @@ // Parse link destination

var normalizeLink = require('../common/utils').normalizeLink;
var unescapeMd = require('../common/utils').unescapeMd;
var unescapeAll = require('../common/utils').unescapeAll;

@@ -29,3 +29,3 @@

result.pos = pos + 1;
result.str = normalizeLink(unescapeMd(str.slice(start + 1, pos)));
result.str = normalizeLink(unescapeAll(str.slice(start + 1, pos)));
result.ok = true;

@@ -77,3 +77,3 @@ return result;

result.str = normalizeLink(unescapeMd(str.slice(start, pos)));
result.str = normalizeLink(unescapeAll(str.slice(start, pos)));
result.lines = lines;

@@ -80,0 +80,0 @@ result.pos = pos;

@@ -6,3 +6,3 @@ // Parse link title

var unescapeMd = require('../common/utils').unescapeMd;
var unescapeAll = require('../common/utils').unescapeAll;

@@ -38,3 +38,3 @@

result.lines = lines;
result.str = unescapeMd(str.slice(start + 1, pos));
result.str = unescapeAll(str.slice(start + 1, pos));
result.ok = true;

@@ -41,0 +41,0 @@ return result;

@@ -12,2 +12,3 @@ // Main perser class

var ParserInline = require('./parser_inline');
var LinkifyIt = require('linkify-it');

@@ -196,2 +197,11 @@ var config = {

/**
* MarkdownIt#linkify -> LinkifyIt
*
* [linkify-it](https://github.com/markdown-it/linkify-it) instance.
* Used by [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js)
* rule.
**/
this.linkify = new LinkifyIt();
// Expose utils & helpers for easy acces from plugins

@@ -376,6 +386,6 @@

*
* `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.
* `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
* inject data in specific cases. Usually, you will be ok to pass `{}`,
* and then pass updated object to renderer.
**/

@@ -415,4 +425,4 @@ MarkdownIt.prototype.parse = function (src, env) {

* The same as [[MarkdownIt.parse]] but skip all block rules. It returns the
* block tokens list with th single `inline` element, containing parsed inline
* tokens in `children` property.
* block tokens list with the single `inline` element, containing parsed inline
* tokens in `children` property. Also updates `env` object.
**/

@@ -419,0 +429,0 @@ MarkdownIt.prototype.parseInline = function (src, env) {

@@ -12,4 +12,3 @@ /**

var assign = require('./common/utils').assign;
var unescapeMd = require('./common/utils').unescapeMd;
var replaceEntities = require('./common/utils').replaceEntities;
var unescapeAll = require('./common/utils').unescapeAll;
var escapeHtml = require('./common/utils').escapeHtml;

@@ -43,3 +42,3 @@

if (token.params) {
langName = escapeHtml(replaceEntities(unescapeMd(token.params.split(/\s+/g)[0])));
langName = escapeHtml(unescapeAll(token.params.split(/\s+/g)[0]));
langClass = ' class="' + langPrefix + langName + '"';

@@ -106,3 +105,3 @@ }

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

@@ -118,3 +117,3 @@ return '<a href="' + escapeHtml(tokens[idx].href) + '"' + title + target + '>';

var src = ' src="' + escapeHtml(tokens[idx].src) + '"';
var title = tokens[idx].title ? (' title="' + escapeHtml(replaceEntities(tokens[idx].title)) + '"') : '';
var title = tokens[idx].title ? (' title="' + escapeHtml(tokens[idx].title) + '"') : '';
var alt = ' alt="' + self.renderInlineAsText(tokens[idx].tokens, options, env) + '"';

@@ -121,0 +120,0 @@ var suffix = options.xhtmlOut ? ' /' : '';

@@ -149,2 +149,4 @@ 'use strict';

// Reference can not terminate anything. This check is for safety only.
/*istanbul ignore if*/
if (silent) { return true; }

@@ -151,0 +153,0 @@

@@ -8,9 +8,6 @@ // Replace link-like texts with link nodes.

var Autolinker = require('autolinker');
var arrayReplaceAt = require('../common/utils').arrayReplaceAt;
var normalizeLink = require('../common/utils').normalizeLink;
var LINK_SCAN_RE = /www|@|\:\/\//;
function isLinkOpen(str) {

@@ -23,45 +20,7 @@ return /^<a[>\s]/i.test(str);

// Stupid fabric to avoid singletons, for thread safety.
// Required for engines like Nashorn.
//
function createLinkifier() {
var links = [];
var autolinker = new Autolinker({
stripPrefix: false,
url: true,
email: true,
twitter: false,
replaceFn: function (__, match) {
// Only collect matched strings but don't change anything.
switch (match.getType()) {
/*eslint default-case:0*/
case 'url':
links.push({
text: match.matchedText,
url: match.getUrl()
});
break;
case 'email':
links.push({
text: match.matchedText,
// normalize email protocol
url: 'mailto:' + match.getEmail().replace(/^mailto:/i, '')
});
break;
}
return false;
}
});
return {
links: links,
autolinker: autolinker
};
}
module.exports = function linkify(state) {
var i, j, l, tokens, token, text, nodes, ln, pos, level, htmlLinkLevel,
var i, j, l, tokens, token, nodes, ln, text, pos, lastPos, level, htmlLinkLevel,
blockTokens = state.tokens,
linkifier = null, links, autolinker;
links;

@@ -72,2 +31,3 @@ if (!state.md.options.linkify) { return; }

if (blockTokens[j].type !== 'inline') { continue; }
tokens = blockTokens[j].children;

@@ -102,20 +62,11 @@

if (token.type === 'text' && LINK_SCAN_RE.test(token.content)) {
if (token.type === 'text' && state.md.linkify.test(token.content)) {
// Init linkifier in lazy manner, only if required.
if (!linkifier) {
linkifier = createLinkifier();
links = linkifier.links;
autolinker = linkifier.autolinker;
}
text = token.content;
links.length = 0;
autolinker.link(text);
links = state.md.linkify.match(text);
if (!links.length) { continue; }
// Now split string to nodes
nodes = [];
level = token.level;
lastPos = 0;

@@ -126,9 +77,9 @@ for (ln = 0; ln < links.length; ln++) {

pos = text.indexOf(links[ln].text);
pos = links[ln].index;
if (pos) {
if (pos > lastPos) {
level = level;
nodes.push({
type: 'text',
content: text.slice(0, pos),
content: text.slice(lastPos, pos),
level: level

@@ -139,3 +90,3 @@ });

type: 'link_open',
href: links[ln].url,
href: normalizeLink(links[ln].url),
target: '',

@@ -154,8 +105,8 @@ title: '',

});
text = text.slice(pos + links[ln].text.length);
lastPos = links[ln].lastIndex;
}
if (text.length) {
if (lastPos < text.length) {
nodes.push({
type: 'text',
content: text,
content: text.slice(lastPos),
level: level

@@ -162,0 +113,0 @@ });

@@ -6,15 +6,11 @@ // Convert straight quotation marks to typographic ones

var isWhiteSpace = require('../common/utils').isWhiteSpace;
var isPunctChar = require('../common/utils').isPunctChar;
var isMdAsciiPunct = require('../common/utils').isMdAsciiPunct;
var QUOTE_TEST_RE = /['"]/;
var QUOTE_RE = /['"]/g;
var PUNCT_RE = /[-\s()\[\]]/;
var APOSTROPHE = '\u2019'; /* ’ */
// This function returns true if the character at `pos`
// could be inside a word.
function isLetter(str, pos) {
if (pos < 0 || pos >= str.length) { return false; }
return !PUNCT_RE.test(str[pos]);
}
function replaceAt(str, index, ch) {

@@ -27,5 +23,5 @@ return str.substr(0, index) + ch + str.substr(index + 1);

/*eslint max-depth:0*/
var i, token, text, t, pos, max, thisLevel, lastSpace, nextSpace, item,
canOpen, canClose, j, isSingle, blkIdx, tokens,
stack;
var i, token, text, t, pos, max, thisLevel, item, lastChar, nextChar,
isLastPunctChar, isNextPunctChar, isLastWhiteSpace, isNextWhiteSpace,
canOpen, canClose, j, isSingle, blkIdx, tokens, stack;

@@ -66,8 +62,47 @@ if (!state.md.options.typographer) { return; }

lastSpace = !isLetter(text, t.index - 1);
canOpen = canClose = true;
pos = t.index + 1;
isSingle = (t[0] === "'");
nextSpace = !isLetter(text, pos);
if (!nextSpace && !lastSpace) {
lastChar = t.index - 1 >= 0 ? text.charCodeAt(t.index - 1) : -1;
nextChar = pos < max ? text.charCodeAt(pos) : -1;
isLastPunctChar = lastChar >= 0 &&
(isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar)));
isNextPunctChar = nextChar >= 0 &&
(isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)));
// begin/end of the line counts as a whitespace too
isLastWhiteSpace = lastChar < 0 || isWhiteSpace(lastChar);
isNextWhiteSpace = nextChar < 0 || isWhiteSpace(nextChar);
if (isNextWhiteSpace) {
canOpen = false;
} else if (isNextPunctChar) {
if (!(isLastWhiteSpace || isLastPunctChar)) {
canOpen = false;
}
}
if (isLastWhiteSpace) {
canClose = false;
} else if (isLastPunctChar) {
if (!(isNextWhiteSpace || isNextPunctChar)) {
canClose = false;
}
}
if (nextChar === 0x22 /* " */ && t[0] === '"') {
if (lastChar >= 0x30 /* 0 */ && lastChar <= 0x39 /* 9 */) {
// special case: 1"" - count first quote as an inch
canClose = canOpen = false;
}
}
if (canOpen && canClose) {
// treat this as the middle of the word
canOpen = canClose = false;
}
if (!canOpen && !canClose) {
// middle of word

@@ -80,5 +115,2 @@ if (isSingle) {

canOpen = !nextSpace;
canClose = !lastSpace;
if (canClose) {

@@ -85,0 +117,0 @@ // this could be a closing quote, rewind the stack to get a match

@@ -11,8 +11,2 @@ // Process *this* and _that_

function isAlphaNum(code) {
return (code >= 0x30 /* 0 */ && code <= 0x39 /* 9 */) ||
(code >= 0x41 /* A */ && code <= 0x5A /* Z */) ||
(code >= 0x61 /* a */ && code <= 0x7A /* z */);
}
// parse sequence of emphasis markers,

@@ -41,9 +35,11 @@ // "start" should point at a valid marker

(isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)));
isLastWhiteSpace = lastChar >= 0 && isWhiteSpace(lastChar);
isNextWhiteSpace = nextChar >= 0 && isWhiteSpace(nextChar);
// begin/end of the line counts as a whitespace too
isLastWhiteSpace = lastChar < 0 || isWhiteSpace(lastChar);
isNextWhiteSpace = nextChar < 0 || isWhiteSpace(nextChar);
if (isNextWhiteSpace) {
can_open = false;
} else if (isNextPunctChar) {
if (!(isLastWhiteSpace || isLastPunctChar || lastChar === -1)) {
if (!(isLastWhiteSpace || isLastPunctChar)) {
can_open = false;

@@ -56,3 +52,3 @@ }

} else if (isLastPunctChar) {
if (!(isNextWhiteSpace || isNextPunctChar || nextChar === -1)) {
if (!(isNextWhiteSpace || isNextPunctChar)) {
can_close = false;

@@ -63,5 +59,6 @@ }

if (marker === 0x5F /* _ */) {
// check if we aren't inside the word
if (isAlphaNum(lastChar)) { can_open = false; }
if (isAlphaNum(nextChar)) { can_close = false; }
if (can_open && can_close) {
// "_" inside a word can neither open nor close an emphasis
can_open = can_close = false;
}
}

@@ -68,0 +65,0 @@

{
"name": "markdown-it",
"version": "3.0.7",
"version": "3.1.0",
"description": "Markdown-it - modern pluggable markdown parser.",

@@ -13,9 +13,3 @@ "keywords": [

"homepage": "https://github.com/markdown-it/markdown-it",
"repository": {
"type": "git",
"url": "git://github.com/markdown-it/markdown-it.git"
},
"bugs": {
"url": "https://github.com/markdown-it/markdown-it/issues"
},
"repository": "markdown-it/markdown-it",
"license": "MIT",

@@ -29,3 +23,4 @@ "main": "index.js",

"argparse": "~ 1.0.0",
"autolinker": "~ 0.15.2",
"linkify-it": "~ 0.1.2",
"mdurl": "~ 1.0.0",
"uc.micro": "~ 0.1.0"

@@ -38,4 +33,4 @@ },

"browserify": "*",
"chai": "~1.10.0",
"commonmark": "~ 0.17.1",
"chai": "~2.1.0",
"commonmark": "~0.18.1",
"coveralls": "~2.11.2",

@@ -42,0 +37,0 @@ "eslint": "0.13.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