Author Archives: AKIYAMA

2022-01-08 ,

WordPressのプラグインを作る

これまで画像の表示にEasy FancyBoxを使っていたのですが表示する情報を増やせず追加の拡張に課金するのもなぁと思ったので自分で作りました。

とりあえず表示するだけなら簡単だったのですが、スクロール出来るようにしようと思ったら案外大変。適当にoverflow: scrollでスクロールバー出しておけば良いだろうと思ったのですが、ホイールでスクロールするときに後ろのページがスクロールしてしまうことが判明。元々背景のdivでpreventDefaultしてホイールを抑制していたのですが、それだとホイールで画像をスクロール出来ないのでスクロール領域だけpreventDefaultしないように変更。しかしそうすると画像のスクロールが必要ない状況(高さが足りているとか上限に達しているとか)の時に後ろのページがスクロールするという。部分的にブラウザ既定の動作に任せるというのは思っていたよりも難しいらしく、どうすればよく分からなかったため、最終的にはスクロール機能は自前で実装することに。しかしそうするとタッチイベントでも同じ問題が発生。もうピンチイン/アウトも含めて対応してしまえ、そうするとホイールも拡大縮小に割り当ててマウスでパンするように修正。

というわけでCSSでちょろっとスクロール出来るようにしておけば良いだろうと思ったのが、思いのほか時間を取られてしまいました。他にも自分で作ってみると細かい改善点が沢山見えてきますね。ヤレヤレ。

動作例:

白馬大池

WordPress部分はheadにscriptを追加するだけなので簡単でした。しかし、deferにするのってこんなことしなきゃいけないの?? マジで??

2022-01-05

360Photo System

これまでに歴代Googleスマホ(Nexus/Pixel)のPhoto Sphereで撮った写真を共有する仕組みを作った。

必要な作業は次の通り。

  1. HDDの中からそれらしき画像をかき集める
  2. 画像ファイル名とタイトルの対応表を作る
  3. 8192x4096に変換
  4. 2~4MBくらいのJPEGに頑張って圧縮(mozjpegで-quality 40くらいに落ち着いた)
  5. 600x314のサムネイル画像を作る(ImageMagickで1800幅に縮小して中心600幅を切り抜く)
  6. ついでに、押せるマーク付きサムネイルも作る
  7. 画像毎にHTMLを生成する(中身はメタ情報と外部JS起動のみ。OGP、TwitterCard情報付き)
  8. サーバにアップロードする

1と2はある程度手動でやらざるを得ないとして、3以降は自動的に行う。変換処理のスクリプトはEmacs Lispで書いた。私はシェルスクリプトは何もわからんので。Emacs Lispでは directory-files して shell-command 呼べばいいだけ。後はある種のテンプレートエンジンというか、 {{{key}}} をalistを元に置換するような仕組みを作ってHTMLを生成する。わずかにMakefileも使用。必要な操作はtransientで作ったメニューにまとめたので忘れても安心。

一番手間がかかったのは圧縮の方法を決めるところ。元の画像は6~16MBくらいもあるので、転送量・転送時間的にもサーバ容量的にも厳しい。2MB程度に収まらないか色々試したが、あまり品質を低くすると空のグラデーションがはっきり帯状になってしまうので無理だった。最初はImageMagickで圧縮したが、Photoshopで保存した方が綺麗だった。最終的にはmozjpegを使った。

ブラウザでの表示は以前星空を描画するために作ったもの(misohena/drawstars)を転用。正距円筒図法(equirectangular)の画像をWebGLのテクスチャにして描画する。1枚のテクスチャで描画する仕組みになっていたが、8192ピクセルサイズのテクスチャは手元のAndroid端末ではエラーになったので、急遽複数のテクスチャに分割して描画するように変更した。こういうのがあるから私はどうにも3Dグラフィックスハードウェアというのが好きになれない。ただ、WebGLは素のOpenGL ESをいじるよりは(主に周辺的な事情により)幾分気が楽である。変なバグを発見。起動したときになぜか中途半端な方向を向いているなと思ったら現在の恒星時の方向を向いていた。機能を切り忘れていたらしい。内部的には北極に立って全宇宙を眺めているという扱いになっているので。

こうやってブログにも簡単に貼り付けられる。

20180715_074423_thb.jpg
20190104_120508_thb.jpg
20200826_080913_thb.jpg
20211105_130232_thb.jpg
20190121_110427_thb.jpg
20211106_104109_thb.jpg
20181002_123850_thb.jpg
2022-01-02 ,

org言語のソースブロックをエクスポートしたときにリンクをそのまま出力する

例えば次のようなソースブロックがあった時に……

リンクは次のように書きます。
#+begin_src org
[[https://example.com/][example.com]] へ行ってみよう。
#+end_src

エクスポートすると……

リンクは次のように書きます。

example.com へ行ってみよう。

みたいに出力されてしまいます。リンクの書き方を説明したいのに、リンクのブラケットやパスの部分が消えてしまうわけです。

昔からそうだったけ?とモヤモヤしながらもう長いこと経つのですが、org-modeの書き方を例示することが多い私はよくこの問題に引っかかります(最近ではこういうのとかこういうのとか)。

C-x 8 RET zero width space と打って見えない空白を[と[の間に入れて回避するのが常なのですが、そろそろ何とかしたいなぁと思って調べました。そのコードをコピペすると空白までコピーされて機能しませんからね。

結果、次のようなコードで回避できました。

(defvar-local my-org-in-html-fontify-code nil)

(advice-add 'org-html-fontify-code :around 'my-org-html-fontify-code-advice)
(advice-add 'org-html-htmlize-region-for-paste :around 'my-org-html-htmlize-region-for-paste)

(defun my-org-html-fontify-code-advice (old-func &rest rest)
  (cl-letf (((default-value 'org-link-descriptive) nil)
            ((default-value 'my-org-in-html-fontify-code) t))
    (apply old-func rest)))

(defun my-org-html-htmlize-region-for-paste (old-fun beg end &rest rest)
  ;; Erase htmlize-link properties
  (when (and my-org-in-html-fontify-code
             (eq major-mode 'org-mode))
    (remove-text-properties beg end '(htmlize-link nil)))
  ;; Call original
  (apply old-fun beg end rest))

ソースブロックがどのようにHTMLへ変換されるかは org-html-fontify-code を見ると良いです。テンポラリバッファを作って言語用のメジャーモードを起動し、ソースブロックの内容を挿入します。確実にfont-lockしたら、テキストプロパティを元にhtml化するわけです。

org-modeにはリンクを文字通りに表示する org-link-descriptive というオプションがあるので、この関数が呼ばれている間だけ nil になってもらうのが先のコードです。

org-link-descriptive はorg-modeが立ち上がるとバッファローカル変数になってしまいます。なのでエクスポート元のバッファでいくら let で nil にしても、新しく作られるテンポラリバッファでは nil になりません。そこでcl-letfでデフォルト値の方を nil にしています。

何かエクスポート中であることを判別する方法があるならorg-mode-hookでorg-toggle-link-displayでも呼んでしまおうかと思ったのですが、残念ながら見つかりませんでした。

まずはその辺りを修正してからエクスポートしたのがこちら。

リンクは次のように書きます。

[[https://example.com/][example.com]] へ行ってみよう。

リンクがクリックできるようになっているのがちょっと気持ち悪いです。この例では正しいURLになっていますが、URLとは解釈できないようなorg-mode独自のリンクパスも問答無用でHTMLのリンクにしてくれます。

これはhtmlize-linkというテキストプロパティの作用です。ソースのHTML化はhtmlizeというパッケージがバッファ内のテキストプロパティを元に行いますが、org-modeのfont-lockがhtmlize-linkというテキストプロパティを付けるので、それを見たhtmlizeが自動的にリンクに置き換えてしまうのです。

ソースブロックの中からリンクを張りたいなどとは思わないので、こちらも問答無用でhtmlize-linkというテキストプロパティを削除するようにしました。

最終結果は次の通りです。

リンクは次のように書きます。

[[https://example.com/][example.com]] へ行ってみよう。