markdown-magic 2.5.1 → 2.6.1
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 +20 -0
- package/cli.js +0 -0
- package/lib/index.js +219 -0
- package/lib/processFile.js +2 -1
- package/lib/transforms/toc.js +5 -3
- package/lib/updateContents.js +8 -2
- package/lib/utils/_md.test.js +63 -0
- package/lib/utils/new-parser.js +412 -0
- package/lib/utils/new-parser.test.js +324 -0
- package/lib/utils/regex.js +20 -6
- package/lib/utils/weird-parse.js +230 -0
- package/lib/utils/weird-parse.test.js +217 -0
- package/package.json +17 -3
- package/.github/FUNDING.yml +0 -1
- package/.github/workflows/test.yml +0 -40
- package/.travis.yml +0 -10
- package/examples/basic-usage.js +0 -5
- package/examples/generate-readme.js +0 -37
- package/examples/package.json +0 -14
- package/examples/plugin-example.js +0 -16
- package/markdown.config.js +0 -13
- package/test/fixtures/CODE-test.md +0 -21
- package/test/fixtures/CUSTOM-async.md +0 -9
- package/test/fixtures/CUSTOM-test.md +0 -9
- package/test/fixtures/FILE-test.md +0 -11
- package/test/fixtures/REMOTE-test.md +0 -12
- package/test/fixtures/TOC-test.md +0 -39
- package/test/fixtures/custom-match-word-test.md +0 -9
- package/test/fixtures/local-code-file-lines.js +0 -6
- package/test/fixtures/local-code-file.js +0 -6
- package/test/fixtures/nested/file.md +0 -9
- package/test/fixtures/test.md +0 -432
- package/test/main.test.js +0 -319
package/test/main.test.js
DELETED
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const test = require('ava')
|
|
4
|
-
const rimraf = require('rimraf')
|
|
5
|
-
const sinon = require('sinon')
|
|
6
|
-
const markdownMagic= require('../index')
|
|
7
|
-
|
|
8
|
-
const CLEAN_UP = true
|
|
9
|
-
const testMarkdownPath = path.join(__dirname, 'fixtures', 'test.md')
|
|
10
|
-
const outputDir = path.join(__dirname, 'fixtures', 'output')
|
|
11
|
-
const delay = (ms) => new Promise(res => setTimeout(res, ms))
|
|
12
|
-
const matchWord = 'AUTO-GENERATED-CONTENTX'
|
|
13
|
-
const defaultConfig = {
|
|
14
|
-
matchWord: matchWord
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Test markdownMagic Function
|
|
18
|
-
*/
|
|
19
|
-
test('if valid string path supplied', t => {
|
|
20
|
-
markdownMagic(testMarkdownPath, defaultConfig)
|
|
21
|
-
t.pass()
|
|
22
|
-
// emptyDirectory(outputDir)
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
test('if valid glob pattern supplied', t => {
|
|
26
|
-
const config = {
|
|
27
|
-
outputDir: outputDir
|
|
28
|
-
}
|
|
29
|
-
markdownMagic(['test/fixtures/**/*md', '!test/fixtures/output/*.md'], config)
|
|
30
|
-
t.pass()
|
|
31
|
-
// empty dir
|
|
32
|
-
// rimraf.sync(outputDir)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test('if valid config supplied', t => {
|
|
36
|
-
markdownMagic(testMarkdownPath, defaultConfig)
|
|
37
|
-
t.pass()
|
|
38
|
-
// emptyDirectory(outputDir)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
test.cb('if callback function supplied, call it once', t => {
|
|
42
|
-
const callback = sinon.spy()
|
|
43
|
-
markdownMagic(testMarkdownPath, defaultConfig, () => {
|
|
44
|
-
callback()
|
|
45
|
-
t.true(callback.calledOnce)
|
|
46
|
-
t.end()
|
|
47
|
-
})
|
|
48
|
-
// emptyDirectory(outputDir)
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
test.cb('if callback function supplied, as second arg, call it once', t => {
|
|
52
|
-
const callback = sinon.spy()
|
|
53
|
-
markdownMagic(testMarkdownPath, defaultConfig, () => {
|
|
54
|
-
callback()
|
|
55
|
-
t.true(callback.calledOnce)
|
|
56
|
-
t.end()
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
// emptyDirectory(outputDir)
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Test Config settings
|
|
64
|
-
*/
|
|
65
|
-
|
|
66
|
-
test.cb('if config.outputDir supplied, make new file', t => {
|
|
67
|
-
const config = {
|
|
68
|
-
outputDir: outputDir,
|
|
69
|
-
...defaultConfig
|
|
70
|
-
}
|
|
71
|
-
markdownMagic(testMarkdownPath, config, function() {
|
|
72
|
-
const newfile = path.join(outputDir, 'test.md')
|
|
73
|
-
const fileWasCreated = filePathExists(newfile)
|
|
74
|
-
t.true(fileWasCreated)
|
|
75
|
-
t.end()
|
|
76
|
-
// remove test file after assertion
|
|
77
|
-
// emptyDirectory(outputDir)
|
|
78
|
-
})
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
test.cb('if config.matchWord supplied, use it for comment matching', t => {
|
|
82
|
-
const filePath = path.join(__dirname, 'fixtures', 'custom-match-word-test.md')
|
|
83
|
-
const config = {
|
|
84
|
-
matchWord: 'YOLO',
|
|
85
|
-
outputDir: outputDir
|
|
86
|
-
}
|
|
87
|
-
markdownMagic(filePath, config, () => {
|
|
88
|
-
const newfile = path.join(config.outputDir, 'custom-match-word-test.md')
|
|
89
|
-
const newContent = fs.readFileSync(newfile, 'utf8')
|
|
90
|
-
t.regex(newContent, /module\.exports\.run/, 'local code snippet inserted')
|
|
91
|
-
t.end()
|
|
92
|
-
})
|
|
93
|
-
// remove test file after assertion
|
|
94
|
-
// rimraf.sync(outputDir)
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
test.cb('<!-- AUTO-GENERATED-CONTENT:START (TOC)-->', t => {
|
|
98
|
-
const filePath = path.join(__dirname, 'fixtures', 'TOC-test.md')
|
|
99
|
-
const config = {
|
|
100
|
-
outputDir: outputDir
|
|
101
|
-
}
|
|
102
|
-
markdownMagic(filePath, config, () => {
|
|
103
|
-
const newfile = path.join(config.outputDir, 'TOC-test.md')
|
|
104
|
-
const newContent = fs.readFileSync(newfile, 'utf8')
|
|
105
|
-
|
|
106
|
-
const expectedTest1 = `
|
|
107
|
-
<!-- AUTO-GENERATED-CONTENT:START (TOC) - Test #1: without option and the content with empty line -->
|
|
108
|
-
- [Title A](#title-a)
|
|
109
|
-
- [Subtitle z](#subtitle-z)
|
|
110
|
-
- [Subtitle x](#subtitle-x)
|
|
111
|
-
- [Title B](#title-b)
|
|
112
|
-
- [Title C](#title-c)
|
|
113
|
-
<!-- AUTO-GENERATED-CONTENT:END -->`
|
|
114
|
-
|
|
115
|
-
// console.log('expectedTest1', expectedTest1)
|
|
116
|
-
// console.log('newContent', newContent)
|
|
117
|
-
const regexTest1 = new RegExp(`(?=${expectedTest1.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})`, "i")
|
|
118
|
-
t.regex(newContent, regexTest1, 'Test #1 : without option and the content with empty line')
|
|
119
|
-
|
|
120
|
-
const expectedTest2 = `
|
|
121
|
-
<!-- AUTO-GENERATED-CONTENT:START (TOC:collapse=true&collapseText=Click Me) - Test #2: with collapse options and the content with 'aaaaaaaaa' -->
|
|
122
|
-
<details>
|
|
123
|
-
<summary>Click Me</summary>
|
|
124
|
-
|
|
125
|
-
- [Title A](#title-a)
|
|
126
|
-
- [Subtitle z](#subtitle-z)
|
|
127
|
-
- [Subtitle x](#subtitle-x)
|
|
128
|
-
- [Title B](#title-b)
|
|
129
|
-
- [Title C](#title-c)
|
|
130
|
-
|
|
131
|
-
</details>
|
|
132
|
-
<!-- AUTO-GENERATED-CONTENT:END -->`
|
|
133
|
-
const regexTest2 = new RegExp(`(?=${expectedTest2.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})`, "i")
|
|
134
|
-
t.regex(newContent, regexTest2, "Test #2: with collapse options and the content with 'aaaaaaaaa'")
|
|
135
|
-
|
|
136
|
-
const expectedTest3 = `
|
|
137
|
-
<!-- AUTO-GENERATED-CONTENT:START (TOC:collapse=true&collapseText=Click Me=I have the power) - Test #3: with collapseText contains character '=' -->
|
|
138
|
-
<details>
|
|
139
|
-
<summary>Click Me=I have the power</summary>
|
|
140
|
-
|
|
141
|
-
- [Title A](#title-a)
|
|
142
|
-
- [Subtitle z](#subtitle-z)
|
|
143
|
-
- [Subtitle x](#subtitle-x)
|
|
144
|
-
- [Title B](#title-b)
|
|
145
|
-
- [Title C](#title-c)
|
|
146
|
-
|
|
147
|
-
</details>
|
|
148
|
-
<!-- AUTO-GENERATED-CONTENT:END -->`
|
|
149
|
-
const regexTest3 = new RegExp(`(?=${expectedTest3.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})`, "i")
|
|
150
|
-
t.regex(newContent, regexTest3, "Test #3: with collapseText contains character '='")
|
|
151
|
-
|
|
152
|
-
const expectedTest4 = `
|
|
153
|
-
<!-- AUTO-GENERATED-CONTENT:START (TOC) - Test #4: without option and the content is empty -->
|
|
154
|
-
- [Title A](#title-a)
|
|
155
|
-
- [Subtitle z](#subtitle-z)
|
|
156
|
-
- [Subtitle x](#subtitle-x)
|
|
157
|
-
- [Title B](#title-b)
|
|
158
|
-
- [Title C](#title-c)
|
|
159
|
-
<!-- AUTO-GENERATED-CONTENT:END -->`
|
|
160
|
-
const regexTest4 = new RegExp(`(?=${expectedTest4.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})`, "i")
|
|
161
|
-
t.regex(newContent, regexTest4, 'Test #4 : without option and the content is empty')
|
|
162
|
-
|
|
163
|
-
const expectedTest5 = `
|
|
164
|
-
<!-- AUTO-GENERATED-CONTENT:START (TOC) - Test #5: without option and tags with same line -->
|
|
165
|
-
- [Title A](#title-a)
|
|
166
|
-
- [Subtitle z](#subtitle-z)
|
|
167
|
-
- [Subtitle x](#subtitle-x)
|
|
168
|
-
- [Title B](#title-b)
|
|
169
|
-
- [Title C](#title-c)
|
|
170
|
-
<!-- AUTO-GENERATED-CONTENT:END -->`
|
|
171
|
-
const regexTest5 = new RegExp(`(?=${expectedTest5.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})`, "i")
|
|
172
|
-
t.regex(newContent, regexTest5, 'Test #5 : without option and tags with same line')
|
|
173
|
-
|
|
174
|
-
t.end()
|
|
175
|
-
})
|
|
176
|
-
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Test Built in transforms
|
|
181
|
-
*/
|
|
182
|
-
test.cb('<!-- AUTO-GENERATED-CONTENT:START (CODE)-->', t => {
|
|
183
|
-
const filePath = path.join(__dirname, 'fixtures', 'CODE-test.md')
|
|
184
|
-
const config = { outputDir: outputDir }
|
|
185
|
-
const newfile = path.join(config.outputDir, 'CODE-test.md')
|
|
186
|
-
|
|
187
|
-
markdownMagic(filePath, config, function(err, data) {
|
|
188
|
-
// console.log('data', data)
|
|
189
|
-
const newContent = fs.readFileSync(newfile, 'utf8')
|
|
190
|
-
// check local code
|
|
191
|
-
t.regex(newContent, /module\.exports\.run/, 'local code snippet inserted')
|
|
192
|
-
// check local code with range lines
|
|
193
|
-
t.regex(newContent, /```js\n const baz = 'foobar'\n console\.log\(`Hello \${baz}`\)\n```/, 'local code snippet with range lines inserted')
|
|
194
|
-
// check remotely fetched code
|
|
195
|
-
t.regex(newContent, /require\('doxxx'\)/, 'remote code snippet inserted')
|
|
196
|
-
// check remotely fetched code with range lines
|
|
197
|
-
t.regex(newContent, /```json\n "author": "David Wells",\n "license": "MIT",\n```/, 'remote code snippet with range lines inserted')
|
|
198
|
-
|
|
199
|
-
t.end()
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
if (filePathExists(newfile)) {
|
|
203
|
-
// rimraf.sync(outputDir)
|
|
204
|
-
}
|
|
205
|
-
// remove test file after assertion
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Test Built in transforms
|
|
210
|
-
*/
|
|
211
|
-
test.cb('<!-- AUTO-GENERATED-CONTENT:START (FILE)-->', t => {
|
|
212
|
-
const filePath = path.join(__dirname, 'fixtures', 'FILE-test.md')
|
|
213
|
-
const config = { outputDir: outputDir }
|
|
214
|
-
const newfile = path.join(config.outputDir, 'FILE-test.md')
|
|
215
|
-
|
|
216
|
-
markdownMagic(filePath, config, function(err, data) {
|
|
217
|
-
// console.log('data', data)
|
|
218
|
-
const newContent = fs.readFileSync(newfile, 'utf8')
|
|
219
|
-
// check local code
|
|
220
|
-
t.regex(newContent, /module\.exports\.run/, 'local code snippet inserted')
|
|
221
|
-
// check local code with range lines
|
|
222
|
-
t.regex(newContent, /const baz = 'foobar'\n console\.log\(`Hello \${baz}`\)/, 'local code snippet with range lines inserted')
|
|
223
|
-
t.end()
|
|
224
|
-
})
|
|
225
|
-
|
|
226
|
-
if (filePathExists(newfile)) {
|
|
227
|
-
// rimraf.sync(outputDir)
|
|
228
|
-
}
|
|
229
|
-
// remove test file after assertion
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
test.cb('<!-- AUTO-GENERATED-CONTENT:START (REMOTE)-->', t => {
|
|
233
|
-
const filePath = path.join(__dirname, 'fixtures', 'REMOTE-test.md')
|
|
234
|
-
|
|
235
|
-
const config = { outputDir: outputDir }
|
|
236
|
-
markdownMagic(filePath, config, function() {
|
|
237
|
-
const newfile = path.join(config.outputDir, 'REMOTE-test.md')
|
|
238
|
-
const newContent = fs.readFileSync(newfile, 'utf8')
|
|
239
|
-
// check local code
|
|
240
|
-
t.regex(newContent, /Markdown Magic/, 'word "Markdown Magic" not found in remote block')
|
|
241
|
-
t.end()
|
|
242
|
-
// remove test file after assertion
|
|
243
|
-
// rimraf.sync(outputDir)
|
|
244
|
-
})
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
test.cb('<!-- AUTO-GENERATED-CONTENT:START (customTransform)-->', t => {
|
|
248
|
-
const filePath = path.join(__dirname, 'fixtures', 'CUSTOM-test.md')
|
|
249
|
-
|
|
250
|
-
const config = {
|
|
251
|
-
outputDir: outputDir,
|
|
252
|
-
transforms: {
|
|
253
|
-
/* Match <!-- AUTO-GENERATED-CONTENT:START (customTransform:optionOne=hi&optionOne=DUDE) --> */
|
|
254
|
-
customTransform(content, options) {
|
|
255
|
-
// options = { optionOne: hi, optionOne: DUDE}
|
|
256
|
-
return `This will replace all the contents of inside the comment ${options.optionOne}`
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
markdownMagic(filePath, config, function() {
|
|
261
|
-
const newfile = path.join(config.outputDir, 'CUSTOM-test.md')
|
|
262
|
-
// console.log('newfile', newfile)
|
|
263
|
-
const newContent = fs.readFileSync(newfile, 'utf8')
|
|
264
|
-
// console.log('newContent', newContent)
|
|
265
|
-
// check local code
|
|
266
|
-
t.regex(newContent, /will replace all the contents/, 'has custom transform data')
|
|
267
|
-
t.end()
|
|
268
|
-
// remove test file after assertion
|
|
269
|
-
// rimraf.sync(outputDir)
|
|
270
|
-
})
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
test.cb('Async <!-- AUTO-GENERATED-CONTENT:START (customAsync)-->', t => {
|
|
274
|
-
const filePath = path.join(__dirname, 'fixtures', 'CUSTOM-async.md')
|
|
275
|
-
|
|
276
|
-
const config = {
|
|
277
|
-
outputDir: outputDir,
|
|
278
|
-
transforms: {
|
|
279
|
-
/* Match <!-- AUTO-GENERATED-CONTENT:START (customAsync:optionOne=hi) --> */
|
|
280
|
-
async customAsync(content, options) {
|
|
281
|
-
await delay(500)
|
|
282
|
-
// options = { optionOne: hi, optionOne: DUDE}
|
|
283
|
-
return `async data here ${options.optionOne}`
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
markdownMagic(filePath, config, function() {
|
|
288
|
-
const newfile = path.join(config.outputDir, 'CUSTOM-async.md')
|
|
289
|
-
const newContent = fs.readFileSync(newfile, 'utf8')
|
|
290
|
-
// check local code
|
|
291
|
-
t.regex(newContent, /async data here hi/, 'has custom transform data')
|
|
292
|
-
t.end()
|
|
293
|
-
// remove test file after assertion
|
|
294
|
-
// rimraf.sync(outputDir)
|
|
295
|
-
})
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
test.after.always('cleanup', async t => {
|
|
299
|
-
if (CLEAN_UP) {
|
|
300
|
-
rimraf.sync(outputDir)
|
|
301
|
-
}
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
/*
|
|
305
|
-
Util functions
|
|
306
|
-
*/
|
|
307
|
-
function filePathExists(fp) {
|
|
308
|
-
try {
|
|
309
|
-
fs.accessSync(fp)
|
|
310
|
-
return true
|
|
311
|
-
} catch (err) {
|
|
312
|
-
return false
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
function emptyDirectory(filePath, callBack) {
|
|
317
|
-
rimraf.sync(filePath)
|
|
318
|
-
callBack && callBack(null)
|
|
319
|
-
}
|