Browse Source

Tweak scanDelims algorithm

- explicitly set nextChar and lastChar to 0x20 at the begin/end of line

 - `_` between punctuation characters can now close an emphasis, see:
   https://github.com/jgm/commonmark.js/issues/12#issuecomment-77421682

 - `"` between punctuation characters can now be a closed quote
   in smartquotes rule.
pull/82/head
Alex Kocharin 10 years ago
parent
commit
3ba6f8b6d2
  1. 19
      lib/rules_core/smartquotes.js
  2. 20
      lib/rules_inline/emphasis.js
  3. 17
      lib/rules_inline/strikethrough.js
  4. 8
      test/fixtures/markdown-it/commonmark_extras.txt
  5. 8
      test/fixtures/markdown-it/smartquotes.txt

19
lib/rules_core/smartquotes.js

@ -50,17 +50,15 @@ function process_inlines(tokens, state) {
pos = t.index + 1; pos = t.index + 1;
isSingle = (t[0] === "'"); isSingle = (t[0] === "'");
lastChar = t.index - 1 >= 0 ? text.charCodeAt(t.index - 1) : -1; // treat begin/end of the line as a whitespace
nextChar = pos < max ? text.charCodeAt(pos) : -1; lastChar = t.index - 1 >= 0 ? text.charCodeAt(t.index - 1) : 0x20;
nextChar = pos < max ? text.charCodeAt(pos) : 0x20;
isLastPunctChar = lastChar >= 0 && isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
(isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar))); isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
isNextPunctChar = nextChar >= 0 &&
(isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)));
// begin/end of the line counts as a whitespace too isLastWhiteSpace = isWhiteSpace(lastChar);
isLastWhiteSpace = lastChar < 0 || isWhiteSpace(lastChar); isNextWhiteSpace = isWhiteSpace(nextChar);
isNextWhiteSpace = nextChar < 0 || isWhiteSpace(nextChar);
if (isNextWhiteSpace) { if (isNextWhiteSpace) {
canOpen = false; canOpen = false;
@ -87,7 +85,8 @@ function process_inlines(tokens, state) {
if (canOpen && canClose) { if (canOpen && canClose) {
// treat this as the middle of the word // treat this as the middle of the word
canOpen = canClose = false; canOpen = false;
canClose = isNextPunctChar;
} }
if (!canOpen && !canClose) { if (!canOpen && !canClose) {

20
lib/rules_inline/emphasis.js

@ -19,7 +19,8 @@ function scanDelims(state, start) {
max = state.posMax, max = state.posMax,
marker = state.src.charCodeAt(start); marker = state.src.charCodeAt(start);
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1; // treat beginning of the line as a whitespace
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : 0x20;
while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; } while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
@ -29,16 +30,14 @@ function scanDelims(state, start) {
count = pos - start; count = pos - start;
nextChar = pos < max ? state.src.charCodeAt(pos) : -1; // treat end of the line as a whitespace
nextChar = pos < max ? state.src.charCodeAt(pos) : 0x20;
isLastPunctChar = lastChar >= 0 && isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
(isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar))); isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
isNextPunctChar = nextChar >= 0 &&
(isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)));
// begin/end of the line counts as a whitespace too isLastWhiteSpace = isWhiteSpace(lastChar);
isLastWhiteSpace = lastChar < 0 || isWhiteSpace(lastChar); isNextWhiteSpace = isWhiteSpace(nextChar);
isNextWhiteSpace = nextChar < 0 || isWhiteSpace(nextChar);
if (isNextWhiteSpace) { if (isNextWhiteSpace) {
can_open = false; can_open = false;
@ -59,7 +58,8 @@ function scanDelims(state, start) {
if (marker === 0x5F /* _ */) { if (marker === 0x5F /* _ */) {
if (can_open && can_close) { if (can_open && can_close) {
// "_" inside a word can neither open nor close an emphasis // "_" inside a word can neither open nor close an emphasis
can_open = can_close = false; can_open = false;
can_close = isNextPunctChar;
} }
} }

17
lib/rules_inline/strikethrough.js

@ -19,7 +19,8 @@ function scanDelims(state, start) {
max = state.posMax, max = state.posMax,
marker = state.src.charCodeAt(start); marker = state.src.charCodeAt(start);
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1; // treat beginning of the line as a whitespace
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : 0x20;
while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; } while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
@ -29,16 +30,14 @@ function scanDelims(state, start) {
count = pos - start; count = pos - start;
nextChar = pos < max ? state.src.charCodeAt(pos) : -1; // treat end of the line as a whitespace
nextChar = pos < max ? state.src.charCodeAt(pos) : 0x20;
isLastPunctChar = lastChar >= 0 && isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
(isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar))); isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
isNextPunctChar = nextChar >= 0 &&
(isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)));
// begin/end of the line counts as a whitespace too isLastWhiteSpace = isWhiteSpace(lastChar);
isLastWhiteSpace = lastChar < 0 || isWhiteSpace(lastChar); isNextWhiteSpace = isWhiteSpace(nextChar);
isNextWhiteSpace = nextChar < 0 || isWhiteSpace(nextChar);
if (isNextWhiteSpace) { if (isNextWhiteSpace) {
can_open = false; can_open = false;

8
test/fixtures/markdown-it/commonmark_extras.txt

@ -61,6 +61,14 @@ just a funny little fence
</code></pre> </code></pre>
. .
Underscore between punctuation chars should be able to close emphasis.
.
_(hai)_.
.
<p><em>(hai)</em>.</p>
.
Coverage. Directive can terminate paragraph. Coverage. Directive can terminate paragraph.
. .

8
test/fixtures/markdown-it/smartquotes.txt

@ -82,3 +82,11 @@ users' stuff
. .
<p>users’ stuff</p> <p>users’ stuff</p>
. .
Quotes between punctuation chars:
.
"(hai)".
.
<p>“(hai)”.</p>
.

Loading…
Cancel
Save