Skip to content

Commit

Permalink
Links are masked only once per inline string
Browse files Browse the repository at this point in the history
  • Loading branch information
calculuschild committed Jun 30, 2020
1 parent 56b6f5e commit 4db32dc
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 25 deletions.
18 changes: 16 additions & 2 deletions src/Lexer.js
Expand Up @@ -322,6 +322,20 @@ module.exports = class Lexer {
inlineTokens(src, tokens = [], inLink = false, inRawBlock = false, prevChar = '') {
let token;

// String with links masked to avoid interference with em and strong
let maskedSrc = src;
if (this.tokens.links) {
const links = Object.keys(this.tokens.links);
if (links.length > 0) {
let match;
while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
}
}
}
}

while (src) {
// escape
if (token = this.tokenizer.escape(src)) {
Expand Down Expand Up @@ -360,15 +374,15 @@ module.exports = class Lexer {
}

// strong
if (token = this.tokenizer.strong(src, prevChar, this.tokens.links)) {
if (token = this.tokenizer.strong(src, maskedSrc, prevChar)) {
src = src.substring(token.raw.length);
token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
tokens.push(token);
continue;
}

// em
if (token = this.tokenizer.em(src, prevChar, this.tokens.links)) {
if (token = this.tokenizer.em(src, maskedSrc, prevChar)) {
src = src.substring(token.raw.length);
token.tokens = this.inlineTokens(token.text, [], inLink, inRawBlock);
tokens.push(token);
Expand Down
29 changes: 6 additions & 23 deletions src/Tokenizer.js
Expand Up @@ -58,21 +58,6 @@ function indentCodeCompensation(raw, text) {
.join('\n');
}

function maskReflinks(text, links) {
if (links) {
links = Object.keys(links).filter(l => l.match(/[*_]/));
if (links.length > 0) {
let match;
while ((match = this.rules.inline.reflinkSearch.exec(text)) != null) {
if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
text = text.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + text.slice(this.rules.inline.reflinkSearch.lastIndex);
}
}
}
}
return text;
}

/**
* Tokenizer
*/
Expand Down Expand Up @@ -504,13 +489,12 @@ module.exports = class Tokenizer {
}
}

strong(src, prevChar = '', links) {
strong(src, maskedSrc, prevChar = '') {
let cap = this.rules.inline.preStrong.exec(src);

if (cap) {
const text = maskReflinks(src, links);

cap = this.rules.inline.strong.exec(text);
maskedSrc = maskedSrc.slice(-1*src.length);
cap = this.rules.inline.strong.exec(maskedSrc);

if (cap) {
if (!cap[1] || (cap[1] && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) {
Expand All @@ -524,13 +508,12 @@ module.exports = class Tokenizer {
}
}

em(src, prevChar = '', links) {
em(src, maskedSrc, prevChar = '') {
let cap = this.rules.inline.preEm.exec(src);

if (cap) {
const text = maskReflinks(src, links);

cap = this.rules.inline.em.exec(text);
maskedSrc = maskedSrc.slice(-1*src.length);
cap = this.rules.inline.em.exec(maskedSrc);

if (cap) {
if (!cap[1] || (cap[1] && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) {
Expand Down
1 change: 1 addition & 0 deletions test/specs/new/em_and_reflinks.html
Expand Up @@ -2,3 +2,4 @@
<p><em>Hello [not</em>reflink] guys*!</p>
<p><em>Hello [not</em>a<em>reflink] guys</em>!</p>
<p><em>Hello<a href="theaddress">reflink*bottom</a>guys</em>!</p>
<p><em>Hello<a href="theaddress">reflinknoem</a>guys</em>!</p>
4 changes: 4 additions & 0 deletions test/specs/new/em_and_reflinks.md
Expand Up @@ -8,4 +8,8 @@

*Hello [reflink*bottom] guys*!

*Hello [reflinknoem] guys*!

[reflink*bottom]: theaddress

[reflinknoem]: theaddress

0 comments on commit 4db32dc

Please sign in to comment.