diff --git a/lib/autolinker.js b/lib/autolinker.js index 5705950b..12558d68 100644 --- a/lib/autolinker.js +++ b/lib/autolinker.js @@ -35,10 +35,10 @@ function linkClause(spec, clause, replacerCache) { autolinkmap = {}; spec.biblio.inScopeByType(clause.namespace, 'term') - .forEach(entry => autolinkmap[entry.key.toLowerCase()] = entry); + .forEach(entry => autolinkmap[narrowSpace(entry.key.toLowerCase())] = entry); spec.biblio.inScopeByType(clause.namespace, 'op') - .forEach(entry => autolinkmap[entry.key.toLowerCase()] = entry); + .forEach(entry => autolinkmap[narrowSpace(entry.key.toLowerCase())] = entry); clauseReplacer = new RegExp(Object.keys(autolinkmap) .sort(function (a, b) { return b.length - a.length; }) @@ -48,9 +48,13 @@ function linkClause(spec, clause, replacerCache) { if (entry.type === 'term') { if (isCommonTerm(key)) { - return '\\b' + key + '\\b(?!\\.\\w|%%|\\]\\])'; + return '\\b' + + widenSpace(key) + + '\\b(?!\\.\\w|%%|\\]\\])'; } else if (key[0].match(/[A-Za-z0-9]/)) { - return '\\b' + caseInsensitiveRegExp(key) + '\\b(?!\\.\\w|%%|\\]\\])'; + return '\\b' + + widenSpace(caseInsensitiveRegExp(key)) + + '\\b(?!\\.\\w|%%|\\]\\])'; } else { return key; } @@ -86,7 +90,7 @@ function autolink(replacer, autolinkmap, spec, node, parentId, allowSameId) { const template = spec.doc.createElement('template'); const content = escape(node.textContent); const autolinked = content.replace(replacer, match => { - const entry = autolinkmap[match.toLowerCase()]; + const entry = autolinkmap[narrowSpace(match.toLowerCase())]; if (!entry) { return match; } @@ -132,3 +136,16 @@ function caseInsensitiveRegExp(str) { return `[${lower}${upper}]${str.slice(1)}`; } + +// given a regexp string, returns a regexp string where each space can be +// many spaces or line breaks. +function widenSpace(str) { + return str.replace(/\s+/g, '[\\s\\r\\n]+'); +} + +// given a regexp string, returns a regexp string where multiple spaces +// or linebreaks can only be a single space +function narrowSpace(str) { + return str.replace(/[\s\r\n]+/g, ' '); +} + diff --git a/test/autolinking.html b/test/autolinking.html index cfdec65c..69e75af2 100644 --- a/test/autolinking.html +++ b/test/autolinking.html @@ -10,11 +10,14 @@
Lowercase
strict mode
%Percent%
+extra spaces
lowercase should not autolink. But Lowercase should. But not LowerCase.
-Strict mode shoud link. But Strict Mode should not.
+Strict mode shoud link. But Strict Mode should not. Also, strict + mode can be wrapped across lines and contain extra whitespace.
+extra spaces in a dfn should be narrowed to one space.
%Percent% should autolink.
Vars to dfns should be vars not dfns: _Lowercase_.
Also, no autolinks in anchors: Lowercase.
diff --git a/test/autolinking.html.baseline b/test/autolinking.html.baseline index d6be3f2c..6b34a4cf 100644 --- a/test/autolinking.html.baseline +++ b/test/autolinking.html.baseline @@ -8,11 +8,14 @@Lowercase
strict mode
%Percent%
+extra spaces
lowercase should not autolink. But
Vars to dfns should be vars not dfns: Lowercase.
Also, no autolinks in anchors: Lowercase.