From d52b43cab1240ee4f3a198b8372ad7f265ff77aa Mon Sep 17 00:00:00 2001 From: Aymeric Date: Wed, 18 Sep 2019 10:25:19 +0200 Subject: [PATCH] v1.1.0 - Added an option parameter to pass `window` and to overwrite the default styles (see issue https://github.com/Aymkdn/html-to-pdfmake/issues/14) - Added support for `` - Updated documentation --- README.md | 78 +++++++++++++++++++++++++- example.js | 2 +- example.pdf | Bin 35422 -> 35422 bytes index.js | 53 ++++++++++++++++-- package-lock.json | 140 ++++++++++++++++++++++++++++++++++++---------- package.json | 4 +- 6 files changed, 238 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index c91f9d8..bc15b12 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ var html = htmlToPdfMake(` and one with underline. And finally a link.

- `); +`); /* it will return: @@ -101,17 +101,45 @@ The below HTML tags are supported: - BR - B / STRONG - I / EM + - S - UL / OL / LI - TABLE / THEAD / TBODY / TFOOTER / TR / TH / TD - H1 to H6 - IMG -### Default style +### Default styles I've defined some default styles for the supported element. For example, using a <STRONG> will display the word in **bold**. Or, a link will appear in blue with an underline, and so on... +Here is the list of defaults styles: +```javascript +{ + b: {bold:true}, + strong: {bold:true}, + u: {decoration:'underline'}, + s: {decoration: 'lineThrough'}, + em: {italics:true}, + i: {italics:true}, + h1: {fontSize:24, bold:true, marginBottom:5}, + h2: {fontSize:22, bold:true, marginBottom:5}, + h3: {fontSize:20, bold:true, marginBottom:5}, + h4: {fontSize:18, bold:true, marginBottom:5}, + h5: {fontSize:16, bold:true, marginBottom:5}, + h6: {fontSize:14, bold:true, marginBottom:5}, + a: {color:'blue', decoration:'underline'}, + strike: {decoration: 'lineThrough'}, + p: {margin:[0, 5, 0, 10]}, + ul: {marginBottom:5}, + li: {marginLeft:5}, + table: {marginBottom:5}, + th: {bold:true, fillColor:'#EEEEEE'} + } +``` + +**Please, note that the above default styles are stronger than the ones defined in the style classes.** Read below how to overwrite them. + ### Customize style Each converted element will have an associated style-class called `html-tagname`. @@ -185,6 +213,48 @@ var docDefinition = { var pdfDocGenerator = pdfMake.createPdf(docDefinition); ``` +**Please, note that the default styles are stronger than the ones defined in the style classes.** For example, if you define a class `html-a` to change all links in *purple*, then it won't work because the default styles will overwrite it: + +```javascript +var docDefinition = { + content: [ + html + ], + styles:{ + 'html-a':{ + color:'purple' // it won't work: all links will remain 'blue' + } + } +}; + +``` + +To make it work, you have to either delete the default styles, or change it with a new value. Starting `v1.1.0`, an option parameter is available as a second parameter. + +Example: you want `
  • ` to not have a margin-left, and `` to be 'purple' and without 'underline' style: +```javascript +var html = htmlToPdfMake('', { + defaultStyles:{ // change the default styles + a:{ // for + color:'purple', // all links should be 'purple' + decoration:'' // remove underline + }, + li:'' // remove all default styles for
  • + } +}); + +var docDefinition = { + content: [ + html + ], + styles:{ + 'with-margin':{ + marginLeft: 30 // apply a margin with the specific class is used + } + } +}; +``` + ### `` The `` tag is supported, however the `src` attribute must already be a **base64 encoded content** (as describe in the [PDFMake documentation](https://pdfmake.github.io/docs/document-definition-object/images/)). @@ -198,3 +268,7 @@ You can find more examples in [example.js](example.js) which will create [exampl ```bash node example.js ``` + +## Donate + +You can support my work by [making a donation](https://www.paypal.me/aymkdn). Thank you! diff --git a/example.js b/example.js index 30071d7..2f402b0 100644 --- a/example.js +++ b/example.js @@ -150,7 +150,7 @@ var html = htmlToPdfMake(`

    Bold italic centered text

    text "bold" text "bold & italic" text "bold & italic & red" text "bold & italic" text "bold" -`, window); +`, {window:window}); var docDefinition = { content: [ diff --git a/example.pdf b/example.pdf index 0482b92a3d4ba83d164e87024ebb7df89c8b5ab0..e929969d0fb8382ab0d64f15186ae33bfadd5c37 100644 GIT binary patch delta 118 zcmcaNh3VcDrVVYz>=p**rY43Kn|qCm!r~2$O;XKFjg8ZijV(>hEDX$23@y!#jm%OE r5-n3r(-Q3zYzQie<+8KmDlSPZDyb++P2(~)F)=XXQdM>JcjE#85|$vv delta 118 zcmcaNh3VcDrVVYz>?Ve$h88BKn|qCm!s5-+jM9>fQjLrfEzJ{+jgrib%`DALQ%sW0 rEKJN(3@q#vYzQie<+8KmDlSPZDyb++P2(~)F)=XXQdM>JcjE#8L7pKf diff --git a/index.js b/index.js index 2955312..ee62839 100644 --- a/index.js +++ b/index.js @@ -10,23 +10,37 @@ /** * Transform HTML code to a PdfMake object * @param {String} htmlText The HTML code to transform - * @param {Object} [window] The `window` object (only used for the tests) + * @param {Object} [options] + * @param {Object} [defaultStyles] An object with the default styles for each elements + * @param {Object} [window] The `window` object (only used for the tests) * @return {Object} it returns a PdfMake object * * @example * // Some styles are applied by defaults for the supported HTML elements * // but you can pass your own styles if you prefer - * htmlToPdfMake('

    My Title

    My paragraph

    ') + * htmlToPdfMake('

    My Title

    My paragraph

    '); + * + * // If you want to overwrite the default styles, e.g. you want
  • to not have a margin-left, and links to be 'purple' and not 'blue', and links without 'underline' + * htmlToPdfMake('', { + * defaultStyles:{ + * a:{ + * color:'purple', + * decoration:null + * }, + * li:null + * } + * }); */ //var util = require("util"); // to debug -module.exports = function(htmlText, wndw) { - wndw = wndw || window; +module.exports = function(htmlText, options) { + var wndw = (options && options.window ? options.window : window); // set default styles var defaultStyles = { b: {bold:true}, strong: {bold:true}, u: {decoration:'underline'}, + s: {decoration: 'lineThrough'}, em: {italics:true}, i: {italics:true}, h1: {fontSize:24, bold:true, marginBottom:5}, @@ -46,6 +60,31 @@ module.exports = function(htmlText, wndw) { var inlineTags = [ 'p', 'li', 'span', 'strong', 'em', 'b', 'i', 'u' ]; + /** + * Permit to change the default styles based on the options + * @return {[type]} [description] + */ + function changeDefaultStyles () { + for (var keyStyle in options.defaultStyles) { + if (defaultStyles.hasOwnProperty(keyStyle)) { + // if we want to remove a default style + if (options.defaultStyles.hasOwnProperty(keyStyle) && !options.defaultStyles[keyStyle]) { + delete defaultStyles[keyStyle]; + } else { + for (var k in options.defaultStyles[keyStyle]) { + // if we want to delete a specific property + if (!options.defaultStyles[keyStyle][k]) delete defaultStyles[keyStyle][k]; + else defaultStyles[keyStyle][k] = options.defaultStyles[keyStyle][k]; + } + } + } + } + } + + if (options && options.defaultStyles) { + changeDefaultStyles(); + } + /** * Takes an HTML string, converts to HTML using a DOM parser and recursivly parses * the content into pdfmake compatible doc definition @@ -260,7 +299,6 @@ module.exports = function(htmlText, wndw) { if (isInlineTag) { applyDefaultStyle(ret, nodeName); } - ret.style = ['html-'+nodeName]; } } else if (ret.table || ret.ol || ret.ul) { // for TABLE / UL / OL @@ -280,6 +318,11 @@ module.exports = function(htmlText, wndw) { // apply all the classes not there yet ret.style = (ret.style || []) .concat(cssClass.split(' ')) + } + + // remove doublon in classes + if (typeof ret === 'object' && Array.isArray(ret.style)) { + ret.style = ret.style .filter(function (value, index, self) { return self.indexOf(value) === index; }); diff --git a/package-lock.json b/package-lock.json index 6cc69f6..d5d12d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,12 +36,6 @@ "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", "dev": true }, - "acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", - "dev": true - }, "acorn-globals": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.3.tgz", @@ -59,15 +53,28 @@ "dev": true }, "acorn-node": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.7.0.tgz", - "integrity": "sha512-XhahLSsCB6X6CJbe+uNu3Mn9sJBNFxtBN9NLgAOQovfS6Kh0lDUtmlclhjn9CvEK7A7YyRU13PXlNcpSiLI9Yw==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", "dev": true, "requires": { - "acorn": "^6.1.1", - "acorn-dynamic-import": "^4.0.0", - "acorn-walk": "^6.1.1", - "xtend": "^4.0.1" + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + }, + "dependencies": { + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "dev": true + }, + "acorn-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.0.0.tgz", + "integrity": "sha512-7Bv1We7ZGuU79zZbb6rRqcpxo3OY+zrdtloZWoyD8fmGX+FeXRjE+iuGkZjSXLVovLzrsvMGMy0EkwA0E0umxg==", + "dev": true + } } }, "acorn-walk": { @@ -552,10 +559,18 @@ } }, "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.0.tgz", + "integrity": "sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } }, "deep-is": { "version": "0.1.3", @@ -563,6 +578,15 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -619,9 +643,9 @@ "dev": true }, "es5-ext": { - "version": "0.10.50", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.50.tgz", - "integrity": "sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==", + "version": "0.10.51", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.51.tgz", + "integrity": "sha512-oRpWzM2WcLHVKpnrcyB7OW8j/s67Ba04JCm0WnNv3RiABSvs7mrQlutB8DBv793gKcp0XENR8Il8WxGTlZ73gQ==", "dev": true, "requires": { "es6-iterator": "~2.0.3", @@ -665,16 +689,28 @@ "es6-iterator": "~2.0.1", "es6-symbol": "3.1.1", "event-emitter": "~0.3.5" + }, + "dependencies": { + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + } } }, "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.2.tgz", + "integrity": "sha512-/ZypxQsArlv+KHpGvng52/Iz8by3EQPxhmbuz8yFG89N/caTFBSbcXONDw0aMjy827gQg26XAjP4uXFvnfINmQ==", "dev": true, "requires": { - "d": "1", - "es5-ext": "~0.10.14" + "d": "^1.0.1", + "es5-ext": "^0.10.51" } }, "escape-string-regexp": { @@ -1217,6 +1253,18 @@ } } }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -1229,6 +1277,15 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -1505,6 +1562,12 @@ "integrity": "sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw==", "dev": true }, + "object-is": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", + "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=", + "dev": true + }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -1685,14 +1748,15 @@ } }, "pdfmake": { - "version": "0.1.58", - "resolved": "https://registry.npmjs.org/pdfmake/-/pdfmake-0.1.58.tgz", - "integrity": "sha512-xLiLf47dBpONYQUP/dyy4TAVJtA79lEqd8vS02FBmKbbOcTzTRDongnJ095tf4q2b6UbT27VLgBRPA4vuiJK3w==", + "version": "0.1.59", + "resolved": "https://registry.npmjs.org/pdfmake/-/pdfmake-0.1.59.tgz", + "integrity": "sha512-OtxA3lmYtqPcFDLQUu5JmZX70rj9kivRqyL9eQygEs9gH5e/dotIlwzmIQsT8DrBG/W8W9szE0/zb/Riw6cDkg==", "dev": true, "requires": { "iconv-lite": "^0.5.0", "linebreak": "^1.0.2", - "pdfkit": "^0.10.0" + "pdfkit": "^0.10.0", + "svg-to-pdfkit": "^0.1.7" }, "dependencies": { "iconv-lite": { @@ -1808,6 +1872,15 @@ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", "dev": true }, + "regexp.prototype.flags": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", + "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2" + } + }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -2162,6 +2235,15 @@ "has-flag": "^3.0.0" } }, + "svg-to-pdfkit": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/svg-to-pdfkit/-/svg-to-pdfkit-0.1.7.tgz", + "integrity": "sha1-fbbUfkeziI3OGAYHUajeJBf4V3U=", + "dev": true, + "requires": { + "pdfkit": ">=0.8.1" + } + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index e8886aa..4ec5db1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "html-to-pdfmake", - "version": "1.0.7", + "version": "1.1.0", "description": "Convert HTML code to PDFMake", "main": "index.js", "scripts": { @@ -21,7 +21,7 @@ "devDependencies": { "eslint": "^5.16.0", "jsdom": "^14.1.0", - "pdfmake": "^0.1.58", + "pdfmake": "^0.1.59", "simple-test-framework": "^0.1.7" }, "dependencies": {}