markdown-magic 3.0.2 → 3.0.4
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 +295 -101
- package/cli.js +4 -1
- package/lib/block-parser.js +32 -28
- package/lib/block-parser.test.js +2 -0
- package/lib/cli.js +101 -22
- package/lib/cli.test.js +12 -12
- package/lib/index.js +418 -119
- package/lib/process-contents.js +59 -23
- package/lib/process-file.js +39 -4
- package/lib/transforms/code.js +33 -10
- package/lib/transforms/file.js +4 -2
- package/lib/transforms/index.js +114 -0
- package/lib/transforms/sectionToc.js +2 -2
- package/lib/transforms/toc.js +22 -4
- package/lib/transforms/wordCount.js +2 -2
- package/lib/utils/fs.js +8 -172
- package/lib/utils/fs.test.js +4 -162
- package/lib/utils/hash-file.js +28 -0
- package/lib/utils/logs.js +16 -2
- package/lib/utils/syntax.js +1 -0
- package/lib/utils/text.js +1 -1
- package/lib/utils/toposort.js +131 -0
- package/package.json +4 -3
- package/lib/globals.d.ts +0 -66
- package/lib/utils/md/filters.js +0 -20
- package/lib/utils/md/find-code-blocks.js +0 -88
- package/lib/utils/md/find-date.js +0 -32
- package/lib/utils/md/find-frontmatter.js +0 -92
- package/lib/utils/md/find-frontmatter.test.js +0 -17
- package/lib/utils/md/find-html-tags.js +0 -105
- package/lib/utils/md/find-images-md.js +0 -27
- package/lib/utils/md/find-images.js +0 -107
- package/lib/utils/md/find-links.js +0 -220
- package/lib/utils/md/find-unmatched-html-tags.js +0 -32
- package/lib/utils/md/fixtures/2022-01-22-date-in-filename.md +0 -14
- package/lib/utils/md/fixtures/file-with-frontmatter.md +0 -32
- package/lib/utils/md/fixtures/file-with-links.md +0 -153
- package/lib/utils/md/md.test.js +0 -105
- package/lib/utils/md/parse.js +0 -146
- package/lib/utils/md/utils.js +0 -19
package/lib/process-contents.js
CHANGED
|
@@ -2,30 +2,48 @@ const { parseBlocks } = require('./block-parser')
|
|
|
2
2
|
const { deepLog } = require('./utils/logs')
|
|
3
3
|
const { getCodeLocation } = require('./utils')
|
|
4
4
|
const { indentString, trimString } = require('./utils/text')
|
|
5
|
-
const { OPEN_WORD, CLOSE_WORD } = require('./defaults')
|
|
5
|
+
const { OPEN_WORD, CLOSE_WORD, SYNTAX } = require('./defaults')
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Configuration object for processing contents.
|
|
9
|
+
* @typedef {Object} ProcessContentConfig
|
|
10
|
+
* @property {string} srcPath - The source path.
|
|
11
|
+
* @property {string} outputPath - The output path.
|
|
12
|
+
* @property {string} [open=OPEN_WORD] - The opening delimiter.
|
|
13
|
+
* @property {string} [close=CLOSE_WORD] - The closing delimiter.
|
|
14
|
+
* @property {string} [syntax='md'] - The syntax type.
|
|
15
|
+
* @property {Array<Function>} [transforms=[]] - The array of transform functions.
|
|
16
|
+
* @property {Array<Function>} [beforeMiddleware=[]] - The array of middleware functions to be executed before processing.
|
|
17
|
+
* @property {Array<Function>} [afterMiddleware=[]] - The array of middleware functions to be executed after processing.
|
|
18
|
+
* @property {boolean} [debug=false] - Enable debug mode.
|
|
19
|
+
* @property {boolean} [removeComments=false] - Remove comments from the processed contents.
|
|
20
|
+
*/
|
|
6
21
|
|
|
7
22
|
/**
|
|
8
23
|
* Pull comment blocks out of content and process them
|
|
9
24
|
* @param {string} text
|
|
10
|
-
* @param {
|
|
25
|
+
* @param {ProcessContentConfig} config
|
|
11
26
|
* @returns
|
|
12
27
|
*/
|
|
13
|
-
|
|
28
|
+
async function processContents(text, config) {
|
|
29
|
+
const opts = config || {}
|
|
30
|
+
|
|
14
31
|
const {
|
|
15
32
|
srcPath,
|
|
16
33
|
outputPath,
|
|
17
34
|
open = OPEN_WORD, // 'DOCS:START',
|
|
18
35
|
close = CLOSE_WORD, // 'DOCS:END',
|
|
19
|
-
syntax = 'md'
|
|
20
|
-
transforms,
|
|
36
|
+
syntax = SYNTAX, // 'md'
|
|
37
|
+
transforms = [],
|
|
21
38
|
beforeMiddleware = [],
|
|
22
39
|
afterMiddleware = [],
|
|
23
40
|
debug = false,
|
|
24
|
-
|
|
41
|
+
removeComments = false
|
|
42
|
+
} = opts
|
|
25
43
|
|
|
26
44
|
/*
|
|
27
|
-
console.log('
|
|
28
|
-
console.log('
|
|
45
|
+
console.log('Open word', open)
|
|
46
|
+
console.log('Close word', close)
|
|
29
47
|
console.log('syntax', syntax)
|
|
30
48
|
// console.log('text', text)
|
|
31
49
|
/** */
|
|
@@ -38,7 +56,7 @@ const { OPEN_WORD, CLOSE_WORD } = require('./defaults')
|
|
|
38
56
|
close,
|
|
39
57
|
})
|
|
40
58
|
} catch (e) {
|
|
41
|
-
throw new Error(`${e.message} in
|
|
59
|
+
throw new Error(`${e.message}\nFix content in ${srcPath}\n`)
|
|
42
60
|
}
|
|
43
61
|
|
|
44
62
|
if (debug) {
|
|
@@ -82,7 +100,7 @@ const { OPEN_WORD, CLOSE_WORD } = require('./defaults')
|
|
|
82
100
|
// }
|
|
83
101
|
// console.log('transformsToRun', transformsToRun)
|
|
84
102
|
let missingTransforms = []
|
|
85
|
-
|
|
103
|
+
let updatedContents = await transformsToRun.reduce(async (contentPromise, originalMatch) => {
|
|
86
104
|
const md = await contentPromise
|
|
87
105
|
/* Apply Before middleware to all transforms */
|
|
88
106
|
const match = await applyMiddleware(originalMatch, md, beforeMiddleware)
|
|
@@ -148,6 +166,7 @@ const { OPEN_WORD, CLOSE_WORD } = require('./defaults')
|
|
|
148
166
|
}
|
|
149
167
|
}
|
|
150
168
|
}, md, afterMiddleware)
|
|
169
|
+
|
|
151
170
|
if (debug) {
|
|
152
171
|
console.log('afterContent', afterContent)
|
|
153
172
|
}
|
|
@@ -161,8 +180,12 @@ const { OPEN_WORD, CLOSE_WORD } = require('./defaults')
|
|
|
161
180
|
const formattedNewContent = (options.noTrim) ? newContent : trimString(newContent)
|
|
162
181
|
// console.log('formattedNewContent', formattedNewContent)
|
|
163
182
|
/* Remove any conflicting imported comments */
|
|
164
|
-
const fix = removeConflictingComments(formattedNewContent,
|
|
165
|
-
//
|
|
183
|
+
const fix = removeConflictingComments(formattedNewContent, COMMENT_OPEN_REGEX, COMMENT_CLOSE_REGEX)
|
|
184
|
+
// console.log('fix', fix)
|
|
185
|
+
if (options.removeComments) {
|
|
186
|
+
// console.log('removeComments', options.removeComments)
|
|
187
|
+
}
|
|
188
|
+
// const fix = stripAllComments(formattedNewContent, foundBlocks.COMMENT_OPEN_REGEX, COMMENT_CLOSE_REGEX)
|
|
166
189
|
|
|
167
190
|
// console.log('COMMENT_CLOSE_REGEX', COMMENT_CLOSE_REGEX)
|
|
168
191
|
// console.log('formattedNewContent', formattedNewContent)
|
|
@@ -175,10 +198,10 @@ const { OPEN_WORD, CLOSE_WORD } = require('./defaults')
|
|
|
175
198
|
return Promise.resolve(newContents)
|
|
176
199
|
}, Promise.resolve(text))
|
|
177
200
|
|
|
178
|
-
if (debug) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
201
|
+
// if (debug) {
|
|
202
|
+
// console.log('Output Markdown')
|
|
203
|
+
// console.log(updatedContents)
|
|
204
|
+
// }
|
|
182
205
|
|
|
183
206
|
/*
|
|
184
207
|
if (missingTransforms.length) {
|
|
@@ -198,22 +221,30 @@ const { OPEN_WORD, CLOSE_WORD } = require('./defaults')
|
|
|
198
221
|
|
|
199
222
|
// console.log('detect slow srcPath', srcPath)
|
|
200
223
|
|
|
224
|
+
const isNewPath = srcPath !== outputPath
|
|
225
|
+
|
|
226
|
+
if (removeComments && !isNewPath) {
|
|
227
|
+
throw new Error('"removeComments" can only be used if "outputPath" option is set. Otherwise this will break doc generation.')
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* Strip block comments from output files */
|
|
231
|
+
const stripComments = isNewPath && removeComments
|
|
232
|
+
|
|
201
233
|
const result = {
|
|
202
234
|
/* Has markdown content changed? */
|
|
203
235
|
isChanged: text !== updatedContents,
|
|
204
|
-
isNewPath
|
|
236
|
+
isNewPath,
|
|
237
|
+
stripComments,
|
|
205
238
|
srcPath,
|
|
206
239
|
outputPath,
|
|
207
240
|
// config,
|
|
208
241
|
transforms: transformsToRun,
|
|
209
242
|
missingTransforms,
|
|
210
243
|
originalContents: text,
|
|
211
|
-
updatedContents
|
|
244
|
+
updatedContents,
|
|
212
245
|
}
|
|
213
|
-
|
|
214
246
|
// console.log('result')
|
|
215
247
|
// deepLog(result)
|
|
216
|
-
|
|
217
248
|
return result
|
|
218
249
|
}
|
|
219
250
|
|
|
@@ -225,15 +256,16 @@ function transformApi(stuff, opts) {
|
|
|
225
256
|
options: stuff.options || {},
|
|
226
257
|
srcPath: stuff.srcPath,
|
|
227
258
|
outputPath: outputPath,
|
|
259
|
+
/* Library settings */
|
|
228
260
|
settings: {
|
|
229
261
|
...rest,
|
|
230
262
|
regex: stuff.regex,
|
|
231
263
|
},
|
|
232
|
-
|
|
233
264
|
// blockContent: stuff.content.value,
|
|
234
|
-
|
|
265
|
+
currentFileContent: stuff.currentContents,
|
|
235
266
|
originalFileContent: stuff.originalContents,
|
|
236
267
|
/* Methods */
|
|
268
|
+
getCurrentContent: () => stuff.currentContents,
|
|
237
269
|
getOriginalContent: () => stuff.originalContents,
|
|
238
270
|
getOriginalBlock: () => stuff,
|
|
239
271
|
getBlockDetails: (content) => {
|
|
@@ -267,6 +299,7 @@ function getDetails({
|
|
|
267
299
|
}) {
|
|
268
300
|
/* Re-parse current file for updated positions */
|
|
269
301
|
const blockData = parseBlocks(contents, opts)
|
|
302
|
+
// console.log('blockData', blockData)
|
|
270
303
|
|
|
271
304
|
const matchingBlocks = blockData.blocks.filter((block) => {
|
|
272
305
|
return block.open.value === openValue
|
|
@@ -298,6 +331,8 @@ function getDetails({
|
|
|
298
331
|
* @returns
|
|
299
332
|
*/
|
|
300
333
|
function removeConflictingComments(content, openPattern, closePattern) {
|
|
334
|
+
// console.log('openPattern', openPattern)
|
|
335
|
+
// console.log('closePattern', closePattern)
|
|
301
336
|
const removeOpen = content.replace(openPattern, '')
|
|
302
337
|
// TODO this probably needs to be a loop for larger blocks
|
|
303
338
|
closePattern.lastIndex = 0; // reset regex
|
|
@@ -311,7 +346,8 @@ function getDetails({
|
|
|
311
346
|
const closeTag = `${hasClose[2]}${hasClose[3] || ''}`
|
|
312
347
|
// console.log('closeTag', closeTag)
|
|
313
348
|
return removeOpen
|
|
314
|
-
.
|
|
349
|
+
.replace(closePattern, '')
|
|
350
|
+
// .replaceAll(closeTag, '')
|
|
315
351
|
/* Trailing new line */
|
|
316
352
|
.replace(/\n$/, '')
|
|
317
353
|
}
|
package/lib/process-file.js
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const isValidFile = require('is-valid-path')
|
|
3
|
-
const { readFile } = require('./utils/fs')
|
|
3
|
+
const { readFile, writeFile } = require('./utils/fs')
|
|
4
4
|
const { processContents } = require('./process-contents')
|
|
5
|
-
// const { OPEN_WORD, CLOSE_WORD } = require('./defaults')
|
|
6
5
|
|
|
7
6
|
async function processFile(opts = {}) {
|
|
8
|
-
const { content, syntax } = opts
|
|
7
|
+
const { content, syntax, outputPath, dryRun, patterns, output = {} } = opts
|
|
8
|
+
const outputDir = output.directory || opts.outputDir
|
|
9
|
+
|
|
10
|
+
let applyTransformsToSource = false
|
|
11
|
+
if (typeof output.applyTransformsToSource !== 'undefined') {
|
|
12
|
+
applyTransformsToSource = output.applyTransformsToSource
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
} else if (typeof opts.applyTransformsToSource !== 'undefined') {
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
applyTransformsToSource = opts.applyTransformsToSource
|
|
17
|
+
}
|
|
18
|
+
|
|
9
19
|
let srcPath = opts.srcPath
|
|
10
20
|
if (srcPath && content) {
|
|
11
21
|
throw new Error(`Can't set both "srcPath" & "content"`)
|
|
@@ -25,11 +35,36 @@ async function processFile(opts = {}) {
|
|
|
25
35
|
if (srcPath && !syntaxType) {
|
|
26
36
|
syntaxType = path.extname(srcPath).replace(/^\./, '')
|
|
27
37
|
}
|
|
28
|
-
|
|
38
|
+
// console.log('processFile order', srcPath)
|
|
39
|
+
|
|
40
|
+
const result = await processContents(fileContents, {
|
|
29
41
|
...opts,
|
|
42
|
+
outputPath,
|
|
30
43
|
srcPath,
|
|
31
44
|
syntax: syntaxType,
|
|
32
45
|
})
|
|
46
|
+
// console.log('result', result)
|
|
47
|
+
|
|
48
|
+
if (dryRun) {
|
|
49
|
+
return result
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (result.isChanged) {
|
|
53
|
+
let cleanContents = result.updatedContents
|
|
54
|
+
if (result.stripComments && patterns.openPattern && patterns.closePattern) {
|
|
55
|
+
cleanContents = result.updatedContents.replace(patterns.openPattern, '').replace(patterns.closePattern, '')
|
|
56
|
+
}
|
|
57
|
+
if (outputDir) {
|
|
58
|
+
// console.log(`- Update output file: ${outputPath}`)
|
|
59
|
+
await writeFile(outputPath, cleanContents)
|
|
60
|
+
}
|
|
61
|
+
if (!outputDir || applyTransformsToSource) {
|
|
62
|
+
// console.log(`- Update source file: ${srcPath}`)
|
|
63
|
+
await writeFile(srcPath, result.updatedContents)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return result
|
|
33
68
|
}
|
|
34
69
|
|
|
35
70
|
module.exports = {
|
package/lib/transforms/code.js
CHANGED
|
@@ -5,17 +5,40 @@ const { isLocalPath } = require('../utils/fs')
|
|
|
5
5
|
const { deepLog } = require('../utils/logs')
|
|
6
6
|
const { getLineCount, getTextBetweenLines } = require('../utils/text')
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Options for specifying source code to include in documentation.
|
|
10
|
+
* @typedef {Object} CodeTransformOptions
|
|
11
|
+
* @property {string} src - The relative path to the code to include, or the URL where the raw code lives.
|
|
12
|
+
* @property {string} [syntax] - The syntax of the code. If not specified, it will be inferred by fileType.
|
|
13
|
+
* @property {string} [header] - The header comment to add to the code snippet. Useful for pointing to relative source directory or adding live doc links.
|
|
14
|
+
* @property {string} [lines] - A range of lines of code to include from the file. The line range should be defined like "lines=22-44".
|
|
15
|
+
* @example
|
|
16
|
+
```md
|
|
17
|
+
<!-- doc-gen CODE src="./relative/path/to/code.js" -->
|
|
18
|
+
This content will be dynamically replaced with code from the file
|
|
19
|
+
<!-- end-doc-gen -->
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```md
|
|
23
|
+
<!-- doc-gen CODE src="./relative/path/to/code.js" lines="22-44" -->
|
|
24
|
+
This content will be dynamically replaced with code from the file lines 22 through 44
|
|
25
|
+
<!-- end-doc-gen -->
|
|
26
|
+
```
|
|
27
|
+
*/
|
|
28
|
+
|
|
8
29
|
// TODO code sections
|
|
9
30
|
// https://github.com/linear/linear/blob/94af540244864fbe466fb933256278e04e87513e/docs/transforms/code-section.js
|
|
10
31
|
// https://github.com/linear/linear/blob/bc39d23af232f9fdbe7df458b0aaa9554ca83c57/packages/sdk/src/_tests/readme.test.ts#L133-L140
|
|
11
32
|
// usage https://github.com/linear/linear/blame/93981d3a3db571e2f8efdce9f5271ea678941c43/packages/sdk/README.md#L1
|
|
12
33
|
|
|
13
34
|
module.exports = function CODE(api) {
|
|
14
|
-
const { content,
|
|
35
|
+
const { content, srcPath } = api
|
|
36
|
+
/** @type {CodeTransformOptions} */
|
|
37
|
+
const options = api.options || {}
|
|
15
38
|
// console.log('CODE API', api)
|
|
16
39
|
// process.exit(1)
|
|
17
40
|
// console.log('options', options)
|
|
18
|
-
const { src, lines } = options
|
|
41
|
+
const { src, lines, id } = options
|
|
19
42
|
const originalContent = content
|
|
20
43
|
let code
|
|
21
44
|
let syntax = options.syntax
|
|
@@ -28,6 +51,7 @@ module.exports = function CODE(api) {
|
|
|
28
51
|
const fileDir = (srcPath) ? path.dirname(srcPath) : process.cwd()
|
|
29
52
|
codeFilePath = path.resolve(fileDir, src)
|
|
30
53
|
try {
|
|
54
|
+
// console.log('READFILE CODE', codeFilePath)
|
|
31
55
|
code = fs.readFileSync(codeFilePath, 'utf8')
|
|
32
56
|
} catch (e) {
|
|
33
57
|
console.log(`FILE NOT FOUND ${codeFilePath}`)
|
|
@@ -70,19 +94,19 @@ module.exports = function CODE(api) {
|
|
|
70
94
|
}
|
|
71
95
|
|
|
72
96
|
/* Check for Id */
|
|
73
|
-
if (
|
|
97
|
+
if (id) {
|
|
74
98
|
const lines = code.split("\n")
|
|
75
|
-
const startLine = lines.findIndex(line => line.includes(`CODE_SECTION:${
|
|
76
|
-
const endLine = lines.findIndex(line => line.includes(`CODE_SECTION:${
|
|
99
|
+
const startLine = lines.findIndex(line => line.includes(`CODE_SECTION:${id}:START`)) ?? 0
|
|
100
|
+
const endLine = lines.findIndex(line => line.includes(`CODE_SECTION:${id}:END`)) ?? lines.length - 1
|
|
77
101
|
// console.log('startLine', startLine)
|
|
78
102
|
// console.log('endLineendLine', endLine)
|
|
79
103
|
if (startLine === -1 && endLine === -1) {
|
|
80
|
-
throw new Error(`Missing ${
|
|
104
|
+
throw new Error(`Missing ${id} code section from ${codeFilePath}`)
|
|
81
105
|
}
|
|
82
106
|
|
|
83
|
-
const selectedLines = lines.slice(startLine + 1, endLine)
|
|
107
|
+
const selectedLines = lines.slice(startLine + 1, endLine)
|
|
84
108
|
|
|
85
|
-
const trimBy = selectedLines[0]?.match(/^(\s*)/)?.[1]?.length
|
|
109
|
+
const trimBy = selectedLines[0]?.match(/^(\s*)/)?.[1]?.length
|
|
86
110
|
const newValue = `${selectedLines.map(line => line.substring(trimBy).replace(/^\/\/ CODE_SECTION:INCLUDE /g, "")).join("\n")}`
|
|
87
111
|
// console.log('newValue', newValue)
|
|
88
112
|
code = newValue
|
|
@@ -96,8 +120,7 @@ module.exports = function CODE(api) {
|
|
|
96
120
|
header = `\n${options.header}`
|
|
97
121
|
}
|
|
98
122
|
|
|
99
|
-
return
|
|
100
|
-
\`\`\`${syntax}${header}
|
|
123
|
+
return `\`\`\`${syntax}${header}
|
|
101
124
|
${code}
|
|
102
125
|
\`\`\``
|
|
103
126
|
}
|
package/lib/transforms/file.js
CHANGED
|
@@ -5,8 +5,7 @@ const isLocalPath = require('is-local-path')
|
|
|
5
5
|
module.exports = function FILE(api) {
|
|
6
6
|
/*
|
|
7
7
|
console.log('FILE API', api)
|
|
8
|
-
|
|
9
|
-
process.exit(1)
|
|
8
|
+
|
|
10
9
|
/** */
|
|
11
10
|
const { options, srcPath } = api
|
|
12
11
|
if (!options.src) {
|
|
@@ -17,6 +16,7 @@ module.exports = function FILE(api) {
|
|
|
17
16
|
const fileDir = path.dirname(srcPath)
|
|
18
17
|
const resolvedFilePath = path.resolve(fileDir, options.src)
|
|
19
18
|
try {
|
|
19
|
+
// console.log('READFILE', resolvedFilePath)
|
|
20
20
|
fileContents = fs.readFileSync(resolvedFilePath, 'utf8')
|
|
21
21
|
} catch (e) {
|
|
22
22
|
console.log(`FILE NOT FOUND ${resolvedFilePath}`)
|
|
@@ -27,6 +27,8 @@ module.exports = function FILE(api) {
|
|
|
27
27
|
// trim leading and trailing spaces/line breaks in code and keeps the indentation of the first non-empty line
|
|
28
28
|
fileContents = fileContents.replace(/^(?:[\t ]*(?:\r?\n|\r))+|\s+$/g, '')
|
|
29
29
|
|
|
30
|
+
return fileContents
|
|
31
|
+
|
|
30
32
|
return `<!-- The below content is automatically added from ${options.src} -->
|
|
31
33
|
${fileContents}`
|
|
32
34
|
}
|
package/lib/transforms/index.js
CHANGED
|
@@ -0,0 +1,114 @@
|
|
|
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
|
+
* <!-- doc-gen (TOC) -->
|
|
22
|
+
* toc will be generated here
|
|
23
|
+
* <!-- end-doc-gen -->
|
|
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
|
+
* <!-- doc-gen (CODE:src=./relative/path/to/code.js) -->
|
|
48
|
+
* This content will be dynamically replaced with code from the file
|
|
49
|
+
* <!-- end-doc-gen -->
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* ```md
|
|
53
|
+
* <!-- doc-gen (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
|
+
* <!-- end-doc-gen -->
|
|
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
|
+
* <!-- doc-gen (FILE:src=./path/to/file) -->
|
|
77
|
+
* This content will be dynamically replaced from the local file
|
|
78
|
+
* <!-- end-doc-gen -->
|
|
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
|
+
* <!-- doc-gen (REMOTE:url=http://url-to-raw-md-file.md) -->
|
|
100
|
+
* This content will be dynamically replaced from the remote url
|
|
101
|
+
* <!-- end-doc-gen -->
|
|
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
|
|
@@ -2,7 +2,7 @@ const { generateToc } = require('../utils/toc')
|
|
|
2
2
|
|
|
3
3
|
module.exports = async function sectionToc(api) {
|
|
4
4
|
// console.log("sectionToc", api)
|
|
5
|
-
const { options,
|
|
5
|
+
const { options, currentFileContent, srcPath, getBlockDetails } = api
|
|
6
6
|
const opts = options || {}
|
|
7
7
|
const subToc = await generateToc({
|
|
8
8
|
options: {
|
|
@@ -10,7 +10,7 @@ module.exports = async function sectionToc(api) {
|
|
|
10
10
|
// Set sub table of contents
|
|
11
11
|
sub: true
|
|
12
12
|
},
|
|
13
|
-
fileContent,
|
|
13
|
+
fileContent: currentFileContent,
|
|
14
14
|
srcPath,
|
|
15
15
|
getBlockDetails: getBlockDetails
|
|
16
16
|
})
|
package/lib/transforms/toc.js
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
1
|
const { generateToc } = require('../utils/toc')
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Options for configuring the table of contents.
|
|
5
|
+
* @typedef {Object} ToCTransformOptions
|
|
6
|
+
* @property {boolean} [firsth1=false] - Show the first h1 of the document in the table of contents. Default is `false`.
|
|
7
|
+
* @property {boolean} [collapse=false] - Collapse the table of contents in a detail accordion. Default is `false`.
|
|
8
|
+
* @property {string} [collapseText] - Text for the summary of the table of contents accordion.
|
|
9
|
+
* @property {string} [excludeText="Table of Contents"] - Text to exclude in the table of contents. Default is `Table of Contents`.
|
|
10
|
+
* @property {number} [maxDepth=4] - Maximum depth of headings to include in the table of contents. Default is `4`.
|
|
11
|
+
* @example
|
|
12
|
+
```md
|
|
13
|
+
<!-- doc-gen (TOC) -->
|
|
14
|
+
toc will be generated here
|
|
15
|
+
<!-- end-doc-gen -->
|
|
16
|
+
```
|
|
17
|
+
*/
|
|
18
|
+
|
|
3
19
|
module.exports = async function TOC(api) {
|
|
4
20
|
// console.log("TOC API", api)
|
|
5
|
-
const {
|
|
21
|
+
const { currentFileContent, srcPath, getBlockDetails } = api
|
|
22
|
+
/** @type {ToCTransformOptions} */
|
|
23
|
+
const options = api.options || {}
|
|
6
24
|
const toc = await generateToc({
|
|
7
|
-
options
|
|
8
|
-
fileContent,
|
|
25
|
+
options,
|
|
9
26
|
srcPath,
|
|
10
|
-
getBlockDetails: getBlockDetails
|
|
27
|
+
getBlockDetails: getBlockDetails,
|
|
28
|
+
fileContent: currentFileContent,
|
|
11
29
|
})
|
|
12
30
|
return toc
|
|
13
31
|
}
|