1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Desktop: Resolves #5440: Do not escape content when copying from Rich Text editor

This commit is contained in:
Laurent Cozic 2021-09-19 13:00:06 +01:00
parent 87f83236cf
commit e447acc076
4 changed files with 21 additions and 1 deletions

View File

@ -84,4 +84,10 @@ describe('HtmlToMd', function() {
} }
})); }));
it('should allow disabling escape', async () => {
const htmlToMd = new HtmlToMd();
expect(htmlToMd.parse('https://test.com/1_2_3.pdf', { disableEscapeContent: true })).toBe('https://test.com/1_2_3.pdf');
expect(htmlToMd.parse('https://test.com/1_2_3.pdf', { disableEscapeContent: false })).toBe('https://test.com/1\\_2\\_3.pdf');
});
}); });

View File

@ -69,8 +69,17 @@ export function htmlToClipboardData(html: string): ClipboardData {
// In that case we need to set both HTML and Text context, otherwise it // In that case we need to set both HTML and Text context, otherwise it
// won't be possible to paste the text in, for example, a text editor. // won't be possible to paste the text in, for example, a text editor.
// https://github.com/laurent22/joplin/issues/4788 // https://github.com/laurent22/joplin/issues/4788
//
// Also we don't escape the content produced in HTML to MD conversion
// because it's not what would be expected. For example, if the content is
// `* something`, strictly speaking it would be correct to escape to `\*
// something`, however this is not what the user would expect when copying
// text. Likewise for URLs that contain "_". So the resulting Markdown might
// not be perfectly valid but would be closer to what a user would expect.
// If they want accurate MArkdown they can switch to the MD editor.
// https://github.com/laurent22/joplin/issues/5440
return { return {
text: htmlToMd().parse(copyableContent), text: htmlToMd().parse(copyableContent, { disableEscapeContent: true }),
html: cleanUpCodeBlocks(copyableContent), html: cleanUpCodeBlocks(copyableContent),
}; };
} }

View File

@ -6,6 +6,7 @@ export interface ParseOptions {
anchorNames?: string[]; anchorNames?: string[];
preserveImageTagsWithSize?: boolean; preserveImageTagsWithSize?: boolean;
baseUrl?: string; baseUrl?: string;
disableEscapeContent?: boolean;
} }
export default class HtmlToMd { export default class HtmlToMd {
@ -20,6 +21,7 @@ export default class HtmlToMd {
emDelimiter: '*', emDelimiter: '*',
strongDelimiter: '**', strongDelimiter: '**',
br: '', br: '',
disableEscapeContent: 'disableEscapeContent' in options ? options.disableEscapeContent : false,
}); });
turndown.use(turndownPluginGfm); turndown.use(turndownPluginGfm);
turndown.remove('script'); turndown.remove('script');

View File

@ -23,6 +23,7 @@ export default function TurndownService (options) {
linkReferenceStyle: 'full', linkReferenceStyle: 'full',
anchorNames: [], anchorNames: [],
br: ' ', br: ' ',
disableEscapeContent: false,
blankReplacement: function (content, node) { blankReplacement: function (content, node) {
return node.isBlock ? '\n\n' : '' return node.isBlock ? '\n\n' : ''
}, },
@ -181,6 +182,8 @@ TurndownService.prototype = {
*/ */
function process (parentNode, escapeContent = 'auto') { function process (parentNode, escapeContent = 'auto') {
if (this.options.disableEscapeContent) escapeContent = false;
var self = this var self = this
return reduce.call(parentNode.childNodes, function (output, node) { return reduce.call(parentNode.childNodes, function (output, node) {
node = new Node(node) node = new Node(node)