write-and-forget <p>markdown で妥協して新しくブログを作ることにした。</p> <!-- waf_thread::toc --> <h2 id="html-is-not-enough"><a class="permalink-anchor permalink-anchor-head" href="#html-is-not-enough"><!----></a>HTML では足りない!</h2> <p>メタデータや意味を十全に与えたいと考えたとき、 markdown は言うに及ばず、ある種の拡張なしの HTML であっても表現力に不満がある。</p> <h3 id="poor-blockquote"><a class="permalink-anchor permalink-anchor-head" href="#poor-blockquote"><!----></a>blockquote が貧弱すぎる</h3> <p>たとえば HTML で何らかのまとまった引用をしたいとき用いる <code>blockquote</code> タグを考えてみよう。 <code>blockquote</code> に特有の意味を与えられる機構は <code>cite</code> 属性と <code>cite</code> タグのみである。</p> <figure> <blockquote> <p>Content inside a <code>blockquote</code> must be quoted from another source, whose address, if it has one, may be cited in the <code>cite</code> attribute.</p> </blockquote> <figcaption> <p><a rel="external" href="https://web.archive.org/web/20241216222858/https://html.spec.whatwg.org/multipage/grouping-content.html#the-blockquote-element">HTML LS の cite 属性の解説 (<time>2024-12-16</time>)</a></p> </figcaption> </figure> <figure> <blockquote> <p>The cite element represents the title of a work (e.g. a book, a paper, an essay, a poem, a score, a song, a script, a film, a TV show, a game, a sculpture, a painting, a theatre production, a play, an opera, a musical, an exhibition, a legal case report, a computer program, etc.). This can be a work that is being quoted or referenced in detail (i.e., a citation), or it can just be a work that is mentioned in passing.</p> </blockquote> <figcaption> <p><a rel="external" href="https://web.archive.org/web/20241215200402/https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-cite-element">HTML LS の cite タグの解説 (<time>2024-12-15</time>)</a></p> </figcaption> </figure> <p>それ以外の情報は、著者や発言者も、参照日時も、出版日や版も、「強調は引用者による」も、区別して表現するためのタグや属性はない。</p> <p><a rel="external" href="https://developer.mozilla.org/ja/docs/Web/HTML/Element/cite">MDN</a> に載っている例では以下のようになっている:</p> <pre class="giallo" style="color-scheme: light dark; color: light-dark(#3C3836, #EBDBB2); background-color: light-dark(#FBF1C7, #282828);" data-lang="html"><code data-lang="html"><span class="giallo-l"><span style="color: light-dark(#076678, #83A598);"><</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">figure</span><span style="color: light-dark(#076678, #83A598);">></span></span> <span class="giallo-l"><span style="color: light-dark(#076678, #83A598);"> <</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">blockquote</span><span style="color: light-dark(#076678, #83A598);">></span></span> <span class="giallo-l"><span style="color: light-dark(#076678, #83A598);"> <</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">p</span><span style="color: light-dark(#076678, #83A598);">></span><span>It was a bright cold day in April, and the clocks were striking thirteen.</span><span style="color: light-dark(#076678, #83A598);"></</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">p</span><span style="color: light-dark(#076678, #83A598);">></span></span> <span class="giallo-l"><span style="color: light-dark(#076678, #83A598);"> </</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">blockquote</span><span style="color: light-dark(#076678, #83A598);">></span></span> <span class="giallo-l"><span style="color: light-dark(#076678, #83A598);"> <</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">figcaption</span><span style="color: light-dark(#076678, #83A598);">></span></span> <span class="giallo-l"><span> First sentence in </span><span style="color: light-dark(#076678, #83A598);"><</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">cite</span><span style="color: light-dark(#076678, #83A598);">></span><span style="color: light-dark(#076678, #83A598);"><</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">a</span><span style="color: light-dark(#B57614, #FABD2F);"> href</span><span style="color: light-dark(#7C6F64, #A89984);">=</span><span style="color: light-dark(#7C6F64, #A89984);">"</span><span style="color: light-dark(#79740E, #B8BB26);">http://www.george-orwell.org/1984/0.html</span><span style="color: light-dark(#7C6F64, #A89984);">"</span><span style="color: light-dark(#076678, #83A598);">></span><span>Nineteen Eighty-Four</span><span style="color: light-dark(#076678, #83A598);"></</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">a</span><span style="color: light-dark(#076678, #83A598);">></span><span style="color: light-dark(#076678, #83A598);"></</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">cite</span><span style="color: light-dark(#076678, #83A598);">></span><span> by George</span></span> <span class="giallo-l"><span> Orwell (Part 1, Chapter 1).</span></span> <span class="giallo-l"><span style="color: light-dark(#076678, #83A598);"> </</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">figcaption</span><span style="color: light-dark(#076678, #83A598);">></span></span> <span class="giallo-l"><span style="color: light-dark(#076678, #83A598);"></</span><span style="color: light-dark(#427B58, #8EC07C);font-weight: bold;">figure</span><span style="color: light-dark(#076678, #83A598);">></span></span></code></pre> <p>そう珍しいものではない形式の引用だが汎用のマークアップ (<code>figure</code> と <code>figcaption</code> 要素) で記述せねば紐付けられず、また "George Orwell" が著者である (しかし発言者ではない) ことは <code>figure</code> 要素でマークアップしてなお機械可読に表現されていないことがわかる。 もちろん「(中略)」を本文と区別して表現する能力もない。</p> <blockquote> <p>もちろん「(中略)」を本文と区別して表現する能力もない。</p> </blockquote> <p>万が一このような引用をする羽目になったら、「(中略)」が本当に何かを略しているのか、それとも単に記号列として「(」「中」「略」「)」が元からあったものなのか、引用の外側から補足が必要になる。 もっとも、機械可読に表現可能だったとしても補足するに越したことはないであろうが。</p> <p>似たような問題で、訳註が存在する文書をさらに翻訳して訳註を加えた場合にどれが翻訳前文書内の訳註でどれが最終翻訳者による訳註なのかマークアップで区別する標準的な方法がないというのも、 HTML の引用まわりの表現力の弱さの一例である。</p> <p>さらには markdown では <code>figure</code> 要素どころか <code>cite</code> 属性でさえ生の HTML の挿入なしに記述できない。 技術文書ばかりでなく日常的な文書であっても markdown や素朴な HTML では圧倒的に表現力が不足しており、 HTML タグに microdata なり RDFa Lite なりの追加仕様を組み合わせてはじめてまともなレベルになるわけで、喩えるなら高級言語を許されずアセンブリ言語を使わされているばかりか CFI directive まで常用せねばならないようなものである。 (一応 microdata は WHATWG HTML 標準内で定義されているようだが……。) このような迂遠なものを頻繁に作成し長期間メンテナンスするような文書群で使いたくはなかった。</p> <h3 id="lack-of-reference-and-dereference"><a class="permalink-anchor permalink-anchor-head" href="#lack-of-reference-and-dereference"><!----></a>参照能力と参照外し能力の欠如</h3> <p>HTML で markdown よりマシになるならタグが足りずともひとまず HTML で書けば良いではないかという話になるわけで、部分的には実際その通りなのだが、話はそれで終わらない。 上に挙げた例は microdata のような追加のメタデータで意味を与えれば解決できる問題だったが、根本的に重複なしでの記述が難しい課題がある。 それはクロスリファレンスや目次 (ToC) だ。</p> <p>たとえば同じページ内の特定のセクションへリンクしたいとき、そのリンクのテキストをセクション名から持ってきたり、あるいはセクション番号を利用したいということはあるだろう。 ToC (目次, Table of Contents) はその最たる例である。 HTML ではこれが自動化できず、自分でテキストを複製してきたりカウントして数字を直接使わねばならない。 一応 CSS でカウンタを使うことはできるが、その数字はあくまでスタイリングに使うことしかできず、マウスでドラッグして選択可能な本文として配置することはできない。 本文の一部としてそういった参照をしたくばソース中で複製・決め打ちする他なく、つまり文書を編集する際にミスして一貫性がなくなる (数字や文字列が実態と一致しなくなる) 可能性がそれなりに高い。</p> <p>footnote (脚注) も同じような問題を抱えており、 footnote をまとめる footer なり <code>aside</code> 要素なりにおける記載と、マウスホバーしたとき表示されるツールチップ (素朴には <code>title</code> 属性で実装できる) で同じ文章を表示しようとすると、ソース中でのテキストの複製が必要になる。 JavaScript を使えばどうにかできるにはできるが、それはむしろ HTML ではどうにもならないと言っているようなものである。 静的な文書に後付けの動的な機構を必須としたくはない。</p> <p>このような問題を抱える HTML という形式は、人間が保守する前提のしっかりしたドキュメントのソースファイルに適しているとはいえない。</p> <h3 id="more-stuff-missing"><a class="permalink-anchor permalink-anchor-head" href="#more-stuff-missing"><!----></a>他にもいろいろ不足あり</h3> <p><a rel="external" href="https://tdg.docbook.org/tdg/5.2/ref-elements">DocBook 5 の要素一覧</a>と比較すれば、 HTML の語彙がいかに貧弱で原始的であるかわかるだろう。 HTML では用語集も Q&A も全て <code>dl</code> タグで表現することになるし、ファイルパスも変数名も短いコード片もすべて <code>code</code> タグで表現することになる。</p> <p>HTML ではそのように情報を潰して潰して、それでもどうにかスタイルを変えるとよさそうなものだけを区別した結果が今定義されているタグなのであって、根本的に機械可読な意味を残すための形式ではない。 あくまで出力 (特に表示と印刷) のための形式か、あるいは編集がギリギリできるくらいの中間形式と捉えるくらいが妥当で、セマンティックな入力として最適に作られた形式と考えるべきではない。</p> <h2 id="settle-for-markdown-partially"><a class="permalink-anchor permalink-anchor-head" href="#settle-for-markdown-partially"><!----></a>markdown で諦める (ただし限定的に)</h2> <p>これだけ不満がありながら markdown を使うことにした理由は、単にこの調子でやっていくと記事にできたはずの考えまでどんどん揮発していきそうで、それはそれで非常に良くないと思ったからである。 最近 (というほど最近でもないが) XML 処理系を字句解析器レベルから自分で実装しようとしており (libxml2 と libxslt は偉大だがどうにも満足できない事情があった)、進捗は確かにあるもののこの調子ではあと何年かかるかわかったものではない。 markdown のように意味を込めるのが難しい形式であっても、そもそも意味を込める意義の薄い用途に限っては使い物になる。</p> <p>旧ブログではどんなに長く技術的な情報であっても、あるいはどんなに私的でどうでもいい情報であっても、無関係に豊かな語彙を活用して同じ場所にブログ記事としてしたためていた。 しかし冷静に考えて、誤った実装方法を警告する記事と技術的思想の解説記事と私的な日記が区別されず同居しているのは明らかに体験が悪い。 体験が悪かろうと区別が難しければ同居させるしかないことを私はここ十数年の SNS アカウント運用で身をもって学んだわけだが、そうはいってもやはり明らかに性質の異なる記事というのは存在するのである。</p> <p>その「性質」が最も極端なのが、日記である。 日記は後から書き直したり改善することが滅多になく (稀に追記やリンク URL 修正はあるかもしれない)、紐付けられたプライマリな日時が文脈として本質的に重要で、かつ正しさを価値判断の基準に持たない。 (一応補足すると、これは正しいことが価値を生まないという意味ではなく、誤った記述があるという事実そのものにも価値が認められることがあるということ。)</p> <p>何より個人的に、他人の私信とかいうやつは、ごく一部自分に刺さるトピックのものを除いてかなりどうでもいい。 日記の価値の8割くらい (数字は適当) は、他人に読まれることではなく自分に読み返されることによってその存在意義を回収するのではないだろうかと思えるほどである。 かような日記という空虚でどうでもいい記事群は、他人が読んで役立てられる前提の “どうでもよくない” 記事と同列で扱うようなものではなく、相応に人目につきづらい日陰に埋もれさせたい。 となれば、日記を正しく weblog として分離して、日記でなく正しさが重要でメンテナンスに値するような記事を別の場所でリッチにやるというのが妥当に思われる。</p> <p>そういったわけで、このたび日記や雑感の集積場所としてのブログをこうして分離して、こちらは既存実装で雑に用意することにした。 この文脈であれば、むしろ表現力が弱いという制約は「表現力が欲しくなるような用途に使うべからず」という誓約としてポジティブに機能させられよう。 そして本文形式を高度に拡張可能な static site generator を使わないことで、「埋もれるべき日陰の場所を必要以上に “良く” しない」という自分への枷とする。 このブログは (現時点では) <a rel="external" href="https://www.getzola.org/">Zola</a> を使っており、これは <a rel="external" href="https://www.getzola.org/documentation/content/shortcodes/">shortcode の定義機能</a>などがあるという点では高度だが、本文が基本的に markdown 前提であるという点では拡張性に乏しい。</p> <h2 id="reasons-not-to-use-existing-blog"><a class="permalink-anchor permalink-anchor-head" href="#reasons-not-to-use-existing-blog"><!----></a>旧ブログを使わない理由</h2> <p>実はオレオレ XML スキーマを利用して書けるブログを <a rel="external" href="https://nanoc.app/">nanoc</a> で用意して既に持っている。 nanoc は極めて拡張性が高く、本文が markdown である必要がないばかりか、オレオレ XML 文書を HTML にすることもできる。 そちらを使わず自力で XML 処理系を実装する理由はいくつかあるが、端的には Rust で書きたいから (あるいは Rust 以外で書きたくないから) ということになる。</p> <p>nanoc はキャッシュの仕組みがあってなおまあまあ遅かったり、フレームワークから少々外れたところでがっつりコードを書くことになったり、既存のフィルタも処理を改変したいため自分でパッチをあてる羽目になったり、 XSLT 1.0 範囲での記述だと面倒で汎用言語のロジック表現力を使いたかったりなどで、現状の旧ブログではあまり素直に nanoc に乗りきれていない。 また nanoc では、 XSLT によるレイアウトは XSLT 側での import や include による依存追跡がうまくできずキャッシュが不適切に利用されてしまったり、 XSLT でのレイアウトはページあたり1回しかできないため複数段の XSLT スタイルシート適用が素直にはできないという問題もあり、 XSLT の利用は手厚いサポートを受けているとはいえない状況である。 これは XSLT 前提でオレオレ XML を書きまくっている私にとっては懸念材料で、それならいっそ最初から Rust で書いた方がコントロールも効くし便利で楽しいだろうということで自前実装を試みることになった。</p> <p>そしてその自前実装が完成するまで待つほどのことでもないような記事を書き出す先として、また先述のように「どうでもいい」記事を隔離する場所として、新たにこのブログを用意した。</p> <h2 id="write-and-forget"><a class="permalink-anchor permalink-anchor-head" href="#write-and-forget"><!----></a>write-and-forget</h2> <p>このブログに置く記事の基準はただひとつ、「書いたきりノーメンテナンスで、あるいは最小限の追記に留めて放置することに躊躇いがないこと」である。</p> <p>たとえば次のように判断する。</p> <ul> <li>「この日こういったことがあった、こう感じた」は当時の事実認識のスナップショットとして価値があるので良い。 <ul> <li>認識が変わってどうしても補足したくなったら、後日に紐付けて別の記事を作ってリンクだけ追加する。旧記事そのものを訂正してはいけない。</li> </ul> </li> <li>「このバージョンの処理系ではこう書くのが正しい」は「後のバージョンでは別のこのような書き方が正しい」と大きめの情報を補足したくなるので望ましくない。 <ul> <li>「このバージョンの処理系にこういったバグがあった」までなら「後のバージョンでは直った」という僅かな追記で済むので良い。</li> </ul> </li> <li>「こういったトラブルがあったのでこう対処した (できなかった)」は、成果がなかろうと誤っていようと作業記録としての価値があるので良い。 <ul> <li>誤ったリスクある手順があとで発見されたら「この手順は適当でないので真似してはいけない」程度の追記で済ますこと。正しい手順を長々と解説しようとするのは望ましくない。 <ul> <li>誤っている理由の追加くらいはあっても良い。</li> </ul> </li> </ul> </li> <li>製品の評価 (レビュー) などは、各種観点あるいは総合的にみての評価という特定構造のメタデータを共通して持つような記事なので望ましくない。 <ul> <li>多少なりとも機械可読な情報を提供したい気持ちがあるなら、最初からそのように設計したり後から既存データの構造を弄れるような柔軟なシステムに乗せるべき。</li> <li>あくまで感想や経験を主観的に述べるものであって結論として点数をつけたりしないようなものであれば、まあ良いか……</li> </ul> </li> </ul> <p>このような性質を、 fire-and-forget という概念をもじって <strong>write-and-forget</strong> と呼ぶことにした。 <a rel="external" href="https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%83%BB%E3%82%A2%E3%83%B3%E3%83%89%E3%83%BB%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B2%E3%83%83%E3%83%88">fire-and-forget</a> とはミサイル兵器だけでなくしばしばプログラミングの文脈でも用いられる概念で、ミサイルやリクエストやタスクをひとたび fire (発射) すればその後の動作を監視したりコントロールする必要がないという性質のことである。</p> <p>そしてこのブログを write-and-forget メディアにするという戒めとして、 <code>waf_thread</code> と命名することにした。 今後このサイトには忘れられるべき記事が打ち捨てられていくことになるだろう。</p>