Browse Source

Fix spaces in subscript and superscript

pull/14/head
Alex Kocharin 10 years ago
parent
commit
74602dba90
  1. 14
      lib/renderer.js
  2. 4
      lib/rules_inline/del.js
  3. 49
      lib/rules_inline/sub.js
  4. 51
      lib/rules_inline/sup.js
  5. 14
      test/fixtures/remarkable/del.txt
  6. 32
      test/fixtures/remarkable/sub.txt
  7. 36
      test/fixtures/remarkable/sup.txt

14
lib/renderer.js

@ -240,17 +240,11 @@ rules.mark_close = function(/*tokens, idx, options*/) {
};
rules.sub_open = function(/*tokens, idx, options*/) {
return '<sub>';
rules.sub = function(tokens, idx/*, options*/) {
return '<sub>' + escapeHtml(tokens[idx].content) + '</sub>';
};
rules.sub_close = function(/*tokens, idx, options*/) {
return '</sub>';
};
rules.sup_open = function(/*tokens, idx, options*/) {
return '<sup>';
};
rules.sup_close = function(/*tokens, idx, options*/) {
return '</sup>';
rules.sup = function(tokens, idx/*, options*/) {
return '<sup>' + escapeHtml(tokens[idx].content) + '</sup>';
};

4
lib/rules_inline/del.js

@ -26,8 +26,8 @@ module.exports = function del(state, silent) {
pos = start + 2;
while (pos < max && state.src.charCodeAt(pos) === 0x7E/* ~ */) { pos++; }
if (pos !== start + 2) {
// sequence of 3+ markers taking as literal, same as in a emphasis
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;

49
lib/rules_inline/sub.js

@ -2,53 +2,40 @@
'use strict';
// same as UNESCAPE_MD_RE plus a space
var UNESCAPE_RE = /\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g;
module.exports = function sub(state, silent) {
var found,
stack,
content,
max = state.posMax,
start = state.pos,
lastChar,
nextChar;
start = state.pos;
if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; }
if (silent) { return false; } // don't run any pairs in validation mode
if (start + 2 >= max) { 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 (nextChar === 0x20 || nextChar === 0x0A) { return false; }
state.pos = start + 1;
stack = 1;
while (state.pos < max) {
if (state.src.charCodeAt(state.pos) === 0x7E/* ~ */) {
lastChar = state.src.charCodeAt(state.pos - 1);
nextChar = state.pos + 1 < max ? state.src.charCodeAt(state.pos + 1) : -1;
if (nextChar !== 0x7E/* ~ */ && lastChar !== 0x7E/* ~ */) {
if (lastChar !== 0x20 && lastChar !== 0x0A) {
// closing '~'
stack--;
} else if (nextChar !== 0x20 && nextChar !== 0x0A) {
// opening '~'
stack++;
} // else {
// // standalone ' ~ ' indented with spaces
//}
if (stack <= 0) {
found = true;
break;
}
}
}
state.parser.skipToken(state);
}
if (!found) {
// parser failed to find ending tag, so it's not valid emphasis
if (!found || start + 1 === state.pos) {
state.pos = start;
return false;
}
content = state.src.slice(start + 1, state.pos);
// don't allow unescaped spaces/newlines inside
if (content.match(/(^|[^\\])(\\\\)*\s/)) {
state.pos = start;
return false;
}
@ -58,9 +45,11 @@ module.exports = function sub(state, silent) {
state.pos = start + 1;
if (!silent) {
state.push({ type: 'sub_open', level: state.level++ });
state.parser.tokenize(state);
state.push({ type: 'sub_close', level: --state.level });
state.push({
type: 'sub',
level: state.level,
content: content.replace(UNESCAPE_RE, '$1')
});
}
state.pos = state.posMax + 1;

51
lib/rules_inline/sup.js

@ -1,54 +1,41 @@
// Process ~superscript~
// Process ^superscript^
'use strict';
// same as UNESCAPE_MD_RE plus a space
var UNESCAPE_RE = /\\([ \\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g;
module.exports = function sup(state, silent) {
var found,
stack,
content,
max = state.posMax,
start = state.pos,
lastChar,
nextChar;
start = state.pos;
if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; }
if (silent) { return false; } // don't run any pairs in validation mode
if (start + 2 >= max) { 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 (nextChar === 0x20 || nextChar === 0x0A) { return false; }
state.pos = start + 1;
stack = 1;
while (state.pos < max) {
if (state.src.charCodeAt(state.pos) === 0x5E/* ^ */) {
lastChar = state.src.charCodeAt(state.pos - 1);
nextChar = state.pos + 1 < max ? state.src.charCodeAt(state.pos + 1) : -1;
if (nextChar !== 0x5E/* ^ */ && lastChar !== 0x5E/* ^ */) {
if (lastChar !== 0x20 && lastChar !== 0x0A) {
// closing '^'
stack--;
} else if (nextChar !== 0x20 && nextChar !== 0x0A) {
// opening '^'
stack++;
} // else {
// // standalone ' ^ ' indented with spaces
//}
if (stack <= 0) {
found = true;
break;
}
}
}
state.parser.skipToken(state);
}
if (!found) {
// parser failed to find ending tag, so it's not valid emphasis
if (!found || start + 1 === state.pos) {
state.pos = start;
return false;
}
content = state.src.slice(start + 1, state.pos);
// don't allow unescaped spaces/newlines inside
if (content.match(/(^|[^\\])(\\\\)*\s/)) {
state.pos = start;
return false;
}
@ -58,9 +45,11 @@ module.exports = function sup(state, silent) {
state.pos = start + 1;
if (!silent) {
state.push({ type: 'sup_open', level: state.level++ });
state.parser.tokenize(state);
state.push({ type: 'sup_close', level: --state.level });
state.push({
type: 'sup',
level: state.level,
content: content.replace(UNESCAPE_RE, '$1')
});
}
state.pos = state.posMax + 1;

14
test/fixtures/remarkable/del.txt

@ -4,20 +4,6 @@
<p><del>Strikeout</del></p>
.
These are not strikeouts, you have to use exactly two "~~":
.
x ~~~foo~~~
x ~~foo~~~
x ~~~foo~~
.
<p>x ~~~foo~~~</p>
<p>x ~~foo~~~</p>
<p>x ~~~foo~~</p>
.
Strikeouts have the same priority as emphases:
.

32
test/fixtures/remarkable/sub.txt

@ -1,12 +1,36 @@
.
~foo ~bar~ baz~
~foo\~
.
<p><sub>foo <sub>bar</sub> baz</sub></p>
<p>~foo~</p>
.
.
this ~ is ~ not ~ subscript
~foo bar~
.
<p>this ~ is ~ not ~ subscript</p>
<p>~foo bar~</p>
.
.
~foo\ bar\ baz~
.
<p><sub>foo bar baz</sub></p>
.
.
~\ foo\ ~
.
<p><sub> foo </sub></p>
.
.
~foo\\\\\\\ bar~
.
<p><sub>foo\\\ bar</sub></p>
.
.
~foo\\\\\\ bar~
.
<p>~foo\\\ bar~</p>
.

36
test/fixtures/remarkable/sup.txt

@ -1,18 +1,42 @@
.
^foo ^bar^ baz^
^test^
.
<p><sup>foo <sup>bar</sup> baz</sup></p>
<p><sup>test</sup></p>
.
.
^foo ~bar~ baz^
^foo\^
.
<p><sup>foo <sub>bar</sub> baz</sup></p>
<p>^foo^</p>
.
.
this ^ is ^ not ^ superscript
2^4 + 3^5
.
<p>this ^ is ^ not ^ superscript</p>
<p>2^4 + 3^5</p>
.
.
^foo~bar^baz^bar~foo^
.
<p><sup>foo~bar</sup>baz<sup>bar~foo</sup></p>
.
.
^\ foo\ ^
.
<p><sup> foo </sup></p>
.
.
^foo\\\\\\\ bar^
.
<p><sup>foo\\\ bar</sup></p>
.
.
^foo\\\\\\ bar^
.
<p>^foo\\\ bar^</p>
.

Loading…
Cancel
Save