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.
Files changed (61) hide show
  1. package/README.md +6 -10
  2. package/cli.js +5 -82
  3. package/lib/block-parser-js.test.js +179 -0
  4. package/lib/block-parser.js +389 -0
  5. package/lib/{utils/new-parser.test.js → block-parser.test.js} +168 -50
  6. package/lib/cli.js +234 -0
  7. package/lib/cli.test.js +409 -0
  8. package/lib/defaults.js +12 -0
  9. package/lib/index.js +319 -184
  10. package/lib/index.test.js +11 -0
  11. package/lib/options-parser.js +498 -0
  12. package/lib/options-parser.test.js +1237 -0
  13. package/lib/process-contents.js +330 -0
  14. package/lib/process-file.js +34 -0
  15. package/lib/transforms/code.js +67 -22
  16. package/lib/transforms/file.js +13 -10
  17. package/lib/transforms/remote.js +9 -6
  18. package/lib/transforms/toc.js +136 -64
  19. package/lib/transforms/wordCount.js +5 -0
  20. package/lib/utils/fs.js +340 -0
  21. package/lib/utils/fs.test.js +268 -0
  22. package/lib/utils/html-to-json/compat.js +42 -0
  23. package/lib/utils/html-to-json/format.js +64 -0
  24. package/lib/utils/html-to-json/index.js +37 -0
  25. package/lib/utils/html-to-json/lexer.js +345 -0
  26. package/lib/utils/html-to-json/parser.js +146 -0
  27. package/lib/utils/html-to-json/stringify.js +37 -0
  28. package/lib/utils/html-to-json/tags.js +171 -0
  29. package/lib/utils/index.js +19 -0
  30. package/{cli-utils.js → lib/utils/load-config.js} +2 -6
  31. package/lib/utils/logs.js +89 -0
  32. package/lib/utils/md/filters.js +20 -0
  33. package/lib/utils/md/find-code-blocks.js +80 -0
  34. package/lib/utils/md/find-date.js +32 -0
  35. package/lib/utils/md/find-frontmatter.js +94 -0
  36. package/lib/utils/md/find-frontmatter.test.js +17 -0
  37. package/lib/utils/md/find-html-tags.js +105 -0
  38. package/lib/utils/md/find-images.js +102 -0
  39. package/lib/utils/md/find-links.js +202 -0
  40. package/lib/utils/md/find-unmatched-html-tags.js +33 -0
  41. package/lib/utils/md/fixtures/2022-01-22-date-in-filename.md +14 -0
  42. package/lib/utils/md/fixtures/file-with-frontmatter.md +32 -0
  43. package/lib/utils/md/fixtures/file-with-links.md +143 -0
  44. package/lib/utils/md/md.test.js +37 -0
  45. package/lib/utils/md/parse.js +122 -0
  46. package/lib/utils/md/utils.js +19 -0
  47. package/lib/utils/regex-timeout.js +83 -0
  48. package/lib/utils/regex.js +38 -5
  49. package/lib/utils/remoteRequest.js +54 -0
  50. package/lib/utils/syntax.js +79 -0
  51. package/lib/utils/text.js +260 -0
  52. package/lib/utils/text.test.js +311 -0
  53. package/package.json +26 -26
  54. package/index.js +0 -46
  55. package/lib/processFile.js +0 -154
  56. package/lib/transforms/index.js +0 -114
  57. package/lib/updateContents.js +0 -125
  58. package/lib/utils/_md.test.js +0 -63
  59. package/lib/utils/new-parser.js +0 -412
  60. package/lib/utils/weird-parse.js +0 -230
  61. package/lib/utils/weird-parse.test.js +0 -217
@@ -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
@@ -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
- }
@@ -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()