remarkable
Advanced tools
Comparing version 1.4.2 to 1.5.0
@@ -50,7 +50,7 @@ #!/usr/bin/env node | ||
readFile(options.file, 'utf8', function (error, input) { | ||
readFile(options.file, 'utf8', function (err, input) { | ||
var output, md; | ||
if (error) { | ||
if (error.code === 'ENOENT') { | ||
if (err) { | ||
if (err.code === 'ENOENT') { | ||
console.error('File not found: ' + options.file); | ||
@@ -60,3 +60,3 @@ process.exit(2); | ||
console.error(error.stack || error.message || String(error)); | ||
console.error(err.stack || err.message || String(err)); | ||
@@ -76,4 +76,4 @@ process.exit(1); | ||
} catch (error) { | ||
console.error(error.stack || error.message || String(error)); | ||
} catch (e) { | ||
console.error(e.stack || e.message || String(e)); | ||
@@ -80,0 +80,0 @@ process.exit(1); |
@@ -0,1 +1,12 @@ | ||
1.5.0 / 2014-12-12 | ||
------------------ | ||
- Added Demo sync scroll, to show how lines mapping can be used. | ||
- Improved IE8 support. Now you need only es5-shim, without es5-sham. | ||
- Fixed errors on refs/attrs/footnoted with special names like `__proto__`. | ||
- Renamed Ruler() private properties, to show those should not be accessed | ||
directly. | ||
- Fixed Makefile OSX compatibility. | ||
1.4.2 / 2014-11-29 | ||
@@ -2,0 +13,0 @@ ------------------ |
'use strict'; | ||
module.exports = function normalizeReference(str) { | ||
return str.trim().replace(/\s+/g, ' ').toLowerCase(); | ||
// use .toUpperCase() instead of .toLowerCase() | ||
// here to avoid a conflict with Object.prototype | ||
// members (most notably, `__proto__`) | ||
return str.trim().replace(/\s+/g, ' ').toUpperCase(); | ||
}; |
125
lib/ruler.js
@@ -22,3 +22,3 @@ // Ruler is helper class to build responsibility chains from parse rules. | ||
// | ||
this.rules = []; | ||
this.__rules__ = []; | ||
@@ -30,11 +30,14 @@ // Cached rule chains. | ||
// | ||
this.cache = null; | ||
this.__cache__ = null; | ||
} | ||
//////////////////////////////////////////////////////////////////////////////// | ||
// Helper methods, should not be used directly | ||
// Find rule index by name | ||
// | ||
Ruler.prototype.find = function (name) { | ||
for (var i = 0; i < this.rules.length; i++) { | ||
if (this.rules[i].name === name) { | ||
Ruler.prototype.__find__ = function (name) { | ||
for (var i = 0; i < this.__rules__.length; i++) { | ||
if (this.__rules__[i].name === name) { | ||
return i; | ||
@@ -47,6 +50,42 @@ } | ||
// 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); | ||
}); | ||
}); | ||
}; | ||
//////////////////////////////////////////////////////////////////////////////// | ||
// Public methods | ||
// Replace rule function | ||
// | ||
Ruler.prototype.at = function (name, fn, options) { | ||
var index = this.find(name); | ||
var index = this.__find__(name); | ||
var opt = options || {}; | ||
@@ -56,5 +95,5 @@ | ||
this.rules[index].fn = fn; | ||
this.rules[index].alt = opt.alt || []; | ||
this.cache = null; | ||
this.__rules__[index].fn = fn; | ||
this.__rules__[index].alt = opt.alt || []; | ||
this.__cache__ = null; | ||
}; | ||
@@ -66,3 +105,3 @@ | ||
Ruler.prototype.before = function (beforeName, ruleName, fn, options) { | ||
var index = this.find(beforeName); | ||
var index = this.__find__(beforeName); | ||
var opt = options || {}; | ||
@@ -72,3 +111,3 @@ | ||
this.rules.splice(index, 0, { | ||
this.__rules__.splice(index, 0, { | ||
name: ruleName, | ||
@@ -80,3 +119,3 @@ enabled: true, | ||
this.cache = null; | ||
this.__cache__ = null; | ||
}; | ||
@@ -88,3 +127,3 @@ | ||
Ruler.prototype.after = function (afterName, ruleName, fn, options) { | ||
var index = this.find(afterName); | ||
var index = this.__find__(afterName); | ||
var opt = options || {}; | ||
@@ -94,3 +133,3 @@ | ||
this.rules.splice(index + 1, 0, { | ||
this.__rules__.splice(index + 1, 0, { | ||
name: ruleName, | ||
@@ -102,3 +141,3 @@ enabled: true, | ||
this.cache = null; | ||
this.__cache__ = null; | ||
}; | ||
@@ -111,3 +150,3 @@ | ||
this.rules.push({ | ||
this.__rules__.push({ | ||
name: ruleName, | ||
@@ -119,3 +158,3 @@ enabled: true, | ||
this.cache = null; | ||
this.__cache__ = null; | ||
}; | ||
@@ -134,3 +173,3 @@ | ||
if (strict) { | ||
this.rules.forEach(function (rule) { | ||
this.__rules__.forEach(function (rule) { | ||
rule.enabled = false; | ||
@@ -142,10 +181,10 @@ }); | ||
list.forEach(function (name) { | ||
var idx = this.find(name); | ||
var idx = this.__find__(name); | ||
if (idx < 0) { throw new Error('Rules manager: invalid rule name ' + name); } | ||
this.rules[idx].enabled = true; | ||
this.__rules__[idx].enabled = true; | ||
}, this); | ||
this.cache = null; | ||
this.__cache__ = null; | ||
}; | ||
@@ -163,55 +202,23 @@ | ||
list.forEach(function (name) { | ||
var idx = this.find(name); | ||
var idx = this.__find__(name); | ||
if (idx < 0) { throw new Error('Rules manager: invalid rule name ' + name); } | ||
this.rules[idx].enabled = false; | ||
this.__rules__[idx].enabled = false; | ||
}, this); | ||
this.cache = null; | ||
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(); | ||
if (this.__cache__ === null) { | ||
this.__compile__(); | ||
} | ||
return this.cache[chainName]; | ||
return this.__cache__[chainName]; | ||
}; | ||
module.exports = Ruler; |
@@ -31,5 +31,5 @@ // Process footnote reference list | ||
if (!state.env.footnotes) { state.env.footnotes = {}; } | ||
if (!state.env.footnotes.refs) { state.env.footnotes.refs = Object.create(null); } | ||
if (!state.env.footnotes.refs) { state.env.footnotes.refs = {}; } | ||
label = state.src.slice(start + 2, pos - 2); | ||
state.env.footnotes.refs[label] = -1; | ||
state.env.footnotes.refs[':' + label] = -1; | ||
@@ -36,0 +36,0 @@ state.tokens.push({ |
@@ -31,4 +31,4 @@ // heading (#, ##, ...) | ||
max = state.skipCharsBack(max, 0x20/* space */, pos); | ||
tmp = state.skipCharsBack(max, 0x23/* # */, pos); | ||
max = state.skipCharsBack(max, 0x20, pos); // space | ||
tmp = state.skipCharsBack(max, 0x23, pos); // # | ||
if (tmp > pos && state.src.charCodeAt(tmp - 1) === 0x20/* space */) { | ||
@@ -35,0 +35,0 @@ max = tmp; |
@@ -185,4 +185,2 @@ // Lists | ||
//nextLine++; | ||
oldIndent = state.blkIndent; | ||
@@ -189,0 +187,0 @@ oldTight = state.tight; |
@@ -35,3 +35,6 @@ // Parse abbreviation definitions, i.e. `*[abbr]: description` | ||
if (!env.abbreviations) { env.abbreviations = {}; } | ||
env.abbreviations[label] = env.abbreviations[label] || title; | ||
// prepend ':' to avoid conflict with Object.prototype members | ||
if (typeof env.abbreviations[':' + label] === 'undefined') { | ||
env.abbreviations[':' + label] = title; | ||
} | ||
@@ -38,0 +41,0 @@ return pos; |
@@ -23,3 +23,5 @@ // Enclose abbreviations in <abbr> tags | ||
regText = '(^|[' + PUNCT_CHARS.split('').map(regEscape).join('') + '])' | ||
+ '(' + Object.keys(state.env.abbreviations).sort(function (a, b) { | ||
+ '(' + Object.keys(state.env.abbreviations).map(function (x) { | ||
return x.substr(1); | ||
}).sort(function (a, b) { | ||
return b.length - a.length; | ||
@@ -58,3 +60,3 @@ }).map(regEscape).join('|') + ')' | ||
type: 'abbr_open', | ||
title: state.env.abbreviations[m[2]], | ||
title: state.env.abbreviations[':' + m[2]], | ||
level: level++ | ||
@@ -61,0 +63,0 @@ }); |
@@ -8,3 +8,3 @@ 'use strict'; | ||
insideRef = false, | ||
refTokens = Object.create(null); | ||
refTokens = {}; | ||
@@ -22,3 +22,4 @@ if (!state.env.footnotes) { return; } | ||
insideRef = false; | ||
refTokens[currentLabel] = current; | ||
// prepend ':' to avoid conflict with Object.prototype members | ||
refTokens[':' + currentLabel] = current; | ||
return false; | ||
@@ -63,3 +64,3 @@ } | ||
} else if (list[i].label) { | ||
tokens = refTokens[list[i].label]; | ||
tokens = refTokens[':' + list[i].label]; | ||
} | ||
@@ -66,0 +67,0 @@ |
@@ -61,3 +61,5 @@ 'use strict'; | ||
label = normalizeReference(str.slice(1, labelEnd)); | ||
env.references[label] = env.references[label] || { title: title, href: href }; | ||
if (typeof env.references[label] === 'undefined') { | ||
env.references[label] = { title: title, href: href }; | ||
} | ||
@@ -64,0 +66,0 @@ return pos; |
@@ -32,3 +32,3 @@ // Parse backticks | ||
content: state.src.slice(pos, matchStart) | ||
.replace(/[ \n]+/g,' ') | ||
.replace(/[ \n]+/g, ' ') | ||
.trim(), | ||
@@ -35,0 +35,0 @@ block: false, |
@@ -53,3 +53,3 @@ // Process ~~deleted text~~ | ||
// // standalone ' ~~ ' indented with spaces | ||
//} | ||
// } | ||
if (stack <= 0) { | ||
@@ -56,0 +56,0 @@ found = true; |
@@ -35,3 +35,3 @@ // Process footnote references ([^...]) | ||
label = state.src.slice(start + 2, pos - 1); | ||
if (state.env.footnotes.refs[label] === undefined) { return false; } | ||
if (typeof state.env.footnotes.refs[':' + label] === 'undefined') { return false; } | ||
@@ -41,8 +41,8 @@ if (!silent) { | ||
if (state.env.footnotes.refs[label] < 0) { | ||
if (state.env.footnotes.refs[':' + label] < 0) { | ||
footnoteId = state.env.footnotes.list.length; | ||
state.env.footnotes.list[footnoteId] = { label: label, count: 0 }; | ||
state.env.footnotes.refs[label] = footnoteId; | ||
state.env.footnotes.refs[':' + label] = footnoteId; | ||
} else { | ||
footnoteId = state.env.footnotes.refs[label]; | ||
footnoteId = state.env.footnotes.refs[':' + label]; | ||
} | ||
@@ -49,0 +49,0 @@ |
@@ -53,3 +53,3 @@ // Process ++inserted text++ | ||
// // standalone ' ++ ' indented with spaces | ||
//} | ||
// } | ||
if (stack <= 0) { | ||
@@ -56,0 +56,0 @@ found = true; |
@@ -53,3 +53,3 @@ // Process ==highlighted text== | ||
// // standalone ' == ' indented with spaces | ||
//} | ||
// } | ||
if (stack <= 0) { | ||
@@ -56,0 +56,0 @@ found = true; |
{ | ||
"name": "remarkable", | ||
"version": "1.4.2", | ||
"version": "1.5.0", | ||
"description": "Markdown parser, done right.", | ||
@@ -34,3 +34,3 @@ "keywords": [ | ||
"coveralls": "^2.11.2", | ||
"eslint": "0.9.1", | ||
"eslint": "0.10.1", | ||
"eslint-plugin-nodeca": "^1.0.0", | ||
@@ -37,0 +37,0 @@ "istanbul": "*", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
546886
14691