@peaceroad/markdown-it-strong-ja 0.7.2 → 0.8.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.
@@ -1,334 +1 @@
1
- import Token from 'markdown-it/lib/token.mjs'
2
- import { convertCollapsedReferenceLinks, mergeBrokenMarksAroundLinks, getMapFromTokenRange } from './token-link-utils.js'
3
- import {
4
- rebuildInlineLevels,
5
- findLinkClose,
6
- fixEmOuterStrongSequence,
7
- fixLeadingAsteriskEm,
8
- fixTrailingStrong
9
- } from './token-core.js'
10
- import { getRuntimeOpt } from './token-utils.js'
11
-
12
- const scanBrokenRefState = (text, out) => {
13
- if (!text || text.indexOf('][') === -1) {
14
- out.depth = 0
15
- out.brokenEnd = false
16
- return out
17
- }
18
- let depth = 0
19
- let lastOpen = -1
20
- let lastClose = -1
21
- for (let i = 0; i < text.length; i++) {
22
- const ch = text.charCodeAt(i)
23
- if (ch === 0x5B) {
24
- depth++
25
- lastOpen = i
26
- } else if (ch === 0x5D) {
27
- if (depth > 0) depth--
28
- lastClose = i
29
- }
30
- }
31
- out.depth = depth
32
- out.brokenEnd = depth > 0 && lastOpen > lastClose
33
- return out
34
- }
35
-
36
- const updateBracketDepth = (text, depth) => {
37
- if (!text || depth <= 0) return depth
38
- for (let i = 0; i < text.length; i++) {
39
- const ch = text.charCodeAt(i)
40
- if (ch === 0x5B) {
41
- depth++
42
- } else if (ch === 0x5D) {
43
- if (depth > 0) {
44
- depth--
45
- if (depth === 0) return 0
46
- }
47
- }
48
- }
49
- return depth
50
- }
51
-
52
- const getAttr = (token, name) => {
53
- if (!token || !token.attrs) return ''
54
- for (let i = 0; i < token.attrs.length; i++) {
55
- if (token.attrs[i][0] === name) return token.attrs[i][1]
56
- }
57
- return ''
58
- }
59
-
60
- const buildLabelText = (tokens, startIdx, endIdx) => {
61
- let label = ''
62
- for (let i = startIdx; i <= endIdx; i++) {
63
- const t = tokens[i]
64
- if (!t) continue
65
- if (t.type === 'text') {
66
- label += t.content
67
- } else if (t.type === 'code_inline') {
68
- const fence = t.markup || '`'
69
- label += fence + t.content + fence
70
- } else if (t.markup) {
71
- label += t.markup
72
- }
73
- }
74
- return label
75
- }
76
-
77
- const buildRawFromTokens = (tokens, startIdx, endIdx) => {
78
- let raw = ''
79
- for (let i = startIdx; i <= endIdx; i++) {
80
- const t = tokens[i]
81
- if (!t) continue
82
- if (t.type === 'link_open') {
83
- const closeIdx = findLinkClose(tokens, i)
84
- if (closeIdx === -1 || closeIdx > endIdx) break
85
- const label = buildLabelText(tokens, i + 1, closeIdx - 1)
86
- const href = getAttr(t, 'href')
87
- raw += `[${label}](${href || ''})`
88
- i = closeIdx
89
- continue
90
- }
91
- if (t.type === 'text') {
92
- raw += t.content
93
- continue
94
- }
95
- if (t.type === 'code_inline') {
96
- const fence = t.markup || '`'
97
- raw += fence + t.content + fence
98
- continue
99
- }
100
- if (t.markup) {
101
- raw += t.markup
102
- }
103
- }
104
- return raw
105
- }
106
-
107
- const parseInlineWithFixes = (md, raw, env) => {
108
- const parsed = md.parseInline(raw, env)
109
- const inline = parsed && parsed.length > 0 ? parsed[0] : null
110
- if (!inline || !inline.children) return null
111
- const children = inline.children
112
- let changed = false
113
- if (fixEmOuterStrongSequence(children)) changed = true
114
- if (fixLeadingAsteriskEm(children)) changed = true
115
- if (fixTrailingStrong(children)) changed = true
116
- if (changed) rebuildInlineLevels(children)
117
- return children
118
- }
119
-
120
- const hasUnsafeAttrs = (token) => {
121
- if (!token) return false
122
- if (token.meta && Object.keys(token.meta).length > 0) return true
123
- if (!token.attrs || token.attrs.length === 0) return false
124
- if (token.type !== 'link_open') return true
125
- for (let i = 0; i < token.attrs.length; i++) {
126
- const name = token.attrs[i][0]
127
- if (name !== 'href' && name !== 'title') return true
128
- }
129
- return false
130
- }
131
-
132
- const REPARSE_ALLOWED_TYPES = new Set([
133
- 'text',
134
- 'strong_open',
135
- 'strong_close',
136
- 'em_open',
137
- 'em_close',
138
- 'code_inline',
139
- 'link_open',
140
- 'link_close',
141
- 'softbreak',
142
- 'hardbreak'
143
- ])
144
-
145
- const shouldReparseSegment = (tokens, startIdx, endIdx) => {
146
- for (let i = startIdx; i <= endIdx && i < tokens.length; i++) {
147
- const t = tokens[i]
148
- if (!t) continue
149
- if (hasUnsafeAttrs(t)) return false
150
- if (t.type && !REPARSE_ALLOWED_TYPES.has(t.type)) return false
151
- }
152
- return true
153
- }
154
-
155
- const fixTailAfterLinkStrongClose = (tokens, md, env) => {
156
- let strongDepth = 0
157
- for (let i = 0; i < tokens.length; i++) {
158
- const t = tokens[i]
159
- if (!t) continue
160
- if (t.type === 'strong_open') strongDepth++
161
- if (t.type === 'strong_close') {
162
- if (strongDepth > 0) strongDepth--
163
- }
164
- if (t.type !== 'link_close') continue
165
- if (strongDepth !== 0) continue
166
- let startIdx = -1
167
- let foundStrongClose = -1
168
- let foundStrongOpen = -1
169
- for (let j = i + 1; j < tokens.length; j++) {
170
- const node = tokens[j]
171
- if (!node) continue
172
- if (node.type === 'strong_open') {
173
- foundStrongOpen = j
174
- break
175
- }
176
- if (node.type === 'strong_close') {
177
- foundStrongClose = j
178
- break
179
- }
180
- if (node.type === 'text' && node.content && startIdx === -1) {
181
- startIdx = j
182
- }
183
- }
184
- if (foundStrongClose === -1 || foundStrongOpen !== -1) continue
185
- if (startIdx === -1) startIdx = foundStrongClose
186
- const raw = buildRawFromTokens(tokens, startIdx, tokens.length - 1)
187
- const children = parseInlineWithFixes(md, raw, env)
188
- if (children && children.length > 0) {
189
- tokens.splice(startIdx, tokens.length - startIdx, ...children)
190
- return true
191
- }
192
- }
193
- return false
194
- }
195
-
196
- const registerTokenPostprocess = (md, baseOpt, getNoLinkMdInstance) => {
197
- if (md.__strongJaTokenPostprocessRegistered) return
198
- md.__strongJaTokenPostprocessRegistered = true
199
- md.core.ruler.after('inline', 'strong_ja_token_postprocess', (state) => {
200
- if (!state || !state.tokens) return
201
- const opt = getRuntimeOpt(state, baseOpt)
202
- if (opt.postprocess === false) return
203
- if (state.__strongJaReferenceCount === undefined) {
204
- const references = state.env && state.env.references
205
- state.__strongJaReferenceCount = references ? Object.keys(references).length : 0
206
- }
207
- for (let i = 0; i < state.tokens.length; i++) {
208
- const token = state.tokens[i]
209
- if (!token || token.type !== 'inline' || !token.children || token.children.length === 0) continue
210
- const children = token.children
211
- let changed = false
212
- let hasBracketText = false
213
- let hasEmphasis = false
214
- let hasLinkClose = false
215
- let reparseCount = 0
216
- let maxReparse = 0
217
- const scanState = { depth: 0, brokenEnd: false }
218
- for (let j = 0; j < children.length; j++) {
219
- const child = children[j]
220
- if (!child) continue
221
- if (!hasEmphasis &&
222
- (child.type === 'strong_open' || child.type === 'strong_close' || child.type === 'em_open' || child.type === 'em_close')) {
223
- hasEmphasis = true
224
- }
225
- if (!hasLinkClose && child.type === 'link_close') {
226
- hasLinkClose = true
227
- }
228
- if (child.type !== 'text' || !child.content) continue
229
- if (!hasBracketText && (child.content.indexOf('[') !== -1 || child.content.indexOf(']') !== -1)) {
230
- hasBracketText = true
231
- }
232
- if (scanBrokenRefState(child.content, scanState).brokenEnd) {
233
- maxReparse++
234
- }
235
- }
236
- if (maxReparse !== 0) {
237
- let allowReparse = true
238
- while (true) {
239
- let didReparse = false
240
- let brokenRefStart = -1
241
- let brokenRefDepth = 0
242
- hasBracketText = false
243
- hasEmphasis = false
244
- hasLinkClose = false
245
- for (let j = 0; j < children.length; j++) {
246
- const child = children[j]
247
- if (!child) continue
248
- if (child.type === 'text' && child.content) {
249
- if (!hasBracketText && (child.content.indexOf('[') !== -1 || child.content.indexOf(']') !== -1)) {
250
- hasBracketText = true
251
- }
252
- if (brokenRefStart === -1) {
253
- const scan = scanBrokenRefState(child.content, scanState)
254
- if (scan.brokenEnd) {
255
- brokenRefStart = j
256
- brokenRefDepth = scan.depth
257
- continue
258
- }
259
- } else {
260
- brokenRefDepth = updateBracketDepth(child.content, brokenRefDepth)
261
- if (brokenRefDepth <= 0) {
262
- brokenRefStart = -1
263
- brokenRefDepth = 0
264
- }
265
- }
266
- }
267
- if (!hasEmphasis &&
268
- (child.type === 'strong_open' || child.type === 'strong_close' || child.type === 'em_open' || child.type === 'em_close')) {
269
- hasEmphasis = true
270
- }
271
- if (!hasLinkClose && child.type === 'link_close') {
272
- hasLinkClose = true
273
- }
274
- if (allowReparse && brokenRefStart !== -1 && child.type === 'link_open') {
275
- if (brokenRefDepth <= 0) {
276
- brokenRefStart = -1
277
- brokenRefDepth = 0
278
- continue
279
- }
280
- const closeIdx = findLinkClose(children, j)
281
- if (closeIdx !== -1) {
282
- if (shouldReparseSegment(children, brokenRefStart, closeIdx)) {
283
- const originalMap = getMapFromTokenRange(children, brokenRefStart, closeIdx)
284
- const raw = buildRawFromTokens(children, brokenRefStart, closeIdx)
285
- const noLink = getNoLinkMdInstance(md, opt)
286
- const parsed = parseInlineWithFixes(noLink, raw, state.env)
287
- if (parsed && parsed.length > 0) {
288
- if (originalMap) {
289
- for (let k = 0; k < parsed.length; k++) {
290
- const childToken = parsed[k]
291
- if (childToken && !childToken.map) childToken.map = [originalMap[0], originalMap[1]]
292
- }
293
- }
294
- children.splice(brokenRefStart, closeIdx - brokenRefStart + 1, ...parsed)
295
- } else {
296
- const text = new Token('text', '', 0)
297
- text.content = raw
298
- if (originalMap) text.map = [originalMap[0], originalMap[1]]
299
- children.splice(brokenRefStart, closeIdx - brokenRefStart + 1, text)
300
- }
301
- brokenRefStart = -1
302
- changed = true
303
- didReparse = true
304
- break
305
- }
306
- brokenRefStart = -1
307
- }
308
- }
309
- }
310
- if (!didReparse) break
311
- reparseCount++
312
- if (reparseCount >= maxReparse) {
313
- allowReparse = false
314
- }
315
- if (!allowReparse) {
316
- continue
317
- }
318
- }
319
- }
320
- if (hasEmphasis) {
321
- if (fixEmOuterStrongSequence(children)) changed = true
322
- if (hasLinkClose && fixTailAfterLinkStrongClose(children, md, state.env)) changed = true
323
- if (hasLinkClose && fixLeadingAsteriskEm(children)) changed = true
324
- if (fixTrailingStrong(children)) changed = true
325
- }
326
- if (changed) rebuildInlineLevels(children)
327
- if (!hasBracketText) continue
328
- convertCollapsedReferenceLinks(children, state)
329
- mergeBrokenMarksAroundLinks(children)
330
- }
331
- })
332
- }
333
-
334
- export { registerTokenPostprocess }
1
+ export { registerTokenPostprocess } from './token-postprocess/orchestrator.js'