@peaceroad/markdown-it-strong-ja 0.7.0 → 0.7.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.
- package/index.js +13 -13
- package/package.json +1 -1
- package/src/token-compat.js +33 -27
- package/src/token-postprocess.js +15 -21
package/index.js
CHANGED
|
@@ -3,39 +3,39 @@ import { patchScanDelims } from './src/token-core.js'
|
|
|
3
3
|
import { registerTokenCompat } from './src/token-compat.js'
|
|
4
4
|
import { registerTokenPostprocess } from './src/token-postprocess.js'
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const buildNoLinkCacheKey = (opt) => {
|
|
7
7
|
const mode = resolveMode(opt)
|
|
8
8
|
const mditAttrs = opt && opt.mditAttrs === false ? '0' : '1'
|
|
9
9
|
const mdBreaks = opt && opt.mdBreaks === true ? '1' : '0'
|
|
10
10
|
return `${mode}|${mditAttrs}|${mdBreaks}`
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const getNoLinkMdInstance = (md, opt) => {
|
|
14
14
|
const baseOpt = opt || md.__strongJaTokenOpt || { mode: 'japanese' }
|
|
15
|
-
const key =
|
|
15
|
+
const key = buildNoLinkCacheKey(baseOpt)
|
|
16
16
|
if (!md.__strongJaTokenNoLinkCache) {
|
|
17
17
|
md.__strongJaTokenNoLinkCache = new Map()
|
|
18
18
|
}
|
|
19
19
|
const cache = md.__strongJaTokenNoLinkCache
|
|
20
20
|
if (cache.has(key)) return cache.get(key)
|
|
21
21
|
const noLink = new md.constructor(md.options)
|
|
22
|
-
|
|
22
|
+
mditStrongJa(noLink, { ...baseOpt, _skipPostprocess: true })
|
|
23
23
|
noLink.inline.ruler.disable(['link'])
|
|
24
24
|
cache.set(key, noLink)
|
|
25
25
|
return noLink
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const
|
|
28
|
+
const mditStrongJa = (md, option) => {
|
|
29
29
|
if (option && typeof option.engine === 'string' && option.engine !== 'token') {
|
|
30
30
|
throw new Error('mditStrongJa: legacy engine was removed; use token (default)')
|
|
31
31
|
}
|
|
32
32
|
const opt = {
|
|
33
|
-
mditAttrs: true,
|
|
34
|
-
mdBreaks: md.options.breaks,
|
|
35
|
-
mode: 'japanese',
|
|
36
|
-
coreRulesBeforePostprocess: [],
|
|
37
|
-
postprocess: true,
|
|
38
|
-
patchCorePush: true
|
|
33
|
+
mditAttrs: true, // assume markdown-it-attrs integration by default
|
|
34
|
+
mdBreaks: md.options.breaks, // inherit md.options.breaks for compat handling
|
|
35
|
+
mode: 'japanese', // 'japanese' | 'aggressive' | 'compatible' (pairing behavior)
|
|
36
|
+
coreRulesBeforePostprocess: [], // e.g. ['cjk_breaks'] to keep rules ahead of postprocess
|
|
37
|
+
postprocess: true, // enable link/ref reconstruction pass
|
|
38
|
+
patchCorePush: true // keep restore-softbreaks after late cjk_breaks
|
|
39
39
|
}
|
|
40
40
|
if (option) Object.assign(opt, option)
|
|
41
41
|
opt.hasCjkBreaks = hasCjkBreaksRule(md)
|
|
@@ -45,7 +45,7 @@ const tokenEngine = (md, option) => {
|
|
|
45
45
|
registerTokenCompat(md, opt)
|
|
46
46
|
|
|
47
47
|
if (!opt._skipPostprocess) {
|
|
48
|
-
registerTokenPostprocess(md, opt,
|
|
48
|
+
registerTokenPostprocess(md, opt, getNoLinkMdInstance)
|
|
49
49
|
const rawCoreRules = opt.coreRulesBeforePostprocess
|
|
50
50
|
const hasCoreRuleConfig = Array.isArray(rawCoreRules)
|
|
51
51
|
? rawCoreRules.length > 0
|
|
@@ -59,4 +59,4 @@ const tokenEngine = (md, option) => {
|
|
|
59
59
|
return md
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
export default
|
|
62
|
+
export default mditStrongJa
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peaceroad/markdown-it-strong-ja",
|
|
3
3
|
"description": "This is a plugin for markdown-it. It is an alternative to the standard `**` (strong) and `*` (em) processing. It also processes strings that cannot be converted by the standard.",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.2",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
package/src/token-compat.js
CHANGED
|
@@ -7,6 +7,12 @@ import {
|
|
|
7
7
|
moveRuleAfter
|
|
8
8
|
} from './token-utils.js'
|
|
9
9
|
|
|
10
|
+
const isAsciiWordCode = (code) => {
|
|
11
|
+
return (code >= 0x30 && code <= 0x39) ||
|
|
12
|
+
(code >= 0x41 && code <= 0x5A) ||
|
|
13
|
+
(code >= 0x61 && code <= 0x7A)
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
const registerTokenCompat = (md, baseOpt) => {
|
|
11
17
|
const hasTextJoinRule = Array.isArray(md.core?.ruler?.__rules__)
|
|
12
18
|
? md.core.ruler.__rules__.some((rule) => rule && rule.name === 'text_join')
|
|
@@ -43,7 +49,6 @@ const registerTokenCompat = (md, baseOpt) => {
|
|
|
43
49
|
md.__strongJaTokenSoftbreakSpacingRegistered = true
|
|
44
50
|
const normalizeSoftbreakSpacing = (state) => {
|
|
45
51
|
if (!state) return
|
|
46
|
-
const opt = getRuntimeOpt(state, baseOpt)
|
|
47
52
|
if (baseOpt.hasCjkBreaks !== true && state.md) {
|
|
48
53
|
baseOpt.hasCjkBreaks = hasCjkBreaksRule(state.md)
|
|
49
54
|
}
|
|
@@ -61,20 +66,21 @@ const registerTokenCompat = (md, baseOpt) => {
|
|
|
61
66
|
break
|
|
62
67
|
}
|
|
63
68
|
}
|
|
69
|
+
if (!hasEmphasis) continue
|
|
64
70
|
for (let j = 0; j < token.children.length; j++) {
|
|
65
71
|
const child = token.children[j]
|
|
66
72
|
if (!child) continue
|
|
67
73
|
if (child.type === 'softbreak') {
|
|
68
|
-
if (!hasEmphasis) continue
|
|
69
74
|
const prevToken = token.children[j - 1]
|
|
70
75
|
const nextToken = token.children[j + 1]
|
|
71
76
|
if (!prevToken || !nextToken) continue
|
|
72
77
|
if (prevToken.type !== 'text' || !prevToken.content) continue
|
|
73
78
|
if (nextToken.type !== 'text' || !nextToken.content) continue
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
const isAsciiWord =
|
|
77
|
-
const shouldReplace = isAsciiWord &&
|
|
79
|
+
const prevCharCode = prevToken.content.charCodeAt(prevToken.content.length - 1)
|
|
80
|
+
const nextCharCode = nextToken.content.charCodeAt(0)
|
|
81
|
+
const isAsciiWord = isAsciiWordCode(nextCharCode)
|
|
82
|
+
const shouldReplace = isAsciiWord && nextCharCode !== 0x7B && nextCharCode !== 0x5C &&
|
|
83
|
+
isJapaneseChar(prevCharCode) && !isJapaneseChar(nextCharCode)
|
|
78
84
|
if (!shouldReplace) continue
|
|
79
85
|
child.type = 'text'
|
|
80
86
|
child.tag = ''
|
|
@@ -90,10 +96,11 @@ const registerTokenCompat = (md, baseOpt) => {
|
|
|
90
96
|
for (let idx = 0; idx < child.content.length; idx++) {
|
|
91
97
|
const ch = child.content[idx]
|
|
92
98
|
if (ch === '\n') {
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const isAsciiWord =
|
|
96
|
-
const shouldReplace = isAsciiWord &&
|
|
99
|
+
const prevCharCode = idx > 0 ? child.content.charCodeAt(idx - 1) : 0
|
|
100
|
+
const nextCharCode = idx + 1 < child.content.length ? child.content.charCodeAt(idx + 1) : 0
|
|
101
|
+
const isAsciiWord = isAsciiWordCode(nextCharCode)
|
|
102
|
+
const shouldReplace = isAsciiWord && nextCharCode !== 0x7B && nextCharCode !== 0x5C &&
|
|
103
|
+
isJapaneseChar(prevCharCode) && !isJapaneseChar(nextCharCode)
|
|
97
104
|
if (shouldReplace) {
|
|
98
105
|
normalized += ' '
|
|
99
106
|
continue
|
|
@@ -128,27 +135,26 @@ const registerTokenCompat = (md, baseOpt) => {
|
|
|
128
135
|
const token = state.tokens[i]
|
|
129
136
|
if (!token || token.type !== 'inline' || !token.children || token.children.length === 0) continue
|
|
130
137
|
const children = token.children
|
|
138
|
+
let prevTextCharCode = 0
|
|
131
139
|
for (let j = 0; j < children.length; j++) {
|
|
132
140
|
const child = children[j]
|
|
133
|
-
if (!child
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
141
|
+
if (!child) continue
|
|
142
|
+
if (child.type === 'text') {
|
|
143
|
+
if (child.content === '') {
|
|
144
|
+
if (!prevTextCharCode || !isJapaneseChar(prevTextCharCode)) continue
|
|
145
|
+
const next = children[j + 1]
|
|
146
|
+
if (!next || next.type !== 'text' || !next.content) continue
|
|
147
|
+
const nextCharCode = next.content.charCodeAt(0)
|
|
148
|
+
if (nextCharCode !== 0x7B) continue
|
|
149
|
+
child.type = 'softbreak'
|
|
150
|
+
child.tag = ''
|
|
151
|
+
child.content = '\n'
|
|
152
|
+
child.markup = ''
|
|
153
|
+
child.info = ''
|
|
154
|
+
continue
|
|
140
155
|
}
|
|
156
|
+
prevTextCharCode = child.content.charCodeAt(child.content.length - 1)
|
|
141
157
|
}
|
|
142
|
-
if (!prevChar || !isJapaneseChar(prevChar)) continue
|
|
143
|
-
const next = children[j + 1]
|
|
144
|
-
if (!next || next.type !== 'text' || !next.content) continue
|
|
145
|
-
const nextChar = next.content.charAt(0)
|
|
146
|
-
if (nextChar !== '{') continue
|
|
147
|
-
child.type = 'softbreak'
|
|
148
|
-
child.tag = ''
|
|
149
|
-
child.content = '\n'
|
|
150
|
-
child.markup = ''
|
|
151
|
-
child.info = ''
|
|
152
158
|
}
|
|
153
159
|
}
|
|
154
160
|
}
|
package/src/token-postprocess.js
CHANGED
|
@@ -193,7 +193,7 @@ const fixTailAfterLinkStrongClose = (tokens, md, env) => {
|
|
|
193
193
|
return false
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
const registerTokenPostprocess = (md, baseOpt,
|
|
196
|
+
const registerTokenPostprocess = (md, baseOpt, getNoLinkMdInstance) => {
|
|
197
197
|
if (md.__strongJaTokenPostprocessRegistered) return
|
|
198
198
|
md.__strongJaTokenPostprocessRegistered = true
|
|
199
199
|
md.core.ruler.after('inline', 'strong_ja_token_postprocess', (state) => {
|
|
@@ -217,29 +217,23 @@ const registerTokenPostprocess = (md, baseOpt, getNoLinkMd) => {
|
|
|
217
217
|
const scanState = { depth: 0, brokenEnd: false }
|
|
218
218
|
for (let j = 0; j < children.length; j++) {
|
|
219
219
|
const child = children[j]
|
|
220
|
-
if (!child
|
|
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
|
+
}
|
|
221
232
|
if (scanBrokenRefState(child.content, scanState).brokenEnd) {
|
|
222
233
|
maxReparse++
|
|
223
234
|
}
|
|
224
235
|
}
|
|
225
|
-
if (maxReparse
|
|
226
|
-
for (let j = 0; j < children.length; j++) {
|
|
227
|
-
const child = children[j]
|
|
228
|
-
if (!child) continue
|
|
229
|
-
if (child.type === 'text' && child.content) {
|
|
230
|
-
if (!hasBracketText && (child.content.indexOf('[') !== -1 || child.content.indexOf(']') !== -1)) {
|
|
231
|
-
hasBracketText = true
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
if (!hasEmphasis &&
|
|
235
|
-
(child.type === 'strong_open' || child.type === 'strong_close' || child.type === 'em_open' || child.type === 'em_close')) {
|
|
236
|
-
hasEmphasis = true
|
|
237
|
-
}
|
|
238
|
-
if (!hasLinkClose && child.type === 'link_close') {
|
|
239
|
-
hasLinkClose = true
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
} else {
|
|
236
|
+
if (maxReparse !== 0) {
|
|
243
237
|
let allowReparse = true
|
|
244
238
|
while (true) {
|
|
245
239
|
let didReparse = false
|
|
@@ -288,7 +282,7 @@ const registerTokenPostprocess = (md, baseOpt, getNoLinkMd) => {
|
|
|
288
282
|
if (shouldReparseSegment(children, brokenRefStart, closeIdx)) {
|
|
289
283
|
const originalMap = getMapFromTokenRange(children, brokenRefStart, closeIdx)
|
|
290
284
|
const raw = buildRawFromTokens(children, brokenRefStart, closeIdx)
|
|
291
|
-
const noLink =
|
|
285
|
+
const noLink = getNoLinkMdInstance(md, opt)
|
|
292
286
|
const parsed = parseInlineWithFixes(noLink, raw, state.env)
|
|
293
287
|
if (parsed && parsed.length > 0) {
|
|
294
288
|
if (originalMap) {
|