turndown 4.0.1 → 5.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,9 +32,19 @@ var turndownService = new TurndownService()
32
32
  var markdown = turndownService.turndown('<h1>Hello world!</h1>')
33
33
  ```
34
34
 
35
+ Turndown also accepts DOM nodes as input (either element nodes, document nodes, or document fragment nodes):
36
+
37
+ ```js
38
+ var markdown = turndownService.turndown(document.getElementById('content'))
39
+ ```
40
+
35
41
  ## Options
36
42
 
37
- Options can be passed in to the constructor on instantiation.
43
+ Options can be passed in to the constructor on instantiation. For example:
44
+
45
+ ```js
46
+ var turndownService = new TurndownService({ option: 'value' })
47
+ ```
38
48
 
39
49
  | Option | Valid values | Default |
40
50
  | :-------------------- | :------------ | :------ |
@@ -113,8 +123,8 @@ Use a plugin, or an array of plugins. Example:
113
123
  // Import plugins from turndown-plugin-gfm
114
124
  var turndownPluginGfm = require('turndown-plugin-gfm')
115
125
  var gfm = turndownPluginGfm.gfm
116
- var tables = gfm.tables
117
- var strikethrough = gfm.strikethrough
126
+ var tables = turndownPluginGfm.tables
127
+ var strikethrough = turndownPluginGfm.strikethrough
118
128
 
119
129
  // Use the gfm plugin
120
130
  turndownService.use(gfm)
@@ -189,7 +199,7 @@ rules.emphasis = {
189
199
 
190
200
  ### Rule Precedence
191
201
 
192
- Turndown iterates over the set of rules, and picks the first one that matches satifies the `filter`. The following list describes the order of precedence:
202
+ Turndown iterates over the set of rules, and picks the first one that matches the `filter`. The following list describes the order of precedence:
193
203
 
194
204
  1. Blank rule
195
205
  2. Added rules (optional)
@@ -202,6 +212,18 @@ Turndown iterates over the set of rules, and picks the first one that matches sa
202
212
 
203
213
  The plugin API provides a convenient way for developers to apply multiple extensions. A plugin is just a function that is called with the `TurndownService` instance.
204
214
 
215
+ ## Escaping Markdown Characters
216
+
217
+ Turndown uses backslashes (`\`) to escape Markdown characters in the HTML input. This ensures that these characters are not interpreted as Markdown when the output is compiled back to HTML. For example, the contents of `<h1>1. Hello world</h1>` needs to be escaped to `1\. Hello world`, otherwise it will be interpreted as a list item rather than a heading.
218
+
219
+ To avoid the complexity and the performance implications of parsing the content of every HTML element as Markdown, Turndown uses a group of regular expressions to escape potential Markdown syntax. As a result, the escaping rules can be quite aggressive.
220
+
221
+ ### Overriding `TurndownService.prototype.escape`
222
+
223
+ If you are confident in doing so, you may want to customise the escaping behaviour to suit your needs. This can be done by overriding `TurndownService.prototype.escape`. `escape` takes the text of each HTML element and should return a version with the Markdown characters escaped.
224
+
225
+ Note: text in code elements is never passed to`escape`.
226
+
205
227
  ## License
206
228
 
207
229
  turndown is copyright © 2017+ Dom Christie and released under the MIT license.
package/dist/turndown.js CHANGED
@@ -600,7 +600,7 @@ function Node (node) {
600
600
 
601
601
  function isBlank (node) {
602
602
  return (
603
- ['A', 'TH', 'TD'].indexOf(node.nodeName) === -1 &&
603
+ ['A', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'].indexOf(node.nodeName) === -1 &&
604
604
  /^\s*$/i.test(node.textContent) &&
605
605
  !isVoid(node) &&
606
606
  !hasVoid(node)
@@ -652,6 +652,21 @@ function isFlankedByWhitespace (side, node) {
652
652
  var reduce = Array.prototype.reduce;
653
653
  var leadingNewLinesRegExp = /^\n*/;
654
654
  var trailingNewLinesRegExp = /\n*$/;
655
+ var escapes = [
656
+ [/\\/g, '\\\\'],
657
+ [/\*/g, '\\*'],
658
+ [/^-/g, '\\-'],
659
+ [/^\+ /g, '\\+ '],
660
+ [/^(=+)/g, '\\$1'],
661
+ [/^(#{1,6}) /g, '\\$1 '],
662
+ [/`/g, '\\`'],
663
+ [/^~~~/g, '\\~~~'],
664
+ [/\[/g, '\\['],
665
+ [/\]/g, '\\]'],
666
+ [/^>/g, '\\>'],
667
+ [/_/g, '\\_'],
668
+ [/^(\d+)\. /g, '$1\\. ']
669
+ ];
655
670
 
656
671
  function TurndownService (options) {
657
672
  if (!(this instanceof TurndownService)) return new TurndownService(options)
@@ -772,48 +787,9 @@ TurndownService.prototype = {
772
787
  */
773
788
 
774
789
  escape: function (string) {
775
- return (
776
- string
777
- // Escape backslash escapes!
778
- .replace(/\\(\S)/g, '\\\\$1')
779
-
780
- // Escape headings
781
- .replace(/^(#{1,6} )/gm, '\\$1')
782
-
783
- // Escape hr
784
- .replace(/^([-*_] *){3,}$/gm, function (match, character) {
785
- return match.split(character).join('\\' + character)
786
- })
787
-
788
- // Escape ol bullet points
789
- .replace(/^(\W* {0,3})(\d+)\. /gm, '$1$2\\. ')
790
-
791
- // Escape ul bullet points
792
- .replace(/^([^\\\w]*)[*+-] /gm, function (match) {
793
- return match.replace(/([*+-])/g, '\\$1')
794
- })
795
-
796
- // Escape blockquote indents
797
- .replace(/^(\W* {0,3})> /gm, '$1\\> ')
798
-
799
- // Escape em/strong *
800
- .replace(/\*+(?![*\s\W]).+?\*+/g, function (match) {
801
- return match.replace(/\*/g, '\\*')
802
- })
803
-
804
- // Escape em/strong _
805
- .replace(/_+(?![_\s\W]).+?_+/g, function (match) {
806
- return match.replace(/_/g, '\\_')
807
- })
808
-
809
- // Escape code _
810
- .replace(/`+(?![`\s\W]).+?`+/g, function (match) {
811
- return match.replace(/`/g, '\\`')
812
- })
813
-
814
- // Escape link brackets
815
- .replace(/[\[\]]/g, '\\$&') // eslint-disable-line no-useless-escape
816
- )
790
+ return escapes.reduce(function (accumulator, escape) {
791
+ return accumulator.replace(escape[0], escape[1])
792
+ }, string)
817
793
  }
818
794
  };
819
795
 
@@ -599,7 +599,7 @@ function Node (node) {
599
599
 
600
600
  function isBlank (node) {
601
601
  return (
602
- ['A', 'TH', 'TD'].indexOf(node.nodeName) === -1 &&
602
+ ['A', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'].indexOf(node.nodeName) === -1 &&
603
603
  /^\s*$/i.test(node.textContent) &&
604
604
  !isVoid(node) &&
605
605
  !hasVoid(node)
@@ -651,6 +651,21 @@ function isFlankedByWhitespace (side, node) {
651
651
  var reduce = Array.prototype.reduce;
652
652
  var leadingNewLinesRegExp = /^\n*/;
653
653
  var trailingNewLinesRegExp = /\n*$/;
654
+ var escapes = [
655
+ [/\\/g, '\\\\'],
656
+ [/\*/g, '\\*'],
657
+ [/^-/g, '\\-'],
658
+ [/^\+ /g, '\\+ '],
659
+ [/^(=+)/g, '\\$1'],
660
+ [/^(#{1,6}) /g, '\\$1 '],
661
+ [/`/g, '\\`'],
662
+ [/^~~~/g, '\\~~~'],
663
+ [/\[/g, '\\['],
664
+ [/\]/g, '\\]'],
665
+ [/^>/g, '\\>'],
666
+ [/_/g, '\\_'],
667
+ [/^(\d+)\. /g, '$1\\. ']
668
+ ];
654
669
 
655
670
  function TurndownService (options) {
656
671
  if (!(this instanceof TurndownService)) return new TurndownService(options)
@@ -771,48 +786,9 @@ TurndownService.prototype = {
771
786
  */
772
787
 
773
788
  escape: function (string) {
774
- return (
775
- string
776
- // Escape backslash escapes!
777
- .replace(/\\(\S)/g, '\\\\$1')
778
-
779
- // Escape headings
780
- .replace(/^(#{1,6} )/gm, '\\$1')
781
-
782
- // Escape hr
783
- .replace(/^([-*_] *){3,}$/gm, function (match, character) {
784
- return match.split(character).join('\\' + character)
785
- })
786
-
787
- // Escape ol bullet points
788
- .replace(/^(\W* {0,3})(\d+)\. /gm, '$1$2\\. ')
789
-
790
- // Escape ul bullet points
791
- .replace(/^([^\\\w]*)[*+-] /gm, function (match) {
792
- return match.replace(/([*+-])/g, '\\$1')
793
- })
794
-
795
- // Escape blockquote indents
796
- .replace(/^(\W* {0,3})> /gm, '$1\\> ')
797
-
798
- // Escape em/strong *
799
- .replace(/\*+(?![*\s\W]).+?\*+/g, function (match) {
800
- return match.replace(/\*/g, '\\*')
801
- })
802
-
803
- // Escape em/strong _
804
- .replace(/_+(?![_\s\W]).+?_+/g, function (match) {
805
- return match.replace(/_/g, '\\_')
806
- })
807
-
808
- // Escape code _
809
- .replace(/`+(?![`\s\W]).+?`+/g, function (match) {
810
- return match.replace(/`/g, '\\`')
811
- })
812
-
813
- // Escape link brackets
814
- .replace(/[\[\]]/g, '\\$&') // eslint-disable-line no-useless-escape
815
- )
789
+ return escapes.reduce(function (accumulator, escape) {
790
+ return accumulator.replace(escape[0], escape[1])
791
+ }, string)
816
792
  }
817
793
  };
818
794
 
@@ -597,7 +597,7 @@ function Node (node) {
597
597
 
598
598
  function isBlank (node) {
599
599
  return (
600
- ['A', 'TH', 'TD'].indexOf(node.nodeName) === -1 &&
600
+ ['A', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'].indexOf(node.nodeName) === -1 &&
601
601
  /^\s*$/i.test(node.textContent) &&
602
602
  !isVoid(node) &&
603
603
  !hasVoid(node)
@@ -649,6 +649,21 @@ function isFlankedByWhitespace (side, node) {
649
649
  var reduce = Array.prototype.reduce;
650
650
  var leadingNewLinesRegExp = /^\n*/;
651
651
  var trailingNewLinesRegExp = /\n*$/;
652
+ var escapes = [
653
+ [/\\/g, '\\\\'],
654
+ [/\*/g, '\\*'],
655
+ [/^-/g, '\\-'],
656
+ [/^\+ /g, '\\+ '],
657
+ [/^(=+)/g, '\\$1'],
658
+ [/^(#{1,6}) /g, '\\$1 '],
659
+ [/`/g, '\\`'],
660
+ [/^~~~/g, '\\~~~'],
661
+ [/\[/g, '\\['],
662
+ [/\]/g, '\\]'],
663
+ [/^>/g, '\\>'],
664
+ [/_/g, '\\_'],
665
+ [/^(\d+)\. /g, '$1\\. ']
666
+ ];
652
667
 
653
668
  function TurndownService (options) {
654
669
  if (!(this instanceof TurndownService)) return new TurndownService(options)
@@ -769,48 +784,9 @@ TurndownService.prototype = {
769
784
  */
770
785
 
771
786
  escape: function (string) {
772
- return (
773
- string
774
- // Escape backslash escapes!
775
- .replace(/\\(\S)/g, '\\\\$1')
776
-
777
- // Escape headings
778
- .replace(/^(#{1,6} )/gm, '\\$1')
779
-
780
- // Escape hr
781
- .replace(/^([-*_] *){3,}$/gm, function (match, character) {
782
- return match.split(character).join('\\' + character)
783
- })
784
-
785
- // Escape ol bullet points
786
- .replace(/^(\W* {0,3})(\d+)\. /gm, '$1$2\\. ')
787
-
788
- // Escape ul bullet points
789
- .replace(/^([^\\\w]*)[*+-] /gm, function (match) {
790
- return match.replace(/([*+-])/g, '\\$1')
791
- })
792
-
793
- // Escape blockquote indents
794
- .replace(/^(\W* {0,3})> /gm, '$1\\> ')
795
-
796
- // Escape em/strong *
797
- .replace(/\*+(?![*\s\W]).+?\*+/g, function (match) {
798
- return match.replace(/\*/g, '\\*')
799
- })
800
-
801
- // Escape em/strong _
802
- .replace(/_+(?![_\s\W]).+?_+/g, function (match) {
803
- return match.replace(/_/g, '\\_')
804
- })
805
-
806
- // Escape code _
807
- .replace(/`+(?![`\s\W]).+?`+/g, function (match) {
808
- return match.replace(/`/g, '\\`')
809
- })
810
-
811
- // Escape link brackets
812
- .replace(/[\[\]]/g, '\\$&') // eslint-disable-line no-useless-escape
813
- )
787
+ return escapes.reduce(function (accumulator, escape) {
788
+ return accumulator.replace(escape[0], escape[1])
789
+ }, string)
814
790
  }
815
791
  };
816
792
 
@@ -603,7 +603,7 @@ function Node (node) {
603
603
 
604
604
  function isBlank (node) {
605
605
  return (
606
- ['A', 'TH', 'TD'].indexOf(node.nodeName) === -1 &&
606
+ ['A', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'].indexOf(node.nodeName) === -1 &&
607
607
  /^\s*$/i.test(node.textContent) &&
608
608
  !isVoid(node) &&
609
609
  !hasVoid(node)
@@ -655,6 +655,21 @@ function isFlankedByWhitespace (side, node) {
655
655
  var reduce = Array.prototype.reduce;
656
656
  var leadingNewLinesRegExp = /^\n*/;
657
657
  var trailingNewLinesRegExp = /\n*$/;
658
+ var escapes = [
659
+ [/\\/g, '\\\\'],
660
+ [/\*/g, '\\*'],
661
+ [/^-/g, '\\-'],
662
+ [/^\+ /g, '\\+ '],
663
+ [/^(=+)/g, '\\$1'],
664
+ [/^(#{1,6}) /g, '\\$1 '],
665
+ [/`/g, '\\`'],
666
+ [/^~~~/g, '\\~~~'],
667
+ [/\[/g, '\\['],
668
+ [/\]/g, '\\]'],
669
+ [/^>/g, '\\>'],
670
+ [/_/g, '\\_'],
671
+ [/^(\d+)\. /g, '$1\\. ']
672
+ ];
658
673
 
659
674
  function TurndownService (options) {
660
675
  if (!(this instanceof TurndownService)) return new TurndownService(options)
@@ -775,48 +790,9 @@ TurndownService.prototype = {
775
790
  */
776
791
 
777
792
  escape: function (string) {
778
- return (
779
- string
780
- // Escape backslash escapes!
781
- .replace(/\\(\S)/g, '\\\\$1')
782
-
783
- // Escape headings
784
- .replace(/^(#{1,6} )/gm, '\\$1')
785
-
786
- // Escape hr
787
- .replace(/^([-*_] *){3,}$/gm, function (match, character) {
788
- return match.split(character).join('\\' + character)
789
- })
790
-
791
- // Escape ol bullet points
792
- .replace(/^(\W* {0,3})(\d+)\. /gm, '$1$2\\. ')
793
-
794
- // Escape ul bullet points
795
- .replace(/^([^\\\w]*)[*+-] /gm, function (match) {
796
- return match.replace(/([*+-])/g, '\\$1')
797
- })
798
-
799
- // Escape blockquote indents
800
- .replace(/^(\W* {0,3})> /gm, '$1\\> ')
801
-
802
- // Escape em/strong *
803
- .replace(/\*+(?![*\s\W]).+?\*+/g, function (match) {
804
- return match.replace(/\*/g, '\\*')
805
- })
806
-
807
- // Escape em/strong _
808
- .replace(/_+(?![_\s\W]).+?_+/g, function (match) {
809
- return match.replace(/_/g, '\\_')
810
- })
811
-
812
- // Escape code _
813
- .replace(/`+(?![`\s\W]).+?`+/g, function (match) {
814
- return match.replace(/`/g, '\\`')
815
- })
816
-
817
- // Escape link brackets
818
- .replace(/[\[\]]/g, '\\$&') // eslint-disable-line no-useless-escape
819
- )
793
+ return escapes.reduce(function (accumulator, escape) {
794
+ return accumulator.replace(escape[0], escape[1])
795
+ }, string)
820
796
  }
821
797
  };
822
798
 
@@ -575,7 +575,7 @@ function Node (node) {
575
575
 
576
576
  function isBlank (node) {
577
577
  return (
578
- ['A', 'TH', 'TD'].indexOf(node.nodeName) === -1 &&
578
+ ['A', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'].indexOf(node.nodeName) === -1 &&
579
579
  /^\s*$/i.test(node.textContent) &&
580
580
  !isVoid(node) &&
581
581
  !hasVoid(node)
@@ -627,6 +627,21 @@ function isFlankedByWhitespace (side, node) {
627
627
  var reduce = Array.prototype.reduce;
628
628
  var leadingNewLinesRegExp = /^\n*/;
629
629
  var trailingNewLinesRegExp = /\n*$/;
630
+ var escapes = [
631
+ [/\\/g, '\\\\'],
632
+ [/\*/g, '\\*'],
633
+ [/^-/g, '\\-'],
634
+ [/^\+ /g, '\\+ '],
635
+ [/^(=+)/g, '\\$1'],
636
+ [/^(#{1,6}) /g, '\\$1 '],
637
+ [/`/g, '\\`'],
638
+ [/^~~~/g, '\\~~~'],
639
+ [/\[/g, '\\['],
640
+ [/\]/g, '\\]'],
641
+ [/^>/g, '\\>'],
642
+ [/_/g, '\\_'],
643
+ [/^(\d+)\. /g, '$1\\. ']
644
+ ];
630
645
 
631
646
  function TurndownService (options) {
632
647
  if (!(this instanceof TurndownService)) return new TurndownService(options)
@@ -747,48 +762,9 @@ TurndownService.prototype = {
747
762
  */
748
763
 
749
764
  escape: function (string) {
750
- return (
751
- string
752
- // Escape backslash escapes!
753
- .replace(/\\(\S)/g, '\\\\$1')
754
-
755
- // Escape headings
756
- .replace(/^(#{1,6} )/gm, '\\$1')
757
-
758
- // Escape hr
759
- .replace(/^([-*_] *){3,}$/gm, function (match, character) {
760
- return match.split(character).join('\\' + character)
761
- })
762
-
763
- // Escape ol bullet points
764
- .replace(/^(\W* {0,3})(\d+)\. /gm, '$1$2\\. ')
765
-
766
- // Escape ul bullet points
767
- .replace(/^([^\\\w]*)[*+-] /gm, function (match) {
768
- return match.replace(/([*+-])/g, '\\$1')
769
- })
770
-
771
- // Escape blockquote indents
772
- .replace(/^(\W* {0,3})> /gm, '$1\\> ')
773
-
774
- // Escape em/strong *
775
- .replace(/\*+(?![*\s\W]).+?\*+/g, function (match) {
776
- return match.replace(/\*/g, '\\*')
777
- })
778
-
779
- // Escape em/strong _
780
- .replace(/_+(?![_\s\W]).+?_+/g, function (match) {
781
- return match.replace(/_/g, '\\_')
782
- })
783
-
784
- // Escape code _
785
- .replace(/`+(?![`\s\W]).+?`+/g, function (match) {
786
- return match.replace(/`/g, '\\`')
787
- })
788
-
789
- // Escape link brackets
790
- .replace(/[\[\]]/g, '\\$&') // eslint-disable-line no-useless-escape
791
- )
765
+ return escapes.reduce(function (accumulator, escape) {
766
+ return accumulator.replace(escape[0], escape[1])
767
+ }, string)
792
768
  }
793
769
  };
794
770
 
@@ -573,7 +573,7 @@ function Node (node) {
573
573
 
574
574
  function isBlank (node) {
575
575
  return (
576
- ['A', 'TH', 'TD'].indexOf(node.nodeName) === -1 &&
576
+ ['A', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'].indexOf(node.nodeName) === -1 &&
577
577
  /^\s*$/i.test(node.textContent) &&
578
578
  !isVoid(node) &&
579
579
  !hasVoid(node)
@@ -625,6 +625,21 @@ function isFlankedByWhitespace (side, node) {
625
625
  var reduce = Array.prototype.reduce;
626
626
  var leadingNewLinesRegExp = /^\n*/;
627
627
  var trailingNewLinesRegExp = /\n*$/;
628
+ var escapes = [
629
+ [/\\/g, '\\\\'],
630
+ [/\*/g, '\\*'],
631
+ [/^-/g, '\\-'],
632
+ [/^\+ /g, '\\+ '],
633
+ [/^(=+)/g, '\\$1'],
634
+ [/^(#{1,6}) /g, '\\$1 '],
635
+ [/`/g, '\\`'],
636
+ [/^~~~/g, '\\~~~'],
637
+ [/\[/g, '\\['],
638
+ [/\]/g, '\\]'],
639
+ [/^>/g, '\\>'],
640
+ [/_/g, '\\_'],
641
+ [/^(\d+)\. /g, '$1\\. ']
642
+ ];
628
643
 
629
644
  function TurndownService (options) {
630
645
  if (!(this instanceof TurndownService)) return new TurndownService(options)
@@ -745,48 +760,9 @@ TurndownService.prototype = {
745
760
  */
746
761
 
747
762
  escape: function (string) {
748
- return (
749
- string
750
- // Escape backslash escapes!
751
- .replace(/\\(\S)/g, '\\\\$1')
752
-
753
- // Escape headings
754
- .replace(/^(#{1,6} )/gm, '\\$1')
755
-
756
- // Escape hr
757
- .replace(/^([-*_] *){3,}$/gm, function (match, character) {
758
- return match.split(character).join('\\' + character)
759
- })
760
-
761
- // Escape ol bullet points
762
- .replace(/^(\W* {0,3})(\d+)\. /gm, '$1$2\\. ')
763
-
764
- // Escape ul bullet points
765
- .replace(/^([^\\\w]*)[*+-] /gm, function (match) {
766
- return match.replace(/([*+-])/g, '\\$1')
767
- })
768
-
769
- // Escape blockquote indents
770
- .replace(/^(\W* {0,3})> /gm, '$1\\> ')
771
-
772
- // Escape em/strong *
773
- .replace(/\*+(?![*\s\W]).+?\*+/g, function (match) {
774
- return match.replace(/\*/g, '\\*')
775
- })
776
-
777
- // Escape em/strong _
778
- .replace(/_+(?![_\s\W]).+?_+/g, function (match) {
779
- return match.replace(/_/g, '\\_')
780
- })
781
-
782
- // Escape code _
783
- .replace(/`+(?![`\s\W]).+?`+/g, function (match) {
784
- return match.replace(/`/g, '\\`')
785
- })
786
-
787
- // Escape link brackets
788
- .replace(/[\[\]]/g, '\\$&') // eslint-disable-line no-useless-escape
789
- )
763
+ return escapes.reduce(function (accumulator, escape) {
764
+ return accumulator.replace(escape[0], escape[1])
765
+ }, string)
790
766
  }
791
767
  };
792
768
 
@@ -579,7 +579,7 @@ function Node (node) {
579
579
 
580
580
  function isBlank (node) {
581
581
  return (
582
- ['A', 'TH', 'TD'].indexOf(node.nodeName) === -1 &&
582
+ ['A', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'].indexOf(node.nodeName) === -1 &&
583
583
  /^\s*$/i.test(node.textContent) &&
584
584
  !isVoid(node) &&
585
585
  !hasVoid(node)
@@ -631,6 +631,21 @@ function isFlankedByWhitespace (side, node) {
631
631
  var reduce = Array.prototype.reduce;
632
632
  var leadingNewLinesRegExp = /^\n*/;
633
633
  var trailingNewLinesRegExp = /\n*$/;
634
+ var escapes = [
635
+ [/\\/g, '\\\\'],
636
+ [/\*/g, '\\*'],
637
+ [/^-/g, '\\-'],
638
+ [/^\+ /g, '\\+ '],
639
+ [/^(=+)/g, '\\$1'],
640
+ [/^(#{1,6}) /g, '\\$1 '],
641
+ [/`/g, '\\`'],
642
+ [/^~~~/g, '\\~~~'],
643
+ [/\[/g, '\\['],
644
+ [/\]/g, '\\]'],
645
+ [/^>/g, '\\>'],
646
+ [/_/g, '\\_'],
647
+ [/^(\d+)\. /g, '$1\\. ']
648
+ ];
634
649
 
635
650
  function TurndownService (options) {
636
651
  if (!(this instanceof TurndownService)) return new TurndownService(options)
@@ -751,48 +766,9 @@ TurndownService.prototype = {
751
766
  */
752
767
 
753
768
  escape: function (string) {
754
- return (
755
- string
756
- // Escape backslash escapes!
757
- .replace(/\\(\S)/g, '\\\\$1')
758
-
759
- // Escape headings
760
- .replace(/^(#{1,6} )/gm, '\\$1')
761
-
762
- // Escape hr
763
- .replace(/^([-*_] *){3,}$/gm, function (match, character) {
764
- return match.split(character).join('\\' + character)
765
- })
766
-
767
- // Escape ol bullet points
768
- .replace(/^(\W* {0,3})(\d+)\. /gm, '$1$2\\. ')
769
-
770
- // Escape ul bullet points
771
- .replace(/^([^\\\w]*)[*+-] /gm, function (match) {
772
- return match.replace(/([*+-])/g, '\\$1')
773
- })
774
-
775
- // Escape blockquote indents
776
- .replace(/^(\W* {0,3})> /gm, '$1\\> ')
777
-
778
- // Escape em/strong *
779
- .replace(/\*+(?![*\s\W]).+?\*+/g, function (match) {
780
- return match.replace(/\*/g, '\\*')
781
- })
782
-
783
- // Escape em/strong _
784
- .replace(/_+(?![_\s\W]).+?_+/g, function (match) {
785
- return match.replace(/_/g, '\\_')
786
- })
787
-
788
- // Escape code _
789
- .replace(/`+(?![`\s\W]).+?`+/g, function (match) {
790
- return match.replace(/`/g, '\\`')
791
- })
792
-
793
- // Escape link brackets
794
- .replace(/[\[\]]/g, '\\$&') // eslint-disable-line no-useless-escape
795
- )
769
+ return escapes.reduce(function (accumulator, escape) {
770
+ return accumulator.replace(escape[0], escape[1])
771
+ }, string)
796
772
  }
797
773
  };
798
774
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "turndown",
3
3
  "description": "A library that converts HTML to Markdown",
4
- "version": "4.0.1",
4
+ "version": "5.0.3",
5
5
  "author": "Dom Christie",
6
6
  "main": "lib/turndown.cjs.js",
7
7
  "module": "lib/turndown.es.js",
@@ -10,11 +10,10 @@
10
10
  "jsdom": false
11
11
  },
12
12
  "dependencies": {
13
- "jsdom": "^11.3.0"
13
+ "jsdom": "^11.9.0"
14
14
  },
15
15
  "devDependencies": {
16
- "browserify": "^14.5.0",
17
- "nodemon": "^1.10.2",
16
+ "browserify": "^16.2.3",
18
17
  "rollup": "^0.50.0",
19
18
  "rollup-plugin-commonjs": "^8.2.6",
20
19
  "rollup-plugin-node-resolve": "^3.0.0",
@@ -44,7 +43,6 @@
44
43
  "build-iife": "rollup -c config/rollup.config.iife.js",
45
44
  "build-test": "browserify test/turndown-test.js --outfile test/turndown-test.browser.js",
46
45
  "prepublish": "npm run build",
47
- "start": "nodemon --watch ./src/**/*.js --exec 'npm run build && npm test'",
48
46
  "test": "npm run build && npm run build-test && standard ./src/**/*.js && node test/turndown-test.js"
49
47
  }
50
48
  }