職業プログラマの休日出勤

職業プログラマによる日曜自宅プログラミングや思考実験の成果たち。リアル休日出勤が発生すると更新が滞りがちになる。記事の内容は個人の意見であり、所属している(いた)組織の意見ではない。

人生の空白 a.k.a. #シェル芸 勉強会 参加記

昨日、2020年4月25日は「jus共催 第47回引きこもりシェル芸勉強会」でした。
筆者の個人的な事情によりここ数回ほど参加できない回が続いてきましたが、ようやく参加することができました。
usptomo.doorkeeper.jp

さて、今回の問題の中には、空白文字に関するものがいくつかありました。
回答は筆者のもの*1よりも他のシェル芸人の皆様のものを見て頂いた方が良いのでここでは掲載しませんが、「この人物の人生は空白」と評されるほどに空白文字が大好きな筆者は、シェル芸のワンライナーを掲載する代わりに、問題中に登場した特殊な空白文字たちについて解説をしておきたいと思います。


問題

ファイルは、こちらです。
github.com

この勉強会の動画の2時間21分あたりからが、この問題の部分です。
youtu.be

登場した空白文字

文字の Unicode コードポイントとかを教えてくれる拙作のMacアプリ「CharViewer」で調べてみたところ、次のような空白文字が入っているようでした。

U+0020 SPACE

いわゆる「半角スペース」です。標準的な空白ですね。

幅が異なるだけの空白文字たち
  • U+2002 EN SPACE
  • U+2003 EM SPACE
  • U+2004 THREE-PER-EM SPACE
  • U+2005 FOUR-PER-EM SPACE

今回の問題に出題された文字の中で、これらは機能的な意味は U+0020 半角スペースと同じです。しかし、幅が違います。
これらの幅がどれほどであるのか?を知るためには、まず、印刷用語である emen を理解しなければなりません。HTML/CSSの世界でも同じ用語を使うので馴染みのある読者も多いかもしれませんが、軽く触れておきます。
emはアルファベット大文字のMのことで、enも同様に大文字のNのことです。日常生活の大部分を等幅フォントに依存している我々にとっては「NもMも同じ幅じゃん」という認識が一般的だと思いますが、プロポーショナルフォントの世界においては異なるものです。Mは全てのアルファベット大文字の中で最も大きな文字になり、これが単位emとして大きさの基準になります。enNの幅なのですが、実装上はemの半分の幅になります。ちなみに「1emは何mmなのか?」という問いに答えるには、使用するフォントやフォントサイズが与えられる必要があります。

さて、emenの意味がわかると、これらの文字の幅の意味がわかると思います。「THREE-PER-EM」はemの3分の1、という意味です。
実装上は、U+2003 EM SPACE は後述する「全角スペース」とほぼ同じ幅になることが多いようではありますが…

U+2007 FIGURE SPACE

これは、そのフォントにおける数字(0から9までのやつ)の文字幅と同じ分だけ空白があります。日本語文化圏では電話番号はハイフンで区切りますが、欧米では空白で区切ることが多いです(少なくとも筆者の観測範囲では)。このように数字ばかり並んでいるところにこの空白を使うと、綺麗に表示されることになります。また、この空白は後述のNBSPと同様に、折り返しを抑止する機能*2があります。

U+2008 PUNCTUATION SPACE

前述の Figure Space に似ていますが、これはピリオド . と同じ幅の空白です。どのようなユースケースがあるのか?は筆者もよく知らないところでして…

U+200A HAIR SPACE

髪の毛のように細い空白、です。

ここまで紹介してきた文字たちのうち U+0020 いわゆる半角スペース以外は、活版印刷の世界との互換性のために用意された文字です。画面上の表現だけで事足りてしまうことの多い現代においてはこれらのお世話になることはもうほとんど無いかもしれませんが、知識として知っておくと人生は空白……ではなくて豊かになることでしょう。

U+200B ZERO WIDTH SPACE

これはソフトウェア方面の技術者の中でも馴染みの深い人も多いのではないでしょうか。空白と言いつつも1ミリも間を空けない空白、これが U+200B ゼロ幅スペース です。
主に、画面をロックしないまま離席してしまった素行不良な同僚プログラマを戒める際に、編集中のソースコードの途中にゼロ幅スペースを仕込んでコンパイルエラーや動作不良を起こして悩ませる、という目的で使われます。というのは冗談で(良い子は真似しないでね😉)、これはとても長い単語(ドイツ語とかでよく見られるやつですね)の途中で「ここでは折り返しして改行してもいいんだよ!」という意思表示をするために使われます。

U+3000 IDEOGRAPHIC SPACE

いわゆる「全角スペース」です。日本語の仮名や漢字、そして近年だと絵文字とかとほぼ同じサイズで描画されることの多い空白文字です。我々、日本語話者にとっては U+0020 に次いでとても馴染みの深い空白だと言えるでしょう。
この「ideograph」という言葉は「表意文字」という意味で、CJK*3文化圏で使われる漢字が表意文字であることから、この名が付けられています(これはかなり雑な説明なので、Wikipediaの記事とか見るのも大変良いです😃)。空白文字以外について語るのは本望ではないのですが、例えば日本語の読点「、」U+3001は「IDEOGRAPHIC COMMA」という名前が、日本語の句点「。」U+3002は「IDEOGRAPHIC PERIOD」という名前が付けられています。まるでCJKの文字が唯一の表意文字だと言わんばかりの名付けですが、何か歴史的経緯とかあるのかもしれません。

他にはどんな空白があるの?

今回の問題のファイルに含まれていない空白文字には、例えば以下のようなものがあります。

U+2001 EM QUAD

読んで下さい(雑ですみませんw)
en.wiktionary.org

U+00A0 NO-BREAK SPACE

No Break SPace, 略してNBSPとも呼ばれます。non-breaking space ともいいます。これは、CSSがあまり発達していなかった頃にHTMLに関わる作業なり仕事なりをしていた皆さんにはとても馴染みの深い空白かもしれません。HTMLで通常の半角スペース U+0020 を連続して書いても、残念ながらWebブラウザがそれをレンダリングする際には、これらはひとまとめに U+0020 1文字分の空白しか空けてくれません。任意の個数の U+0020 幅の空白を表現するためにはHTMLに   と書いてNBSPを召喚すれば良いのです。ただ、これは本来のNBSPの使い方ではありません。本来の使い方はWikipediaの記事にもあるように 100 km のように途中で word-wrap して折り返されたら困るようなところで折り返しを防止する目的で使うものです。
ちなみに、英語版のWikipediaの記事では

f:id:t_motooka:20200426004612p:plain
英語版Wikipediaでの NO-BREAK SPACE 解説の一部
このように a non-breaking space (" ") と書いてあり、HTMLソース上も   いかにも「コピーすればNBSPが得られる」ように見えますが、Webブラウザの実装によっては(筆者の手元のMacWebブラウザでは全て)、これをコピーしても得られるのは NBSP ではなくて U+0020 の普通の半角スペースです。これはWebに関わる皆さん向けの小ネタです。

あと、筆者は、働き始めて2年目の頃に、面倒を見ていた情報システムにおけるNBSPのハンドリングに不具合があったことによってシステム障害が発生し、一度終電を逃しました。U+00A0 のUTF-8表記 c2 a0 のバイト列も、筆者の瞼から消えることは無いでしょう。こうした影響により NO-BREAK SPACE は筆者の人生から切り離すことができないものとなったのでした。

参考資料

さいごに

勉強会を執り行ってくれた先生や、登壇されていた方、そして答案を投げ合った参加者の皆さんに感謝です🙏

*1:そもそもほとんど解けていない

*2:Wikipedia英語版を参照 https://en.wikipedia.org/wiki/Figure_space

*3:Chineese / Japanese / Korean