markdown-magic 3.3.0 → 3.3.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.
@@ -0,0 +1,412 @@
1
+ const { test } = require('uvu')
2
+ const assert = require('uvu/assert')
3
+ const { deepLog } = require('./utils/logs')
4
+ const { getGlobGroupsFromArgs } = require('./globparse')
5
+
6
+ const DEBUG = true
7
+ const logger = (DEBUG) ? console.log : () => {}
8
+ const deepLogger = (DEBUG) ? deepLog : () => {}
9
+
10
+ function logInput(rawArgs) {
11
+ logger('\n───────────────────────')
12
+ logger('Input:')
13
+ logger(rawArgs.join(" "))
14
+ logger('───────────────────────\n')
15
+ }
16
+
17
+ test('test 1', () => {
18
+ const rawArgv = [ 'whatever=[uno]', 'nice', '-f', 'no', 'word', '=', '{ foo: bar }' ]
19
+ const globData = getGlobGroupsFromArgs(rawArgv)
20
+ //*
21
+ logInput(rawArgv)
22
+ deepLogger(globData)
23
+ })
24
+
25
+ const longArgs = [
26
+ 'test/fixtures/md/basic.md',
27
+ 'test/fixtures/md/error-missing-transforms-two.md',
28
+ 'test/fixtures/md/error-missing-transforms.md',
29
+ 'test/fixtures/md/error-no-block-transform-defined.md',
30
+ 'test/fixtures/md/error-unbalanced.md',
31
+ 'test/fixtures/md/format-inline.md',
32
+ 'test/fixtures/md/format-with-wacky-indentation.md',
33
+ 'test/fixtures/md/inline-two.md',
34
+ 'test/fixtures/md/inline.md',
35
+ 'test/fixtures/md/missing-transform.md',
36
+ 'test/fixtures/md/mixed.md',
37
+ 'test/fixtures/md/no-transforms.md',
38
+ 'test/fixtures/md/string.md',
39
+ 'test/fixtures/md/syntax-legacy-colon.md',
40
+ 'test/fixtures/md/syntax-legacy-query.md',
41
+ 'test/fixtures/md/transform-code.md',
42
+ 'test/fixtures/md/transform-custom.md',
43
+ 'test/fixtures/md/transform-file.md',
44
+ 'test/fixtures/md/transform-remote.md',
45
+ 'test/fixtures/md/transform-toc.md',
46
+ 'test/fixtures/md/transform-wordCount.md',
47
+ 'debug',
48
+ '--transform',
49
+ 'test/fixtures/md/transform-code.md',
50
+ 'test/fixtures/md/transform-custom.md',
51
+ 'test/fixtures/md/transform-file.md',
52
+ 'test/fixtures/md/transform-remote.md',
53
+ 'test/fixtures/md/transform-toc.md',
54
+ 'test/fixtures/md/transform-wordCount.md',
55
+ '1233535235',
56
+ '=',
57
+ 'hahah',
58
+ 'funky=hi',
59
+ '--ignore',
60
+ 'test/fixtures/output/basic.md',
61
+ 'test/fixtures/output/block-no-transform.md',
62
+ 'test/fixtures/output/error-missing-transforms-two.md',
63
+ 'test/fixtures/output/error-missing-transforms.md',
64
+ 'test/fixtures/output/fixture-code.md',
65
+ 'test/fixtures/output/format-inline.md',
66
+ 'test/fixtures/output/format-with-wacky-indentation.md',
67
+ 'test/fixtures/output/go-simple.md',
68
+ 'test/fixtures/output/inline-two.md',
69
+ 'test/fixtures/output/inline.md',
70
+ 'test/fixtures/output/missing-transform.md',
71
+ 'test/fixtures/output/mixed.md',
72
+ 'test/fixtures/output/params.md',
73
+ 'test/fixtures/output/remote.md',
74
+ 'test/fixtures/output/toc.md',
75
+ 'test/fixtures/output/transform-code.md',
76
+ 'test/fixtures/output/transform-custom.md',
77
+ 'test/fixtures/output/transform-file.md',
78
+ 'test/fixtures/output/transform-remote.md',
79
+ 'test/fixtures/output/transform-toc.md',
80
+ 'test/fixtures/output/transform-wordCount.md',
81
+ 'test/fixtures/output/with-wacky-indentation.md',
82
+ '--lol',
83
+ '--whatever',
84
+ 'test/fixtures/md/syntax-legacy-colon.md',
85
+ 'test/fixtures/md/syntax-legacy-query.md',
86
+ '--foo=bar',
87
+ '--fun',
88
+ 'lol.md',
89
+ 'what=no.md',
90
+ 'x',
91
+ 'xno.md',
92
+ 'what'
93
+ ]
94
+
95
+ test('getGlobGroupsFromArgs returns globs', () => {
96
+ /* CLI command with list of files already passed in
97
+ node ./cli.js test/fixtures/md/**.md debug --transform test/fixtures/md/transform-**.md 1233535235 = hahah funky=hi --ignore test/fixtures/output/**.md --lol --whatever test/fixtures/md/syntax-**.md --foo=bar --fun lol.md what=no.md x 'xno.md' what
98
+ */
99
+ const globData = getGlobGroupsFromArgs(longArgs)
100
+ //*
101
+ logInput(longArgs)
102
+ deepLogger(globData)
103
+ /** */
104
+ assert.equal(globData.globGroups, [
105
+ {
106
+ key: '',
107
+ rawKey: '',
108
+ values: [
109
+ 'test/fixtures/md/basic.md',
110
+ 'test/fixtures/md/error-missing-transforms-two.md',
111
+ 'test/fixtures/md/error-missing-transforms.md',
112
+ 'test/fixtures/md/error-no-block-transform-defined.md',
113
+ 'test/fixtures/md/error-unbalanced.md',
114
+ 'test/fixtures/md/format-inline.md',
115
+ 'test/fixtures/md/format-with-wacky-indentation.md',
116
+ 'test/fixtures/md/inline-two.md',
117
+ 'test/fixtures/md/inline.md',
118
+ 'test/fixtures/md/missing-transform.md',
119
+ 'test/fixtures/md/mixed.md',
120
+ 'test/fixtures/md/no-transforms.md',
121
+ 'test/fixtures/md/string.md',
122
+ 'test/fixtures/md/syntax-legacy-colon.md',
123
+ 'test/fixtures/md/syntax-legacy-query.md',
124
+ 'test/fixtures/md/transform-code.md',
125
+ 'test/fixtures/md/transform-custom.md',
126
+ 'test/fixtures/md/transform-file.md',
127
+ 'test/fixtures/md/transform-remote.md',
128
+ 'test/fixtures/md/transform-toc.md',
129
+ 'test/fixtures/md/transform-wordCount.md'
130
+ ]
131
+ },
132
+ {
133
+ key: 'transform',
134
+ rawKey: '--transform',
135
+ values: [
136
+ 'test/fixtures/md/transform-code.md',
137
+ 'test/fixtures/md/transform-custom.md',
138
+ 'test/fixtures/md/transform-file.md',
139
+ 'test/fixtures/md/transform-remote.md',
140
+ 'test/fixtures/md/transform-toc.md',
141
+ 'test/fixtures/md/transform-wordCount.md'
142
+ ]
143
+ },
144
+ {
145
+ key: 'ignore',
146
+ rawKey: '--ignore',
147
+ values: [
148
+ 'test/fixtures/output/basic.md',
149
+ 'test/fixtures/output/block-no-transform.md',
150
+ 'test/fixtures/output/error-missing-transforms-two.md',
151
+ 'test/fixtures/output/error-missing-transforms.md',
152
+ 'test/fixtures/output/fixture-code.md',
153
+ 'test/fixtures/output/format-inline.md',
154
+ 'test/fixtures/output/format-with-wacky-indentation.md',
155
+ 'test/fixtures/output/go-simple.md',
156
+ 'test/fixtures/output/inline-two.md',
157
+ 'test/fixtures/output/inline.md',
158
+ 'test/fixtures/output/missing-transform.md',
159
+ 'test/fixtures/output/mixed.md',
160
+ 'test/fixtures/output/params.md',
161
+ 'test/fixtures/output/remote.md',
162
+ 'test/fixtures/output/toc.md',
163
+ 'test/fixtures/output/transform-code.md',
164
+ 'test/fixtures/output/transform-custom.md',
165
+ 'test/fixtures/output/transform-file.md',
166
+ 'test/fixtures/output/transform-remote.md',
167
+ 'test/fixtures/output/transform-toc.md',
168
+ 'test/fixtures/output/transform-wordCount.md',
169
+ 'test/fixtures/output/with-wacky-indentation.md'
170
+ ]
171
+ },
172
+ {
173
+ key: 'whatever',
174
+ rawKey: '--whatever',
175
+ values: [
176
+ 'test/fixtures/md/syntax-legacy-colon.md',
177
+ 'test/fixtures/md/syntax-legacy-query.md'
178
+ ]
179
+ },
180
+ { key: 'fun', rawKey: '--fun', values: [ 'lol.md' ] }
181
+ ])
182
+ })
183
+
184
+ test('test 2', () => {
185
+ /* CLI command with list of files already passed in
186
+ node ./cli.js --file '**.md' 'funky**.md' billy --foo 'bar*123'
187
+ */
188
+ const rawArgv = [ '--file', '**.md', 'funky**.md', 'billy', '--foo', 'bar*123' ]
189
+
190
+ logger(rawArgv.join(" "))
191
+
192
+ const globData = getGlobGroupsFromArgs(rawArgv, {
193
+ globKeys: ['file']
194
+ })
195
+ //*
196
+ deepLogger(globData)
197
+ /** */
198
+ assert.equal(globData, {
199
+ globGroups: [ { key: 'file', rawKey: '--file', values: [ '**.md', 'funky**.md' ] } ],
200
+ otherOpts: [ 'billy', '--foo', 'bar*123' ]
201
+ })
202
+ })
203
+
204
+ test('Handles multiple string values and groups them', () => {
205
+ /* CLI command with list of files already passed in
206
+ node ./cli.js 'test/fixtures/md/bar.md' 'test/fixtures/output/foo.md'
207
+ */
208
+ const rawArgv = [ 'test/fixtures/md/bar.md', 'test/fixtures/output/foo.md' ]
209
+
210
+ const globData = getGlobGroupsFromArgs(rawArgv)
211
+ //*
212
+ logInput(rawArgv)
213
+ deepLogger(globData)
214
+ /** */
215
+ assert.equal(globData, {
216
+ globGroups: [
217
+ {
218
+ key: '',
219
+ rawKey: '',
220
+ values: [ 'test/fixtures/md/bar.md', 'test/fixtures/output/foo.md' ]
221
+ }
222
+ ],
223
+ otherOpts: []
224
+ })
225
+ })
226
+
227
+ test('Handles multiple string GLOB values and groups them', () => {
228
+ /* CLI command with list of files already passed in
229
+ node ./cli.js 'test/fixtures/md/**.md' 'test/fixtures/output/**.md'
230
+ */
231
+ const rawArgv = [ 'test/fixtures/md/**.md', 'test/fixtures/output/**.md' ]
232
+
233
+ const globData = getGlobGroupsFromArgs(rawArgv)
234
+ //*
235
+ logInput(rawArgv)
236
+ deepLogger(globData)
237
+ /** */
238
+ assert.equal(globData, {
239
+ globGroups: [
240
+ {
241
+ key: '',
242
+ rawKey: '',
243
+ values: [ 'test/fixtures/md/**.md', 'test/fixtures/output/**.md' ]
244
+ }
245
+ ],
246
+ otherOpts: []
247
+ })
248
+ })
249
+
250
+
251
+ test('Handles globKey set with multiple file/glob like values supplied afterwards', () => {
252
+ /* CLI command with list of files already passed in
253
+ node ./cli.js --file 'foobar.md' "funktown/bar.md" '**.md' 'funky**.md' billy --foo 'bar*123'
254
+ */
255
+ const rawArgv = [
256
+ '--file',
257
+ 'foobar.md',
258
+ 'funktown/bar.md',
259
+ '**.md',
260
+ 'funky**.md',
261
+ 'billy',
262
+ '--foo',
263
+ 'bar*123'
264
+ ]
265
+
266
+ logger(rawArgv.join(" "))
267
+
268
+ const globData = getGlobGroupsFromArgs(rawArgv, {
269
+ globKeys: ['file']
270
+ })
271
+ //*
272
+ logInput(rawArgv)
273
+ deepLogger(globData)
274
+ /** */
275
+ assert.equal(globData, {
276
+ globGroups: [ { key: 'file', rawKey: '--file', values: [
277
+ 'foobar.md',
278
+ 'funktown/bar.md',
279
+ '**.md',
280
+ 'funky**.md'
281
+ ]
282
+ }
283
+ ],
284
+ otherOpts: [ 'billy', '--foo', 'bar*123' ]
285
+ })
286
+ })
287
+
288
+ test('Handles mixed strings, glob strings, array strings, and regex strings', () => {
289
+ /* CLI command with list of files already passed in
290
+ node ./cli.js --file 'test/fixtures/md/**.md' 'test/fixtures/output/**.md' '[foo.md, bar.whatever.md, /patter.md/]'
291
+ */
292
+ const rawArgv = [
293
+ '--file',
294
+ 'funktown/bar.md',
295
+ 'test/fixtures/md/**.md',
296
+ 'test/fixtures/output/**.md',
297
+ '[foo.md, bar.whatever.md, /patter.md/]',
298
+ '/funk.md/'
299
+ ]
300
+
301
+ logger(rawArgv.join(" "))
302
+
303
+ const globData = getGlobGroupsFromArgs(rawArgv, {
304
+ globKeys: ['file']
305
+ })
306
+ //*
307
+ logInput(rawArgv)
308
+ deepLogger(globData)
309
+ /** */
310
+ assert.equal(globData, {
311
+ globGroups: [
312
+ {
313
+ key: 'file',
314
+ rawKey: '--file',
315
+ values: [
316
+ 'funktown/bar.md',
317
+ 'test/fixtures/md/**.md',
318
+ 'test/fixtures/output/**.md',
319
+ 'foo.md',
320
+ 'bar.whatever.md',
321
+ /patter\.md/,
322
+ /funk\.md/
323
+ ]
324
+ }
325
+ ],
326
+ otherOpts: []
327
+ })
328
+ })
329
+
330
+ test('Handles string arrays if globKeys set', () => {
331
+ /* CLI command with list of files already passed in
332
+ node ./cli.js --file '[**.md, /xyz**.md/]' 'funky**.md' billy --foo 'bar*123' --fuzz test/fixtures/output/**.md
333
+ */
334
+ const rawArgv = [
335
+ '--file',
336
+ '[**.md, /xyz**.md/]',
337
+ 'funky**.md',
338
+ 'billy',
339
+ '--foo',
340
+ 'bar*123',
341
+ '--fuzz',
342
+ 'test/fixtures/output/basic.md',
343
+ 'test/fixtures/output/block-no-transform.md',
344
+ 'test/fixtures/output/error-missing-transforms-two.md',
345
+ 'test/fixtures/output/error-missing-transforms.md',
346
+ 'test/fixtures/output/fixture-code.md',
347
+ 'test/fixtures/output/format-inline.md',
348
+ 'test/fixtures/output/format-with-wacky-indentation.md',
349
+ 'test/fixtures/output/go-simple.md',
350
+ 'test/fixtures/output/inline-two.md',
351
+ 'test/fixtures/output/inline.md',
352
+ 'test/fixtures/output/missing-transform.md',
353
+ 'test/fixtures/output/mixed.md',
354
+ 'test/fixtures/output/params.md',
355
+ 'test/fixtures/output/remote.md',
356
+ 'test/fixtures/output/toc.md',
357
+ 'test/fixtures/output/transform-code.md',
358
+ 'test/fixtures/output/transform-custom.md',
359
+ 'test/fixtures/output/transform-file.md',
360
+ 'test/fixtures/output/transform-remote.md',
361
+ 'test/fixtures/output/transform-toc.md',
362
+ 'test/fixtures/output/transform-wordCount.md',
363
+ 'test/fixtures/output/with-wacky-indentation.md'
364
+ ]
365
+ const globData = getGlobGroupsFromArgs(rawArgv, {
366
+ globKeys: ['file']
367
+ })
368
+ //*
369
+ logInput(rawArgv)
370
+ deepLogger(globData)
371
+ /** */
372
+ assert.equal(globData, {
373
+ globGroups: [
374
+ {
375
+ key: 'file',
376
+ rawKey: '--file',
377
+ values: [ '**.md', /xyz\*\*\.md/, 'funky**.md' ]
378
+ },
379
+ {
380
+ key: 'fuzz',
381
+ rawKey: '--fuzz',
382
+ values: [
383
+ 'test/fixtures/output/basic.md',
384
+ 'test/fixtures/output/block-no-transform.md',
385
+ 'test/fixtures/output/error-missing-transforms-two.md',
386
+ 'test/fixtures/output/error-missing-transforms.md',
387
+ 'test/fixtures/output/fixture-code.md',
388
+ 'test/fixtures/output/format-inline.md',
389
+ 'test/fixtures/output/format-with-wacky-indentation.md',
390
+ 'test/fixtures/output/go-simple.md',
391
+ 'test/fixtures/output/inline-two.md',
392
+ 'test/fixtures/output/inline.md',
393
+ 'test/fixtures/output/missing-transform.md',
394
+ 'test/fixtures/output/mixed.md',
395
+ 'test/fixtures/output/params.md',
396
+ 'test/fixtures/output/remote.md',
397
+ 'test/fixtures/output/toc.md',
398
+ 'test/fixtures/output/transform-code.md',
399
+ 'test/fixtures/output/transform-custom.md',
400
+ 'test/fixtures/output/transform-file.md',
401
+ 'test/fixtures/output/transform-remote.md',
402
+ 'test/fixtures/output/transform-toc.md',
403
+ 'test/fixtures/output/transform-wordCount.md',
404
+ 'test/fixtures/output/with-wacky-indentation.md'
405
+ ]
406
+ }
407
+ ],
408
+ otherOpts: [ 'billy', '--foo', 'bar*123' ]
409
+ })
410
+ })
411
+
412
+ test.run()
package/lib/index.js CHANGED
@@ -230,6 +230,15 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
230
230
  })
231
231
  })
232
232
 
233
+ if (debug) {
234
+ // info(`pathsPromise:`)
235
+ // logger(pathsPromise)
236
+ // logger()
237
+ /*
238
+ process.exit(1)
239
+ /** */
240
+ }
241
+
233
242
  let files = []
234
243
  try {
235
244
  files = (await Promise.all(pathsPromise)).flat().filter(onlyUnique)
@@ -238,6 +247,8 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
238
247
  // console.log(e.message)
239
248
  throw new Error(e)
240
249
  }
250
+
251
+
241
252
  // logger('files', files)
242
253
  // return
243
254
  // logger('globs', globs)
@@ -250,23 +261,42 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
250
261
  process.exit(1)
251
262
  /** */
252
263
 
264
+ if (debug) {
265
+ info(`files:`)
266
+ logger(files)
267
+ logger()
268
+ /*
269
+ process.exit(1)
270
+ /** */
271
+ }
253
272
 
254
273
 
274
+
255
275
  const patterns = getBlockRegex({
256
276
  syntax,
257
277
  openText: open,
258
278
  closeText: close
259
279
  })
260
280
 
261
- const blocksByPath = files.map(async (file) => {
262
- const text = await readFile(file, 'utf8')
281
+ if (debug) {
282
+ console.log(`patterns:`, patterns)
283
+ }
284
+
285
+
286
+ const fileContents = await Promise.all(files.map((file) => readFile(file, 'utf8')))
287
+
288
+ const blocksByPath = files.map((file, i) => {
289
+ const text = fileContents[i]
263
290
  let foundBlocks = {}
264
291
  try {
292
+
293
+ // console.log('try, file', file)
265
294
  foundBlocks = parseBlocks(text, {
266
295
  syntax,
267
296
  open,
268
297
  close,
269
298
  })
299
+ // console.log('foundBlocks', foundBlocks.blocks.length)
270
300
  } catch (e) {
271
301
  throw new Error(`${e.message}\nFix content in ${file}\n`)
272
302
  }
@@ -278,7 +308,7 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
278
308
  }
279
309
  })
280
310
 
281
- const blocks = (await Promise.all(blocksByPath)).map((item) => {
311
+ const blocks = blocksByPath.map((item) => {
282
312
  const dir = path.dirname(item.srcPath)
283
313
  item.dependencies = []
284
314
  item.blocks.forEach((block) => {
@@ -292,6 +322,19 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
292
322
  })
293
323
  return item
294
324
  })
325
+
326
+
327
+ // logger(blocks[0].blocks)
328
+
329
+
330
+ if (debug) {
331
+ info(`Found blocks:`)
332
+ logger(blocks)
333
+ logger()
334
+ /*
335
+ process.exit(1)
336
+ /** */
337
+ }
295
338
  /*
296
339
  console.log('blocks')
297
340
  deepLog(blocks)
@@ -532,9 +575,8 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
532
575
  logger(planOutput.join('\n'))
533
576
  } else {
534
577
  info(`Execution plan:`, silent, "📑 ")
535
- logger('\nNo transforms to run. Exiting early.')
536
- logger('If you think this is incorrect. Verify your comment blocks in your src and the settings in your config.')
537
- logger()
578
+ logger('\nNo transforms to run. Exiting markdown magic early.')
579
+ logger('If you think this is incorrect, verify your comment blocks in your src and the settings in your config.')
538
580
  }
539
581
  }
540
582
 
@@ -562,7 +604,7 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
562
604
 
563
605
  if (!dryRun && plan.length) {
564
606
  logger()
565
- info(`Apply changes:`, silent, "✏️ ")
607
+ info(`Apply changes:`, silent, "✏️ ")
566
608
 
567
609
  /* Check for diffs in src vs output only */
568
610
  // if (outputDir) {
@@ -625,6 +667,8 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
625
667
  /*
626
668
  process.exit(1)
627
669
  /** */
670
+ logger()
671
+ info(`Results:`, silent, "💫 ")
628
672
 
629
673
  /*
630
674
  TODO:
@@ -59,10 +59,10 @@ async function processContents(text, config) {
59
59
  throw new Error(`${e.message}\nFix content in ${srcPath}\n`)
60
60
  }
61
61
 
62
- if (debug) {
63
- console.log(`foundBlocks ${srcPath}`)
64
- deepLog(foundBlocks)
65
- }
62
+ // if (debug) {
63
+ // console.log(`foundBlocks ${srcPath}`)
64
+ // deepLog(foundBlocks)
65
+ // }
66
66
  /*
67
67
  deepLog(foundBlocks)
68
68
  process.exit(1)
@@ -173,7 +173,7 @@ async function processContents(text, config) {
173
173
  /** */
174
174
 
175
175
  if (debug) {
176
- console.log('afterContent', afterContent)
176
+ // console.log('afterContent', afterContent)
177
177
  }
178
178
 
179
179
  if (!currentTransformFn) {
@@ -199,11 +199,18 @@ async function processContents(text, config) {
199
199
  // console.log('COMMENT_CLOSE_REGEX', COMMENT_CLOSE_REGEX)
200
200
  // console.log('formattedNewContent', formattedNewContent)
201
201
  // console.log('fix', fix)
202
- const preserveIndent = (true || options.preserveIndent) ? block.indentation.length + match.content.indentation : block.indentation.length
202
+
203
+ let preserveIndent = 0
204
+ if (match.content.indentation) {
205
+ preserveIndent = match.content.indentation
206
+ } else if (preserveIndent === 0) {
207
+ preserveIndent = block.indentation.length
208
+ }
209
+ // console.log('preserveIndent', preserveIndent)
203
210
  const indent = indentString(fix, preserveIndent)
204
211
  const newCont = `${openTag}${indent}${closeTag}`
205
212
  /* Replace original contents */
206
- // Must use replacer function because strings get coearced to regex or something
213
+ // Must use replacer function because strings get coerced to regex or something
207
214
  const newContents = md.replace(block.value, () => newCont)
208
215
  /*
209
216
  deepLog(newContents)
@@ -8,7 +8,7 @@ const { resolveGithubContents, isGithubLink } = require('./resolve-github-file')
8
8
 
9
9
  const GITHUB_LINK = /https:\/\/github\.com\/([^/\s]*)\/([^/\s]*)\/blob\//
10
10
  const GIST_LINK = /https:\/\/gist\.github\.com\/([^/\s]*)\/([^/\s]*)(\/)?/
11
- const RAW_URL_LIKE = /^([A-Za-z0-9_]*)\.([A-Za-z0-9_]*)\/(.*)/
11
+ const RAW_URL_LIKE = /^([A-Za-z0-9_]+)\.([A-Za-z0-9_]*)\/(.*)/
12
12
 
13
13
  /**
14
14
  * Options for specifying source code to include in documentation.
@@ -17,6 +17,7 @@ const RAW_URL_LIKE = /^([A-Za-z0-9_]*)\.([A-Za-z0-9_]*)\/(.*)/
17
17
  * @property {string} [syntax] - The syntax of the code. If not specified, it will be inferred by fileType.
18
18
  * @property {string} [header] - The header comment to add to the code snippet. Useful for pointing to relative source directory or adding live doc links.
19
19
  * @property {string} [lines] - A range of lines of code to include from the file. The line range should be defined like "lines=22-44".
20
+ * @property {string} [section] - A section of code to include from the file. Defined like "section=SECTION_NAME". The code should have "// SECTION_NAME" surrounding the block of text.
20
21
  * @property {boolean} [trimDeadCode] - Remove multi-line comments that start with `//` from the code.
21
22
  * @example
22
23
  ```md
@@ -65,7 +66,7 @@ module.exports = async function CODE(api) {
65
66
  const fileDir = (srcPath) ? path.dirname(srcPath) : process.cwd()
66
67
  codeFilePath = path.resolve(fileDir, src)
67
68
  /* If the path looks like a URL, attempt to resolve it */
68
- const isUrlLike = src.match(RAW_URL_LIKE)
69
+ const isUrlLike = !src.startsWith('./') && !src.startsWith('../') && src.match(RAW_URL_LIKE)
69
70
  if (isUrlLike) {
70
71
  remoteContent = await resolveRemoteContent(options, settings, srcPath)
71
72
  code = remoteContent
@@ -81,8 +82,12 @@ module.exports = async function CODE(api) {
81
82
  if (isUrlLike) {
82
83
  throw new Error(`Unable to resolve ${src}`)
83
84
  }
84
- console.log(`FILE NOT FOUND ${codeFilePath}`)
85
- throw e
85
+ if (src === './relative/path/to/code.js') {
86
+ return api.content
87
+ } else {
88
+ console.log(`FILE NOT FOUND ${codeFilePath}`)
89
+ throw e
90
+ }
86
91
  }
87
92
  }
88
93
  } else {
@@ -133,6 +138,14 @@ module.exports = async function CODE(api) {
133
138
  }
134
139
  }
135
140
 
141
+ if (options.section) {
142
+ code = findInnerBlock(code, options.section)
143
+ }
144
+
145
+ if (options.symbol && syntax === 'js') {
146
+ // Code to get function block or class block or variable block
147
+ }
148
+
136
149
  /* Ensure lowercase on syntax */
137
150
  syntax = (syntax || '').toLowerCase()
138
151
 
@@ -160,7 +173,7 @@ module.exports = async function CODE(api) {
160
173
  }
161
174
 
162
175
  // trim leading and trailing spaces/line breaks in code and keeps the indentation of the first non-empty line
163
- code = code.replace(/^(?:[\t ]*(?:\r?\n|\r))+|\s+$/g, '')
176
+ code = (code || '').replace(/^(?:[\t ]*(?:\r?\n|\r))+|\s+$/g, '')
164
177
 
165
178
  let header = ''
166
179
  if (options.header) {
@@ -199,4 +212,34 @@ async function resolveRemoteContent(options, settings, srcPath) {
199
212
  }
200
213
 
201
214
  return remoteContent
215
+ }
216
+
217
+
218
+ function findInnerBlock(str, text) {
219
+ const matches = matchInnerContent(str, text, text)
220
+ if (!matches.length) {
221
+ throw new Error(`No blocks match ${text} in code`)
222
+ }
223
+ if (matches.length > 1) {
224
+ throw new Error(`Multiple blocks match ${text} in code`)
225
+ }
226
+
227
+ return matches[0]
228
+ }
229
+
230
+ function matchInnerContent(str, open, close) {
231
+ const pattern = new RegExp(`\\/\\/ ${open}\\n([\\s\\S]*?)\\n\\/\\/ ${close}`, 'g')
232
+
233
+ // console.log('closeTagRegex', closeTagRegex)
234
+ var matches
235
+ var blocks = []
236
+ while ((matches = pattern.exec(str)) !== null) {
237
+ if (matches.index === pattern.lastIndex) {
238
+ pattern.lastIndex++ // avoid infinite loops with zero-width matches
239
+ }
240
+ const [ _match, innerContent ] = matches
241
+ console.log('matches', matches)
242
+ blocks.push(innerContent)
243
+ }
244
+ return blocks
202
245
  }