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.
- 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 +26 -26
- 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
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
const { parseBlocks } = require('./block-parser')
|
|
2
|
+
const { deepLog } = require('./utils/logs')
|
|
3
|
+
const { getCodeLocation } = require('./utils')
|
|
4
|
+
const { indentString, trimString } = require('./utils/text')
|
|
5
|
+
const { OPEN_WORD, CLOSE_WORD } = require('./defaults')
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Pull comment blocks out of content and process them
|
|
9
|
+
* @param {string} text
|
|
10
|
+
* @param {object} config
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
async function processContents(text, config = {}) {
|
|
14
|
+
const {
|
|
15
|
+
srcPath,
|
|
16
|
+
outputPath,
|
|
17
|
+
open = OPEN_WORD, // 'DOCS:START',
|
|
18
|
+
close = CLOSE_WORD, // 'DOCS:END',
|
|
19
|
+
syntax = 'md',
|
|
20
|
+
transforms,
|
|
21
|
+
beforeMiddleware = [],
|
|
22
|
+
afterMiddleware = [],
|
|
23
|
+
debug = false,
|
|
24
|
+
} = config
|
|
25
|
+
|
|
26
|
+
let foundBlocks = {}
|
|
27
|
+
try {
|
|
28
|
+
foundBlocks = parseBlocks(text, {
|
|
29
|
+
syntax,
|
|
30
|
+
open,
|
|
31
|
+
close,
|
|
32
|
+
})
|
|
33
|
+
} catch (e) {
|
|
34
|
+
throw new Error(`${e.message} in file ${srcPath}\n`)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (debug) {
|
|
38
|
+
console.log(`foundBlocks ${srcPath}`)
|
|
39
|
+
deepLog(foundBlocks)
|
|
40
|
+
}
|
|
41
|
+
/*
|
|
42
|
+
deepLog(foundBlocks)
|
|
43
|
+
process.exit(1)
|
|
44
|
+
/** */
|
|
45
|
+
const { COMMENT_OPEN_REGEX, COMMENT_CLOSE_REGEX } = foundBlocks
|
|
46
|
+
|
|
47
|
+
const blocksWithTransforms = foundBlocks.blocks
|
|
48
|
+
.filter((block) => block.type)
|
|
49
|
+
.map((block, i) => {
|
|
50
|
+
const transform = block.type
|
|
51
|
+
delete block.type
|
|
52
|
+
return Object.assign({ transform }, block)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const regexInfo = {
|
|
57
|
+
blocks: foundBlocks.pattern,
|
|
58
|
+
open: COMMENT_OPEN_REGEX,
|
|
59
|
+
close: COMMENT_CLOSE_REGEX,
|
|
60
|
+
}
|
|
61
|
+
// console.log('blocksWithTransforms', blocksWithTransforms)
|
|
62
|
+
// process.exit(1)
|
|
63
|
+
|
|
64
|
+
const transformsToRun = sortTranforms(blocksWithTransforms, transforms)
|
|
65
|
+
// .map((transform) => {
|
|
66
|
+
// return {
|
|
67
|
+
// ...transform,
|
|
68
|
+
// srcPath
|
|
69
|
+
// }
|
|
70
|
+
// })
|
|
71
|
+
// console.log('transformsToRun', transformsToRun)
|
|
72
|
+
|
|
73
|
+
// if (!transformsToRun.length) {
|
|
74
|
+
// process.exit(1)
|
|
75
|
+
// }
|
|
76
|
+
// console.log('transformsToRun', transformsToRun)
|
|
77
|
+
let missingTransforms = []
|
|
78
|
+
const updatedContents = await transformsToRun.reduce(async (contentPromise, originalMatch) => {
|
|
79
|
+
const md = await contentPromise
|
|
80
|
+
/* Apply Before middleware to all transforms */
|
|
81
|
+
const match = await applyMiddleware(originalMatch, md, beforeMiddleware)
|
|
82
|
+
const { block, content, open, close, transform, options, context } = match
|
|
83
|
+
const closeTag = close.value
|
|
84
|
+
const openTag = open.value
|
|
85
|
+
|
|
86
|
+
/* Run transform plugins */
|
|
87
|
+
let tempContent = content.value
|
|
88
|
+
// console.log('transform', transform)
|
|
89
|
+
const currentTransform = getTransform(transform, transforms)
|
|
90
|
+
/* Run each transform */
|
|
91
|
+
if (currentTransform) {
|
|
92
|
+
// console.log('context', context)
|
|
93
|
+
let returnedContent
|
|
94
|
+
/* DISABLED legacy syntax */
|
|
95
|
+
/* // Support for legacy syntax... maybe later
|
|
96
|
+
if (context && context.isLegacy) {
|
|
97
|
+
console.log(`CALL legacy ${transform}`, srcPath)
|
|
98
|
+
// backward compat maybe
|
|
99
|
+
// CODE(content, options, config)
|
|
100
|
+
returnedContent = await currentTransform(content.value, options, {
|
|
101
|
+
originalPath: srcPath
|
|
102
|
+
})
|
|
103
|
+
} else {
|
|
104
|
+
returnedContent = await currentTransform(transformApi({
|
|
105
|
+
srcPath,
|
|
106
|
+
...match,
|
|
107
|
+
regex: regexInfo,
|
|
108
|
+
originalContents: text,
|
|
109
|
+
currentContents: md,
|
|
110
|
+
}, config))
|
|
111
|
+
}
|
|
112
|
+
/** */
|
|
113
|
+
|
|
114
|
+
returnedContent = await currentTransform(transformApi({
|
|
115
|
+
srcPath,
|
|
116
|
+
...match,
|
|
117
|
+
regex: regexInfo,
|
|
118
|
+
originalContents: text,
|
|
119
|
+
currentContents: md,
|
|
120
|
+
}, config))
|
|
121
|
+
|
|
122
|
+
/* Run each transform */
|
|
123
|
+
// console.log('config', config)
|
|
124
|
+
|
|
125
|
+
// console.log('returnedContent', returnedContent)
|
|
126
|
+
|
|
127
|
+
if (returnedContent) {
|
|
128
|
+
tempContent = returnedContent
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Apply After middleware to all transforms */
|
|
133
|
+
const afterContent = await applyMiddleware({
|
|
134
|
+
...match,
|
|
135
|
+
...{
|
|
136
|
+
content: {
|
|
137
|
+
...match.content,
|
|
138
|
+
value: tempContent
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}, md, afterMiddleware)
|
|
142
|
+
if (debug) {
|
|
143
|
+
console.log('afterContent', afterContent)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!currentTransform) {
|
|
147
|
+
missingTransforms.push(afterContent)
|
|
148
|
+
// console.log(`Missing "${transform}" transform`)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const newContent = afterContent.content.value
|
|
152
|
+
const formattedNewContent = (options.noTrim) ? newContent : trimString(newContent)
|
|
153
|
+
// console.log('formattedNewContent', formattedNewContent)
|
|
154
|
+
/* Remove any conflicting imported comments */
|
|
155
|
+
const fix = removeConflictingComments(formattedNewContent, foundBlocks.commentOpen, COMMENT_CLOSE_REGEX)
|
|
156
|
+
// const fix = stripAllComments(formattedNewContent, foundBlocks.commentOpen, COMMENT_CLOSE_REGEX)
|
|
157
|
+
|
|
158
|
+
// console.log('COMMENT_CLOSE_REGEX', COMMENT_CLOSE_REGEX)
|
|
159
|
+
// console.log('formattedNewContent', formattedNewContent)
|
|
160
|
+
// console.log('fix', fix)
|
|
161
|
+
const preserveIndent = (true || options.preserveIndent) ? block.indentation.length + match.content.indentation : block.indentation.length
|
|
162
|
+
const indent = indentString(fix, preserveIndent)
|
|
163
|
+
const newCont = `${openTag}${indent}${closeTag}`
|
|
164
|
+
/* Replace original contents */
|
|
165
|
+
const newContents = md.replace(block.value, newCont)
|
|
166
|
+
return Promise.resolve(newContents)
|
|
167
|
+
}, Promise.resolve(text))
|
|
168
|
+
|
|
169
|
+
if (debug) {
|
|
170
|
+
console.log('Output Markdown')
|
|
171
|
+
console.log(updatedContents)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/*
|
|
175
|
+
if (missingTransforms.length) {
|
|
176
|
+
console.log('missingTransforms', missingTransforms)
|
|
177
|
+
let matchOne = missingTransforms[1]
|
|
178
|
+
matchOne = missingTransforms[missingTransforms.length - 1]
|
|
179
|
+
// console.log('matchOne', matchOne)
|
|
180
|
+
const { block, transform, args } = matchOne
|
|
181
|
+
const { openTag, closeTag, content, contentStart, contentEnd, start, end} = block
|
|
182
|
+
|
|
183
|
+
// console.log('contentStart', contentStart)
|
|
184
|
+
// console.log('contentEnd', contentEnd)
|
|
185
|
+
// console.log('original text between', `"${getTextBetweenChars(md, contentStart, contentEnd)}"`)
|
|
186
|
+
// console.log('original block between', `"${getTextBetweenChars(md, start, end)}"`)
|
|
187
|
+
}
|
|
188
|
+
/** */
|
|
189
|
+
|
|
190
|
+
// console.log('detect slow srcPath', srcPath)
|
|
191
|
+
|
|
192
|
+
const result = {
|
|
193
|
+
/* Has markdown content changed? */
|
|
194
|
+
isChanged: text !== updatedContents,
|
|
195
|
+
isNewPath: srcPath !== outputPath,
|
|
196
|
+
srcPath,
|
|
197
|
+
outputPath,
|
|
198
|
+
// config,
|
|
199
|
+
transforms: transformsToRun,
|
|
200
|
+
missingTransforms,
|
|
201
|
+
originalContents: text,
|
|
202
|
+
updatedContents
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// console.log('result')
|
|
206
|
+
// deepLog(result)
|
|
207
|
+
|
|
208
|
+
return result
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function transformApi(stuff, opts) {
|
|
212
|
+
const { transforms, srcPath, outputPath, ...rest } = opts
|
|
213
|
+
return {
|
|
214
|
+
srcPath: stuff.srcPath,
|
|
215
|
+
outputPath: outputPath,
|
|
216
|
+
transform: stuff.transform,
|
|
217
|
+
options: stuff.options || {},
|
|
218
|
+
blockContent: stuff.content.value,
|
|
219
|
+
fileContent: stuff.currentContents,
|
|
220
|
+
originalFileContent: stuff.originalContents,
|
|
221
|
+
settings: {
|
|
222
|
+
...rest,
|
|
223
|
+
regex: stuff.regex,
|
|
224
|
+
},
|
|
225
|
+
getOriginalContent: () => stuff.originalContents,
|
|
226
|
+
getOriginalBlock: () => stuff,
|
|
227
|
+
getCurrentBlock: () => {
|
|
228
|
+
/* Re-parse current file for updated positions */
|
|
229
|
+
const updatedBlocks = parseBlocks(stuff.currentContents, {
|
|
230
|
+
syntax: opts.syntax,
|
|
231
|
+
open: opts.open,
|
|
232
|
+
close: opts.close,
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
const matchingBlocks = updatedBlocks.blocks.filter((block) => {
|
|
237
|
+
return block.open.value === stuff.open.value
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
if (!matchingBlocks.length) {
|
|
241
|
+
return {}
|
|
242
|
+
}
|
|
243
|
+
let foundBlock = matchingBlocks[0]
|
|
244
|
+
|
|
245
|
+
if (matchingBlocks.length > 1) {
|
|
246
|
+
foundBlock = matchingBlocks.filter((block) => {
|
|
247
|
+
return block.index === stuff.index
|
|
248
|
+
})[0]
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const location = getCodeLocation(stuff.srcPath, foundBlock.block.lines[0])
|
|
252
|
+
|
|
253
|
+
return [ foundBlock, location ]
|
|
254
|
+
},
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Remove conflicting comments that might have been inserted from transforms
|
|
260
|
+
* @param {*} content
|
|
261
|
+
* @param {*} openPattern
|
|
262
|
+
* @param {*} closePattern
|
|
263
|
+
* @returns
|
|
264
|
+
*/
|
|
265
|
+
function removeConflictingComments(content, openPattern, closePattern) {
|
|
266
|
+
const removeOpen = content.replace(openPattern, '')
|
|
267
|
+
// TODO this probably needs to be a loop for larger blocks
|
|
268
|
+
closePattern.lastIndex = 0; // reset regex
|
|
269
|
+
const hasClose = closePattern.exec(content)
|
|
270
|
+
// console.log('closePattern', closePattern)
|
|
271
|
+
// console.log('has', content)
|
|
272
|
+
// console.log('hasClose', hasClose)
|
|
273
|
+
if (!hasClose) {
|
|
274
|
+
return removeOpen
|
|
275
|
+
}
|
|
276
|
+
const closeTag = `${hasClose[2]}${hasClose[3] || ''}`
|
|
277
|
+
// console.log('closeTag', closeTag)
|
|
278
|
+
return removeOpen
|
|
279
|
+
.replaceAll(closeTag, '')
|
|
280
|
+
/* Trailing new line */
|
|
281
|
+
.replace(/\n$/, '')
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function applyMiddleware(data, md, middlewares) {
|
|
285
|
+
return middlewares.reduce(async (acc, curr) => {
|
|
286
|
+
const realAcc = await acc
|
|
287
|
+
// console.log(`Running "${curr.name}" Middleware on "${realAcc.transform}" block`)
|
|
288
|
+
const updatedContent = await curr.transform(realAcc, md)
|
|
289
|
+
// realAcc.block.content = updatedContent
|
|
290
|
+
return Promise.resolve({
|
|
291
|
+
...realAcc,
|
|
292
|
+
...{
|
|
293
|
+
content: {
|
|
294
|
+
...realAcc.content,
|
|
295
|
+
value: updatedContent
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
})
|
|
299
|
+
}, Promise.resolve(data))
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function getTransform(name, transforms = {}) {
|
|
303
|
+
return transforms[name] || transforms[name.toLowerCase()]
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function sortTranforms(foundTransForms, registeredTransforms) {
|
|
307
|
+
// console.log('transforms', transforms)
|
|
308
|
+
if (!foundTransForms) return []
|
|
309
|
+
return foundTransForms.sort((a, b) => {
|
|
310
|
+
// put table of contents (TOC) at end of tranforms
|
|
311
|
+
if (a.transform === 'TOC') return 1
|
|
312
|
+
if (b.transform === 'TOC') return -1
|
|
313
|
+
return 0
|
|
314
|
+
}).map((item) => {
|
|
315
|
+
if (getTransform(item.transform, registeredTransforms)) {
|
|
316
|
+
return item
|
|
317
|
+
}
|
|
318
|
+
return {
|
|
319
|
+
...item,
|
|
320
|
+
context: {
|
|
321
|
+
...item.context,
|
|
322
|
+
isMissing: true,
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
})
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
module.exports = {
|
|
329
|
+
processContents
|
|
330
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const isValidFile = require('is-valid-path')
|
|
3
|
+
const { readFile } = require('./utils/fs')
|
|
4
|
+
const { processContents } = require('./process-contents')
|
|
5
|
+
|
|
6
|
+
async function processFile(opts = {}) {
|
|
7
|
+
const { content, syntax } = opts
|
|
8
|
+
let srcPath = opts.srcPath
|
|
9
|
+
if (srcPath && content) throw new Error(`Can't set both "srcPath" & "content"`)
|
|
10
|
+
let fileContents
|
|
11
|
+
if (content) {
|
|
12
|
+
const isFile = isValidFile(content)
|
|
13
|
+
srcPath = (isFile) ? content : undefined
|
|
14
|
+
fileContents = (!isFile) ? content : undefined
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!fileContents) {
|
|
18
|
+
fileContents = await readFile(srcPath || content, 'utf8')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let syntaxType = syntax
|
|
22
|
+
if (srcPath && !syntaxType) {
|
|
23
|
+
syntaxType = path.extname(srcPath).replace(/^\./, '')
|
|
24
|
+
}
|
|
25
|
+
return processContents(fileContents, {
|
|
26
|
+
...opts,
|
|
27
|
+
srcPath,
|
|
28
|
+
syntax: syntaxType,
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = {
|
|
33
|
+
processFile
|
|
34
|
+
}
|
package/lib/transforms/code.js
CHANGED
|
@@ -1,52 +1,97 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
1
|
const fs = require('fs')
|
|
3
|
-
const
|
|
2
|
+
const path = require('path')
|
|
4
3
|
const remoteRequest = require('../utils/remoteRequest')
|
|
4
|
+
const { isLocalPath } = require('../utils/fs')
|
|
5
|
+
const { deepLog } = require('../utils/logs')
|
|
6
|
+
const { getLineCount, getTextBetweenLines } = require('../utils/text')
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
// TODO code sections
|
|
9
|
+
// https://github.com/linear/linear/blob/94af540244864fbe466fb933256278e04e87513e/docs/transforms/code-section.js
|
|
10
|
+
// https://github.com/linear/linear/blob/bc39d23af232f9fdbe7df458b0aaa9554ca83c57/packages/sdk/src/_tests/readme.test.ts#L133-L140
|
|
11
|
+
// usage https://github.com/linear/linear/blame/93981d3a3db571e2f8efdce9f5271ea678941c43/packages/sdk/README.md#L1
|
|
12
|
+
|
|
13
|
+
module.exports = function CODE(api) {
|
|
14
|
+
const { options = {}, blockContent, srcPath } = api
|
|
15
|
+
// console.log('CODE API', api)
|
|
16
|
+
// console.log('options', options)
|
|
17
|
+
const { src, lines } = options
|
|
18
|
+
const originalContent = blockContent
|
|
7
19
|
let code
|
|
8
20
|
let syntax = options.syntax
|
|
9
|
-
if (!
|
|
10
|
-
|
|
21
|
+
if (!src) {
|
|
22
|
+
deepLog(api.getCurrentBlock())
|
|
23
|
+
throw new Error('Missing "src" attribute')
|
|
11
24
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
25
|
+
let codeFilePath = src
|
|
26
|
+
if (isLocalPath(src)) {
|
|
27
|
+
const fileDir = (srcPath) ? path.dirname(srcPath) : process.cwd()
|
|
28
|
+
codeFilePath = path.resolve(fileDir, src)
|
|
15
29
|
try {
|
|
16
|
-
code = fs.readFileSync(
|
|
30
|
+
code = fs.readFileSync(codeFilePath, 'utf8', (err, contents) => {
|
|
17
31
|
if (err) {
|
|
18
|
-
console.log(`FILE NOT FOUND ${
|
|
32
|
+
console.log(`FILE NOT FOUND ${codeFilePath}`)
|
|
19
33
|
console.log(err)
|
|
20
34
|
// throw err
|
|
21
35
|
}
|
|
22
36
|
return contents
|
|
23
37
|
})
|
|
24
38
|
} catch (e) {
|
|
25
|
-
console.log(`FILE NOT FOUND ${
|
|
39
|
+
console.log(`FILE NOT FOUND ${codeFilePath}`)
|
|
26
40
|
throw e
|
|
27
41
|
}
|
|
28
42
|
if (!syntax) {
|
|
29
|
-
syntax = path.extname(
|
|
43
|
+
syntax = path.extname(codeFilePath).replace(/^./, '')
|
|
30
44
|
}
|
|
31
45
|
} else {
|
|
32
46
|
// do remote request
|
|
33
|
-
// console.log(
|
|
34
|
-
const remoteContent = remoteRequest(
|
|
47
|
+
// console.log(src)
|
|
48
|
+
const remoteContent = remoteRequest(src)
|
|
35
49
|
if (!remoteContent) {
|
|
36
|
-
console.log(`WARNING: ${
|
|
37
|
-
return
|
|
50
|
+
console.log(`WARNING: ${src} URL NOT FOUND or internet connection is off`)
|
|
51
|
+
return originalContent
|
|
38
52
|
}
|
|
39
53
|
code = remoteContent
|
|
40
|
-
syntax = path.extname(
|
|
54
|
+
syntax = path.extname(src).replace(/^./, '')
|
|
41
55
|
}
|
|
42
56
|
|
|
43
|
-
|
|
57
|
+
/* handle option `lines` */
|
|
44
58
|
if (options.lines) {
|
|
45
|
-
const
|
|
46
|
-
|
|
59
|
+
const lineCount = getLineCount(code)
|
|
60
|
+
// console.log('lineCount', lineCount)
|
|
61
|
+
// console.log('src', src)
|
|
62
|
+
// console.log('lines', lines)
|
|
63
|
+
let startLine
|
|
64
|
+
let endLine
|
|
65
|
+
if (Array.isArray(lines)) {
|
|
66
|
+
startLine = lines[0]
|
|
67
|
+
endLine = lines[1]
|
|
68
|
+
} else if (typeof lines === 'string') {
|
|
69
|
+
const splitLines = lines.split('-')
|
|
70
|
+
startLine = splitLines[0]
|
|
71
|
+
endLine = splitLines[1]
|
|
72
|
+
}
|
|
47
73
|
if ((startLine) && (endLine) && parseInt(startLine, 10) <= parseInt(endLine, 10)) {
|
|
48
|
-
code = code
|
|
74
|
+
code = getTextBetweenLines(code, startLine, endLine)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Check for Id */
|
|
79
|
+
if (options.id) {
|
|
80
|
+
const lines = code.split("\n")
|
|
81
|
+
const startLine = lines.findIndex(line => line.includes(`CODE_SECTION:${options.id}:START`)) ?? 0
|
|
82
|
+
const endLine = lines.findIndex(line => line.includes(`CODE_SECTION:${options.id}:END`)) ?? lines.length - 1
|
|
83
|
+
// console.log('startLine', startLine)
|
|
84
|
+
// console.log('endLineendLine', endLine)
|
|
85
|
+
if (startLine === -1 && endLine === -1) {
|
|
86
|
+
throw new Error(`Missing ${options.id} code section from ${codeFilePath}`)
|
|
49
87
|
}
|
|
88
|
+
|
|
89
|
+
const selectedLines = lines.slice(startLine + 1, endLine);
|
|
90
|
+
|
|
91
|
+
const trimBy = selectedLines[0]?.match(/^(\s*)/)?.[1]?.length;
|
|
92
|
+
const newValue = `${selectedLines.map(line => line.substring(trimBy).replace(/^\/\/ CODE_SECTION:INCLUDE /g, "")).join("\n")}`
|
|
93
|
+
// console.log('newValue', newValue)
|
|
94
|
+
code = newValue
|
|
50
95
|
}
|
|
51
96
|
|
|
52
97
|
// trim leading and trailing spaces/line breaks in code and keeps the indentation of the first non-empty line
|
|
@@ -57,7 +102,7 @@ module.exports = function CODE(content, options, config) {
|
|
|
57
102
|
header = `\n${options.header}`
|
|
58
103
|
}
|
|
59
104
|
|
|
60
|
-
return `<!-- The below code snippet is automatically added from ${
|
|
105
|
+
return `<!-- The below code snippet is automatically added from ${src} -->
|
|
61
106
|
\`\`\`${syntax}${header}
|
|
62
107
|
${code}
|
|
63
108
|
\`\`\``
|
package/lib/transforms/file.js
CHANGED
|
@@ -2,31 +2,29 @@ const path = require('path')
|
|
|
2
2
|
const fs = require('fs')
|
|
3
3
|
const isLocalPath = require('is-local-path')
|
|
4
4
|
|
|
5
|
-
module.exports = function FILE(
|
|
5
|
+
module.exports = function FILE(api) {
|
|
6
|
+
const { options, srcPath } = api
|
|
7
|
+
// console.log('FILE API', api)
|
|
6
8
|
let fileContents
|
|
7
|
-
let syntax = options.syntax
|
|
8
9
|
if (!options.src) {
|
|
9
10
|
return false
|
|
10
11
|
}
|
|
11
12
|
if (isLocalPath(options.src)) {
|
|
12
|
-
const fileDir = path.dirname(
|
|
13
|
-
const
|
|
13
|
+
const fileDir = path.dirname(srcPath)
|
|
14
|
+
const resolvedFilePath = path.resolve(fileDir, options.src)
|
|
14
15
|
try {
|
|
15
|
-
fileContents = fs.readFileSync(
|
|
16
|
+
fileContents = fs.readFileSync(resolvedFilePath, 'utf8', (err, contents) => {
|
|
16
17
|
if (err) {
|
|
17
|
-
console.log(`FILE NOT FOUND ${
|
|
18
|
+
console.log(`FILE NOT FOUND ${resolvedFilePath}`)
|
|
18
19
|
console.log(err)
|
|
19
20
|
// throw err
|
|
20
21
|
}
|
|
21
22
|
return contents
|
|
22
23
|
})
|
|
23
24
|
} catch (e) {
|
|
24
|
-
console.log(`FILE NOT FOUND ${
|
|
25
|
+
console.log(`FILE NOT FOUND ${resolvedFilePath}`)
|
|
25
26
|
throw e
|
|
26
27
|
}
|
|
27
|
-
if (!syntax) {
|
|
28
|
-
syntax = path.extname(filePath).replace(/^./, '')
|
|
29
|
-
}
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
// trim leading and trailing spaces/line breaks in code and keeps the indentation of the first non-empty line
|
|
@@ -35,3 +33,8 @@ module.exports = function FILE(content, options, config) {
|
|
|
35
33
|
return `<!-- The below content is automatically added from ${options.src} -->
|
|
36
34
|
${fileContents}`
|
|
37
35
|
}
|
|
36
|
+
|
|
37
|
+
// maybe support...
|
|
38
|
+
function legacyCODE(content, options, config) {
|
|
39
|
+
|
|
40
|
+
}
|
package/lib/transforms/remote.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
const regexUtils = require('../utils/regex')
|
|
2
2
|
const remoteRequest = require('../utils/remoteRequest')
|
|
3
3
|
|
|
4
|
-
module.exports = function REMOTE(
|
|
5
|
-
|
|
4
|
+
module.exports = function REMOTE(api) {
|
|
5
|
+
// console.log('REMOTE api', api)
|
|
6
|
+
const { options, blockContent, settings } = api
|
|
7
|
+
const { regex } = settings
|
|
8
|
+
// console.log('MAKE REMOTE REQUEST')
|
|
9
|
+
const remoteContent = remoteRequest(options.url)
|
|
6
10
|
if (!remoteContent) {
|
|
7
|
-
return
|
|
11
|
+
return blockContent
|
|
8
12
|
}
|
|
9
13
|
if (options.keepComments) {
|
|
10
14
|
return remoteContent
|
|
11
15
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return remoteContent.replace(openTagRegex, '').replace(closeTagRegex, '')
|
|
16
|
+
// console.log('REMOTE', remoteContent)
|
|
17
|
+
return remoteContent.replace(regex.open, '').replace(regex.close, '')
|
|
15
18
|
}
|