11import type { Plugin } from "unified" ;
2- import type { Nodes , Root , RootContent } from "mdast" ;
2+ import type { Nodes , PhrasingContent , Root , RootContent } from "mdast" ;
33import { phrasing } from "mdast-util-phrasing" ;
44
55/**
66 * `[[用語]]`を`<Term>用語</Term>`に変換するプラグイン。
7- * `[[**用語**]]`のように中身が単一のASTノードの場合も変換可能。
87 *
98 * @example
109 * // returns "<Term>**HTML**</Term>と<Term>CSS</Term>、そして<Term>JavaScript</Term>です。"
@@ -30,7 +29,7 @@ function transform(node: Nodes) {
3029 transform ( child ) ;
3130 }
3231
33- node . children = wrapDelimitedPhrasingAsTerm (
32+ node . children = wrapDelimitedPhrasingContentsAsTerm (
3433 node . children . flatMap ( ( child ) => isolateTermDelimiters ( child ) ) ,
3534 ) ;
3635}
@@ -47,35 +46,43 @@ function isolateTermDelimiters(node: RootContent): RootContent[] {
4746 } ) ) ;
4847}
4948
50- function wrapDelimitedPhrasingAsTerm ( children : RootContent [ ] ) : RootContent [ ] {
49+ function wrapDelimitedPhrasingContentsAsTerm (
50+ children : RootContent [ ] ,
51+ ) : RootContent [ ] {
5152 const result : RootContent [ ] = [ ] ;
53+ const buffer : PhrasingContent [ ] = [ ] ;
5254
53- let i = 0 ;
54- while ( i < children . length ) {
55- const openingDelimiter = children [ i ] ;
56- const innerNode = children [ i + 1 ] ;
57- const closingDelimiter = children [ i + 2 ] ;
58- if (
59- openingDelimiter . type === "text" &&
60- openingDelimiter . value === "[[" &&
61- innerNode &&
62- phrasing ( innerNode ) &&
63- closingDelimiter &&
64- closingDelimiter . type === "text" &&
65- closingDelimiter . value === "]]"
66- ) {
55+ for ( const child of children ) {
56+ if ( buffer . length === 0 ) {
57+ if ( child . type === "text" && child . value === "[[" ) {
58+ buffer . push ( child ) ;
59+ continue ;
60+ }
61+ result . push ( child ) ;
62+ continue ;
63+ }
64+
65+ if ( child . type === "text" && child . value === "]]" ) {
6766 result . push ( {
6867 type : "mdxJsxTextElement" ,
6968 name : "Term" ,
7069 attributes : [ ] ,
71- children : [ innerNode ] ,
70+ children : buffer . slice ( 1 ) ,
7271 } ) ;
73- i += 3 ;
74- } else {
75- result . push ( children [ i ] ) ;
76- i += 1 ;
72+ buffer . length = 0 ;
73+ continue ;
74+ }
75+
76+ if ( phrasing ( child ) ) {
77+ buffer . push ( child ) ;
78+ continue ;
7779 }
80+
81+ result . push ( ...buffer , child ) ;
82+ buffer . length = 0 ;
7883 }
7984
85+ result . push ( ...buffer ) ;
86+
8087 return result ;
8188}
0 commit comments