From 234c05a966d09a6d0eeb6adee5cf2b9f590d95a3 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Wed, 9 Dec 2020 14:58:38 +0000 Subject: [PATCH] Desktop: Rich Text: Do not converts to markdown links URLs that would be linkified --- .eslintignore | 3 ++ .gitignore | 3 ++ .../tests/{HtmlToMd.js => HtmlToMd.ts} | 30 +++++++------------ .../html_to_md/anchor_same_title_and_url.html | 8 +++++ .../html_to_md/anchor_same_title_and_url.md | 6 ++++ packages/turndown/src/commonmark-rules.js | 26 +++++++++++++++- 6 files changed, 55 insertions(+), 21 deletions(-) rename packages/app-cli/tests/{HtmlToMd.js => HtmlToMd.ts} (73%) create mode 100644 packages/app-cli/tests/html_to_md/anchor_same_title_and_url.html create mode 100644 packages/app-cli/tests/html_to_md/anchor_same_title_and_url.md diff --git a/.eslintignore b/.eslintignore index 7696f7902..bf77bff48 100644 --- a/.eslintignore +++ b/.eslintignore @@ -70,6 +70,9 @@ packages/app-cli/app/services/plugins/PluginRunner.js.map packages/app-cli/tests/EnexToMd.d.ts packages/app-cli/tests/EnexToMd.js packages/app-cli/tests/EnexToMd.js.map +packages/app-cli/tests/HtmlToMd.d.ts +packages/app-cli/tests/HtmlToMd.js +packages/app-cli/tests/HtmlToMd.js.map packages/app-cli/tests/InMemoryCache.d.ts packages/app-cli/tests/InMemoryCache.js packages/app-cli/tests/InMemoryCache.js.map diff --git a/.gitignore b/.gitignore index 4dbae5ea0..fe1134146 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,9 @@ packages/app-cli/app/services/plugins/PluginRunner.js.map packages/app-cli/tests/EnexToMd.d.ts packages/app-cli/tests/EnexToMd.js packages/app-cli/tests/EnexToMd.js.map +packages/app-cli/tests/HtmlToMd.d.ts +packages/app-cli/tests/HtmlToMd.js +packages/app-cli/tests/HtmlToMd.js.map packages/app-cli/tests/InMemoryCache.d.ts packages/app-cli/tests/InMemoryCache.js packages/app-cli/tests/InMemoryCache.js.map diff --git a/packages/app-cli/tests/HtmlToMd.js b/packages/app-cli/tests/HtmlToMd.ts similarity index 73% rename from packages/app-cli/tests/HtmlToMd.js rename to packages/app-cli/tests/HtmlToMd.ts index a166393c7..d0287a11c 100644 --- a/packages/app-cli/tests/HtmlToMd.js +++ b/packages/app-cli/tests/HtmlToMd.ts @@ -1,24 +1,15 @@ -/* eslint-disable no-unused-vars */ - - +import shim from '@joplin/lib/shim'; const os = require('os'); -const time = require('@joplin/lib/time').default; const { filename } = require('@joplin/lib/path-utils'); -const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('./test-utils.js'); -const Folder = require('@joplin/lib/models/Folder.js'); -const Note = require('@joplin/lib/models/Note.js'); -const BaseModel = require('@joplin/lib/BaseModel').default; -const shim = require('@joplin/lib/shim').default; const HtmlToMd = require('@joplin/lib/HtmlToMd'); -const { enexXmlToMd } = require('@joplin/lib/import-enex-md-gen.js'); describe('HtmlToMd', function() { - beforeEach(async (done) => { - await setupDatabaseAndSynchronizer(1); - await switchClient(1); - done(); - }); + // beforeEach(async (done) => { + // await setupDatabaseAndSynchronizer(1); + // await switchClient(1); + // done(); + // }); it('should convert from Html to Markdown', (async () => { const basePath = `${__dirname}/html_to_md`; @@ -32,11 +23,11 @@ describe('HtmlToMd', function() { const htmlPath = `${basePath}/${htmlFilename}`; const mdPath = `${basePath}/${filename(htmlFilename)}.md`; - // if (htmlFilename !== 'code_3.html') continue; + // if (htmlFilename !== 'anchor_same_title_and_url.html') continue; // if (htmlFilename.indexOf('image_preserve_size') !== 0) continue; - const htmlToMdOptions = {}; + const htmlToMdOptions: any = {}; if (htmlFilename === 'anchor_local.html') { // Normally the list of anchor names in the document are retrieved from the HTML code @@ -66,15 +57,14 @@ describe('HtmlToMd', function() { result.push(''); result.push(`Error converting file: ${htmlFilename}`); result.push('--------------------------------- Got:'); - result.push(actualMd.split('\n').map(l => `"${l}"`).join('\n')); + result.push(actualMd.split('\n').map((l: string) => `"${l}"`).join('\n')); result.push('--------------------------------- Expected:'); - result.push(expectedMd.split('\n').map(l => `"${l}"`).join('\n')); + result.push(expectedMd.split('\n').map((l: string) => `"${l}"`).join('\n')); result.push('--------------------------------------------'); result.push(''); console.info(result.join('\n')); - // console.info(''); // console.info(`Error converting file: ${htmlFilename}`); // console.info('--------------------------------- Got:'); diff --git a/packages/app-cli/tests/html_to_md/anchor_same_title_and_url.html b/packages/app-cli/tests/html_to_md/anchor_same_title_and_url.html new file mode 100644 index 000000000..a25f22dd3 --- /dev/null +++ b/packages/app-cli/tests/html_to_md/anchor_same_title_and_url.html @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/packages/app-cli/tests/html_to_md/anchor_same_title_and_url.md b/packages/app-cli/tests/html_to_md/anchor_same_title_and_url.md new file mode 100644 index 000000000..b6eb47ddc --- /dev/null +++ b/packages/app-cli/tests/html_to_md/anchor_same_title_and_url.md @@ -0,0 +1,6 @@ +- https://example.com +- http://example.com +- file:///mnt/c/test.txt +- [https://example.com](https://example.com "with title") +- [example.com](example.com) +- [test@example.com](test@example.com) \ No newline at end of file diff --git a/packages/turndown/src/commonmark-rules.js b/packages/turndown/src/commonmark-rules.js index da92fc8a8..74a7e5047 100644 --- a/packages/turndown/src/commonmark-rules.js +++ b/packages/turndown/src/commonmark-rules.js @@ -216,6 +216,10 @@ function getNamedAnchorFromLink(node, options) { } } +function isLinkifiedUrl(url) { + return url.indexOf('http://') === 0 || url.indexOf('https://') === 0 || url.indexOf('file://') === 0; +} + rules.inlineLink = { filter: function (node, options) { return ( @@ -227,12 +231,32 @@ rules.inlineLink = { replacement: function (content, node, options) { var href = filterLinkHref(node.getAttribute('href')) + if (!href) { return getNamedAnchorFromLink(node, options) + filterLinkContent(content) } else { var title = node.title && node.title !== href ? ' "' + node.title + '"' : '' if (!href) title = '' - return getNamedAnchorFromLink(node, options) + '[' + filterLinkContent(content) + '](' + href + title + ')' + let output = getNamedAnchorFromLink(node, options) + '[' + filterLinkContent(content) + '](' + href + title + ')' + + // If the URL is automatically linkified by Joplin, and the title is + // the same as the URL, there is no need to make it a link here. That + // will prevent URsL from the rich text editor to be needlessly + // converted from this: + // + // https://example.com + // + // to this: + // + // [https://example.com](https://example.com) + // + // It means cleaner Markdown will also be generated by the web + // clipper. + if (isLinkifiedUrl(href)) { + if (output === '[' + href + '](' + href + ')') return href; + } + + return output; } } }