Author Archives: misohena

2021-08-04

WindowsでflycheckがNULというファイルを作ってしまう問題

以前flycheckを試したときにNULというファイルが出来て消すのが大変だったのでflymakeでいいやーと思ったことがあったのですが、最近また調べたところ対処法を書いているサイトを見つけました。

Emacs Flycheck

下記の記述だと、Windowsで、gcc によっては、同じディレクトリに "NUL" というファイルが生成されることがある。

:command ("gcc" "-c" "-I../../inc" "-I." "-O1" "-Wall" source "-o" null-device)

その場合、下記のように temporary-file-name を指定すると回避できる

:command ("gcc" "-c" "-I../../inc" "-I." "-O1" "-Wall" source "-o" temporary-file-name)

checker定義内の 'null-device は同名の変数null-deviceの値で置き換えられて、Windowsだと "NUL" になります。これをCygwinやMSYS2/MinGWのgccが受け取るとコンパイルが成功したときにそのままNULというファイルを出力してしまうのが原因のようです。

同じようにcheckerを再定義すれば良いのかなと思ったのですが、flycheck.elを見てみると沢山のcheckerが定義されていてその中でnull-deviceも沢山使われていました。

そもそもcheckerを再定義するのも面倒ですし、かといってnull-deviceの値を書き替えるのも(他にどこで使われているのか分からないので)怖いですし、手っ取り早くadviceでnull-deviceをtemporary-file-nameに置き換えてしまうことにしました。

;;; Windowsでnull-deviceを使わないようにする。
;; null-deviceはNULなので、CygwinやMinGWだとNULというファイルを作ってしまう。
;; flycheck-command-wrapper-function でNULを置き換えても良いのだが
;; flycheck-substitute-argument でやった方が確実だし簡単。
(when (locate-library "flycheck")
  (with-eval-after-load 'flycheck
    (defun my-flycheck-substitute-argument (old-func arg checker &optional rest)
      (when (eq arg 'null-device)
        (setq arg 'temporary-file-name))

      (apply old-func arg checker rest))
    (advice-add 'flycheck-substitute-argument :around 'my-flycheck-substitute-argument)))

最近はLSPの方でエラー箇所を検出してしまうので必要ないのかもしれませんけどまたNULファイルが出来ると面倒なので念のため。

2021-08-03

2021年夏の新番組

最近は1話が月末まで遅れることが多くなってきましたね。

初評 テレビ開始 テレビCh 作品名 ネット配信
06/29(火) 25:34 日テレ ワンダーエッグ・プライオリティ 特別編  
07/01(木) 22:00 MX ピーチボーイリバーサイド dアニメ
07/01(木) 22:30 MX SCARLET NEXUS dアニメ
07/01(木) 23:30 MX ひぐらしのなく頃に 卒  
07/02(金) 24:00 MX ヴァニタスの手記 第1クール Amazon
07/02(金) 24:30 MX 100万の命の上に俺は立っている 第2シーズン  
07/02(金) 25:05 MX ぶらどらぶ(VLADLOVE) ※ネットでは既に配信済 dアニメ
07/02(金) 25:25 TBS系 乙女ゲームの破滅フラグしかない悪役令嬢に転生してしまった…X (第2期) dアニメ
07/02(金) 25:50 TBS系 俺、つしま Youtube
× 07/02(金) 26:25 TBS カノジョも彼女 ABEMA
× 07/03(土) 22:00 MX ぼくたちのリメイク ABEMA
07/03(土) 23:30 MX 魔法科高校の優等生 dアニメ
× 07/03(土) 25:00 MX かげきしょうじょ!! dアニメ
07/03(土) 25:30 MX 現実主義勇者の王国再建記 FOD
07/03(土) 25:30 テレ朝 RE-MAIN dアニメ
07/04(日) 21:30 MX 天官賜福 -吹替版- dアニメ
07/04(日) 22:00 MX 死神坊ちゃんと黒メイド dアニメ
07/04(日) 22:30 MX アイドリッシュセブン Third BEAT! (第3期) 第1クール  
07/04(日) 23:00 MX ゲッターロボ アーク dアニメ
× 07/04(日) 24:00 MX 探偵はもう、死んでいる。 dアニメ
07/04(日) 25:00 MX 指先から本気の熱情2-恋人は消防士- dアニメ
× 07/05(月) 25:30 テレ東 うらみちお兄さん dアニメ
07/05(月) 26:00 テレ東 精霊幻想記 ABEMA
07/06(火) 23:00 MX 転生したらスライムだった件 第2期 第2部 dアニメ
07/07(水) 07:05 テレ東 KICK&SLIDE  
07/07(水) 22:00 MX チート薬師のスローライフ~異世界に作ろうドラッグストア~ dアニメ
07/07(水) 22:30 MX TSUKIPRO THE ANIMATION 2  
07/07(水) 23:00 MX 月が導く異世界道中 dアニメ
07/07(水) 24:00 MX 小林さんちのメイドラゴンS (第2期) dアニメ
07/08(木) 24:00 MX 白い砂のアクアトープ ABEMA
07/08(木) ~ Netflix BIOHAZARD(バイオハザード):Infinite Darkness Netflix
07/09(金) 22:30 MX 迷宮ブラックカンパニー dアニメ
× 07/10(土) 22:30 MX D_CIDE TRAUMEREI dアニメ
07/11(日) 19:00 Eテレ ラブライブ!スーパースター!!  
07/11(日) テレ東 闇芝居 第9期 Paravi
× 07/12(月) 24:00 MX 出会って5秒でバトル dアニメ
× 07/14(水) 25:05 MX 女神寮の寮母くん。 dアニメ
07/14(水) 24:55 フジテレ NIGHT HEAD 2041 FOD
× 07/15(木) 24:30 MX Sonny Boy -サニーボーイ- dアニメ
07/18(日) 24:30 BS日テレ 戦乙女の食卓Ⅱ YouTube
07/20(火) ~ WEB配信 アサルトリリィふるーつ  
07/22(木) 24:55 フジテレ 平穏世代の韋駄天達 Amazon
07/31(土) 24:00 MX マギアレコード 魔法少女まどか☆マギカ外伝 2nd Season  
07/31(土) 26:00 テレ朝日 ジャヒー様はくじけない! dアニメ

今期は不作……凶作ですかね?

2021-08-03 ,

org-modeのコードブロックでHTMLを「実行」する

org-modeのコードブロック(org-babel)でHTMLを書いているとフラストレーションが溜まります。なぜならば書いたHTMLの結果を確認しづらいからです。

org-modeにはob-html.elが定義されていません。なので org-babel-execute:html も定義されておらず通常のコードブロックを評価する方法(C-c C-c)でHTMLを実行出来ません。

HTMLの実行とは何か

ちょとまって。実行? HTMLの実行とは何でしょう。HTMLはマークアップ言語ですからプログラミング言語のように実行と言われても何をするのかよく分かりません。ob-html.elが無いのはおそらくそのためではないでしょうか。

私が思う実行とは何でしょうか。

ブラウザで開く
HTMLの実行と聞いて真っ先に思い浮かべるのはブラウザで開くことでしょう。プログラミング言語では無いと言いますが現実的にはもはやアプリケーションプラットフォームでもあります。
HTMLをそのまま文書に埋め込む
例えばコードブロックを使ってHTMLの書き方を説明したとしましょう。表の書き方、段落の書き方、強調の書き方等々。エクスポートしたときにHTMLの書き方(コード)と表示結果を並べて表示したいことがあります。そのとき、HTMLでエクスポートするならコードの後にそのHTMLそのものを埋め込めれば手っ取り早く結果をブラウザで表示できるはずです。
単にHTMLをそのままファイルとして書き出す
単にそのまま別ファイルに書き出してくれれば十分なこともあるでしょう。結果欄にはそのファイルへのリンクを表示すれば読んでいる人はそれをクリックして結果を確認することが出来ます。ちなみに単に書き出すだけなら :tangle というヘッダー引数があるのですが、これは文芸的プログラミングのためのものでバッファ内のものを一度に全部書き出すコマンドしか見当たらず何だか用途が違う気がします。通常の :results file :file filename で書き出したいところです。
HTMLの文字列そのものを結果とする
コードブロックに書いてあるテキストをそのまま結果とするという考え方も出来ます。実はob-org.elはそうなっています。別の所から参照して活用するのに使えそうです。ちなみに上の二つの「実行」はこれが実現出来るだけで自動的に実現出来ます。「そのまま」というのがミソですね。前者はそのままhtmlエクスポートブロックにするだけ。後者はそのままファイルに書き出すだけです。結果をそのまま返すだけでエクスポートブロックで囲んだりファイルに書き出す処理はOrg Babel側でやってくれます。
スクリーンショットを撮る
結果を画像で表示できれば便利です。これを実現する方法はこれまでにいくつか見たことがあります。ネットを探すとPhantomJSやヘッドレスChromeを使用してスクリーンショットを取れるようにした事例が見つかります(krisajenkins/ob-browser, ob-html-chrome/ob-html-chrome.el)。
ブラウザで開きセッションを維持する
単にブラウザで開くだけで無く、開いたらそのままセッションを維持して、続くJavaScriptのコードブロックをそのセッションで実行できたら面白いのではないでしょうか。JavaScriptからHTML(というかDOM)を操作する方法を解説したいときに便利かもしれません。

とりあえず私がパッと思いつくのはこのくらいでしょうか。HTMLは単なる文書ですから、他にもいくらでもやりたい動作はあることでしょう。

ob-html.el を作る

まず ob-html.el が無いことが問題です。せめて ob-org.el レベルの物は用意しておいて欲しい所ですが無いのだから仕方ありません。

というわけで作りました。

misohena/ob-html

これを読み込ませるとHTMLのコードブロックが評価できるようになり、その結果を #+RESULTS: の場所に埋め込むことが出来るようになります。具体的には次のことが出来るようになります。

HTMLとしてそのまま埋め込む

次のコードブロックは評価するとHTMLのエクスポートブロック(#+begin_export html#+end_export)になります。

#+name: ob-html-ex1-1
#+begin_src html :exports both :results html :cache yes
<p><strong>つよつよ</strong> <ins>追加</ins> <del>削除</del></p>
#+end_src

上のHTMLは次のように表示されます。

#+RESULTS[9621841e579ea4feee64be832813d72c5428d389]: ob-html-ex1-1
#+begin_export html
<p><strong>つよつよ</strong> <ins>追加</ins> <del>削除</del></p>
#+end_export

上のOrg文書はHTMLでエクスポートすると次のように表示されます。

<p><strong>つよつよ</strong> <ins>追加</ins> <del>削除</del></p>

上のHTMLは次のように表示されます。

つよつよ 追加 削除

外部にHTMLファイルを生成し、そのファイルへのリンクを埋め込む

次のコードブロックは評価すると外部にhtmlファイル(example.html)を出力しそのファイルへのリンクが結果になります。

#+name: ob-html-ex2
#+begin_src html :results replace file :file example.html
<!DOCTYPE html>
<html>
  <head>
    <title>Hello</title>
  </head>
  <body>Hello</body>
</html>
#+end_src

どう表示されるかは下をクリックしてね。

#+RESULTS: ob-html-ex2
[​[file:example.html]]

:results には file を指定します。

外部にスクリーンショット画像ファイルを生成し、そのファイルへのリンクを埋め込む

次のコードブロックは評価すると外部にスクリーンショットを含むpngファイル(example.png)が生成されそのファイルへのリンクが結果になります。

#+begin_src html :results replace file graphics :file example.png :width 320 :height 64
<!DOCTYPE html>
<html>
  <head>
    <title>Hello2</title>
  </head>
  <body>Hello2</body>
</html>
#+end_src

#+RESULTS:
[​[file:example.png]]

:results には graphics を指定します。

スクリーンショットはとりあえずChromeのコマンドラインオプション(いわゆるヘッドレスChrome)で取得するようにしてあります。事前にchromeへのパスを正しく設定する必要があります。

C-c C-oでブラウザで開く

以上は何らかの結果を生成して #+RESULTS: のところに埋め込む方法でした。

しかし肝心の「ブラウザで開く」がまだ実現出来ていません。

org-modeからブラウザで開くというのはorg-babelの「評価」とは何か根本的に違うような気がします。私は別にファイルを書き出したいわけでは無いんです。ファイルを書き出されると管理が面倒なので出来れば書き出して欲しくありません。評価して結果を得たいわけでも無いんです。単にブラウザで見たいだけなんです。

「評価」というよりは「開く」と言った方が良さそうです。

開くと言えば C-c C-o 。org-modeだと org-open-at-point に割り当てられていてポイントにある要素を良い感じに開いてくれます。HTMLコードブロックの上で C-c C-o したら即ブラウザで表示してくれたら便利ではないでしょうか。実は結果がファイルになる場合はすでにそのファイルを開いてくれるようになっています。上の例で言えば、二番目(example.html)と三番目(example.png)は C-c C-o でファイルが開きます。しかし次のように結果が出力されないコードブロックで C-c C-o しても何も起きません。

#+begin_src html
<!DOCTYPE html>
<html>
  <head>
    <title>Hello</title>
  </head>
  <body>Hello</body>
</html>
#+end_src

このようなコードブロックはファイルが関連付けられていないのでブラウザで表示するのは難しいのですが、一時的にテンポラリファイルに書き出してブラウザで開き、その後テンポラリファイルを削除するというのはどうでしょう。

ob-html.elにそのような機能を追加してみました。 (org-babel-html-enable-open-src-block-result-temporary) 関数を呼び出すと org-babel-open-src-block-result 関数にadviceをかけてテンポラリファイルで表示できるようにします。

(require 'ob-html)
(org-babel-html-enable-open-src-block-result-temporary)

:results silentの時はブラウザで開く

ob-html.elでは:resultsのデフォルト値はsilentにしました。これは ob-org.el がそうだったのでそれを踏襲しました。org-mode全体でのデフォルトはreplaceなのになぜsilentなのでしょうか。org言語は結果を求めるものでは無いという考えがあるのかもしれません。それならばhtmlも同じです。

デフォルトでsilentなので何もヘッダー引数を指定しなかった場合は評価しても何も起こりません。 #+RESULTS: も挿入されません。エクスポートブロックや外部ファイル、画像を生成したければreplaceを指定する必要があります。

silentのときはほとんど何もしないわけですから、このときブラウザで開いてみるのはどうでしょう。

困るときもありそうなので設定で開くかどうか決められるようにしておきました。

セッション対応

残るはセッション対応ですが、これは少し保留させてください。

いくつかやる方法は考えつくのですが、これはhtmlコードブロックだけの範囲を超えています。JavaScriptコードブロックの改善も一緒にやらなければ意味がありません。

2021-08-03-ob-html-screenshot.png