markdown-magic 2.6.1 → 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 +25 -25
- 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/index.js
CHANGED
|
@@ -1,219 +1,354 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
|
-
const
|
|
3
|
-
const
|
|
2
|
+
const { glob, globWithGit } = require('smart-glob')
|
|
3
|
+
const codeTransform = require('./transforms/code')
|
|
4
|
+
const fileTransform = require('./transforms/file')
|
|
5
|
+
const tocTransform = require('./transforms/toc')
|
|
6
|
+
const wordCountTransform = require('./transforms/wordCount')
|
|
7
|
+
const remoteTransform = require('./transforms/remote')
|
|
8
|
+
const { deepLog, success, error, info } = require('./utils/logs')
|
|
9
|
+
const { getSyntaxInfo } = require('./utils/syntax')
|
|
10
|
+
const { onlyUnique, getCodeLocation, pluralize } = require('./utils')
|
|
11
|
+
const { writeFile, resolveOutputPath, resolveFlatPath } = require('./utils/fs')
|
|
12
|
+
const { processFile } = require('./process-file')
|
|
13
|
+
const { processContents } = require('./process-contents')
|
|
14
|
+
const { getBlockRegex } = require('./block-parser')
|
|
15
|
+
const { OPEN_WORD, CLOSE_WORD, DEFAULT_GLOB_PATTERN } = require('./defaults')
|
|
16
|
+
const { parseMarkdown } = require('./utils/md/parse')
|
|
4
17
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
const LINE = '────────────────────────────────────────'
|
|
19
|
+
// const diff = require('../misc/old-test/utils/diff')
|
|
20
|
+
|
|
21
|
+
const defaultTransforms = {
|
|
22
|
+
CODE: codeTransform,
|
|
23
|
+
FILE: fileTransform,
|
|
24
|
+
TOC: tocTransform,
|
|
25
|
+
wordCount: wordCountTransform,
|
|
26
|
+
remote: remoteTransform
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function markdownMagic(globOrOpts, options = {}) {
|
|
30
|
+
let opts = {}
|
|
31
|
+
let globPat
|
|
32
|
+
if (typeof globOrOpts === 'string' || Array.isArray(globOrOpts)) {
|
|
33
|
+
opts = options
|
|
34
|
+
globPat = globOrOpts
|
|
35
|
+
} else if (typeof globOrOpts === 'object') {
|
|
36
|
+
opts = globOrOpts
|
|
37
|
+
}
|
|
38
|
+
const {
|
|
39
|
+
transforms,
|
|
40
|
+
outputDir,
|
|
41
|
+
outputFlatten = false,
|
|
42
|
+
handleOutputPath,
|
|
43
|
+
useGitGlob = false,
|
|
44
|
+
failOnMissingTransforms = false,
|
|
45
|
+
dryRun = false,
|
|
46
|
+
debug = true,
|
|
47
|
+
} = opts
|
|
48
|
+
|
|
49
|
+
let open = OPEN_WORD
|
|
50
|
+
if (opts.open) {
|
|
51
|
+
open = opts.open
|
|
52
|
+
} else if (opts.matchWord) {
|
|
53
|
+
open = `${opts.matchWord}:start`
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let close = CLOSE_WORD
|
|
57
|
+
if (opts.close) {
|
|
58
|
+
close = opts.close
|
|
59
|
+
} else if (opts.matchWord) {
|
|
60
|
+
close = `${opts.matchWord}:end`
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// console.log('outputDir', outputDir)
|
|
64
|
+
// console.log('outputFlatten', outputFlatten)
|
|
65
|
+
// return
|
|
17
66
|
|
|
18
|
-
const
|
|
19
|
-
|
|
67
|
+
const cwd = opts.cwd || process.cwd()
|
|
68
|
+
// console.log('cwd', cwd)
|
|
69
|
+
const globPattern = globPat || globOrOpts.glob || globOrOpts.file || globOrOpts.files
|
|
70
|
+
// console.log('globPattern', globPattern)
|
|
71
|
+
|
|
72
|
+
const useTransforms = Object.assign({}, defaultTransforms, transforms)
|
|
73
|
+
let globs = []
|
|
74
|
+
if (!globPattern) {
|
|
75
|
+
globs = [ DEFAULT_GLOB_PATTERN ]
|
|
76
|
+
} else if (Array.isArray(globPattern)) {
|
|
77
|
+
globs = globPattern
|
|
78
|
+
} else if (typeof globPattern === 'string') {
|
|
79
|
+
globs = [ globPattern ]
|
|
80
|
+
}
|
|
81
|
+
opts.glob = globs
|
|
82
|
+
// console.log('globs', globs)
|
|
83
|
+
// return
|
|
84
|
+
|
|
85
|
+
info(`Running Markdown Magic:`)
|
|
86
|
+
logCommentBlockSyntax({
|
|
87
|
+
syntax: opts.syntax || 'md',
|
|
20
88
|
open,
|
|
21
|
-
close
|
|
89
|
+
close
|
|
22
90
|
})
|
|
23
91
|
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
-
console.log(
|
|
92
|
+
if (dryRun || debug) {
|
|
93
|
+
info(`Glob patterns:`)
|
|
94
|
+
console.log(globs)
|
|
95
|
+
console.log()
|
|
96
|
+
/*
|
|
97
|
+
process.exit(1)
|
|
98
|
+
/** */
|
|
27
99
|
}
|
|
28
100
|
|
|
29
|
-
const
|
|
30
|
-
// console.log('transformsToRun', transformsToRun)
|
|
31
|
-
|
|
32
|
-
// if (!transformsToRun.length) {
|
|
33
|
-
// process.exit(1)
|
|
34
|
-
// }
|
|
35
|
-
|
|
36
|
-
let missingTransforms = []
|
|
37
|
-
const updatedContents = await transformsToRun.reduce(async (updatedContent, ogmatch) => {
|
|
38
|
-
const md = await updatedContent
|
|
39
|
-
/* Apply Before middleware to all transforms */
|
|
40
|
-
const match = await applyMiddleware(ogmatch, md, beforeMiddelwares)
|
|
41
|
-
const { block, raw, transform, args } = match
|
|
42
|
-
const { openTag, closeTag, content, contentStart, contentEnd, start, end } = block
|
|
43
|
-
|
|
44
|
-
/* Run transform plugins */
|
|
45
|
-
let tempContent = content
|
|
46
|
-
if (transforms[transform]) {
|
|
47
|
-
tempContent = await transforms[transform](match, md)
|
|
48
|
-
}
|
|
101
|
+
const globFn = (useGitGlob) ? globWithGit : glob
|
|
49
102
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (!transforms[transform]) {
|
|
65
|
-
missingTransforms.push(afterContent)
|
|
66
|
-
console.log(`Missing "${transform}" transform`)
|
|
67
|
-
}
|
|
103
|
+
const pathsPromise = globs.map((str) => {
|
|
104
|
+
// console.log('str', str)
|
|
105
|
+
// Glob pattern examples https://github.com/terkelg/globrex/blob/master/test/index.js
|
|
106
|
+
// return globWithGit(str, {
|
|
107
|
+
// const g = str.replace(/^(?:\.\.\/)+/, "")
|
|
108
|
+
// console.log('g', g)
|
|
109
|
+
return globFn(str, {
|
|
110
|
+
absolute: true,
|
|
111
|
+
alwaysReturnUnixPaths: true,
|
|
112
|
+
ignoreGlobs: ['**/node_modules/**'],
|
|
113
|
+
})
|
|
114
|
+
})
|
|
68
115
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// console.log('fix', fix)
|
|
77
|
-
const preserveIndent = (true || args.preserveIndent) ? block.indentation.length + block.contentIndent : block.indentation.length
|
|
78
|
-
const indent = indentString(fix, preserveIndent)
|
|
79
|
-
const newCont = `${openTag}${indent}${closeTag}`
|
|
80
|
-
/* Replace original contents */
|
|
81
|
-
const newContents = md.replace(raw.block, newCont)
|
|
82
|
-
return Promise.resolve(newContents)
|
|
83
|
-
}, Promise.resolve(originalContents))
|
|
84
|
-
|
|
85
|
-
if (DEBUG) {
|
|
86
|
-
console.log('Output Markdown')
|
|
87
|
-
console.log(updatedContents)
|
|
116
|
+
let files = []
|
|
117
|
+
try {
|
|
118
|
+
files = (await Promise.all(pathsPromise)).flat().filter(onlyUnique)
|
|
119
|
+
opts.files = files
|
|
120
|
+
} catch (e) {
|
|
121
|
+
console.log(e.message)
|
|
122
|
+
throw new Error(e)
|
|
88
123
|
}
|
|
124
|
+
// console.log('files', files)
|
|
125
|
+
// return
|
|
126
|
+
// console.log('globs', globs)
|
|
127
|
+
// const filex = await globby(globs)
|
|
128
|
+
// console.log('filex', filex)
|
|
89
129
|
|
|
90
130
|
/*
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
matchOne = missingTransforms[missingTransforms.length - 1]
|
|
95
|
-
// console.log('matchOne', matchOne)
|
|
96
|
-
const { block, transform, args } = matchOne
|
|
97
|
-
const { openTag, closeTag, content, contentStart, contentEnd, start, end} = block
|
|
98
|
-
|
|
99
|
-
// console.log('contentStart', contentStart)
|
|
100
|
-
// console.log('contentEnd', contentEnd)
|
|
101
|
-
// console.log('original text between', `"${getTextBetween(md, contentStart, contentEnd)}"`)
|
|
102
|
-
// console.log('original block between', `"${getTextBetween(md, start, end)}"`)
|
|
103
|
-
}
|
|
131
|
+
const relativeFilePaths = files.map((file) => file.replace(cwd, '').replace(/^\//, ''))
|
|
132
|
+
console.log('relativeFilePaths', relativeFilePaths)
|
|
133
|
+
process.exit(1)
|
|
104
134
|
/** */
|
|
105
135
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
136
|
+
if (dryRun || debug) {
|
|
137
|
+
info(`${files.length} Files found:`)
|
|
138
|
+
console.log(files)
|
|
139
|
+
/*
|
|
140
|
+
process.exit(1)
|
|
141
|
+
/** */
|
|
112
142
|
}
|
|
113
|
-
}
|
|
114
143
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
144
|
+
const processedFiles = files.map((file) => {
|
|
145
|
+
// console.log('file', file)
|
|
146
|
+
let newPath = path.resolve(cwd, file)
|
|
147
|
+
/* Allow for different output directory */
|
|
148
|
+
if (outputDir) {
|
|
149
|
+
newPath = (outputFlatten) ? resolveFlatPath(cwd, outputDir, file) : resolveOutputPath(cwd, outputDir, file)
|
|
150
|
+
}
|
|
151
|
+
/* Allow for custom handling of individual files */
|
|
152
|
+
if (handleOutputPath) {
|
|
153
|
+
newPath = handleOutputPath(newPath)
|
|
154
|
+
}
|
|
155
|
+
// const cleanerDirPath = path.dirname(file)
|
|
156
|
+
// const baseDir = cleanerDirPath.replace(cwd, '')
|
|
157
|
+
// const cleanerDir = baseDir
|
|
158
|
+
// const resolvedDir = path.join(cleanerDir, outputDir)
|
|
159
|
+
// const cleanFinalPath = path.resolve(resolvedDir, path.basename(file))
|
|
160
|
+
/*
|
|
161
|
+
console.log('cleanerDir', cleanerDir)
|
|
162
|
+
console.log('resolvedDir', resolvedDir)
|
|
163
|
+
console.log('cleanFinalPath', cleanFinalPath)
|
|
164
|
+
/** */
|
|
165
|
+
// console.log('newPath', newPath)
|
|
166
|
+
return processFile({
|
|
167
|
+
...opts,
|
|
168
|
+
open,
|
|
169
|
+
close,
|
|
170
|
+
srcPath: file,
|
|
171
|
+
outputPath: newPath,
|
|
172
|
+
transforms: useTransforms
|
|
173
|
+
})
|
|
174
|
+
})
|
|
175
|
+
// process.exit(1)
|
|
176
|
+
const plan = (await Promise.all(processedFiles)).filter((file) => {
|
|
177
|
+
/* Filter out files without transforms */
|
|
178
|
+
return file.transforms.length
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
if (dryRun || debug) {
|
|
182
|
+
/* Generate output paths */
|
|
183
|
+
const outputPaths = plan.map((item) => item.outputPath)
|
|
184
|
+
info(`Output files:`)
|
|
185
|
+
console.log(outputPaths)
|
|
186
|
+
/*
|
|
187
|
+
process.exit(1)
|
|
188
|
+
/** */
|
|
189
|
+
}
|
|
190
|
+
/*
|
|
191
|
+
console.log('plan')
|
|
192
|
+
deepLog(plan)
|
|
193
|
+
process.exit(1)
|
|
194
|
+
/** */
|
|
195
|
+
|
|
196
|
+
const missing = plan.filter((item) => {
|
|
197
|
+
return item.missingTransforms.length
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
let errors = []
|
|
201
|
+
if (missing.length) {
|
|
202
|
+
errors = missing.map((item, i) => {
|
|
203
|
+
const errorMessage = `Missing ${item.missingTransforms.length} transforms in ${item.srcPath}`
|
|
204
|
+
const issues = item.missingTransforms.map((trn) => {
|
|
205
|
+
// console.log('trn', trn)
|
|
206
|
+
// const rowData = getRowAndColumnFromCharPos(item.updatedContents, trn.open.start)
|
|
207
|
+
const location = `${item.srcPath}:${trn.block.lines[0]}:0`
|
|
208
|
+
const message = `Transform "${trn.transform}" at line ${trn.block.lines[0]} does not exist. → ${location}`
|
|
209
|
+
return {
|
|
210
|
+
message,
|
|
211
|
+
location
|
|
127
212
|
}
|
|
213
|
+
})
|
|
214
|
+
return {
|
|
215
|
+
errorMessage,
|
|
216
|
+
errors: issues
|
|
128
217
|
}
|
|
129
218
|
})
|
|
130
|
-
}
|
|
131
|
-
}
|
|
219
|
+
}
|
|
132
220
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
221
|
+
/* If transform errors and should throw, exit early */
|
|
222
|
+
if (errors.length && failOnMissingTransforms) {
|
|
223
|
+
throw new Error(logErrors(errors))
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* Log out execution plan */
|
|
227
|
+
let planTotal = 0
|
|
228
|
+
let missingTotal = 0
|
|
229
|
+
const planOutput = plan.map((item, i) => {
|
|
230
|
+
const transformsToRun = item.transforms.filter((item) => {
|
|
231
|
+
if (item.context.isMissing) {
|
|
232
|
+
// console.log('item', item)
|
|
233
|
+
missingTotal = missingTotal + 1
|
|
234
|
+
}
|
|
235
|
+
return !item.context.isMissing
|
|
236
|
+
})
|
|
237
|
+
if (!transformsToRun.length) {
|
|
238
|
+
return
|
|
239
|
+
}
|
|
240
|
+
const count = `${i + 1}.`
|
|
241
|
+
let planMsg = `${count} Found ${transformsToRun.length} transforms in ${item.srcPath}`
|
|
242
|
+
planTotal = planTotal + transformsToRun.length
|
|
243
|
+
// console.log(`Found ${transformsToRun.length} transforms in ${item.srcPath}`)
|
|
244
|
+
transformsToRun.forEach((trn) => {
|
|
245
|
+
const line = trn.block.lines[0]
|
|
246
|
+
const location = getCodeLocation(item.srcPath, line)
|
|
247
|
+
const planData = ` - "${trn.transform}" at line ${line} → ${location}`
|
|
248
|
+
planMsg += `\n${planData}`
|
|
249
|
+
// console.log(` - "${trn.transform}" at line ${trn.block.lines[0]}`)
|
|
250
|
+
})
|
|
251
|
+
const newLine = plan.length !== i + 1 ? '\n' : ''
|
|
252
|
+
return `${planMsg}${newLine}`
|
|
253
|
+
}).filter(Boolean)
|
|
141
254
|
|
|
142
|
-
|
|
143
|
-
|
|
255
|
+
if (files.length) {
|
|
256
|
+
console.log(LINE)
|
|
257
|
+
info(`Markdown Magic updates`, '')
|
|
258
|
+
const total = planTotal + missingTotal
|
|
259
|
+
console.log(`Parsed files: ${files.length}`)
|
|
260
|
+
console.log(`Block Open: ${open}`)
|
|
261
|
+
console.log(`Block Close: ${close}`)
|
|
262
|
+
console.log(`Files w/ transforms: ${plan.length} / ${files.length}`)
|
|
263
|
+
console.log(`Total transforms: ${total}`)
|
|
264
|
+
console.log(`Valid transforms: ${planTotal} / ${total}`)
|
|
265
|
+
console.log(`Invalid transforms: ${missingTotal} / ${total}`)
|
|
266
|
+
console.log('Syntax:')
|
|
267
|
+
logCommentBlockSyntax({
|
|
268
|
+
syntax: opts.syntax || 'md',
|
|
269
|
+
open,
|
|
270
|
+
close
|
|
271
|
+
})
|
|
272
|
+
console.log(LINE)
|
|
273
|
+
console.log(planOutput.join('\n'))
|
|
274
|
+
}
|
|
144
275
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
276
|
+
/* Execute updates based on plan */
|
|
277
|
+
if (!dryRun) {
|
|
278
|
+
const changed = plan.filter(({ isChanged }) => isChanged)
|
|
279
|
+
if (changed.length) {
|
|
280
|
+
console.log(LINE)
|
|
281
|
+
console.log()
|
|
282
|
+
const execute = changed.map(({ srcPath, outputPath, updatedContents, originalContents }, i) => {
|
|
283
|
+
// console.log(`${i + 1}. newPath`, newPath)
|
|
284
|
+
console.log(`- Update file ${outputPath}`)
|
|
285
|
+
return writeFile(outputPath, updatedContents)
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
await Promise.all(execute)
|
|
289
|
+
} else {
|
|
290
|
+
console.log(LINE)
|
|
291
|
+
console.log('No changes. Skipping file writes')
|
|
151
292
|
}
|
|
152
|
-
const [ match, leadingText, leadingSpace, comment, insideComment, trailingText, trailingNewLine ] = matches
|
|
153
|
-
/*
|
|
154
|
-
console.log('match', match)
|
|
155
|
-
console.log('leadingText', leadingText)
|
|
156
|
-
console.log('leadingSpace', leadingSpace)
|
|
157
|
-
console.log('comment', comment)
|
|
158
|
-
console.log('insideComment', insideComment)
|
|
159
|
-
console.log('trailingText', trailingText)
|
|
160
|
-
console.log('trailingNewLine', trailingNewLine)
|
|
161
|
-
/** */
|
|
162
|
-
const newLineCount = (trailingNewLine || '').length
|
|
163
|
-
const trailing = (!trailingText && newLineCount > 1) ? `${trailingNewLine || ''}` : ''
|
|
164
|
-
const leading = (leadingSpace) ? leadingSpace.slice(1) : ''
|
|
165
|
-
remove.push(`${leading}${comment}${trailing}`)
|
|
166
293
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
294
|
+
/*
|
|
295
|
+
TODO:
|
|
296
|
+
- Output to new file
|
|
297
|
+
- Clean up default transforms
|
|
298
|
+
- Expose md utils
|
|
299
|
+
*/
|
|
300
|
+
if (errors.length) {
|
|
301
|
+
logErrors(errors)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
console.log(LINE)
|
|
305
|
+
success(`Markdown Magic Done`)
|
|
306
|
+
console.log(`${LINE}\n`)
|
|
171
307
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
* @param {*} closePattern
|
|
177
|
-
* @returns
|
|
178
|
-
*/
|
|
179
|
-
function removeConflictingComments(content, openPattern, closePattern) {
|
|
180
|
-
const removeOpen = content.replace(openPattern, '')
|
|
181
|
-
// TODO this probably needs to be a loop for larger blocks
|
|
182
|
-
closePattern.lastIndex = 0; // reset regex
|
|
183
|
-
const hasClose = closePattern.exec(content)
|
|
184
|
-
// console.log('closePattern', closePattern)
|
|
185
|
-
// console.log('has', content)
|
|
186
|
-
// console.log('hasClose', hasClose)
|
|
187
|
-
if (!hasClose) {
|
|
188
|
-
return removeOpen
|
|
308
|
+
return {
|
|
309
|
+
errors,
|
|
310
|
+
changes: plan,
|
|
311
|
+
data: plan
|
|
189
312
|
}
|
|
190
|
-
const closeTag = `${hasClose[2]}${hasClose[3] || ''}`
|
|
191
|
-
// console.log('closeTag', closeTag)
|
|
192
|
-
return removeOpen
|
|
193
|
-
.replaceAll(closeTag, '')
|
|
194
|
-
/* Trailing new line */
|
|
195
|
-
.replace(/\n$/, '')
|
|
196
313
|
}
|
|
197
|
-
|
|
198
|
-
function
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
314
|
+
|
|
315
|
+
function logErrors(allErrors) {
|
|
316
|
+
const word = pluralize(allErrors, 'error', 'errors')
|
|
317
|
+
const title = `Markdown Magic ${word}: ${allErrors.length}`
|
|
318
|
+
console.log('\n──────────────────────────────')
|
|
319
|
+
error(title)
|
|
320
|
+
console.log('──────────────────────────────\n')
|
|
321
|
+
let msg = title
|
|
322
|
+
allErrors.forEach(({ errorMessage, errors }, i) => {
|
|
323
|
+
const finalMessage = `${i + 1}. ${errorMessage}`
|
|
324
|
+
msg += `\n${finalMessage}`
|
|
325
|
+
error(finalMessage, ``)
|
|
326
|
+
errors.forEach(({ message }, n) => {
|
|
327
|
+
const newLineX = errors.length !== n + 1 ? '' : '\n'
|
|
328
|
+
const lineMessage = ` - ${message}`
|
|
329
|
+
msg += `\n${lineMessage}`
|
|
330
|
+
console.log(`${lineMessage}${newLineX}`)
|
|
331
|
+
})
|
|
204
332
|
})
|
|
333
|
+
return msg
|
|
205
334
|
}
|
|
206
335
|
|
|
207
|
-
function
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
336
|
+
function logCommentBlockSyntax({
|
|
337
|
+
syntax,
|
|
338
|
+
open,
|
|
339
|
+
close
|
|
340
|
+
}) {
|
|
341
|
+
const syntaxDetails = getSyntaxInfo(syntax)
|
|
342
|
+
console.log(`
|
|
343
|
+
${syntaxDetails.tags[0]} ${open} transformName ${syntaxDetails.tags[1]}
|
|
344
|
+
generated content here
|
|
345
|
+
${syntaxDetails.tags[0]} ${close} ${syntaxDetails.tags[1]}
|
|
346
|
+
`)
|
|
215
347
|
}
|
|
216
348
|
|
|
217
349
|
module.exports = {
|
|
218
|
-
|
|
350
|
+
markdownMagic,
|
|
351
|
+
parseMarkdown,
|
|
352
|
+
processContents,
|
|
353
|
+
processFile
|
|
219
354
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const { test } = require('uvu')
|
|
2
|
+
const assert = require('uvu/assert')
|
|
3
|
+
const { markdownMagic, processContents, processFile } = require('./')
|
|
4
|
+
|
|
5
|
+
test('Main API', () => {
|
|
6
|
+
assert.equal(typeof markdownMagic, 'function')
|
|
7
|
+
assert.equal(typeof processContents, 'function')
|
|
8
|
+
assert.equal(typeof processFile, 'function')
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
test.run()
|