mirror of https://github.com/zulip/zulip.git
turndown: Paste single line of code as inline code in markdown.
When pasting any code without any newlines, whether from a code block or a code span, it will always be pasted as inline code. That is, a line of code copied from within a code span will retain code span formatting on paste, and a line of code copied from within a code block will be pasted as inline code, instead of a 1 line code block.
This commit is contained in:
parent
446ba4d6df
commit
79ec61b373
|
@ -319,7 +319,7 @@ export function paste_handler_converter(paste_html) {
|
||||||
copied_html_fragment.childNodes.length === 1 &&
|
copied_html_fragment.childNodes.length === 1 &&
|
||||||
copied_html_fragment.firstElementChild &&
|
copied_html_fragment.firstElementChild &&
|
||||||
copied_html_fragment.firstElementChild.innerHTML;
|
copied_html_fragment.firstElementChild.innerHTML;
|
||||||
const outer_elements_to_retain = ["PRE", "UL", "OL", "A"];
|
const outer_elements_to_retain = ["PRE", "UL", "OL", "A", "CODE"];
|
||||||
// If the entire selection copied is within a single HTML element (like an
|
// If the entire selection copied is within a single HTML element (like an
|
||||||
// `h1`), we don't want to retain its styling, except when it is needed to
|
// `h1`), we don't want to retain its styling, except when it is needed to
|
||||||
// identify the intended structure of the copied content.
|
// identify the intended structure of the copied content.
|
||||||
|
@ -481,6 +481,62 @@ export function paste_handler_converter(paste_html) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// We override the original upstream implementation of this rule to turn any
|
||||||
|
// single line code blocks into inline markdown code. Everything else is the same.
|
||||||
|
turndownService.addRule("fencedCodeBlock", {
|
||||||
|
filter(node, options) {
|
||||||
|
return (
|
||||||
|
options.codeBlockStyle === "fenced" &&
|
||||||
|
node.nodeName === "PRE" &&
|
||||||
|
node.firstChild &&
|
||||||
|
node.firstChild.nodeName === "CODE"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
replacement(_content, node, options) {
|
||||||
|
const code = node.firstChild.textContent;
|
||||||
|
|
||||||
|
// We convert single line code inside a code block to inline markdown code,
|
||||||
|
// and the code for this is taken from upstream's `code` rule.
|
||||||
|
if (!code.includes("\n")) {
|
||||||
|
if (!code) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const extraSpace = /^`|^ .*?[^ ].* $|`$/.test(code) ? " " : "";
|
||||||
|
|
||||||
|
// Pick the shortest sequence of backticks that is not found in the code
|
||||||
|
// to be the delimiter.
|
||||||
|
let delimiter = "`";
|
||||||
|
const matches = code.match(/`+/gm) || [];
|
||||||
|
while (matches.includes(delimiter)) {
|
||||||
|
delimiter = delimiter + "`";
|
||||||
|
}
|
||||||
|
|
||||||
|
return delimiter + extraSpace + code + extraSpace + delimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
const className = node.firstChild.getAttribute("class") || "";
|
||||||
|
const language = (className.match(/language-(\S+)/) || [null, ""])[1];
|
||||||
|
|
||||||
|
const fenceChar = options.fence.charAt(0);
|
||||||
|
let fenceSize = 3;
|
||||||
|
const fenceInCodeRegex = new RegExp("^" + fenceChar + "{3,}", "gm");
|
||||||
|
|
||||||
|
let match;
|
||||||
|
while ((match = fenceInCodeRegex.exec(code))) {
|
||||||
|
if (match[0].length >= fenceSize) {
|
||||||
|
fenceSize = match[0].length + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fence = fenceChar.repeat(fenceSize);
|
||||||
|
|
||||||
|
return (
|
||||||
|
"\n\n" + fence + language + "\n" + code.replace(/\n$/, "") + "\n" + fence + "\n\n"
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
let markdown_text = turndownService.turndown(paste_html);
|
let markdown_text = turndownService.turndown(paste_html);
|
||||||
|
|
||||||
// Checks for escaped ordered list syntax.
|
// Checks for escaped ordered list syntax.
|
||||||
|
|
|
@ -35,6 +35,11 @@ run_test("paste_handler_converter", () => {
|
||||||
'zulip code block in python\n\n```Python\nprint("hello world")\n```',
|
'zulip code block in python\n\n```Python\nprint("hello world")\n```',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Single line in a code block
|
||||||
|
input =
|
||||||
|
'<meta http-equiv="content-type" content="text/html; charset=utf-8"><pre><code>single line</code></pre>';
|
||||||
|
assert.equal(copy_and_paste.paste_handler_converter(input), "`single line`");
|
||||||
|
|
||||||
// Raw links without custom text
|
// Raw links without custom text
|
||||||
input =
|
input =
|
||||||
'<meta http-equiv="content-type" content="text/html; charset=utf-8"><a href="https://zulip.readthedocs.io/en/latest/subsystems/logging.html" target="_blank" title="https://zulip.readthedocs.io/en/latest/subsystems/logging.html" style="color: hsl(200, 100%, 40%); text-decoration: none; cursor: pointer; font-family: "Source Sans 3", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: hsl(0, 0%, 100%);">https://zulip.readthedocs.io/en/latest/subsystems/logging.html</a>';
|
'<meta http-equiv="content-type" content="text/html; charset=utf-8"><a href="https://zulip.readthedocs.io/en/latest/subsystems/logging.html" target="_blank" title="https://zulip.readthedocs.io/en/latest/subsystems/logging.html" style="color: hsl(200, 100%, 40%); text-decoration: none; cursor: pointer; font-family: "Source Sans 3", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: hsl(0, 0%, 100%);">https://zulip.readthedocs.io/en/latest/subsystems/logging.html</a>';
|
||||||
|
|
Loading…
Reference in New Issue