markdown-magic 4.1.0 → 4.5.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/package.json +5 -5
- package/src/cli-run.js +30 -17
- package/src/index.js +12 -4
- package/src/transforms/code/index.js +3 -2
- package/src/transforms/file.js +9 -2
- package/src/utils/fs.js +24 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markdown-magic",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"description": "Automatically update markdown files with content from external sources",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@davidwells/md-utils": "0.0.53",
|
|
44
44
|
"color-convert": "^2.0.1",
|
|
45
|
-
"comment-block-parser": "1.
|
|
46
|
-
"comment-block-replacer": "0.1.
|
|
47
|
-
"comment-block-transformer": "0.
|
|
45
|
+
"comment-block-parser": "1.4.0",
|
|
46
|
+
"comment-block-replacer": "0.1.8",
|
|
47
|
+
"comment-block-transformer": "0.5.0",
|
|
48
48
|
"globrex": "^0.1.2",
|
|
49
49
|
"gray-matter": "^4.0.3",
|
|
50
50
|
"is-glob": "^4.0.3",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "7329dd17e21dea4551f995fa85a5f843c08f9109"
|
|
74
74
|
}
|
package/src/cli-run.js
CHANGED
|
@@ -60,6 +60,18 @@ function interpretEscapes(str) {
|
|
|
60
60
|
return str.replace(/\\n/g, '\n').replace(/\\t/g, '\t')
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
/**
|
|
64
|
+
* JSON.stringify replacer that handles RegExp objects
|
|
65
|
+
* @param {string} key
|
|
66
|
+
* @param {any} value
|
|
67
|
+
*/
|
|
68
|
+
function jsonReplacer(key, value) {
|
|
69
|
+
if (value instanceof RegExp) {
|
|
70
|
+
return value.toString()
|
|
71
|
+
}
|
|
72
|
+
return value
|
|
73
|
+
}
|
|
74
|
+
|
|
63
75
|
/**
|
|
64
76
|
* Check if string looks like markdown content vs a file path
|
|
65
77
|
* @param {string} str
|
|
@@ -103,6 +115,7 @@ Options:
|
|
|
103
115
|
--output Output directory
|
|
104
116
|
--open Opening comment keyword (default: docs)
|
|
105
117
|
--close Closing comment keyword (default: /docs)
|
|
118
|
+
--json Output full result as JSON
|
|
106
119
|
--pretty Render output with ANSI styling
|
|
107
120
|
--dry Dry run - show what would be changed
|
|
108
121
|
--debug Show debug output
|
|
@@ -130,7 +143,12 @@ Stdin/stdout mode:
|
|
|
130
143
|
}
|
|
131
144
|
|
|
132
145
|
// Check if first positional arg is markdown content (before stdin check)
|
|
133
|
-
|
|
146
|
+
// Handle case where mri assigns content to a flag (e.g., --json '# content')
|
|
147
|
+
let firstArg = options._ && options._[0]
|
|
148
|
+
const outputJson = options.json === true || (typeof options.json === 'string' && isMarkdownContent(options.json))
|
|
149
|
+
if (typeof options.json === 'string' && isMarkdownContent(options.json)) {
|
|
150
|
+
firstArg = options.json
|
|
151
|
+
}
|
|
134
152
|
const openKeyword = options.open || 'docs'
|
|
135
153
|
const closeKeyword = options.close || (options.open && options.open !== 'docs' ? `/${options.open}` : '/docs')
|
|
136
154
|
if (firstArg && isMarkdownContent(firstArg)) {
|
|
@@ -143,14 +161,12 @@ Stdin/stdout mode:
|
|
|
143
161
|
transforms: defaultTransforms,
|
|
144
162
|
dryRun: true,
|
|
145
163
|
})
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
// }
|
|
153
|
-
console.log(result.updatedContents)
|
|
164
|
+
console.log('result', result)
|
|
165
|
+
if (outputJson) {
|
|
166
|
+
console.log(JSON.stringify(result, jsonReplacer, 2))
|
|
167
|
+
} else {
|
|
168
|
+
console.log(result.updatedContents)
|
|
169
|
+
}
|
|
154
170
|
return
|
|
155
171
|
}
|
|
156
172
|
|
|
@@ -168,14 +184,11 @@ Stdin/stdout mode:
|
|
|
168
184
|
transforms: defaultTransforms,
|
|
169
185
|
dryRun: true, // Don't write files
|
|
170
186
|
})
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
// console.log(result.updatedContents)
|
|
177
|
-
// }
|
|
178
|
-
console.log(result.updatedContents)
|
|
187
|
+
if (outputJson) {
|
|
188
|
+
console.log(JSON.stringify(result, jsonReplacer, 2))
|
|
189
|
+
} else {
|
|
190
|
+
console.log(result.updatedContents)
|
|
191
|
+
}
|
|
179
192
|
return
|
|
180
193
|
}
|
|
181
194
|
}
|
package/src/index.js
CHANGED
|
@@ -13,7 +13,7 @@ const remoteTransform = require('./transforms/remote')
|
|
|
13
13
|
const installTransform = require('./transforms/install')
|
|
14
14
|
const { getSyntaxInfo } = require('./utils/syntax')
|
|
15
15
|
const { onlyUnique, getCodeLocation, pluralize } = require('./utils')
|
|
16
|
-
const { readFile, resolveOutputPath, resolveFlatPath } = require('./utils/fs')
|
|
16
|
+
const { readFile, resolveOutputPath, resolveFlatPath, hasIgnoreFile } = require('./utils/fs')
|
|
17
17
|
const stringBreak = require('./utils/string-break')
|
|
18
18
|
const { processFile } = require('comment-block-replacer')
|
|
19
19
|
const { blockTransformer } = require('comment-block-transformer')
|
|
@@ -257,7 +257,10 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
|
|
|
257
257
|
|
|
258
258
|
let files = []
|
|
259
259
|
try {
|
|
260
|
-
files = (await Promise.all(pathsPromise))
|
|
260
|
+
files = (await Promise.all(pathsPromise))
|
|
261
|
+
.flat()
|
|
262
|
+
.filter(onlyUnique)
|
|
263
|
+
.filter((f) => !hasIgnoreFile(f))
|
|
261
264
|
// opts.files = files
|
|
262
265
|
} catch (e) {
|
|
263
266
|
// console.log(e.message)
|
|
@@ -311,6 +314,7 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
|
|
|
311
314
|
syntax,
|
|
312
315
|
open,
|
|
313
316
|
close,
|
|
317
|
+
firstArgIsType: true,
|
|
314
318
|
})
|
|
315
319
|
// console.log('foundBlocks', foundBlocks.blocks.length)
|
|
316
320
|
} catch (e) {
|
|
@@ -541,12 +545,16 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
|
|
|
541
545
|
let planMsg = `${count} Found ${transformsToRun.length} transforms in ${item.srcPath}`
|
|
542
546
|
planTotal = planTotal + transformsToRun.length
|
|
543
547
|
// logger(`Found ${transformsToRun.length} transforms in ${item.srcPath}`)
|
|
548
|
+
const maxPrefixLen = Math.max(...transformsToRun.map((t) => {
|
|
549
|
+
return `"${t.transform}" on line ${t.lines[0]}`.length
|
|
550
|
+
}))
|
|
544
551
|
transformsToRun.forEach((trn) => {
|
|
545
552
|
const line = trn.lines[0]
|
|
553
|
+
const prefix = `"${trn.transform}" on line ${line}`
|
|
554
|
+
const paddedPrefix = prefix.padEnd(maxPrefixLen)
|
|
546
555
|
const location = getCodeLocation(item.srcPath, line)
|
|
547
|
-
const planData = ` -
|
|
556
|
+
const planData = ` - ${paddedPrefix} → ${location}`
|
|
548
557
|
planMsg += `\n${planData}`
|
|
549
|
-
// logger(` - "${trn.transform}" at line ${trn.lines[0]}`)
|
|
550
558
|
})
|
|
551
559
|
const newLine = plan.length !== i + 1 ? '\n' : ''
|
|
552
560
|
return `${planMsg}${newLine}`
|
|
@@ -91,8 +91,9 @@ module.exports = async function CODE(api) {
|
|
|
91
91
|
if (src === './relative/path/to/code.js') {
|
|
92
92
|
return api.content
|
|
93
93
|
} else {
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
const err = new Error(`FILE NOT FOUND: ${codeFilePath}\n Referenced in: ${srcPath}\n src="${src}"`)
|
|
95
|
+
err.code = 'ENOENT'
|
|
96
|
+
throw err
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
}
|
package/src/transforms/file.js
CHANGED
|
@@ -23,8 +23,15 @@ module.exports = function FILE(api) {
|
|
|
23
23
|
if (options.src === './path/to/file') {
|
|
24
24
|
return api.content
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
const err = new Error(`FILE NOT FOUND: ${resolvedFilePath}
|
|
27
|
+
|
|
28
|
+
Referenced in: ${srcPath}
|
|
29
|
+
|
|
30
|
+
Via the "src" attribute: src="${options.src}"
|
|
31
|
+
|
|
32
|
+
`)
|
|
33
|
+
err.code = 'ENOENT'
|
|
34
|
+
throw err
|
|
28
35
|
}
|
|
29
36
|
}
|
|
30
37
|
|
package/src/utils/fs.js
CHANGED
|
@@ -192,11 +192,34 @@ function isLocalPath(filePath) {
|
|
|
192
192
|
return _isLocalPath(filePath)
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
const fsSync = require('fs')
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Check if file's directory or any parent has .md-ignore
|
|
199
|
+
* @param {string} filePath - Absolute path to file
|
|
200
|
+
* @returns {boolean} True if should be ignored
|
|
201
|
+
*/
|
|
202
|
+
function hasIgnoreFile(filePath) {
|
|
203
|
+
let dir = dirname(filePath)
|
|
204
|
+
const root = resolve('/')
|
|
205
|
+
while (dir !== root) {
|
|
206
|
+
const ignoreFile = join(dir, '.md-ignore')
|
|
207
|
+
if (fsSync.existsSync(ignoreFile)) {
|
|
208
|
+
return true
|
|
209
|
+
}
|
|
210
|
+
const parent = dirname(dir)
|
|
211
|
+
if (parent === dir) break
|
|
212
|
+
dir = parent
|
|
213
|
+
}
|
|
214
|
+
return false
|
|
215
|
+
}
|
|
216
|
+
|
|
195
217
|
module.exports = {
|
|
196
218
|
isLocalPath,
|
|
197
219
|
writeFile,
|
|
198
|
-
readFile,
|
|
220
|
+
readFile,
|
|
199
221
|
findUp,
|
|
222
|
+
hasIgnoreFile,
|
|
200
223
|
resolveOutputPath,
|
|
201
224
|
resolveFlatPath,
|
|
202
225
|
resolveCommonParent,
|