html-to-text
Advanced tools
Comparing version 3.3.0 to 4.0.0
# Changelog | ||
## Version 4.0.0 | ||
* Support dropped for node version < 4. | ||
* New option `unorderedListItemPrefix` added. | ||
* HTML entities in links are not supported. | ||
## Version 3.3.0 | ||
@@ -4,0 +10,0 @@ |
@@ -5,3 +5,3 @@ var path = require('path'); | ||
console.log('fromString:') | ||
console.log('fromString:'); | ||
var text = htmlToText.fromString('<h1>Hello World</h1>', { | ||
@@ -8,0 +8,0 @@ wordwrap: 130 |
@@ -1,3 +0,8 @@ | ||
var _ = require('underscore'); | ||
var _s = require('underscore.string'); | ||
var max = require('lodash/max'); | ||
var compact = require('lodash/compact'); | ||
var times = require('lodash/times'); | ||
var trimStart = require('lodash/trimStart'); | ||
var padEnd = require('lodash/padEnd'); | ||
var he = require('he'); | ||
@@ -14,3 +19,3 @@ | ||
} else { | ||
return helper.wordwrap(elem.trimLeadingSpace ? _s.lstrip(text) : text, options); | ||
return helper.wordwrap(elem.trimLeadingSpace ? trimStart(text) : text, options); | ||
} | ||
@@ -42,7 +47,7 @@ } | ||
function formatParagraph(elem, fn, options) { | ||
var paragraph = fn(elem.children, options) | ||
var paragraph = fn(elem.children, options); | ||
if (options.singleNewLineParagraphs) { | ||
return paragraph + '\n' | ||
return paragraph + '\n'; | ||
} else { | ||
return paragraph + '\n\n' | ||
return paragraph + '\n\n'; | ||
} | ||
@@ -73,3 +78,3 @@ } | ||
var result = elem.trimLeadingSpace ? _s.lstrip(text) : text; | ||
var result = elem.trimLeadingSpace ? trimStart(text) : text; | ||
@@ -79,10 +84,10 @@ if (!options.ignoreHref) { | ||
if (elem.attribs && elem.attribs.href) { | ||
href = elem.attribs.href.replace(/^mailto\:/, ''); | ||
href = elem.attribs.href.replace(/^mailto:/, ''); | ||
} | ||
if (href) { | ||
if ((!options.noAnchorUrl) || (options.noAnchorUrl && href.indexOf('#') === -1)) { | ||
if ((!options.noAnchorUrl) || (options.noAnchorUrl && href[0] !== '#')) { | ||
if (options.linkHrefBaseUrl && href.indexOf('/') === 0) { | ||
href = options.linkHrefBaseUrl + href; | ||
} | ||
if (!options.hideLinkHrefIfSameAsText || href !== _s.replaceAll(result, '\n', '')) { | ||
if (!options.hideLinkHrefIfSameAsText || href !== helper.replaceAll(result, '\n', '')) { | ||
if (!options.noLinkBrackets) { | ||
@@ -104,7 +109,7 @@ result += ' [' + href + ']'; | ||
function formatHorizontalLine(elem, fn, options) { | ||
return '\n' + _s.repeat('-', options.wordwrap) + '\n\n'; | ||
return '\n' + '-'.repeat(options.wordwrap) + '\n\n'; | ||
} | ||
function formatListItem(prefix, elem, fn, options) { | ||
options = _.clone(options); | ||
options = Object.assign({}, options); | ||
// Reduce the wordwrap for sub elements. | ||
@@ -117,3 +122,3 @@ if (options.wordwrap) { | ||
// Replace all line breaks with line break + prefix spacing. | ||
text = text.replace(/\n/g, '\n' + _s.repeat(' ', prefix.length)); | ||
text = text.replace(/\n/g, '\n' + ' '.repeat(prefix.length)); | ||
// Add first prefix and line break at the end. | ||
@@ -127,7 +132,8 @@ return prefix + text + '\n'; | ||
var result = ''; | ||
var prefix = options.unorderedListItemPrefix; | ||
var nonWhiteSpaceChildren = (elem.children || []).filter(function(child) { | ||
return child.type !== 'text' || !whiteSpaceRegex.test(child.data); | ||
}); | ||
_.each(nonWhiteSpaceChildren, function(elem) { | ||
result += formatListItem(' * ', elem, fn, options); | ||
nonWhiteSpaceChildren.forEach(function(elem) { | ||
result += formatListItem(prefix, elem, fn, options); | ||
}); | ||
@@ -149,8 +155,8 @@ return result + '\n'; | ||
switch(olType) { | ||
case 'a': return function(start, i) { return String.fromCharCode(i + start + 97)}; | ||
case 'A': return function(start, i) { return String.fromCharCode(i + start + 65)}; | ||
case 'a': return function(start, i) { return String.fromCharCode(i + start + 97);}; | ||
case 'A': return function(start, i) { return String.fromCharCode(i + start + 65);}; | ||
case '1': | ||
default: return function(start, i) { return i + 1 + start}; | ||
default: return function(start, i) { return i + 1 + start;}; | ||
} | ||
}()) | ||
}()); | ||
// Make sure there are list items present | ||
@@ -162,3 +168,3 @@ if (nonWhiteSpaceChildren.length) { | ||
var maxLength = (nonWhiteSpaceChildren.length + start).toString().length; | ||
_.each(nonWhiteSpaceChildren, function(elem, i) { | ||
nonWhiteSpaceChildren.forEach(function(elem, i) { | ||
// Use different function depending on type | ||
@@ -168,3 +174,3 @@ var index = typeFunction(start, i); | ||
var spacing = maxLength - index.toString().length; | ||
var prefix = ' ' + index + '. ' + _s.repeat(' ', spacing); | ||
var prefix = ' ' + index + '. ' + ' '.repeat(spacing); | ||
result += formatListItem(prefix, elem, fn, options); | ||
@@ -179,4 +185,4 @@ }); | ||
// Convert all rows to lengths | ||
var widths = _.map(table, function(row) { | ||
return _.map(row, function(col) { | ||
var widths = table.map(function(row) { | ||
return row.map(function(col) { | ||
return col.length; | ||
@@ -188,4 +194,4 @@ }); | ||
// Determine the max values for each column | ||
widths = _.map(widths, function(col) { | ||
return _.max(col); | ||
widths = widths.map(function(col) { | ||
return max(col); | ||
}); | ||
@@ -195,6 +201,6 @@ | ||
var text = ''; | ||
_.each(table, function(row) { | ||
table.forEach(function(row) { | ||
var i = 0; | ||
_.each(row, function(col) { | ||
text += _s.rpad(_s.strip(col), widths[i++], ' ') + ' '; | ||
row.forEach(function(col) { | ||
text += padEnd(col.trim(), widths[i++], ' ') + ' '; | ||
}); | ||
@@ -208,3 +214,3 @@ text += '\n'; | ||
var table = []; | ||
_.each(elem.children, tryParseRows); | ||
elem.children.forEach(tryParseRows); | ||
return tableToString(table); | ||
@@ -221,3 +227,3 @@ | ||
case "center": | ||
_.each(elem.children, tryParseRows); | ||
elem.children.forEach(tryParseRows); | ||
return; | ||
@@ -227,4 +233,4 @@ | ||
var rows = []; | ||
_.each(elem.children, function(elem) { | ||
var tokens, times; | ||
elem.children.forEach(function(elem) { | ||
var tokens, count; | ||
if (elem.type === 'tag') { | ||
@@ -234,3 +240,3 @@ switch (elem.name.toLowerCase()) { | ||
tokens = formatHeading(elem, fn, options).split('\n'); | ||
rows.push(_.compact(tokens)); | ||
rows.push(compact(tokens)); | ||
break; | ||
@@ -240,7 +246,7 @@ | ||
tokens = fn(elem.children, options).split('\n'); | ||
rows.push(_.compact(tokens)); | ||
rows.push(compact(tokens)); | ||
// Fill colspans with empty values | ||
if (elem.attribs && elem.attribs.colspan) { | ||
times = elem.attribs.colspan - 1 || 0; | ||
_.times(times, function() { | ||
count = elem.attribs.colspan - 1 || 0; | ||
times(count, function() { | ||
rows.push(['']); | ||
@@ -254,4 +260,4 @@ }); | ||
rows = helper.arrayZip(rows); | ||
_.each(rows, function(row) { | ||
row = _.map(row, function(col) { | ||
rows.forEach(function(row) { | ||
row = row.map(function(col) { | ||
return col || ''; | ||
@@ -266,2 +272,6 @@ }); | ||
function formatBlockquote(elem, fn, options) { | ||
return '> ' + fn(elem.children, options) + '\n'; | ||
} | ||
exports.text = formatText; | ||
@@ -278,1 +288,2 @@ exports.image = formatImage; | ||
exports.horizontalLine = formatHorizontalLine; | ||
exports.blockquote = formatBlockquote; |
@@ -1,3 +0,3 @@ | ||
var _ = require('underscore'); | ||
var _s = require('underscore.string'); | ||
var zip = require('lodash/zip'); | ||
var trimEnd = require('lodash/trimEnd'); | ||
@@ -58,3 +58,3 @@ // Split a long word up to fit within the word wrap limit. Use either a | ||
// Preserve leading space | ||
var result = _s.startsWith(text, ' ') ? ' ' : ''; | ||
var result = text.startsWith(' ') ? ' ' : ''; | ||
length += result.length; | ||
@@ -65,6 +65,6 @@ var buffer = []; | ||
? text.replace(/\n/g, '\n ').split(/\ +/) | ||
: _s.words(text); | ||
: text.trim().split(/\s+/); | ||
// Determine where to end line word by word. | ||
_.each(words, function(word) { | ||
words.forEach(function(word) { | ||
// Add buffer to result if we can't fit any more words in the buffer. | ||
@@ -106,5 +106,5 @@ if ((max || max === 0) && length > 0 && ((length + word.length > max) || (length + word.indexOf('\n') > max))) { | ||
// Preserve trailing space | ||
if (!_s.endsWith(text, ' ')) { | ||
result = _s.rtrim(result); | ||
} else if (!_s.endsWith(result, ' ')) { | ||
if (!text.endsWith(' ')) { | ||
result = trimEnd(result); | ||
} else if (!result.endsWith(' ')) { | ||
result = result + ' '; | ||
@@ -117,3 +117,3 @@ } | ||
exports.arrayZip = function arrayZip(array) { | ||
return _.zip.apply(_, array); | ||
return zip.apply(null, array); | ||
}; | ||
@@ -138,1 +138,7 @@ | ||
}; | ||
exports.replaceAll = function replaceAll(str, find, replace) { | ||
var reg = new RegExp(find, 'g'); | ||
return str.replace(reg, replace); | ||
}; |
var fs = require('fs'); | ||
var util = require('util'); | ||
var _ = require('underscore'); | ||
var _s = require('underscore.string'); | ||
var includes = require('lodash/includes'); | ||
var trimEnd = require('lodash/trimEnd'); | ||
var htmlparser = require('htmlparser2'); | ||
@@ -18,4 +18,3 @@ | ||
function htmlToText(html, options) { | ||
options = options || {}; | ||
_.defaults(options, { | ||
options = Object.assign({ | ||
wordwrap: 80, | ||
@@ -40,4 +39,5 @@ tables: [], | ||
forceWrapOnLimit: false | ||
} | ||
}); | ||
}, | ||
unorderedListItemPrefix: ' * ' | ||
}, options || {}); | ||
@@ -58,3 +58,3 @@ var handler = new htmlparser.DefaultHandler(function (error, dom) { | ||
} | ||
return _s.strip(result); | ||
return trimEnd(result); | ||
} | ||
@@ -69,3 +69,3 @@ | ||
if (result) return; | ||
_.each(dom, function(elem) { | ||
dom.forEach(function(elem) { | ||
if (result) return; | ||
@@ -76,4 +76,4 @@ if (elem.name === splitTag.element) { | ||
if ((splitTag.classes.every(function (val) { return documentClasses.indexOf(val) >= 0 })) && | ||
(splitTag.ids.every(function (val) { return documentIds.indexOf(val) >= 0 }))) { | ||
if ((splitTag.classes.every(function (val) { return documentClasses.indexOf(val) >= 0; })) && | ||
(splitTag.ids.every(function (val) { return documentIds.indexOf(val) >= 0; }))) { | ||
result = [elem]; | ||
@@ -98,14 +98,13 @@ return; | ||
return function(key) { | ||
return _s.startsWith(key, prefix); | ||
return key.startsWith(prefix); | ||
}; | ||
} | ||
function filterByPrefix(tables, prefix) { | ||
return _(tables).chain() | ||
return tables | ||
.filter(checkPrefix(prefix)) | ||
.map(removePrefix) | ||
.value(); | ||
.map(removePrefix); | ||
} | ||
var classes = filterByPrefix(tables, '.'); | ||
var ids = filterByPrefix(tables, '#'); | ||
return attr && (_.include(classes, attr['class']) || _.include(ids, attr['id'])); | ||
return attr && (includes(classes, attr['class']) || includes(ids, attr['id'])); | ||
} | ||
@@ -118,5 +117,9 @@ | ||
var whiteSpaceRegex = /\s$/; | ||
var format = _.assign({}, defaultFormat, options.format); | ||
var format = Object.assign({}, defaultFormat, options.format); | ||
_.each(dom, function(elem) { | ||
if (!dom) { | ||
return result; | ||
} | ||
dom.forEach(function(elem) { | ||
switch(elem.type) { | ||
@@ -158,3 +161,3 @@ case 'tag': | ||
case 'pre': | ||
var newOptions = _(options).clone(); | ||
var newOptions = Object.assign({}, options); | ||
newOptions.isInPre = true; | ||
@@ -168,2 +171,5 @@ result += format.paragraph(elem, walk, newOptions); | ||
break; | ||
case 'blockquote': | ||
result += format.blockquote(elem, walk, options); | ||
break; | ||
default: | ||
@@ -182,3 +188,3 @@ result = walk(elem.children || [], options, result); | ||
default: | ||
if (!_.include(SKIP_TYPES, elem.type)) { | ||
if (!includes(SKIP_TYPES, elem.type)) { | ||
result = walk(elem.children || [], options, result); | ||
@@ -185,0 +191,0 @@ } |
{ | ||
"name": "html-to-text", | ||
"version": "3.3.0", | ||
"version": "4.0.0", | ||
"description": "Advanced html to plain text converter", | ||
@@ -9,3 +9,4 @@ "main": "index.js", | ||
"example": "node ./example/html-to-text.js", | ||
"lint": "eslint ." | ||
"lint": "eslint .", | ||
"prepublish": "npm test" | ||
}, | ||
@@ -28,5 +29,4 @@ "author": { | ||
"htmlparser2": "^3.9.2", | ||
"optimist": "^0.6.1", | ||
"underscore": "^1.8.3", | ||
"underscore.string": "^3.2.3" | ||
"lodash": "^4.17.4", | ||
"optimist": "^0.6.1" | ||
}, | ||
@@ -42,3 +42,3 @@ "keywords": [ | ||
"engines": { | ||
"node": ">= 0.10.0" | ||
"node": ">= 4.0.0" | ||
}, | ||
@@ -49,7 +49,7 @@ "bin": { | ||
"devDependencies": { | ||
"chai": "^3.5.0", | ||
"eslint": "^3.14.1", | ||
"chai": "^4.0.1", | ||
"eslint": "^4.18.2", | ||
"istanbul": "^0.4.5", | ||
"mocha": "^3.0.0" | ||
"mocha": "^5.0.2" | ||
} | ||
} |
273
README.md
@@ -36,6 +36,6 @@ # html-to-text | ||
htmlToText.fromFile(path.join(__dirname, 'test.html'), { | ||
tables: ['#invoice', '.address'] | ||
tables: ['#invoice', '.address'] | ||
}, (err, text) => { | ||
if (err) return console.error(err); | ||
console.log(text); | ||
if (err) return console.error(err); | ||
console.log(text); | ||
}); | ||
@@ -50,3 +50,3 @@ ``` | ||
var text = htmlToText.fromString('<h1>Hello World</h1>', { | ||
wordwrap: 130 | ||
wordwrap: 130 | ||
}); | ||
@@ -77,2 +77,3 @@ console.log(text); | ||
* `format` pass an object to enable custom formatting for specific elements (see below) | ||
* `unorderedListItemPrefix` defines the string that is used as item prefix for unordered lists `<ol>`. Default: `' * '` | ||
@@ -83,3 +84,3 @@ ### Override formatting for specific elements | ||
Each key must be a function which eventually receive `node` (the current node), `fn` (the next formatting function) and `options` (the options passed to html-to-text). | ||
Each key must be a function which eventually receive `elem` (the current elem), `fn` (the next formatting function) and `options` (the options passed to html-to-text). | ||
@@ -90,8 +91,8 @@ ```js | ||
var text = htmlToText.fromString('<h1>Hello World</h1>', { | ||
format: { | ||
heading: function (node, fn, options) { | ||
var h = fn(elem.children, options); | ||
return '====\n' + h.toUpperCase() + '\n===='; | ||
} | ||
} | ||
format: { | ||
heading: function (elem, fn, options) { | ||
var h = fn(elem.children, options); | ||
return '====\n' + h.toUpperCase() + '\n===='; | ||
} | ||
} | ||
}); | ||
@@ -124,129 +125,129 @@ | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
</head> | ||
<head> | ||
<meta charset="utf-8"> | ||
</head> | ||
<body> | ||
<table cellpadding="0" cellspacing="0" border="0"> | ||
<tr> | ||
<td> | ||
<h2>Paragraphs</h2> | ||
<p class="normal-space">At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. <a href="www.github.com">Github</a> | ||
</p> | ||
<p class="normal-space">At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. | ||
</p> | ||
</td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<hr/> | ||
<h2>Pretty printed table</h2> | ||
<table id="invoice"> | ||
<thead> | ||
<tr> | ||
<th>Article</th> | ||
<th>Price</th> | ||
<th>Taxes</th> | ||
<th>Amount</th> | ||
<th>Total</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td> | ||
<p> | ||
Product 1<br /> | ||
<span style="font-size:0.8em">Contains: 1x Product 1</span> | ||
</p> | ||
</td> | ||
<td align="right" valign="top">6,99€</td> | ||
<td align="right" valign="top">7%</td> | ||
<td align="right" valign="top">1</td> | ||
<td align="right" valign="top">6,99€</td> | ||
</tr> | ||
<tr> | ||
<td>Shipment costs</td> | ||
<td align="right">3,25€</td> | ||
<td align="right">7%</td> | ||
<td align="right">1</td> | ||
<td align="right">3,25€</td> | ||
</tr> | ||
</tbody> | ||
<tfoot> | ||
<tr> | ||
<td> </td> | ||
<td> </td> | ||
<td colspan="3">to pay: 10,24€</td> | ||
</tr> | ||
<tr> | ||
<td></td> | ||
<td></td> | ||
<td colspan="3">Taxes 7%: 0,72€</td> | ||
</tr> | ||
</tfoot> | ||
</table> | ||
<body> | ||
<table cellpadding="0" cellspacing="0" border="0"> | ||
<tr> | ||
<td> | ||
<h2>Paragraphs</h2> | ||
<p class="normal-space">At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. <a href="www.github.com">Github</a> | ||
</p> | ||
<p class="normal-space">At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. | ||
</p> | ||
</td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<hr/> | ||
<h2>Pretty printed table</h2> | ||
<table id="invoice"> | ||
<thead> | ||
<tr> | ||
<th>Article</th> | ||
<th>Price</th> | ||
<th>Taxes</th> | ||
<th>Amount</th> | ||
<th>Total</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td> | ||
<p> | ||
Product 1<br /> | ||
<span style="font-size:0.8em">Contains: 1x Product 1</span> | ||
</p> | ||
</td> | ||
<td align="right" valign="top">6,99€</td> | ||
<td align="right" valign="top">7%</td> | ||
<td align="right" valign="top">1</td> | ||
<td align="right" valign="top">6,99€</td> | ||
</tr> | ||
<tr> | ||
<td>Shipment costs</td> | ||
<td align="right">3,25€</td> | ||
<td align="right">7%</td> | ||
<td align="right">1</td> | ||
<td align="right">3,25€</td> | ||
</tr> | ||
</tbody> | ||
<tfoot> | ||
<tr> | ||
<td> </td> | ||
<td> </td> | ||
<td colspan="3">to pay: 10,24€</td> | ||
</tr> | ||
<tr> | ||
<td></td> | ||
<td></td> | ||
<td colspan="3">Taxes 7%: 0,72€</td> | ||
</tr> | ||
</tfoot> | ||
</table> | ||
</td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<hr/> | ||
<h2>Lists</h2> | ||
<ul> | ||
<li>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</li> | ||
<li>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</li> | ||
</ul> | ||
<ol> | ||
<li>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</li> | ||
<li>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</li> | ||
</ol> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<hr /> | ||
<h2>Column Layout with tables</h2> | ||
<table class="address"> | ||
<tr> | ||
<th align="left">Invoice Address</th> | ||
<th align="left">Shipment Address</th> | ||
</tr> | ||
<tr> | ||
<td align="left"> | ||
<p> | ||
Mr.<br/> | ||
John Doe<br/> | ||
Featherstone Street 49<br/> | ||
28199 Bremen<br/> | ||
</p> | ||
</td> | ||
<td align="left"> | ||
<p> | ||
Mr.<br/> | ||
John Doe<br/> | ||
Featherstone Street 49<br/> | ||
28199 Bremen<br/> | ||
</p> | ||
</td> | ||
</tr> | ||
</table> | ||
</td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<hr/> | ||
<h2>Mailto formating</h2> | ||
<p class="normal-space small"> | ||
Some Company<br /> | ||
Some Street 42<br /> | ||
Somewhere<br /> | ||
E-Mail: <a href="mailto:test@example.com">Click here</a> | ||
</p> | ||
</td> | ||
</tr> | ||
</table> | ||
</body> | ||
</td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<hr/> | ||
<h2>Lists</h2> | ||
<ul> | ||
<li>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</li> | ||
<li>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</li> | ||
</ul> | ||
<ol> | ||
<li>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</li> | ||
<li>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</li> | ||
</ol> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<hr /> | ||
<h2>Column Layout with tables</h2> | ||
<table class="address"> | ||
<tr> | ||
<th align="left">Invoice Address</th> | ||
<th align="left">Shipment Address</th> | ||
</tr> | ||
<tr> | ||
<td align="left"> | ||
<p> | ||
Mr.<br/> | ||
John Doe<br/> | ||
Featherstone Street 49<br/> | ||
28199 Bremen<br/> | ||
</p> | ||
</td> | ||
<td align="left"> | ||
<p> | ||
Mr.<br/> | ||
John Doe<br/> | ||
Featherstone Street 49<br/> | ||
28199 Bremen<br/> | ||
</p> | ||
</td> | ||
</tr> | ||
</table> | ||
</td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<hr/> | ||
<h2>Mailto formating</h2> | ||
<p class="normal-space small"> | ||
Some Company<br /> | ||
Some Street 42<br /> | ||
Somewhere<br /> | ||
E-Mail: <a href="mailto:test@example.com">Click here</a> | ||
</p> | ||
</td> | ||
</tr> | ||
</table> | ||
</body> | ||
</html> | ||
@@ -253,0 +254,0 @@ ``` |
@@ -198,2 +198,12 @@ /* eslint max-len: "off" */ | ||
describe('a', function () { | ||
it('should decode html attribute entities from href', function () { | ||
var result = htmlToText.fromString('<a href="/foo?a=b">test</a>'); | ||
expect(result).to.equal('test [/foo?a=b]'); | ||
}); | ||
it('should strip mailto: from email links', function () { | ||
var result = htmlToText.fromString('<a href="mailto:foo@example.com">email me</a>'); | ||
expect(result).to.equal('email me [foo@example.com]'); | ||
}); | ||
it('should return link with brackets', function () { | ||
@@ -235,4 +245,10 @@ var result = htmlToText.fromString('<a href="http://my.link">test</a>'); | ||
var testString = '<ul><li>foo</li><li>bar</li></ul>'; | ||
expect(htmlToText.fromString(testString)).to.equal('* foo\n * bar'); | ||
expect(htmlToText.fromString(testString)).to.equal(' * foo\n * bar'); | ||
}); | ||
it('should handle an unordered list prefix option', function() { | ||
var testString = '<ul><li>foo</li><li>bar</li></ul>'; | ||
var options = {unorderedListItemPrefix: ' test '}; | ||
expect(htmlToText.fromString(testString, options)).to.equal(' test foo\n test bar'); | ||
}); | ||
}); | ||
@@ -248,3 +264,3 @@ | ||
var testString = '<ol><li>foo</li><li>bar</li></ol>'; | ||
expect(htmlToText.fromString(testString)).to.equal('1. foo\n 2. bar'); | ||
expect(htmlToText.fromString(testString)).to.equal(' 1. foo\n 2. bar'); | ||
}); | ||
@@ -254,3 +270,3 @@ | ||
var testString = '<ol type="1"><li>foo</li><li>bar</li></ol>'; | ||
expect(htmlToText.fromString(testString)).to.equal('1. foo\n 2. bar'); | ||
expect(htmlToText.fromString(testString)).to.equal(' 1. foo\n 2. bar'); | ||
}); | ||
@@ -260,3 +276,3 @@ | ||
var testString = '<ol type="1"><li>foo</li><li>bar</li></ol>'; | ||
expect(htmlToText.fromString(testString)).to.equal('1. foo\n 2. bar'); | ||
expect(htmlToText.fromString(testString)).to.equal(' 1. foo\n 2. bar'); | ||
}); | ||
@@ -266,3 +282,3 @@ | ||
var testString = '<ol type="a"><li>foo</li><li>bar</li></ol>'; | ||
expect(htmlToText.fromString(testString)).to.equal('a. foo\n b. bar'); | ||
expect(htmlToText.fromString(testString)).to.equal(' a. foo\n b. bar'); | ||
}); | ||
@@ -272,3 +288,3 @@ | ||
var testString = '<ol type="A"><li>foo</li><li>bar</li></ol>'; | ||
expect(htmlToText.fromString(testString)).to.equal('A. foo\n B. bar'); | ||
expect(htmlToText.fromString(testString)).to.equal(' A. foo\n B. bar'); | ||
}); | ||
@@ -280,3 +296,3 @@ | ||
// expect(htmlToText.fromString(testString)).to.equal('i. foo\nii. bar'); | ||
expect(htmlToText.fromString(testString)).to.equal('1. foo\n 2. bar'); | ||
expect(htmlToText.fromString(testString)).to.equal(' 1. foo\n 2. bar'); | ||
}); | ||
@@ -288,3 +304,3 @@ | ||
// expect(htmlToText.fromString(testString)).to.equal('I. foo\nII. bar'); | ||
expect(htmlToText.fromString(testString)).to.equal('1. foo\n 2. bar'); | ||
expect(htmlToText.fromString(testString)).to.equal(' 1. foo\n 2. bar'); | ||
}); | ||
@@ -294,3 +310,3 @@ | ||
var testString = '<ol start="2"><li>foo</li><li>bar</li></ol>'; | ||
expect(htmlToText.fromString(testString)).to.equal('2. foo\n 3. bar'); | ||
expect(htmlToText.fromString(testString)).to.equal(' 2. foo\n 3. bar'); | ||
}); | ||
@@ -373,3 +389,3 @@ | ||
expect(result).to.equal('====\ntest\n===='); | ||
}) | ||
}); | ||
}); | ||
@@ -609,3 +625,11 @@ | ||
}); | ||
}) | ||
}); | ||
describe('blockquote', function() { | ||
it('should handle format blockquote', function() { | ||
var testString = 'foo<blockquote>test</blockquote>bar'; | ||
var expectedResult = 'foo> test\nbar'; | ||
expect(htmlToText.fromString(testString)).to.equal(expectedResult); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
86922
4
1115
333
22
+ Addedlodash@^4.17.4
+ Addedlodash@4.17.21(transitive)
- Removedunderscore@^1.8.3
- Removedunderscore.string@^3.2.3
- Removedsprintf-js@1.1.3(transitive)
- Removedunderscore@1.13.7(transitive)
- Removedunderscore.string@3.3.6(transitive)