オープンソースの画像生成AIをセットアップから使い方まで解説する『Stable Diffusion AI画像生成ガイドブック』(ソシム刊)発売中(→本のサポートページ

はてなブログにおけるはてな記法の展開バグあれこれ

はてなブログにおけるはてな記法の解釈にはバグが多い。こちらでつかんでいるものは以下で、すべて運営に報告済みであるが、ここでいったんまとめておこうと思う。

定義リスト記法のdt要素にURLなどがあるとその中のコロンからdd要素になる

定義リスト記法は行頭に「:」を書き、続く文字列と「:」を書く。「:A:B」のように書くと、Aがdl(定義リスト)要素のdt要素、Bがdd要素になる。

:A(定義リストの見出し、dt要素):B(定義リストの内容、dd要素)

↑こう書くとこうなる↓

<dl>
<dt>A(定義リストの見出し、dt要素)</dt>
<dd>B(定義リストの内容、dd要素)</dd>
</dl>

表示結果は以下。

A(定義リストの見出し、dt要素)
B(定義リストの内容、dd要素)

この定義リスト記法において、「A」の範囲にURLやid記法(例:id:Imamura)など「:」を含む文字列があると、そこでdt要素が終わったものと勘違いされてしまうことがある。

たとえば「:https://www.hatena.ne.jp/:はてな」と書いたとする。期待されるHTMLは以下である。

<dl>
<dt>https://www.hatena.ne.jp/</dt>
<dd>はてな</dd>
</dl>

はてなダイアリーではこの通りのHTMLが出力され、以下のようになっていた。

https://www.hatena.ne.jp/
はてな

しかし、今のはてなブログではこういうHTMLが生成される。

<dl>
<dt>https</dt>
<dd>//www.hatena.ne.jp/:はてな</dd>
</dl>

表示結果はこうなっちゃう。

https
//www.hatena.ne.jp/:はてな

この書き方に限ってはURLを「[~]」で囲む「http記法」にすると解消するのだが、http記法の前に文字列があるとちゃんと解釈されない。

現状うまく解釈されない書き方

:はてな<a href="http://www.hatena.ne.jp/">はてな</a>:はてなです
:http://www.hatena.ne.jp/:はてなです
:はてな[http://www.hatena.ne.jp/:title=はてな]:はてなです
:はてな[http://www.hatena.ne.jp/:bookmark]:はてなです
:はてな[http://www.hatena.ne.jp/:title=はてな:bookmark]:はてなです
:はてな[http://www.hatena.ne.jp/]:はてなです
:はてな [http://www.hatena.ne.jp/]:はてなです
:はてなブログ[id:hatenablog:detail]:はてなブログです

表示結果はこう。

はてなはてな
はてなです
http://www.hatena.ne.jp/
はてなです
はてなはてな
はてなです
はてな
はてなです
はてなはてな
はてなです
はてなhttp://www.hatena.ne.jp/
はてなです
はてな http://www.hatena.ne.jp/
はてなです
はてなブログid:hatenablog
はてなブログです

記事掲載時点ではこういうHTMLが生成されている。(はてなブログ タグ(はてなキーワード)へのリンクは省略)

<dl>
<dt>はてな</dt>
<dd>//www.hatena.ne.jp/">はてな</a>:はてなです</dd>
<dt>http</dt>
<dd>//www.hatena.ne.jp/:はてなです</dd>
<dt>はてな[http</dt>
<dd>//www.hatena.ne.jp/:title=はてな]:はてなです</dd>
<dt>はてな[http</dt>
<dd>//www.hatena.ne.jp/:bookmark]:はてなです</dd>
<dt>はてな[http</dt>
<dd>//www.hatena.ne.jp/:title=はてな:bookmark]:はてなです</dd>
<dt>はてな[http</dt>
<dd>//www.hatena.ne.jp/]:はてなです</dd>
<dt>はてな [http</dt>
<dd>//www.hatena.ne.jp/]:はてなです</dd>
<dt>はてなブログ[id</dt>
<dd>hatenablog:detail]:はてなブログです</dd>
</dl>

(追記:2020年4月3日現在、この書き方は正しく解釈されるようになっている。しかしそのことについてアナウンスはない)

正しく解釈される書き方

:<a href="http://www.hatena.ne.jp/">はてな</a>:はてなです
:[http://www.hatena.ne.jp/:title=はてな]:はてなです
:[http://www.hatena.ne.jp/:title=はてな]はてな:はてなです
:[http://www.hatena.ne.jp/:title=はてな] はてな:はてなです
:[http://www.hatena.ne.jp/:title=はてな:bookmark]:はてなです
:[http://www.hatena.ne.jp/:title=はてな:bookmark]はてな:はてなです
:[http://www.hatena.ne.jp/]:はてなです
:[http://www.hatena.ne.jp/:bookmark]:はてなです
:[id:hatenablog:detail]:はてなブログです
:[id:hatenablog:detail]はてなブログ:はてなブログです

表示結果はこう。

はてな
はてなです
はてな
はてなです
はてなはてな
はてなです
はてな はてな
はてなです
はてな
はてなです
はてなはてな
はてなです
http://www.hatena.ne.jp/
はてなです
はてなです
id:hatenablog
はてなブログです
id:hatenablogはてなブログ
はてなブログです

生成されるHTMLは以下。ちゃんとしている。

<dl>
<dt><a href="http://www.hatena.ne.jp/">はてな</a></dt>
<dd>はてなです</dd>
<dt><a href="http://www.hatena.ne.jp/">&#x306F;&#x3066;&#x306A;</a></dt>
<dd>はてなです</dd>
<dt><a href="http://www.hatena.ne.jp/">&#x306F;&#x3066;&#x306A;</a>はてな</dt>
<dd>はてなです</dd>
<dt><a href="http://www.hatena.ne.jp/">&#x306F;&#x3066;&#x306A;</a> はてな</dt>
<dd>はてなです</dd>
<dt><a href="http://www.hatena.ne.jp/">&#x306F;&#x3066;&#x306A;</a><a href="https://b.hatena.ne.jp/entry/http://www.hatena.ne.jp/" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/http://www.hatena.ne.jp/" alt="" class="http-bookmark" /></a></dt>
<dd>はてなです</dd>
<dt><a href="http://www.hatena.ne.jp/">&#x306F;&#x3066;&#x306A;</a><a href="https://b.hatena.ne.jp/entry/http://www.hatena.ne.jp/" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/http://www.hatena.ne.jp/" alt="" class="http-bookmark" /></a>はてな</dt>
<dd>はてなです</dd>
<dt><a href="http://www.hatena.ne.jp/">http://www.hatena.ne.jp/</a></dt>
<dd>はてなです</dd>
<dt><a href="https://b.hatena.ne.jp/entry/http://www.hatena.ne.jp/" class="http-bookmark"><img src="https://b.hatena.ne.jp/entry/image/http://www.hatena.ne.jp/" alt="" class="http-bookmark" /></a></dt>
<dd>はてなです</dd>
<dt><a href="http://blog.hatena.ne.jp/hatenablog/" class="hatena-id-icon"><img src="https://cdn.profile-image.st-hatena.com/users/hatenablog/profile.png" width="16" height="16" alt="" class="hatena-id-icon">id:hatenablog</a></dt>
<dd>はてなブログです</dd>
<dt><a href="http://blog.hatena.ne.jp/hatenablog/" class="hatena-id-icon"><img src="https://cdn.profile-image.st-hatena.com/users/hatenablog/profile.png" width="16" height="16" alt="" class="hatena-id-icon">id:hatenablog</a>はてなブログ</dt>
<dd>はてなブログです</dd>
</dl>

http記法の行内にコメント(<!--~-->)があると記法として認識されない

[http://www.hatena.ne.jp/:title=はてな]<!--コメント-->

↑こう書くと、こうなってほしい↓

<a href="http://www.hatena.ne.jp/">はてな</a>

しかしこういうHTMLが生成されてしまう。(はてなブログ タグ(はてなキーワード)へのリンクは省略)

[http://www.hatena.ne.jp/:title=はてな]

たとえばこう書く。

はてなブログ

[[はてなブログ]]

記事掲載時点で、下のようなHTMLが生成される。(改行を追加しています)

<p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0">はてなブログ</a></p>
<p><a href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0">はてなブログ</a></p>

タグ(キーワード)へのリンクに「class="keyword"」をつけてくれないので、「はてなブログ」のような普通のリンクの見栄えになってしまう。

対策としては、以下のようなCSSを「設定」-「デザイン」-「デザインCSS」に追加するとよい。

.entry-content a[href*="d.hatena.ne.jp/keyword"]{
    color: inherit!important; /*タグ(キーワード)へのリンクの文字色を地の文と同じにする*/
    border-bottom: 1px solid #dedede; /*キーワードリンクの見た目をカスタマイズしているならそれに合わせる*/
}

これは「<a href="http://d.hatena.ne.jp/keyword/~">~</a>」というHTMLを見つけて、キーワードと同じ見た目にするというCSSである。でもそういうバッドノウハウがいらなくなってほしい。

はてなブログ タグについては以下で書いた。


http記法や引用記法の「:title=」に「[」や「]」を使えない

[http://www.hatena.ne.jp/:title=[hatena]はてな]

↑こう書いたら、こうなってほしい↓

<a href="http://www.hatena.ne.jp/">[hatena]はてな</a>

しかしこうなってしまう。

[http://www.hatena.ne.jp/:title=[hatena]はてな]

記事掲載時点で、このようなHTMLが生成される。

[<a href="http://www.hatena.ne.jp/:title=">http://www.hatena.ne.jp/:title=</a>[hatena];はてな]

「[」は「&#91;」、「]」は「&#93;」に置き換えればよい。

[http://www.hatena.ne.jp/:title=&#91;hatena&#93;はてな]

これで以下のようになる。

[hatena]はてな

しかし、そうしなくてもうまいこと処理してほしい。

「[」~「]」で囲まないダイアリー記法がid記法として解釈されることがある

ダイアリー記法ははてなダイアリーの記事へのリンクを生成する記法で、「d:id:Imamura:20030217:p1」のように書く。これが「d:id:Imamura:20030217:p1」ではなく「d:id:Imamura:20030217:p1」となってしまうことがある。「id:Imamura」はidへリンクする「id記法」である。

「[」~「]」で囲んで「[d:id:Imamura:20030217:p1]」と書くと問題は起きない。でも「[」~「]」で囲まなくてもちゃんとダイアリー記法として解釈されることもあり、条件がわからなくてモヤモヤする。

今まで多くのケースを見てきて、idにアンダーバーを含むときと、日付の次が「:」ではなく「#」のときが怪しいのだが確証が持てない。

まったく同じダイアリー記法を書いていても展開結果が異なる例も見つかった。

f:id:Imamura:20191004112054p:plain

これは http://ima.hatenablog.jp/entry/20060310/umigame3 のキャプチャである(今は「[」~「]」で囲んで修正済み)。一度書かれたダイアリー記法をくり返すとid記法として解釈されるのだろうか? 謎である。

asin記法の「:detail」が展開されないことがある

(この項は2020年2月7日追記)

Amazonの商品を埋め込みで紹介できるのが「asin記法」の「:detail」オプションである。たとえば「asin:9784295004837:detail」と書くと下のように展開される。

サルでもわかるGit入門

サルでもわかるGit入門

この「9784295004837」の部分は書籍コードの「ISBN」と共通で、実際の書籍を見てみるとハイフンつきで書かれていることがある。上の場合「978-4-295-004837」といった具合である。

はてなダイアリーでは、asin記法にこのハイフンつきISBNを書いてもきちんと展開されたのだが、はてなブログでは「asin:978-4-295-004837:detail」は展開されず、また正しいリンクにもならない。

下は「asin:978-4-295-004837:detail」と書いたものである。クリックするとAmazonに「何かお探しですか?申し訳ございません。入力されたウェブアドレスは当社サイトの有効なページではありません。」と言われてしまう。(後日修正されて、きちんと展開されるようになったらいいな)

asin:978-4-295-004837:detail

ハイフンつきのasin記法を書いたはてなダイアリーの記事をはてなブログへインポートした場合、きちんと展開されている。

この検索結果で現在この記事の次に出てくる「『3D Printing Handbook』見本出来 - ただいま村」では「ISBN:978-4-87311-632-7:detail」と書いていて、問題なく展開されている。

「拡張id記法」を解釈してほしい

これは不具合ではなく仕様であるが、いい機会なので要望させてほしい。

はてなダイアリーにダイアリー記法が実装される以前、「d:id:Imamura:20030217:p1」に相当するリンク記法は「id:Imamura:20030217:p1」というid記法が担っていた。これははてなダイアリー(とはてなグループ)だけで使える独自の「拡張id記法」ともいうべき書き方で、id記法は本来「id:Imamura」という書き方しか解釈しない。

「歴史的な経緯で、はてなダイアリー(やはてなグループ)では『id:Imamura:20030217:p1』という書き方もダイアリー記法として解釈されていた」ということだ。

はてなブログはこの「拡張id記法」をサポートしていないので、「id:Imamura:20030217:p1」と書いても「id:Imamura:20030217:p1」にならず、「id:Imamura:20030217:p1」となってしまう。

これは仕様としては正しい。しかしはてなダイアリーからインポートした記事でこうなっていると、本来想定されたURLへのリンクにならない。つまり大量のリンク切れが発生しているのと変わらない。

この下に紹介した記事の通りにすれば、「拡張id記法」で書かれた記事をダイアリー記法へ一括置換することはできる。一方で物故者のダイアリーなど、はてなブログへ自動移行したものの修正を期待できないものもある。そういった記事でも目的の記事へきちんとリンクするよう、「id:Imamura:20030217:p1」や「id:Imamura:20030217#p1」といった書き方を「[d:id:Imamura:20030217:p1]」と書いたものとして扱うようにしてほしい。

(あるいは拡張id記法をダイアリー記法として扱うGreasemonkeyを書いて、自分が閲覧するときに限ってちゃんとしたリンクになるようにするとか…また勉強しないと)

はてなダイアリーには15年にわたる膨大な記事の蓄積があった。それをはてなブログへインポートできるようにして資産を生かすことにしたのははてなの判断である。であれば、はてなブログは仕様が違うのだからと切り捨てるのではなく、責任を持ってきちんとリンクするようにしてほしい。「10年後もユーザーの皆さんとともにあるサービスを目指す」(2019年“マイ推し記事”7選! はてなブログ編集部スタッフの心に残ったのはこれだ - 週刊はてなブログ)とはそういうことではないだろうか。

はてなブログライターで一括置換できます

ここまで紹介したはてな記法は決して特殊な書き方ではなく、はてなダイアリーではきちんと解釈してくれていた。はてなダイアリーからはてなブログへインポートした記事で、意図しない表示結果になっていることが多い。

すでにはてなブログへ投稿した記事やはてなダイアリーからインポートした記事を1つのテキストファイルにまとめ、テキストエディタで一括置換して登録し直すことができる。方法は以下で解説しています。


冒頭にも書いたように、これらの不具合はすべて運営へ報告済みである。しかし概して反応は鈍い。また「修正しました」と連絡があっても修正もれがあったりする。この記事が参考になるかはわからないが、ぜひきちんと修正してほしい。