mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Desktop: Fixes #8978: Rich text editor: Fix repeated newline characters discarded on save to markdown (#9199)
This commit is contained in:
parent
a38fe11bbe
commit
6593025051
@ -15,7 +15,4 @@ however.
|
||||
Because it isn't
|
||||
|
||||
necessary.
|
||||
|
||||
|
||||
|
||||
...
|
||||
<br/><br/><br/>...
|
4
packages/app-cli/tests/html_to_md/repeated_brs.html
Normal file
4
packages/app-cli/tests/html_to_md/repeated_brs.html
Normal file
@ -0,0 +1,4 @@
|
||||
A<br/><br/><br/>test.<br/>
|
||||
|
||||
A single <br/><br/>can use two spaces at the end of the line,
|
||||
but<br/><br/>the markdown renderer discards these if the line is otherwise empty.
|
5
packages/app-cli/tests/html_to_md/repeated_brs.md
Normal file
5
packages/app-cli/tests/html_to_md/repeated_brs.md
Normal file
@ -0,0 +1,5 @@
|
||||
A
|
||||
<br/><br/>test.
|
||||
A single <br/>
|
||||
can use two spaces at the end of the line, but
|
||||
<br/>the markdown renderer discards these if the line is otherwise empty.
|
@ -45,11 +45,18 @@ rules.paragraph = {
|
||||
rules.lineBreak = {
|
||||
filter: 'br',
|
||||
|
||||
replacement: function (content, node, options) {
|
||||
replacement: function (_content, node, options, previousNode) {
|
||||
let brReplacement = options.br + '\n';
|
||||
|
||||
// Code blocks may include <br/>s -- replacing them should not be necessary
|
||||
// in code blocks.
|
||||
const brReplacement = node.isCode ? '' : options.br;
|
||||
return brReplacement + '\n'
|
||||
if (node.isCode) {
|
||||
brReplacement = '\n';
|
||||
} else if (previousNode && previousNode.nodeName === 'BR') {
|
||||
brReplacement = '<br/>';
|
||||
}
|
||||
|
||||
return brReplacement;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,27 +165,32 @@ TurndownService.prototype = {
|
||||
function process (parentNode, escapeContent = 'auto') {
|
||||
if (this.options.disableEscapeContent) escapeContent = false;
|
||||
|
||||
var self = this
|
||||
return reduce.call(parentNode.childNodes, function (output, node) {
|
||||
node = new Node(node, self.options)
|
||||
let output = '';
|
||||
let previousNode = null;
|
||||
|
||||
for (let node of parentNode.childNodes) {
|
||||
node = new Node(node, this.options);
|
||||
|
||||
var replacement = ''
|
||||
if (node.nodeType === 3) {
|
||||
if (node.isCode || escapeContent === false) {
|
||||
replacement = node.nodeValue
|
||||
} else {
|
||||
replacement = self.escape(node.nodeValue)
|
||||
replacement = this.escape(node.nodeValue);
|
||||
|
||||
// Escape < and > so that, for example, this kind of HTML text: "This is a tag: <p>" is still rendered as "This is a tag: <p>"
|
||||
// and not "This is a tag: <p>". If the latter, it means the HTML will be rendered if the viewer supports HTML (which, in Joplin, it does).
|
||||
replacement = replacement.replace(/<(.+?)>/g, '<$1>');
|
||||
}
|
||||
} else if (node.nodeType === 1) {
|
||||
replacement = replacementForNode.call(self, node)
|
||||
replacement = replacementForNode.call(this, node, previousNode);
|
||||
}
|
||||
|
||||
return join(output, replacement)
|
||||
}, '')
|
||||
output = join(output, replacement);
|
||||
previousNode = node;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,11 +216,12 @@ function postProcess (output) {
|
||||
* Converts an element node to its Markdown equivalent
|
||||
* @private
|
||||
* @param {HTMLElement} node The node to convert
|
||||
* @param {HTMLElement|null} previousNode The node immediately before this node.
|
||||
* @returns A Markdown representation of the node
|
||||
* @type String
|
||||
*/
|
||||
|
||||
function replacementForNode (node) {
|
||||
function replacementForNode (node, previousNode) {
|
||||
var rule = this.rules.forNode(node)
|
||||
var content = process.call(this, node, rule.escapeContent ? rule.escapeContent(node) : 'auto')
|
||||
var whitespace = node.flankingWhitespace
|
||||
@ -223,7 +229,7 @@ function replacementForNode (node) {
|
||||
|
||||
return (
|
||||
whitespace.leading +
|
||||
rule.replacement(content, node, this.options) +
|
||||
rule.replacement(content, node, this.options, previousNode) +
|
||||
whitespace.trailing
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user