Browse Source

Added <mark> support

pull/14/head
Vitaly Puzrin 10 years ago
parent
commit
0411b14cf5
  1. 2
      demo/sample.md
  2. 5
      lib/parser_inline.js
  3. 8
      lib/renderer.js
  4. 78
      lib/rules_inline/mark.js
  5. 92
      test/fixtures/remarkable/mark.txt

2
demo/sample.md

@ -58,6 +58,8 @@ _This is italic text_
++Inserted text++ ++Inserted text++
==Marked text==
## Blockquotes ## Blockquotes

5
lib/parser_inline.js

@ -19,6 +19,7 @@ rules.push(require('./rules_inline/escape'));
rules.push(require('./rules_inline/backticks')); rules.push(require('./rules_inline/backticks'));
rules.push(require('./rules_inline/del')); rules.push(require('./rules_inline/del'));
rules.push(require('./rules_inline/ins')); rules.push(require('./rules_inline/ins'));
rules.push(require('./rules_inline/mark'));
rules.push(require('./rules_inline/emphasis')); rules.push(require('./rules_inline/emphasis'));
rules.push(require('./rules_inline/links')); rules.push(require('./rules_inline/links'));
rules.push(require('./rules_inline/autolink')); rules.push(require('./rules_inline/autolink'));
@ -49,9 +50,9 @@ function ParserInline() {
this._rules = []; this._rules = [];
// Rule to skip pure text // Rule to skip pure text
// - '{$%@}' reserved for extentions // - '{}$%@+=' reserved for extentions
// - '<>"' added for internal html escaping // - '<>"' added for internal html escaping
this.textMatch = /^[^\n\\`*_\[\]!&{}$%@<>"~+]+/; this.textMatch = /^[^\n\\`*_\[\]!&{}$%@<>"~+=]+/;
// By default CommonMark allows too much in links // By default CommonMark allows too much in links
// If you need to restrict it - override this with your validator. // If you need to restrict it - override this with your validator.

8
lib/renderer.js

@ -208,6 +208,14 @@ rules.ins_close = function(/*tokens, idx, options*/) {
}; };
rules.mark_open = function(/*tokens, idx, options*/) {
return '<mark>';
};
rules.mark_close = function(/*tokens, idx, options*/) {
return '</mark>';
};
rules.hardbreak = function (tokens, idx, options) { rules.hardbreak = function (tokens, idx, options) {
return options.xhtmlOut ? '<br />\n' : '<br>\n'; return options.xhtmlOut ? '<br />\n' : '<br>\n';
}; };

78
lib/rules_inline/mark.js

@ -0,0 +1,78 @@
// Process ++inserted text++
'use strict';
module.exports = function mark(state, silent) {
var found,
pos,
max = state.posMax,
start = state.pos,
lastChar,
nextChar;
if (state.src.charCodeAt(start) !== 0x3D/* = */) { return false; }
if (start + 4 >= max) { return false; }
if (state.src.charCodeAt(start + 1) !== 0x3D/* = */) { return false; }
// make ins lower a priority tag with respect to links, same as <em>;
// this code also prevents recursion
if (silent && state.isInLabel) { return false; }
if (state.level >= state.options.maxNesting) { return false; }
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
nextChar = state.src.charCodeAt(start + 2);
if (lastChar === 0x3D/* = */) { return false; }
if (nextChar === 0x3D/* = */) { return false; }
if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
pos = start + 2;
while (pos < max && state.src.charCodeAt(pos) === 0x3D/* = */) { pos++; }
if (pos !== start + 2) {
// sequence of 3+ markers taking as literal, same as in a emphasis
state.pos += pos - start;
if (!silent) { state.pending += state.src.slice(start, pos); }
return true;
}
state.pos = start + 2;
while (state.pos + 1 < max) {
if (state.src.charCodeAt(state.pos) === 0x3D/* = */) {
if (state.src.charCodeAt(state.pos + 1) === 0x3D/* = */) {
lastChar = state.src.charCodeAt(state.pos - 1);
nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1;
if (nextChar !== 0x3D/* = */ && lastChar !== 0x3D/* = */) {
if (lastChar !== 0x20 && lastChar !== 0x0A) {
// closing '++'
found = true;
break;
}
}
}
}
state.parser.skipToken(state);
}
if (!found) {
// parser failed to find ending tag, so it's not valid emphasis
state.pos = start;
return false;
}
// found!
state.posMax = state.pos;
state.pos = start + 2;
if (!silent) {
state.push({ type: 'mark_open', level: state.level++ });
state.parser.tokenize(state);
state.push({ type: 'mark_close', level: --state.level });
}
state.pos = state.posMax + 2;
state.posMax = max;
return true;
};

92
test/fixtures/remarkable/mark.txt

@ -0,0 +1,92 @@
.
==Mark==
.
<p><mark>Mark</mark></p>
.
These are not marks, you have to use exactly two "==":
.
x ===foo===
x ==foo===
x ===foo==
.
<p>x ===foo===</p>
<p>x ==foo===</p>
<p>x ===foo==</p>
.
Marks have the same priority as emphases:
.
**==test**==
==**test==**
.
<p>**<mark>test**</mark></p>
<p>==<strong>test==</strong></p>
.
Marks have the same priority as emphases with respect to links:
.
[==link]()==
==[link==]()
.
<p><a href="">==link</a>==</p>
<p>==<a href="">link==</a></p>
.
Marks have the same priority as emphases with respect to backticks:
.
==`code==`
`==code`==
.
<p>==<code>code==</code></p>
<p><code>==code</code>==</p>
.
Nested marks:
.
==foo ==bar== baz==
.
<p><mark>foo <mark>bar</mark> baz</mark></p>
.
.
==f **o ==o b== a** r==
.
<p><mark>f <strong>o <mark>o b</mark> a</strong> r</mark></p>
.
Should not have a whitespace between text and "==":
.
foo == bar == baz
.
<p>foo == bar == baz</p>
.
Newline should be considered a whitespace:
.
==test
==
==
test==
==
test
==
.
<h1>==test</h1>
<p>==
test==</p>
<p>==
test
==</p>
.
Loading…
Cancel
Save