pantsdown 1.10.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -40
- package/package.json +1 -1
- package/src/{code-copy.ts → javascript.ts} +16 -12
- package/src/pantsdown.ts +6 -3
- package/src/rules/block.ts +1 -1
package/README.md
CHANGED
|
@@ -6,9 +6,6 @@
|
|
|
6
6
|
Pantsdown is a **Markdown** to **HTML** converter. It attempts to render markdown similar to how GitHub does it plus
|
|
7
7
|
some features developed specifically for [github-preview.nvim](https://github.com/wallpants/github-preview.nvim).
|
|
8
8
|
|
|
9
|
-
If you need a feature that's supported by GitHub and is not already listed in the [Roadmap](#-roadmap),
|
|
10
|
-
feel free to open an issue.
|
|
11
|
-
|
|
12
9
|
## [▶️ Demo](https://wallpants.github.io/pantsdown/)
|
|
13
10
|
|
|
14
11
|
## 📦 Installation
|
|
@@ -32,7 +29,9 @@ it's recommended you use a sanitization library like [DOMPurify](https://github.
|
|
|
32
29
|
### Styles
|
|
33
30
|
|
|
34
31
|
For styles to be properly applied, either the element containing the generated html or one of its parents
|
|
35
|
-
must have the classes `class="pantsdown light"` or `class="pantsdown dark"` added.
|
|
32
|
+
must have the classes `class="pantsdown light"` or `class="pantsdown dark"` added. You can also add
|
|
33
|
+
the class `"high-contrast"` to enable high-contrast themes `class="pantsdown dark high-contrast"` or
|
|
34
|
+
`class="pantsdown light high-contrast"`.
|
|
36
35
|
|
|
37
36
|
### [Bun](https://bun.sh/)
|
|
38
37
|
|
|
@@ -74,16 +73,22 @@ import { useEffect } from "react";
|
|
|
74
73
|
const pantsdown = new Pantsdown();
|
|
75
74
|
|
|
76
75
|
function App() {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
const container = document.getElementById("markdown-container");
|
|
78
|
+
if (!container) return;
|
|
79
|
+
|
|
80
|
+
const markdown = "# Hello world\n- [ ] Task 1\n- [x] Task 2";
|
|
81
|
+
const { html, javascript } = pantsdown.parse(markdown);
|
|
82
|
+
container.innerHTML = html;
|
|
83
|
+
|
|
84
|
+
const newScript = document.createElement("script");
|
|
85
|
+
newScript.text = javascript;
|
|
86
|
+
container.appendChild(newScript);
|
|
87
|
+
}, []);
|
|
88
|
+
|
|
89
|
+
// ⚠️ for styles to be applied, a parent element must have
|
|
90
|
+
// the classes "pantsdown light" or "pantsdown dark" added
|
|
91
|
+
return <div id="markdown-container" className="pantsdown light" />;
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
export default App;
|
|
@@ -100,32 +105,32 @@ import { Pantsdown, type PartialPantsdownConfig } from "pantsdown";
|
|
|
100
105
|
// This is the default config object. If you provide
|
|
101
106
|
// a config object, it will be deeply merged into this.
|
|
102
107
|
const config: PartialPantsdownConfig = {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
108
|
+
renderer: {
|
|
109
|
+
/**
|
|
110
|
+
* Prefix to be added to relative image sources.
|
|
111
|
+
* Must start and end with "/"
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* relativeImageUrlPrefix: "/__localimage__/"
|
|
115
|
+
*
|
|
116
|
+
* 
|
|
117
|
+
* relative src is updated and results in:
|
|
118
|
+
* <img src="/__localimage__/wallpants-512.png" />
|
|
119
|
+
*
|
|
120
|
+
* 
|
|
121
|
+
* absolute src remains unchanged:
|
|
122
|
+
* <img src="https://avatars.githubusercontent.com/wallpants" />
|
|
123
|
+
*/
|
|
124
|
+
relativeImageUrlPrefix: "",
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Whether to render <details> html tags with attribute open=""
|
|
128
|
+
*
|
|
129
|
+
* @default
|
|
130
|
+
* false
|
|
131
|
+
*/
|
|
132
|
+
detailsTagDefaultOpen: false,
|
|
133
|
+
},
|
|
129
134
|
};
|
|
130
135
|
|
|
131
136
|
const pantsdown = new Pantsdown(config);
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const
|
|
2
|
-
|
|
1
|
+
export const javascript = `
|
|
2
|
+
/** code copy button */
|
|
3
3
|
document.querySelectorAll("pre").forEach((pre) => {
|
|
4
4
|
const firstElement = pre.firstElementChild;
|
|
5
5
|
if (!firstElement || firstElement.tagName !== "CODE") return;
|
|
@@ -15,17 +15,21 @@ export const codeCopyScript = `
|
|
|
15
15
|
|
|
16
16
|
pre.appendChild(copyButton);
|
|
17
17
|
copyButton.addEventListener("click", () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
copyButton.classList.add("success");
|
|
22
|
-
setTimeout(() => {
|
|
23
|
-
copyButton.classList.remove("success");
|
|
24
|
-
}, 1000);
|
|
25
|
-
}
|
|
26
|
-
);
|
|
18
|
+
if (!pre.firstChild?.textContent) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
27
21
|
|
|
22
|
+
navigator.clipboard
|
|
23
|
+
.writeText(pre.firstChild.textContent)
|
|
24
|
+
.then(() => {
|
|
25
|
+
copyButton.classList.add("success");
|
|
26
|
+
setTimeout(() => {
|
|
27
|
+
copyButton.classList.remove("success");
|
|
28
|
+
}, 1000);
|
|
29
|
+
})
|
|
30
|
+
.catch(() => {
|
|
31
|
+
//
|
|
32
|
+
});
|
|
28
33
|
});
|
|
29
34
|
});
|
|
30
|
-
</script>
|
|
31
35
|
`;
|
package/src/pantsdown.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import GithubSlugger from "github-slugger";
|
|
2
|
-
import {
|
|
2
|
+
import { javascript } from "./javascript.ts";
|
|
3
3
|
import { Lexer } from "./lexer.ts";
|
|
4
4
|
import { Parser } from "./parser.ts";
|
|
5
5
|
import { type PantsdownConfig, type PartialPantsdownConfig } from "./types.ts";
|
|
@@ -38,13 +38,16 @@ export class Pantsdown {
|
|
|
38
38
|
/**
|
|
39
39
|
* Parse markdown string
|
|
40
40
|
*/
|
|
41
|
-
parse(src: string): string {
|
|
41
|
+
parse(src: string): { html: string; javascript: string } {
|
|
42
42
|
// re-init slugger to avoid slug count from incorrectly incrementing
|
|
43
43
|
// from previosly slugged headings
|
|
44
44
|
this.parser.renderer.slugger = new GithubSlugger();
|
|
45
45
|
|
|
46
46
|
const tokens = this.lexer.lex(src);
|
|
47
47
|
const html = this.parser.parse(tokens);
|
|
48
|
-
return
|
|
48
|
+
return {
|
|
49
|
+
html,
|
|
50
|
+
javascript,
|
|
51
|
+
};
|
|
49
52
|
}
|
|
50
53
|
}
|
package/src/rules/block.ts
CHANGED
|
@@ -126,6 +126,6 @@ export const block: Record<BlockRuleNames, RegExp> = {
|
|
|
126
126
|
table: block_table,
|
|
127
127
|
lheading: block_lheading,
|
|
128
128
|
paragraph: block_paragraph,
|
|
129
|
-
footnote: /^\[\^([^\]\n]+)\]:(?:[ \t]+|[\n]*?|$)([^\
|
|
129
|
+
footnote: /^\[\^([^\]\n]+)\]:(?:[ \t]+|[\n]*?|$)([^\n]*?(?:\n|$)(?:[\n]*?[ ]{4,}[^\n]*)*)/,
|
|
130
130
|
text: /^[^\n]+/,
|
|
131
131
|
};
|