diff --git a/package.json b/package.json index e11b7ed..0551614 100755 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "node": ">=10.0.0" }, "dependencies": { - "node-html-parser": "^4.0.0" + "node-html-parser": "^4.1.0" }, "devDependencies": { "@types/jest": "^26.0.23", diff --git a/src/utilities.ts b/src/utilities.ts index 83c7607..00e85e9 100755 --- a/src/utilities.ts +++ b/src/utilities.ts @@ -183,7 +183,7 @@ export function parseHTML(html: string, options: NodeHtmlMarkdownOptions): Eleme } } else nodeHtmlParse = getNodeHtmlParser(); - if (!el) el = nodeHtmlParse!(html, nodeHtmlParserConfig).removeWhitespace(); + if (!el) el = nodeHtmlParse!(html, nodeHtmlParserConfig); perfStop('parse'); return el; diff --git a/src/visitor.ts b/src/visitor.ts index 5824488..db35ab2 100755 --- a/src/visitor.ts +++ b/src/visitor.ts @@ -137,8 +137,8 @@ export class Visitor { /* Handle text node */ if (isTextNode(node)) return node.isWhitespace - ? void 0 - : this.appendResult(metadata?.noEscape ? node.text : this.processText(node.text)); + ? (!result.text.length || result.trailingNewlineStats.whitespace > 0) ? void 0 : this.appendResult(' ') + : this.appendResult(metadata?.noEscape ? node.trimmedText : this.processText(node.trimmedText)); if (textOnly || !isElementNode(node)) return; diff --git a/test/default-tags.test.ts b/test/default-tags.test.ts index 347fc4d..ec09781 100755 --- a/test/default-tags.test.ts +++ b/test/default-tags.test.ts @@ -49,7 +49,7 @@ describe(`Default Tags`, () => { ab ${url} `); - expect(res).toBe(`[a b**c**](${url})a**b**<${url}>`); + expect(res).toBe(`[a b**c**](${url}) a**b** <${url}> `); }); test(`Image (img)`, () => { @@ -61,7 +61,7 @@ describe(`Default Tags`, () => { `); - expect(res).toBe(`![](${url}1)` + `![](${url}3 "t3")` + `![a4](${url}4 "t4")`); + expect(res).toBe(`![](${url}1)` + ` ![](${url}3 "t3")` + ` ![a4](${url}4 "t4") `); }); test(`Pre-formatted Text (pre)`, () => { diff --git a/test/options.test.ts b/test/options.test.ts index ff38144..a3cdea5 100644 --- a/test/options.test.ts +++ b/test/options.test.ts @@ -240,12 +240,12 @@ text`); instance.options.keepDataImages = true; const resKeep = translate(` `); - expect(resKeep).toBe(`![normal](normal_img.jpg)![](data:image/gif;base64,R0lGODlhEA)`); + expect(resKeep).toBe(`![normal](normal_img.jpg) ![](data:image/gif;base64,R0lGODlhEA)`); instance.options.keepDataImages = false; const resNoKeep = translate(` `); - expect(resNoKeep).toBe(`![normal](normal_img.jpg)`); + expect(resNoKeep).toBe(`![normal](normal_img.jpg) `); instance.options.keepDataImages = originalKeepDataImages; }); @@ -265,13 +265,13 @@ text`); instance.options.useLinkReferenceDefinitions = false; let res = translate(html); expect(res).toBe( - `Hello: [a b**c**](${url})a**b**[link2](${url}/other)[repeat link](${url})<${url}> Goodbye!` + `Hello: [a b**c**](${url}) a**b** [link2](${url}/other) [repeat link](${url}) <${url}> Goodbye!` ); instance.options.useLinkReferenceDefinitions = true; res = translate(html); expect(res).toBe( - `Hello: [a b**c**][1]a**b**[link2][2][repeat link][1]<${url}> Goodbye!\n\n[1]: ${url}\n[2]: ${url}/other` + `Hello: [a b**c**][1] a**b** [link2][2] [repeat link][1] <${url}> Goodbye!\n\n[1]: ${url}\n[2]: ${url}/other` ); instance.options.useLinkReferenceDefinitions = originalUseLinkReferenceDefinitions; diff --git a/test/special-cases.test.ts b/test/special-cases.test.ts index 9fa01c3..49a0f42 100755 --- a/test/special-cases.test.ts +++ b/test/special-cases.test.ts @@ -47,7 +47,7 @@ describe(`Special Cases`, () => { test.each(textFormatTags)(`%s`, tag => { const delim = delims[tag]; - expect(translate(`
<${tag}> Label: ${tag}>Value
`)).toBe(` ${delim}Label:${delim} Value`); + expect(translate(`<${tag}> Label: ${tag}>Value
`)).toBe(` ${delim}Label:${delim} Value`); expect(translate(`<${tag}> Label: ${tag}>Value
`)).toBe(` ${delim}Label:${delim} Value`); }); }); @@ -62,4 +62,10 @@ describe(`Special Cases`, () => { ); }); }); + + // See: https://github.com/crosstype/node-html-markdown/issues/16 + test(`Handles whitespace with single space`, () => { + const res = translate(`test test2 \ntest3\r\n\r\n\t\t\ttest4`); + expect(res).toBe(`test test2 test3 test4`); + }); }); diff --git a/yarn.lock b/yarn.lock index 748feec..882faa2 100755 --- a/yarn.lock +++ b/yarn.lock @@ -2963,10 +2963,10 @@ neo-async@^2.6.0: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-html-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-4.0.0.tgz#95e4fec010c48425821d5659eaf39e27b0781b6d" - integrity sha512-vuOcp3u4GrfYOcqe+FpUffQKnfVBq781MbtFEcTR6fJYnYRE2qUPdDaDk7TGdq6H9r2B3TbyU6K9Rah6/C7qvg== +node-html-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-4.1.0.tgz#9c23130609e203030113255c519ff2d3fbbfc439" + integrity sha512-sqSaqyrg1mqsRTl0r0h4UVAHBoW605rSpanOz0Yr7NzERl0fJ1eh6CRoZFcIXEIyzD3QJfGqsIMP+kzkViTiAA== dependencies: css-select "^4.1.3" he "1.2.0"