remove-markdown 0.6.4 → 0.7.0-rc.1
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 +39 -2
- package/index.d.mts +13 -0
- package/index.mjs +99 -0
- package/index.node.mjs +3 -0
- package/package.json +56 -6
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://github.com/zuchka/remove-markdown/actions/workflows/default.yaml)
|
|
4
4
|
|
|
5
5
|
## What is it?
|
|
6
|
-
**remove-markdown** is a
|
|
6
|
+
**remove-markdown** is a JavaScript module that removes (strips) Markdown formatting from text. It supports CommonJS and ES modules in Node.js, plus Deno through npm compatibility.
|
|
7
7
|
*Markdown formatting* means pretty much anything that doesn’t look like regular text, like square brackets, asterisks etc.
|
|
8
8
|
|
|
9
9
|
## When do I need it?
|
|
@@ -11,17 +11,54 @@ The typical use case is to display an excerpt from some Markdown text, without a
|
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
|
-
```
|
|
14
|
+
```sh
|
|
15
15
|
npm install remove-markdown
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
19
|
+
|
|
20
|
+
### CommonJS
|
|
21
|
+
|
|
19
22
|
```js
|
|
20
23
|
const removeMd = require('remove-markdown');
|
|
21
24
|
const markdown = '# This is a heading\n\nThis is a paragraph with [a link](http://www.disney.com/) in it.';
|
|
22
25
|
const plainText = removeMd(markdown); // plainText is now 'This is a heading\n\nThis is a paragraph with a link in it.'
|
|
23
26
|
```
|
|
24
27
|
|
|
28
|
+
### Node.js ES modules
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
import removeMd from 'remove-markdown';
|
|
32
|
+
|
|
33
|
+
const markdown = '# This is a heading\n\nThis is a paragraph with [a link](http://www.disney.com/) in it.';
|
|
34
|
+
const plainText = removeMd(markdown);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Browser ES modules
|
|
38
|
+
|
|
39
|
+
The ESM entry is self-contained and can be loaded directly from a CDN that
|
|
40
|
+
serves JavaScript with the correct MIME type. Pin the URL to the version you
|
|
41
|
+
have tested:
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<script type="module">
|
|
45
|
+
import removeMd from 'https://unpkg.com/remove-markdown@0.7.0/index.mjs';
|
|
46
|
+
|
|
47
|
+
const plainText = removeMd('# This is a heading');
|
|
48
|
+
</script>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Deno
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
import removeMd from 'npm:remove-markdown@^0.7.0';
|
|
55
|
+
|
|
56
|
+
const markdown = '# This is a heading\n\nThis is a paragraph with [a link](http://www.disney.com/) in it.';
|
|
57
|
+
const plainText = removeMd(markdown);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Deno support is provided through the npm package; there is no separate JSR package. The package exposes one callable default export in every runtime. Named exports and direct imports from raw GitHub URLs, which do not reliably serve the correct JavaScript MIME type, are not supported.
|
|
61
|
+
|
|
25
62
|
You can also supply an options object to the function. Currently, the following options are supported:
|
|
26
63
|
|
|
27
64
|
```js
|
package/index.d.mts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare function removeMd(md: string, options?: {
|
|
2
|
+
stripListLeaders?: boolean;
|
|
3
|
+
listUnicodeChar?: string;
|
|
4
|
+
gfm?: boolean;
|
|
5
|
+
useImgAltText?: boolean;
|
|
6
|
+
abbr?: boolean;
|
|
7
|
+
replaceLinksWithURL?: boolean;
|
|
8
|
+
separateLinksAndTexts?: string;
|
|
9
|
+
htmlTagsToSkip?: string[];
|
|
10
|
+
throwError?: boolean;
|
|
11
|
+
}): string;
|
|
12
|
+
|
|
13
|
+
export default removeMd;
|
package/index.mjs
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// Generated from index.js by scripts/build-esm.mjs. Do not edit directly.
|
|
2
|
+
|
|
3
|
+
export default function removeMarkdown(md, options) {
|
|
4
|
+
options = options || {};
|
|
5
|
+
options.listUnicodeChar = options.hasOwnProperty('listUnicodeChar') ? options.listUnicodeChar : false;
|
|
6
|
+
options.stripListLeaders = options.hasOwnProperty('stripListLeaders') ? options.stripListLeaders : true;
|
|
7
|
+
options.gfm = options.hasOwnProperty('gfm') ? options.gfm : true;
|
|
8
|
+
options.useImgAltText = options.hasOwnProperty('useImgAltText') ? options.useImgAltText : true;
|
|
9
|
+
options.abbr = options.hasOwnProperty('abbr') ? options.abbr : false;
|
|
10
|
+
options.replaceLinksWithURL = options.hasOwnProperty('replaceLinksWithURL') ? options.replaceLinksWithURL : false;
|
|
11
|
+
options.separateLinksAndTexts = options.hasOwnProperty('separateLinksAndTexts') ? options.separateLinksAndTexts : null;
|
|
12
|
+
options.htmlTagsToSkip = options.hasOwnProperty('htmlTagsToSkip') ? options.htmlTagsToSkip : [];
|
|
13
|
+
options.throwError = options.hasOwnProperty('throwError') ? options.throwError : false;
|
|
14
|
+
|
|
15
|
+
var output = md || '';
|
|
16
|
+
|
|
17
|
+
// Remove horizontal rules (stripListHeaders conflict with this rule, which is why it has been moved to the top)
|
|
18
|
+
output = output.replace(/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/gm, '');
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
if (options.stripListLeaders) {
|
|
22
|
+
if (options.listUnicodeChar)
|
|
23
|
+
output = output.replace(/^([\s\t]*)([\*\-\+]|\d+\.)\s+/gm, options.listUnicodeChar + ' $1');
|
|
24
|
+
else
|
|
25
|
+
output = output.replace(/^([\s\t]*)([\*\-\+]|\d+\.)\s+/gm, '$1');
|
|
26
|
+
}
|
|
27
|
+
if (options.gfm) {
|
|
28
|
+
output = output
|
|
29
|
+
// Header
|
|
30
|
+
.replace(/\n={2,}/g, '\n')
|
|
31
|
+
// Fenced codeblocks
|
|
32
|
+
.replace(/~{3}.*\n/g, '')
|
|
33
|
+
// Strikethrough
|
|
34
|
+
.replace(/~~/g, '')
|
|
35
|
+
// Fenced codeblocks with backticks
|
|
36
|
+
.replace(/```(?:.*)\n([\s\S]*?)```/g, (_, code) => code.trim());
|
|
37
|
+
}
|
|
38
|
+
if (options.abbr) {
|
|
39
|
+
// Remove abbreviations
|
|
40
|
+
output = output.replace(/\*\[.*\]:.*\n/, '');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let htmlReplaceRegex = /<[^>]*>/g
|
|
44
|
+
if (options.htmlTagsToSkip && options.htmlTagsToSkip.length > 0) {
|
|
45
|
+
// Create a regex that matches tags not in htmlTagsToSkip
|
|
46
|
+
const joinedHtmlTagsToSkip = options.htmlTagsToSkip.join('|')
|
|
47
|
+
htmlReplaceRegex = new RegExp(
|
|
48
|
+
`<(?!\/?(${joinedHtmlTagsToSkip})(?=>|\s[^>]*>))[^>]*>`,
|
|
49
|
+
'g',
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (options.separateLinksAndTexts) {
|
|
54
|
+
output = output.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1' + options.separateLinksAndTexts + '$2');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
output = output
|
|
58
|
+
// Remove HTML tags
|
|
59
|
+
.replace(htmlReplaceRegex, '')
|
|
60
|
+
// Remove setext-style headers
|
|
61
|
+
.replace(/^[=\-]{2,}\s*$/g, '')
|
|
62
|
+
// Remove footnotes?
|
|
63
|
+
.replace(/\[\^.+?\](\: .*?$)?/g, '')
|
|
64
|
+
.replace(/\s{0,2}\[.*?\]: .*?$/g, '')
|
|
65
|
+
// Remove images
|
|
66
|
+
.replace(/\!\[(.*?)\][\[\(].*?[\]\)]/g, options.useImgAltText ? '$1' : '')
|
|
67
|
+
// Remove inline links
|
|
68
|
+
.replace(/\[([\s\S]*?)\]\s*[\(\[](.*?)[\)\]]/g, options.replaceLinksWithURL ? '$2' : '$1')
|
|
69
|
+
// Remove blockquotes
|
|
70
|
+
.replace(/^(\n)?\s{0,3}>\s?/gm, '$1')
|
|
71
|
+
// .replace(/(^|\n)\s{0,3}>\s?/g, '\n\n')
|
|
72
|
+
// Remove reference-style links?
|
|
73
|
+
.replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g, '')
|
|
74
|
+
// Remove atx-style headers
|
|
75
|
+
.replace(/^(\n)?\s{0,}#{1,6}\s*( (.+))? +#+$|^(\n)?\s{0,}#{1,6}\s*( (.+))?$/gm, '$1$3$4$6')
|
|
76
|
+
// Remove * emphasis
|
|
77
|
+
.replace(/([\*]+)(\S)(.*?\S)??\1/g, '$2$3')
|
|
78
|
+
// Remove _ emphasis. Unlike *, _ emphasis gets rendered only if
|
|
79
|
+
// 1. Either there is a whitespace character before opening _ and after closing _.
|
|
80
|
+
// 2. Or _ is at the start/end of the string.
|
|
81
|
+
.replace(/(^|\W)([_]+)(\S)(.*?\S)??\2($|\W)/g, '$1$3$4$5')
|
|
82
|
+
// Remove single-line code blocks (already handled multiline above in gfm section)
|
|
83
|
+
.replace(/(`{3,})(.*?)\1/gm, '$2')
|
|
84
|
+
// Remove inline code
|
|
85
|
+
.replace(/`(.+?)`/g, '$1')
|
|
86
|
+
// // Replace two or more newlines with exactly two? Not entirely sure this belongs here...
|
|
87
|
+
// .replace(/\n{2,}/g, '\n\n')
|
|
88
|
+
// // Remove newlines in a paragraph
|
|
89
|
+
// .replace(/(\S+)\n\s*(\S+)/g, '$1 $2')
|
|
90
|
+
// Replace strike through
|
|
91
|
+
.replace(/~(.*?)~/g, '$1');
|
|
92
|
+
} catch(e) {
|
|
93
|
+
if (options.throwError) throw e;
|
|
94
|
+
|
|
95
|
+
console.error("remove-markdown encountered error: %s", e);
|
|
96
|
+
return md;
|
|
97
|
+
}
|
|
98
|
+
return output;
|
|
99
|
+
};
|
package/index.node.mjs
ADDED
package/package.json
CHANGED
|
@@ -1,20 +1,61 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remove-markdown",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0-rc.1",
|
|
4
4
|
"description": "Remove Markdown formatting from text",
|
|
5
|
-
"
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "./index.js",
|
|
7
|
+
"types": "./index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./index.d.mts",
|
|
12
|
+
"browser": "./index.mjs",
|
|
13
|
+
"node": "./index.node.mjs",
|
|
14
|
+
"default": "./index.mjs"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./index.d.ts",
|
|
18
|
+
"default": "./index.js"
|
|
19
|
+
},
|
|
20
|
+
"default": "./index.js"
|
|
21
|
+
},
|
|
22
|
+
"./index": "./index.js",
|
|
23
|
+
"./index.js": "./index.js",
|
|
24
|
+
"./index.mjs": {
|
|
25
|
+
"types": "./index.d.mts",
|
|
26
|
+
"default": "./index.mjs"
|
|
27
|
+
},
|
|
28
|
+
"./index.d.mts": "./index.d.mts",
|
|
29
|
+
"./index.d.ts": "./index.d.ts",
|
|
30
|
+
"./LICENSE": "./LICENSE",
|
|
31
|
+
"./README.md": "./README.md",
|
|
32
|
+
"./package.json": "./package.json"
|
|
33
|
+
},
|
|
6
34
|
"files": [
|
|
7
35
|
"index.js",
|
|
36
|
+
"index.mjs",
|
|
37
|
+
"index.node.mjs",
|
|
8
38
|
"index.d.ts",
|
|
39
|
+
"index.d.mts",
|
|
9
40
|
"README.md",
|
|
10
41
|
"LICENSE"
|
|
11
42
|
],
|
|
12
43
|
"scripts": {
|
|
13
|
-
"
|
|
44
|
+
"build:esm": "node scripts/build-esm.mjs",
|
|
45
|
+
"check:esm": "node scripts/build-esm.mjs --check",
|
|
46
|
+
"test": "mocha -R spec test/remove-markdown.js",
|
|
47
|
+
"test:modules": "node --test test/modules.test.mjs",
|
|
48
|
+
"test:package": "node --test test/package.test.mjs",
|
|
49
|
+
"test:types": "node --test test/types.test.mjs",
|
|
50
|
+
"test:differential": "node --test test/differential.test.mjs",
|
|
51
|
+
"test:bundlers": "node --test test/bundlers.test.mjs",
|
|
52
|
+
"test:deno": "deno test --no-lock --allow-import=127.0.0.1 --allow-net=127.0.0.1 --allow-read test/deno.test.mjs",
|
|
53
|
+
"test:deno:package": "node --test test/deno-package.test.mjs",
|
|
54
|
+
"prepublishOnly": "npm run check:esm && npm test && npm run test:modules && npm run test:package && npm run test:types"
|
|
14
55
|
},
|
|
15
56
|
"repository": {
|
|
16
57
|
"type": "git",
|
|
17
|
-
"url": "https://github.com/zuchka/remove-markdown.git"
|
|
58
|
+
"url": "git+https://github.com/zuchka/remove-markdown.git"
|
|
18
59
|
},
|
|
19
60
|
"keywords": [
|
|
20
61
|
"markdown"
|
|
@@ -26,8 +67,17 @@
|
|
|
26
67
|
},
|
|
27
68
|
"homepage": "https://github.com/zuchka/remove-markdown",
|
|
28
69
|
"devDependencies": {
|
|
70
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
71
|
+
"@rollup/plugin-commonjs": "^29.0.3",
|
|
72
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
29
73
|
"chai": "^4.0.2",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
74
|
+
"esbuild": "^0.28.2",
|
|
75
|
+
"mocha": "11.3.0",
|
|
76
|
+
"rollup": "^4.62.5",
|
|
77
|
+
"should": "^5.0.0",
|
|
78
|
+
"typescript": "^7.0.2"
|
|
79
|
+
},
|
|
80
|
+
"overrides": {
|
|
81
|
+
"serialize-javascript": "^7.0.5"
|
|
32
82
|
}
|
|
33
83
|
}
|