remark-cjk-adjacent-strong
v0.0.2
Published
remark plugin that repairs literal **...** strong sequences left unparsed when punctuation-ended content is immediately followed by CJK text.
Downloads
197
Maintainers
Readme
remark-cjk-adjacent-strong
remark-cjk-adjacent-strong 是一个 remark 插件,用来修复 Markdown/MDX 中因为 CJK 邻接字符而导致 **...** 强调仍然停留在 plain text 的狭窄问题。
典型例子:
**커피(coffee)**가**コーヒー(coffee)**が**咖啡(coffee)**是
README 语言
什么时候使用这个插件?
当闭合 ** 后面紧跟着 CJK 字符,默认解析器没有生成强调而是把它保留为 literal text 时,就应该使用这个插件。
这通常发生在 **...** 内部最后一个字符是 ), ?, !, 引号、括号等标点或符号时。
包定位
- 公开包名:
remark-cjk-adjacent-strong - 默认入口面向更广的 CJK 邻接修复
./hangul提供 Hangul 专用 preset./core提供公共 factory
安装
npm install remark-cjk-adjacent-strong兼容性
- Node.js 18+
- ESM 包
- 可用于
next-mdx-remote、@next/mdx、Contentlayer、Astro MDX、plainunified管道等remarkPlugins链
应该使用哪个入口?
默认入口
import remarkCjkAdjacentStrong from 'remark-cjk-adjacent-strong'当你想同时修复以下文字系统的相邻情况时,使用它:
- Hangul
- Han
- Hiragana
- Katakana
Hangul 专用入口
import remarkHangulAdjacentStrong from 'remark-cjk-adjacent-strong/hangul'当你只需要韩语邻接修复时使用它。
Core factory
import { createRemarkAdjacentStrong } from 'remark-cjk-adjacent-strong/core'
const remarkAsciiAdjacentStrong = createRemarkAdjacentStrong(/[A-Z]/u)当你想复用相同的修复引擎,但自己定义后续字符规则时使用它。
集成示例
plain unified 管道
import remarkCjkAdjacentStrong from 'remark-cjk-adjacent-strong'
import remarkParse from 'remark-parse'
import { unified } from 'unified'
const processor = unified()
.use(remarkParse)
.use(remarkCjkAdjacentStrong)remarkPlugins 链
import remarkCjkAdjacentStrong from 'remark-cjk-adjacent-strong'
import remarkGfm from 'remark-gfm'
const mdxOptions = {
remarkPlugins: [remarkGfm, remarkCjkAdjacentStrong],
}精确的 rewrite 条件
转换器只会修复同时满足以下条件的 plain text 节点:
- 文本中存在
**X**Y模式 X不包含*或换行X的最后一个字符匹配/[\p{P}\p{S}]/uY的第一个字符匹配配置好的 suffix-character 模式- 文本不在受保护节点内部
默认 CJK suffix 模式:
/[\p{Script=Hangul}\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/uHangul 专用 suffix 模式:
/[\p{Script=Hangul}\p{Script=Hangul_Jamo}\p{Script=Hangul_Compatibility_Jamo}]/u已覆盖的示例
默认 CJK 入口会修复的示例
| 输入 | 结果 |
| --- | --- |
| **커피(coffee)**가 필요하다. | <strong>커피(coffee)</strong>가 필요하다. |
| **브런치(brunch)**를 먹으러 가자. | <strong>브런치(brunch)</strong>를 먹으러 가자. |
| **コーヒー(coffee)**が好きだ。 | <strong>コーヒー(coffee)</strong>が好きだ。 |
| **拿铁(latte)**也很受欢迎。 | <strong>拿铁(latte)</strong>也很受欢迎。 |
| **咖啡(coffee)**是必需品。 | <strong>咖啡(coffee)</strong>是必需品。 |
Hangul 专用入口会修复的示例
| 输入 | 结果 |
| --- | --- |
| **커피(coffee)**가 필요하다. | <strong>커피(coffee)</strong>가 필요하다. |
| **디저트(dessert)**를 곁들이자. | <strong>디저트(dessert)</strong>를 곁들이자. |
| **라테(latte)**를 마셔 보자. | <strong>라테(latte)</strong>를 마셔 보자. |
| **커피(coffee)!**가 먼저다. | <strong>커피(coffee)!</strong>가 먼저다. |
| **모카(mocha).**도 괜찮다. | <strong>모카(mocha).</strong>도 괜찮다. |
有意不覆盖的范围
CommonMark 已经能正确处理的情况
**커피**는 이미 잘 파싱된다.**커피(coffee)** 가 필요하다.**커피(coffee)**!설명 예시는 **coffee**이렇게도 붙을 수 있다.
非目标 suffix
**咖啡(coffee)**abc**咖啡(coffee)**123
受保护节点
codeinlineCodehtmlstrongemphasisdeletelinkmdx*
保持 literal 的例子:
`**コーヒー(coffee)**が`[**咖啡(coffee)**是](https://example.com)<Callout>**커피(coffee)**가</Callout>~~**라테(latte)**를~~
已知取舍
这个插件比较保守,但仍然可能把说明用 literal 示例转换成真正的 strong。
例如:
설명 예시는 **커피(coffee)**가 라고 적는다고 착각할 수 있다.
如果某个 literal 示例必须保持原样,最好把它放进 inline code 之类的受保护上下文中。
代表性的副作用候选写在 fixtures/manual-check.mdx 里。
包结构
src/core.ts: 公共遍历与修复引擎src/hangul.ts: Hangul 专用 presetsrc/index.ts: 默认 CJK preset 与主入口
API
默认 export
remarkCjkAdjacentStrong
named exports
remarkCjkAdjacentStrongCJK_SUFFIX_CHARACTERremarkHangulAdjacentStrongHANGUL_SUFFIX_CHARACTERcreateRemarkAdjacentStrong
开发
npm install
npm run verify
npm run pack:check发布检查清单
- 运行
npm run verify - 运行
npm run pack:check - 确认
package.json元数据 - 运行
npm publish
由于配置了 prepublishOnly,发布时会重新执行验证和 dry-run pack check。
