markdown-magic 3.0.0 → 3.0.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 +43 -29
- package/lib/block-parser-js.test.js +148 -156
- package/lib/block-parser.js +255 -262
- package/lib/block-parser.test.js +43 -6
- package/lib/cli.js +30 -19
- package/lib/cli.test.js +73 -73
- package/lib/globals.d.ts +66 -0
- package/lib/index.js +43 -9
- package/lib/process-contents.js +80 -39
- package/lib/process-file.js +4 -1
- package/lib/transforms/code.js +4 -10
- package/lib/transforms/file.js +7 -10
- package/lib/transforms/index.js +0 -0
- package/lib/transforms/remote.js +2 -3
- package/lib/transforms/sectionToc.js +18 -0
- package/lib/transforms/toc.js +10 -335
- package/lib/types.js +11 -0
- package/lib/utils/fs.js +21 -19
- package/lib/utils/fs.test.js +4 -5
- package/lib/utils/logs.js +7 -2
- package/lib/utils/md/filters.js +5 -5
- package/lib/utils/md/find-code-blocks.js +16 -8
- package/lib/utils/md/find-frontmatter.js +11 -13
- package/lib/utils/md/find-frontmatter.test.js +2 -2
- package/lib/utils/md/find-html-tags.js +1 -1
- package/lib/utils/md/find-images-md.js +27 -0
- package/lib/utils/md/find-images.js +39 -34
- package/lib/utils/md/find-links.js +72 -54
- package/lib/utils/md/find-unmatched-html-tags.js +1 -2
- package/lib/utils/md/fixtures/file-with-links.md +10 -0
- package/lib/utils/md/md.test.js +72 -4
- package/lib/utils/md/parse.js +91 -67
- package/lib/utils/regex-timeout.js +2 -1
- package/lib/utils/regex.js +3 -2
- package/lib/utils/remoteRequest.js +1 -0
- package/lib/utils/syntax.js +3 -0
- package/lib/utils/text.js +71 -3
- package/lib/utils/text.test.js +3 -9
- package/lib/utils/toc.js +315 -0
- package/package.json +7 -3
- package/lib/options-parser.js +0 -498
- package/lib/options-parser.test.js +0 -1237
- package/lib/utils/html-to-json/compat.js +0 -42
- package/lib/utils/html-to-json/format.js +0 -64
- package/lib/utils/html-to-json/index.js +0 -37
- package/lib/utils/html-to-json/lexer.js +0 -345
- package/lib/utils/html-to-json/parser.js +0 -146
- package/lib/utils/html-to-json/stringify.js +0 -37
- package/lib/utils/html-to-json/tags.js +0 -171
package/lib/block-parser.js
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
const {
|
|
2
|
+
const { parse } = require('oparser')
|
|
3
3
|
const { getSyntaxInfo } = require('./utils/syntax')
|
|
4
|
-
const {
|
|
5
|
-
getFirstCharacter,
|
|
6
|
-
getLastCharacter,
|
|
7
|
-
getTextBetweenChars,
|
|
8
|
-
stripIndent,
|
|
9
|
-
findMinIndent
|
|
10
|
-
} = require('./utils/text')
|
|
4
|
+
const { getTextBetweenChars, findMinIndent } = require('./utils/text')
|
|
11
5
|
const { OPEN_WORD, CLOSE_WORD, SYNTAX } = require('./defaults')
|
|
12
6
|
// Alt parser https://github.com/LesterLyu/fast-formula-parser/blob/master/grammar/lexing.js
|
|
13
7
|
|
|
@@ -18,7 +12,6 @@ const defaultOptions = {
|
|
|
18
12
|
}
|
|
19
13
|
|
|
20
14
|
function parseBlocks(contents, opts = {}) {
|
|
21
|
-
const blocks = []
|
|
22
15
|
const options = Object.assign({}, defaultOptions, opts)
|
|
23
16
|
const { syntax, open, close } = options
|
|
24
17
|
if (!open) {
|
|
@@ -35,25 +28,41 @@ function parseBlocks(contents, opts = {}) {
|
|
|
35
28
|
throw new Error(`Unknown syntax "${syntax}"`)
|
|
36
29
|
}
|
|
37
30
|
const [ openComment, closeComment ] = syntaxInfo.pattern
|
|
31
|
+
|
|
32
|
+
const patterns = getBlockRegex({
|
|
33
|
+
openComment,
|
|
34
|
+
closeComment,
|
|
35
|
+
openText: open,
|
|
36
|
+
closeText: close
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const newerRegex = patterns.blockPattern
|
|
40
|
+
// console.log('newerRegex', newerRegex)
|
|
41
|
+
|
|
42
|
+
/*
|
|
38
43
|
const regexToUse = getBlockRegex({
|
|
39
44
|
openComment,
|
|
40
45
|
closeComment,
|
|
41
46
|
openText: open,
|
|
42
47
|
closeText: close
|
|
43
48
|
})
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// (
|
|
49
|
-
|
|
50
|
-
let openTagRegex = getOpenCommentRegex(open, openComment, closeComment)
|
|
51
|
-
let closeTagRegex = getClosingCommentRegex(close, openComment, closeComment)
|
|
49
|
+
console.log('regexToUse', regexToUse)
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
// let openTagRegex = getOpenCommentRegex(open, openComment, closeComment)
|
|
53
|
+
// let closeTagRegex = getClosingCommentRegex(close, openComment, closeComment)
|
|
52
54
|
// console.log('openTagRegex', openTagRegex)
|
|
55
|
+
// console.log('patterns.openPattern', patterns.openPattern)
|
|
53
56
|
// console.log('closeTagRegex', closeTagRegex)
|
|
54
|
-
|
|
57
|
+
// console.log('patterns.closePattern', patterns.closePattern)
|
|
58
|
+
|
|
55
59
|
/* Verify comment blocks aren't broken (redos) */
|
|
56
|
-
const { isBalanced, openCount, closeCount } = verifyTagsBalanced(
|
|
60
|
+
const { isBalanced, openCount, closeCount } = verifyTagsBalanced(
|
|
61
|
+
contents,
|
|
62
|
+
patterns.openPattern,
|
|
63
|
+
patterns.closePattern
|
|
64
|
+
)
|
|
65
|
+
// console.log('isBalanced', isBalanced)
|
|
57
66
|
const balanced = (closeCount > openCount) ? true : isBalanced
|
|
58
67
|
if (!balanced) {
|
|
59
68
|
throw new Error(`Blocks are unbalanced.
|
|
@@ -61,173 +70,125 @@ function parseBlocks(contents, opts = {}) {
|
|
|
61
70
|
${closeCount} "${close}" close tags.
|
|
62
71
|
`)
|
|
63
72
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
|
|
74
|
+
/* New regex works! */
|
|
75
|
+
const newBlocks = []
|
|
76
|
+
let blockIndex = 0
|
|
77
|
+
let newMatches
|
|
78
|
+
while ((newMatches = newerRegex.exec(contents)) !== null) {
|
|
79
|
+
blockIndex++
|
|
68
80
|
let paramString = ''
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
81
|
+
let options = {}
|
|
82
|
+
const [ block, spaces, openTag, type, params = '', content, closeTag ] = newMatches
|
|
83
|
+
|
|
84
|
+
let transformType = type
|
|
85
|
+
paramString = params.trim()
|
|
86
|
+
|
|
87
|
+
/* Account for dashes in transform name. E.g. funky-name-here */
|
|
88
|
+
const dashInTransform = params.match(/^(-[^\s]*)/)
|
|
89
|
+
if (dashInTransform && dashInTransform[1]) {
|
|
90
|
+
transformType = type + dashInTransform[1]
|
|
91
|
+
paramString = paramString.replace(dashInTransform[1], '')
|
|
73
92
|
}
|
|
74
|
-
// console.log('commentMatches', commentMatches)
|
|
75
|
-
const indentation = spaces || ''
|
|
76
|
-
/* Remove trailing -- if no params */
|
|
77
|
-
const type = __type.replace(/-*$/, '')
|
|
78
93
|
/*
|
|
79
|
-
console.log('index',
|
|
94
|
+
console.log('index', newMatches.index)
|
|
80
95
|
console.log('block', block)
|
|
81
96
|
console.log('type', type)
|
|
82
97
|
console.log('params', params)
|
|
83
98
|
console.log('spaces', `"${spaces}"`)
|
|
84
99
|
/** */
|
|
100
|
+
const isMultiline = block.indexOf('\n') > -1
|
|
101
|
+
const indentation = spaces || ''
|
|
102
|
+
let context = {
|
|
103
|
+
isMultiline,
|
|
104
|
+
}
|
|
105
|
+
// console.log('newMatches', newMatches)
|
|
85
106
|
// This is necessary to avoid infinite loops
|
|
86
|
-
if (
|
|
87
|
-
|
|
107
|
+
if (newMatches.index === newerRegex.lastIndex) {
|
|
108
|
+
newerRegex.lastIndex++
|
|
88
109
|
}
|
|
110
|
+
const openValue = indentation + openTag
|
|
111
|
+
const openStart = newMatches.index + indentation.length
|
|
112
|
+
const openEnd = openStart + openTag.length
|
|
89
113
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
//
|
|
99
|
-
const closingTag = getClosingTags(block, {
|
|
100
|
-
pattern: closeTagRegex
|
|
101
|
-
})
|
|
102
|
-
/*
|
|
103
|
-
console.log('openingTag', openingTag)
|
|
104
|
-
console.log('closingTag', closingTag)
|
|
105
|
-
/** */
|
|
106
|
-
if (!openingTag || !closingTag) {
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const openingTagLength = openingTag.length //+ indentation.length
|
|
111
|
-
const contentEndPosition = block.indexOf(closingTag.tag, openingTagLength)
|
|
112
|
-
const content = getTextBetweenChars(block, openingTagLength, contentEndPosition)
|
|
113
|
-
// console.log('content', content)
|
|
114
|
-
let originalContent = content
|
|
115
|
-
const contentEndsWithNewLine = getLastCharacter(originalContent) === '\n'
|
|
116
|
-
const openEndsWithNewLine = getLastCharacter(openingTag.tag) === '\n'
|
|
117
|
-
|
|
118
|
-
const closeTag = (contentEndsWithNewLine) ? `\n${closingTag.tag}` : closingTag.tag
|
|
119
|
-
|
|
120
|
-
// Move new line to beginning of closing tag
|
|
121
|
-
// if (originalContent.match(/\n$/)) {
|
|
122
|
-
if (contentEndsWithNewLine) {
|
|
123
|
-
// originalContent = originalContent.replace(/\n$/, '')
|
|
124
|
-
originalContent = originalContent.slice(0, -1)
|
|
125
|
-
}
|
|
126
|
-
/* Strip indentation */
|
|
127
|
-
originalContent = stripIndent(originalContent, indentation.length)
|
|
128
|
-
// originalContent = originalContent.replace(/^\s+|\s+$/g, '')
|
|
129
|
-
/*
|
|
130
|
-
console.log('originalContent')
|
|
131
|
-
console.log(`"${originalContent}"`)
|
|
132
|
-
/** */
|
|
133
|
-
|
|
134
|
-
/* strip brackets (functionName) or [functionName] or {functionName} */
|
|
135
|
-
const cleanType = stripBrackets(type)
|
|
136
|
-
const shift = (openEndsWithNewLine) ? 1 : 0
|
|
137
|
-
const lineOpen = contents.substr(0, commentMatches.index).split('\n').length
|
|
138
|
-
const lineClose = contents.substr(0, regexToUse.lastIndex).split('\n').length
|
|
139
|
-
const contentStart = commentMatches.index + openingTag.tag.length - shift //+ indentation.length
|
|
114
|
+
|
|
115
|
+
const closeEnd = newerRegex.lastIndex
|
|
116
|
+
// const finIndentation = (lineOpen === lineClose) ? '' : indentation
|
|
117
|
+
|
|
118
|
+
const lineOpen = contents.substr(0, openStart).split('\n').length
|
|
119
|
+
const lineClose = contents.substr(0, closeEnd).split('\n').length
|
|
120
|
+
|
|
121
|
+
const contentStart = openStart + openTag.length // + indentation.length// - shift //+ indentation.length
|
|
122
|
+
const contentEnd = contentStart + content.length // + finIndentation.length // + shift
|
|
140
123
|
/* If single line comment block, remove indentation */
|
|
141
124
|
const finIndentation = (lineOpen === lineClose) ? '' : indentation
|
|
142
|
-
const contentEnd = contentStart + content.length + finIndentation.length + shift
|
|
143
125
|
|
|
144
|
-
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
// console.log('param', `${paramString}`)
|
|
155
|
-
// console.log('type ', `${__type}`)
|
|
156
|
-
// console.log('──────────────────────')
|
|
157
|
-
// console.log(`${cleanType} "${paramString}" "${__type}"`)
|
|
158
|
-
if (paramString) {
|
|
159
|
-
// console.log('paramString', `"${paramString}"`)
|
|
160
|
-
// Legacy v1 options parser
|
|
161
|
-
if (getFirstCharacter(paramString) === ':' || getFirstCharacter(paramString) === '?') {
|
|
162
|
-
context.isLegacy = true
|
|
163
|
-
// paramString = paramString.replace(/\s?\)\s*$/, '').substring(1)
|
|
164
|
-
paramString = paramString.split(')')[0].substring(1)
|
|
165
|
-
// console.log('fixed paramString', paramString)
|
|
166
|
-
props = legacyParseOptions(paramString)
|
|
167
|
-
} else {
|
|
168
|
-
if (type.startsWith('(') && paramString.endsWith(')')) {
|
|
169
|
-
paramString = paramString.replace(/\)$/, '')
|
|
170
|
-
}
|
|
171
|
-
props = optionsParse(paramString)
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
} else if (!paramString && __type.match(/^\(.*\)$/)) {
|
|
175
|
-
context.isLegacy = true
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
/*
|
|
179
|
-
console.log(regexToUse)
|
|
180
|
-
console.log(`cleanType "${cleanType}" at ${regexToUse.lastIndex} using props:`)
|
|
181
|
-
console.log(props)
|
|
182
|
-
console.log('───────────────────────')
|
|
183
|
-
/** */
|
|
126
|
+
/* If old syntax XYZ?foo | XYZ:foo */
|
|
127
|
+
if (paramString.match(/^:|^\?/)) {
|
|
128
|
+
paramString = paramString.split(')')[0]
|
|
129
|
+
paramString = paramString.replace(/^:/, '').replace(/^\?/, '').replace(/\)$/g, '')
|
|
130
|
+
// console.log('paramString', `"${paramString}"`)
|
|
131
|
+
options = legacyParseOptions(paramString)
|
|
132
|
+
context.isLegacy = true
|
|
133
|
+
} else {
|
|
134
|
+
// console.log('paramString', paramString)
|
|
135
|
+
options = parse(paramString)
|
|
184
136
|
}
|
|
185
137
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
138
|
+
// console.log('open start', openStart)
|
|
139
|
+
// console.log('openEnd', openEnd)
|
|
140
|
+
// console.log('options', options)
|
|
141
|
+
|
|
142
|
+
const blockData = {
|
|
143
|
+
index: blockIndex,
|
|
144
|
+
type: transformType,
|
|
145
|
+
options,
|
|
191
146
|
context,
|
|
192
147
|
/* Open Tag */
|
|
193
148
|
open: {
|
|
194
|
-
value:
|
|
195
|
-
start:
|
|
196
|
-
end:
|
|
149
|
+
value: openValue,
|
|
150
|
+
start: openStart,
|
|
151
|
+
end: openEnd
|
|
197
152
|
},
|
|
198
153
|
/* Inner Content */
|
|
199
154
|
content: {
|
|
200
|
-
value:
|
|
155
|
+
value: content,
|
|
201
156
|
start: contentStart,
|
|
202
157
|
end: contentEnd,
|
|
203
|
-
indentation: findMinIndent(
|
|
158
|
+
indentation: findMinIndent(content),
|
|
204
159
|
},
|
|
205
160
|
/* Close Tag */
|
|
206
161
|
close: {
|
|
207
162
|
value: closeTag,
|
|
208
163
|
start: contentEnd,
|
|
209
|
-
end:
|
|
164
|
+
end: closeEnd
|
|
210
165
|
},
|
|
211
166
|
/* Full Block */
|
|
212
167
|
block: {
|
|
213
168
|
indentation: finIndentation,
|
|
214
169
|
lines: [lineOpen, lineClose],
|
|
215
|
-
start:
|
|
216
|
-
end:
|
|
170
|
+
start: openStart,
|
|
171
|
+
end: closeEnd,
|
|
217
172
|
// position: [ commentMatches.index, regexToUse.lastIndex ],
|
|
218
|
-
rawType: (context.isLegacy) ? type.replace(/^\s?\(/, '') : type,
|
|
173
|
+
// rawType: (context.isLegacy) ? type.replace(/^\s?\(/, '') : type,
|
|
219
174
|
rawArgs: paramString,
|
|
220
175
|
rawContent: getTextBetweenChars(contents, contentStart, contentEnd),
|
|
221
176
|
value: block,
|
|
222
177
|
},
|
|
223
|
-
}
|
|
178
|
+
}
|
|
179
|
+
// console.log('blockData', blockData)
|
|
180
|
+
newBlocks.push(blockData)
|
|
224
181
|
}
|
|
182
|
+
|
|
225
183
|
return {
|
|
226
184
|
// Close but no single line newPattern: newGetBlockRegex({ openComment, commentClose, start: START, ending: END }),
|
|
227
|
-
pattern: regexToUse,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
185
|
+
// pattern: regexToUse,
|
|
186
|
+
pattern: newerRegex,
|
|
187
|
+
// COMMENT_OPEN_REGEX: openTagRegex,
|
|
188
|
+
// COMMENT_CLOSE_REGEX: closeTagRegex,
|
|
189
|
+
COMMENT_OPEN_REGEX: patterns.openPattern,
|
|
190
|
+
COMMENT_CLOSE_REGEX: patterns.closePattern,
|
|
191
|
+
blocks: newBlocks
|
|
231
192
|
}
|
|
232
193
|
}
|
|
233
194
|
|
|
@@ -241,124 +202,6 @@ function verifyTagsBalanced(str, open, close) {
|
|
|
241
202
|
}
|
|
242
203
|
}
|
|
243
204
|
|
|
244
|
-
function getOpeningTags(block, {
|
|
245
|
-
pattern,
|
|
246
|
-
open,
|
|
247
|
-
close
|
|
248
|
-
}) {
|
|
249
|
-
// console.log(block.match(/^\/\*+(.*)\*\//))
|
|
250
|
-
// console.log('openTagRegex', pattern)
|
|
251
|
-
let matches
|
|
252
|
-
while ((matches = pattern.exec(block)) !== null) {
|
|
253
|
-
if (matches.index === pattern.lastIndex) {
|
|
254
|
-
pattern.lastIndex++ // avoid infinite loops with zero-width matches
|
|
255
|
-
}
|
|
256
|
-
const [ tag, spaces, tagStart, tagEnd ] = matches
|
|
257
|
-
/*
|
|
258
|
-
console.log('FULL Open Tag >>>>>', tag)
|
|
259
|
-
console.log('openTag Start', "'"+tagStart+"'");
|
|
260
|
-
console.log('openTag End', "'"+tagEnd+"'");
|
|
261
|
-
/**/
|
|
262
|
-
return {
|
|
263
|
-
tag,
|
|
264
|
-
spaces: spaces || '',
|
|
265
|
-
length: tag.length,
|
|
266
|
-
tagStart,
|
|
267
|
-
tagEnd,
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
// // Fallthrough
|
|
271
|
-
// // const fallbackRegex = new RegExp(`^([ \\t]*)(${open}([\\s\\S]*?)${close})\\n?`)
|
|
272
|
-
// const fallbackRegex = new RegExp(`^([ \\t]*)(\\b${open}\\b([\\s\\S]*?)${close})\\n?`)
|
|
273
|
-
// // const xyz = block.match(/^([ \t]*)(\/\*+([\s\S]*?)\*+\/)/)
|
|
274
|
-
// const fallbackMatch= block.match(fallbackRegex)
|
|
275
|
-
// if (fallbackMatch) {
|
|
276
|
-
// /*
|
|
277
|
-
// console.log('fallbackRegex', fallbackRegex)
|
|
278
|
-
// console.log('fall through', `"${block}"`)
|
|
279
|
-
// console.log('xyz', xyz)
|
|
280
|
-
// /** */
|
|
281
|
-
// return {
|
|
282
|
-
// fallthrough: true,
|
|
283
|
-
// tag: fallbackMatch[0],
|
|
284
|
-
// spaces: fallbackMatch[1] || '',
|
|
285
|
-
// length: fallbackMatch[0].length,
|
|
286
|
-
// }
|
|
287
|
-
// }
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
function getClosingTags(block, {
|
|
291
|
-
pattern,
|
|
292
|
-
// open,
|
|
293
|
-
// close
|
|
294
|
-
}) {
|
|
295
|
-
// console.log('closeTagRegex', closeTagRegex)
|
|
296
|
-
let matches
|
|
297
|
-
while ((matches = pattern.exec(block)) !== null) {
|
|
298
|
-
if (matches.index === pattern.lastIndex) {
|
|
299
|
-
pattern.lastIndex++ // avoid infinite loops with zero-width matches
|
|
300
|
-
}
|
|
301
|
-
const [ _tag, spaces, tagStart, tagEnd] = matches
|
|
302
|
-
/*
|
|
303
|
-
console.log('FULL CLOSE Tag >>>>>', matches[0])
|
|
304
|
-
console.log('closeTag Start', "'"+matches[1]+"'");
|
|
305
|
-
console.log('closeTag End', "'"+matches[2]+"'");
|
|
306
|
-
/**/
|
|
307
|
-
const tag = spaces + tagStart + tagEnd
|
|
308
|
-
return {
|
|
309
|
-
tag: tag,
|
|
310
|
-
length: tag.length,
|
|
311
|
-
spaces: spaces || '',
|
|
312
|
-
tagStart,
|
|
313
|
-
tagEnd
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
const EMOJI = '\\u00a9|\\u00ae|[\\u2000-\\u3300]|\\ud83c[\\ud000-\\udfff]|\\ud83d[\\ud000-\\udfff]|\\ud83e[\\ud000-\\udfff]'
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Get Regex pattern to match block
|
|
323
|
-
* @param {object} options
|
|
324
|
-
* @param {string} [options.openComment] - comment syntax open
|
|
325
|
-
* @param {string} [options.closeComment] - comment syntax open
|
|
326
|
-
* @param {string} [options.openText] - comment open text
|
|
327
|
-
* @param {string} [options.closeText] - comment close text
|
|
328
|
-
* @returns {RegExp}
|
|
329
|
-
*/
|
|
330
|
-
function getBlockRegex({ openComment, closeComment, openText, closeText }) {
|
|
331
|
-
return new RegExp(
|
|
332
|
-
`([ \\t]*)(?:${openComment}(?:.*|\\r?|\\n?|\\s*)${openText}\\s*([(\\[\\{]*[A-Za-z0-9_$-]*[)\\]\\}]*)\\s*)((?:.*?|.*?\\r?\\n?)*?)${openComment}(?:.*|\\r?|\\n?|\\s*)${closeText}(?:.|\\r?\\n)*?${closeComment}`,
|
|
333
|
-
'gmi'
|
|
334
|
-
)
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/* // Named matches
|
|
338
|
-
(?<leading>[ \t]*)(?:<!-{2,}(?:.*|\r?|\n?|\s*)MD-MAGIC-EXAMPLE:START\s*(?<key>[(\[\{]*[A-Za-z0-9_$-]*[)\]\}]*)\s*)([\s\S]*?)-->(?<content>(?:.*?|.*?\r?\n?)*?)<!-{2,}(?:.*|\r?|\n?|\s*)MD-MAGIC-EXAMPLE:END(?:.|\r?\n)*?-{2,}>
|
|
339
|
-
*/
|
|
340
|
-
function newGetBlockRegex({ commentOpen, commentClose, start, ending }) {
|
|
341
|
-
// https://regex101.com/r/C9WSk8/1 close but breaks on single line blocks. Maybe needs lookahead https://stackoverflow.com/questions/7124778/how-can-i-match-anything-up-until-this-sequence-of-characters-in-a-regular-exp
|
|
342
|
-
return new RegExp(
|
|
343
|
-
`([ \\t]*)(?:${commentOpen}(?:.*|\\r?|\\n?|\\s*)${start}\\s*([(\\[\\{]*[A-Za-z0-9_$-]*[)\\]\\}]*)\\s*)([\\s\\S]*?)${commentClose}((?:.*?|.*?\\r?\\n?)*?)${commentOpen}(?:.*|\\r?|\\n?|\\s*)${ending}(?:.|\\r?\\n)*?${commentClose}`,
|
|
344
|
-
'gmi'
|
|
345
|
-
)
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
function getOpenCommentRegex(word, open, close) {
|
|
349
|
-
// console.log('open', open)
|
|
350
|
-
const boundary = word.indexOf('/') > -1 ? '' : '\\b'
|
|
351
|
-
// console.log('boundary', boundary)
|
|
352
|
-
// return new RegExp(`(\\<\\!--(?:.|\\r?\\n)*?${matchWord}:START)((?:.|\\r?\\n)*?--\\>)`, 'g')
|
|
353
|
-
return new RegExp(`([ \\t]*)(${open}(?:.|\r?|\n?|\\s*)${boundary}${word}${boundary})((?:.|\\r?\\n)*?${close}\n?)`, 'gi')
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
function getClosingCommentRegex(word, open, close) {
|
|
357
|
-
const boundary = word.indexOf('/') > -1 ? '' : '\\b'
|
|
358
|
-
return new RegExp(`${close}(?:.|\\r?\\n)*?([ \t]*)((?:${open}(?:.*|\\r?\\n)(?:.*|\\r?\\n))*?${boundary}${word}${boundary})((?:.|\\r?\\n)*?${close})`, 'gi')
|
|
359
|
-
// return new RegExp(`--\\>(?:.|\\r?\\n)*?([ \t]*)((?:\\<\\!--(?:.*|\\r?\\n)(?:.*|\\r?\\n))*?${word}:END)((?:.|\\r?\\n)*?--\\>)`, 'gi')
|
|
360
|
-
}
|
|
361
|
-
|
|
362
205
|
/**
|
|
363
206
|
* Strip brackets from string (functionName) or [functionName] or {functionName}
|
|
364
207
|
* @param {string} str
|
|
@@ -383,6 +226,156 @@ function legacyParseOptions(options) {
|
|
|
383
226
|
}
|
|
384
227
|
|
|
385
228
|
|
|
229
|
+
/* TODO someday Named matches
|
|
230
|
+
(?<leading>[ \t]*)(?:<!-{2,}(?:.*|\r?|\n?|\s*)MD-MAGIC-EXAMPLE:START\s*(?<key>[(\[\{]*[A-Za-z0-9_$-]*[)\]\}]*)\s*)([\s\S]*?)-->(?<content>(?:.*?|.*?\r?\n?)*?)<!-{2,}(?:.*|\r?|\n?|\s*)MD-MAGIC-EXAMPLE:END(?:.|\r?\n)*?-{2,}>
|
|
231
|
+
*/
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Block matching patterns
|
|
235
|
+
* @typedef {{blockPattern: RegExp, openPattern: RegExp, closePattern: RegExp}} RegexPatterns
|
|
236
|
+
*/
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Get Regex pattern to match block
|
|
240
|
+
* @param {object} options
|
|
241
|
+
* @param {string} [options.openEmoji] - emoji
|
|
242
|
+
* @param {string} [options.openComment] - comment syntax open
|
|
243
|
+
* @param {string} [options.closeComment] - comment syntax open
|
|
244
|
+
* @param {string} [options.openText] - comment open text
|
|
245
|
+
* @param {string} [options.closeText] - comment close text
|
|
246
|
+
* @param {boolean} [options.allowMissingTransforms] - Allow for missing transform key
|
|
247
|
+
* @returns {RegexPatterns}
|
|
248
|
+
*/
|
|
249
|
+
function getBlockRegex({
|
|
250
|
+
openEmoji,
|
|
251
|
+
openComment,
|
|
252
|
+
closeComment,
|
|
253
|
+
openText = '',
|
|
254
|
+
closeText = '',
|
|
255
|
+
allowMissingTransforms = false
|
|
256
|
+
}) {
|
|
257
|
+
// https://regex101.com/r/SU2g1Q/1
|
|
258
|
+
// https://regex101.com/r/SU2g1Q/2
|
|
259
|
+
// https://regex101.com/r/SU2g1Q/3
|
|
260
|
+
// https://regex101.com/r/SU2g1Q/4
|
|
261
|
+
// https://regex101.com/r/SU2g1Q/5
|
|
262
|
+
// https://regex101.com/r/SU2g1Q/6
|
|
263
|
+
// /([ \t]*)(<!-{2,}(?:.|\r?|\n?|\s*)\bdoc-gen\b)((?:.|\r?\n)*?)-{2,}>([\s\S]*?.*)\n?<!-{2,}(?:.*|\r?|\n?|\s*)end-doc-gen(?:.|\r?\n)*?-{2,}>/gim
|
|
264
|
+
// /([ \t]*)(<!-{2,}(?:\r?|\n?|\s*)\bdoc-gen\b)\s*([(\[\{]*[A-Za-z0-9_$-]*[)\]\}]*)\s*((?:.|\r?\n)*?)-{2,}>([\s\S]*?.*)\n?<!-{2,}(?:.*|\r?|\n?|\s*)end-doc-gen(?:.|\r?\n)*?-{2,}>/
|
|
265
|
+
const emojiPat = (openEmoji) ? `(?:\\s*${openEmoji})?` : '(?:\\s*⛔️)?'
|
|
266
|
+
const boundary = openText.indexOf('/') > -1 ? '' : '\\b'
|
|
267
|
+
const matchWord = `${boundary}${openText}${boundary}`
|
|
268
|
+
const hasOne = (allowMissingTransforms) ? '*' : '+'
|
|
269
|
+
const open = `((?:${openComment}${emojiPat}(?:\\r?|\\n?|\\s*)${matchWord})\\s*[(\\[\\{]*([A-Za-z0-9_$]${hasOne})[)\\]\\}]*\\s*((?:.|\\r?\\n)*?)${closeComment}\\n?)`
|
|
270
|
+
const close = `(\\n?[ \\t]*${openComment}${emojiPat}(?:\\r?|\\n?|\\s*)${closeText}(?:.|\\r?\\n)*?${closeComment})`
|
|
271
|
+
// const close = `(\\n?${openComment}(?:.*|\\r?|\\n?|\\s*)${closeText}(?:.|\\r?\\n)*?${closeComment})`
|
|
272
|
+
const blockPattern = new RegExp(`([ \\t]*)${open}([\\s\\S]*?.*)${close}`, 'gmi')
|
|
273
|
+
const openPattern = new RegExp(open, 'gi')
|
|
274
|
+
const closePattern = new RegExp(close, 'gi')
|
|
275
|
+
|
|
276
|
+
return {
|
|
277
|
+
blockPattern,
|
|
278
|
+
openPattern,
|
|
279
|
+
closePattern
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// function getOpeningTags(block, {
|
|
284
|
+
// pattern,
|
|
285
|
+
// open,
|
|
286
|
+
// close
|
|
287
|
+
// }) {
|
|
288
|
+
// // console.log(block.match(/^\/\*+(.*)\*\//))
|
|
289
|
+
// // console.log('openTagRegex', pattern)
|
|
290
|
+
// let matches
|
|
291
|
+
// while ((matches = pattern.exec(block)) !== null) {
|
|
292
|
+
// if (matches.index === pattern.lastIndex) {
|
|
293
|
+
// pattern.lastIndex++ // avoid infinite loops with zero-width matches
|
|
294
|
+
// }
|
|
295
|
+
// const [ tag, spaces, tagStart, tagEnd ] = matches
|
|
296
|
+
// /*
|
|
297
|
+
// console.log('FULL Open Tag >>>>>', tag)
|
|
298
|
+
// console.log('openTag Start', "'"+tagStart+"'");
|
|
299
|
+
// console.log('openTag End', "'"+tagEnd+"'");
|
|
300
|
+
// /**/
|
|
301
|
+
// return {
|
|
302
|
+
// tag,
|
|
303
|
+
// spaces: spaces || '',
|
|
304
|
+
// length: tag.length,
|
|
305
|
+
// tagStart,
|
|
306
|
+
// tagEnd,
|
|
307
|
+
// }
|
|
308
|
+
// }
|
|
309
|
+
// }
|
|
310
|
+
|
|
311
|
+
// function getClosingTags(block, {
|
|
312
|
+
// pattern,
|
|
313
|
+
// // open,
|
|
314
|
+
// // close
|
|
315
|
+
// }) {
|
|
316
|
+
// // console.log('closeTagRegex', closeTagRegex)
|
|
317
|
+
// let matches
|
|
318
|
+
// while ((matches = pattern.exec(block)) !== null) {
|
|
319
|
+
// if (matches.index === pattern.lastIndex) {
|
|
320
|
+
// pattern.lastIndex++ // avoid infinite loops with zero-width matches
|
|
321
|
+
// }
|
|
322
|
+
// const [ _tag, spaces, tagStart, tagEnd] = matches
|
|
323
|
+
// /*
|
|
324
|
+
// console.log('FULL CLOSE Tag >>>>>', matches[0])
|
|
325
|
+
// console.log('closeTag Start', "'"+matches[1]+"'");
|
|
326
|
+
// console.log('closeTag End', "'"+matches[2]+"'");
|
|
327
|
+
// /**/
|
|
328
|
+
// const tag = spaces + tagStart + tagEnd
|
|
329
|
+
// return {
|
|
330
|
+
// tag: tag,
|
|
331
|
+
// length: tag.length,
|
|
332
|
+
// spaces: spaces || '',
|
|
333
|
+
// tagStart,
|
|
334
|
+
// tagEnd
|
|
335
|
+
// }
|
|
336
|
+
// }
|
|
337
|
+
// }
|
|
338
|
+
|
|
339
|
+
// /**
|
|
340
|
+
// * Get Regex pattern to match block
|
|
341
|
+
// * @param {object} options
|
|
342
|
+
// * @param {string} [options.openComment] - comment syntax open
|
|
343
|
+
// * @param {string} [options.closeComment] - comment syntax open
|
|
344
|
+
// * @param {string} [options.openText] - comment open text
|
|
345
|
+
// * @param {string} [options.closeText] - comment close text
|
|
346
|
+
// * @returns {RegExp}
|
|
347
|
+
// */
|
|
348
|
+
// function getBlockRegexOld({ openComment, closeComment, openText, closeText }) {
|
|
349
|
+
// // /([ \t]*)(<!-{2,}(?:.|\r?|\n?|\s*)\bdoc-gen\b)((?:.|\r?\n)*?)-{2,}>(.*)<!-{2,}(?:.*|\r?|\n?|\s*)end-doc-gen(?:.|\r?\n)*?-{2,}>/i singleline
|
|
350
|
+
// return new RegExp(
|
|
351
|
+
// `([ \\t]*)(?:${openComment}(?:.*|\\r?|\\n?|\\s*)${openText}\\s*([(\\[\\{]*[A-Za-z0-9_$-]*[)\\]\\}]*)\\s*)((?:.*?|.*?\\r?\\n?)*?)${openComment}(?:.*|\\r?|\\n?|\\s*)${closeText}(?:.|\\r?\\n)*?${closeComment}`,
|
|
352
|
+
// 'gmi'
|
|
353
|
+
// )
|
|
354
|
+
// }
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
// function newGetBlockRegex({ commentOpen, commentClose, start, ending }) {
|
|
358
|
+
// // https://regex101.com/r/C9WSk8/1 close but breaks on single line blocks. Maybe needs lookahead https://stackoverflow.com/questions/7124778/how-can-i-match-anything-up-until-this-sequence-of-characters-in-a-regular-exp
|
|
359
|
+
// return new RegExp(
|
|
360
|
+
// `([ \\t]*)(?:${commentOpen}(?:.*|\\r?|\\n?|\\s*)${start}\\s*([(\\[\\{]*[A-Za-z0-9_$-]*[)\\]\\}]*)\\s*)([\\s\\S]*?)${commentClose}((?:.*?|.*?\\r?\\n?)*?)${commentOpen}(?:.*|\\r?|\\n?|\\s*)${ending}(?:.|\\r?\\n)*?${commentClose}`,
|
|
361
|
+
// 'gmi'
|
|
362
|
+
// )
|
|
363
|
+
// }
|
|
364
|
+
|
|
365
|
+
// function getOpenCommentRegex(word, open, close) {
|
|
366
|
+
// // console.log('open', open)
|
|
367
|
+
// const boundary = word.indexOf('/') > -1 ? '' : '\\b'
|
|
368
|
+
// // console.log('boundary', boundary)
|
|
369
|
+
// // return new RegExp(`(\\<\\!--(?:.|\\r?\\n)*?${matchWord}:START)((?:.|\\r?\\n)*?--\\>)`, 'g')
|
|
370
|
+
// return new RegExp(`([ \\t]*)(${open}(?:.|\r?|\n?|\\s*)${boundary}${word}${boundary})((?:.|\\r?\\n)*?${close}\n?)`, 'gi')
|
|
371
|
+
// }
|
|
372
|
+
|
|
373
|
+
// function getClosingCommentRegex(word, open, close) {
|
|
374
|
+
// const boundary = word.indexOf('/') > -1 ? '' : '\\b'
|
|
375
|
+
// return new RegExp(`${close}(?:.|\\r?\\n)*?([ \t]*)((?:${open}(?:.*|\\r?\\n)(?:.*|\\r?\\n))*?${boundary}${word}${boundary})((?:.|\\r?\\n)*?${close})`, 'gi')
|
|
376
|
+
// // return new RegExp(`--\\>(?:.|\\r?\\n)*?([ \t]*)((?:\\<\\!--(?:.*|\\r?\\n)(?:.*|\\r?\\n))*?${word}:END)((?:.|\\r?\\n)*?--\\>)`, 'gi')
|
|
377
|
+
// }
|
|
378
|
+
|
|
386
379
|
module.exports = {
|
|
387
380
|
getBlockRegex,
|
|
388
381
|
parseBlocks,
|