You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-23 22:36:32 +02:00
Desktop: Fixes #5626: When web clipper clipping code blocks, keep code in multiline and delete code number lines (#10126)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com> Co-authored-by: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com>
This commit is contained in:
24
packages/app-cli/tests/html_to_md/code_multiline_1.html
Normal file
24
packages/app-cli/tests/html_to_md/code_multiline_1.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!-- this is from: https://flaviocopes.com/bubble-sort-javascript/ -->
|
||||
<div><pre class="astro-code github-dark" style="background-color: rgb(36, 41, 46); color: rgb(225, 228, 232); overflow-x: auto; --darkreader-inline-bgcolor: #1d2125; --darkreader-inline-color: #d7d4cf; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;" tabindex="0" data-darkreader-inline-bgcolor="" data-darkreader-inline-color=""><code><span class="line"><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">const</span><span style="color: rgb(179, 146, 240); --darkreader-inline-color: #ab86ee;" data-darkreader-inline-color=""> bubbleSort</span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> =</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> (</span><span style="color: rgb(255, 171, 112); --darkreader-inline-color: #ffa668;" data-darkreader-inline-color="">originalArray</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">) </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">=></span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> {</span></span>
|
||||
<span class="line"><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> let</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> swapped </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">=</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color=""> false</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> const</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color=""> a</span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> =</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> [</span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">...</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">originalArray]</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> for</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> (</span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">let</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> i </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">=</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color=""> 1</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">; i </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""><</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> a.</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color="">length</span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> -</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color=""> 1</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">; i</span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">++</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">) {</span></span>
|
||||
<span class="line"><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> swapped </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">=</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color=""> false</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> for</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> (</span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">let</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> j </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">=</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color=""> 0</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">; j </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""><</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> a.</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color="">length</span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> -</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> i; j</span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">++</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">) {</span></span>
|
||||
<span class="line"><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> if</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> (a[j </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">+</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color=""> 1</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">] </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""><</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> a[j]) {</span></span>
|
||||
<span class="line"><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> ;[a[j], a[j </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">+</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color=""> 1</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">]] </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">=</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> [a[j </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">+</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color=""> 1</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">], a[j]]</span></span>
|
||||
<span class="line"><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> swapped </span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">=</span><span style="color: rgb(121, 184, 255); --darkreader-inline-color: #6ebdff;" data-darkreader-inline-color=""> true</span></span>
|
||||
<span class="line"><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> }</span></span>
|
||||
<span class="line"><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> }</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> if</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> (</span><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color="">!</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">swapped) {</span></span>
|
||||
<span class="line"><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> return</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> a</span></span>
|
||||
<span class="line"><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> }</span></span>
|
||||
<span class="line"><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> }</span></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span style="color: rgb(249, 117, 131); --darkreader-inline-color: #f96e7c;" data-darkreader-inline-color=""> return</span><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color=""> a</span></span>
|
||||
<span class="line"><span style="color: rgb(225, 228, 232); --darkreader-inline-color: #d7d4cf;" data-darkreader-inline-color="">}</span></span></code></pre>
|
||||
<p></p></div>
|
||||
24
packages/app-cli/tests/html_to_md/code_multiline_1.md
Normal file
24
packages/app-cli/tests/html_to_md/code_multiline_1.md
Normal file
@@ -0,0 +1,24 @@
|
||||
```
|
||||
const bubbleSort = (originalArray) => {
|
||||
let swapped = false
|
||||
|
||||
const a = [...originalArray]
|
||||
|
||||
for (let i = 1; i < a.length - 1; i++) {
|
||||
swapped = false
|
||||
|
||||
for (let j = 0; j < a.length - i; j++) {
|
||||
if (a[j + 1] < a[j]) {
|
||||
;[a[j], a[j + 1]] = [a[j + 1], a[j]]
|
||||
swapped = true
|
||||
}
|
||||
}
|
||||
|
||||
if (!swapped) {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
```
|
||||
21
packages/app-cli/tests/html_to_md/code_multiline_2.html
Normal file
21
packages/app-cli/tests/html_to_md/code_multiline_2.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!-- this is from: https://blog.csdn.net/qq_42025798/article/details/121727781 -->
|
||||
<div><pre data-index="6" class="prettyprint set-code-show" style="font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono", Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, "PingFang SC", "Microsoft YaHei", sans-serif;"><code class="prism language-java has-numbering" onclick="mdcp.copyCode(event)" style="position: unset;"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
|
||||
|
||||
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> name<span class="token punctuation">;</span>
|
||||
<span class="token punctuation">}</span>
|
||||
|
||||
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
|
||||
<span class="token punctuation">}</span>
|
||||
|
||||
<span class="token annotation punctuation">@Override</span>
|
||||
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
||||
<span class="token keyword">return</span> <span class="token string">"User{"</span> <span class="token operator">+</span>
|
||||
<span class="token string">"name='"</span> <span class="token operator">+</span> name <span class="token operator">+</span> <span class="token string">'\''</span> <span class="token operator">+</span>
|
||||
<span class="token string">'}'</span><span class="token punctuation">;</span>
|
||||
<span class="token punctuation">}</span>
|
||||
<span class="token punctuation">}</span>
|
||||
</code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">1</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">2</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">3</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">4</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">5</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">6</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">7</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">8</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">9</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">10</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">11</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">12</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">13</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">14</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">15</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">16</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">17</li><li style="color: rgb(153, 153, 153); --darkreader-inline-color: #a8a095;" data-darkreader-inline-color="">18</li></ul></pre>
|
||||
<h4></h4></div>
|
||||
20
packages/app-cli/tests/html_to_md/code_multiline_2.md
Normal file
20
packages/app-cli/tests/html_to_md/code_multiline_2.md
Normal file
@@ -0,0 +1,20 @@
|
||||
```
|
||||
public class User {
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User{" +
|
||||
"name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
```
|
||||
2
packages/app-cli/tests/html_to_md/code_multiline_3.html
Normal file
2
packages/app-cli/tests/html_to_md/code_multiline_3.html
Normal file
File diff suppressed because one or more lines are too long
16
packages/app-cli/tests/html_to_md/code_multiline_3.md
Normal file
16
packages/app-cli/tests/html_to_md/code_multiline_3.md
Normal file
@@ -0,0 +1,16 @@
|
||||
```typescript
|
||||
// Import the Joplin API
|
||||
import joplin from 'api';
|
||||
|
||||
// Register the plugin
|
||||
joplin.plugins.register({
|
||||
|
||||
// Run initialisation code in the onStart event handler
|
||||
// Note that due to the plugin multi-process architecture, you should
|
||||
// always assume that all function calls and event handlers are async.
|
||||
onStart: async function() {
|
||||
console.info('TOC plugin started!');
|
||||
},
|
||||
|
||||
});
|
||||
```
|
||||
2
packages/app-cli/tests/html_to_md/code_multiline_4.html
Normal file
2
packages/app-cli/tests/html_to_md/code_multiline_4.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<!-- this is from: https://blog.csdn.net/ch5256865/article/details/52957360 -->
|
||||
<pre data-index="0" class="set-code-show" name="code" style="font-family: Consolas, Inconsolata, Courier, monospace;"><code class="hljs language-javascript"><ol class="hljs-ln" style="width:100%"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">let</span> str = <span class="hljs-string">` hello world ! `</span>;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">let</span> _trim = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) {</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-variable language_">this</span> == <span class="hljs-string">"number"</span>) <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">"Invalid or unexpected token"</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-variable language_">this</span> !== <span class="hljs-string">"string"</span>)</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">"Cannot read property 'trim' of"</span> + <span class="hljs-variable language_">this</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword">let</span> reg = <span class="hljs-regexp">/^\s*|\s*$/g</span>;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">replace</span>(reg, <span class="hljs-string">""</span>);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">};</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-title class_">String</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">_trim</span> = _trim;</div></div></li></ol></code></pre>
|
||||
12
packages/app-cli/tests/html_to_md/code_multiline_4.md
Normal file
12
packages/app-cli/tests/html_to_md/code_multiline_4.md
Normal file
@@ -0,0 +1,12 @@
|
||||
```
|
||||
let str = ` hello world ! `;
|
||||
let _trim = function () {
|
||||
if (typeof this == "number") new Error("Invalid or unexpected token");
|
||||
if (typeof this !== "string")
|
||||
new Error("Cannot read property 'trim' of" + this);
|
||||
let reg = /^\s*|\s*$/g;
|
||||
return this.replace(reg, "");
|
||||
};
|
||||
|
||||
String.prototype._trim = _trim;
|
||||
```
|
||||
42
packages/app-cli/tests/html_to_md/code_multiline_5.html
Normal file
42
packages/app-cli/tests/html_to_md/code_multiline_5.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<!-- this is from: https://www.slingacademy.com/article/python-aiohttp-how-to-download-files-using-streams/ -->
|
||||
<div><pre class="wp-block-code prettyprinted" style="font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "liberation mono", "courier new", monospace;"><code class=" prettyprinted" style=""><span class="com"><span class="com"># SlingAcademy.com</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="com"><span class="com"># This code uses Python 3.11.4</span></span><span class="pln"><span class="pln">
|
||||
|
||||
</span></span><span class="kwd"><span class="kwd">import</span></span><span class="pln"><span class="pln"> asyncio
|
||||
</span></span><span class="kwd"><span class="kwd">import</span></span><span class="pln"><span class="pln"> aiohttp
|
||||
|
||||
</span></span><span class="com"><span class="com"># This function downloads a file from a URL and saves it to a local file</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="com"><span class="com"># The function is asynchronous and can handle large files because it uses aiohttp streams</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">async</span></span><span class="pln"><span class="pln"> </span></span><span class="kwd"><span class="kwd">def</span></span><span class="pln"><span class="pln"> download_file</span></span><span class="pun"><span class="pun">(</span></span><span class="pln"><span class="pln">url</span></span><span class="pun"><span class="pun">,</span></span><span class="pln"><span class="pln"> filename</span></span><span class="pun"><span class="pun">):</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">async</span></span><span class="pln"><span class="pln"> </span></span><span class="kwd"><span class="kwd">with</span></span><span class="pln"><span class="pln"> aiohttp</span></span><span class="pun"><span class="pun">.</span></span><span class="typ"><span class="typ">ClientSession</span></span><span class="pun"><span class="pun">()</span></span><span class="pln"><span class="pln"> </span></span><span class="kwd"><span class="kwd">as</span></span><span class="pln"><span class="pln"> session</span></span><span class="pun"><span class="pun">:</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">print</span></span><span class="pun"><span class="pun">(</span></span><span class="pln"><span class="pln">f</span></span><span class="str"><span class="str">"Starting download file from {url}"</span></span><span class="pun"><span class="pun">)</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">async</span></span><span class="pln"><span class="pln"> </span></span><span class="kwd"><span class="kwd">with</span></span><span class="pln"><span class="pln"> session</span></span><span class="pun"><span class="pun">.</span></span><span class="kwd"><span class="kwd">get</span></span><span class="pun"><span class="pun">(</span></span><span class="pln"><span class="pln">url</span></span><span class="pun"><span class="pun">)</span></span><span class="pln"><span class="pln"> </span></span><span class="kwd"><span class="kwd">as</span></span><span class="pln"><span class="pln"> response</span></span><span class="pun"><span class="pun">:</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">assert</span></span><span class="pln"><span class="pln"> response</span></span><span class="pun"><span class="pun">.</span></span><span class="pln"><span class="pln">status </span></span><span class="pun"><span class="pun">==</span></span><span class="pln"><span class="pln"> </span></span><span class="lit"><span class="lit">200</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">with</span></span><span class="pln"><span class="pln"> open</span></span><span class="pun"><span class="pun">(</span></span><span class="pln"><span class="pln">filename</span></span><span class="pun"><span class="pun">,</span></span><span class="pln"><span class="pln"> </span></span><span class="str"><span class="str">"wb"</span></span><span class="pun"><span class="pun">)</span></span><span class="pln"><span class="pln"> </span></span><span class="kwd"><span class="kwd">as</span></span><span class="pln"><span class="pln"> f</span></span><span class="pun"><span class="pun">:</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">while</span></span><span class="pln"><span class="pln"> </span></span><span class="kwd"><span class="kwd">True</span></span><span class="pun"><span class="pun">:</span></span><span class="pln"><span class="pln">
|
||||
chunk </span></span><span class="pun"><span class="pun">=</span></span><span class="pln"><span class="pln"> </span></span><span class="kwd"><span class="kwd">await</span></span><span class="pln"><span class="pln"> response</span></span><span class="pun"><span class="pun">.</span></span><span class="pln"><span class="pln">content</span></span><span class="pun"><span class="pun">.</span></span><span class="pln"><span class="pln">readany</span></span><span class="pun"><span class="pun">()</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">if</span></span><span class="pln"><span class="pln"> </span></span><span class="kwd"><span class="kwd">not</span></span><span class="pln"><span class="pln"> chunk</span></span><span class="pun"><span class="pun">:</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">break</span></span><span class="pln"><span class="pln">
|
||||
f</span></span><span class="pun"><span class="pun">.</span></span><span class="pln"><span class="pln">write</span></span><span class="pun"><span class="pun">(</span></span><span class="pln"><span class="pln">chunk</span></span><span class="pun"><span class="pun">)</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">print</span></span><span class="pun"><span class="pun">(</span></span><span class="pln"><span class="pln">f</span></span><span class="str"><span class="str">"Downloaded {filename} from {url}"</span></span><span class="pun"><span class="pun">)</span></span><span class="pln"><span class="pln">
|
||||
|
||||
|
||||
</span></span><span class="com"><span class="com"># This function downloads two files at the same time</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">async</span></span><span class="pln"><span class="pln"> </span></span><span class="kwd"><span class="kwd">def</span></span><span class="pln"><span class="pln"> main</span></span><span class="pun"><span class="pun">():</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="kwd"><span class="kwd">await</span></span><span class="pln"><span class="pln"> asyncio</span></span><span class="pun"><span class="pun">.</span></span><span class="pln"><span class="pln">gather</span></span><span class="pun"><span class="pun">(</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="com"><span class="com"># download a CSV file</span></span><span class="pln"><span class="pln">
|
||||
download_file</span></span><span class="pun"><span class="pun">(</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="str"><span class="str">"https://api.slingacademy.com/v1/sample-data/files/student-scores.csv"</span></span><span class="pun"><span class="pun">,</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="str"><span class="str">"test.csv"</span></span><span class="pun"><span class="pun">,</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="pun"><span class="pun">),</span></span><span class="pln"><span class="pln">
|
||||
|
||||
</span></span><span class="com"><span class="com"># download a PDF file</span></span><span class="pln"><span class="pln">
|
||||
download_file</span></span><span class="pun"><span class="pun">(</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="str"><span class="str">"https://api.slingacademy.com/v1/sample-data/files/text-and-table.pdf"</span></span><span class="pun"><span class="pun">,</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="str"><span class="str">"test.pdf"</span></span><span class="pun"><span class="pun">,</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="pun"><span class="pun">),</span></span><span class="pln"><span class="pln">
|
||||
</span></span><span class="pun"><span class="pun">)</span></span><span class="pln"><span class="pln">
|
||||
|
||||
</span></span><span class="com"><span class="com"># Run the main function</span></span><span class="pln"><span class="pln">
|
||||
asyncio</span></span><span class="pun"><span class="pun">.</span></span><span class="pln"><span class="pln">run</span></span><span class="pun"><span class="pun">(</span></span><span class="pln"><span class="pln">main</span></span><span class="pun"><span class="pun">())</span></span></code></pre><span class="ezoic-autoinsert-video ezoic-mid_content"></span>
|
||||
<p></p></div>
|
||||
42
packages/app-cli/tests/html_to_md/code_multiline_5.md
Normal file
42
packages/app-cli/tests/html_to_md/code_multiline_5.md
Normal file
@@ -0,0 +1,42 @@
|
||||
```
|
||||
# SlingAcademy.com
|
||||
# This code uses Python 3.11.4
|
||||
|
||||
import asyncio
|
||||
import aiohttp
|
||||
|
||||
# This function downloads a file from a URL and saves it to a local file
|
||||
# The function is asynchronous and can handle large files because it uses aiohttp streams
|
||||
async def download_file(url, filename):
|
||||
async with aiohttp.ClientSession() as session:
|
||||
print(f"Starting download file from {url}")
|
||||
async with session.get(url) as response:
|
||||
assert response.status == 200
|
||||
with open(filename, "wb") as f:
|
||||
while True:
|
||||
chunk = await response.content.readany()
|
||||
if not chunk:
|
||||
break
|
||||
f.write(chunk)
|
||||
print(f"Downloaded {filename} from {url}")
|
||||
|
||||
|
||||
# This function downloads two files at the same time
|
||||
async def main():
|
||||
await asyncio.gather(
|
||||
# download a CSV file
|
||||
download_file(
|
||||
"https://api.slingacademy.com/v1/sample-data/files/student-scores.csv",
|
||||
"test.csv",
|
||||
),
|
||||
|
||||
# download a PDF file
|
||||
download_file(
|
||||
"https://api.slingacademy.com/v1/sample-data/files/text-and-table.pdf",
|
||||
"test.pdf",
|
||||
),
|
||||
)
|
||||
|
||||
# Run the main function
|
||||
asyncio.run(main())
|
||||
```
|
||||
@@ -44,6 +44,15 @@ export default class HtmlToMd {
|
||||
if (node.matches('object')) {
|
||||
return pdfRule.replacement(content, node, {});
|
||||
}
|
||||
|
||||
if (node.isCode) {
|
||||
// Fix: Web clipper has trouble with code blocks on Joplin's website.
|
||||
// See https://github.com/laurent22/joplin/pull/10126#issuecomment-2016523281 .
|
||||
// If isCode, blank keep empty
|
||||
// test case: packages/app-cli/tests/html_to_md/code_multiline_3.html
|
||||
return '';
|
||||
}
|
||||
|
||||
return '\n\n';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -159,7 +159,12 @@ rules.list = {
|
||||
|
||||
replacement: function (content, node) {
|
||||
var parent = node.parentNode
|
||||
if (parent.nodeName === 'LI' && parent.lastElementChild === node) {
|
||||
if (parent && isCodeBlock(parent) && node.classList && node.classList.contains('pre-numbering')){
|
||||
// Ignore code-block children of type ul with class pre-numbering.
|
||||
// See https://github.com/laurent22/joplin/pull/10126#discussion_r1532204251 .
|
||||
// test case: packages/app-cli/tests/html_to_md/code_multiline_2.html
|
||||
return '';
|
||||
} else if (parent.nodeName === 'LI' && parent.lastElementChild === node) {
|
||||
return '\n' + content
|
||||
} else {
|
||||
return '\n\n' + content + '\n\n'
|
||||
@@ -185,7 +190,10 @@ rules.listItem = {
|
||||
.replace(/\n+$/, '\n') // replace trailing newlines with just a single one
|
||||
|
||||
var prefix = options.bulletListMarker + ' '
|
||||
if (node.isCode === false) {
|
||||
content = content.replace(/\n/gm, '\n ') // indent
|
||||
}
|
||||
|
||||
|
||||
const joplinCheckbox = joplinCheckboxInfo(node);
|
||||
if (joplinCheckbox) {
|
||||
@@ -193,6 +201,12 @@ rules.listItem = {
|
||||
} else {
|
||||
var parent = node.parentNode
|
||||
if (isOrderedList(parent)) {
|
||||
if (node.isCode) {
|
||||
// Ordered lists in code blocks are often for line numbers. Remove them.
|
||||
// See https://github.com/laurent22/joplin/pull/10126
|
||||
// test case: packages/app-cli/tests/html_to_md/code_multiline_4.html
|
||||
prefix = '';
|
||||
} else {
|
||||
var start = parent.getAttribute('start')
|
||||
var index = Array.prototype.indexOf.call(parent.children, node)
|
||||
var indexStr = (start ? Number(start) + index : index + 1) + ''
|
||||
@@ -215,6 +229,7 @@ rules.listItem = {
|
||||
prefix = indexStr + '.' + ' '.repeat(3 - indexStr.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
prefix + content + (node.nextSibling && !/\n$/.test(content) ? '\n' : '')
|
||||
@@ -266,6 +281,9 @@ rules.fencedCodeBlock = {
|
||||
|
||||
var fence = repeat(fenceChar, fenceSize)
|
||||
|
||||
// remove code block leading and trailing empty lines
|
||||
code = code.replace(/^([ \t]*\n)+/, '').trimEnd()
|
||||
|
||||
return (
|
||||
'\n\n' + fence + language + '\n' +
|
||||
code.replace(/\n$/, '') +
|
||||
@@ -465,9 +483,23 @@ rules.code = {
|
||||
return node.nodeName === 'CODE' && !isCodeBlock
|
||||
},
|
||||
|
||||
replacement: function (content) {
|
||||
if (!content) return ''
|
||||
content = content.replace(/\r?\n|\r/g, ' ')
|
||||
replacement: function (content, node, options) {
|
||||
if (!content) {
|
||||
return ''
|
||||
}
|
||||
|
||||
content = content.replace(/\r?\n|\r/g, '\n')
|
||||
// If code is multiline and in codeBlock, just return it, codeBlock will add fence(default is ```).
|
||||
//
|
||||
// This handles the case where a <code> element is nested directly within a <pre> and
|
||||
// should not be turned into an inline code region.
|
||||
//
|
||||
// See https://github.com/laurent22/joplin/pull/10126 .
|
||||
if (content.indexOf('\n') !== -1 && node.parentNode && isCodeBlock(node.parentNode)){
|
||||
return content
|
||||
}
|
||||
|
||||
content = content.replace(/\r?\n|\r/g, '')
|
||||
|
||||
var extraSpace = /^`|^ .*?[^ ].* $|`$/.test(content) ? ' ' : ''
|
||||
var delimiter = '`'
|
||||
|
||||
@@ -43,7 +43,10 @@ Rules.prototype = {
|
||||
},
|
||||
|
||||
forNode: function (node) {
|
||||
if (node.isBlank) return this.blankRule
|
||||
// code block keep blank lines
|
||||
// See https://github.com/laurent22/joplin/pull/10126 .
|
||||
// test case: packages/app-cli/tests/html_to_md/code_multiline_4.html
|
||||
if (node.isCode === false && node.isBlank) return this.blankRule
|
||||
var rule
|
||||
|
||||
if ((rule = findRule(this.array, node, this.options))) return rule
|
||||
|
||||
@@ -202,7 +202,7 @@ function process (parentNode, escapeContent = 'auto') {
|
||||
replacement = replacementForNode.call(this, node, previousNode);
|
||||
}
|
||||
|
||||
output = join(output, replacement);
|
||||
output = join(output, replacement, parentNode.isCode);
|
||||
previousNode = node;
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ function postProcess (output) {
|
||||
var self = this
|
||||
this.rules.forEach(function (rule) {
|
||||
if (typeof rule.append === 'function') {
|
||||
output = join(output, rule.append(self.options))
|
||||
output = join(output, rule.append(self.options), false)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -241,7 +241,34 @@ 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
|
||||
if (whitespace.leading || whitespace.trailing) content = content.trim()
|
||||
if (whitespace.leading || whitespace.trailing){
|
||||
if (node.isCode) {
|
||||
// Fix: Web clipper has trouble with code blocks on Joplin's website.
|
||||
// See https://github.com/laurent22/joplin/pull/10126#issuecomment-2016523281 .
|
||||
// if isCode, keep line breaks
|
||||
//test case: packages/app-cli/tests/html_to_md/code_multiline_1.html
|
||||
//test case: packages/app-cli/tests/html_to_md/code_multiline_3.html
|
||||
|
||||
//If the leading blank of current node or leading blank of current node including line breaks, and the leading blank of current node is equal to the leading blank of it's first child node, and the trailing blank of the current node is equal to the leading blank of it's last child node, it indicates that the leading blank and leading blank of current node is from it's child nodes, so should not be added repeatedly, this remove multiple line breaks.
|
||||
//test case: packages/app-cli/tests/html_to_md/code_multiline_5.html
|
||||
if ( (whitespace.leading.indexOf('\n') !== -1 || whitespace.trailing.indexOf('\n') !== -1) &&
|
||||
node.childNodes && node.childNodes.length > 0) {
|
||||
|
||||
var firstChildWhitespace = node.childNodes[0].flankingWhitespace
|
||||
var lastChildWhitespace = node.childNodes[node.childNodes.length-1].flankingWhitespace
|
||||
|
||||
if (whitespace.leading === firstChildWhitespace.leading &&
|
||||
whitespace.trailing === lastChildWhitespace.trailing) {
|
||||
content = content.trim()
|
||||
}
|
||||
} else {
|
||||
// keep line breaks
|
||||
content = content.replace(/^[ \t]+|[ \t]+$/g, '');
|
||||
}
|
||||
} else {
|
||||
content = content.trim()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
whitespace.leading +
|
||||
@@ -259,13 +286,20 @@ function replacementForNode (node, previousNode) {
|
||||
* @type String
|
||||
*/
|
||||
|
||||
function join (output, replacement) {
|
||||
function join (output, replacement, isCode) {
|
||||
if (isCode === true) {
|
||||
// Fix: Web clipper has trouble with code blocks on Joplin's website.
|
||||
// See https://github.com/laurent22/joplin/pull/10126#issuecomment-2016523281 .
|
||||
// If isCode, keep line breaks
|
||||
return output + replacement
|
||||
} else {
|
||||
var s1 = trimTrailingNewlines(output)
|
||||
var s2 = trimLeadingNewlines(replacement)
|
||||
var nls = Math.max(output.length - s1.length, replacement.length - s2.length)
|
||||
var separator = '\n\n'.substring(0, nls)
|
||||
|
||||
return s1 + separator + s2
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user