Skip to content

Commit feca08c

Browse files
authored
Merge pull request #54 from sorcio/fix-nested-html
Improve parsing of HTML anchor content
2 parents eac0cd5 + fd12c0f commit feca08c

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

src/paste-markdown-html.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ function onPaste(event: ClipboardEvent) {
3333
// Generate DOM tree from HTML string
3434
const parser = new DOMParser()
3535
const doc = parser.parseFromString(textHTMLClean, 'text/html')
36-
const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ELEMENT)
36+
const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ELEMENT, node =>
37+
node.parentNode && isLink(node.parentNode) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT
38+
)
3739

3840
const markdown = convertToMarkdown(plaintext, walker)
3941

@@ -56,7 +58,9 @@ function convertToMarkdown(plaintext: string, walker: TreeWalker): string {
5658
// Walk through the DOM tree
5759
while (currentNode && index < NODE_LIMIT) {
5860
index++
59-
const text = isLink(currentNode) ? currentNode.textContent || '' : (currentNode.firstChild as Text)?.wholeText || ''
61+
const text = isLink(currentNode)
62+
? (currentNode.textContent || '').replace(/[\t\n\r ]+/g, ' ')
63+
: (currentNode.firstChild as Text)?.wholeText || ''
6064

6165
// No need to transform whitespace
6266
if (isEmptyString(text)) {
@@ -69,7 +73,7 @@ function convertToMarkdown(plaintext: string, walker: TreeWalker): string {
6973

7074
if (markdownFoundIndex >= 0) {
7175
if (isLink(currentNode)) {
72-
const markdownLink = linkify(currentNode)
76+
const markdownLink = linkify(currentNode, text)
7377
// Transform 'example link plus more text' into 'example [link](example link) plus more text'
7478
// Method: 'example [link](example link) plus more text' = 'example ' + '[link](example link)' + ' plus more text'
7579
markdown =
@@ -100,8 +104,7 @@ function hasHTML(transfer: DataTransfer): boolean {
100104
}
101105

102106
// Makes markdown link from a link element, avoiding special GitHub links
103-
function linkify(element: HTMLAnchorElement): string {
104-
const label = element.textContent || ''
107+
function linkify(element: HTMLAnchorElement, label: string): string {
105108
const url = element.href || ''
106109
let markdown = ''
107110

test/test.js

+22
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,28 @@ describe('paste-markdown', function () {
146146
assert.equal(textarea.value, markdownSentence)
147147
})
148148

149+
it('deals with links with nested html', function () {
150+
// eslint-disable-next-line github/unescaped-html-literal
151+
const sentence = `<a href="https://example.com/"><span>foo</span></a>
152+
<a href="https://example.com/">bar</a>
153+
foo bar`
154+
const plaintextSentence = 'foo bar foo bar'
155+
const markdownSentence = '[foo](https://example.com/) [bar](https://example.com/) foo bar'
156+
157+
paste(textarea, {'text/html': sentence, 'text/plain': plaintextSentence})
158+
assert.equal(textarea.value, markdownSentence)
159+
})
160+
161+
it('deals with link labels that contains line breaks in html', function () {
162+
// eslint-disable-next-line github/unescaped-html-literal
163+
const sentence = '<a href="https://example.com/">foo\nbar</a>'
164+
const plaintextSentence = 'foo bar'
165+
const markdownSentence = '[foo bar](https://example.com/)'
166+
167+
paste(textarea, {'text/html': sentence, 'text/plain': plaintextSentence})
168+
assert.equal(textarea.value, markdownSentence)
169+
})
170+
149171
it("doesn't render any markdown for html link without corresponding plaintext", function () {
150172
// eslint-disable-next-line github/unescaped-html-literal
151173
const link = `<meta charset='utf-8'><a href="https://github.com/monalisa/playground/issues/1">

0 commit comments

Comments
 (0)