Socket
Socket
Sign inDemoInstall

turndown

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

turndown - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

170

dist/turndown.js

@@ -29,5 +29,5 @@ var TurndownService = (function () {

var converters = {};
var rules = {};
converters.paragraph = {
rules.paragraph = {
filter: 'p',

@@ -40,3 +40,3 @@

converters.lineBreak = {
rules.lineBreak = {
filter: 'br',

@@ -49,3 +49,3 @@

converters.heading = {
rules.heading = {
filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],

@@ -67,3 +67,3 @@

converters.blockquote = {
rules.blockquote = {
filter: 'blockquote',

@@ -78,3 +78,3 @@

converters.list = {
rules.list = {
filter: ['ul', 'ol'],

@@ -92,3 +92,3 @@

converters.listItem = {
rules.listItem = {
filter: 'li',

@@ -114,3 +114,3 @@

converters.indentedCodeBlock = {
rules.indentedCodeBlock = {
filter: function (node, options) {

@@ -134,3 +134,3 @@ return (

converters.fencedCodeBlock = {
rules.fencedCodeBlock = {
filter: function (node, options) {

@@ -157,3 +157,3 @@ return (

converters.horizontalRule = {
rules.horizontalRule = {
filter: 'hr',

@@ -166,3 +166,3 @@

converters.inlineLink = {
rules.inlineLink = {
filter: function (node, options) {

@@ -183,3 +183,3 @@ return (

converters.referenceLink = {
rules.referenceLink = {
filter: function (node, options) {

@@ -230,3 +230,3 @@ return (

converters.emphasis = {
rules.emphasis = {
filter: ['em', 'i'],

@@ -239,3 +239,3 @@

converters.strong = {
rules.strong = {
filter: ['strong', 'b'],

@@ -248,3 +248,3 @@

converters.code = {
rules.code = {
filter: function (node) {

@@ -258,7 +258,8 @@ var hasSiblings = node.previousSibling || node.nextSibling;

replacement: function (content) {
return '`' + content + '`'
var delimiter = /`/.test(content) ? '``' : '`';
return delimiter + content + delimiter
}
};
converters.image = {
rules.image = {
filter: 'img',

@@ -736,4 +737,6 @@

function TurndownService (options) {
if (!(this instanceof TurndownService)) return new TurndownService(options)
var defaults = {
converters: converters,
rules: rules,
headingStyle: 'setext',

@@ -749,36 +752,36 @@ hr: '* * *',

br: ' ',
blankConverter: {
replacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
}
blankReplacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
},
defaultConverter: {
replacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
defaultReplacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
},
keepConverter: {
filter: function (node) {
switch (node.nodeName) {
case 'TABLE':
return true
case 'PRE':
return node.firstChild && node.firstChild.nodeName !== 'CODE'
default:
return false
}
},
replacement: function (content, node) {
return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML
keep: function (node) {
switch (node.nodeName) {
case 'TABLE':
return true
case 'PRE':
return node.firstChild && node.firstChild.nodeName !== 'CODE'
default:
return false
}
},
removeConverter: {
filter: ['head', 'script'],
replacement: function () {
return ''
}
}
remove: ['head', 'link', 'meta', 'script', 'style']
};
optionsValidator.validate(options);
this.options = extend({}, defaults, options);
this.options.keepConverter = this.options.keepConverter || {
filter: this.options.keep,
replacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
};
this.options.removeConverter = this.options.removeConverter || {
filter: this.options.remove,
replacement: function () {
return ''
}
};
}

@@ -800,2 +803,18 @@

use: function (plugin) {
if (Array.isArray(plugin)) {
for (var i = 0; i < plugin.length; i++) this.use(plugin[i]);
} else if (typeof plugin === 'function') {
plugin(this);
} else {
throw new TypeError('plugin must be a Function or an Array of Functions')
}
return this
},
addRule: function (key, rule) {
this.options.rules[key] = rule;
return this
},
/**

@@ -810,3 +829,3 @@ * Reduces a DOM node down to its Markdown string equivalent

var replacement;
var replacement = '';
if (node.nodeType === 3) {

@@ -838,3 +857,5 @@ replacement = _this.escape(node.nodeValue);

// Escape ul bullet points
.replace(/^([^\\\w]*)([*+-]) /gm, '$1\\$2 ')
.replace(/^([^\\\w]*)[*+-] /gm, function (match) {
return match.replace(/([*+-])/g, '\\$1')
})

@@ -844,14 +865,24 @@ // Escape blockquote indents

// Escape em/strong *
.replace(/\*{1,2}([^\W*]+\W*)+\*{1,2}/g, function (match) {
// Escape strong *
.replace(/[^\\]\*\*[^*\s.].+?[^\s]\*\*/g, function (match) {
return match.replace(/\*/g, '\\*')
})
// Escape em/strong _
.replace(/_{1,2}([^\W_]+\W*)+_{1,2}/g, function (match) {
// Escape em *
.replace(/[^\\]\*[^*\s.].+?[^\s]\*/g, function (match) {
return match.replace(/\*/g, '\\*')
})
// Escape strong _
.replace(/[^\\]__[^_\s.].+?[^\s]__/g, function (match) {
return match.replace(/_/g, '\\_')
})
// Escape em _
.replace(/[^\\]_[^_\s.].+?[^\s]_/g, function (match) {
return match.replace(/_/g, '\\_')
})
// Escape `
.replace(/`([^\W`]+\W*)+`/g, function (match) {
.replace(/[^\\]`[^`\s.].+?`/g, function (match) {
return match.replace(/`/g, '\\`')

@@ -870,10 +901,9 @@ })

replacementForNode: function replacementForNode (node) {
var converter = this.converterForNode(node);
var rule = this.ruleForNode(node);
var content = this.process(node);
var whitespace = node.flankingWhitespace;
if (whitespace.leading || whitespace.trailing) content = content.trim();
return (
whitespace.leading +
converter.replacement(content, node, this.options) +
rule.replacement(content, node, this.options) +
whitespace.trailing

@@ -884,24 +914,26 @@ )

/**
* Finds a converter for a given node
* Finds a rule for a given node
*/
converterForNode: function converterForNode (node) {
ruleForNode: function ruleForNode (node) {
if (this.filterValue(this.options.keepConverter, node)) {
return this.options.keepConverter
}
if (this.filterValue(this.options.removeConverter, node)) {
return this.options.removeConverter
}
if (node.isBlank) return this.options.blankConverter
for (var key in this.options.converters) {
var converter = this.options.converters[key];
if (this.filterValue(converter, node)) return converter
if (node.isBlank) return { replacement: this.options.blankReplacement }
for (var key in this.options.rules) {
var rule = this.options.rules[key];
if (this.filterValue(rule, node)) return rule
}
return this.options.defaultConverter
return { replacement: this.options.defaultReplacement }
},
filterValue: function filterValue (converter, node) {
var filter = converter.filter;
filterValue: function filterValue (rule, node) {
var filter = rule.filter;
if (typeof filter === 'string') {

@@ -912,3 +944,3 @@ if (filter === node.nodeName.toLowerCase()) return true

} else if (typeof filter === 'function') {
if (filter.call(converter, node, this.options)) return true
if (filter.call(rule, node, this.options)) return true
} else {

@@ -920,6 +952,6 @@ throw new TypeError('`filter` needs to be a string, array, or function')

postProcess: function postProcess (output) {
for (var key in this.options.converters) {
var converter = this.options.converters[key];
if (typeof converter.append === 'function') {
output = join(output, converter.append(this.options));
for (var key in this.options.rules) {
var rule = this.options.rules[key];
if (typeof rule.append === 'function') {
output = join(output, rule.append(this.options));
}

@@ -926,0 +958,0 @@ }

@@ -28,5 +28,5 @@ 'use strict';

var converters = {};
var rules = {};
converters.paragraph = {
rules.paragraph = {
filter: 'p',

@@ -39,3 +39,3 @@

converters.lineBreak = {
rules.lineBreak = {
filter: 'br',

@@ -48,3 +48,3 @@

converters.heading = {
rules.heading = {
filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],

@@ -66,3 +66,3 @@

converters.blockquote = {
rules.blockquote = {
filter: 'blockquote',

@@ -77,3 +77,3 @@

converters.list = {
rules.list = {
filter: ['ul', 'ol'],

@@ -91,3 +91,3 @@

converters.listItem = {
rules.listItem = {
filter: 'li',

@@ -113,3 +113,3 @@

converters.indentedCodeBlock = {
rules.indentedCodeBlock = {
filter: function (node, options) {

@@ -133,3 +133,3 @@ return (

converters.fencedCodeBlock = {
rules.fencedCodeBlock = {
filter: function (node, options) {

@@ -156,3 +156,3 @@ return (

converters.horizontalRule = {
rules.horizontalRule = {
filter: 'hr',

@@ -165,3 +165,3 @@

converters.inlineLink = {
rules.inlineLink = {
filter: function (node, options) {

@@ -182,3 +182,3 @@ return (

converters.referenceLink = {
rules.referenceLink = {
filter: function (node, options) {

@@ -229,3 +229,3 @@ return (

converters.emphasis = {
rules.emphasis = {
filter: ['em', 'i'],

@@ -238,3 +238,3 @@

converters.strong = {
rules.strong = {
filter: ['strong', 'b'],

@@ -247,3 +247,3 @@

converters.code = {
rules.code = {
filter: function (node) {

@@ -257,7 +257,8 @@ var hasSiblings = node.previousSibling || node.nextSibling;

replacement: function (content) {
return '`' + content + '`'
var delimiter = /`/.test(content) ? '``' : '`';
return delimiter + content + delimiter
}
};
converters.image = {
rules.image = {
filter: 'img',

@@ -735,4 +736,6 @@

function TurndownService (options) {
if (!(this instanceof TurndownService)) return new TurndownService(options)
var defaults = {
converters: converters,
rules: rules,
headingStyle: 'setext',

@@ -748,36 +751,36 @@ hr: '* * *',

br: ' ',
blankConverter: {
replacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
}
blankReplacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
},
defaultConverter: {
replacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
defaultReplacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
},
keepConverter: {
filter: function (node) {
switch (node.nodeName) {
case 'TABLE':
return true
case 'PRE':
return node.firstChild && node.firstChild.nodeName !== 'CODE'
default:
return false
}
},
replacement: function (content, node) {
return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML
keep: function (node) {
switch (node.nodeName) {
case 'TABLE':
return true
case 'PRE':
return node.firstChild && node.firstChild.nodeName !== 'CODE'
default:
return false
}
},
removeConverter: {
filter: ['head', 'script'],
replacement: function () {
return ''
}
}
remove: ['head', 'link', 'meta', 'script', 'style']
};
optionsValidator.validate(options);
this.options = extend({}, defaults, options);
this.options.keepConverter = this.options.keepConverter || {
filter: this.options.keep,
replacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
};
this.options.removeConverter = this.options.removeConverter || {
filter: this.options.remove,
replacement: function () {
return ''
}
};
}

@@ -799,2 +802,18 @@

use: function (plugin) {
if (Array.isArray(plugin)) {
for (var i = 0; i < plugin.length; i++) this.use(plugin[i]);
} else if (typeof plugin === 'function') {
plugin(this);
} else {
throw new TypeError('plugin must be a Function or an Array of Functions')
}
return this
},
addRule: function (key, rule) {
this.options.rules[key] = rule;
return this
},
/**

@@ -809,3 +828,3 @@ * Reduces a DOM node down to its Markdown string equivalent

var replacement;
var replacement = '';
if (node.nodeType === 3) {

@@ -837,3 +856,5 @@ replacement = _this.escape(node.nodeValue);

// Escape ul bullet points
.replace(/^([^\\\w]*)([*+-]) /gm, '$1\\$2 ')
.replace(/^([^\\\w]*)[*+-] /gm, function (match) {
return match.replace(/([*+-])/g, '\\$1')
})

@@ -843,14 +864,24 @@ // Escape blockquote indents

// Escape em/strong *
.replace(/\*{1,2}([^\W*]+\W*)+\*{1,2}/g, function (match) {
// Escape strong *
.replace(/[^\\]\*\*[^*\s.].+?[^\s]\*\*/g, function (match) {
return match.replace(/\*/g, '\\*')
})
// Escape em/strong _
.replace(/_{1,2}([^\W_]+\W*)+_{1,2}/g, function (match) {
// Escape em *
.replace(/[^\\]\*[^*\s.].+?[^\s]\*/g, function (match) {
return match.replace(/\*/g, '\\*')
})
// Escape strong _
.replace(/[^\\]__[^_\s.].+?[^\s]__/g, function (match) {
return match.replace(/_/g, '\\_')
})
// Escape em _
.replace(/[^\\]_[^_\s.].+?[^\s]_/g, function (match) {
return match.replace(/_/g, '\\_')
})
// Escape `
.replace(/`([^\W`]+\W*)+`/g, function (match) {
.replace(/[^\\]`[^`\s.].+?`/g, function (match) {
return match.replace(/`/g, '\\`')

@@ -869,10 +900,9 @@ })

replacementForNode: function replacementForNode (node) {
var converter = this.converterForNode(node);
var rule = this.ruleForNode(node);
var content = this.process(node);
var whitespace = node.flankingWhitespace;
if (whitespace.leading || whitespace.trailing) content = content.trim();
return (
whitespace.leading +
converter.replacement(content, node, this.options) +
rule.replacement(content, node, this.options) +
whitespace.trailing

@@ -883,24 +913,26 @@ )

/**
* Finds a converter for a given node
* Finds a rule for a given node
*/
converterForNode: function converterForNode (node) {
ruleForNode: function ruleForNode (node) {
if (this.filterValue(this.options.keepConverter, node)) {
return this.options.keepConverter
}
if (this.filterValue(this.options.removeConverter, node)) {
return this.options.removeConverter
}
if (node.isBlank) return this.options.blankConverter
for (var key in this.options.converters) {
var converter = this.options.converters[key];
if (this.filterValue(converter, node)) return converter
if (node.isBlank) return { replacement: this.options.blankReplacement }
for (var key in this.options.rules) {
var rule = this.options.rules[key];
if (this.filterValue(rule, node)) return rule
}
return this.options.defaultConverter
return { replacement: this.options.defaultReplacement }
},
filterValue: function filterValue (converter, node) {
var filter = converter.filter;
filterValue: function filterValue (rule, node) {
var filter = rule.filter;
if (typeof filter === 'string') {

@@ -911,3 +943,3 @@ if (filter === node.nodeName.toLowerCase()) return true

} else if (typeof filter === 'function') {
if (filter.call(converter, node, this.options)) return true
if (filter.call(rule, node, this.options)) return true
} else {

@@ -919,6 +951,6 @@ throw new TypeError('`filter` needs to be a string, array, or function')

postProcess: function postProcess (output) {
for (var key in this.options.converters) {
var converter = this.options.converters[key];
if (typeof converter.append === 'function') {
output = join(output, converter.append(this.options));
for (var key in this.options.rules) {
var rule = this.options.rules[key];
if (typeof rule.append === 'function') {
output = join(output, rule.append(this.options));
}

@@ -925,0 +957,0 @@ }

@@ -26,5 +26,5 @@ function extend (destination) {

var converters = {};
var rules = {};
converters.paragraph = {
rules.paragraph = {
filter: 'p',

@@ -37,3 +37,3 @@

converters.lineBreak = {
rules.lineBreak = {
filter: 'br',

@@ -46,3 +46,3 @@

converters.heading = {
rules.heading = {
filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],

@@ -64,3 +64,3 @@

converters.blockquote = {
rules.blockquote = {
filter: 'blockquote',

@@ -75,3 +75,3 @@

converters.list = {
rules.list = {
filter: ['ul', 'ol'],

@@ -89,3 +89,3 @@

converters.listItem = {
rules.listItem = {
filter: 'li',

@@ -111,3 +111,3 @@

converters.indentedCodeBlock = {
rules.indentedCodeBlock = {
filter: function (node, options) {

@@ -131,3 +131,3 @@ return (

converters.fencedCodeBlock = {
rules.fencedCodeBlock = {
filter: function (node, options) {

@@ -154,3 +154,3 @@ return (

converters.horizontalRule = {
rules.horizontalRule = {
filter: 'hr',

@@ -163,3 +163,3 @@

converters.inlineLink = {
rules.inlineLink = {
filter: function (node, options) {

@@ -180,3 +180,3 @@ return (

converters.referenceLink = {
rules.referenceLink = {
filter: function (node, options) {

@@ -227,3 +227,3 @@ return (

converters.emphasis = {
rules.emphasis = {
filter: ['em', 'i'],

@@ -236,3 +236,3 @@

converters.strong = {
rules.strong = {
filter: ['strong', 'b'],

@@ -245,3 +245,3 @@

converters.code = {
rules.code = {
filter: function (node) {

@@ -255,7 +255,8 @@ var hasSiblings = node.previousSibling || node.nextSibling;

replacement: function (content) {
return '`' + content + '`'
var delimiter = /`/.test(content) ? '``' : '`';
return delimiter + content + delimiter
}
};
converters.image = {
rules.image = {
filter: 'img',

@@ -733,4 +734,6 @@

function TurndownService (options) {
if (!(this instanceof TurndownService)) return new TurndownService(options)
var defaults = {
converters: converters,
rules: rules,
headingStyle: 'setext',

@@ -746,36 +749,36 @@ hr: '* * *',

br: ' ',
blankConverter: {
replacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
}
blankReplacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
},
defaultConverter: {
replacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
defaultReplacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
},
keepConverter: {
filter: function (node) {
switch (node.nodeName) {
case 'TABLE':
return true
case 'PRE':
return node.firstChild && node.firstChild.nodeName !== 'CODE'
default:
return false
}
},
replacement: function (content, node) {
return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML
keep: function (node) {
switch (node.nodeName) {
case 'TABLE':
return true
case 'PRE':
return node.firstChild && node.firstChild.nodeName !== 'CODE'
default:
return false
}
},
removeConverter: {
filter: ['head', 'script'],
replacement: function () {
return ''
}
}
remove: ['head', 'link', 'meta', 'script', 'style']
};
optionsValidator.validate(options);
this.options = extend({}, defaults, options);
this.options.keepConverter = this.options.keepConverter || {
filter: this.options.keep,
replacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
};
this.options.removeConverter = this.options.removeConverter || {
filter: this.options.remove,
replacement: function () {
return ''
}
};
}

@@ -797,2 +800,18 @@

use: function (plugin) {
if (Array.isArray(plugin)) {
for (var i = 0; i < plugin.length; i++) this.use(plugin[i]);
} else if (typeof plugin === 'function') {
plugin(this);
} else {
throw new TypeError('plugin must be a Function or an Array of Functions')
}
return this
},
addRule: function (key, rule) {
this.options.rules[key] = rule;
return this
},
/**

@@ -807,3 +826,3 @@ * Reduces a DOM node down to its Markdown string equivalent

var replacement;
var replacement = '';
if (node.nodeType === 3) {

@@ -835,3 +854,5 @@ replacement = _this.escape(node.nodeValue);

// Escape ul bullet points
.replace(/^([^\\\w]*)([*+-]) /gm, '$1\\$2 ')
.replace(/^([^\\\w]*)[*+-] /gm, function (match) {
return match.replace(/([*+-])/g, '\\$1')
})

@@ -841,14 +862,24 @@ // Escape blockquote indents

// Escape em/strong *
.replace(/\*{1,2}([^\W*]+\W*)+\*{1,2}/g, function (match) {
// Escape strong *
.replace(/[^\\]\*\*[^*\s.].+?[^\s]\*\*/g, function (match) {
return match.replace(/\*/g, '\\*')
})
// Escape em/strong _
.replace(/_{1,2}([^\W_]+\W*)+_{1,2}/g, function (match) {
// Escape em *
.replace(/[^\\]\*[^*\s.].+?[^\s]\*/g, function (match) {
return match.replace(/\*/g, '\\*')
})
// Escape strong _
.replace(/[^\\]__[^_\s.].+?[^\s]__/g, function (match) {
return match.replace(/_/g, '\\_')
})
// Escape em _
.replace(/[^\\]_[^_\s.].+?[^\s]_/g, function (match) {
return match.replace(/_/g, '\\_')
})
// Escape `
.replace(/`([^\W`]+\W*)+`/g, function (match) {
.replace(/[^\\]`[^`\s.].+?`/g, function (match) {
return match.replace(/`/g, '\\`')

@@ -867,10 +898,9 @@ })

replacementForNode: function replacementForNode (node) {
var converter = this.converterForNode(node);
var rule = this.ruleForNode(node);
var content = this.process(node);
var whitespace = node.flankingWhitespace;
if (whitespace.leading || whitespace.trailing) content = content.trim();
return (
whitespace.leading +
converter.replacement(content, node, this.options) +
rule.replacement(content, node, this.options) +
whitespace.trailing

@@ -881,24 +911,26 @@ )

/**
* Finds a converter for a given node
* Finds a rule for a given node
*/
converterForNode: function converterForNode (node) {
ruleForNode: function ruleForNode (node) {
if (this.filterValue(this.options.keepConverter, node)) {
return this.options.keepConverter
}
if (this.filterValue(this.options.removeConverter, node)) {
return this.options.removeConverter
}
if (node.isBlank) return this.options.blankConverter
for (var key in this.options.converters) {
var converter = this.options.converters[key];
if (this.filterValue(converter, node)) return converter
if (node.isBlank) return { replacement: this.options.blankReplacement }
for (var key in this.options.rules) {
var rule = this.options.rules[key];
if (this.filterValue(rule, node)) return rule
}
return this.options.defaultConverter
return { replacement: this.options.defaultReplacement }
},
filterValue: function filterValue (converter, node) {
var filter = converter.filter;
filterValue: function filterValue (rule, node) {
var filter = rule.filter;
if (typeof filter === 'string') {

@@ -909,3 +941,3 @@ if (filter === node.nodeName.toLowerCase()) return true

} else if (typeof filter === 'function') {
if (filter.call(converter, node, this.options)) return true
if (filter.call(rule, node, this.options)) return true
} else {

@@ -917,6 +949,6 @@ throw new TypeError('`filter` needs to be a string, array, or function')

postProcess: function postProcess (output) {
for (var key in this.options.converters) {
var converter = this.options.converters[key];
if (typeof converter.append === 'function') {
output = join(output, converter.append(this.options));
for (var key in this.options.rules) {
var rule = this.options.rules[key];
if (typeof rule.append === 'function') {
output = join(output, rule.append(this.options));
}

@@ -923,0 +955,0 @@ }

@@ -28,5 +28,5 @@ 'use strict';

var converters = {};
var rules = {};
converters.paragraph = {
rules.paragraph = {
filter: 'p',

@@ -39,3 +39,3 @@

converters.lineBreak = {
rules.lineBreak = {
filter: 'br',

@@ -48,3 +48,3 @@

converters.heading = {
rules.heading = {
filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],

@@ -66,3 +66,3 @@

converters.blockquote = {
rules.blockquote = {
filter: 'blockquote',

@@ -77,3 +77,3 @@

converters.list = {
rules.list = {
filter: ['ul', 'ol'],

@@ -91,3 +91,3 @@

converters.listItem = {
rules.listItem = {
filter: 'li',

@@ -113,3 +113,3 @@

converters.indentedCodeBlock = {
rules.indentedCodeBlock = {
filter: function (node, options) {

@@ -133,3 +133,3 @@ return (

converters.fencedCodeBlock = {
rules.fencedCodeBlock = {
filter: function (node, options) {

@@ -156,3 +156,3 @@ return (

converters.horizontalRule = {
rules.horizontalRule = {
filter: 'hr',

@@ -165,3 +165,3 @@

converters.inlineLink = {
rules.inlineLink = {
filter: function (node, options) {

@@ -182,3 +182,3 @@ return (

converters.referenceLink = {
rules.referenceLink = {
filter: function (node, options) {

@@ -229,3 +229,3 @@ return (

converters.emphasis = {
rules.emphasis = {
filter: ['em', 'i'],

@@ -238,3 +238,3 @@

converters.strong = {
rules.strong = {
filter: ['strong', 'b'],

@@ -247,3 +247,3 @@

converters.code = {
rules.code = {
filter: function (node) {

@@ -257,7 +257,8 @@ var hasSiblings = node.previousSibling || node.nextSibling;

replacement: function (content) {
return '`' + content + '`'
var delimiter = /`/.test(content) ? '``' : '`';
return delimiter + content + delimiter
}
};
converters.image = {
rules.image = {
filter: 'img',

@@ -735,4 +736,6 @@

function TurndownService (options) {
if (!(this instanceof TurndownService)) return new TurndownService(options)
var defaults = {
converters: converters,
rules: rules,
headingStyle: 'setext',

@@ -748,36 +751,36 @@ hr: '* * *',

br: ' ',
blankConverter: {
replacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
}
blankReplacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
},
defaultConverter: {
replacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
defaultReplacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
},
keepConverter: {
filter: function (node) {
switch (node.nodeName) {
case 'TABLE':
return true
case 'PRE':
return node.firstChild && node.firstChild.nodeName !== 'CODE'
default:
return false
}
},
replacement: function (content, node) {
return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML
keep: function (node) {
switch (node.nodeName) {
case 'TABLE':
return true
case 'PRE':
return node.firstChild && node.firstChild.nodeName !== 'CODE'
default:
return false
}
},
removeConverter: {
filter: ['head', 'script'],
replacement: function () {
return ''
}
}
remove: ['head', 'link', 'meta', 'script', 'style']
};
optionsValidator.validate(options);
this.options = extend({}, defaults, options);
this.options.keepConverter = this.options.keepConverter || {
filter: this.options.keep,
replacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
};
this.options.removeConverter = this.options.removeConverter || {
filter: this.options.remove,
replacement: function () {
return ''
}
};
}

@@ -799,2 +802,18 @@

use: function (plugin) {
if (Array.isArray(plugin)) {
for (var i = 0; i < plugin.length; i++) this.use(plugin[i]);
} else if (typeof plugin === 'function') {
plugin(this);
} else {
throw new TypeError('plugin must be a Function or an Array of Functions')
}
return this
},
addRule: function (key, rule) {
this.options.rules[key] = rule;
return this
},
/**

@@ -809,3 +828,3 @@ * Reduces a DOM node down to its Markdown string equivalent

var replacement;
var replacement = '';
if (node.nodeType === 3) {

@@ -837,3 +856,5 @@ replacement = _this.escape(node.nodeValue);

// Escape ul bullet points
.replace(/^([^\\\w]*)([*+-]) /gm, '$1\\$2 ')
.replace(/^([^\\\w]*)[*+-] /gm, function (match) {
return match.replace(/([*+-])/g, '\\$1')
})

@@ -843,14 +864,24 @@ // Escape blockquote indents

// Escape em/strong *
.replace(/\*{1,2}([^\W*]+\W*)+\*{1,2}/g, function (match) {
// Escape strong *
.replace(/[^\\]\*\*[^*\s.].+?[^\s]\*\*/g, function (match) {
return match.replace(/\*/g, '\\*')
})
// Escape em/strong _
.replace(/_{1,2}([^\W_]+\W*)+_{1,2}/g, function (match) {
// Escape em *
.replace(/[^\\]\*[^*\s.].+?[^\s]\*/g, function (match) {
return match.replace(/\*/g, '\\*')
})
// Escape strong _
.replace(/[^\\]__[^_\s.].+?[^\s]__/g, function (match) {
return match.replace(/_/g, '\\_')
})
// Escape em _
.replace(/[^\\]_[^_\s.].+?[^\s]_/g, function (match) {
return match.replace(/_/g, '\\_')
})
// Escape `
.replace(/`([^\W`]+\W*)+`/g, function (match) {
.replace(/[^\\]`[^`\s.].+?`/g, function (match) {
return match.replace(/`/g, '\\`')

@@ -869,10 +900,9 @@ })

replacementForNode: function replacementForNode (node) {
var converter = this.converterForNode(node);
var rule = this.ruleForNode(node);
var content = this.process(node);
var whitespace = node.flankingWhitespace;
if (whitespace.leading || whitespace.trailing) content = content.trim();
return (
whitespace.leading +
converter.replacement(content, node, this.options) +
rule.replacement(content, node, this.options) +
whitespace.trailing

@@ -883,24 +913,26 @@ )

/**
* Finds a converter for a given node
* Finds a rule for a given node
*/
converterForNode: function converterForNode (node) {
ruleForNode: function ruleForNode (node) {
if (this.filterValue(this.options.keepConverter, node)) {
return this.options.keepConverter
}
if (this.filterValue(this.options.removeConverter, node)) {
return this.options.removeConverter
}
if (node.isBlank) return this.options.blankConverter
for (var key in this.options.converters) {
var converter = this.options.converters[key];
if (this.filterValue(converter, node)) return converter
if (node.isBlank) return { replacement: this.options.blankReplacement }
for (var key in this.options.rules) {
var rule = this.options.rules[key];
if (this.filterValue(rule, node)) return rule
}
return this.options.defaultConverter
return { replacement: this.options.defaultReplacement }
},
filterValue: function filterValue (converter, node) {
var filter = converter.filter;
filterValue: function filterValue (rule, node) {
var filter = rule.filter;
if (typeof filter === 'string') {

@@ -911,3 +943,3 @@ if (filter === node.nodeName.toLowerCase()) return true

} else if (typeof filter === 'function') {
if (filter.call(converter, node, this.options)) return true
if (filter.call(rule, node, this.options)) return true
} else {

@@ -919,6 +951,6 @@ throw new TypeError('`filter` needs to be a string, array, or function')

postProcess: function postProcess (output) {
for (var key in this.options.converters) {
var converter = this.options.converters[key];
if (typeof converter.append === 'function') {
output = join(output, converter.append(this.options));
for (var key in this.options.rules) {
var rule = this.options.rules[key];
if (typeof rule.append === 'function') {
output = join(output, rule.append(this.options));
}

@@ -925,0 +957,0 @@ }

@@ -26,5 +26,5 @@ function extend (destination) {

var converters = {};
var rules = {};
converters.paragraph = {
rules.paragraph = {
filter: 'p',

@@ -37,3 +37,3 @@

converters.lineBreak = {
rules.lineBreak = {
filter: 'br',

@@ -46,3 +46,3 @@

converters.heading = {
rules.heading = {
filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],

@@ -64,3 +64,3 @@

converters.blockquote = {
rules.blockquote = {
filter: 'blockquote',

@@ -75,3 +75,3 @@

converters.list = {
rules.list = {
filter: ['ul', 'ol'],

@@ -89,3 +89,3 @@

converters.listItem = {
rules.listItem = {
filter: 'li',

@@ -111,3 +111,3 @@

converters.indentedCodeBlock = {
rules.indentedCodeBlock = {
filter: function (node, options) {

@@ -131,3 +131,3 @@ return (

converters.fencedCodeBlock = {
rules.fencedCodeBlock = {
filter: function (node, options) {

@@ -154,3 +154,3 @@ return (

converters.horizontalRule = {
rules.horizontalRule = {
filter: 'hr',

@@ -163,3 +163,3 @@

converters.inlineLink = {
rules.inlineLink = {
filter: function (node, options) {

@@ -180,3 +180,3 @@ return (

converters.referenceLink = {
rules.referenceLink = {
filter: function (node, options) {

@@ -227,3 +227,3 @@ return (

converters.emphasis = {
rules.emphasis = {
filter: ['em', 'i'],

@@ -236,3 +236,3 @@

converters.strong = {
rules.strong = {
filter: ['strong', 'b'],

@@ -245,3 +245,3 @@

converters.code = {
rules.code = {
filter: function (node) {

@@ -255,7 +255,8 @@ var hasSiblings = node.previousSibling || node.nextSibling;

replacement: function (content) {
return '`' + content + '`'
var delimiter = /`/.test(content) ? '``' : '`';
return delimiter + content + delimiter
}
};
converters.image = {
rules.image = {
filter: 'img',

@@ -733,4 +734,6 @@

function TurndownService (options) {
if (!(this instanceof TurndownService)) return new TurndownService(options)
var defaults = {
converters: converters,
rules: rules,
headingStyle: 'setext',

@@ -746,36 +749,36 @@ hr: '* * *',

br: ' ',
blankConverter: {
replacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
}
blankReplacement: function (content, node) {
return node.isBlock ? '\n\n' : ''
},
defaultConverter: {
replacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
defaultReplacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
},
keepConverter: {
filter: function (node) {
switch (node.nodeName) {
case 'TABLE':
return true
case 'PRE':
return node.firstChild && node.firstChild.nodeName !== 'CODE'
default:
return false
}
},
replacement: function (content, node) {
return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML
keep: function (node) {
switch (node.nodeName) {
case 'TABLE':
return true
case 'PRE':
return node.firstChild && node.firstChild.nodeName !== 'CODE'
default:
return false
}
},
removeConverter: {
filter: ['head', 'script'],
replacement: function () {
return ''
}
}
remove: ['head', 'link', 'meta', 'script', 'style']
};
optionsValidator.validate(options);
this.options = extend({}, defaults, options);
this.options.keepConverter = this.options.keepConverter || {
filter: this.options.keep,
replacement: function (content, node) {
return node.isBlock ? '\n\n' + content + '\n\n' : content
}
};
this.options.removeConverter = this.options.removeConverter || {
filter: this.options.remove,
replacement: function () {
return ''
}
};
}

@@ -797,2 +800,18 @@

use: function (plugin) {
if (Array.isArray(plugin)) {
for (var i = 0; i < plugin.length; i++) this.use(plugin[i]);
} else if (typeof plugin === 'function') {
plugin(this);
} else {
throw new TypeError('plugin must be a Function or an Array of Functions')
}
return this
},
addRule: function (key, rule) {
this.options.rules[key] = rule;
return this
},
/**

@@ -807,3 +826,3 @@ * Reduces a DOM node down to its Markdown string equivalent

var replacement;
var replacement = '';
if (node.nodeType === 3) {

@@ -835,3 +854,5 @@ replacement = _this.escape(node.nodeValue);

// Escape ul bullet points
.replace(/^([^\\\w]*)([*+-]) /gm, '$1\\$2 ')
.replace(/^([^\\\w]*)[*+-] /gm, function (match) {
return match.replace(/([*+-])/g, '\\$1')
})

@@ -841,14 +862,24 @@ // Escape blockquote indents

// Escape em/strong *
.replace(/\*{1,2}([^\W*]+\W*)+\*{1,2}/g, function (match) {
// Escape strong *
.replace(/[^\\]\*\*[^*\s.].+?[^\s]\*\*/g, function (match) {
return match.replace(/\*/g, '\\*')
})
// Escape em/strong _
.replace(/_{1,2}([^\W_]+\W*)+_{1,2}/g, function (match) {
// Escape em *
.replace(/[^\\]\*[^*\s.].+?[^\s]\*/g, function (match) {
return match.replace(/\*/g, '\\*')
})
// Escape strong _
.replace(/[^\\]__[^_\s.].+?[^\s]__/g, function (match) {
return match.replace(/_/g, '\\_')
})
// Escape em _
.replace(/[^\\]_[^_\s.].+?[^\s]_/g, function (match) {
return match.replace(/_/g, '\\_')
})
// Escape `
.replace(/`([^\W`]+\W*)+`/g, function (match) {
.replace(/[^\\]`[^`\s.].+?`/g, function (match) {
return match.replace(/`/g, '\\`')

@@ -867,10 +898,9 @@ })

replacementForNode: function replacementForNode (node) {
var converter = this.converterForNode(node);
var rule = this.ruleForNode(node);
var content = this.process(node);
var whitespace = node.flankingWhitespace;
if (whitespace.leading || whitespace.trailing) content = content.trim();
return (
whitespace.leading +
converter.replacement(content, node, this.options) +
rule.replacement(content, node, this.options) +
whitespace.trailing

@@ -881,24 +911,26 @@ )

/**
* Finds a converter for a given node
* Finds a rule for a given node
*/
converterForNode: function converterForNode (node) {
ruleForNode: function ruleForNode (node) {
if (this.filterValue(this.options.keepConverter, node)) {
return this.options.keepConverter
}
if (this.filterValue(this.options.removeConverter, node)) {
return this.options.removeConverter
}
if (node.isBlank) return this.options.blankConverter
for (var key in this.options.converters) {
var converter = this.options.converters[key];
if (this.filterValue(converter, node)) return converter
if (node.isBlank) return { replacement: this.options.blankReplacement }
for (var key in this.options.rules) {
var rule = this.options.rules[key];
if (this.filterValue(rule, node)) return rule
}
return this.options.defaultConverter
return { replacement: this.options.defaultReplacement }
},
filterValue: function filterValue (converter, node) {
var filter = converter.filter;
filterValue: function filterValue (rule, node) {
var filter = rule.filter;
if (typeof filter === 'string') {

@@ -909,3 +941,3 @@ if (filter === node.nodeName.toLowerCase()) return true

} else if (typeof filter === 'function') {
if (filter.call(converter, node, this.options)) return true
if (filter.call(rule, node, this.options)) return true
} else {

@@ -917,6 +949,6 @@ throw new TypeError('`filter` needs to be a string, array, or function')

postProcess: function postProcess (output) {
for (var key in this.options.converters) {
var converter = this.options.converters[key];
if (typeof converter.append === 'function') {
output = join(output, converter.append(this.options));
for (var key in this.options.rules) {
var rule = this.options.rules[key];
if (typeof rule.append === 'function') {
output = join(output, rule.append(this.options));
}

@@ -923,0 +955,0 @@ }

{
"name": "turndown",
"description": "A library that converts HTML to Markdown",
"version": "0.0.5",
"version": "0.0.6",
"author": "Dom Christie",

@@ -6,0 +6,0 @@ "browser": {

@@ -26,2 +26,5 @@ # Turndown

```js
// For Node.js
var TurndownService = require('turndown')
var turndownService = new TurndownService()

@@ -28,0 +31,0 @@ var markdown = turndownService.turndown('<h1>Hello world!</h1>')

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc