markdown-magic 2.6.0 → 3.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 +6 -10
- package/cli.js +5 -82
- package/lib/block-parser-js.test.js +179 -0
- package/lib/block-parser.js +389 -0
- package/lib/{utils/new-parser.test.js → block-parser.test.js} +168 -50
- package/lib/cli.js +234 -0
- package/lib/cli.test.js +409 -0
- package/lib/defaults.js +12 -0
- package/lib/index.js +319 -184
- package/lib/index.test.js +11 -0
- package/lib/options-parser.js +498 -0
- package/lib/options-parser.test.js +1237 -0
- package/lib/process-contents.js +330 -0
- package/lib/process-file.js +34 -0
- package/lib/transforms/code.js +67 -22
- package/lib/transforms/file.js +13 -10
- package/lib/transforms/remote.js +9 -6
- package/lib/transforms/toc.js +136 -64
- package/lib/transforms/wordCount.js +5 -0
- package/lib/utils/fs.js +340 -0
- package/lib/utils/fs.test.js +268 -0
- package/lib/utils/html-to-json/compat.js +42 -0
- package/lib/utils/html-to-json/format.js +64 -0
- package/lib/utils/html-to-json/index.js +37 -0
- package/lib/utils/html-to-json/lexer.js +345 -0
- package/lib/utils/html-to-json/parser.js +146 -0
- package/lib/utils/html-to-json/stringify.js +37 -0
- package/lib/utils/html-to-json/tags.js +171 -0
- package/lib/utils/index.js +19 -0
- package/{cli-utils.js → lib/utils/load-config.js} +2 -6
- package/lib/utils/logs.js +89 -0
- package/lib/utils/md/filters.js +20 -0
- package/lib/utils/md/find-code-blocks.js +80 -0
- package/lib/utils/md/find-date.js +32 -0
- package/lib/utils/md/find-frontmatter.js +94 -0
- package/lib/utils/md/find-frontmatter.test.js +17 -0
- package/lib/utils/md/find-html-tags.js +105 -0
- package/lib/utils/md/find-images.js +102 -0
- package/lib/utils/md/find-links.js +202 -0
- package/lib/utils/md/find-unmatched-html-tags.js +33 -0
- package/lib/utils/md/fixtures/2022-01-22-date-in-filename.md +14 -0
- package/lib/utils/md/fixtures/file-with-frontmatter.md +32 -0
- package/lib/utils/md/fixtures/file-with-links.md +143 -0
- package/lib/utils/md/md.test.js +37 -0
- package/lib/utils/md/parse.js +122 -0
- package/lib/utils/md/utils.js +19 -0
- package/lib/utils/regex-timeout.js +83 -0
- package/lib/utils/regex.js +38 -5
- package/lib/utils/remoteRequest.js +54 -0
- package/lib/utils/syntax.js +79 -0
- package/lib/utils/text.js +260 -0
- package/lib/utils/text.test.js +311 -0
- package/package.json +26 -26
- package/index.js +0 -46
- package/lib/processFile.js +0 -154
- package/lib/transforms/index.js +0 -114
- package/lib/updateContents.js +0 -125
- package/lib/utils/_md.test.js +0 -63
- package/lib/utils/new-parser.js +0 -412
- package/lib/utils/weird-parse.js +0 -230
- package/lib/utils/weird-parse.test.js +0 -217
package/lib/transforms/index.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
const code = require('./code')
|
|
2
|
-
const file = require('./file')
|
|
3
|
-
const remoteContent = require('./remote')
|
|
4
|
-
const toc = require('./toc')
|
|
5
|
-
|
|
6
|
-
const transforms = {
|
|
7
|
-
/**
|
|
8
|
-
* ### > TOC
|
|
9
|
-
*
|
|
10
|
-
* Generate table of contents from markdown file
|
|
11
|
-
*
|
|
12
|
-
* **Options:**
|
|
13
|
-
* - `firsth1` - *boolean* - (optional): Show first h1 of doc in table of contents. Default `false`
|
|
14
|
-
* - `collapse` - *boolean* - (optional): Collapse the table of contents in a detail accordian. Default `false`
|
|
15
|
-
* - `collapseText` - *string* - (optional): Text the toc accordian summary
|
|
16
|
-
* - `excludeText` - *string* - (optional): Text to exclude in the table of contents. Default `Table of Contents`
|
|
17
|
-
* - `maxDepth` - *number* - (optional): Max depth of headings. Default 4
|
|
18
|
-
*
|
|
19
|
-
* **Example:**
|
|
20
|
-
* ```md
|
|
21
|
-
* <!-- AUTO-GENERATED-CONTENT:START (TOC) -->
|
|
22
|
-
* toc will be generated here
|
|
23
|
-
* <!-- AUTO-GENERATED-CONTENT:END -->
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* Default `MATCHWORD` is `AUTO-GENERATED-CONTENT`
|
|
27
|
-
*
|
|
28
|
-
* ---
|
|
29
|
-
* @param {string} content The current content of the comment block
|
|
30
|
-
* @param {object} options The options passed in from the comment declaration
|
|
31
|
-
* @return {string} Updated content to place in the content block
|
|
32
|
-
*/
|
|
33
|
-
TOC: toc,
|
|
34
|
-
/**
|
|
35
|
-
* ### > CODE
|
|
36
|
-
*
|
|
37
|
-
* Get code from file or URL and put in markdown
|
|
38
|
-
*
|
|
39
|
-
* **Options:**
|
|
40
|
-
* - `src`: The relative path to the code to pull in, or the `URL` where the raw code lives
|
|
41
|
-
* - `syntax` (optional): Syntax will be inferred by fileType if not specified
|
|
42
|
-
* - `header` (optional): Will add header comment to code snippet. Useful for pointing to relative source directory or adding live doc links
|
|
43
|
-
* - `lines` (optional): a range with lines of code which will then be replaced with code from the file. The line range should be defined as: "lines=*startLine*-*EndLine*" (for example: "lines=22-44"). Please see the example below
|
|
44
|
-
*
|
|
45
|
-
* **Example:**
|
|
46
|
-
* ```md
|
|
47
|
-
* <!-- AUTO-GENERATED-CONTENT:START (CODE:src=./relative/path/to/code.js) -->
|
|
48
|
-
* This content will be dynamically replaced with code from the file
|
|
49
|
-
* <!-- AUTO-GENERATED-CONTENT:END -->
|
|
50
|
-
* ```
|
|
51
|
-
*
|
|
52
|
-
* ```md
|
|
53
|
-
* <!-- AUTO-GENERATED-CONTENT:START (CODE:src=./relative/path/to/code.js&lines=22-44) -->
|
|
54
|
-
* This content will be dynamically replaced with code from the file lines 22 through 44
|
|
55
|
-
* <!-- AUTO-GENERATED-CONTENT:END -->
|
|
56
|
-
* ```
|
|
57
|
-
*
|
|
58
|
-
* Default `MATCHWORD` is `AUTO-GENERATED-CONTENT`
|
|
59
|
-
*
|
|
60
|
-
* ---
|
|
61
|
-
* @param {string} content The current content of the comment block
|
|
62
|
-
* @param {object} options The options passed in from the comment declaration
|
|
63
|
-
* @return {string} Updated inner contents of the comment block
|
|
64
|
-
*/
|
|
65
|
-
CODE: code,
|
|
66
|
-
/**
|
|
67
|
-
* ### > FILE
|
|
68
|
-
*
|
|
69
|
-
* Get local file contents.
|
|
70
|
-
*
|
|
71
|
-
* **Options:**
|
|
72
|
-
* - `src`: The relative path to the file to pull in
|
|
73
|
-
*
|
|
74
|
-
* **Example:**
|
|
75
|
-
* ```md
|
|
76
|
-
* <!-- AUTO-GENERATED-CONTENT:START (FILE:src=./path/to/file) -->
|
|
77
|
-
* This content will be dynamically replaced from the local file
|
|
78
|
-
* <!-- AUTO-GENERATED-CONTENT:END -->
|
|
79
|
-
* ```
|
|
80
|
-
*
|
|
81
|
-
* Default `MATCHWORD` is `AUTO-GENERATED-CONTENT`
|
|
82
|
-
*
|
|
83
|
-
* ---
|
|
84
|
-
* @param {string} content The current content of the comment block
|
|
85
|
-
* @param {object} options The options passed in from the comment declaration
|
|
86
|
-
* @return {string} Updated content to place in the content block
|
|
87
|
-
*/
|
|
88
|
-
FILE: file,
|
|
89
|
-
/**
|
|
90
|
-
* ### > REMOTE
|
|
91
|
-
*
|
|
92
|
-
* Get any remote Data and put in markdown
|
|
93
|
-
*
|
|
94
|
-
* **Options:**
|
|
95
|
-
* - `url`: The URL of the remote content to pull in
|
|
96
|
-
*
|
|
97
|
-
* **Example:**
|
|
98
|
-
* ```md
|
|
99
|
-
* <!-- AUTO-GENERATED-CONTENT:START (REMOTE:url=http://url-to-raw-md-file.md) -->
|
|
100
|
-
* This content will be dynamically replaced from the remote url
|
|
101
|
-
* <!-- AUTO-GENERATED-CONTENT:END -->
|
|
102
|
-
* ```
|
|
103
|
-
*
|
|
104
|
-
* Default `MATCHWORD` is `AUTO-GENERATED-CONTENT`
|
|
105
|
-
*
|
|
106
|
-
* ---
|
|
107
|
-
* @param {string} content The current content of the comment block
|
|
108
|
-
* @param {object} options The options passed in from the comment declaration
|
|
109
|
-
* @return {string} Updated content to place in the content block
|
|
110
|
-
*/
|
|
111
|
-
REMOTE: remoteContent,
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
module.exports = transforms
|
package/lib/updateContents.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
const regexUtils = require('./utils/regex')
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
Update contents between Comment tags
|
|
5
|
-
*/
|
|
6
|
-
module.exports = async function updateContents(block, config) {
|
|
7
|
-
let newContent
|
|
8
|
-
const openingTag = getOpeningTags(block, config)
|
|
9
|
-
const closingTag = getClosingTags(block, config)
|
|
10
|
-
|
|
11
|
-
if (!openingTag.transform) {
|
|
12
|
-
// no transform command return original block
|
|
13
|
-
return block
|
|
14
|
-
}
|
|
15
|
-
const contentStart = openingTag.openTag.length
|
|
16
|
-
const endStart = block.indexOf(closingTag.closeTag, openingTag.openTag.length)
|
|
17
|
-
const originalContent = block.slice(contentStart, endStart).replace(/^\s+|\s+$/g, '')
|
|
18
|
-
|
|
19
|
-
if (openingTag.transform) {
|
|
20
|
-
const cmd = openingTag.transform.cmd
|
|
21
|
-
const cmdOptions = openingTag.transform.cmdOptions || {}
|
|
22
|
-
// check if command exists
|
|
23
|
-
if (cmd && config.transforms && config.transforms[cmd]) {
|
|
24
|
-
let updatedContent = await config.transforms[cmd](originalContent, cmdOptions, config)
|
|
25
|
-
if (typeof updatedContent === 'function') {
|
|
26
|
-
// if plugin has no options defined, invoke it with defaults
|
|
27
|
-
updatedContent = await updatedContent(originalContent, cmdOptions, config)
|
|
28
|
-
}
|
|
29
|
-
newContent = updatedContent
|
|
30
|
-
if (!newContent) {
|
|
31
|
-
console.log(`COMMAND '${cmd}' is returning undefined value. using original content instead. Make sure you return a value from your transform`)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
if (!config.transforms[cmd]) {
|
|
35
|
-
console.warn(`Error '${cmd}' transform function not found in \`config.transforms\``)
|
|
36
|
-
console.warn(`Comment block skipped: <!-- ${config.matchWord}:START (${cmd}) -->`)
|
|
37
|
-
// throw new Error(errMsg)
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// if no transform matches
|
|
42
|
-
if (!newContent) {
|
|
43
|
-
newContent = originalContent
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// If original block or new content contains a new line, preserve it
|
|
47
|
-
if (block.indexOf('\n') > -1 || newContent.indexOf('\n') > -1) {
|
|
48
|
-
return `${openingTag.openTag}
|
|
49
|
-
${newContent}
|
|
50
|
-
${closingTag.closeTag}`
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Block has no newline, inline contents
|
|
54
|
-
return `${openingTag.openTag}${newContent}${closingTag.closeTag}`
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function parseOptions(options) {
|
|
58
|
-
if (!options) {
|
|
59
|
-
return null
|
|
60
|
-
}
|
|
61
|
-
const returnOptions = {}
|
|
62
|
-
options.split('&').map((opt, i) => { // eslint-disable-line
|
|
63
|
-
const getValues = opt.split(/=(.+)/)
|
|
64
|
-
if (getValues[0] && getValues[1]) {
|
|
65
|
-
returnOptions[getValues[0]] = getValues[1]
|
|
66
|
-
}
|
|
67
|
-
})
|
|
68
|
-
return returnOptions
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function processTransforms(hasCommand) {
|
|
72
|
-
const hasOptions = hasCommand[1].match(/([^:]*):(.*)/)
|
|
73
|
-
const cmd = (hasOptions) ? hasOptions[1] : hasCommand[1]
|
|
74
|
-
// no options found, run command with no options
|
|
75
|
-
const cmdOptions = (hasOptions) ? hasOptions[2] : null
|
|
76
|
-
return {
|
|
77
|
-
cmd: cmd,
|
|
78
|
-
cmdOptions: parseOptions(cmdOptions)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function getOpeningTags(block, config) {
|
|
83
|
-
const openTagRegex = regexUtils.matchOpeningCommentTag(config.matchWord)
|
|
84
|
-
let matches
|
|
85
|
-
while ((matches = openTagRegex.exec(block)) !== null) { // eslint-disable-line
|
|
86
|
-
// This is necessary to avoid infinite loops with zero-width matches
|
|
87
|
-
if (matches.index === openTagRegex.lastIndex) {
|
|
88
|
-
openTagRegex.lastIndex++
|
|
89
|
-
}
|
|
90
|
-
/*
|
|
91
|
-
console.log('FULL Open Tag >>>>>', matches[0])
|
|
92
|
-
console.log('openTag Start', "'"+matches[1]+"'");
|
|
93
|
-
console.log('openTag End', "'"+matches[2]+"'");
|
|
94
|
-
/**/
|
|
95
|
-
const hasCommand = matches[0].match(/\((.*)\)/)
|
|
96
|
-
const cmd = (hasCommand) ? processTransforms(hasCommand) : false
|
|
97
|
-
return {
|
|
98
|
-
openTag: matches[0],
|
|
99
|
-
openTagStart: matches[1],
|
|
100
|
-
openTagEnd: matches[2],
|
|
101
|
-
transform: cmd
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function getClosingTags(block, config) {
|
|
107
|
-
const closeTagRegex = regexUtils.matchClosingCommentTag(config.matchWord)
|
|
108
|
-
let matches
|
|
109
|
-
while ((matches = closeTagRegex.exec(block)) !== null) { // eslint-disable-line
|
|
110
|
-
// This is necessary to avoid infinite loops with zero-width matches
|
|
111
|
-
if (matches.index === closeTagRegex.lastIndex) {
|
|
112
|
-
closeTagRegex.lastIndex++
|
|
113
|
-
}
|
|
114
|
-
/*
|
|
115
|
-
console.log('FULL CLOSE Tag >>>>>', matches[0])
|
|
116
|
-
console.log('closeTag Start', "'"+matches[1]+"'");
|
|
117
|
-
console.log('closeTag End', "'"+matches[2]+"'");
|
|
118
|
-
/**/
|
|
119
|
-
return {
|
|
120
|
-
closeTag: matches[1] + matches[2],
|
|
121
|
-
closeTagStart: matches[1],
|
|
122
|
-
closeTagEnd: matches[2]
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
package/lib/utils/_md.test.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
const { test } = require('uvu')
|
|
2
|
-
const assert = require('uvu/assert')
|
|
3
|
-
const { parseBlocks, replaceContent } = require('./new-parser')
|
|
4
|
-
|
|
5
|
-
const defaultOpts = {
|
|
6
|
-
syntax: 'md',
|
|
7
|
-
open: 'DOCS:START',
|
|
8
|
-
close: 'DOCS:END',
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
test('Returns empty array', () => {
|
|
12
|
-
assert.equal(parseBlocks('', defaultOpts).transforms, [])
|
|
13
|
-
assert.equal(parseBlocks(' ', defaultOpts).transforms, [])
|
|
14
|
-
assert.equal(parseBlocks(`
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
`, defaultOpts).transforms, [])
|
|
18
|
-
assert.equal(parseBlocks(`
|
|
19
|
-
# No block in here
|
|
20
|
-
|
|
21
|
-
nope
|
|
22
|
-
`, defaultOpts).transforms, [])
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
const md = `
|
|
26
|
-
Very nice
|
|
27
|
-
|
|
28
|
-
<!-- DOCS:START(TOC) foo={{ rad: 'orange' }} ------>
|
|
29
|
-
ok
|
|
30
|
-
<!-- DOCS:END -->`
|
|
31
|
-
|
|
32
|
-
test('Parse md blocks', () => {
|
|
33
|
-
const parsedValue = parseBlocks(md, defaultOpts)
|
|
34
|
-
console.log('parsedValue', parsedValue)
|
|
35
|
-
assert.equal(parsedValue.transforms, [
|
|
36
|
-
{
|
|
37
|
-
transform: 'TOC',
|
|
38
|
-
args: { foo: { rad: 'orange' } },
|
|
39
|
-
block: {
|
|
40
|
-
indentation: '',
|
|
41
|
-
start: 12,
|
|
42
|
-
end: 85,
|
|
43
|
-
contentStart: 64,
|
|
44
|
-
contentEnd: 68,
|
|
45
|
-
contentIndent: 0,
|
|
46
|
-
openTag: "<!-- DOCS:START(TOC) foo={{ rad: 'orange' }} ------>\n",
|
|
47
|
-
content: 'ok',
|
|
48
|
-
closeTag: '\n<!-- DOCS:END -->'
|
|
49
|
-
},
|
|
50
|
-
raw: {
|
|
51
|
-
transform: '(TOC)',
|
|
52
|
-
args: "foo={{ rad: 'orange' }} ----",
|
|
53
|
-
content: '\nok\n',
|
|
54
|
-
block: "<!-- DOCS:START(TOC) foo={{ rad: 'orange' }} ------>\n" +
|
|
55
|
-
'ok\n' +
|
|
56
|
-
'<!-- DOCS:END -->'
|
|
57
|
-
},
|
|
58
|
-
meta: { isMultiline: true }
|
|
59
|
-
}
|
|
60
|
-
], '')
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
test.run()
|