markdown-magic 3.5.0 → 3.6.2
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/cli.js +0 -0
- package/package.json +1 -1
- package/src/cli.js +0 -0
- package/src/index.js +3 -1
- package/src/transforms/code/index.js +15 -3
- package/src/transforms/file.js +6 -23
- package/src/transforms/index.js +27 -0
- package/src/transforms/install.js +72 -0
- package/src/transforms/remote.js +13 -1
- package/src/utils/format-md.js +33 -0
- package/src/utils/text.js +7 -2
- package/package-lock.json +0 -1127
- package/src/.DS_Store +0 -0
- package/src/utils/.DS_Store +0 -0
package/cli.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
File without changes
|
package/src/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const tocTransform = require('./transforms/toc')
|
|
|
9
9
|
const sectionTocTransform = require('./transforms/sectionToc')
|
|
10
10
|
const wordCountTransform = require('./transforms/wordCount')
|
|
11
11
|
const remoteTransform = require('./transforms/remote')
|
|
12
|
+
const installTransform = require('./transforms/install')
|
|
12
13
|
const { getSyntaxInfo } = require('./utils/syntax')
|
|
13
14
|
const { onlyUnique, getCodeLocation, pluralize } = require('./utils')
|
|
14
15
|
const { readFile, resolveOutputPath, resolveFlatPath } = require('./utils/fs')
|
|
@@ -34,7 +35,8 @@ const defaultTransforms = {
|
|
|
34
35
|
TOC: tocTransform,
|
|
35
36
|
sectionToc: sectionTocTransform,
|
|
36
37
|
wordCount: wordCountTransform,
|
|
37
|
-
remote: remoteTransform
|
|
38
|
+
remote: remoteTransform,
|
|
39
|
+
install: installTransform,
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
const defaultOptions = {
|
|
@@ -3,7 +3,13 @@ const path = require('path')
|
|
|
3
3
|
const { remoteRequest } = require('../../utils/remoteRequest')
|
|
4
4
|
const { isLocalPath } = require('../../utils/fs')
|
|
5
5
|
const { deepLog } = require('../../utils/logs')
|
|
6
|
-
const {
|
|
6
|
+
const {
|
|
7
|
+
getLineCount,
|
|
8
|
+
getTextBetweenLines,
|
|
9
|
+
stripMultiLineDoubleSlashComments,
|
|
10
|
+
stripSingleLineDoubleSlashComments,
|
|
11
|
+
stripHTMLComments
|
|
12
|
+
} = require('../../utils/text')
|
|
7
13
|
const { resolveGithubContents, isGithubLink } = require('./resolve-github-file')
|
|
8
14
|
|
|
9
15
|
const GITHUB_LINK = /https:\/\/github\.com\/([^/\s]*)\/([^/\s]*)\/blob\//
|
|
@@ -158,7 +164,7 @@ module.exports = async function CODE(api) {
|
|
|
158
164
|
const endLineIndex = lines.findIndex(line => line.includes(`CODE_SECTION:${id}:END`));
|
|
159
165
|
const endLine = endLineIndex !== -1 ? endLineIndex : lines.length - 1;
|
|
160
166
|
// console.log('startLine', startLine)
|
|
161
|
-
// console.log('
|
|
167
|
+
// console.log('endLine', endLine)
|
|
162
168
|
if (startLine === -1 && endLine === -1) {
|
|
163
169
|
throw new Error(`Missing ${id} code section from ${codeFilePath}`)
|
|
164
170
|
}
|
|
@@ -179,10 +185,16 @@ module.exports = async function CODE(api) {
|
|
|
179
185
|
if (options.header) {
|
|
180
186
|
header = `\n${options.header}`
|
|
181
187
|
}
|
|
188
|
+
|
|
189
|
+
if (options.trimSingleLineComments) {
|
|
190
|
+
if (syntax === 'js' || syntax === 'ts' || syntax === 'javascript' || syntax === 'typescript') {
|
|
191
|
+
code = stripSingleLineDoubleSlashComments(code)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
182
194
|
|
|
183
195
|
if (options.trimDeadCode) {
|
|
184
196
|
if (syntax === 'js' || syntax === 'ts' || syntax === 'javascript' || syntax === 'typescript') {
|
|
185
|
-
code =
|
|
197
|
+
code = stripMultiLineDoubleSlashComments(code)
|
|
186
198
|
} else if (syntax === 'html') {
|
|
187
199
|
code = stripHTMLComments(code, { multilineOnly: true })
|
|
188
200
|
}
|
package/src/transforms/file.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const fs = require('fs')
|
|
3
3
|
const isLocalPath = require('is-local-path')
|
|
4
|
-
const {
|
|
5
|
-
const { removeLeadingH1 } = require('@davidwells/md-utils/string-utils')
|
|
4
|
+
const { formatMd } = require('../utils/format-md')
|
|
6
5
|
|
|
7
6
|
module.exports = function FILE(api) {
|
|
8
7
|
/*
|
|
@@ -32,27 +31,11 @@ module.exports = function FILE(api) {
|
|
|
32
31
|
// trim leading and trailing spaces/line breaks in code and keeps the indentation of the first non-empty line
|
|
33
32
|
fileContents = fileContents.replace(/^(?:[\t ]*(?:\r?\n|\r))+|\s+$/g, '')
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// Shift headers up or down by the specified number of levels if shiftHeaders is enabled and file is markdown
|
|
41
|
-
if (options.shiftHeaders && isMarkdown) {
|
|
42
|
-
fileContents = fileContents.replace(/^(#{1,6})\s/gm, (match, hashes) => {
|
|
43
|
-
const currentLevel = hashes.length;
|
|
44
|
-
const shiftAmount = options.shiftHeaders;
|
|
45
|
-
const newLevel = Math.max(1, Math.min(6, currentLevel + shiftAmount));
|
|
46
|
-
return '#'.repeat(newLevel) + ' ';
|
|
47
|
-
})
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/* automatically trim frontmatter if file is markdown */
|
|
51
|
-
if (isMarkdown && options.trimFrontmatter !== false) {
|
|
52
|
-
const frontmatter = findFrontmatter(fileContents)
|
|
53
|
-
if (frontmatter && frontmatter.frontMatterRaw) {
|
|
54
|
-
fileContents = fileContents.replace(frontmatter.frontMatterRaw, '')
|
|
55
|
-
}
|
|
34
|
+
const ext = path.extname(options.src).toLowerCase()
|
|
35
|
+
const isMarkdown = ext === '.md' || ext === '.markdown' || ext === '.mdown' || ext === '.mdx'
|
|
36
|
+
|
|
37
|
+
if (isMarkdown) {
|
|
38
|
+
fileContents = formatMd(fileContents, options)
|
|
56
39
|
}
|
|
57
40
|
|
|
58
41
|
if (options.textBefore) {
|
package/src/transforms/index.js
CHANGED
|
@@ -3,6 +3,7 @@ const file = require('./file')
|
|
|
3
3
|
const remoteContent = require('./remote')
|
|
4
4
|
const toc = require('./toc')
|
|
5
5
|
const sectionToc = require('./sectionToc')
|
|
6
|
+
const install = require('./install')
|
|
6
7
|
|
|
7
8
|
const transforms = {
|
|
8
9
|
/**
|
|
@@ -111,6 +112,32 @@ const transforms = {
|
|
|
111
112
|
* @return {string} Updated content to place in the content block
|
|
112
113
|
*/
|
|
113
114
|
REMOTE: remoteContent,
|
|
115
|
+
/**
|
|
116
|
+
* ### > install
|
|
117
|
+
*
|
|
118
|
+
* Generate installation instructions in a markdown table format
|
|
119
|
+
*
|
|
120
|
+
* **Options:**
|
|
121
|
+
* - `packageName` (optional): The name of the package to install. If not provided, will try to read from package.json
|
|
122
|
+
* - `isDev` (optional): Whether to install the package as a dev dependency. Default `false`
|
|
123
|
+
* - `header` (optional): The header to use for the installation instructions. Default `# Installation`
|
|
124
|
+
* - `body` (optional): The body to use for the installation instructions. Default `Install the \`${packageName}\` cli using your favorite package manager.`
|
|
125
|
+
*
|
|
126
|
+
* **Example:**
|
|
127
|
+
* ```md
|
|
128
|
+
* <!-- doc-gen install -->
|
|
129
|
+
* Installation instructions will be generated here
|
|
130
|
+
* <!-- end-doc-gen -->
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* Default `matchWord` is `doc-gen`
|
|
134
|
+
*
|
|
135
|
+
* ---
|
|
136
|
+
* @param {string} content The current content of the comment block
|
|
137
|
+
* @param {object} options The options passed in from the comment declaration
|
|
138
|
+
* @return {string} Updated content to place in the content block
|
|
139
|
+
*/
|
|
140
|
+
install: install,
|
|
114
141
|
}
|
|
115
142
|
|
|
116
143
|
module.exports = transforms
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ### > INSTALL
|
|
6
|
+
*
|
|
7
|
+
* Generate installation instructions in a markdown table format
|
|
8
|
+
*
|
|
9
|
+
* **Options:**
|
|
10
|
+
* - `packageName` (optional): The name of the package to install. If not provided, will try to read from package.json
|
|
11
|
+
*
|
|
12
|
+
* **Example:**
|
|
13
|
+
* ```md
|
|
14
|
+
* <!-- doc-gen INSTALL packageName=my-package -->
|
|
15
|
+
* Installation instructions will be generated here
|
|
16
|
+
* <!-- end-doc-gen -->
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Default `matchWord` is `doc-gen`
|
|
20
|
+
*
|
|
21
|
+
* ---
|
|
22
|
+
* @param {string} content The current content of the comment block
|
|
23
|
+
* @param {object} options The options passed in from the comment declaration
|
|
24
|
+
* @return {string} Updated content to place in the content block
|
|
25
|
+
*/
|
|
26
|
+
function install(api) {
|
|
27
|
+
console.log('INSTALL API', api)
|
|
28
|
+
const { options } = api
|
|
29
|
+
const { isDev = false } = options
|
|
30
|
+
let packageName = options.packageName
|
|
31
|
+
|
|
32
|
+
// If no package name provided, try to read from package.json
|
|
33
|
+
if (!packageName) {
|
|
34
|
+
try {
|
|
35
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json')
|
|
36
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
|
|
37
|
+
packageName = packageJson.name
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.log('Could not read package.json:', error.message)
|
|
40
|
+
return 'Error: No package name provided and could not read from package.json'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let header = '# Installation'
|
|
45
|
+
if (options.header) {
|
|
46
|
+
header = (options.header.startsWith('#')) ? options.header : `# ${options.header}`
|
|
47
|
+
}
|
|
48
|
+
header = `${header}\n\n`
|
|
49
|
+
|
|
50
|
+
let body = `Install the \`${packageName}\` cli using your favorite package manager.`
|
|
51
|
+
if (options.body) {
|
|
52
|
+
body = (options.body.startsWith('\n')) ? options.body : `\n${options.body}`
|
|
53
|
+
}
|
|
54
|
+
body = `${body}\n`
|
|
55
|
+
|
|
56
|
+
if (!packageName) {
|
|
57
|
+
return 'Error: No package name provided'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const flag = isDev ? ' -D' : ' '
|
|
61
|
+
const space = isDev ? ' ' : ''
|
|
62
|
+
|
|
63
|
+
return `${header}${body}
|
|
64
|
+
| package manager | command |
|
|
65
|
+
| --------------- | ------- |
|
|
66
|
+
| npm | \`npm install ${packageName}${flag}\` |
|
|
67
|
+
| pnpm | \`pnpm add ${packageName}${flag}\` |
|
|
68
|
+
| yarn | \`yarn add ${packageName}${flag}\` |
|
|
69
|
+
| bun | \`bun install ${packageName}\`${space} |`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = install
|
package/src/transforms/remote.js
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
|
+
const path = require('path')
|
|
1
2
|
const { remoteRequest } = require('../utils/remoteRequest')
|
|
3
|
+
const { formatMd } = require('../utils/format-md')
|
|
2
4
|
|
|
3
5
|
module.exports = async function REMOTE(api) {
|
|
4
6
|
// console.log('REMOTE api', api)
|
|
5
7
|
const { options, content, settings } = api
|
|
6
8
|
const { regex } = settings
|
|
9
|
+
const remoteUrl = options.url || options.src || options.URL || options.Url
|
|
7
10
|
|
|
8
11
|
// console.log('MAKE REMOTE REQUEST')
|
|
9
|
-
|
|
12
|
+
let remoteContent = await remoteRequest(remoteUrl, settings, api.srcPath)
|
|
10
13
|
if (!remoteContent) {
|
|
11
14
|
return content
|
|
12
15
|
}
|
|
16
|
+
|
|
17
|
+
const ext = path.extname(remoteUrl).toLowerCase()
|
|
18
|
+
const isMarkdown = ext === '.md' || ext === '.markdown' || ext === '.mdown' || ext === '.mdx'
|
|
19
|
+
|
|
20
|
+
if (isMarkdown) {
|
|
21
|
+
remoteContent = formatMd(remoteContent, options)
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
if (options.keepComments) {
|
|
14
25
|
return remoteContent
|
|
15
26
|
}
|
|
27
|
+
|
|
16
28
|
// console.log('REMOTE', remoteContent)
|
|
17
29
|
return remoteContent.replace(regex.open, '').replace(regex.close, '')
|
|
18
30
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const { findFrontmatter } = require('@davidwells/md-utils/find-frontmatter')
|
|
2
|
+
const { removeLeadingH1 } = require('@davidwells/md-utils/string-utils')
|
|
3
|
+
|
|
4
|
+
function formatMd(content, options = {}) {
|
|
5
|
+
let fileContents = content
|
|
6
|
+
if (options.removeLeadingH1 || options.stripFirstH1) {
|
|
7
|
+
fileContents = removeLeadingH1(fileContents)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Shift headers up or down by the specified number of levels if shiftHeaders is enabled and file is markdown
|
|
11
|
+
if (options.shiftHeaders) {
|
|
12
|
+
fileContents = fileContents.replace(/^(#{1,6})\s/gm, (match, hashes) => {
|
|
13
|
+
const currentLevel = hashes.length;
|
|
14
|
+
const shiftAmount = Number(options.shiftHeaders);
|
|
15
|
+
const newLevel = Math.max(1, Math.min(6, currentLevel + shiftAmount));
|
|
16
|
+
return '#'.repeat(newLevel) + ' ';
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* automatically trim frontmatter if file is markdown */
|
|
21
|
+
if (options.trimFrontmatter !== false) {
|
|
22
|
+
const frontmatter = findFrontmatter(fileContents)
|
|
23
|
+
if (frontmatter && frontmatter.frontMatterRaw) {
|
|
24
|
+
fileContents = fileContents.replace(frontmatter.frontMatterRaw, '')
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return fileContents
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
formatMd
|
|
33
|
+
}
|
package/src/utils/text.js
CHANGED
|
@@ -197,10 +197,14 @@ function stripComments(str, syntax = 'md') {
|
|
|
197
197
|
|
|
198
198
|
|
|
199
199
|
// https://regex101.com/r/nCnt2J/1
|
|
200
|
-
function
|
|
200
|
+
function stripMultiLineDoubleSlashComments(str = '') {
|
|
201
201
|
return str.replace(/(?:\n\s*\/\/.*){2,}/g, '')
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
function stripSingleLineDoubleSlashComments(str = '') {
|
|
205
|
+
return str.replace(/\/\/.*$/gm, '')
|
|
206
|
+
}
|
|
207
|
+
|
|
204
208
|
// https://regex101.com/r/plpXmr/1
|
|
205
209
|
function stripOutMultilineJsComments(str = '') {
|
|
206
210
|
return str.replace(/\/\*[\s\S]+?\*\/\s*\n?/g, (match) => {
|
|
@@ -351,7 +355,8 @@ module.exports = {
|
|
|
351
355
|
dedentString,
|
|
352
356
|
stripComments,
|
|
353
357
|
convertCommentSyntax,
|
|
354
|
-
|
|
358
|
+
stripSingleLineDoubleSlashComments,
|
|
359
|
+
stripMultiLineDoubleSlashComments,
|
|
355
360
|
stripHTMLComments,
|
|
356
361
|
// stripCommentBlockJS,
|
|
357
362
|
trimString,
|