Skip to content

Commit e1ca460

Browse files
committed
複数のASTノードにも対応
1 parent f07e9c0 commit e1ca460

1 file changed

Lines changed: 30 additions & 23 deletions

File tree

src/remark/remark-term.ts

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import type { Plugin } from "unified";
2-
import type { Nodes, Root, RootContent } from "mdast";
2+
import type { Nodes, PhrasingContent, Root, RootContent } from "mdast";
33
import { 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

Comments
 (0)