Browse Source

Allow sequence of 4+ markers in pairs

pull/14/head
Alex Kocharin 10 years ago
parent
commit
0c0917048c
  1. 110
      lib/rules_inline/del.js
  2. 110
      lib/rules_inline/ins.js
  3. 110
      lib/rules_inline/mark.js
  4. 24
      test/fixtures/markdown-it/del.txt
  5. 25
      test/fixtures/markdown-it/ins.txt
  6. 24
      test/fixtures/markdown-it/mark.txt

110
lib/rules_inline/del.js

@ -1,62 +1,80 @@
// Process ~~deleted text~~
'use strict'; 'use strict';
module.exports = function del(state, silent) {
var found, // parse sequence of markers,
pos, // "start" should point at a valid marker
function scanDelims(state, start) {
var pos = start, lastChar, nextChar, count,
can_open = true,
can_close = true,
max = state.posMax,
marker = state.src.charCodeAt(start);
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
if (pos >= max) { can_open = false; }
count = pos - start;
nextChar = pos < max ? state.src.charCodeAt(pos) : -1;
// check whitespace conditions
if (nextChar === 0x20 || nextChar === 0x0A) { can_open = false; }
if (lastChar === 0x20 || lastChar === 0x0A) { can_close = false; }
return {
can_open: can_open,
can_close: can_close,
delims: count
};
}
module.exports = function(state, silent) {
var startCount,
count,
tagCount,
found,
stack, stack,
res,
max = state.posMax, max = state.posMax,
start = state.pos, start = state.pos,
lastChar, marker = state.src.charCodeAt(start);
nextChar;
if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; } if (marker !== 0x7E/* ~ */) { return false; }
if (silent) { return false; } // don't run any pairs in validation mode if (silent) { return false; } // don't run any pairs in validation mode
if (start + 4 >= max) { return false; }
if (state.src.charCodeAt(start + 1) !== 0x7E/* ~ */) { return false; }
if (state.level >= state.options.maxNesting) { return false; }
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1; res = scanDelims(state, start);
nextChar = state.src.charCodeAt(start + 2); startCount = res.delims;
if (!res.can_open) {
if (lastChar === 0x7E/* ~ */) { return false; } state.pos += startCount;
if (nextChar === 0x7E/* ~ */) { return false; } if (!silent) { state.pending += state.src.slice(start, state.pos); }
if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
pos = start + 2;
while (pos < max && state.src.charCodeAt(pos) === 0x7E/* ~ */) { pos++; }
if (pos > start + 3) {
// sequence of 4+ markers taking as literal, same as in a emphasis
state.pos += pos - start;
if (!silent) { state.pending += state.src.slice(start, pos); }
return true; return true;
} }
state.pos = start + 2; if (state.level >= state.options.maxNesting) { return false; }
stack = 1; stack = Math.floor(startCount / 2);
if (stack <= 0) { return false; }
while (state.pos + 1 < max) { state.pos = start + startCount;
if (state.src.charCodeAt(state.pos) === 0x7E/* ~ */) {
if (state.src.charCodeAt(state.pos + 1) === 0x7E/* ~ */) { while (state.pos < max) {
lastChar = state.src.charCodeAt(state.pos - 1); if (state.src.charCodeAt(state.pos) === marker) {
nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1; res = scanDelims(state, state.pos);
if (nextChar !== 0x7E/* ~ */ && lastChar !== 0x7E/* ~ */) { count = res.delims;
if (lastChar !== 0x20 && lastChar !== 0x0A) { tagCount = Math.floor(count / 2);
// closing '~~' if (res.can_close) {
stack--; if (tagCount >= stack) {
} else if (nextChar !== 0x20 && nextChar !== 0x0A) { state.pos += count - 2;
// opening '~~' found = true;
stack++; break;
} // else {
// // standalone ' ~~ ' indented with spaces
// }
if (stack <= 0) {
found = true;
break;
}
} }
stack -= tagCount;
state.pos += count;
continue;
} }
if (res.can_open) { stack += tagCount; }
state.pos += count;
continue;
} }
state.parser.skipToken(state); state.parser.skipToken(state);

110
lib/rules_inline/ins.js

@ -1,62 +1,80 @@
// Process ++inserted text++
'use strict'; 'use strict';
module.exports = function ins(state, silent) {
var found, // parse sequence of markers,
pos, // "start" should point at a valid marker
function scanDelims(state, start) {
var pos = start, lastChar, nextChar, count,
can_open = true,
can_close = true,
max = state.posMax,
marker = state.src.charCodeAt(start);
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
if (pos >= max) { can_open = false; }
count = pos - start;
nextChar = pos < max ? state.src.charCodeAt(pos) : -1;
// check whitespace conditions
if (nextChar === 0x20 || nextChar === 0x0A) { can_open = false; }
if (lastChar === 0x20 || lastChar === 0x0A) { can_close = false; }
return {
can_open: can_open,
can_close: can_close,
delims: count
};
}
module.exports = function(state, silent) {
var startCount,
count,
tagCount,
found,
stack, stack,
res,
max = state.posMax, max = state.posMax,
start = state.pos, start = state.pos,
lastChar, marker = state.src.charCodeAt(start);
nextChar;
if (state.src.charCodeAt(start) !== 0x2B/* + */) { return false; } if (marker !== 0x2B/* + */) { return false; }
if (silent) { return false; } // don't run any pairs in validation mode if (silent) { return false; } // don't run any pairs in validation mode
if (start + 4 >= max) { return false; }
if (state.src.charCodeAt(start + 1) !== 0x2B/* + */) { return false; }
if (state.level >= state.options.maxNesting) { return false; }
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1; res = scanDelims(state, start);
nextChar = state.src.charCodeAt(start + 2); startCount = res.delims;
if (!res.can_open) {
if (lastChar === 0x2B/* + */) { return false; } state.pos += startCount;
if (nextChar === 0x2B/* + */) { return false; } if (!silent) { state.pending += state.src.slice(start, state.pos); }
if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
pos = start + 2;
while (pos < max && state.src.charCodeAt(pos) === 0x2B/* + */) { 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; return true;
} }
state.pos = start + 2; if (state.level >= state.options.maxNesting) { return false; }
stack = 1; stack = Math.floor(startCount / 2);
if (stack <= 0) { return false; }
while (state.pos + 1 < max) { state.pos = start + startCount;
if (state.src.charCodeAt(state.pos) === 0x2B/* + */) {
if (state.src.charCodeAt(state.pos + 1) === 0x2B/* + */) { while (state.pos < max) {
lastChar = state.src.charCodeAt(state.pos - 1); if (state.src.charCodeAt(state.pos) === marker) {
nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1; res = scanDelims(state, state.pos);
if (nextChar !== 0x2B/* + */ && lastChar !== 0x2B/* + */) { count = res.delims;
if (lastChar !== 0x20 && lastChar !== 0x0A) { tagCount = Math.floor(count / 2);
// closing '++' if (res.can_close) {
stack--; if (tagCount >= stack) {
} else if (nextChar !== 0x20 && nextChar !== 0x0A) { state.pos += count - 2;
// opening '++' found = true;
stack++; break;
} // else {
// // standalone ' ++ ' indented with spaces
// }
if (stack <= 0) {
found = true;
break;
}
} }
stack -= tagCount;
state.pos += count;
continue;
} }
if (res.can_open) { stack += tagCount; }
state.pos += count;
continue;
} }
state.parser.skipToken(state); state.parser.skipToken(state);

110
lib/rules_inline/mark.js

@ -1,62 +1,80 @@
// Process ==highlighted text==
'use strict'; 'use strict';
module.exports = function del(state, silent) {
var found, // parse sequence of markers,
pos, // "start" should point at a valid marker
function scanDelims(state, start) {
var pos = start, lastChar, nextChar, count,
can_open = true,
can_close = true,
max = state.posMax,
marker = state.src.charCodeAt(start);
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
if (pos >= max) { can_open = false; }
count = pos - start;
nextChar = pos < max ? state.src.charCodeAt(pos) : -1;
// check whitespace conditions
if (nextChar === 0x20 || nextChar === 0x0A) { can_open = false; }
if (lastChar === 0x20 || lastChar === 0x0A) { can_close = false; }
return {
can_open: can_open,
can_close: can_close,
delims: count
};
}
module.exports = function(state, silent) {
var startCount,
count,
tagCount,
found,
stack, stack,
res,
max = state.posMax, max = state.posMax,
start = state.pos, start = state.pos,
lastChar, marker = state.src.charCodeAt(start);
nextChar;
if (state.src.charCodeAt(start) !== 0x3D/* = */) { return false; } if (marker !== 0x3D/* = */) { return false; }
if (silent) { return false; } // don't run any pairs in validation mode if (silent) { return false; } // don't run any pairs in validation mode
if (start + 4 >= max) { return false; }
if (state.src.charCodeAt(start + 1) !== 0x3D/* = */) { return false; }
if (state.level >= state.options.maxNesting) { return false; }
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1; res = scanDelims(state, start);
nextChar = state.src.charCodeAt(start + 2); startCount = res.delims;
if (!res.can_open) {
if (lastChar === 0x3D/* = */) { return false; } state.pos += startCount;
if (nextChar === 0x3D/* = */) { return false; } if (!silent) { state.pending += state.src.slice(start, state.pos); }
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; return true;
} }
state.pos = start + 2; if (state.level >= state.options.maxNesting) { return false; }
stack = 1; stack = Math.floor(startCount / 2);
if (stack <= 0) { return false; }
while (state.pos + 1 < max) { state.pos = start + startCount;
if (state.src.charCodeAt(state.pos) === 0x3D/* = */) {
if (state.src.charCodeAt(state.pos + 1) === 0x3D/* = */) { while (state.pos < max) {
lastChar = state.src.charCodeAt(state.pos - 1); if (state.src.charCodeAt(state.pos) === marker) {
nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1; res = scanDelims(state, state.pos);
if (nextChar !== 0x3D/* = */ && lastChar !== 0x3D/* = */) { count = res.delims;
if (lastChar !== 0x20 && lastChar !== 0x0A) { tagCount = Math.floor(count / 2);
// closing '==' if (res.can_close) {
stack--; if (tagCount >= stack) {
} else if (nextChar !== 0x20 && nextChar !== 0x0A) { state.pos += count - 2;
// opening '==' found = true;
stack++; break;
} // else {
// // standalone ' == ' indented with spaces
// }
if (stack <= 0) {
found = true;
break;
}
} }
stack -= tagCount;
state.pos += count;
continue;
} }
if (res.can_open) { stack += tagCount; }
state.pos += count;
continue;
} }
state.parser.skipToken(state); state.parser.skipToken(state);

24
test/fixtures/markdown-it/del.txt

@ -4,6 +4,30 @@
<p><del>Strikeout</del></p> <p><del>Strikeout</del></p>
. .
.
x ~~~~foo~~ bar~~
.
<p>x <del><del>foo</del> bar</del></p>
.
.
x ~~foo ~~bar~~~~
.
<p>x <del>foo <del>bar</del></del></p>
.
.
x ~~~~foo~~~~
.
<p>x <del><del>foo</del></del></p>
.
.
x ~~~foo~~~
.
<p>x <del><sub>foo</sub></del></p>
.
Strikeouts have the same priority as emphases: Strikeouts have the same priority as emphases:
. .

25
test/fixtures/markdown-it/ins.txt

@ -5,17 +5,28 @@
. .
These are not inserts, you have to use exactly two "++":
. .
x +++foo+++ x ++++foo++ bar++
.
<p>x <ins><ins>foo</ins> bar</ins></p>
.
.
x ++foo ++bar++++
.
<p>x <ins>foo <ins>bar</ins></ins></p>
.
x ++foo+++ .
x ++++foo++++
.
<p>x <ins><ins>foo</ins></ins></p>
.
x +++foo++
. .
<p>x +++foo+++</p> x +++foo+++
<p>x ++foo+++</p> .
<p>x +++foo++</p> <p>x <ins>+foo+</ins></p>
. .
Inserts have the same priority as emphases: Inserts have the same priority as emphases:

24
test/fixtures/markdown-it/mark.txt

@ -4,18 +4,28 @@
<p><mark>Mark</mark></p> <p><mark>Mark</mark></p>
. .
.
x ====foo== bar==
.
<p>x <mark><mark>foo</mark> bar</mark></p>
.
These are not marks, you have to use exactly two "==":
. .
x ===foo=== x ==foo ==bar====
.
<p>x <mark>foo <mark>bar</mark></mark></p>
.
x ==foo=== .
x ====foo====
.
<p>x <mark><mark>foo</mark></mark></p>
.
x ===foo==
. .
<p>x ===foo===</p> x ===foo===
<p>x ==foo===</p> .
<p>x ===foo==</p> <p>x <mark>=foo=</mark></p>
. .
Marks have the same priority as emphases: Marks have the same priority as emphases:

Loading…
Cancel
Save