From d49126efde8807589cf59833ed05e544275cf401 Mon Sep 17 00:00:00 2001 From: 安竹洋平 <61961825+yasutakeyohei@users.noreply.github.com> Date: Thu, 9 May 2024 00:19:19 +0900 Subject: build --- build/blog/atom.xml | 68 +++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 33 deletions(-) (limited to 'build/blog/atom.xml') diff --git a/build/blog/atom.xml b/build/blog/atom.xml index 45ec26d3..ec6bc000 100644 --- a/build/blog/atom.xml +++ b/build/blog/atom.xml @@ -20,7 +20,7 @@

合気公園に関してこれまでの経緯はこちら↓にまとめています。

セレモニーの様子

@@ -43,16 +43,16 @@
  • 閉会の辞(水と緑と公園課長)
  • お知らせ(水と緑と公園課長)
  • -

    最後のお知らせとしては、2種類の草の種子を植えているので養生中とのことでした。4月中旬頃に様子をみて養生の囲いを外すそうです。

    +

    最後のお知らせとしては、2種類の草の種子を植えているので養生中とのことでした。4月中旬ころに様子をみて養生の囲いを外すそうです。

    挨拶の様子
    -↑沢山の方が参加されました。

    +↑たくさんの方が参加されました。

    除幕直前

    除幕直後
    ↑市長、市議会議長、木村氏、岡江氏により、顕彰碑の除幕が行われました。

    式次第(小平市)

    そのほかの写真

    -

    以下の写真と動画はセレモニー直後と3月28日(木)に撮影したものです。

    +

    次の写真と動画はセレモニー直後と3月28日(木)に撮影したものです。

    出入口

    正面出入口
    正面出入口

    @@ -65,7 +65,7 @@

    合気公園・顕彰碑

    合気公園・顕彰碑詳細

    -

    合気柔術は それ以前の柔術や柔道とは全く別系統の柔術で 武田忽角先生によって初めて世に知られるようになった

    +

    合気柔術は それ以前の柔術や柔道とはまったく別系統の柔術で 武田忽角先生によって初めて世に知られるようになった

    佐川幸義先生は 明治三十五年北海道の湧別に生まれ 十歳より 武田先生から大東流合気柔術を習い 三十歳代には武田先生と二人で各地を教えて廻った

    昭和三十年 小平市のこの場所に正伝大東流合気武術総本部道場(佐川道場)を開いた

    平成十年に九十五歳で逝去する前日までこの佐川道場で合気を発展させ続け前人未到の境地に達し人間が年齢を乗り越える可能性を体現した

    @@ -75,12 +75,12 @@ 円満に滞り無く動じて居るのである
    その調和が合氣なのである

    -

    日本庭園

    +

    日本庭園

    日本庭園(1)

    日本庭園(2)
    -早くも子ども達が石に上って遊んでいました😍

    +早くも子どもたちが石に上って遊んでいました😍

    道場跡地横にあるベンチ

    -

    道場跡地横にあるベンチ
    +

    道場跡地横のベンチ
    緑色に舗装された部分が道場跡地です。

    テーブル

    ベンチとテーブル

    @@ -94,14 +94,15 @@

    公園の立て看板

    売却予定地

    売却予定地
    -佐川幸義氏のご遺族から土地約1,300㎡と現金約3,000万円をご遺贈いただき、さらにふるさと納税で小平市として過去最多の約1,600万円ものご寄附をいただきました。それでもなお整備費用として約2千万円が不足しているという理由から、小林洋子市政である小平市は1区画を売却することになりました。

    -

    路線価は約21万円/㎡ですので土地の評価額は約2.7億円となります。合計で優に3億円もの寄附をいただいたことになります。また市民と市が理想的な形での協働ができたり、ふるさと納税で歴代記録を更新している画期的な事業だったわけですから、最後は市に残りの整備費用を出してもらいたかったところです。残念ですがこの1区画は令和6年度中に売却予定です。

    +佐川幸義氏のご遺族から土地約1,300㎡と現金約3,000万円をご遺贈いただき、さらにふるさと納税で小平市として過去最多の約1,600万円ものご寄附をいただきました。ありがとうございました。それでもなお整備費用として約2千万円が不足しているという理由から、小林洋子市政である小平市は1区画を売却するとしました。

    +

    路線価は約21万円/㎡ですので、土地の評価額は約2.7億円となります。合計で優に3億円もの寄附をいただいたことになります。また市民と市が理想的な形での協働ができたり、ふるさと納税で歴代記録を更新している画期的な事業だったわけですから、最後は市に残りの整備費用を出してもらいたかったところです。残念ですがこの1区画は令和6年度中に売却予定です。

    動画

    Xに投稿した動画をご覧ください。

    -
    ]]> +
    +]]> 安竹 洋平 yohei@yasutakeyohei.com @@ -125,7 +126,7 @@

    合気公園に関してこれまでの経緯はこちら↓にまとめています。

    市民による公園整備案

    旧佐川邸の公園化を考える会が市に提出した公園計画案はこちら↓(ランドスケープデザイナー・鈴木綾氏による)

    @@ -135,7 +136,7 @@

    市民による計画案を受けて小平市水と緑と公園課が提示した合気公園整備イメージ案

    この整備イメージに基づいて整備が進んでいます。

    写真

    -

    以下の写真と動画は令和6年1月30日(火)に撮影したものです。

    +

    次の写真と動画は令和6年1月30日(火)に撮影したものです。

    お知らせ

    合気公園整備中・お知らせ

    野外卓・顕彰碑・背なしベンチ

    @@ -151,7 +152,7 @@

    合気公園整備中・水飲み場・東側出入口

    庭園付近

    合気公園整備中・庭園付近

    -

    西側出入口への道・目隠しフェンス

    +

    西側出入口への道・目隠しフェンス

    合気公園整備中・西側出入口への道・目隠しフェンス

    南東の角

    道路が拡幅されていることが分かります。

    @@ -162,12 +163,12 @@

    売却予定地

    奥の砂が盛ってあるところが売却予定地です。

    合気公園整備中・売却予定地(奥の砂が盛ってあるところ)

    -

    拡幅された東側道路

    +

    拡幅された東側道路

    合気公園整備中・拡幅された東側道路

    道路拡幅は売却予定地前まで

    合気公園整備中・道路拡幅は売却予定地前まで

    佐川氏が四股を踏んでいたとされる石

    -

    右下の平らな石が佐川幸義氏が四股を踏んでいたとされる石です。

    +

    右下の平らな石が、佐川幸義氏が四股を踏んでいたとされる石です。

    合気公園整備中・四股を踏んでいたと思われる石

    西側出入口

    案内板はまだ設置されていません。

    @@ -175,14 +176,15 @@

    西側園路と目隠しフェンス

    合気公園整備中・西側園路と目隠しフェンス

    西側の工事看板・目隠しフェンス上部

    -

    目隠しフェンス上部は人が乗り越えられないような突起が出ています。

    +

    目隠しフェンス上部は人の乗り越えられないような突起が出ています。

    合気公園整備中・西側の工事看板・目隠しフェンス上部

    -

    西側園路の舗装

    +

    西側園路の舗装

    合気公園整備中・西側園路の舗装

    動画

    +

    以上です。完成が楽しみですね。

    ]]> 安竹 洋平 @@ -205,10 +207,10 @@

    文書作成と管理が容易で、拡張の自由度も非常に高く、完全なオープンソース。

    議員活動に重要な「資料を作成しまとめて公開するツール」として現状の最適解と感じます。

    -

    facebookが母体なので色々と気になるところですが、Reactを初めとして有益なソフトウェアを完全なオープンソースとして提供してくれていることは純粋にありがたいと感じます。

    +

    Facebookが母体なのでいろいろと気になるところですが、Reactを初めとして有益なソフトウェアを完全なオープンソースとして提供してくれていることは純粋にありがたいと感じます。

    Admonitionのタイトルが見出しにならない

    -

    さてDocusaurusにはAdmonition(注意書きや警告文)を容易にmarkdownで書く方法が用意されています。

    -

    例えばinfoなら、次のようにmarkdownで書けば、

    +

    さてDocusaurusにはAdmonition(注意書きや警告文)を容易にMarkdownで書く方法が用意されています。

    +

    たとえばinfoなら、次のようにMarkdownで書けば、

    Admonitionの記法(mdもしくはmdxに記載)
    :::info[infoの例]

    ここに文章を書く

    :::

    次のようにHTMLで表示されます。

    infoの例

    ここに文章を書く

    @@ -223,20 +225,20 @@
    備考

    テスト

    ~文章~

    ほかのユーザーからの要望も上がっており、私も少し不便に感じていたので、次の仕様になるようカスタマイズしましたのでその方法を解説します。

    カスタマイズ後はどうなるか

    -

    後述のカスタマイズをすると、Admonitionのタイトル部に(通常の見出しmarkdownと同様に)#を冒頭に2個以上入れる ことで見出しになります。またTOCにも反映されます。#を2個以上としているのは、H1をAdmonitionには使わないはずのため。また#を入れない場合は見出しにならず、TOCにも反映されません。

    +

    後述のカスタマイズをすると、Admonitionのタイトル部に(通常の見出しMarkdownと同様に)#を冒頭に2個以上入れる ことで見出しになります。またTOCにも反映されます。#を2個以上としているのは、H1をAdmonitionには使わないはずのため。#を入れない場合は見出しにならず、TOCにも反映されません。

    タイトル冒頭に#を入れた場合

    Admonitionの記法(mdもしくはmdxに記載)
    :::info[#### 見出しになりTOCに反映されるタイトルの例]

    #が4つ分のためH4見出しになります。TOCにも反映されます。

    :::

    -

    見出しになりTOCに反映されるタイトルの例

    #が4つ分のためH4見出しになります。TOCにも反映されます。

    +

    見出しになり、TOCに反映されるタイトルの例

    #が4つ分のためH4見出しになります。TOCにも反映されます。

    このブログでもTOCに表示されています。
    なおマウスカーソルを乗せた際にハッシュリンク(#)が表示されるようにするにはCSSの設定が必要です。

    タイトル冒頭に#を入れない場合

    Admonitionの記法(mdもしくはmdxに記載)
    :::info[見出しにならずTOCに反映されないタイトルの例]

    #がないため見出しにならず、TOCにも反映されません。

    :::

    -

    見出しにならずTOCに反映されないタイトルの例

    #がないため見出しになりません。

    -

    タイトルにHTMLを入れることも可能

    +

    見出しにならず、TOCに反映されないタイトルの例

    #がないため見出しになりません。

    +

    タイトルにHTMLを入れることも可能

    なおタイトル部にHTMLを入れることもできます。TOCにも反映されます。

    テスト123テスト下線


    タイトル部のmarkdownは次の通りです。

    #### テスト<sup>123</sup>テスト<u>下線</u>

    @@ -247,25 +249,25 @@
  • Swizzling
  • RemarkとRehypeについて

    -

    RemarkとRehypeは、markdownをHTMLに変換するプロセスにおいて、AST(抽象構文木・Abstract Syntax Tree)に作用するプラグインです。なおASTを操作するオープンソースのエコシステムの中にはもう一つRetextというプラグインもありますが、Docusaurusには実装されていないようです。

    +

    RemarkとRehypeは、MarkdownをHTMLに変換するプロセスにおいて、AST(抽象構文木・Abstract Syntax Tree)に作用するプラグインです。なおASTを操作するオープンソースのエコシステムの中にはもう1つRetextというプラグインもありますが、Docusaurusには実装されていないようです。

    markdownからHTMLへ変換処理の流れ
    | ........................ process ........................... |
    | .......... parse ... | ... run ... | ... stringify ..........|

    +--------+ +----------+
    Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output
    +--------+ | +----------+
    X
    |
    +--------------+
    | Transformers |
    +--------------+

    上図(Unified Overviewより)にTransformersとあるところがRemark/Rehypeの動作するところ。

    -

    Remarkはmarkdown形式で、RehypeはHTML形式でASTを扱います。どちらも同じようにASTを操作できますが、データ構造が違うため、目的に応じて選択することになるのかなと思います。

    +

    RemarkはMarkdown形式で、RehypeはHTML形式でASTを扱います。どちらも同じようにASTを操作できますが、データ構造が違うため、目的に応じて選択することになるのかなと思います。

    こちらのサイトなどが詳しいです。

    Docusaurusにおけるプラグインの実行タイミング

    Docusaurusでこれらのプラグインを利用するためにはdocusaurus.config.jsonに設定が必要です。このページによると次の4種類の設定値にてプラグインを登録できます。

    デフォルトプラグイン適用前デフォルトプラグイン適用後
    Remark
    Markdown形式
    beforeDefaultRemarkPluginsremarkPlugins
    Rehype
    HTML形式
    beforeDefaultRehypePluginsrehypePlugins
    -

    markdownからHTMLへの変換処理のところで、Docusaurusは自前のプラグイン(デフォルトプラグイン)を使い「見出しにidをつける」「ASTからTOCを作成する」などの処理を行っています。そのため今回のように「Amonitionのタイトルを読んでTOCに反映する」ためには、デフォルトプラグイン適用前と適用後の両方のタイミングでの処理が必要になります。

    +

    MarkdownからHTMLへの変換処理のところで、Docusaurusは自前のプラグイン(デフォルトプラグイン)を使い「見出しにidをつける」「ASTからTOCを作成する」などの処理を行っています。そのため今回のように「Amonitionのタイトルを読んでTOCに反映する」ためには、デフォルトプラグイン適用前と適用後の両方のタイミングでの処理が必要になります。

    Swizzlingについて

    -

    Swizzlingはこちらに説明がある通りの機能で、簡単に言うとReactのコンポーネントをカスタマイズできる機能です。

    -

    Swizzlingの設定をすると、Docusaurusがデフォルトのコンポーネントの代わりに自動的にカスタマイズしたコンポーネントを使用するようになります。

    +

    Swizzlingはこちらに説明があるとおりの機能で、簡単に言うとReactのコンポーネントをカスタマイズできる機能です。

    +

    Swizzlingの設定をすると、Docusaurusがデフォルトのコンポーネントの代わりに自動的にカスタマイズしたコンポーネントを使用します。

    今回は、デフォルトのAdmonitionにないID属性を持たせるためAdmonitionコンポーネントをカスタマイズしました。Swizzlingの設定をすることにより、デフォルトのAdmonitionの代わりにこのカスタムコンポーネントが使われるようにします。

    動作原理

    TOCは「ASTに含まれているheading要素を単純に配列に入れている」だけですが、この処理はカスタマイズで上書きできません。そこで、カスタマイズできる処理だけでAdmonitionのタイトルをTOCに反映する方法として次を思いつき、実装しました。

    1. docusaurusのデフォルトプラグインがTOCの処理を行うより前に、Admonitionのタイトル部を見出しとして新規作成し、Admonition要素の直前に追加する
    2. docusaurusのデフォルトプラグインがTOCの処理を行い、Admonitionのタイトル部がTOCに入る。見出しにはidが付与される
    3. -
    4. デフォルトプラグインの処理が終了したら作成した見出しは不要になるので削除する。その際、削除する見出しと同じタイトルを持つAdmonition要素を探し、idを与える
    5. +
    6. デフォルトプラグインの処理が終了したら作成した見出しは不要になるので削除する。その際、削除する見出しと同じタイトルをもつAdmonition要素を探し、idを与える
    7. AdmonitionコンポーネントでidをHTMLタグに付与する

    実装

    @@ -279,14 +281,14 @@

    docusaurusのsrcディレクトリ下にrehypeとremarkというディレクトリを作り、次のファイル名と内容で2つのプラグインを作ります。

    src/rehype/admonition-title-to-heading-before-toc.js
    import {visit} from 'unist-util-visit';

    const plugin = (options) => {
    const transformer = async (ast) => {
    let newBeginningText = "";
    const visitor = ((node, index, parent) => {
    if (node.type === 'containerDirective') {
    // :::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: (beginningText.match(/^##+/) || [''])[0].length, // #の連続数がheadingの深さ
    children: newTitleNodes,
    });
    // 次に検索するのはindexを2つ分飛ばしたノード
    return index + 2;
    }
    }
    });

    visit(ast, 'containerDirective', visitor);

    };
    return transformer;
    };

    export default plugin;
    src/rehype/admonition-title-to-heading-after-toc.js
    import {visit} from 'unist-util-visit';

    const plugin = (options) => {
    const transformer = async (ast) => {
    let hId = null;
    let hContent = null;
    visit(ast, 'element', (node, index, parent) => {
    if (/^h[2-6]$/.test(node.tagName) && node.properties && node.properties.id) {
    // H要素(h2~h6)を見つけた場合

    // IDとタイトルの冒頭Text部を取得する
    hId = node.properties.id;
    hContent = node.children ? node.children[0].value :
    node.children[0].children[0] ? node.children[0].children[0].value : '';

    // 続くAdmonitionを探す(docはH要素とadmonitionが連続しているが
    // blogではなぜか改行要素{ type:'text', value:'\n' }が間に入っているので念のため隣接3要素を探す
    for (let i = index + 1; i < index + 4 && i < parent.children.length; i++) {
    if(parent.children[i] && parent.children[i].tagName === 'admonition') {
    // admonition(div)を見つけた場合
    const admonitionNode = parent.children[i];

    // admonitionタイトルの冒頭Text部分を取得(properties.titleもしくはchildren[0].children[0].value)
    const admonitionNodeTitle = admonitionNode.properties.title ? admonitionNode.properties.title :
    admonitionNode.children[0] && admonitionNode.children[0].children[0] ? admonitionNode.children[0].children[0].value : '';

    if(/^##/.test(admonitionNodeTitle) && admonitionNodeTitle.replace(/^#+/, '').trim() === hContent.trim()) {
    // #で始まっていて、タイトル冒頭部が同じ場合
    // divのidをHタグのidに設定
    admonitionNode.properties.id = hId;
    // H要素を削除
    parent.children.splice(index, 1);
    }
    }
    }
    }
    });
    };
    return transformer;
    };

    export default plugin;
    -
    Admonitionのツリー構造

    参考までに、Remarkのプラグインから見るとAdmonitionのASTは例えば次のようになっています。

    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] },
    ...
    ],
    ...
    }
    +
    Admonitionのツリー構造

    参考までに、Remarkのプラグインから見るとAdmonitionのASTはたとえば次のようになっています。

    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] },
    ...
    ],
    ...
    }

    Swizzling

    次にSwizzlingです。

    Docusaurusのsrc/themeディレクトリにAdmonitionというディレクトリを作り、次の一例のファイルを格納します。

    なおここに説明がある通りSwizzlingにはEjectingとWrappingの方法があります。

    WrappingではAdmonitionの内部までカスタマイズできないため「タイトル部分にidプロパティを付ける」といったことができません。そのためEjectingを使います。

    注記

    Ejectingを使う場合はバージョンアップによってデフォルトのコンポーネントと挙動が変わってくる可能性があるのでアップグレードの際は注意が必要です。

    -

    Ejecting

    +

    Ejecting

    npm run swizzle @docusaurus/theme-classic Admonition -- --eject

    Docusaurus V3.1では次のようなメッセージが出ますので、YESを選びます。

    ? Do you really want to swizzle this unsafe internal component? » - Use arrow-keys. Return to submit.
    NO: cancel and stay safe
    > YES: I know what I am doing!
    -- cgit v1.2.3-54-g00ecf