turndown 7.2.2 → 7.2.4
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 +2 -0
- package/dist/turndown.js +181 -357
- package/lib/turndown.browser.cjs.js +180 -356
- package/lib/turndown.browser.es.js +181 -357
- package/lib/turndown.browser.umd.js +182 -358
- package/lib/turndown.cjs.js +177 -352
- package/lib/turndown.es.js +178 -353
- package/lib/turndown.umd.js +179 -354
- package/package.json +19 -12
|
@@ -1,146 +1,107 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
function extend
|
|
3
|
+
function extend(destination) {
|
|
4
4
|
for (var i = 1; i < arguments.length; i++) {
|
|
5
5
|
var source = arguments[i];
|
|
6
6
|
for (var key in source) {
|
|
7
|
-
if (
|
|
7
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) destination[key] = source[key];
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
-
return destination
|
|
10
|
+
return destination;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return Array(count + 1).join(character)
|
|
12
|
+
function repeat(character, count) {
|
|
13
|
+
return Array(count + 1).join(character);
|
|
15
14
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return string.replace(/^\n*/, '')
|
|
15
|
+
function trimLeadingNewlines(string) {
|
|
16
|
+
return string.replace(/^\n*/, '');
|
|
19
17
|
}
|
|
20
|
-
|
|
21
|
-
function trimTrailingNewlines (string) {
|
|
18
|
+
function trimTrailingNewlines(string) {
|
|
22
19
|
// avoid match-at-end regexp bottleneck, see #370
|
|
23
20
|
var indexEnd = string.length;
|
|
24
21
|
while (indexEnd > 0 && string[indexEnd - 1] === '\n') indexEnd--;
|
|
25
|
-
return string.substring(0, indexEnd)
|
|
22
|
+
return string.substring(0, indexEnd);
|
|
26
23
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return trimTrailingNewlines(trimLeadingNewlines(string))
|
|
24
|
+
function trimNewlines(string) {
|
|
25
|
+
return trimTrailingNewlines(trimLeadingNewlines(string));
|
|
30
26
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
'CENTER', 'DD', 'DIR', 'DIV', 'DL', 'DT', 'FIELDSET', 'FIGCAPTION', 'FIGURE',
|
|
35
|
-
'FOOTER', 'FORM', 'FRAMESET', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEADER',
|
|
36
|
-
'HGROUP', 'HR', 'HTML', 'ISINDEX', 'LI', 'MAIN', 'MENU', 'NAV', 'NOFRAMES',
|
|
37
|
-
'NOSCRIPT', 'OL', 'OUTPUT', 'P', 'PRE', 'SECTION', 'TABLE', 'TBODY', 'TD',
|
|
38
|
-
'TFOOT', 'TH', 'THEAD', 'TR', 'UL'
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
function isBlock (node) {
|
|
42
|
-
return is(node, blockElements)
|
|
27
|
+
var blockElements = ['ADDRESS', 'ARTICLE', 'ASIDE', 'AUDIO', 'BLOCKQUOTE', 'BODY', 'CANVAS', 'CENTER', 'DD', 'DIR', 'DIV', 'DL', 'DT', 'FIELDSET', 'FIGCAPTION', 'FIGURE', 'FOOTER', 'FORM', 'FRAMESET', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEADER', 'HGROUP', 'HR', 'HTML', 'ISINDEX', 'LI', 'MAIN', 'MENU', 'NAV', 'NOFRAMES', 'NOSCRIPT', 'OL', 'OUTPUT', 'P', 'PRE', 'SECTION', 'TABLE', 'TBODY', 'TD', 'TFOOT', 'TH', 'THEAD', 'TR', 'UL'];
|
|
28
|
+
function isBlock(node) {
|
|
29
|
+
return is(node, blockElements);
|
|
43
30
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
'KEYGEN', 'LINK', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR'
|
|
48
|
-
];
|
|
49
|
-
|
|
50
|
-
function isVoid (node) {
|
|
51
|
-
return is(node, voidElements)
|
|
31
|
+
var voidElements = ['AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR'];
|
|
32
|
+
function isVoid(node) {
|
|
33
|
+
return is(node, voidElements);
|
|
52
34
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return has(node, voidElements)
|
|
35
|
+
function hasVoid(node) {
|
|
36
|
+
return has(node, voidElements);
|
|
56
37
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
'AUDIO', 'VIDEO'
|
|
61
|
-
];
|
|
62
|
-
|
|
63
|
-
function isMeaningfulWhenBlank (node) {
|
|
64
|
-
return is(node, meaningfulWhenBlankElements)
|
|
38
|
+
var meaningfulWhenBlankElements = ['A', 'TABLE', 'THEAD', 'TBODY', 'TFOOT', 'TH', 'TD', 'IFRAME', 'SCRIPT', 'AUDIO', 'VIDEO'];
|
|
39
|
+
function isMeaningfulWhenBlank(node) {
|
|
40
|
+
return is(node, meaningfulWhenBlankElements);
|
|
65
41
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return has(node, meaningfulWhenBlankElements)
|
|
42
|
+
function hasMeaningfulWhenBlank(node) {
|
|
43
|
+
return has(node, meaningfulWhenBlankElements);
|
|
69
44
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return tagNames.indexOf(node.nodeName) >= 0
|
|
45
|
+
function is(node, tagNames) {
|
|
46
|
+
return tagNames.indexOf(node.nodeName) >= 0;
|
|
73
47
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
)
|
|
48
|
+
function has(node, tagNames) {
|
|
49
|
+
return node.getElementsByTagName && tagNames.some(function (tagName) {
|
|
50
|
+
return node.getElementsByTagName(tagName).length;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
var markdownEscapes = [[/\\/g, '\\\\'], [/\*/g, '\\*'], [/^-/g, '\\-'], [/^\+ /g, '\\+ '], [/^(=+)/g, '\\$1'], [/^(#{1,6}) /g, '\\$1 '], [/`/g, '\\`'], [/^~~~/g, '\\~~~'], [/\[/g, '\\['], [/\]/g, '\\]'], [/^>/g, '\\>'], [/_/g, '\\_'], [/^(\d+)\. /g, '$1\\. ']];
|
|
54
|
+
function escapeMarkdown(string) {
|
|
55
|
+
return markdownEscapes.reduce(function (accumulator, escape) {
|
|
56
|
+
return accumulator.replace(escape[0], escape[1]);
|
|
57
|
+
}, string);
|
|
82
58
|
}
|
|
83
59
|
|
|
84
60
|
var rules = {};
|
|
85
|
-
|
|
86
61
|
rules.paragraph = {
|
|
87
62
|
filter: 'p',
|
|
88
|
-
|
|
89
63
|
replacement: function (content) {
|
|
90
|
-
return '\n\n' + content + '\n\n'
|
|
64
|
+
return '\n\n' + content + '\n\n';
|
|
91
65
|
}
|
|
92
66
|
};
|
|
93
|
-
|
|
94
67
|
rules.lineBreak = {
|
|
95
68
|
filter: 'br',
|
|
96
|
-
|
|
97
69
|
replacement: function (content, node, options) {
|
|
98
|
-
return options.br + '\n'
|
|
70
|
+
return options.br + '\n';
|
|
99
71
|
}
|
|
100
72
|
};
|
|
101
|
-
|
|
102
73
|
rules.heading = {
|
|
103
74
|
filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
|
|
104
|
-
|
|
105
75
|
replacement: function (content, node, options) {
|
|
106
76
|
var hLevel = Number(node.nodeName.charAt(1));
|
|
107
|
-
|
|
108
77
|
if (options.headingStyle === 'setext' && hLevel < 3) {
|
|
109
|
-
var underline = repeat(
|
|
110
|
-
return
|
|
111
|
-
'\n\n' + content + '\n' + underline + '\n\n'
|
|
112
|
-
)
|
|
78
|
+
var underline = repeat(hLevel === 1 ? '=' : '-', content.length);
|
|
79
|
+
return '\n\n' + content + '\n' + underline + '\n\n';
|
|
113
80
|
} else {
|
|
114
|
-
return '\n\n' + repeat('#', hLevel) + ' ' + content + '\n\n'
|
|
81
|
+
return '\n\n' + repeat('#', hLevel) + ' ' + content + '\n\n';
|
|
115
82
|
}
|
|
116
83
|
}
|
|
117
84
|
};
|
|
118
|
-
|
|
119
85
|
rules.blockquote = {
|
|
120
86
|
filter: 'blockquote',
|
|
121
|
-
|
|
122
87
|
replacement: function (content) {
|
|
123
88
|
content = trimNewlines(content).replace(/^/gm, '> ');
|
|
124
|
-
return '\n\n' + content + '\n\n'
|
|
89
|
+
return '\n\n' + content + '\n\n';
|
|
125
90
|
}
|
|
126
91
|
};
|
|
127
|
-
|
|
128
92
|
rules.list = {
|
|
129
93
|
filter: ['ul', 'ol'],
|
|
130
|
-
|
|
131
94
|
replacement: function (content, node) {
|
|
132
95
|
var parent = node.parentNode;
|
|
133
96
|
if (parent.nodeName === 'LI' && parent.lastElementChild === node) {
|
|
134
|
-
return '\n' + content
|
|
97
|
+
return '\n' + content;
|
|
135
98
|
} else {
|
|
136
|
-
return '\n\n' + content + '\n\n'
|
|
99
|
+
return '\n\n' + content + '\n\n';
|
|
137
100
|
}
|
|
138
101
|
}
|
|
139
102
|
};
|
|
140
|
-
|
|
141
103
|
rules.listItem = {
|
|
142
104
|
filter: 'li',
|
|
143
|
-
|
|
144
105
|
replacement: function (content, node, options) {
|
|
145
106
|
var prefix = options.bulletListMarker + ' ';
|
|
146
107
|
var parent = node.parentNode;
|
|
@@ -152,273 +113,208 @@ rules.listItem = {
|
|
|
152
113
|
var isParagraph = /\n$/.test(content);
|
|
153
114
|
content = trimNewlines(content) + (isParagraph ? '\n' : '');
|
|
154
115
|
content = content.replace(/\n/gm, '\n' + ' '.repeat(prefix.length)); // indent
|
|
155
|
-
return (
|
|
156
|
-
prefix + content + (node.nextSibling ? '\n' : '')
|
|
157
|
-
)
|
|
116
|
+
return prefix + content + (node.nextSibling ? '\n' : '');
|
|
158
117
|
}
|
|
159
118
|
};
|
|
160
|
-
|
|
161
119
|
rules.indentedCodeBlock = {
|
|
162
120
|
filter: function (node, options) {
|
|
163
|
-
return
|
|
164
|
-
options.codeBlockStyle === 'indented' &&
|
|
165
|
-
node.nodeName === 'PRE' &&
|
|
166
|
-
node.firstChild &&
|
|
167
|
-
node.firstChild.nodeName === 'CODE'
|
|
168
|
-
)
|
|
121
|
+
return options.codeBlockStyle === 'indented' && node.nodeName === 'PRE' && node.firstChild && node.firstChild.nodeName === 'CODE';
|
|
169
122
|
},
|
|
170
|
-
|
|
171
123
|
replacement: function (content, node, options) {
|
|
172
|
-
return (
|
|
173
|
-
'\n\n ' +
|
|
174
|
-
node.firstChild.textContent.replace(/\n/g, '\n ') +
|
|
175
|
-
'\n\n'
|
|
176
|
-
)
|
|
124
|
+
return '\n\n ' + node.firstChild.textContent.replace(/\n/g, '\n ') + '\n\n';
|
|
177
125
|
}
|
|
178
126
|
};
|
|
179
|
-
|
|
180
127
|
rules.fencedCodeBlock = {
|
|
181
128
|
filter: function (node, options) {
|
|
182
|
-
return
|
|
183
|
-
options.codeBlockStyle === 'fenced' &&
|
|
184
|
-
node.nodeName === 'PRE' &&
|
|
185
|
-
node.firstChild &&
|
|
186
|
-
node.firstChild.nodeName === 'CODE'
|
|
187
|
-
)
|
|
129
|
+
return options.codeBlockStyle === 'fenced' && node.nodeName === 'PRE' && node.firstChild && node.firstChild.nodeName === 'CODE';
|
|
188
130
|
},
|
|
189
|
-
|
|
190
131
|
replacement: function (content, node, options) {
|
|
191
132
|
var className = node.firstChild.getAttribute('class') || '';
|
|
192
133
|
var language = (className.match(/language-(\S+)/) || [null, ''])[1];
|
|
193
134
|
var code = node.firstChild.textContent;
|
|
194
|
-
|
|
195
135
|
var fenceChar = options.fence.charAt(0);
|
|
196
136
|
var fenceSize = 3;
|
|
197
137
|
var fenceInCodeRegex = new RegExp('^' + fenceChar + '{3,}', 'gm');
|
|
198
|
-
|
|
199
138
|
var match;
|
|
200
|
-
while (
|
|
139
|
+
while (match = fenceInCodeRegex.exec(code)) {
|
|
201
140
|
if (match[0].length >= fenceSize) {
|
|
202
141
|
fenceSize = match[0].length + 1;
|
|
203
142
|
}
|
|
204
143
|
}
|
|
205
|
-
|
|
206
144
|
var fence = repeat(fenceChar, fenceSize);
|
|
207
|
-
|
|
208
|
-
return (
|
|
209
|
-
'\n\n' + fence + language + '\n' +
|
|
210
|
-
code.replace(/\n$/, '') +
|
|
211
|
-
'\n' + fence + '\n\n'
|
|
212
|
-
)
|
|
145
|
+
return '\n\n' + fence + language + '\n' + code.replace(/\n$/, '') + '\n' + fence + '\n\n';
|
|
213
146
|
}
|
|
214
147
|
};
|
|
215
|
-
|
|
216
148
|
rules.horizontalRule = {
|
|
217
149
|
filter: 'hr',
|
|
218
|
-
|
|
219
150
|
replacement: function (content, node, options) {
|
|
220
|
-
return '\n\n' + options.hr + '\n\n'
|
|
151
|
+
return '\n\n' + options.hr + '\n\n';
|
|
221
152
|
}
|
|
222
153
|
};
|
|
223
|
-
|
|
224
154
|
rules.inlineLink = {
|
|
225
155
|
filter: function (node, options) {
|
|
226
|
-
return (
|
|
227
|
-
options.linkStyle === 'inlined' &&
|
|
228
|
-
node.nodeName === 'A' &&
|
|
229
|
-
node.getAttribute('href')
|
|
230
|
-
)
|
|
156
|
+
return options.linkStyle === 'inlined' && node.nodeName === 'A' && node.getAttribute('href');
|
|
231
157
|
},
|
|
232
|
-
|
|
233
158
|
replacement: function (content, node) {
|
|
234
|
-
var href = node.getAttribute('href');
|
|
235
|
-
|
|
236
|
-
var
|
|
237
|
-
|
|
238
|
-
return '[' + content + '](' + href + title + ')'
|
|
159
|
+
var href = escapeLinkDestination(node.getAttribute('href'));
|
|
160
|
+
var title = escapeLinkTitle(cleanAttribute(node.getAttribute('title')));
|
|
161
|
+
var titlePart = title ? ' "' + title + '"' : '';
|
|
162
|
+
return '[' + content + '](' + href + titlePart + ')';
|
|
239
163
|
}
|
|
240
164
|
};
|
|
241
|
-
|
|
242
165
|
rules.referenceLink = {
|
|
243
166
|
filter: function (node, options) {
|
|
244
|
-
return (
|
|
245
|
-
options.linkStyle === 'referenced' &&
|
|
246
|
-
node.nodeName === 'A' &&
|
|
247
|
-
node.getAttribute('href')
|
|
248
|
-
)
|
|
167
|
+
return options.linkStyle === 'referenced' && node.nodeName === 'A' && node.getAttribute('href');
|
|
249
168
|
},
|
|
250
|
-
|
|
251
169
|
replacement: function (content, node, options) {
|
|
252
|
-
var href = node.getAttribute('href');
|
|
170
|
+
var href = escapeLinkDestination(node.getAttribute('href'));
|
|
253
171
|
var title = cleanAttribute(node.getAttribute('title'));
|
|
254
|
-
if (title) title = ' "' + title + '"';
|
|
172
|
+
if (title) title = ' "' + escapeLinkTitle(title) + '"';
|
|
255
173
|
var replacement;
|
|
256
174
|
var reference;
|
|
257
|
-
|
|
258
175
|
switch (options.linkReferenceStyle) {
|
|
259
176
|
case 'collapsed':
|
|
260
177
|
replacement = '[' + content + '][]';
|
|
261
178
|
reference = '[' + content + ']: ' + href + title;
|
|
262
|
-
break
|
|
179
|
+
break;
|
|
263
180
|
case 'shortcut':
|
|
264
181
|
replacement = '[' + content + ']';
|
|
265
182
|
reference = '[' + content + ']: ' + href + title;
|
|
266
|
-
break
|
|
183
|
+
break;
|
|
267
184
|
default:
|
|
268
185
|
var id = this.references.length + 1;
|
|
269
186
|
replacement = '[' + content + '][' + id + ']';
|
|
270
187
|
reference = '[' + id + ']: ' + href + title;
|
|
271
188
|
}
|
|
272
|
-
|
|
273
189
|
this.references.push(reference);
|
|
274
|
-
return replacement
|
|
190
|
+
return replacement;
|
|
275
191
|
},
|
|
276
|
-
|
|
277
192
|
references: [],
|
|
278
|
-
|
|
279
193
|
append: function (options) {
|
|
280
194
|
var references = '';
|
|
281
195
|
if (this.references.length) {
|
|
282
196
|
references = '\n\n' + this.references.join('\n') + '\n\n';
|
|
283
197
|
this.references = []; // Reset references
|
|
284
198
|
}
|
|
285
|
-
return references
|
|
199
|
+
return references;
|
|
286
200
|
}
|
|
287
201
|
};
|
|
288
|
-
|
|
289
202
|
rules.emphasis = {
|
|
290
203
|
filter: ['em', 'i'],
|
|
291
|
-
|
|
292
204
|
replacement: function (content, node, options) {
|
|
293
|
-
if (!content.trim()) return ''
|
|
294
|
-
return options.emDelimiter + content + options.emDelimiter
|
|
205
|
+
if (!content.trim()) return '';
|
|
206
|
+
return options.emDelimiter + content + options.emDelimiter;
|
|
295
207
|
}
|
|
296
208
|
};
|
|
297
|
-
|
|
298
209
|
rules.strong = {
|
|
299
210
|
filter: ['strong', 'b'],
|
|
300
|
-
|
|
301
211
|
replacement: function (content, node, options) {
|
|
302
|
-
if (!content.trim()) return ''
|
|
303
|
-
return options.strongDelimiter + content + options.strongDelimiter
|
|
212
|
+
if (!content.trim()) return '';
|
|
213
|
+
return options.strongDelimiter + content + options.strongDelimiter;
|
|
304
214
|
}
|
|
305
215
|
};
|
|
306
|
-
|
|
307
216
|
rules.code = {
|
|
308
217
|
filter: function (node) {
|
|
309
218
|
var hasSiblings = node.previousSibling || node.nextSibling;
|
|
310
219
|
var isCodeBlock = node.parentNode.nodeName === 'PRE' && !hasSiblings;
|
|
311
|
-
|
|
312
|
-
return node.nodeName === 'CODE' && !isCodeBlock
|
|
220
|
+
return node.nodeName === 'CODE' && !isCodeBlock;
|
|
313
221
|
},
|
|
314
|
-
|
|
315
222
|
replacement: function (content) {
|
|
316
|
-
if (!content) return ''
|
|
223
|
+
if (!content) return '';
|
|
317
224
|
content = content.replace(/\r?\n|\r/g, ' ');
|
|
318
|
-
|
|
319
225
|
var extraSpace = /^`|^ .*?[^ ].* $|`$/.test(content) ? ' ' : '';
|
|
320
226
|
var delimiter = '`';
|
|
321
227
|
var matches = content.match(/`+/gm) || [];
|
|
322
228
|
while (matches.indexOf(delimiter) !== -1) delimiter = delimiter + '`';
|
|
323
|
-
|
|
324
|
-
return delimiter + extraSpace + content + extraSpace + delimiter
|
|
229
|
+
return delimiter + extraSpace + content + extraSpace + delimiter;
|
|
325
230
|
}
|
|
326
231
|
};
|
|
327
|
-
|
|
328
232
|
rules.image = {
|
|
329
233
|
filter: 'img',
|
|
330
|
-
|
|
331
234
|
replacement: function (content, node) {
|
|
332
|
-
var alt = cleanAttribute(node.getAttribute('alt'));
|
|
333
|
-
var src = node.getAttribute('src') || '';
|
|
235
|
+
var alt = escapeMarkdown(cleanAttribute(node.getAttribute('alt')));
|
|
236
|
+
var src = escapeLinkDestination(node.getAttribute('src') || '');
|
|
334
237
|
var title = cleanAttribute(node.getAttribute('title'));
|
|
335
|
-
var titlePart = title ? ' "' + title + '"' : '';
|
|
336
|
-
return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : ''
|
|
238
|
+
var titlePart = title ? ' "' + escapeLinkTitle(title) + '"' : '';
|
|
239
|
+
return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : '';
|
|
337
240
|
}
|
|
338
241
|
};
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
242
|
+
function cleanAttribute(attribute) {
|
|
243
|
+
return attribute ? attribute.replace(/(\n+\s*)+/g, '\n') : '';
|
|
244
|
+
}
|
|
245
|
+
function escapeLinkDestination(destination) {
|
|
246
|
+
var escaped = destination.replace(/([<>()])/g, '\\$1');
|
|
247
|
+
return escaped.indexOf(' ') >= 0 ? '<' + escaped + '>' : escaped;
|
|
248
|
+
}
|
|
249
|
+
function escapeLinkTitle(title) {
|
|
250
|
+
return title.replace(/"/g, '\\"');
|
|
342
251
|
}
|
|
343
252
|
|
|
344
253
|
/**
|
|
345
254
|
* Manages a collection of rules used to convert HTML to Markdown
|
|
346
255
|
*/
|
|
347
256
|
|
|
348
|
-
function Rules
|
|
257
|
+
function Rules(options) {
|
|
349
258
|
this.options = options;
|
|
350
259
|
this._keep = [];
|
|
351
260
|
this._remove = [];
|
|
352
|
-
|
|
353
261
|
this.blankRule = {
|
|
354
262
|
replacement: options.blankReplacement
|
|
355
263
|
};
|
|
356
|
-
|
|
357
264
|
this.keepReplacement = options.keepReplacement;
|
|
358
|
-
|
|
359
265
|
this.defaultRule = {
|
|
360
266
|
replacement: options.defaultReplacement
|
|
361
267
|
};
|
|
362
|
-
|
|
363
268
|
this.array = [];
|
|
364
269
|
for (var key in options.rules) this.array.push(options.rules[key]);
|
|
365
270
|
}
|
|
366
|
-
|
|
367
271
|
Rules.prototype = {
|
|
368
272
|
add: function (key, rule) {
|
|
369
273
|
this.array.unshift(rule);
|
|
370
274
|
},
|
|
371
|
-
|
|
372
275
|
keep: function (filter) {
|
|
373
276
|
this._keep.unshift({
|
|
374
277
|
filter: filter,
|
|
375
278
|
replacement: this.keepReplacement
|
|
376
279
|
});
|
|
377
280
|
},
|
|
378
|
-
|
|
379
281
|
remove: function (filter) {
|
|
380
282
|
this._remove.unshift({
|
|
381
283
|
filter: filter,
|
|
382
284
|
replacement: function () {
|
|
383
|
-
return ''
|
|
285
|
+
return '';
|
|
384
286
|
}
|
|
385
287
|
});
|
|
386
288
|
},
|
|
387
|
-
|
|
388
289
|
forNode: function (node) {
|
|
389
|
-
if (node.isBlank) return this.blankRule
|
|
290
|
+
if (node.isBlank) return this.blankRule;
|
|
390
291
|
var rule;
|
|
391
|
-
|
|
392
|
-
if (
|
|
393
|
-
if (
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
return this.defaultRule
|
|
292
|
+
if (rule = findRule(this.array, node, this.options)) return rule;
|
|
293
|
+
if (rule = findRule(this._keep, node, this.options)) return rule;
|
|
294
|
+
if (rule = findRule(this._remove, node, this.options)) return rule;
|
|
295
|
+
return this.defaultRule;
|
|
397
296
|
},
|
|
398
|
-
|
|
399
297
|
forEach: function (fn) {
|
|
400
298
|
for (var i = 0; i < this.array.length; i++) fn(this.array[i], i);
|
|
401
299
|
}
|
|
402
300
|
};
|
|
403
|
-
|
|
404
|
-
function findRule (rules, node, options) {
|
|
301
|
+
function findRule(rules, node, options) {
|
|
405
302
|
for (var i = 0; i < rules.length; i++) {
|
|
406
303
|
var rule = rules[i];
|
|
407
|
-
if (filterValue(rule, node, options)) return rule
|
|
304
|
+
if (filterValue(rule, node, options)) return rule;
|
|
408
305
|
}
|
|
409
|
-
return
|
|
306
|
+
return undefined;
|
|
410
307
|
}
|
|
411
|
-
|
|
412
|
-
function filterValue (rule, node, options) {
|
|
308
|
+
function filterValue(rule, node, options) {
|
|
413
309
|
var filter = rule.filter;
|
|
414
310
|
if (typeof filter === 'string') {
|
|
415
|
-
if (filter === node.nodeName.toLowerCase()) return true
|
|
311
|
+
if (filter === node.nodeName.toLowerCase()) return true;
|
|
416
312
|
} else if (Array.isArray(filter)) {
|
|
417
|
-
if (filter.indexOf(node.nodeName.toLowerCase()) > -1) return true
|
|
313
|
+
if (filter.indexOf(node.nodeName.toLowerCase()) > -1) return true;
|
|
418
314
|
} else if (typeof filter === 'function') {
|
|
419
|
-
if (filter.call(rule, node, options)) return true
|
|
315
|
+
if (filter.call(rule, node, options)) return true;
|
|
420
316
|
} else {
|
|
421
|
-
throw new TypeError('`filter` needs to be a string, array, or function')
|
|
317
|
+
throw new TypeError('`filter` needs to be a string, array, or function');
|
|
422
318
|
}
|
|
423
319
|
}
|
|
424
320
|
|
|
@@ -454,46 +350,39 @@ function filterValue (rule, node, options) {
|
|
|
454
350
|
*
|
|
455
351
|
* @param {Object} options
|
|
456
352
|
*/
|
|
457
|
-
function collapseWhitespace
|
|
353
|
+
function collapseWhitespace(options) {
|
|
458
354
|
var element = options.element;
|
|
459
355
|
var isBlock = options.isBlock;
|
|
460
356
|
var isVoid = options.isVoid;
|
|
461
357
|
var isPre = options.isPre || function (node) {
|
|
462
|
-
return node.nodeName === 'PRE'
|
|
358
|
+
return node.nodeName === 'PRE';
|
|
463
359
|
};
|
|
464
|
-
|
|
465
|
-
if (!element.firstChild || isPre(element)) return
|
|
466
|
-
|
|
360
|
+
if (!element.firstChild || isPre(element)) return;
|
|
467
361
|
var prevText = null;
|
|
468
362
|
var keepLeadingWs = false;
|
|
469
|
-
|
|
470
363
|
var prev = null;
|
|
471
364
|
var node = next(prev, element, isPre);
|
|
472
|
-
|
|
473
365
|
while (node !== element) {
|
|
474
|
-
if (node.nodeType === 3 || node.nodeType === 4) {
|
|
366
|
+
if (node.nodeType === 3 || node.nodeType === 4) {
|
|
367
|
+
// Node.TEXT_NODE or Node.CDATA_SECTION_NODE
|
|
475
368
|
var text = node.data.replace(/[ \r\n\t]+/g, ' ');
|
|
476
|
-
|
|
477
|
-
if ((!prevText || / $/.test(prevText.data)) &&
|
|
478
|
-
!keepLeadingWs && text[0] === ' ') {
|
|
369
|
+
if ((!prevText || / $/.test(prevText.data)) && !keepLeadingWs && text[0] === ' ') {
|
|
479
370
|
text = text.substr(1);
|
|
480
371
|
}
|
|
481
372
|
|
|
482
373
|
// `text` might be empty at this point.
|
|
483
374
|
if (!text) {
|
|
484
375
|
node = remove(node);
|
|
485
|
-
continue
|
|
376
|
+
continue;
|
|
486
377
|
}
|
|
487
|
-
|
|
488
378
|
node.data = text;
|
|
489
|
-
|
|
490
379
|
prevText = node;
|
|
491
|
-
} else if (node.nodeType === 1) {
|
|
380
|
+
} else if (node.nodeType === 1) {
|
|
381
|
+
// Node.ELEMENT_NODE
|
|
492
382
|
if (isBlock(node) || node.nodeName === 'BR') {
|
|
493
383
|
if (prevText) {
|
|
494
384
|
prevText.data = prevText.data.replace(/ $/, '');
|
|
495
385
|
}
|
|
496
|
-
|
|
497
386
|
prevText = null;
|
|
498
387
|
keepLeadingWs = false;
|
|
499
388
|
} else if (isVoid(node) || isPre(node)) {
|
|
@@ -506,14 +395,12 @@ function collapseWhitespace (options) {
|
|
|
506
395
|
}
|
|
507
396
|
} else {
|
|
508
397
|
node = remove(node);
|
|
509
|
-
continue
|
|
398
|
+
continue;
|
|
510
399
|
}
|
|
511
|
-
|
|
512
400
|
var nextNode = next(prev, node, isPre);
|
|
513
401
|
prev = node;
|
|
514
402
|
node = nextNode;
|
|
515
403
|
}
|
|
516
|
-
|
|
517
404
|
if (prevText) {
|
|
518
405
|
prevText.data = prevText.data.replace(/ $/, '');
|
|
519
406
|
if (!prevText.data) {
|
|
@@ -529,12 +416,10 @@ function collapseWhitespace (options) {
|
|
|
529
416
|
* @param {Node} node
|
|
530
417
|
* @return {Node} node
|
|
531
418
|
*/
|
|
532
|
-
function remove
|
|
419
|
+
function remove(node) {
|
|
533
420
|
var next = node.nextSibling || node.parentNode;
|
|
534
|
-
|
|
535
421
|
node.parentNode.removeChild(node);
|
|
536
|
-
|
|
537
|
-
return next
|
|
422
|
+
return next;
|
|
538
423
|
}
|
|
539
424
|
|
|
540
425
|
/**
|
|
@@ -546,25 +431,24 @@ function remove (node) {
|
|
|
546
431
|
* @param {Function} isPre
|
|
547
432
|
* @return {Node}
|
|
548
433
|
*/
|
|
549
|
-
function next
|
|
550
|
-
if (
|
|
551
|
-
return current.nextSibling || current.parentNode
|
|
434
|
+
function next(prev, current, isPre) {
|
|
435
|
+
if (prev && prev.parentNode === current || isPre(current)) {
|
|
436
|
+
return current.nextSibling || current.parentNode;
|
|
552
437
|
}
|
|
553
|
-
|
|
554
|
-
return current.firstChild || current.nextSibling || current.parentNode
|
|
438
|
+
return current.firstChild || current.nextSibling || current.parentNode;
|
|
555
439
|
}
|
|
556
440
|
|
|
557
441
|
/*
|
|
558
442
|
* Set up window for Node.js
|
|
559
443
|
*/
|
|
560
444
|
|
|
561
|
-
var root =
|
|
445
|
+
var root = typeof window !== 'undefined' ? window : {};
|
|
562
446
|
|
|
563
447
|
/*
|
|
564
448
|
* Parsing HTML strings
|
|
565
449
|
*/
|
|
566
450
|
|
|
567
|
-
function canParseHTMLNatively
|
|
451
|
+
function canParseHTMLNatively() {
|
|
568
452
|
var Parser = root.DOMParser;
|
|
569
453
|
var canParse = false;
|
|
570
454
|
|
|
@@ -576,13 +460,10 @@ function canParseHTMLNatively () {
|
|
|
576
460
|
canParse = true;
|
|
577
461
|
}
|
|
578
462
|
} catch (e) {}
|
|
579
|
-
|
|
580
|
-
return canParse
|
|
463
|
+
return canParse;
|
|
581
464
|
}
|
|
582
|
-
|
|
583
|
-
function createHTMLParser () {
|
|
465
|
+
function createHTMLParser() {
|
|
584
466
|
var Parser = function () {};
|
|
585
|
-
|
|
586
467
|
{
|
|
587
468
|
if (shouldUseActiveX()) {
|
|
588
469
|
Parser.prototype.parseFromString = function (string) {
|
|
@@ -591,7 +472,7 @@ function createHTMLParser () {
|
|
|
591
472
|
doc.open();
|
|
592
473
|
doc.write(string);
|
|
593
474
|
doc.close();
|
|
594
|
-
return doc
|
|
475
|
+
return doc;
|
|
595
476
|
};
|
|
596
477
|
} else {
|
|
597
478
|
Parser.prototype.parseFromString = function (string) {
|
|
@@ -599,35 +480,31 @@ function createHTMLParser () {
|
|
|
599
480
|
doc.open();
|
|
600
481
|
doc.write(string);
|
|
601
482
|
doc.close();
|
|
602
|
-
return doc
|
|
483
|
+
return doc;
|
|
603
484
|
};
|
|
604
485
|
}
|
|
605
486
|
}
|
|
606
|
-
return Parser
|
|
487
|
+
return Parser;
|
|
607
488
|
}
|
|
608
|
-
|
|
609
|
-
function shouldUseActiveX () {
|
|
489
|
+
function shouldUseActiveX() {
|
|
610
490
|
var useActiveX = false;
|
|
611
491
|
try {
|
|
612
492
|
document.implementation.createHTMLDocument('').open();
|
|
613
493
|
} catch (e) {
|
|
614
494
|
if (root.ActiveXObject) useActiveX = true;
|
|
615
495
|
}
|
|
616
|
-
return useActiveX
|
|
496
|
+
return useActiveX;
|
|
617
497
|
}
|
|
618
|
-
|
|
619
498
|
var HTMLParser = canParseHTMLNatively() ? root.DOMParser : createHTMLParser();
|
|
620
499
|
|
|
621
|
-
function RootNode
|
|
500
|
+
function RootNode(input, options) {
|
|
622
501
|
var root;
|
|
623
502
|
if (typeof input === 'string') {
|
|
624
503
|
var doc = htmlParser().parseFromString(
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
'text/html'
|
|
630
|
-
);
|
|
504
|
+
// DOM parsers arrange elements in the <head> and <body>.
|
|
505
|
+
// Wrapping in a custom element ensures elements are reliably arranged in
|
|
506
|
+
// a single element.
|
|
507
|
+
'<x-turndown id="turndown-root">' + input + '</x-turndown>', 'text/html');
|
|
631
508
|
root = doc.getElementById('turndown-root');
|
|
632
509
|
} else {
|
|
633
510
|
root = input.cloneNode(true);
|
|
@@ -638,43 +515,34 @@ function RootNode (input, options) {
|
|
|
638
515
|
isVoid: isVoid,
|
|
639
516
|
isPre: options.preformattedCode ? isPreOrCode : null
|
|
640
517
|
});
|
|
641
|
-
|
|
642
|
-
return root
|
|
518
|
+
return root;
|
|
643
519
|
}
|
|
644
|
-
|
|
645
520
|
var _htmlParser;
|
|
646
|
-
function htmlParser
|
|
521
|
+
function htmlParser() {
|
|
647
522
|
_htmlParser = _htmlParser || new HTMLParser();
|
|
648
|
-
return _htmlParser
|
|
523
|
+
return _htmlParser;
|
|
649
524
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
return node.nodeName === 'PRE' || node.nodeName === 'CODE'
|
|
525
|
+
function isPreOrCode(node) {
|
|
526
|
+
return node.nodeName === 'PRE' || node.nodeName === 'CODE';
|
|
653
527
|
}
|
|
654
528
|
|
|
655
|
-
function Node
|
|
529
|
+
function Node(node, options) {
|
|
656
530
|
node.isBlock = isBlock(node);
|
|
657
531
|
node.isCode = node.nodeName === 'CODE' || node.parentNode.isCode;
|
|
658
532
|
node.isBlank = isBlank(node);
|
|
659
533
|
node.flankingWhitespace = flankingWhitespace(node, options);
|
|
660
|
-
return node
|
|
534
|
+
return node;
|
|
661
535
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
return (
|
|
665
|
-
!isVoid(node) &&
|
|
666
|
-
!isMeaningfulWhenBlank(node) &&
|
|
667
|
-
/^\s*$/i.test(node.textContent) &&
|
|
668
|
-
!hasVoid(node) &&
|
|
669
|
-
!hasMeaningfulWhenBlank(node)
|
|
670
|
-
)
|
|
536
|
+
function isBlank(node) {
|
|
537
|
+
return !isVoid(node) && !isMeaningfulWhenBlank(node) && /^\s*$/i.test(node.textContent) && !hasVoid(node) && !hasMeaningfulWhenBlank(node);
|
|
671
538
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
539
|
+
function flankingWhitespace(node, options) {
|
|
540
|
+
if (node.isBlock || options.preformattedCode && node.isCode) {
|
|
541
|
+
return {
|
|
542
|
+
leading: '',
|
|
543
|
+
trailing: ''
|
|
544
|
+
};
|
|
676
545
|
}
|
|
677
|
-
|
|
678
546
|
var edges = edgeWhitespace(node.textContent);
|
|
679
547
|
|
|
680
548
|
// abandon leading ASCII WS if left-flanked by ASCII WS
|
|
@@ -686,27 +554,28 @@ function flankingWhitespace (node, options) {
|
|
|
686
554
|
if (edges.trailingAscii && isFlankedByWhitespace('right', node, options)) {
|
|
687
555
|
edges.trailing = edges.trailingNonAscii;
|
|
688
556
|
}
|
|
689
|
-
|
|
690
|
-
|
|
557
|
+
return {
|
|
558
|
+
leading: edges.leading,
|
|
559
|
+
trailing: edges.trailing
|
|
560
|
+
};
|
|
691
561
|
}
|
|
692
|
-
|
|
693
|
-
function edgeWhitespace (string) {
|
|
562
|
+
function edgeWhitespace(string) {
|
|
694
563
|
var m = string.match(/^(([ \t\r\n]*)(\s*))(?:(?=\S)[\s\S]*\S)?((\s*?)([ \t\r\n]*))$/);
|
|
695
564
|
return {
|
|
696
|
-
leading: m[1],
|
|
565
|
+
leading: m[1],
|
|
566
|
+
// whole string for whitespace-only strings
|
|
697
567
|
leadingAscii: m[2],
|
|
698
568
|
leadingNonAscii: m[3],
|
|
699
|
-
trailing: m[4],
|
|
569
|
+
trailing: m[4],
|
|
570
|
+
// empty for whitespace-only strings
|
|
700
571
|
trailingNonAscii: m[5],
|
|
701
572
|
trailingAscii: m[6]
|
|
702
|
-
}
|
|
573
|
+
};
|
|
703
574
|
}
|
|
704
|
-
|
|
705
|
-
function isFlankedByWhitespace (side, node, options) {
|
|
575
|
+
function isFlankedByWhitespace(side, node, options) {
|
|
706
576
|
var sibling;
|
|
707
577
|
var regExp;
|
|
708
578
|
var isFlanked;
|
|
709
|
-
|
|
710
579
|
if (side === 'left') {
|
|
711
580
|
sibling = node.previousSibling;
|
|
712
581
|
regExp = / $/;
|
|
@@ -714,7 +583,6 @@ function isFlankedByWhitespace (side, node, options) {
|
|
|
714
583
|
sibling = node.nextSibling;
|
|
715
584
|
regExp = /^ /;
|
|
716
585
|
}
|
|
717
|
-
|
|
718
586
|
if (sibling) {
|
|
719
587
|
if (sibling.nodeType === 3) {
|
|
720
588
|
isFlanked = regExp.test(sibling.nodeValue);
|
|
@@ -724,29 +592,12 @@ function isFlankedByWhitespace (side, node, options) {
|
|
|
724
592
|
isFlanked = regExp.test(sibling.textContent);
|
|
725
593
|
}
|
|
726
594
|
}
|
|
727
|
-
return isFlanked
|
|
595
|
+
return isFlanked;
|
|
728
596
|
}
|
|
729
597
|
|
|
730
598
|
var reduce = Array.prototype.reduce;
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
[/\*/g, '\\*'],
|
|
734
|
-
[/^-/g, '\\-'],
|
|
735
|
-
[/^\+ /g, '\\+ '],
|
|
736
|
-
[/^(=+)/g, '\\$1'],
|
|
737
|
-
[/^(#{1,6}) /g, '\\$1 '],
|
|
738
|
-
[/`/g, '\\`'],
|
|
739
|
-
[/^~~~/g, '\\~~~'],
|
|
740
|
-
[/\[/g, '\\['],
|
|
741
|
-
[/\]/g, '\\]'],
|
|
742
|
-
[/^>/g, '\\>'],
|
|
743
|
-
[/_/g, '\\_'],
|
|
744
|
-
[/^(\d+)\. /g, '$1\\. ']
|
|
745
|
-
];
|
|
746
|
-
|
|
747
|
-
function TurndownService (options) {
|
|
748
|
-
if (!(this instanceof TurndownService)) return new TurndownService(options)
|
|
749
|
-
|
|
599
|
+
function TurndownService(options) {
|
|
600
|
+
if (!(this instanceof TurndownService)) return new TurndownService(options);
|
|
750
601
|
var defaults = {
|
|
751
602
|
rules: rules,
|
|
752
603
|
headingStyle: 'setext',
|
|
@@ -761,19 +612,18 @@ function TurndownService (options) {
|
|
|
761
612
|
br: ' ',
|
|
762
613
|
preformattedCode: false,
|
|
763
614
|
blankReplacement: function (content, node) {
|
|
764
|
-
return node.isBlock ? '\n\n' : ''
|
|
615
|
+
return node.isBlock ? '\n\n' : '';
|
|
765
616
|
},
|
|
766
617
|
keepReplacement: function (content, node) {
|
|
767
|
-
return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML
|
|
618
|
+
return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML;
|
|
768
619
|
},
|
|
769
620
|
defaultReplacement: function (content, node) {
|
|
770
|
-
return node.isBlock ? '\n\n' + content + '\n\n' : content
|
|
621
|
+
return node.isBlock ? '\n\n' + content + '\n\n' : content;
|
|
771
622
|
}
|
|
772
623
|
};
|
|
773
624
|
this.options = extend({}, defaults, options);
|
|
774
625
|
this.rules = new Rules(this.options);
|
|
775
626
|
}
|
|
776
|
-
|
|
777
627
|
TurndownService.prototype = {
|
|
778
628
|
/**
|
|
779
629
|
* The entry point for converting a string or DOM node to Markdown
|
|
@@ -785,17 +635,12 @@ TurndownService.prototype = {
|
|
|
785
635
|
|
|
786
636
|
turndown: function (input) {
|
|
787
637
|
if (!canConvert(input)) {
|
|
788
|
-
throw new TypeError(
|
|
789
|
-
input + ' is not a string, or an element/document/fragment node.'
|
|
790
|
-
)
|
|
638
|
+
throw new TypeError(input + ' is not a string, or an element/document/fragment node.');
|
|
791
639
|
}
|
|
792
|
-
|
|
793
|
-
if (input === '') return ''
|
|
794
|
-
|
|
640
|
+
if (input === '') return '';
|
|
795
641
|
var output = process.call(this, new RootNode(input, this.options));
|
|
796
|
-
return postProcess.call(this, output)
|
|
642
|
+
return postProcess.call(this, output);
|
|
797
643
|
},
|
|
798
|
-
|
|
799
644
|
/**
|
|
800
645
|
* Add one or more plugins
|
|
801
646
|
* @public
|
|
@@ -810,11 +655,10 @@ TurndownService.prototype = {
|
|
|
810
655
|
} else if (typeof plugin === 'function') {
|
|
811
656
|
plugin(this);
|
|
812
657
|
} else {
|
|
813
|
-
throw new TypeError('plugin must be a Function or an Array of Functions')
|
|
658
|
+
throw new TypeError('plugin must be a Function or an Array of Functions');
|
|
814
659
|
}
|
|
815
|
-
return this
|
|
660
|
+
return this;
|
|
816
661
|
},
|
|
817
|
-
|
|
818
662
|
/**
|
|
819
663
|
* Adds a rule
|
|
820
664
|
* @public
|
|
@@ -826,9 +670,8 @@ TurndownService.prototype = {
|
|
|
826
670
|
|
|
827
671
|
addRule: function (key, rule) {
|
|
828
672
|
this.rules.add(key, rule);
|
|
829
|
-
return this
|
|
673
|
+
return this;
|
|
830
674
|
},
|
|
831
|
-
|
|
832
675
|
/**
|
|
833
676
|
* Keep a node (as HTML) that matches the filter
|
|
834
677
|
* @public
|
|
@@ -839,9 +682,8 @@ TurndownService.prototype = {
|
|
|
839
682
|
|
|
840
683
|
keep: function (filter) {
|
|
841
684
|
this.rules.keep(filter);
|
|
842
|
-
return this
|
|
685
|
+
return this;
|
|
843
686
|
},
|
|
844
|
-
|
|
845
687
|
/**
|
|
846
688
|
* Remove a node that matches the filter
|
|
847
689
|
* @public
|
|
@@ -852,9 +694,8 @@ TurndownService.prototype = {
|
|
|
852
694
|
|
|
853
695
|
remove: function (filter) {
|
|
854
696
|
this.rules.remove(filter);
|
|
855
|
-
return this
|
|
697
|
+
return this;
|
|
856
698
|
},
|
|
857
|
-
|
|
858
699
|
/**
|
|
859
700
|
* Escapes Markdown syntax
|
|
860
701
|
* @public
|
|
@@ -864,9 +705,7 @@ TurndownService.prototype = {
|
|
|
864
705
|
*/
|
|
865
706
|
|
|
866
707
|
escape: function (string) {
|
|
867
|
-
return
|
|
868
|
-
return accumulator.replace(escape[0], escape[1])
|
|
869
|
-
}, string)
|
|
708
|
+
return escapeMarkdown(string);
|
|
870
709
|
}
|
|
871
710
|
};
|
|
872
711
|
|
|
@@ -878,20 +717,18 @@ TurndownService.prototype = {
|
|
|
878
717
|
* @type String
|
|
879
718
|
*/
|
|
880
719
|
|
|
881
|
-
function process
|
|
720
|
+
function process(parentNode) {
|
|
882
721
|
var self = this;
|
|
883
722
|
return reduce.call(parentNode.childNodes, function (output, node) {
|
|
884
723
|
node = new Node(node, self.options);
|
|
885
|
-
|
|
886
724
|
var replacement = '';
|
|
887
725
|
if (node.nodeType === 3) {
|
|
888
726
|
replacement = node.isCode ? node.nodeValue : self.escape(node.nodeValue);
|
|
889
727
|
} else if (node.nodeType === 1) {
|
|
890
728
|
replacement = replacementForNode.call(self, node);
|
|
891
729
|
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
}, '')
|
|
730
|
+
return join(output, replacement);
|
|
731
|
+
}, '');
|
|
895
732
|
}
|
|
896
733
|
|
|
897
734
|
/**
|
|
@@ -902,15 +739,14 @@ function process (parentNode) {
|
|
|
902
739
|
* @type String
|
|
903
740
|
*/
|
|
904
741
|
|
|
905
|
-
function postProcess
|
|
742
|
+
function postProcess(output) {
|
|
906
743
|
var self = this;
|
|
907
744
|
this.rules.forEach(function (rule) {
|
|
908
745
|
if (typeof rule.append === 'function') {
|
|
909
746
|
output = join(output, rule.append(self.options));
|
|
910
747
|
}
|
|
911
748
|
});
|
|
912
|
-
|
|
913
|
-
return output.replace(/^[\t\r\n]+/, '').replace(/[\t\r\n\s]+$/, '')
|
|
749
|
+
return output.replace(/^[\t\r\n]+/, '').replace(/[\t\r\n\s]+$/, '');
|
|
914
750
|
}
|
|
915
751
|
|
|
916
752
|
/**
|
|
@@ -921,16 +757,12 @@ function postProcess (output) {
|
|
|
921
757
|
* @type String
|
|
922
758
|
*/
|
|
923
759
|
|
|
924
|
-
function replacementForNode
|
|
760
|
+
function replacementForNode(node) {
|
|
925
761
|
var rule = this.rules.forNode(node);
|
|
926
762
|
var content = process.call(this, node);
|
|
927
763
|
var whitespace = node.flankingWhitespace;
|
|
928
764
|
if (whitespace.leading || whitespace.trailing) content = content.trim();
|
|
929
|
-
return (
|
|
930
|
-
whitespace.leading +
|
|
931
|
-
rule.replacement(content, node, this.options) +
|
|
932
|
-
whitespace.trailing
|
|
933
|
-
)
|
|
765
|
+
return whitespace.leading + rule.replacement(content, node, this.options) + whitespace.trailing;
|
|
934
766
|
}
|
|
935
767
|
|
|
936
768
|
/**
|
|
@@ -942,13 +774,12 @@ function replacementForNode (node) {
|
|
|
942
774
|
* @type String
|
|
943
775
|
*/
|
|
944
776
|
|
|
945
|
-
function join
|
|
777
|
+
function join(output, replacement) {
|
|
946
778
|
var s1 = trimTrailingNewlines(output);
|
|
947
779
|
var s2 = trimLeadingNewlines(replacement);
|
|
948
780
|
var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
|
|
949
781
|
var separator = '\n\n'.substring(0, nls);
|
|
950
|
-
|
|
951
|
-
return s1 + separator + s2
|
|
782
|
+
return s1 + separator + s2;
|
|
952
783
|
}
|
|
953
784
|
|
|
954
785
|
/**
|
|
@@ -959,15 +790,8 @@ function join (output, replacement) {
|
|
|
959
790
|
* @type String|Object|Array|Boolean|Number
|
|
960
791
|
*/
|
|
961
792
|
|
|
962
|
-
function canConvert
|
|
963
|
-
return (
|
|
964
|
-
input != null && (
|
|
965
|
-
typeof input === 'string' ||
|
|
966
|
-
(input.nodeType && (
|
|
967
|
-
input.nodeType === 1 || input.nodeType === 9 || input.nodeType === 11
|
|
968
|
-
))
|
|
969
|
-
)
|
|
970
|
-
)
|
|
793
|
+
function canConvert(input) {
|
|
794
|
+
return input != null && (typeof input === 'string' || input.nodeType && (input.nodeType === 1 || input.nodeType === 9 || input.nodeType === 11));
|
|
971
795
|
}
|
|
972
796
|
|
|
973
797
|
module.exports = TurndownService;
|