Skip to content

Commit

Permalink
Avoid match-at-end regexp bottleneck in replacement to output joining.
Browse files Browse the repository at this point in the history
…Fix #370.
  • Loading branch information
martincizek committed Mar 15, 2021
1 parent e7a9351 commit b77b96e
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 21 deletions.
30 changes: 9 additions & 21 deletions src/turndown.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import COMMONMARK_RULES from './commonmark-rules'
import Rules from './rules'
import { extend } from './utilities'
import { extend, repeat, trimLeadingNewlines, trimTrailingNewlines } from './utilities'
import RootNode from './root-node'
import Node from './node'
var reduce = Array.prototype.reduce
var leadingNewLinesRegExp = /^\n*/
var trailingNewLinesRegExp = /\n*$/
var escapes = [
[/\\/g, '\\\\'],
[/\*/g, '\\*'],
Expand Down Expand Up @@ -212,31 +210,21 @@ function replacementForNode (node) {
}

/**
* Determines the new lines between the current output and the replacement
* Joins replacement to the current output with appropriate number of new lines
* @private
* @param {String} output The current conversion output
* @param {String} replacement The string to append to the output
* @returns The whitespace to separate the current output and the replacement
* @returns Joined output
* @type String
*/

function separatingNewlines (output, replacement) {
var newlines = [
output.match(trailingNewLinesRegExp)[0],
replacement.match(leadingNewLinesRegExp)[0]
].sort()
var maxNewlines = newlines[newlines.length - 1]
return maxNewlines.length < 2 ? maxNewlines : '\n\n'
}

function join (string1, string2) {
var separator = separatingNewlines(string1, string2)

// Remove trailing/leading newlines and replace with separator
string1 = string1.replace(trailingNewLinesRegExp, '')
string2 = string2.replace(leadingNewLinesRegExp, '')
function join (output, replacement) {
var s1 = trimTrailingNewlines(output)
var s2 = trimLeadingNewlines(replacement)
var nls = Math.max(output.length - s1.length, replacement.length - s2.length)
var separator = repeat('\n', Math.min(nls, 2))

return string1 + separator + string2
return s1 + separator + s2
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ export function repeat (character, count) {
return Array(count + 1).join(character)
}

export function trimLeadingNewlines (string) {
return string.replace(/^\n*/, '')
}

export function trimTrailingNewlines (string) {
// avoid match-at-end regexp bottleneck, see #370
var indexEnd = string.length
while (indexEnd > 0 && string[indexEnd - 1] === '\n') indexEnd--
return string.substring(0, indexEnd)
}

export var blockElements = [
'ADDRESS', 'ARTICLE', 'ASIDE', 'AUDIO', 'BLOCKQUOTE', 'BODY', 'CANVAS',
'CENTER', 'DD', 'DIR', 'DIV', 'DL', 'DT', 'FIELDSET', 'FIGCAPTION', 'FIGURE',
Expand Down

0 comments on commit b77b96e

Please sign in to comment.