aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/remark/admonition-title-to-heading-before-toc.js111
1 files changed, 69 insertions, 42 deletions
diff --git a/src/remark/admonition-title-to-heading-before-toc.js b/src/remark/admonition-title-to-heading-before-toc.js
index 34d2f9fa..65e29d74 100644
--- a/src/remark/admonition-title-to-heading-before-toc.js
+++ b/src/remark/admonition-title-to-heading-before-toc.js
@@ -1,58 +1,85 @@
-import {visit, SKIP, EXIT, INDEX, CONTINUE} from 'unist-util-visit';
-import {inspect} from 'unist-util-inspect'
+import {visit} from 'unist-util-visit';
+import {inspect} from 'unist-util-inspect';
+/*
+Admonitionのツリー構造
+{
+ type: 'containerDirective',
+ name: 'info',
+ attributes: {},
+ children: [
+ {
+ type: 'paragraph',
+ data: { directiveLabel: true },
+ children: [
+ {
+ type: 'text',
+ value: '#### info title もしHTML等が入ると(ここにaタグを入れると)',
+ position: [Object]
+ },
+ {
+ type: 'mdxJsxTextElement',
+ name: 'a',
+ attributes: [],
+ position: [Object],
+ data: [Object],
+ children: [Array]
+ },
+ { type: 'text', value: 'このようにタイトル部が別々の要素として配列に入っている。', position: [Object] }
+ ],
+ position: {
+ start: { line: 1347, column: 8, offset: 34053 },
+ end: { line: 1347, column: 55, offset: 34100 }
+ }
+ },
+ { type: 'paragraph', children: [Array], position: [Object] },
+ ...
+ ],
+ ...
+}
+*/
const plugin = (options) => {
const transformer = async (ast) => {
- let hId = null;
- let hContent = null;
- let offset = 0;
-
- // Visitor関数を定義
+ let newBeginningText = "";
const visitor = ((node, index, parent) => {
if (node.type === 'containerDirective') {
- const val = node.children[0].children[0].value;
- if(/^##/.test(val)) {
- // headingノードをparentのchildrenに追加
+ // :::infoなどに続くタイトル冒頭Text部(冒頭#を含む(もしくは含まない)部分)を取得(:::info ##** )
+ // (タイトル全体にはHTML等が含まれる可能性があるため冒頭Text部だけ操作する、残りはシャロ―コピー)
+ const beginningText = node.children[0].children[0].value;
+
+ // タイトル冒頭Text部に#が2つ以上連続しているとき
+ if(/^##/.test(beginningText)) {
+ // タイトル冒頭部から#とそれに続く空白を削除
+ newBeginningText = beginningText.replace(/^#+/, '').trim();
+
+ // タイトル部冒頭だけ更新し、残りはシャロ―コピー
+ // まずタイトル部全体をシャロ―コピー
+ let titleNodes = [...node.children[0].children];
+
+ // 冒頭要素のvalueを更新(ほかはシャロ―コピー)
+ const newTitleBeginningNode = {
+ ...titleNodes[0],
+ value: newBeginningText,
+ }
+
+ // タイトルノードの冒頭要素だけ更新(ほかはシャロ―コピー)
+ const newTitleNodes = [ ...titleNodes ];
+ newTitleNodes[0] = newTitleBeginningNode;
+
+ // visitしているcontainerDirectiveの前にheadingノードを追加
parent.children.splice(index, 0, {
type: 'heading',
- depth: 4, // Headingの深さを適切に設定
- children: [{ type: 'text', value: val.replace(/^#+/, '').trim() }],
+ depth: (beginningText.match(/^##+/) || [''])[0].length, // #の連続数がheadingの深さ
+ children: newTitleNodes,
});
- //次に検索するのはindexを2つ飛ばしたノード。
+ // 次に検索するのはindexを2つ分飛ばしたノード
return index + 2;
}
}
});
-
+
visit(ast, 'containerDirective', visitor);
- /*
- visit(ast, 'containerDirective', (node, index, parent) => {
- //console.log(node);
- parent.children.splice(index, 0, {type: 'heading', depth: 4, children:[{type: 'text', value: 'テスト'}]});
- index++;
- //offset++;
- //console.log(offset);
- //return EXIT;
- // if (/^h[3-6]$/.test(node.tagName) && node.properties && node.properties.id) {
- // h3~h6のタグを見つけたら
- /*
- hId = node.properties.id;
- hContent = node.children && node.children[0] ? node.children[0].value : '';
- // h3~h6タグの隣にあるdivタグを探す
- const nextNode = parent.children[index + 1];
- if (nextNode && nextNode.tagName === 'admonition') {
- // 該当のdiv要素を見つけたらHタグの内容とline-5の#以降の文字列が一致した場合
- const contentAfterHash = nextNode.properties.title ? nextNode.properties.title.replace(/^#+/, '').trim() : '';
-
- if (contentAfterHash === hContent.trim()) {
- // Hタグのidを取得しそれをdivのidに設定
- nextNode.properties.id = hId;
- // Hタグを削除
- parent.children.splice(index, 1);
- }
- }*/
-// }
-// });
+
};
return transformer;
};