2026-06-04

株式会社 kubell を退職しました

はじめに

株式会社 kubell を 2026-05-29 (金) に退職しました。 2014-04-01 (火) に入社したので、12 年近く働いたことになります。

kubell は、ビジネスチャット・サービス Chatwork を開発・運営する会社です。 入社当時は ChatWork 株式会社という社名で、2018 年 11 月に Chatwork 株式会社 (Work の W の文字が小文字に)、2024 年 7 月に株式会社 kubell に社名を変更しました。 私はそこで iOS アプリエンジニアとして働いていました。

kubell 在籍中、印象深かったイベントがいくつもあります。 いくつかをピックアップしてふりかえることで、退職エントリーとします。 なお、本エントリーで触れているコードネームや内部事情については、会社ブログや YouTube で既に言及されているものばかりで、社外秘情報はありません。

2014-04 入社

2014-02-14 (金) は体験入社二日目。 技術部メンバーの前でプレゼンが予定されていました。 ところがその日は東京大雪。 まさかのリモート・プレゼン。

手元にあるのは小さな個人所有の MacBook が一台。 外付けディスプレイはなし。 画面共有を開始すると、ビデオ通話側の画面を隠さないとスペースが確保できません。 画面先のエンジニアの反応が全く分からない中、プレゼンを行い、運良く合格をもらうことができました。

入社初日の 2014-04-01 はなんとオフィス移転日。 池尻オフィスから合羽橋オフィスへの引越作業を、右も左も分からないまま手伝いました。 というわけで池尻オフィスで働いた (?) のはたった一日。 二日目からマシン設定等を始めて、私の新天地での仕事が始まりました。

2014-04〜2014-06 Eiger 開発

2014 年当時、Chatwork iOS アプリは Titanium SDK で実装されていました。 Titanium は JavaScript で iOS/Android のクロスプラットフォーム・アプリを作れる SDK です。

この手のクロスプラットフォーム開発用 SDK は、シンプルな画面を作るだけなら高速な開発成果が得られてとても良いものですが、iOS 特有の機能を使おうとしたり、少し手のこんだ仕様を実現しようとしたり、デバッグを行うとすると躓くポイントがたくさんあって、逆に開発スピードが遅くなってしまうことがありました。

Chatwork iOS アプリもその問題に直面し、Objective-C によるネイティブ実装に舵を切ります。 開発コードネームは Eiger。 アルプスの三大北壁の一つ、アイガー北壁を持つ山 Eiger です。 「難易度の高いアイガー (北壁) を攻略しよう」。 そんな意気も込めてのコードネーム設定だったと聞きます。

私はコードネームが決まって、開発が始まる直前にモバイルチームにジョインしました。

Chatwork iOS アプリの開発経緯などは、技術イベントで軽く触れられているので興味があれば見てみてください。

2014-05 シリコンバレー研修

iOS アプリ刷新プロジェクト推進の裏では、サーバーに刷新プロジェクトも動いていました。 イケイケです。 そんなことも追い風になったのでしょうか? 社員にシリコンバレーの雰囲気を知ってもらいたい、と言う話が出てシリコンバレー研修の予定が組まれました。

とは言っても社員全員が一勢に行くわけにもいかず。 いくつかのグループに分かれて向かうことになりました。 最初は○○チーム、3 番目は□□チームという具合です。

私たちモバイル開発チームは 2 番目に出発。 チームメンバーは私を含めて 4 人でした。

当時の ChatWork 社はアメリカに支社を持っていて、社長の山本敏行氏はシリコンバレー・オフィスを拠点にしていました。 時々日本には帰国していたものの、彼の主戦場はアメリカでした。 なので、私にとっては初めて社長に会う旅でもありました。

シリコンバレー研修。 一緒に行ったメンバー、ChatWork US 支社で会ったメンバー。 全員、もう辞めてしまいました。 ちょっと淋しいです。

2015-08〜2015-12 Scala を触る

先にも少し触れましたが、Eiger 開発と並んでサーバーの刷新プロジェクトも進んでいました。 PHP で書かれているサーバーのソースコードを、Scala で書き直そうというビッグ・プロジェクトです。 Eiger もこの Scala 版新サーバーで動くことを前提に実装が進みました。

Scala 選定に関しては、私の入社前に決まっていました。 開発合宿をやって決めたそうですよ。

そんな Scala サーバーですが、どうやら開発が遅延気味。 相談が持ちかけられたのは、たしか 2015 年 8 月の後半だったように思います。 上長がミーティングをしたい、と言ってきました。

しかし、オフィスのミーティングルームは全て埋まっています。 上長は大阪オフィス在籍で、なにかの用事で東京は合羽橋オフィスに来ていました。 つまり、大阪に戻る新幹線の時間があります。 悠長に会議室が空くまで待つわけにもいきません。

仕方がないので、近くの喫茶店で話すことになりました。 合羽橋に来たことがある方ならご存じと思いますが、合羽橋には喫茶店がほとんどありません。 そんな私たちの光明が喫茶店・合羽橋珈琲 (2016 年 8 月閉店)。 テーブルとテーブルの間が少し離れているので、ちょっとした小話程度なら良い感じにできるお店です。 ところが、その日に限ってお店は満席。 上長の新幹線の時間が迫ってきます。

8 月の日差しの中、トボトボ歩く二人。

道の先に見える自動販売機。

二人で缶コーヒーを買い、道の縁石に座って…

「サーバーが遅れてるんだよね。プッシュ通知回りの実装でヘルプに行ってもらえる?」

「モバイルチームで Scala を新しく学んでサーバーのコードを書けそうな人間、ぼくくらいしかいないですねぇ。行きます。」

それで Scala の最低限の勉強をして、サーバーのコードを書くことになりました。 あ、でも、もう 10 年近く前のことなので Scala の書き方はきれいさっぱり忘れてしまいましたね。

2016-01 サーバープロジェクト・キャンセル

サーバーの完成も近づいた 2016 年 1 月。 初めての iOS アプリとサーバーの疎通確認が行われました。

そして、上手くいかなかったんですね。

いろいろと手を尽くしたと思うのですが、無念のサーバープロジェクト・キャンセルとなりました。 サーバーのあれこれ顛末については、Podcast で放送されています。 もしお時間があれば、聞いてみてください。

サーバーキャンセル。

つまり、私が半年近く関わった Scala のコードも土に帰りました。

ショック。

開発を続けていればそういうこともあります。 一応、仕様とかフローチャート図とかは PHP の開発チームに引き継がれて実装が行われました。

2016-06 Eiger リリース

サーバープロジェクトはキャンセルされましたが、Eiger プロジェクトは止まりませんでした (ホッ)。

4 月末にはプッシュ通知回りの最終テストを実施。 バグが見つかって、ゴールデンウィーク返上でバグ修正。

iOS アプリ側でバグがないことを確認したので、PHP のソースコードを確認。 2 つのバグが相補的に不具合を引き起こしていたことを突きとめた時には、PHP エンジニアと一緒になって喜んだものです。

これが最後の大きなバグでした。 最終結合テストを経て 2016 年 6 月、ネイティブ版 iOS アプリがリリースされたのでした。

2016-12 メッセージID 枯渇問題

2016 年 12 月 29 日。 真夜中に 7 時間かけてサーバーのメンテナンスが行れました。

32 bit だったメッセージ ID の型を 64 bit に拡張するためのメンテナンスです。 このプロジェクトはサーバーチームが半年以上の入念な準備を整えて行われたものです。

なので、iOS エンジニアである私はほとんど関わっていません。 ただ、メンテナンス終了後の動作確認。 これは各クライアントチームが行う方が良い、ということで最後だけ参加することになったのでした。

東京在住のエンジニアで集まれる人は全員、当時の合羽橋オフィスに集合。 午前 0 時からの経過を見守り、少しトラブルはあったものの、最終的には無事リリース完了。 各クライアントチームが検証を行い、全てのテストをパスして、メンテナンスは終了となりました。

真夜中にオフィスに集まって、サーバーチーム・クライアントチームが混合で作業をした経験は、12 年の在籍期間中、後にも先にもこの一回限りです。 それだけに、とても印象深く記憶に残っています。

2017-11〜2018-05 Mauna Loa 開発

Eiger リリースでフルネイティブ化した Chatwork の iOS アプリですが、保守状況は必ずしも順風満帆というわけには行きませんでした。 その要因の一つは、サーバープロジェクト・キャンセルによる API 変更が上げられるかと思います。 Scala で用意された新 API を使う予定だったのに、急遽 PHP サーバーの旧 API を使うことになったため、Eiger 開発の終盤では腐敗防止層を導入して API の変換を行う仕組みを導入しました。 この腐敗防止層のおかげで Eiger リリースは最小の変更期間でリリースができたわけですが、その代わり新規開発への技術的負債になってしまいました。

折しも Swift 言語が iOS 業界でもメジャーになっていた頃。

Swift 化とリアーキテクチャーを行うプロジェクトが始まりました。 それが Mauna Loa。 Mauna Loa はハワイにある山の名前です。

Chatwork の iOS アプリには「山の名前」のコードネームを付ける、という伝統がありました。 ルールは一つ。 新しいコードネームには、より高い山の名前を付けること。

チームメンバーで Eiger より高い山をリストアップし、あれでもないこれでもないと話し合いをしました。 その中で持った共通認識が一つ。 Eiger より登りやすい山を選ぼう。

Eiger 北壁は難度が高すぎました。 Eiger の開発はその難度の高さから、iOS エンジニアの心を折っていたのです。

そこで選んだのが Eiger (標高 3,970 m) より 199 m 高いハワイの Mauna Loa (標高 4,169 m) でした。 画像検索ができるようなら是非 Mauna Loa を見て欲しいのですが、Eiger より高い山だというのになだらかな山だと思いませんか? これなら登れるよね?! という期待を込めて、コードネームが決定したのでした。

後日、Android エンジニアの方が Mauna Loa のアイコンを作って下さったのですが、なぜか Mauna Loa から溶岩が流れていました。 さすがに噴火中の Mauna Loa には登れませんよ? と思ったのはここだけの秘密です。

2018-11〜2021-04 AST プロジェクト

Chatwork の iOS アプリ開発プロジェクトの中で、「iOS 担当が私一人」なプロジェクトのうち「最長」の開発期間だったのが AST プロジェクトです。 2018 年末からコードを書き始めて、途中準備待ちとか別プロジェクトへの緊急ヘルプとかで開発が休止することもあったのですが、約 18 か月開発に費やしリリースにこぎつけました。

内容は Chatwork 内で使われる独自記法 (Chatwork 記法) を iOS・Android・Web で統一仕様にしようという試みです。

まず Chatwork 記法のパーサーを赤津氏が開発。

そして、パーサーが出力する AST (抽象構文木) に対して、タイムライン表示用の描画・メッセージ入力欄での編集用描画・コピー & ペーストの対応を私が行いました。 表示用の描画だけでコーディングに半年かかったのですが、その内 info トークンの描画実装についてはブログ記事に起こしています。

このプロジェクトを進めるに当たって、Chatwork 記法描画・編集・コピペの設計をほぼ一からやり直しました。

開発中、私は自分に一つ縛りを設けました。 それは「旧設計での描画」と「新設計での描画」の違いにユーザーがなるべく気づかないようにする、ということです。

Chatwork 記法の見た目の仕様を変えるプロジェクトではないので、ユーザーに気づかれないことが好ましい。 そんなちょっと変わったプロジェクトでした。

もちろんそれは表向きのことです。 細かな所に目を向ければ、行間が大きかったり小さかったりでガタガタした見た目が直っていたり、引用線が無駄に長かったのが短くなっていたり、絵文字の位置調整が正確になっていたり、長〜いメッセージへのケアが入っていたり、メッセージの範囲選択にあった諸々のバグが修正されていたり。 山のような改善と不具合修正が入っています。

言い換えると、「何が変わったのか分からないけど、何か使いやすくなった」と言ってもらえることを目指して開発しました。

リリース後、全くバズりませんでした。 狙い通りと言えば狙い通りなのですが、それはそれでモヤっとするのは私の器の小ささでしょうか?

2020〜 コロナとリモートワーク

2020 年にコロナが流行して、会社はフルリモートワークに舵を切りました。

この頃、kubell の社員数は 100 人を越えるくらい。 入社時点で 30 人程度しかいなかったこ とを考えると、社員数が急拡大していました。

採用するエンジニア層も即戦力の中途採用オンリーから、ジュニア・エンジニア、第二新卒、そして新卒受入れへと幅が広がりました。

結果、新入社員のサポート的な仕事も増えました。 と言ってもリモートワークが推進される時分です。 机を並べてサポートするわけにも行きません。

この頃、個人的な試みで成功したなぁと思ったのが、「Google Meet 繋ぎっぱなし」作戦です。

  1. 私が特定の Google Meet に入りっぱなしにしておく (マイクとカメラはオフ)
  2. 新入社員が質問なり相談なりしたくなったら、その Meet に入って声をかける
  3. 声が聞こえたら、私の方でマイクとカメラをオンにしてお話をする

こんなシンプルな仕組みです。

質問・相談があればチャットで投げれば良い。 文章コミュニケーションで足りなければ、改めて Google Meet で話せば十分。 という反論も聞くのですが、新入社員にはその最初のチャットを書くハードルが高い? 質問・相談内容が明確なら良いのですが、新入社員だと、何が分からないのかが分からない状態だったりもするようで。

オフライン・コミュニケーションだと隣にいる先輩の手が空いていそうなら、すいませんと声をかけるところでしょう。 その気安さがリモートワークだと作りづらい。

「Google Meet 繋ぎっぱなし」作戦は、リモートワークに少しだけオフライン・コミュニケーションの気楽さ・気安さを取り込めた良い試みだったと思っています。

この試みは、バーチャルオフィス・サービスが会社に導入されたことで、そちらで続けることになりました。

2026-05 退職へ

色々思うところがあって、2026 年 5 月 29 日付をもって株式会社 kubell を退職をしました。

写真は最終出社日に撮影したオフィスビルです。

転職先はまだ決まっていません。 iOS エンジニアとして働き続けたいと思っています。 もし私に興味のある企業さんがいらっしゃいましたら @at_aka に DM 頂ければ幸いです。

2026-03-10

オーディオ・オフ会 なお&トラさん邸訪問 (第 10 回)

10 回目のオーディオ・オフ会

2026-01-17 (土)、 なお&トラさん さん邸でのオーディオ・オフ会に参加しました。 前回、オーディオ・オフ会が 2015-04-04 (土) ですから、10 年以上ぶりの訪問となります。

Apple Music のプレイリスト

今回のオフ会で聴いた曲を見つけたものだけですが、Apple Music のプレイリストにまとめてみました。もし良ければ聴いてみてください。

経緯

お互い忙しかったのかもしれません。連絡を取る回数がいつしか減って、今、連絡しても大丈夫かしらんと変な遠慮が入り、気がつけば 10 年の月日が経っていました。

再会のきっかけは年賀状でした。 実は毎年、年賀状だけは出し続けていました。 2025 年の 1 月に「年賀状ありがとう」の返信を頂いて、また会いたいですね、というメッセージのやり取りをしました。 しかし、2025 年の 1 月は大きな風邪で寝込んでしまい、そのままお流れに。。。

そして、2026 年。 今年も去年末から 1 月にかけて大きな風邪を引き、実家で 1 週間近く寝込みました。 なんとか治って、実家から東京に戻ろうとしたところに、なお&トラさんから電話が一本。 あっという間にオーディオ・オフ会の日取りが決まりました。

サブシステム

最初にサブシステムで LP を 9 枚、聴かせてもらいました。 サブシステムはパラダイムのブックシェルフ・スピーカー Persona B を主軸にした構成です。

なお&トラさんと言えば、絵のような、写真のようなオーディオ表現を得意とされています。 裏を返せば、楽器の響きをメインに出さない音作りを好まれる印象でした。

サブシステムは過去の方向性を踏襲していて、スピーカーとスピーカーの間に音場が作られ、その空間で全ての音が明瞭に鳴っていました。 意外に思ったのは、ピアノの音がとても良く響くこと。 これは過去の方向性に対して大きな変化だと思いました。

ピアノの響きは中域がやや厚く、フワッと音が広がる空気感が出ています。 ピアノという楽器が弦から音を取り出し、響板をふるわせ、フレームを鳴らして響きが生まれる。 そんな様子を目の当たりにするような感覚です。 加えて、ピアノの低音は沈み込むよう。 すごく深く音が落ちていくように感じました。

少し気になったのは、左右のバランス。 右の響きが左に比べて、やや強いように思いました。

聴かせて頂いた LP から、いくつかピックアップして感想を書いてみます。

まずは、アシュケナージが弾くベートーヴェンのピアノソナタ第 23 番「熱情」。 アシュケナージはどちらかと言うとベートーヴェンを淡泊に弾く、という私の印象? 思い込み? が覆りました。 音の一つ一つが明確な意志を持って、なんと丁寧に扱われていることか! ドイツ的な音楽づくりではないのですが、ベートーヴェンの音楽づくりを真摯に取り組んでいるのだと知りました。 Decca 録音というのもあるかもしれませんが、鍵盤のタッチと底つきまで見えるようでした。

Yuko Mabuchi Trio のアルバム「Yuko Mabuchi Trio」から What is This Thing Called Love?。 ジャズのアルバムです。 ハイハットの空気感は弱め。 ドラムのアタック感がいたって自然。 そしてピアノが良い。 バランスとしてピアノを主役に立てるシステムだと感じました。

カティア・ブニアティシヴィリのアルバム「ラビリンス」は、私も愛聴の一枚。 映画「ワンス・アポン・ア・タイム・イン・アメリカ」からエンニオ・モリコーネ作曲の「デボラのテーマ」。 とても深い低音が味わえる一品。たまりません。

同アルバムから、フランソワ・クープランの「神秘的な障壁」も聴きました。 クープランはバロック時代の作曲家。 ピアノのなかった時代。 クラヴサンという楽器のために作曲された小品です。 CD を探すとチェンバロやクラヴサンで演奏した録音が見つかります。 ブニアティシヴィリはこの曲をピアノで演奏しました。 舟に揺られて行っては戻り行っては戻りを繰り返すような音楽が、ピアノでロマンティックに演奏されていて「ラビリンス」の中でもお気に入りの一曲です。 自分のオーディオ・システムで聴いていた時は気がつかなかったのですが、ブニアティシヴィリは強弱を大きくつけているのですね。 ニュアンスが掴めると、より音楽が楽しくなり、更にこの演奏が好きになりました。

ラモーのクラヴサン曲集から La Dauphine。 演奏は Albert Fuller。 チェンバロの演奏です。 チェンバロというと高音が耳にきつく低音が出ない、と思っていたのですが、全ての音が明瞭に聞こえるのにキツく感じなくて、低音もしっかりと鳴っていてとても楽しく音楽を味わいました。

メインシステム

メインシステムでは、私が持参した CD を 4 枚、なお&トラさんおすすめの CD を 5 枚、聴かせてもらいました。 メインシステムで使っているスピーカーは三菱のダイヤトーン 2S-3003 に改造を加えたもの。

サブシステムと比べると圧倒的に音場が広い! 目の前に音楽が広がります。 サブシステムで顕著だったピアノの「楽器としての響き」は抑えられ、音楽の描写力がより精緻です。 音楽の描写をメインに据えるオーディオ・マニアとしての芯は変わらないのだなぁと思いつつも、10 年前の記憶と比べてみると、少し響きが加わり、写真のような少し人工的な描写から自然な描写へと進化したように感じました。

ピアノの響きだけを取るならサブシステムの方が好きなのですが、全体的にはメインシステムの方が好み。 なぜ? と問われると答えづらいのですが、音楽を聴いていて楽しい。 おそらく音場の広さ・描写力の高さと響きのバランスの取り方が私の好みに合っているのではないかと思います。

メインシステムで聴いた CD も、感想を少しだけ書いておきます。

ベートーヴェン作曲「コリオラン序曲」、ブルーノ・ワルター指揮コロンビア交響楽団。 オーディオ視聴における私のリファレンス CD です。 管弦楽曲ということもありますが、音場の広さに圧倒されます。 スピーカーの少し先くらいまでしか音が広がらなかったサブシステムと比べて、こちらは部屋の端から端までステージが広がりました。 ホールトーンの響きも素晴らしい。

ベートーヴェンのピアノソナタ第 23 番「熱情」をギーゼキングの EMI 録音から。 ギーゼキングは私が大好きなピアニストです。 たまたま EMI のベートーヴェン、ピアノソナタ選集を持ってきていたので、アシュケナージに対抗してギーゼキングの「熱情」を聴かせてもらいました。 ギーゼキングはピアニッシモから大音量のフォルテッシモまで、ダイナミックレンジの広い演奏をしていたそうですが、EMI の「熱情」はその広いダイナミックレンジを捉えることに成功していません。 音量が大きくなったところで無惨なほどに音が割れてしまいます。 私のシステムではそこまで気にならなかったのですが、写実的に描くオーディオシステムでは録音の粗が逆に目立ってしまいました。 割れる音の中から、ギーゼキングはこんな音を鳴らしたかったんだろうなぁ、という意志は良く伝わってきて、録音が残念なことに涙する体験となりました。 無念です。

マイケル・ジャクソンの「ヒール・ザ・ワールド」。 曲の冒頭。 どこかの公園で録音したのでしょうか? 子供たちが後ろで遊び回っている様子が伺え、少女の語りが入ります。 音がね。輝いているようです。 感動して涙が出そうになりました。 マイケルの音作りの妥協のなさを堪能しました。

Solas のライブアルバム「Reunion」から Ni Na La。 Ni Na La は Solas のファーストアルバム「Solas」の 1 曲目に収録されている曲です。 アイリッシュ・トラッド曲なのかな? ライブアルバム「Reunion」は、その Solas の 10 周年記念ライブを録音したもの。 10 年の活動の中でグループから離れたメンバーもいて、そういう人達がこのライブで再び姿を見せているそうです。 録音はファーストアルバムの方が良いですが、ライブ盤には会場の熱気が記録されていて聴いているとこちらまで心がウキウキしてきます。 家のシステムではライブ会場の音が少し団子状になって聴こえます。 しかし、こちらのメインシステムでは音と音がしっかり分離されていて、ライブ会場にいるような感覚になりました。 ただ、ギーゼキングの「熱情」でも書いたように録音の粗を出してしまうのか、音が少しキツく感じることがありました。

ラストはイーグルスのライブアルバム「ヘル・フリーゼス・オーバー」からホテル・カリフォルニアを聴かせてもらいました。 目の前に観衆がいて、奥のステージに演者であるイーグルスがいる。 そして、観衆は観衆向けのマイクで録音されていて、イーグルスの演奏は全く別のマイクで録音している。 そういう音作りが目に見えて驚きました。 そんな気づきもイントロが終わるころには消えてしまい、音楽に合わせて体を揺らしていました。

あとがき

今回、ブログ環境を作り直したり、Apple Music のプレイリストを作ってみたりと、ブログの記事を書き始めるまでに随分時間がかかりました。 そして、ブログの記事を書き始めてからも、筆が進まず書き終えるまでにまた 3 週間近くかけてしまいました。 なんとか形になってホッとしています。

10 年ぶりということで自分のオーディオ勘が鈍っているのではないかと心配しましたが、いざオーディオ機器を前にすると 10 年前の印象を思い出すことができて驚きました。 これはオーディオが好きということも一因だと思いますが、インプットしたものを「ブログという形でアウトプットする」ことで記憶が定着したのではないかな? なんて思っています。 前回の記事でも月一くらいでブログの更新をしたいと書きましたが、続けられればと思います。

ref

2026-02-16

ブログ記事を Markdown で作成する

今までこのブログは HTML を直接書いていました。しかし、最近は Markdown でテキストを書くことが増え、HTML を直書きすることが億劫に感じます。そこで、Markdown から HTML に変換する仕組みに変えてみました。

あわせて、本ブログの文体も「ですます調」に切り替えてみます。

Pandoc の導入

Markdown から HTML ファイルを生成する仕組みとして Pandoc を使います。

Pandoc は各種文書フォーマットを相互変換するツールです。開発言語は Haskell。2006 年から開発が始まっており、2026-02-16 現在の最新バージョンは 3.9 です。

Pandoc のインストール

Pandoc は brew コマンドでインストールできます。

brew install pandoc
Pandoc の基本的な使い方

Pandoc の基本オプションは --from--to です。--from オプションで入力フォーマット指定します。今回は markdown を選択します。--to オプションは出力フォーマット指定です。出力フォーマットは html5 を選びます。

出力先は --output オプションで指定できます。

利用例は次の通りです:

pandoc --from=markdown --to=html5 --output=entry.html entry.md

上記コマンドは、Markdown ファイル entry.md を HTML に変換し、entry.html ファイルを作成します。

例えば entry.md が次のような中身だった場合

# Pandoc の導入

Markdown から HTML ファイルを生成する仕組みとして [Pandoc](https://pandoc.org/) を使います。

Pandoc は各種文書フォーマットを相互変換するツールです。...

## Pandoc のインストール

Pandoc は `brew` コマンドでインストールできます。

出力の entry.html は下記のようになります。

<h1 id="pandoc-の導入">Pandoc の導入</h1>
<p>Markdown から HTML ファイルを生成する仕組みとして <a
href="https://pandoc.org/">Pandoc</a> を使います。</p>
<p>Pandoc は各種文書フォーマットを相互変換するツールです。…</p>
<h2 id="pandoc-のインストール">Pandoc のインストール</h2>
<p>Pandoc は <code>brew</code> コマンドでインストールできます。</p>
markdown フォーマット

--from オプションに設定する markdown について補足です。 Pandoc には Markdown を表すフォーマットが 8 つあります:

  1. commonmark : CommonMark
  2. commanmark_x : 拡張付き CommonMark
  3. gfm : GitHub-Flavored Markdown
  4. markdown_github : deprecated になった gfm
  5. markdown : Pandoc’s Markdown
  6. markdown_mmd : MultiMarkdown
  7. markdown_phpextra : PHP Markdown Extra
  8. markdown_strict : オリジナルの (拡張なしの) Markdown

これらは Markdown の様々な方言に対応したものです。8 つのフォーマットのうち、どのフォーマットを使うのが適切でしょうか?

最もオリジナルに近い Markdown を使いたい場合は markdown_strict を使います。

GitHub-Flavored Markdown で導入された Fenced Code Block を使いたい場合は gfm です。と言いたいところですが、gfm には罠があります。実は gfm を指定すると、厳密に GitHub-Flavored Markdown な記法に限定されてしまうのです。言い換えると、gfm は Pandoc 用の拡張を受け付けません。

私は markdown フォーマットを選んでいます。markdown フォーマットは Pandoc 用の拡張をサポートした Markdown 用フォーマットです。HTML に変換する時に、例えば classid を付与することが可能になります。先の Fenced Code Block も markdown フォーマットはデフォルトで対応しています。

ブログ出力用のカスタマイズ

自動 ID 付与の抑制

Pandoc はヘッダーに自動で ID を振ってくれます。とても便利な機能ですが、ブログでは少し問題があります。というのは、ブログは複数の記事を 1 つのページに表示することがあるからです。

例えば、ブログの記事毎に「あとがき」なるヘッダーを入れたとします。この時 Pandoc は id="あとがき" という ID を自動生成します。読者がその記事だけを読むのであれば良いでしょう。しかし、「月別アーカイブ」を開くとどうでしょう。「月別アーカイブ」の中にいくつもの id="あとがき" が現れてしまいます。ID が複数あると、<a href="#あとがき">あとがきへのリンク</a> はどこへジャンプすれば良いのか分からなくなってしまいます。

Pandoc の自動 ID 付与機能をオフにするには、--format オプションに追加オプション -auto_identifiers を付けます。

pandoc --from=markdown-auto_identifiers --to=html5 entry.md > entry.html

以下、実行結果です:

<h1>Pandoc の導入</h1>
<p>Markdown から HTML ファイルを生成する仕組みとして <a
href="https://pandoc.org/">Pandoc</a> を使います。</p>
<p>Pandoc は各種文書フォーマットを相互変換するツールです。…</p>
<h2>Pandoc のインストール</h2>
<p>Pandoc は <code>brew</code> コマンドでインストールできます。</p>
ID の指定

ブログ記事を書いていると、ID を付けたいケースもあります。その場合、Pandoc 拡張を利用します。

# Pandoc の導入{#introduce-pandoc}

上記のように、# ヘッダー文字列{#id-text} という形で ID を記入します。すると、次のように ID が振られます。

<h1 id="introduce-pandoc">Pandoc の導入</h1>
ヘディング・レベルの変更

Blogger では HTML のヘディング・レベルは次のようになっています。

  • h1 : ブログのタイトル
  • h2 : 日付ヘッダー
  • h3 : 記事タイトル

従って、ブログ記事内の最初のヘッダーは h4 から始まります。ですので、Markdown でブログ記事を書く時も h4 が始まりとなります。

ですが、いちいち書き手がそんな気を回さなければいけないのは面倒です。幸い Pandoc には Shift Heading Level という機能があり、ヘディング・レベルを変更できます。オプションは --shift-heading-level-by を使います。今回は # (h1 相当) を #### (h4 相当) にシフトさせたいので、ヘディング・レベルを 3 つ上げます。

pandoc --from=markdown-auto_identifiers --to=html5 --shift-heading-level-by=3 entry.md > entry.html

これで次のように #h4 に変換されます。

<h4>Pandoc の導入</h4>
<p>Markdown から HTML ファイルを生成する仕組みとして <a
href="https://pandoc.org/">Pandoc</a> を使います。</p>
<p>Pandoc は各種文書フォーマットを相互変換するツールです。…</p>
<h5>Pandoc のインストール</h5>
<p>Pandoc は <code>brew</code> コマンドでインストールできます。</p>

コードの表示

Pandoc のシンタックス・ハイライト

Pandoc はソースコードのシンタックス・ハイライトをデフォルトでサポートしています。

例えば、次のソースコードを含む Markdown ファイルを HTML に変換してみましょう。

Lua のサンプルコードです。

``` lua
local languages = {
  ['emacs-lisp'] = true,
  elisp = true,
  html = true,
  lua = true,
  markdown = true,
  ruby = true,
  swift = true,
}
```

上記の Markdown ファイルに対して、次のコマンドを実行してみました。

pandoc --from=markdown-auto_identifiers --to=html5 --shift-heading-level-by=3 --output=source1.html source1.md

結果は次のようになります。

<p>Lua のサンプルコードです。</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode lua"><code class="sourceCode lua"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">local</span> <span class="va">languages</span> <span class="op">=</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">[</span><span class="st">&#39;emacs-lisp&#39;</span><span class="op">]</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="va">elisp</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="va">html</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  <span class="va">lua</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="va">markdown</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>  <span class="va">ruby</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>  <span class="va">swift</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>

どうでしょう。ソースコードの構文が解析され、変数やオペレーターに span 要素が追加されています。ただ、CSS が当たっていないので色が付いていません。

ここで --standalone オプションを追加すると、HTML ファイルに CSS を追加してくれます。

pandoc --from=markdown-auto_identifiers --to=html5 --shift-heading-level-by=3 --standalone --output=source1.html source1.md
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <title>source1</title>
  <style>
    /* Default styles provided by pandoc.
    ** See https://pandoc.org/MANUAL.html#variables-for-html for config info.
    */
    html {
      color: #1a1a1a;
      background-color: #fdfdfd;
    }
    body {
      margin: 0 auto;
      max-width: 36em;
      padding-left: 50px;
      padding-right: 50px;
      padding-top: 50px;
      padding-bottom: 50px;
      hyphens: auto;
      overflow-wrap: break-word;
      text-rendering: optimizeLegibility;
      font-kerning: normal;
    }
    @media (max-width: 600px) {
      body {
        font-size: 0.9em;
        padding: 12px;
      }
      h1 {
        font-size: 1.8em;
      }
    }
    @media print {
      html {
        background-color: white;
      }
      body {
        background-color: transparent;
        color: black;
        font-size: 12pt;
      }
      p, h2, h3 {
        orphans: 3;
        widows: 3;
      }
      h2, h3, h4 {
        page-break-after: avoid;
      }
    }
    p {
      margin: 1em 0;
    }
    a {
      color: #1a1a1a;
    }
    a:visited {
      color: #1a1a1a;
    }
    img {
      max-width: 100%;
    }
    svg {
      height: auto;
      max-width: 100%;
    }
    h1, h2, h3, h4, h5, h6 {
      margin-top: 1.4em;
    }
    h5, h6 {
      font-size: 1em;
      font-style: italic;
    }
    h6 {
      font-weight: normal;
    }
    ol, ul {
      padding-left: 1.7em;
      margin-top: 1em;
    }
    li > ol, li > ul {
      margin-top: 0;
    }
    blockquote {
      margin: 1em 0 1em 1.7em;
      padding-left: 1em;
      border-left: 2px solid #e6e6e6;
      color: #606060;
    }
    code {
      font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
      font-size: 85%;
      margin: 0;
      hyphens: manual;
    }
    pre {
      margin: 1em 0;
      overflow: auto;
    }
    pre code {
      padding: 0;
      overflow: visible;
      overflow-wrap: normal;
    }
    .sourceCode {
     background-color: transparent;
     overflow: visible;
    }
    hr {
      border: none;
      border-top: 1px solid #1a1a1a;
      height: 1px;
      margin: 1em 0;
    }
    table {
      margin: 1em 0;
      border-collapse: collapse;
      width: 100%;
      overflow-x: auto;
      display: block;
      font-variant-numeric: lining-nums tabular-nums;
    }
    table caption {
      margin-bottom: 0.75em;
    }
    tbody {
      margin-top: 0.5em;
      border-top: 1px solid #1a1a1a;
      border-bottom: 1px solid #1a1a1a;
    }
    th {
      border-top: 1px solid #1a1a1a;
      padding: 0.25em 0.5em 0.25em 0.5em;
    }
    td {
      padding: 0.125em 0.5em 0.25em 0.5em;
    }
    header {
      margin-bottom: 4em;
      text-align: center;
    }
    #TOC li {
      list-style: none;
    }
    #TOC ul {
      padding-left: 1.3em;
    }
    #TOC > ul {
      padding-left: 0;
    }
    #TOC a:not(:hover) {
      text-decoration: none;
    }
    code{white-space: pre-wrap;}
    span.smallcaps{font-variant: small-caps;}
    div.columns{display: flex; gap: min(4vw, 1.5em);}
    div.column{flex: auto; overflow-x: auto;}
    div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
    /* The extra [class] is a hack that increases specificity enough to
       override a similar rule in reveal.js */
    ul.task-list[class]{list-style: none;}
    ul.task-list li input[type="checkbox"] {
      font-size: inherit;
      width: 0.8em;
      margin: 0 0.8em 0.2em -1.6em;
      vertical-align: middle;
    }
    .display.math{display: block; text-align: center; margin: 0.5rem auto;}
    /* CSS for syntax highlighting */
    html { -webkit-text-size-adjust: 100%; }
    pre > code.sourceCode { white-space: pre; position: relative; }
    pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
    pre > code.sourceCode > span:empty { height: 1.2em; }
    .sourceCode { overflow: visible; }
    code.sourceCode > span { color: inherit; text-decoration: inherit; }
    div.sourceCode { margin: 1em 0; }
    pre.sourceCode { margin: 0; }
    @media screen {
    div.sourceCode { overflow: auto; }
    }
    @media print {
    pre > code.sourceCode { white-space: pre-wrap; }
    pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
    }
    pre.numberSource code
      { counter-reset: source-line 0; }
    pre.numberSource code > span
      { position: relative; left: -4em; counter-increment: source-line; }
    pre.numberSource code > span > a:first-child::before
      { content: counter(source-line);
        position: relative; left: -1em; text-align: right; vertical-align: baseline;
        border: none; display: inline-block;
        -webkit-touch-callout: none; -webkit-user-select: none;
        -khtml-user-select: none; -moz-user-select: none;
        -ms-user-select: none; user-select: none;
        padding: 0 4px; width: 4em;
        color: #aaaaaa;
      }
    pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
    div.sourceCode
      {   }
    @media screen {
    pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
    }
    code span.al { color: #ff0000; font-weight: bold; } /* Alert */
    code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
    code span.at { color: #7d9029; } /* Attribute */
    code span.bn { color: #40a070; } /* BaseN */
    code span.bu { color: #008000; } /* BuiltIn */
    code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
    code span.ch { color: #4070a0; } /* Char */
    code span.cn { color: #880000; } /* Constant */
    code span.co { color: #60a0b0; font-style: italic; } /* Comment */
    code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
    code span.do { color: #ba2121; font-style: italic; } /* Documentation */
    code span.dt { color: #902000; } /* DataType */
    code span.dv { color: #40a070; } /* DecVal */
    code span.er { color: #ff0000; font-weight: bold; } /* Error */
    code span.ex { } /* Extension */
    code span.fl { color: #40a070; } /* Float */
    code span.fu { color: #06287e; } /* Function */
    code span.im { color: #008000; font-weight: bold; } /* Import */
    code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
    code span.kw { color: #007020; font-weight: bold; } /* Keyword */
    code span.op { color: #666666; } /* Operator */
    code span.ot { color: #007020; } /* Other */
    code span.pp { color: #bc7a00; } /* Preprocessor */
    code span.sc { color: #4070a0; } /* SpecialChar */
    code span.ss { color: #bb6688; } /* SpecialString */
    code span.st { color: #4070a0; } /* String */
    code span.va { color: #19177c; } /* Variable */
    code span.vs { color: #4070a0; } /* VerbatimString */
    code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
  </style>
</head>
<body>
<p>Lua のサンプルコードです。</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode lua"><code class="sourceCode lua"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">local</span> <span class="va">languages</span> <span class="op">=</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">[</span><span class="st">&#39;emacs-lisp&#39;</span><span class="op">]</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="va">elisp</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="va">html</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  <span class="va">lua</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="va">markdown</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>  <span class="va">ruby</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>  <span class="va">swift</span> <span class="op">=</span> <span class="kw">true</span><span class="op">,</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</body>
</html>

ウェブブラウザーで HTML ファイルを開くと、色が付いているのが分かります。

Prism.js を使ったシンタックス・ハイライト

Pandoc のシンタックス・ハイライトを使っても良いですが、せっかく前記事で Prism.js を導入したので、シンタックス・ハイライトはそちらに任せようと思います。

Prism.js を使う場合、Pandoc のデフォルトで付いてくるシンタック・ハイライトの出力が邪魔です。まず --standalone オプションを 付けない ことで、CSS の挿入を妨げ、続いて --syntax-highlighting=none オプションを付けてシンタックス・ハイライト用の出力も抑制します。

pandoc --from=markdown-auto_identifiers --to=html5 --shift-heading-level-by=3 --syntax-highlighting=none --output=source1.html source1.md

すると、シンプルな HTML 出力を得ました。

<p>Lua のサンプルコードです。</p>
<pre class="lua"><code>local languages = {
  [&#39;emacs-lisp&#39;] = true,
  elisp = true,
  html = true,
  lua = true,
  markdown = true,
  ruby = true,
  swift = true,
}</code></pre>

さて、Prism.js にシンタックス・ハイライトをさせるためには、次の書式で HTML を書く必要がありました。 これは HTML5 で推奨されている書き方だそうです。

<pre><code class="language-XXX">
プログラミング言語 XXX のソースコード
</code></pre>

HTML5 の推奨は code 要素の class 属性に language-lua と書くのですが、Pandoc の出力は pre 要素の class 属性に lua と書なっています。

Pandoc には Lua 言語でフィルターを作成することができて、Pandoc の HTML 出力を Prism.js に合わせることが可能です。

上記サイトを参考にして、Lua フィルタースクリプトを書きました。これを standard_code.lua という名前で保存します。 なお、保存する時に、シンタックスハイライトしたい言語を languages に記述してください。

--- standard-code: ouput code blocks with class="language-*" attributes
-- © 2020 Aman Verma. Distributed under the MIT license.

-- Check keywords at https://prismjs.com/#supported-languages
local languages = {
  ['emacs-lisp'] = true,
  elisp = true,
  html = true,
  lua = true,
  makefile = true,
  markdown = true,
  ruby = true,
  shellsession = true,
  swift = true,
}

-- local languages = {meta = true,markup = true,css = true,clike = true,javascript = true,abap = true,abnf = true,actionscript = true,ada = true,agda = true,al = true,antlr4 = true,apacheconf = true,apl = true,applescript = true,aql = true,arduino = true,arff = true,asciidoc = true,aspnet = true,asm6502 = true,autohotkey = true,autoit = true,bash = true,basic = true,batch = true,bbcode = true,bison = true,bnf = true,brainfuck = true,brightscript = true,bro = true,bsl = true,c = true,csharp = true,cpp = true,cil = true,clojure = true,cmake = true,coffeescript = true,concurnas = true,csp = true,crystal = true,['css-extras'] = true,cypher = true,d = true,dart = true,dax = true,dhall = true,diff = true,django = true,['dns-zone-file'] = true,docker = true,ebnf = true,editorconfig = true,eiffel = true,ejs = true,['emacs-lisp'] = true,elisp = true,elixir = true,elm = true,etlua = true,erb = true,erlang = true,['excel-formula'] = true,fsharp = true,factor = true,['firestore-security-rules'] = true,flow = true,fortran = true,ftl = true,gml = true,gcode = true,gdscript = true,gedcom = true,gherkin = true,git = true,glsl = true,go = true,graphql = true,groovy = true,haml = true,html = true,handlebars = true,haskell = true,haxe = true,hcl = true,hlsl = true,http = true,hpkp = true,hsts = true,ichigojam = true,icon = true,ignore = true,inform7 = true,ini = true,io = true,j = true,java = true,javadoc = true,javadoclike = true,javastacktrace = true,jolie = true,jq = true,jsdoc = true,['js-extras'] = true,json = true,json5 = true,jsonp = true,jsstacktrace = true,['js-templates'] = true,julia = true,keyman = true,kotlin = true,latex = true,latte = true,less = true,lilypond = true,liquid = true,lisp = true,livescript = true,llvm = true,lolcode = true,lua = true,makefile = true,markdown = true,['markup-templating'] = true,matlab = true,mel = true,mizar = true,mongodb = true,monkey = true,moonscript = true,n1ql = true,n4js = true,['nand2tetris-hdl'] = true,naniscript = true,nasm = true,neon = true,nginx = true,nim = true,nix = true,nsis = true,objc = true,objectivec = true,ocaml = true,opencl = true,oz = true,parigp = true,parser = true,pascal = true,pascaligo = true,pcaxis = true,peoplecode = true,perl = true,php = true,phpdoc = true,['php-extras'] = true,plsql = true,powerquery = true,powershell = true,processing = true,prolog = true,properties = true,protobuf = true,pug = true,puppet = true,pure = true,purebasic = true,purescript = true,python = true,q = true,qml = true,qore = true,r = true,racket = true,jsx = true,tsx = true,reason = true,regex = true,renpy = true,rest = true,rip = true,roboconf = true,robotframework = true,ruby = true,rust = true,sas = true,sass = true,scss = true,scala = true,scheme = true,['shell-session'] = true,smali = true,smalltalk = true,smarty = true,solidity = true,['solution-file'] = true,soy = true,sparql = true,['splunk-spl'] = true,sqf = true,sql = true,stan = true,iecst = true,stylus = true,swift = true,['t4-templating'] = true,['t4-cs'] = true,['t4-vb'] = true,tap = true,tcl = true,tt2 = true,textile = true,toml = true,turtle = true,twig = true,typescript = true,typoscript = true,unrealscript = true,vala = true,vbnet = true,velocity = true,verilog = true,vhdl = true,vim = true,['visual-basic'] = true,warpscript = true,wasm = true,wiki = true,xeora = true,['xml-doc'] = true,xojo = true,xquery = true,yaml = true,yang = true,zig = true}


local function escape(s)
  -- Escape according to HTML 5 rules
  return s:gsub(
    [=[[<>&"']]=],
    function(x)
      if x == '<' then
        return '&lt;'
      elseif x == '>' then
        return '&gt;'
      elseif x == '&' then
        return '&amp;'
      elseif x == '"' then
        return '&quot;'
      elseif x == "'" then
        return '&#39;'
      else
        return x
      end
    end
  )
end

local function getCodeClass(classes)
  -- Check if the first element of classes (pandoc.CodeBlock.classes) matches a
  -- programming language name. If it does, it gets removed from classes and a valid
  -- HTML class attribute string (with space at beginning) is returned.

  if languages[classes[1]] then
    return ' class="language-' .. table.remove(classes, 1) .. '"'
  else
    return ''
  end
end

local function makeIdentifier(ident)
  -- Returns a valid HTML id attribute (with space at beginning) OR empty string.

  if #ident ~= 0 then
    return ' id="'.. ident .. '"'
  else
    return ''
  end
end

local function makeClasses(classes)
  -- Returns a valid HTML class attribute with classes separated by spaces (with a space
  -- at the beginning) OR empty string.

  if #classes ~= 0 then
    return ' class="' .. table.concat(classes, ' ') .. '"'
  else
    return ''
  end
end

local function makeAttributes(attrs)
  -- Returns a string of HTML attributes from key-value pairs
  -- (with space at beginning for each attribute) OR empty string.

  if #attrs ~= 0 then
    local result = ''
    for key, value in pairs(attrs) do
      result = result .. ' ' .. key .. '="' .. escape(value) .. '"'
    end
    return result
  else
    return ''
  end
end

return {
  {
    CodeBlock = function(elem)
      if FORMAT ~= 'html5' then
        return nil
      end

      local id = makeIdentifier(elem.identifier)
      local classLang = getCodeClass(elem.classes)
      local classReg = makeClasses(elem.classes)
      local extraAttrs = makeAttributes(elem.attributes)

      local preCode = string.format(
        '<pre%s%s%s><code%s>%s</code></pre>', id, classReg, extraAttrs, classLang, escape(elem.text)
      )
      return pandoc.RawBlock('html', preCode, 'RawBlock')
    end,

  }
}

--lua-filter=standard_code.lua オプションで Lua スプリプトを指定します。

pandoc --from=markdown-auto_identifiers --to=html5 --shift-heading-level-by=3 --syntax-highlighting=none --lua-filter=standard_code.lua --output=source1.html source1.md

出力を見てみましょう。Prism.js 向けの HTML になりました。

<p>Lua のサンプルコードです。</p>
<pre><code class="language-lua">local languages = {
  [&#39;emacs-lisp&#39;] = true,
  elisp = true,
  html = true,
  lua = true,
  markdown = true,
  ruby = true,
  swift = true,
}</code></pre>
行番号を表示する

Prism.js にはプラグインを導入することで、行番号を表示することができます。 そのためには、class="line-numbers" を指定する必要があります。 Pandoc では {.line-numbers} と書くことでクラスを追加できます。

実際に試してみます。 Markdown ファイルに {.line-numbers} を追加した後、

Lua のサンプルコードです。

``` lua {.line-numbers}
local languages = {
  ['emacs-lisp'] = true,
  elisp = true,
  html = true,
  lua = true,
  markdown = true,
  ruby = true,
  swift = true,
}
```

pandoc コマンドを実行します。

pandoc --from=markdown-auto_identifiers --to=html5 --shift-heading-level-by=3 --syntax-highlighting=none --lua-filter=standard_code.lua --output=source2.html source2.md

出力は次の通り。 行番号対応した HTML が得られました。

<p>Lua のサンプルコードです。</p>
<pre class="line-numbers"><code class="language-lua">local languages = {
  [&#39;emacs-lisp&#39;] = true,
  elisp = true,
  html = true,
  lua = true,
  markdown = true,
  ruby = true,
  swift = true,
}</code></pre>
行をハイライトする

行をハイライトする方法も見ておきましょう。 ハイライトしたい行を data-line="行番号" という形で指定するのでした。 Pandoc では {data-line="5"} と指定すれば OK です。

こちらも試してみましょう。 Markdown ファイルに data-line="5" を追加してみます。

Lua のサンプルコードです。

``` lua {.line-numbers data-line="5"}
local languages = {
  ['emacs-lisp'] = true,
  elisp = true,
  html = true,
  lua = true,
  markdown = true,
  ruby = true,
  swift = true,
}
```

これを pandoc で処理します。

pandoc --from=markdown-auto_identifiers --to=html5 --shift-heading-level-by=3 --syntax-highlighting=none --lua-filter=standard_code.lua --output=source3.html source3.md

行ハイライトに対応した HTML が出力されていますね。

<p>Lua のサンプルコードです。</p>
<pre class="line-numbers" data-line="5"><code class="language-lua">local languages = {
  [&#39;emacs-lisp&#39;] = true,
  elisp = true,
  html = true,
  lua = true,
  markdown = true,
  ruby = true,
  swift = true,
}</code></pre>

Makefile の作成

以上の準備を整えれば、Markdown ファイルを pandoc コマンドで HTML ファイルに変換ができます。 しかし、必要な pandoc コマンドはオプションを含めると長くなってしまいました。 これだけのオプションを毎回手打ちするのは避けたいところです。

そこで、Makefile を作って自動化することにしました。

Markdown ファイルと同じディレクトリーに、次のコードを Makefile という名前で保存します。

all: html

PANDOC = pandoc
PANDOC_OPTS = --from=markdown-auto_identifiers --to=html5 --shift-heading-level-by=3 --syntax-highlighting=none --lua-filter=standard_code.lua

MD_FILES := $(wildcard *.md)
HTML_FILES := $(MD_FILES:.md=.html)

.PHONY: html
html: $(HTML_FILES)

%.html: %.md
    $(PANDOC) $(PANDOC_OPTS) --output=$@ $<

この Makefile.md という拡張子のファイルがあったら、pandoc コマンドを PANDOC_OPTS オプションを使って処理し、同名の .html ファイルを作成する、というものです。 Makefile を作っておけば、make と実行するだけで、HTML ファイルが作成されます。

make

あとがき

以上で設定は終わりです。 最近はめっきりブログを書くことが少なくなりました。 Markdown で気軽に書けるシステムを構築できたので、月一くらいで記事を書ければと思います。

2025-01-01

Blogger に Syntax Highlight ツール Prism.js を入れてみた

Blog を書き始めて早 20 年。世のテック系ブログでは、コードのシンタックス・ハイライト (Syntax Highlight) など当たり前になっているのに、当ブログはまだシンタックス・ハイライトに対応していない。遅まきながら、シンタックス・ハイライトに対応させてみた。

使ったツールは Prism.js。下記ブログ記事を参考にした。

シンタックス・ハイライトとは...

シンタックス・ハイライトは、プログラム言語のソースコードに色を付ける仕組み。例えば、次のようなソースコードが

// Swift のソースコード
struct Book {
  let id: UUID = .init()
  let name: String
}
let book = Book(name: "Foundation")

シンタックス・ハイライトを付けると次のように表示される。

// Swift のソースコード
struct Book {
  let id: UUID = .init()
  let name: String
}
let book = Book(name: "Foundation")

ソースコードに色が付いていると、読みやすいし、書き手の気分も上がる。

Prism.js + jsDeliver

シンタックス・ハイライトを実現するツールには Prism.js を使う。サフィックスに js と付いていることから分かる通り JavaScript で書かれている。加えて対応する CSS が用意されている。

さて、Blogger は写真・動画以外のファイルをアップロードできない。そのため、Prism.js が用意する JavaScript/CSS ファイルを直接参照することができない。

この対処方法として、これらのファイルを別の場所に保存する方法が考えられる。候補として、Dropbox などのストレージ・サービスがあるけれども、ブログサービスのように不特定多数が頻繁にアクセスする目的で作られているわけではないので、ファイルのダウンロード速度に不満がある。

専用に作られたサービスとして CDN があるので、これを使ってみた。

jsDelivr で用意した JavaScript と CSS のソースコードが次の通り:

<!-- JavaScript -->
<script src="https://cdn.jsdelivr.net/combine/npm/prismjs@1/components/prism-core.min.js,npm/prismjs@1/plugins/line-numbers/prism-line-numbers.min.js,npm/prismjs@1/plugins/line-highlight/prism-line-highlight.min.js,npm/prismjs@1/plugins/toolbar/prism-toolbar.min.js,npm/prismjs@1/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js,npm/prismjs@1/plugins/show-language/prism-show-language.min.js,npm/prismjs@1/plugins/treeview/prism-treeview.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/autoloader/prism-autoloader.min.js"></script>

<!-- CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/combine/npm/prismjs@1/themes/prism.min.css,npm/prismjs@1/plugins/line-numbers/prism-line-numbers.min.css,npm/prismjs@1/plugins/line-highlight/prism-line-highlight.min.css,npm/prismjs@1/plugins/toolbar/prism-toolbar.min.css,npm/prismjs@1/plugins/treeview/prism-treeview.min.css"/>

Blogger にコードを埋める

次に Blogger の説明画面を開き、テーマから「カスタマイズ > HTML を編集」を選択する。

下記サンプルコードを参考に、上記 JavaScript と CSS のコードを挿入する。

<!-- HTML を編集 -->
<html>
<head>
...
<!-- ここに CSS のコードを挿入する -->
</head>
<body>
...
<!-- ここに JavaScript のコードを挿入する -->
</body>

これで準備は終了。

コードをハイライトさせる

コードのハイライトをするためには次の書式で HTML を書く。

<pre><code class="language-XXX">
プログラミング言語 XXX のソースコード  
</code></pre>

XXX の部分にはプログラミング言語の名前が入る。XXX の名前は PrismJS の Supported languages から調べることができる。

例えば、上述の Swift コード。あれのハイライトは、Swift 言語のコード・ハイライトだった。Supported languages で調べると、Swift 言語は swift というキーワードを使えば良いと分かる。そこで、次のコードを書いた。

<pre><code class="language-swift">// Swift のソースコード
struct Book {
  let id: UUID = .init()
  let name: String
}
let book = Book(name: "Foundation")
</code></pre>

プラグイン

今回、7 つのプラグインを導入した。

autoloader

必要なシンタックス・ハイライト文法を自動ロードする

toolbar

copy-to-clipboard, show-language で必要

line-numbers

行番号を表示する。

シンプルな行番号表示には、pre 要素に class="line-numbers" を追加する。

// Swift のソースコード
struct Book {
  let id: UUID = .init()
  let name: String
}
let book = Book(name: "Foundation")

ソースコードは次の通り:

<pre class="line-numbers"><code class="language-swift">// Swift のソースコード
struct Book {
  let id: UUID = .init()
  let name: String
}
let book = Book(name: "Foundation")
</code></pre>

オプションとして、data-start="数字"を追加することで、行番号を開始する行を指定することもできる。

// Swift のソースコード
struct Book {
  let id: UUID = .init()
  let name: String
}
let book = Book(name: "Foundation")

ソースコードは次の通り:

<pre class="line-numbers" data-start="-3"><code class="language-swift">// Swift のソースコード
struct Book {
  let id: UUID = .init()
  let name: String
}
let book = Book(name: "Foundation")
</code></pre>
line-highlight

行をハイライト表示する

ハイライト表示したい行を data-line="N" で指定する。下に示す通り line-numbers プラグインと一緒に使うことも可能。

// Swift のソースコード
struct Book {
  let id: UUID = .init()
  let name: String
}
let book = Book(name: "Foundation")

ソースコードは次の通り:

<pre class="line-numbers" data-line="4"><code class="language-swift">// Swift のソースコード
struct Book {
  let id: UUID = .init()
  let name: String
}
let book = Book(name: "Foundation")
</code></pre>
copy-to-clipboard

「クリップボードへコピー」ボタンを表示する

show-language

言語名を表示する

ディレクトリー構成の表示をサポートする

tree -F で出力したディレクトリー構成を良い感じに表示する。

2023-06-06

WWDC 2023 で iOS 17, iPadOS 17, macOS Sonoma, watchOS 10, 新 MacBook, Apple Vision Pro が発表された

2023-06-06 (火) 02:00、Apple は WWDC のキーノートを放送して、各種新 OS (iOS 17, iPadOS 17, macOS Sonoma, watchOS 10, tvOS 10) と新デバイス (M2 チップ Ultra, MacBook Air, Mac Studio, Mac Pro, Apple Vision Pro) を発表した。

Apple Vision Pro は長年噂され続けていた Apple の AR/VR ヘッドセット。年内にアメリカで発売され、来年中に各国での発売が予定されている。価格は 34,999 ドル。約 50 万円?!

iOS 17

iOS 17 では主な新機能として連絡先ポスター、ステッカー、スタンバイが追加され、新アプリ「ジャーナル」のリリースが予告された。

連絡先ポスター

電話アプリや連絡先アプリなどで、自分の見た目をポスターのように表示する機能が追加される。連絡先ポスターはロック画面と同じようにカスタマイズが可能で、写真もしくはミー文字とタイポグラフィーの組み合わせで表示される。

CallKit からの利用も可能なため、VoIP アプリからも連絡先ポスターの利用が可能になる。

ステッカー

ステッカーを貼る機能が追加される。ステッカーはメッセージ・アプリなどで利用が可能で、ステッカーのように貼り付けることができる。貼り付けられるものはミー文字や絵文字など。ステッカーパックをダウンロードして利用することも可能になるらしい。また、写真から背景を取り除いて、ステッカーにすることも可能。Live Photos からライブステッカーを作成することもできる。

絵文字が使えるあらゆる場所で使えるとされている。

スタンバイ

Apple Watch のナイトスタンド・モードの iPhone 版。充電中に iPhone を横置きにすると、専用のスタンバイ画面を表示する。この画面は 3 ページで構成されていて、左右スワイプで移動可能。その構成は、ウィジェットのページ、写真のページ、そして時計のページ。

ウィジェットはスマートスタックに対応していて、時間などに応じて適切なウィジェットが自動的に表示される。また、ユーザーがウィジェットを手動で切り替えることも可能。時計には複数の文字盤が用意されている。

この他に、スタンバイ画面ではライブアクティビティーの表示や、Siri を使っての操作も可能とされている。

またナイトモードでは、赤の色調で表示され、眠りに誘う工夫が凝らされている。

ジャーナル・アプリ

Apple が提供する日記アプリ。2023 年後半リリース予定。

連絡先・写真・音楽・ポッドキャスト・位置情報・ワークアウト etc. の情報から、日記を書くための「候補」を出す機能がある。これらの候補を出すために開発者には、Suggestions API が提供される。

その他

各アプリの新機能を列挙する:

  • 電話アプリ
    • Live Voicemail: 留守電に残されているメッセージをリアルタイムに書き起こす。テキストを読んで途中で電話に出ることも可能
  • FaceTime アプリ: FaceTime をかけて相手が出なかった場合、メッセージを録画して残せる
  • メッセージ・アプリ
    • キャッチアップ: 未読メッセージの先頭まで辿るボタンが表示されるようになる
    • Swipe to Reply: 吹き出しをスワイプすると、インライン返信できる
    • Audio message transcription: オーディオメッセージが書き起こされる
    • 安否確認 (Check In): 無事に帰宅したことを友人に知らせることができる。帰宅したら自動通知。帰宅しなかったら、自動で各種情報 (現在地・経路・バッテリー情報など) が共有される。
    • 検索フィルターが追加される
  • NameDrop: AirDrop で iPhone を近づけると連絡先情報を渡せる
  • Siri
    • Hey Siri が Siri だけで起動可能になる
    • 連続してリクエストを伝えられるようになる
  • マップアプリ: オフライン用に地図をダウンロードできるようになる
  • 写真: 「お気に入りの人」にペットを追加できるようになる

iPadOS 17

iPadOS 17 での変化で目を引くのはウィジェットとステージマネージャーの進化。それから、iOS でしか提供されていなかったロック画面の変更機能とヘルスケア・アプリがやって来る。

ウィジェット

インタラクティブ・ウィジェットが導入される。今までのウィジェットは、情報を表示するか、アプリを開くか、もしくは大きなボタンを表示してアクションするくらいしかできなかった。なので、ウィジェットの中でチェックボックスを置いてチェックを入れたり、再生ボタンを押して音楽再生を開始したりという操作性を提供できなかった。iPadOS 17 からは、そういったユーザーがインタラクティブに操作するウィジェットの作成が可能になる。

ステージマネージャー

ステージマネージャーは今までよりも細かくウィンドウの位置とサイズを変更できるようになる。

ロック画面

iOS で導入されていたロック画面の設定機能が iPadOS にもやって来る。iPad 版のロック画面では、ウィジェットを表示する領域が左側に寄せられて iOS より広くなる。

また、iPad の大画面に合わせてアストロノミー壁紙が刷新されている。

ヘルスケア・アプリ

iOS のみに提供されていたヘルスケア・アプリが iPadOS にもやって来る。iPad の大画面向けに最適化されている。

misc

その他、キーノートで発表のあったもの。一部の機能は iOS でも利用可能。

  • PDF のテキスト・フィールドを認識して、直接入力が可能になる
  • FaceTime に外部ディスプレイに内蔵されたカメラを利用可能になる
  • フリーボード・アプリに水彩・万年筆といった描画ツールが加わる
  • フリーボード・アプリで共通同作業メンバーのフォロー機能が追加される

macOS Sonoma

macOS Sonoma (macOS 14) で目を引くのはウィジェット機能。続いてビデオ会議系の強化が上げられる。

ウィジェット

iOS や iPadOS でしか提供されていなかったウィジェット機能が、macOS でも使えるようになる。嬉しいことに、macOS 用のウィジェットが用意されていなくても、iPhone アプリ版のウィジェットも (macOS で) 利用可能になる。利用には同じネットワーク内に iPhone があれば良いらしい。

macOS のウィジェットは iOS と同じようにインタラクティブ・ウィジェット。更にアプリを開くとウィジェットは半透明になって、デスクトップにあるウィジェットに気を紛らわせないよう配慮されている。

ビデオ会議

Facebook を始めとしたビデオ会議機能に機能追加が行なわれる。1 つ目は画面共有のプレゼンター・オーバーレイ機能。画面共有をしているプレゼンターの姿を、他の視聴者に見せるための機能。この機能には、プレゼンターの姿を小さなバブルの中に入れて表示するスモールオーバーレイと、プレゼンターの姿を大きく表示して共有画面をプレゼンターの後ろ横に配置するラージオーバーレイの 2 種類が提供される。

2 つ目はリアクション・エフェクトの追加で、ビデオ会議内に花火を上げたりする機能が追加される。このエフェクトはジェスチャーで起動可能とのこと。例えば、花火を上げるエフェクトは、親指 2 本を立てることで起動できる。

リアクション・エフェクトは FaceTime の他に Zoom や Microsoft Teams, Webex などのサードパーティーアプリでも利用可能になる。

ゲーム機能

ゲーム機能の強化として、ゲームモードが導入される。ゲームモードでは、ゲームに対して、最も高い優先度を CPU や GPU に割り当てる。また、バックグラウンド・タスクの稼働率を下げる。こうすることで、より滑らかなフレームレートを提供できるとしている。

また、Blueteeth にサンプリング周波数を 2 倍にすることで、Xbox と PlayStation コントローラーの入力遅延を低減させるという。

Safari の強化

Safari にプロファイル機能が導入される。仕事とプライベートで、Cookie 情報・ブラウズ履歴・機能拡張・タブグループ・お気に入りなどを切り替えられるようになる。

ウェブサイトをアプリ化する機能が追加される。アプリ化されたページは Dock に保存され、Stage Manager 内でもアプリとして動作するという。

その他、Safari はパスキーに対応したり、プライベート・ブラウジング・ウィンドウに対してロック機能を提供したりする。

watchOS 10

watchOS 10 では大幅なデザイン変更が行なわれた。

スマートスタック

文字盤でデジタルクラウンを回したり、下から上へスワイプすると、スタックされたウィジェットにアクセスできるようになる。見た目は Siri 文字盤に似ているけれど、どの文字盤からでもアクセスできるのが特徴。長押しでウィジェットの追加・編集も可能になる。

コントロールセンターへのアクセスは、下から上へのスワイプではなく、サイドボタンを押す。

新しい文字盤

新しく追加された文字盤は 2 つ。1 つ目はスヌーピーの文字盤。スヌーピーとウッドストックが表示される。文字盤には天気情報が反映される。

2 つ目はパレット。時間の変化に合わせてディスプレイの色が変わる。

サイクリング機能

サイクリングのワークアウト機能が強化される。Bluetooth 対応の自動車センサーに接続可能になり、自転車のケイデンス・パワーなどの情報を取得できるようになる。また、これらのデータを使って FTP (機能的作業閾値パワー; Function Threthold Power; 理論上、1時間継続できるサイクリング強度の最高レベル) の計算を行なってくれる。加えて、パワーゾーン (FTP から算出されるパワー領域のことで、6 つのゾーンに分けられる) の表示を可能にする。

サイクリングの情報は、iPhone でもライブ・アクティビティで自動的に表示されるようになる。

ヘルス系の強化

マインドフルネスと近視に関する機能強化が行なわれた。

マインドフルネスでは、自分の気持ちを記録できるようになる。これらの記録は iPhone のヘルスケア・アプリからも確認可能。また、クリニックでも使われる標準検査を提供。鬱や不安症を発症するリスクを確認できるようになる。

近視周りの強化では、Apple Watch の環境光センサーを使って日光の下で過ごした時間を測定できるようになる。近視のリスクを下げるのに、屋外の日光の下で 80〜120 分以上過ごすことが有効だかららしい。また、iPhone や iPad では、TrueDepth カメラを使って画面との距離を測定し、長時間、目とデバイスの位置が近い場合は警告を出すようにしてくれる。

tvOS 10 その他

tvOS 10 では、コントロールセンターが刷新される。また、Siri Remote を探すアプリから探せるようになる。加えてスクリーンセーバーの写真を、写真のメモリーから選択できるようになる。

最後に、FaceTime アプリが tvOS にも提供される。Apple TV にはカメラとマイクがない。そこで、iPhone の連携カメラ機能を使う。センターフレームにも対応するとのこと。この機能は API としても提供されるらしく、2023 年末には Zoom や Webex が FateTime と同じように tvOS 上で使えるようになるとされている。

その他のデバイスの話。

CarPlay では SharePlay が導入される。Apple Music の音楽再生を、後部座席の人たちが SharePlay 経由で行なうことが出来るようになるとのこと。

AirPods は適応型オーディオなる機能を提供する。これは、外部音取り込みとアクティブ・ノイズキャンセリングを動的に組み合わせた機能で、外部音取り込みが基本だけどノイズになる音はノイズキャンセルしてくれるというもの。電話中なら、周りの音や音楽をノイズとして小さくしてくれるし、会話中は音楽の音量を小さくしてくれる。

新しい Mac

15 インチの MacBook Air と M2 Max/M2 Ultra にアップデートされた Mac Studio、そして M2 Ultra をサポートする Mac Pro が発表された。

どの新機種も予約開始は 2023-06-06 から、発売は来週から。

15 インチ MacBook Air

15 インチ MacBook Air の価格は 198,800 円から。スペックは次の通り:

  • MacBook Air 15 インチ/2023
    • ディスプレイ: 15.3 インチ、Liquid Retina
    • チップ: Apple M2
    • 薄さ: 11.5 mm
    • 重さ: 1.5 kg
    • カメラ: 1080p FaceTime
    • マイク: 3 マイクアレイ
    • スピーカー: 6 スピーカー
    • Thunderbolt ポート x2
    • ヘッドフォンジャック
    • 充電 MagSafe
    • バッテリー 18 時間
MacStudio

新しい Mac Studio は、チップが Apple M2 Max にアップデートされる。また、後述の Apple M2 Ultra も選択可能になる。価格は 298,800 円から。

Mac Pro

Mac Pro は Apple M2 Ultra チップを標準搭載し、PCIe gen 4 拡張スロットを 8 つ (背面に 6 つ、上部に 2 つ)、Thunderbolt 4 ポートを 6 つ、HDMI ポートを 2 つ持つ。価格は 1,048,800 円から。

Apple M2 Ultra

Apple M2 Ultra チップが発表された。M1 Ultra と同じように、M2 max チップを 2 つ繋げる構成。搭載可能な最大メモリーが 192 GB に増えている。

  • 24 core CPU
  • 76 core GPU
  • 32 core Neural Engine
  • 192 GB ユニファイドメモリ

Apple Vision Pro

Apple の AR/MR ヘッドセット Apple Vision Pro が発表された。価格は 3,499 ドル (約 50 万円)。発売はアメリカ国内で 2023 年年内を予定。2024 年年末までに各国での発売開始を目標とする。ただし、日本が最初の株外発売国に含まれるかどうかは未発表。

主なスペックは次の通り:

  • チップ: M2 チップ + R1 チップ
  • ディスプレイ: マイクロ OLED (両目で 2,300 万ピクセル、片目だけで 4K 相当)
  • カメラ: 12 個
  • センサー: 5 つ
  • マイク: 6 つ
  • スピーカー: 空間オーディオをサポート
  • バッテリー: 外付けで 2 時間
  • 認証: Optic ID
  • その他: デジタルクラウン

R1 チップは Vision Pro のために Apple が新しく作成した Apple シリコンチップ。リアルタイム処理を担当するチップで、12 のカメラ、5 つのセンサー、6 つのマイクからの入力を高速処理する。

Optic ID は目の虹彩を使った認証システム。Face ID と同様に、ロックの解除・Apple Pay の利用などに用いられる。

ユーザーからの入力は、目と手の動きでほぼ完結するらしい。さらにテキスト入力に関しては、バーチャル・キーボードと音声入力がデフォルトで用意される他、Bluetooth デバイスを接続してトラックパッドやキーボードも利用可能。もちろん、ゲーム用のコントローラーもサポートされる。

用意されるアプリは、visionOS 専用のアプリの他に、iPhone, iPad 用のアプリがある。また、Mac を見つめると、Mac の画面を Vision Pro の中に取り出すことが可能になる。加えて、Unity アプリがネイティブで利用可能になるとのこと。

Vision Pro 特有の機能

Eye Sight 機能は、あなたの目を Vision Pro のディスプレイ上に表示する。そうすることで、周りの時間はあなたの目を見ながら会話することが可能になる。もし、あなたが Vision Pro を完全没入モードで使っていて、外の様子が見えていない場合は、目を表示せず、周りの人に周りが見えていないことを教えてくれる。

空間再現写真とビデオは、Vision Pro の 3D カメラを使って撮る写真・ビデオ。撮影したシーンがそのままに再現されるように見える... らしい。

あとがき

今年の WWDC キーノートは盛り沢山だった。Vision Pro は数年振りの「One more thing...」として発表された。未来感のあるデバイスなので使ってみたい。でも、値段が値段なので、来年買えるかどうか分からない。

2022-09-08

Apple イベント Far out で新 Apple watch, AirPods, iPhone が発表された

2022-09-08 (木) 02:00、Apple はイベント Far out を開いて新型 Apple Watch と AirPods Pro、そして新 iPhone の発表を行なった。

今回発表された新製品は次の通り:

  • Apple Watch Series 8
  • Apple Watch SE (第2世代)
  • Apple Watch Ultra
  • AirPods Pro (第2世代)
  • iPhone 14 / iPhone 14 Plus
  • iPhone 14 Pro / iPhone 14 Pro Max

各プロダクトについて簡単にまとめる

Apple Watch Series 8

Apple Watch Series 8 が発表された。色はアルミニウム・モデルがミッドナイト、スターライト、シルバー、(PRODUCT) RED の 4 色展開; ステンレススチール・モデルはシルバー、ゴールド、グラファイトの 3 色展開。チタニウム・モデルは発売されなくなった (後述の Apple Watch Ultra がチタニウム・モデルで提供)。予約開始は 2022-09-08、販売開始は 2022-09-16。

Apple Watch Series 8 では皮膚温センサーが追加された。いわゆる体温計センサー。センサーは 2 つ搭載される。1 つは背面クリスタル部分に、もう 1 つはディスプレイのすぐ下に。2 つセンサーで外部環境の偏りを減らし精度を高めるという。センサーの精度は 0.1 度単位。

皮膚温センサーは周期記録アプリと連携して、女性の基礎体温の測定を行なってくれる。また、体温情報から推定される過去の排卵日や生理不順について通知を飛ばしてくれるようになる。

Apple Watch Series 8 ではジャイロスコープと加速度センサーもアップデートされた。加速度センサーは最大 256G の加速度まで検出が可能なものに変更されている。

これらの新しいセンサーを使って、車の衝突事故検出が可能になる。転倒検出機能と同じように、車の衝突事故に遭ったら Apple Watch が緊急通報サービスに連携をしてくれる。対象となるのは走行中のみで、事故の種類は正面衝突・側面衝突・追突・横転をサポートする。

イベントでは、watchOS 9 の新機能も 2 つ発表された。

1 つ目は低電力モード。起動する機能を限定することで、通常最大 18 時間しか保たないバッテリーを、最大 36 時間まで保つようにする。起動する機能はアクティビティの記録や転倒検出など。watchOS 9 を搭載した Series 4 以降の Apple Watch で利用可能になる。

2 つ目は国際ローミング対応。セルラー版の Apple Watch が海外でも通話可能になる。利用するには iPhone のローミング・プランに Apple Watch を追加する。対応する通信事業会社のロゴの中に、日本の SoftBank があった。au と DoCoMo は対応するかどうか分からない。watchOS 9 を搭載した Series 5 以降の Apple Watch で利用可能になる。

Apple Watch SE (第2世代)

Apple Watch SE の第2世代が発表された。色はシルバー、ミッドナイト、スターライトの 3 色展開。予約開始は 2022-09-08、販売開始は 2022-09-16。

チップは Series 8 と同じ S8 チップ。背面を再設計してナイロン複合材で作るようにした。

Apple Watch Ultra

Apple Watch Ultra が発表された。通常利用の Apple Watch から一歩進んで、より苛酷な環境での業務やスポーツに対応したモデル。チタニウム製のみの提供。カラー展開なし。GPS + Cellular モデルのみ (GPS モデルは提供なし)。予約開始は 2022-09-08、販売開始は 2022-09-23。価格は 124,800 円 (税込)。

Apple Watch Series 8 との違いは次の通り:

  • 49 mm ディスプレイ
  • 大きなデジタルクラウンと突出したサイドボタン
  • アクションボタン
  • デュアル・スピーカー
  • 3 マイクアレイ
  • 2周波 GPS
  • 水温センサー搭載の水深計
  • 防水 (WR100 + EN13319)
  • 36 時間バッテリー

ディスプレイ・サイズは Series 8 の 45mm より大きな 49 mm。

デジタルクラウン、サイドボタンの変更は手袋をしたままでも操作しやすいように、とのこと。アクションボタンはサイドボタンと逆側の位置に新しくついたボタン。カスタマイズ可能で、ワークアウトを起動するなどといったことが可能になる。

スピーカーにはサイレン機能が追加される。アクションボタン長押しで、86 デシベル (180 m 先にも届く) の音を出す。

Series 8 では 1L GPS のみを使っているところ、Ultra では最新の 5L GPS と従来の 1L GPS を使う 2 波 GPS に対応。より精度の高い位置情報を取得する。

防水は Series 8 の 50m を上回る 100m 防水。ダイビングの国際技術標準規格である EN13319 に準拠。水温センサー搭載の水深計が追加され、水の中に入ると自動的に水深・水中にいる時間・水温を自動計測する。Huish Outdoors 社と Apple が協同開発したスキューター・ダイビング用アプリ Oceanic+ アプリが今秋後半リリース予定。

バッテリーは Series 8 の 18 時間の倍の 36 時間。今秋後半公開予定のバッテリー最適化設定を使うことで、最大 60 時間まで伸ばすことが可能。

バンドは目的別に 3 種用意。探検化向けのアルパインループ、海向けのオーションバンド、持久系アスリート向けに軽く作られたトレイルループ。

AirPods Pro (第2世代)

AirPods Pro の第2世代が発表された。予約開始は 2022-09-09、販売開始は 2022-09-23。価格は 39,800 円 (税込)。

AirPods Pro 第1世代との違いは次の通り:

  • H2 チップ
  • アクティブノイズキャンセリングの強化
  • 6 時間バッテリー

充電ケースにもアップデートがある:

  • U1 チップ
  • 30 時間バッテリー
  • Apple Watch の充電器に対応
  • ケース横にストラップループ

AirPods Pro 第2世代では、ノイズキャンセリングの外部音取り込みモードに適応型環境音除去機能が付く。これは工事音などの環境騒音に限定したノイズキャンセリング。アクティブノイズキャンセリングは、第1世代と比べて最大2倍良くなったと説明があった (どういう基準で2倍なんだろ?)。

また、イヤーチップに XS サイズが新登場。より小さな耳の人へも、イヤーチップの対応の幅が広がる。

充電ケースに付いたU1チップは、探すアプリでの「正確な場所を見つける」に対応する。

iPhone 14 / iPhone 14 Plus

iPhane 14 および iPhane 14 Plus が発表された。色はミッドナイト、スターライト、ブルー、パープル、(PRODUCT) RED の 5 色展開。ディスプレイ・サイズは iPhane 14 が 6.1 インチ、iPhone 14 Plus (新モデル!) が 6.7 インチ。iPhone 14 は 2022-09-09 予約開始、2022-09-16 販売開始; iPhone 16 Plus は 2022-09-09 予約開始、2022-10-07 販売開始。価格は 119,800 円 (税込) から。

主な仕様および新機能は次の通り:

  • ディスプレイ: Super Retina XDR ディスプレイ
  • チップ: A15 Bionic
  • バックカメラ: メインカメラ 12MP + 超広角カメラ 12MP
  • フロントカメラ: フロントカメラ 12MP + TrueDepth カメラ
  • ネットワーク: 5G + eSIM
  • ジャイロスコープ (UPDATE): ハイダイナミックレンジに対応
  • 加速度センサー (UPDATE): 256G まで測定可能に
  • 通信衛星対応 (NEW!)

チップは iPhone 13 と同じ A15 Bionic。Apple Watch でも導入された衝突事故検出機能に対応する。また、通信衛星を使った緊急 SOS が利用可能になる。

US モデルでは物理 SIM スロットが廃止され、eSIM オンリーになる。

衝突事故検出機能

マイク、気圧計、GPS、そしてアップデートされたジャイロスコープと加速度センサーを使って車走行中の衝突事故を検出する。

衛星経由の緊急 SOS

通信衛星を使って緊急 SMS を送信する。SMS といっても標準の SMS 送受信プロトコルは使用しない。専用のショートテキスト・アルゴリズムが使われ、送るメッセージも選択式の Q&A を使ってシンプルなやり取りしか行なわない。とはいえ、送信された情報は緊急サービスに通信衛星を使って適切に届けられる。

iPhone に通信衛星用の大きなアンテナは付けられない。そこで専用のアプリが提供される。このアプリは通信衛星のある位置をユーザーに教えてくれる。ユーザーはアプリに従って通信衛星のある方向に iPhone を向けることで、通信衛星との接続を行なう。このサービスは US とカナダで 2022 年 11 月から開始される。最初の 2 年間は無料で提供とのこと。

iPhone 14 Pro / iPhone 14 Pro Max

iPhane 14 Pro および iPhane 14 Pro Max も発表された。色はスペースブラック、シルバー、ゴールド、ディープパープルの 4 色展開。iPhone 14 Pro および iPhone 14 Pro Max の予約開始は 2022-09-09、販売開始は 2022-09-16。価格は 149,800 円 (税込) から。

主な仕様および新機能は次の通り:

  • ディスプレイ: Super Retina XDR ディスプレイ + 常時表示ディスプレイ
  • チップ: A16 Bionic
  • バックカメラ: メインカメラ 48MP (NEW!) + 超広角カメラ 12MP + 望遠カメラ 12MP
  • フロントカメラ: フロントカメラ 12MP + TrueDepth カメラ
  • ダイナミック・アイランド (NEW!)
  • ネットワーク: 5G + eSIM
  • ジャイロスコープ (UPDATE): ハイダイナミックレンジに対応
  • 加速度センサー (UPDATE): 256G まで測定可能に
  • 通信衛星対応 (NEW!)

チップは A16 Bionic。ディスプレイは常時表示ディスプレイに対応。メインカメラが 12MP から 48MP に向上。ノッチ部分が島状になり機能が追加。ダイナミック・アイランドと呼ばれる。

常時表示ディスプレイ

iPhone のディスプレイが常時表示ディスプレイになった。従来の画面オフ時にロック画面が (少し薄暗い発光で) 表示され続ける。この間、ディスプレイはリフレッシュレートを 1 Hz まで落とすことで、電力の消費を抑える。ロック画面には iOS 16 で導入されたロック画面のウィジェットも表示される。

カメラ

バックカメラのメインカメラが 12MP から 48 MP に変更される。また、疑似的な 2 倍望遠機能を提供する。

フラッシュがカメラの焦点距離と連続するようになり、加えて 2 倍明るくなった。

ダイナミック・アイランド

ノッチが小さくなり大き目のパンチホールのようになっただけでなく、その周囲を iOS の補助的な情報通知・アクション用のパーツとして提供する。これをダイナミック・アイランドと言う。

通知などがダイナミック・アイランドが広がるようにアニメーションして表示される。各アプリのアクティビティー (AirPods の接続状況やミュージックアプリの再生状況、タイマーの状態など) は、ダイナミック・アイランドが少し横に広がった形で、情報を表示するようになる。これをロングプレスすると、ダイナミック・アイランドが広がり、ちょっとしたウィジェットのようにその場でアプリ操作が可能になる。

複数のアプリが同時にバックグラウンドで起動していたら、ダイナミック・アイランドは 2 つの要素に分裂する。

あとがき

iPhone 14 Pro に導入されたダイナミック・アイランドは通知画面やコントロール・センターが刷新された時以来の大きな変更になると思う。音楽を聞きながら、タイマーをかけながら、etc. 最近のスマホではメインのアプリの他に別の作業をすることも多いので、状況の把握・アプリのコントロールが一手間で出来るようになるのは有難い。とてもたのしみ。

2022-06-07

WWDC 2022 で iOS 16, iPadOS 16, macOS Ventura, watchOS 9, 新 MacBook が発表された

2022-06-07 (火) 02:00、Apple は WWDC のキーノートを放送して、各種新 OS (iOS 16, iPadOS 16, macOS Ventura, watchOS 9) と新デバイス (M2 チップ, MacBook Air, MacBook Pro) を発表した。

iOS 16

まずは iOS 16 の新機能。

ロック画面

ロック画面が刷新される。新しいロック画面は自分でカスタマイズできるようになる。長押しで編集画面が起動し、時刻のフォントや色を変更できるようになる。用意されているロック画面の中には、選択した写真が 1 日中シャッフルされる「写真シャッフル」、1 枚だけ写真を選択してフィルターをかけたりできる「写真」、天気アプリと同じように現在の気象状況をアニメーションで表示する「天気」、Apple Watch のアストロノミー文字盤と同じように地球や月を表示する「アストロノミー」などがある。

加えてロック画面にウィジェットを配置できるようになる。ウィジェットは Apple watch のコンプリケーションのように配置領域が決まっている。その中なら、ドラッグで移動可能。開発者は WidgetKit でロック画面に表示するウィジェットを開発できる。

これらのロック画面は複数作成可能。作成したロック画面は長押ししてスワイプするとで切り替えられる。

ライブアクティビティという新しい機能も追加される。現在の状況を表示・コントロールする専用ウィジェットのようなもの。ライブアクティビティを使って、ミュージック・アプリの再生コントロールをロック画面に表示する、なんてことが可能になる。大量のプッシュ通知を表示する代わりに、ライブアクティビティで表示する (例えばバスケのスコアをプッシュ通知で飛ばしていた場合とか) なんて利用例も挙げられていた。

集中モード

前述のロック画面と融合する。1 つのロック画面につき 1 つの集中モードを紐付けられるようになる。ロック画面を選択すると自動的に集中モードも動き出す。

集中モードフィルターなる機能も提供される。集中モードをアプリにも適用するというもの。Safari で「仕事」の集中モード中に仕事関連のタブだけ表示するという利用方法が挙げられていた。

メッセージ・アプリ

送信したメッセージの編集・削除が送信直後に限って可能になる。また、スレッドを未読に戻すことが可能になる。

音声入力

音声入力を始めてもキーボードが閉じないようになる。音声入力での誤入力をキーボードからすぐに修正できるようになる。

句読点の入力も自動で行なうようになる。もう「。」を入力するのに「マル」とか言わなくても良い。絵文字の入力も対応する。

テキスト認識表示 (Live Text)

ビデオ動画でもテキスト認識表示が可能になる。ビデオを一時停止した状態で、テキスト認識表示を呼び出せる。

テキスト認識表示用の Live Text API が提供されるので、アプリの中から直接 Live Text が使えるようになる。

ウォレット・アプリ

メッセージアプリでキー情報を送ると、キーをウォレットに追加できるようになる。

おそらくアメリカ限定 (で日本に来るのは先) で iPhone の Tap to pay を使って非接触型決済を行なえるようになる。つまり、Square みたいな端末の代わりを iPhone 本体がやってくれる。それから、Apple Pay で後払い (6 週間の 4 回払い) に変更することができるようになる。最後に、Apple Pay で注文の追跡が可能になる。

マップ・アプリ

複数地点を経由する経路案内が可能になる。登録できる経由地は最大 15 か所。

マップ・アプリとウォレット・アプリが連携。マップ・アプリで経路確認中に交通系カードの料金が足りなかったら、ウォレット・アプリの中から入金することが可能になる。

最後に MapKit が大幅にアップデート。俯瞰表示とか Look Around とか、ダークモードに対応した地図をアプリ内マップから使えるようになる。

ファミリー共有

新デバイス設定時に iPhone を近付けると、家族用アカウント作成の画面が現れ、初めから適切なペアレンタルコントロールを設定できるようになる。

子供から利用時間の延長やアプリのインストール要請のメッセージを受け取った時、メッセージ・アプリ内で対応が可能になる。

写真アプリ

iCloud 共有写真ライブラリーが提供される。今までは iCloud の共有「アルバム」があった。それのライブラリー版。共有された写真の権限は全員が等しく持ち、全員に同期される。編集・削除・キャプションの記入・キーワードの追加などが同期される。共有写真ライブラリーに入れる写真は、自分のライブラリーの全てを選ぶこともできるし、手動で設定することも可能。手動で入れる場合、カメラ・アプリで撮影後に移動させることもできる。

セーフティー・チェック

DV などから逃げている人などを想定した機能。探すアプリの位置情報共有を停止したり、全デバイスの iCloud でサインアウントを実行できたりする。

ホーム・アプリ

iOS 16 でリデザインされる。部屋タブがなくなる。ホームタブが充実し、ホームタブから各部屋にアクセスできるようになる。新しいカテゴリー (気功・照明・セキュリテティーなど) が用意される。これらはアプリ上部に表示される。

アクセサリーのアイコンと色が大きく追加される。

CarPlay

2023 年後半に登場する予定の新 CarPlay についてチラ見せあった。新しい CarPlay は車とより密接に連携する。車載のディスプレイに CarPlay の出力を行なうことができるようになる。逆に車から計器の情報などを受け取って、速度・回転数・気温などを表示・操作できるようになる。iPhone から車のラジオやエアコンの操作ができるようになる。

Personalized 空間オーディオ

iPhone の TrueDepth カメラを使って耳を撮影。その情報を使って、パーソナライズされた空間オーディオのプロファイルを作成する。

クイックノート

iPad からしか作れなかったクイックノート。iOS 16 からは iPhone でもクイックノートの作成が可能になる。

iPadOS 16

天気アプリ

iPad にも天気アプリが提供される。

共同制作機能

共有シートから共同制作用のリンクを送れるようになる。このリンクを作って共同制限するようになると、その状況をメンバー間で確認できるようになる。共同制作しているメンバーと簡単に FaceTime を開始することも可能になる。

対応アプリは、メモ・Safari・Pages・Numbers・Keynote・ファイル・リマインダーアプリなど。開発用 API も用意されるので、サードパーティー・アプリでも共同制限機能は使えるようになるはず。

Freeform アプリ

Apple 製のホワイトボード・アプリが提供される。

デスクトップクラス・アプリ

iPad の動きがよりデスクトップ OS に近くなる。

システム全体を通しての取り消しややり直し、カスタマイズ可能なツールバーの提供など、インラインで動作する検索と置換など。ファイル・アプリではメニューからファイルの複製・名称変更・書き出し・プリントなどがサポートされ、拡張子の変更やフォルダーサイズの表示が可能になる。

ステージマネージャー

macOS および iPad で提供される新しいマルチタスクの仕組み (M1 を搭載した iPad Air, M1 を搭載した iPad Pro で利用可能)。

利用するアプリをグループ化して管理できるようになる。利用中のグループのアプリは、画面のセンターに重ねて表示される。利用外のグループはセンターから見て左側に並べられる。

利用中アプリの重ね方には自由度があって、全く重ねないようにすることもできれば、アプリのウィンドウ・サイズを小さくして重ねることもできる。アプリのサイズは従来より自由度が高いものの、iPad では (Mac のように) 完全に自由というわけではない。

外部ディスプレイもサポートされる。外部ディスプレイと iPad を合わせて、同時に最大 8 つのアプリを扱うことができる。

watchOS 9

文字盤

4 つの新しい文字盤が追加される。

アストロノミー文字盤。大きなディスプレイを活かすように刷新された。世界中の現在の雲量を表示する。

ルナー文字盤。大陰暦 (中国歴、イスラム歴、ユダヤ歴) に対応する。

プレイタイム文字盤。アーティスト Joi Fulton 氏のデザインによる。デジタル数字がアニメーションする; タップすると数字が跳ね回る、手首を下ろすと数字が眠る。

メトロポリタン文字盤。Digital Crown を回すと、文字盤の数字がダイナミックに伸びる。

ポッドキャスト・アプリ

「検索」と「今すぐ聴く」が追加された。今までは iPhone のポッドキャスト・アプリで登録したポッドキャストしか聞くことができなかったけど、これからは Apple Watch 単体でポッドキャストを見つけることが可能になる。

ワークアウト

ランニング・ワークアウトに 3 つの指標 (上下動・歩幅の長さ・接地時間) が追加される。新しく増えた指標にアクセスできるよう、UI も変更。Digital Crown を回すと測定値の新しい表示を見ることができるようになる。

カスタム・ワークアウトの作成が可能になる。ここで言うカスタム・ワークアウトは距離と時間のインターバルを設定したワークアウトの作成のこと。閾値を設定して、閾値を下回ったり上回ったりしたらアラートを投げる、といったカスタマイズも可能とのこと。

マルチスポーツワークアウト機能が追加される。複数のワークアウトを自動的に切り替えるワークアウト。センサーを使って、次のワークアウトに移るタイミングを感知する。

フィットネス・アプリ

今までフィットネス・アプリは Apple Watch を持っている iPhone にしかインストールされなかった。iOS 16 からは、Apple Watch を持っていなくてもフィットネス・アプリが使えるようになる。

睡眠アプリ

睡眠ステージを分析・記録できるようになる。睡眠ステージは覚醒・レム・コア・深いの 4 つ。

Apple Heart and Movement Study の参加者は [[リサーチ・アプリ (Apple)]] で睡眠ステージのデータを提供できる。

心電図アプリ

心房細動履歴 (AFib History) により、心房細動が起きていた時間を記録する。ヘルスケア・アプリでこれらの記録を確認できる他、PDF で出力も可能。医師に情報共有するのが楽になる。

この機能は間もなく FDA の承認を取得予定とのこと。

服薬アプリ

服薬の記録を取るアプリが新しく追加される。服薬時間に通知を受け取れる他、服薬のスケジュールをコンプリケーションから確認できる。

服用する薬に相互作用がある場合、薬を登録する時に通知を取ばしてくれる。これは薬同士の相互作用の他に、アルコールとの相互作用についても調べてくれる。情報ソースは大手医療出版社のエルゼビア社。

M2チップ

M1チップの後継チップ、M2チップが登場する。

M2チップのスペックは次の通り:

  • メモリー・コントローラー: 100GB/s の帯域幅
  • ユニファイド・メモリー: 最大 24 GB
  • CPU: 8 コア CPU (4 高性能コア + 4 高効率コア)
  • GPU: 10 コア GPU (M1チップより 2 コア多い)
  • 次世代のニューラルエンジンとメディアエンジン

新 MacBook

M2チップを搭載する MacBook Air と MacBook Pro が発表された。

MacBook Air

デザインが刷新された。色は 4 色展開 (シルバー、スペースグレイ、スターライト、ミッドナイト)

  • 厚さ: 11.3mm
  • 重さ: 1.24kg
  • MagSafe: あり!
  • Thunderbolt ポート: 2 つ
  • ディスプレイ: Liquid Retina 13.6 インチ・ディスプレイ
  • カメラ: 1080p FaceTime HD カメラ
  • オーディオ・ジャック: ハイインピーダンスのヘッドフォンに対応
  • マイク: 3 マイクアレイ
  • スピーカー: 4 スピーカーサウンドシステム (空間オーディオに対応)
  • キーボード: Magic Keyboard + TouchID
  • タッチパッド: 感圧タッチパッド
MacBook Pro 13 インチ

デザインはそのまま。M2チップ (8コアCPU+10コアGPU) 搭載により、メモリーの最大搭載量は 24 GB。ストレージは最大 2 TB。

macOS Ventura

ステージマネージャー

iPadOS 16 の説明を参照。

メール・アプリ

メール送信の取り消し、送信時間のスケジュールが可能になる。

フォローアップ提供機能が加わる。返信を受け取っていない場合、追跡するよう自動的にリマインドする。

Safari

共有タブグループ機能が追加される。グループタブを他のメンバーと共有できる。編集権は全員に与えられる。

パスキー

パスワードを置き換える新しい仕組み「パスキー」が発表された。

パスキーは TouchID/FaceID を使って作成される。そしてパスキーを作成すると、そのサイトでしか使えない固有の電子鍵が作られる。

Hand Off

FaceTime で Hand Off が利用可能になる。iPhone で受けた FaceTime を Mac や iPad に引き継げるようになる。

連携カメラ

iPhone のカメラをウェブカメラとして利用できるようになる。

Mac が自動的に iPhone を検知。iPhone のカメラを使うことでセンターフレームやスタジオ照明機能がどの Mac でも実現可能になる。

連携カメラを使うとデスクビューという機能が使えるようになる。iPhone の超広角カメラを使って、正面と同時に手元の机を撮影する機能。

連携カメラは FaceTime だけでなく、Zoom や Microsoft Teams でも利用可能になるとのこと。

専用スタンドを Belkin と開発中で、2022 年末リリース予定。

あとがき

iOS 16, iPadOS 16 では大きな変更は見えないように思う。とても安定的なアップデートになりそう。

2022-03-09

Apple イベントで新 iPhone SE, 新 iPad Air, M1 Ultra, Mac Studio と Studio Display が発表された。

2022-03-09 (水) 03:00、Apple はイベントを開いて iPhone、iPad、Mac に関わる新製品を発表した。

iPhone の発表は 2 つ。まず iPhone 13 モデルに新色が追加された。そして第 3 世代となる iPhone SE が発表された。iPad の発表では第 5 世代となる iPad Air が発表された。Mac 関連では M1 チップ・シリーズのフラッグシップ・モデルとして M1 Ultra が発表され、それを搭載する新しいスタンドアローン型の Mac である Mac Studio が発表された。同時に Mac Studio で使えるディスプレイ Studio Display が発表された。

以下、簡単に概略をまとめてみる:

iPhone 13 の新色

iPhone 13 系に新色が追加された。

  • iPhone 13: グリーン
  • iPhone 13 Pro: アルパイン・グリーン

これで iPhone 13 は 6 色展開 (ピンク、ブルー、ミッドナイト、スターライト、(PRODUCT) RED、(新)グリーン)、iPhone 13 Pro は 5 色展開 (シルバー、ゴールド、グラファイト、シエラブルー、(新)アルパイングリーン) となる。新色はいずれも 2022-03-11 (金) から予約開始、2022-03-18 (金) 発売。

iPhone SE (第 3 世代)

新しい iPhone SE が発表された。色展開は 3 色 (ミッドナイト、スターライト、(PRODUCT) RED)。ストレージは 3 タイプ (64 GB, 128 GB, 256 GB)。価格は 57,800 円 (税込) から。2022-03-11 (金) 午後 10 時から予約開始、2022-03-18 (金) 発売。

iPhone SE (第 2 世代) からの変更点は次の通り:

  • チップ: A13 Bionic → A15 Bionic
  • モバイル: 4G LTE → 5G

A13 Bionic は 6 コア CPU・4 コア GPU・8 コア Neural Engine。対して A15 Bionic は 6 コア CPU・4 コア GPU・16 コア Neural Engine。

ディスプレイ・サイズは変わらず 4.7 インチ。細かい所では重量が第 2 世代より 4g 軽くなって 144g になった。

A15 Bionic にアップデートされたからか、写真撮影でスマート HDR 4 に対応するようになり、動画撮影では 1080p スローモーションビデオ (120fps) に対応するようになった。ビデオ再生時間も 8 時間から 10 時間に伸びている。

iPad Air (第 5 世代)

新しい iPad Air が発表された。色展開は 5 色 (スペースグレイ、ピンク、パープル、ブルー、スターライト)。ストレージは 2 タイプ (64 GB, 256 GB)。価格は 74,800 円 (税込) から。2022-03-11 (金) 午後 10 時から予約開始、2022-03-18 (金) 発売。

iPad Air (第 4 世代) からの変更点は次の通り:

  • チップ: A14 Bionic → M1
  • モバイル: 4G LTE → 5G
  • フロントカメラ: 7MP FaceTime HD カメラ → 12MP 超広角カメラ

A14 Bionic は 6 コア CPU・4 コア GPU・16 コア Neural Engine。M1 は (A14 Bionic と比較するのはおかしいかもしれないけれど) 8 コア CPU・8 コア GPU・16 コア Neural Engine・8 GB のユニファイド・メモリー。

ディスプレイはサイズ変わらず 10.7 インチの Liquid Retina ディスプレイ。フロントカメラがセンターフレームに対応するようになる。

TouchID がトップボタン内蔵、コネクターがUSB-C ポート、Apple Pencil 2 と Magic Keyboard が利用可能、というのは第 4 世代から変わらず。

M1 Ultra

M1 チップシリーズの新チップ M1 Ultra が発表された。後述の Mac Studio で採用される。

M1 Ultra は M1 Max のダイを 2 つ繋げたもの。Apple はこれを Utrla Fusion と呼んでいる。

M1 Max は最大で 10 コア CPU・32 コア GPU・16 コア Neural Engine・64 GB のユニファイド・メモリーといった構成だった。M1 Ultra はこの M1 Max が 2 つ繋がっているので 20 コア CPU・64 コア GPU・32 コア Neural Engine で 128 GB のユニファイド・メモリーとなる。

Mac Studio

高効能な Mac mini、もしくはコンパクト・サイズな Mac Pro という位置付けの Mac Studio が発表された。iMac のようにディスプレイ一体型ではない。チップは M1 Max と M1 Ultra が選択できる。M1 Max モデルは 10 コア CPU・24 コア GPU・16 コア Neural Engine・32 GB ユニファイド・メモリー構成で価格は 249,800 円 (税込) から。M1 Ultra モデルは 20 コア CPU・48 コア GPU・32 コア Neural Engine・64 GB ユニファイド・メモリー構成で価格は 499,800 円 (税込) から。どちらのモデルも GPU を 36 コア/64 コアに、ユニファイド・メモリーを 64GB/128GB にオプションでアップグレード可能。予約開始は今日からで、2022-03-18 (金) 発売。

最小構成の主な特徴は次の通り:

  • サイズ: 19.7 cm x 19.7 cm x 9.5 cm
  • 重さ: 2.7 kg / 3.6 kg
  • チップ: M1 Max / M1 Ultra (アップグレード可)
  • メモリー: 32 GB / 64 GB (アップグレード可)
  • ストレージ: 512 GB / 1 TB (アップグレード可)
  • 背面
    • Thunderbolt 4 ポート x4
    • 10 Gb イーサネット
    • USB-A x2
    • HDMI x1
    • 3.5 インチ・ヘッドフォン・ジャック
  • 前面
    • USB-C ポート x2 / Thunderbolt 4 ポート x2
    • SDXC カードスロット
  • ネットワーク: WiFi 6
  • Bluetooth: 5.0

チップに M1 Max を選ぶか M1 Ultra を選ぶかによって、前面のポートの種類が変わるので注意。M1 Max を選ぶ場合は USB-C ポートが 2 つになって、M1 Ultra を選ぶ場合は Thunderbolt 4 ポートが 2 つになる。

Studio Display

Mac Studio と一緒に Studio Display が発表された。Mac Studio 以外の Mac でも利用可能 (対応している Mac の詳細は Apple のサイトを参照してください)。27 インチの 5K ディスプレイで、A13 チップ搭載によりセンターフレームや空間オーディオ、Siri などの処理をディスプレイ自身が行なう。価格は 199,800 円 (税込) から。予約開始は今日からで、2022-03-18 (金) 発売。

主な仕様は次の通り:

  • ディスプレイ: 5K Retina (5,120 x 2,880; 218ppi); P3, TrueTone 対応
  • サイズ: 27 インチ、62.3 cm x 47.8 cm x 16.8 cm
  • 重さ: 6.3 kg
  • カメラ: 12MP 超広角カメラ (センターフレーム対応)
  • スピーカー: 6 つ (2 ツイーター、4 ベース)、空間オーディオ対応
  • マイク: アレイマイク (Hey, Siri に対応)
  • 背面
    • Thunderbolt 3 (USB-C) ポート x1
    • USB-C ポート x3

HDMI ポートは持たない。

オプションが豊富で、ディスプレイには Nano-texture ガラスを選択可能。標準のスタンドは 30 度の傾き調整に対応しているけれど、傾きと高さを調整できるスタンドと VESA マウントできるアダプターをオプションで選択することができる。

あとがき

iPad Air に M1 チップがのるとは思っていなかったし、M1 Ultra なる新チップが発表されるとは思っもみなかったので、良い意味で驚きのあるイベントだった。今回のイベントは Peak Performance と銘打っていたけれど、なるほど M1 Ultra はその名に恥じない性能に見えた。

これで M1 チップに刷新されていない Mac は Mac Pro だけになった。Apple はどんなアップデートをかけてくるのか、楽しみ。

2021-10-19

Apple イベントで新 Air Pods, MacBook Pro が発表された

2021-10-19 (火) 02:00、Apple はイベントを開いて新型 Air Pods と新 MacBook Pro の発表を行なった。

今回のイベントでは 2 つのテーマについて、次の新製品・アップデートの発表があった:

  • Apple Music
    • 新プラン Voice Plan
    • 新色 HomePod mini
    • 新製品・新 AirPods
  • Macbook Pro
    • 新チップ M1 Pro / M1 Max
    • 新製品・MacBook Pro 14 インチ
    • 新製品・新 MacBook Pro 16 インチ

Apple Music

Voice Plan

Apple は Siri 専用の Apple Music プランを発表した。価格は 480 円/月。対象国は日本を含めた 17 か国 (オーストラリア、オーストリア、カナダ、中国、フランス、ドイツ、香港、インド、アイルランド、イタリア、メキシコ、ニュージーランド、スペイン、台湾、イギリス、アメリカ)。サービス開始は今年秋後半。

Voice プランは Apple Music が提供している全ての楽曲・プレイリストに Siri からアクセス・操作ができる。サポートデバイスは Siri が使える Apple 端末。HomePod は当然のこと、AirPods や iPhone, iPad そして CarPlay からも Apple Music にアクセスできる。ただし、Apple 端末でないもの (例えば Sonas とかは NG っぽい)。それから Voice プランでは、個人プランが提供しているロスレス・オーディオや空間オーディオ、歌詞の表示機能、ミュージックビデオへのアクセスは出来ない。

Voice プランが加わることで、Apple Music は 3 つのプランが提供されることになる:

  • Voice プラン (480 円/月、Siri からのみアクセス; 空間オーディオ、ロスレス・オーディオ、歌詞、ミュージックビデオ非対応)
  • 個人プラン (980 円/月)
  • ファミリープラン (1,480 円/月、最大 6 つのファミリー・アカウントを追加可)
HomePod mini の新色モデル

HomePod mini にイエロー、オレンジ、ブルーの新色モデルが追加された。これで HomePod mini は従来のホワイトとスペースグレイと合わせて 5 色展開となる。新色モデルの発売は 11 月から。

AirPods 第 3 世代

AirPods 第 3 世代が発表された。予約は今日から、発売は 2021-10-26 (火)。価格は 23,800 円 (税込)。

AirPods 第 3 世代は AirPods Pro のみが提供していた多くの機能をサポートする。

  • 空間オーディオ (ダイナミック・ヘッドトラッキング含む) 対応
  • アダプティブ EQ 対応 (耳の形や装着状態に応じて最適なイコライザーをかける機能)
  • 探すアプリ対応

AirPods Pro との差別化はノイズ・キャンセリングだけになりそう。

また、第 3 世代 AirPods は第 2 世代と比べて感圧センサーによるコントロールに変更され、IP4X 相当の防沫に対応、バッテリーも 1 時間伸びて 6 時間再生可能になる。ドライバーも新しくなった。

MacBook Pro

新チップ M1 Pro / M1 Max

Apple が新しい SoC チップ M1 Pro と M1 Max を発表した。従来の M1 との違いは次の通り:

M1M1 ProM1 Max
CPU8 コア (高性能コア x4, 高効率コア x4)10 コア (高性能コア x8, 高効率コア x2)
GPU8 コア16 コア32 コア
最大メモリー16 GB32 GB64 GB
NeuralEngine16 コア

また M1 Pro/Max は H.264, HEVC, 動画(ProRes 含む)のエンコード/デコードに対応した MediaEngine を備える。M1 Max の MediaEngine は M1 Pro のそれに比べてビデオエンコーディングが 2 倍高速で、ProRes アクセラレーターが 2 つに増えている。

14 インチ MacBook Pro

13 インチ MacBook Pro の後継として 14 インチ MacBook Pro が発表された (13 インチ MacBook Pro は M1 チップで引き続き発売)。予約は今日からで、発売は 2021-10-26 (火)。価格は 239,800 円 (税込) から。

14 インチ MacBook Pro は MacBook Pro のメジャー・アップデートとなる。主な変更は次の通り:

  • 厚さ 15.5mm
  • 重さ 1.6kg
  • チップは M1 Pro もしくは M1 Max から選択可
  • Pro Motion 対応の Liquid Retina XDR ディスプレイ (120 Hz サポート)
  • iPhone のようにノッチを採用
  • 1080p FaceTime HD カメラ
  • MagSafe が復活 (MagSafe 3)
  • HDMI ポートが復活
  • SD カードポートが復活
  • 3 つの Thunderbolt 4 ポート
  • TouchBar を廃止して物理キーボードが復活 (TouchID は継続)
  • ノイズフロアを 60% 低下させたマイク
  • 空間オーディオに対応した 2 ツイーター、4 フォースキャンセリングウーファー
  • バッテリーはビデオ再生で 17 時間 (旧モデルより 7 時間延長)
  • 急速充電 (30 分で 50%) に対応

M1 Pro なら 2 台の Pro Display XDR に、M1 Max なら 3 台の Pro Display XDR + 1 つの 4K ディスプレイに接続可能。

16 インチ MacBook Pro

16 インチモデルも 14 インチモデルと同様予約は今日からで、発売は 2021-10-26 (火)。価格は 299,800 円 (税込) から。

基本構成は 14 インチモデルと同様。違いは次の通り:

  • 厚さ 16.8mm
  • 重さ 2.1kg
  • バッテリーはビデオ再生で 21 時間 (旧モデルより 10 時間延長)

あとがき

Apple Music 関連で今日発表されるかな? と思っていたけど発表されなかったものもある。HomePod の「声の識別」の日本語対応。今年秋に複数の国で対応を行なうと言っていたけど発表はなかった。日本語で声の識別ができるようになると、Siri を頼んだ人のプレイリストが再生できるようになるはず。あと、少し前に Apple はクラシック音楽専用の音楽ストリーミング・サービスを売収した。このサービスを Apple Music に取り入れるという話だけど、その話も今回は出なかった。近いうちに発表があると嬉しいな。

Mac の方で言うと、M1 Pro 相当のチップが出るのは予想していたけど、M1 Max 相当のチップまで発表されて 64 GB メモリーに対応するとは思わなかった。びっくりした。お値段も良い感じになっている。

2021-09-15

Apple イベントで新 iPad, iPad mini, Apple watch, iPhone が発表された

2021-09-15 (水) 02:20、Apple はイベントを開いて新型 iPad と iPad mini、そして新 Apple watch と iPhone の発表を行なった。

今回のイベントも聴衆なしのビデオ配信形式で行なわれた。

今回発表された新製品・アップデートは次の通り:

  • iPad
  • iPad mini
  • Apple watch series 7
  • Fitness+
  • iPhone 13 / iPhone 13 mini
  • iPhone 13 Pro / iPhone Pro 13 Max

各プロダクト、サービスについて簡単にまとめる。

iPad

第 9 世代の iPad が発表された。色はスペースグレイとシルバーの 2 色展開。ストレージは 64 GB と 256 GB。予約は今日からで、発売開始は 2021-09-24 (金)。価格は 39,800 円 (税込) から。

新しい iPad は A13 Bionic チップを搭載。フロントカメラは 12 MP の超広角レンズにアップデートされ、(今年前半に発表された iPad Pro と同様に) センターフレーム (Center Stage) 機能に対応する。センターフレーム機能は FaceTime ビデオなどで人物が画面の中心に来るよう調整してくれる。今回の発表では、センターフレーム機能が FaceTime ビデオだけでなく Zoom や BlueJeans, Webex などのビデオ通話アプリでも利用可能であること、ビデオの撮影や配信 (TikTok など) でも使えることが紹介された。

ディスプレイは 10.2 インチ。新しく True Tone に対応。部屋の明るさに応じてディスプレイの色温度を調整する。

アクセサリーに目を向けると、Apple Pencil のサポートは第 1 世代で変わらず。コネクターもライトニング端子のまま。ホームボタンは継続され TouchID が採用されている。

iPad mini

第 6 世代 iPad mini が発表された。色はスペースグレイ、ピンク、パープル、スターライトの 4 色展開。ストレージは 64 GB と 256 GB。予約は今日からで、発売開始は 2021-09-24 (金)。価格は 59,800 円 (税込) から。

新しい iPad mini は 2 年振りのアップデート。メジャーアップデートと言って差しつかえない。

画面のボーダーは狭くなり、ホームボタンが廃止された。iPad Air と同じように、トップボタンhから TouchID を使うことができる。

ディスプレイは Retina ディスプレイから Liquid Retina ディスプレイにアップデート。True Tone に対応する。画面サイズは 7.9 インチから 8.3 インチへと拡大。

チップは A15 Bionic。パフォーマンスは CPU で 40%、GPU で 80% の高速化を果たしたと Apple は言っている。

カメラもアップデートされている。バックカメラは 8MP から 12MP に向上し 4K 動画の撮影も可能になる。フロントカメラは 7MP から 12MP の超広角カメラになり、センターフレームに対応する。加えてスピーカーは横向きでステレオ・スピーカーに対応する。

アクセサリーへの対応も進化した。iPad Air/Pro 等と同じようにライトニング・コネクターから USB-C ポートへ変更されている。携帯ネットワークは 5G をサポート。Apple Pencil は第 2 世代が使えるようになる。

あと Smart Folio カバーも新しい iPad mini 向けに刷新される。

Apple Watch

Apple Watch Series 7 が発表された。色はアルミニウム・モデルがグリーン、ブルー、プロダクト・レッド、スターライト、ミッドナイトの 5 色展開; ステンレススチール・モデルはシルバー、グラファイト、ゴールドの 3 色展開; チタニウム・モデルはナチュラルとスペースブラックの 2 色展開。予約開始日は告知されず、今年秋後半発売とだけ発表された。

Apple Watch Series 7 は (Series 4 から数えて 3 年振りに) ディスプレイ・サイズが大きくなる。画面サイズは 20% 大きくなり、ベゼルは 1.7mm にまで細くなった (40% 細くなった)。ウォッチそのものの大きさに大きな変更はなく、今までのバンドがそのまま使える。

Series 7 では大きくなった画面に合わせて、アプリの UI も刷新されるという。各種アプリでボタンが大きくなりタップしやすくなる上、テキスト入力にフルサイズ・キーボードが提供される。

Series 7 用の文字盤も追加される。「輪郭」文字盤は画面の縁一杯に目盛り盤が広がり、手首を上げるとアニメーションが起きる。「モジュラー」文字盤はアップデートされて、大き目のコンプリケーションを 2 つ配置できるようになる。

防塵性能は IP6X 認定を取得。防水性能は WR50。今まで Apple は防水性能を IPX8 のような形で説明していたけど、Series 7 からは WR50 という形で公表するみたい。WR50 は 50m 防水のことかな? いわゆる 5 気圧防水ということで、Apple Watch をつけたまま水泳が出来ますよ、というレベル。

バッテリー性能は今まで通り変わらないとしているが、充電機能に向上が見られる。バッテリー 0% から 80% までの充電時間は 45 分。Series 6 より最大 33% 速く充電できるという。8 時間の睡眠記録には 8 分の充電で十分という嬉しい情報も提供された。

また watchOS 8 の新規能として、ワークアウトの自転車向けアップデートが発表された。これは自転車に乗って移動を開始すると、ワークアウトの開始を促すというもの。現在、屋外のウォーキングやランニングで同様の機能があるけれど、それの自転車対応版といったところか。自転車を停めるとワークアウトも自動的に一時停止になる。それからサイクリングでの転倒検出機能も追加されるという。転倒検出機能は今までもあったけど、サイクリング中の転倒は検出されなかったみたい。歩いてて転ぶのと、自転車で高速移動している時に転倒するのとでは、動きが違うのかな?

Apple Fitness+

Apple Fitness+ の提供国が拡充される; けど日本はまだ対象外。現在提供されているのはオーストラリア、カナダ、アイルランド、ニュージーランド、イギリス、アメリカの 6 か国。秋には更に 15 か国への提供が行なわれる (オーストリア、ブラジル、コロンビア、フランス、ドイツ、インドネシア、イタリア、メキシコ、ポルトガル、ロシア、サウジアラビア、スペイン、スイス、アラブ首長国連邦)。今までは英語圏だけだったけど、ついに英語圏を飛び出す。吹き替えではなく字幕で対応するとのこと (6 言語の字幕が用意される)。

Fitness+ は SharePlay (iOS 15 では未対応; iOS 15.1 以降で対応される予定) を使ったグループワークアウトにも対応する。一緒にワークアウトをやっている人の顔が見えたり、アクティビティリング達成の通知が行なわれるとのこと。

iPhone 13 / iPhone 13 mini

iPhone 13 と iPhone 13 mini が発表された。色はピンク、ブルー、ミッドナイト、スターライト、プロダクト・レッドの 5 色展開。ストレージは 128 GB、256 GB、512 GB。予約開始は 2021-09-17 (金) 午後 9 時から、販売開始は 2021-09-24 (金)。価格は 86,800 円 (税込) から。

iPhone 13 ではノッチが 20% 小さくなる。

チップは A15 Bionic。A14 Bionic と同様に 2 つの高性能コアと 4 つの高性能コアからなる 6 コア CPU で、GPU は 4 コア。

バックカメラでは iPhone 12 Pro Max で導入されたセンサーシフト式の光学式手ぶれ補正を Iphone 13 (と mini) で採用する。動画撮影ではシネマティック・モードという新しいモードが提供される。これは写真撮影におけるポートレート・モードの動画版みたいなもので、主に人物などにピントが合わさり背景が映画のようにボケてくれるというもの。どこにピントを合わせるかは iPhone が全て自動で行なってくれるけど、マニュアルでピントを合わせる場所を指定することも可能。

iPhone 13 ではバッテリー容量が増加する。iPhone 13 mini で (旧同型機種より) 1.5 時間、iPhone 13 で 2.5 時間動作時間が伸びる。バッテリーの伸びはバッテリー容量の伸びだけでなく、ソフトウェア的な改善でも実現されている。Apple はその一例としてスマートデータ・モードを上げた。この機能は 5G の速度が不要な時は LTE に切り替えるという。

iPhone 13 Pro / iPhone Pro 13 Max

iPhone 13 に引き続き iPhone 13 Pro / iPhone 13 Pro Max も発表された。色はシエラブルー、シルバー、ゴールド、グラファイトの 4 色展開。ストレージは 128 GB、256 GB、512 GB、1 TB。予約開始は 2021-09-17 (金) 午後 9 時から、販売開始は 2021-09-24 (金)。価格は 122,800 円 (税込) から。

基本的に iPhone 13 と同様の進化をしていて (ノッチも 20% 小さくなる!)、更に Pro らしい機能強化が図られている。

iPhone 13 Pro に搭載される A15 Bionic チップは 4 コア GPU ではなく 5 コア GPU を搭載する。

iPhone 13 Pro 最大の変化は ProMotion に対応すること。iPad Pro と同様に最大 120 Hz のリフレッシュレートで、動きに変化がない場合は自動的にリフレッシュレートを低くする (最小 10 Hz)。

iPhone 13 Pro のカメラも進化する。バックカメラのうち望遠カメラは光学 2.5 倍から 3.0 倍へ変わり、ナイトモードにも対応する。超広角レンズはマクロ写真撮影をサポートする。今まで以上に近距離 (最短 2 cm!) での撮影が可能になるとのこと。

iPhone 13 Pro でもバッテリー時間の改善が成されている。iPhone 13 Pro で 1.5 時間、iPhone 13 Pro Max で 2.5 時間、動作時間が伸びる。

あとがき

ついに iPhone Pro に ProMotion がやって来る。iPad Pro でヌルヌルな動作感を味わっているので、少し楽しみ。カメラも色々と進化しているけど、ぼくはカメラのことが詳しくないので、よくわからない。マクロ撮影が出来ると、写真撮影がもっと楽しくなるのかな? Apple Watch は画面サイズの変更と充電効率の改善がメインの変更で、新しいセンサーがつくとかはなかった。Series 4 で数 mm 画面サイズが大きくなっただけで、視認性は見違えるほど変わったので、今回の変更も楽しみ。