This package is a unified/rehype plugin that wraps CJK character sequences in an element (defaulting to span) with a configurable attribute and value, useful for applying different CSS styling rules in multilingual contexts.
By default it emits <span class="cjk">...</span> as a pure styling hook. To emit semantic lang tags instead, pass attribute: 'lang' together with a value such as 'zh', 'ja', or 'ko'. Custom attribute names (e.g. data-lang) are also supported.
Note: this plugin is distributed in ESM and CJS.
npm install rehype-wrap-cjkA typical pipeline transforming Markdown into HTML with remark and rehype:
import rehypeSanitize from 'rehype-sanitize';
import rehypeStringify from 'rehype-stringify';
import rehypeCjkWrap from 'rehype-wrap-cjk';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import { unified } from 'unified';
export function processMarkdown(markdownContent: string): string {
const htmlOutput = unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypeCjkWrap)
.use(rehypeSanitize)
.use(rehypeStringify)
.processSync(markdownContent);
return String(htmlOutput);
}Example plain text input:
Sample text with CJK characters (中日韓字符) interspersed. 中文 can appear anywhere in the text and will be appropriately wrapped.
Example HTML output (default class="cjk" styling hook):
Sample text with CJK characters (<span class="cjk">中日韓字符</span>) interspersed. <span class="cjk">中文</span> can appear anywhere in the text and will be appropriately wrapped.Example CSS rules (for you to implement in your own projects):
.cjk {
font-style: normal !important;
text-decoration: none !important;
word-break: keep-all !important;
}Pass options as the second argument to .use(rehypeCjkWrap, { ... }).
element(default'span'): wrapper element name.attribute(default'class'): attribute written to the wrapper. Use'lang'for semantic language tagging,'class'for a styling hook, or any other attribute name (e.g.'data-lang').value(default'cjk'): value written toattribute. Also selects a preset regex when set to'zh','ja','ko', or'cjk'.regex(default derived fromvalue): custom pattern. Thegflag is added if missing.skipTags(default['code', 'pre', 'kbd', 'samp', 'script', 'style']): elements whose descendants are left alone. Pass[]to disable.
Text inside any ancestor that already carries the target attribute/value is not re-wrapped.