2017/09/28 4:43 am
Installing Digital TV into Linux
Uncategorized

ふだん家では Linux マシンがメインで、サブの Windows マシンはたまにテレビを見るときにつけるという感じだったのだが。ここに来てそれに接続していた15年選手のディスプレイがついに壊れてしまった。なんということでしょう。ブラタモリと鉄腕 DASH が見れなくなってしまうじゃないか。

Windows マシンへは Chrome Remote Desktop を通してリモートで操作する選択肢もあり、10fps くらいになるが一応メインマシンからテレビを見ることはできる…のだが、これが恐ろしく負荷が高い。大体30分もすると熱のために勝手に電源が落とされてしまう。

さてどうするか。ディスプレイが壊れたのだからディスプレイを新調すればいいのだが、実際のところ Windows マシンはほとんど使っていないのであった。ほとんど使ってないマシンに素敵なナウいディスプレイくっつけて何が楽しいのか。何も楽しくない。

それよりも、メインマシンで直接テレビが見られれば遥かに楽なのだが。でも Linux で地デジなんてできるの…? と思いつつググってみたら、なんと今では録画サーバーなるものを Linux マシンで組むことはごくごくあったりまえの行為らしい。そ、そうなんだ…。すごい。

ということでこのあたりを参考にチューナーとカードリーダーを入手してみたところ、実に簡単に VLC でテレビを視聴するところまでいけた。すごい。

このままでも視聴自体はできるのだが、チャンネルを変えたりするのが若干面倒なのでここから Chinachu の諸々を入れるといいようだ。これはまあ、そのうちにやりたい(やらないフラグ)。

CPU 負荷はだいたい10%くらい。すごい。ところでサブチャンネルを選択したい場合とかはどうするのかな。

2017/08/17 10:39 pm
Pikoyan
Uncategorized

再放送中のけものフレンズには字幕が付いているのだが:

  • サーバルがジャパリバスの運転席を持ってジャンプする最後のシーン、「ぴこやん!」としか聞こえない。たぶん「とりゃー!」と言ってるのだと思うのだがぴこやんとしか聞こえない。自信がないので書き起こしでは地の文でごまかしてある。どうしよう
  • タイトルで○○ちほーとよくあるが、字幕ではカタカナのチホーである。これはアプリ版でもそうなので、そうなのかなと迷ったのだが、とりあえず書き起こしではひらがなで統一してある。しかしカタカナが正しいとなると、じゃあ「へいげんちほー」はセリフとしては(ライオンが 1 度セリフとして発音している)へいげんチホー? 平原チホー? ヘイゲンチホー? 判断する材料がない。どうしよう
  • 再放送のソースは最初に放送されたそれに比べて若干の修正が施してある。これは intro や outro のテロップも含まれる。甚だしいところでは、声優名が全然違うものになってたりする。これはどれを底とすべきだろうか
  • 再放送とはあまり関係ないが、サウンドトラックによって各 BGM の題名が明らかになったので、書き起こしにおいて BGM が奏でられるタイミングでその題名を追加したい。が、困ったことにサウンドトラックに収録されているのはサウンドトラック用に編集されたものであって、放送されたものに含まれるものとは若干違うのであった。また、常に BGM の最初から奏でられるわけではなく特徴的な最後の締めが多用されたりするパターンもある。どうしよう

2017/08/08 6:09 pm
Integration #2
Uncategorized, , ,

そういうわけで、設定のうち例外リストとなっていたものを site overrides とした。こんな感じで記述する:

http://example.org/*         *    block
http://example.net/*.html    *    writeas=p

ディレクティブとして有効な行は、3つの要素からなる。左から順に URL パターン、CSS セレクタ、アクション。まず URL パターンと CSS セレクタで要素を特定する。例外リストの段階では CSS セレクタは省略可能で、省略した場合ユニバーサルセレクタを指定したことになっていたが、省略不可能になった。サイトすべての編集可能要素を対象にしたい場合はユニバーサルセレクタを明示的に記述する必要がある。

最後の要素がアクションで、これが block であった場合は、そのパターンに合致する要素上では wasavi の起動が抑制される。それ以外であった場合、set コマンドの引数として wasavi 起動時に評価される。つまり、exrc の最後に付加される。

 * * *

これとは直接は関係ないのだけど、バックグラウンド側での設定の持ち方を変えた。従来は各ブラウザの差異を吸収するような抽象的なクラスを経由していたが、単に chrome の API を直接呼ぶようにした。

2017/08/04 10:10 pm
Integration
Uncategorized, , ,

wasavi のオプションに、writeas というものがあり、こういう仕様になっている。つまり、contentEditable な要素に対して wasavi のバッファを書き戻す際、どのような DOM の構造にするかを指定する。たとえば p なら、各行を p 要素として書き戻す。

しかし、当然ながら contentEditable な要素の内部構造をどのように保持しているかはサイトごとにまちまちであり、ひとつに決められるものではない。そこで、writeas には 連想配列を表す json 文字列を代入することも許している。こんな感じで:

set writeas='{ \
  "http://example.com/*": "div", \
  "http://example.net/*": [ \
    { \
      "selector": "#any-css-selector", \
      "writeas": "textAndBreak" \
    } \
  ] \
}'

連想配列のキーが URL パターンで、値が writeas という形式だ。または、さらに連想配列の配列を入れ子にして、CSS セレクタを指定することもできる。これにより、つまりサイトごとに writeas の定義を分けることができる。

ただ……見てのとおり exrc 中に改行のエスケープしまくりで書かないといけないので、とても面倒くさい。また set all した時の見栄えもとてもよくない。もっと洗練された形式で保持する必要がある。

ところで、サイトごとに定義を振り分けているものは wasavi はもうひとつ持っている。サイト自身が提供するスクリプトとコンフリクトするか何かでうまく動かない場合に、wasavi の起動をしないという例外リストである。これは普通のプレインテキストで

http://example.com/
http://exmaple.org/  #some-id

のように行ごとに URL を書き連ねる。URL のあとに任意の個数の空白を挟んで CSS セレクタを記述することもできる。これと writeas の定義を統合できないだろうか。つまり例外リストではなく per-site overrides という扱いにしたい。

override := URL-pattern (CSS-selector)? action
action := allow-actions
          "block"
allow-actions := allow-action ("," allow-action)*
allow-action := "writeas" "=" writeas-value
writeas-value: "div" | "p" | "textAndBreak" | "plaintext" | "html"

という感じだ。

2017/08/03 2:53 pm
Mapping more modes #2
Uncategorized, , , ,

そういうわけでいろいろ変更している。

  • 特定のキー入力を別の入力に置き換えるために、最新の wasavi は以下の 3 種のマップを保持している:
    1. normal マップ: normal モード時に参照される
    2. bound マップ: bound/bound_line モード時に参照される
    3. input マップ: insert/overwrite モード時に参照される

    これ以外のモードにおいてはリマップはできない。これは技術的にできないのではなく、単に現状ではそういうふうにしていないというだけだ。

  • マップに対するルールの操作は、ex コマンド map、および map! で行う。既定では、前者は normal と bound マップの両方を、後者は input マップを対象にする。どのマップを対象にするかは、後述のアトリビュートで変更できる。
  • map map! は、最小で 0、最大で 2 つの引数を取ることができる。さらに、引数の前にアトリビュートを置くことができる。
  • アトリビュートは、先頭が [、末尾が ] であるカンマ区切りの文字列である。アトリビュートのコンポーネントとして有効なものは、上記のマップ名か、もしくは clear final noremap のいずれかである。
  • アトリビュートにマップ名が含まれる場合、デフォルトマップの代わりにそのマップが選択される。
  • アトリビュートに clear が含まれる場合、選択されたマップに定義されたルールをすべて削除する。引数は使用されない。
  • 引数が 0 個の場合、選択されたマップに定義されたルールをすべて表示する。
  • 引数が 1 個の場合、lhs に引数 1 が部分的にマッチするルールをすべて表示する。
  • 引数が 2 個の場合、引数 1 を lhs、引数 2 を rhs として、選択されたマップ全てに対してルールを登録する。この際、アトリビュートに
    final または noremap が含まれる場合は、再帰展開しないマップとして登録される。

 * * *

ところでここまで修正したのを Selenium でテストしようと思ったら、何やらおかしい。wasavi を起動させたあと、キー入力が行われない。つまり textarea に対する sendKeys() は動くのだが、wasavi 本体の iframe への sendKeys() が動作しないようだ。

以下の chromium の issue が関係しているかもしれない:
https://bugs.chromium.org/p/chromedriver/issues/detail?id=1777
https://bugs.chromium.org/p/chromedriver/issues/detail?id=1819

2017/08/01 7:18 pm
Throw a query to twitter
Uncategorized

Twitter で検索する際、いろいろ特殊な文法が使えるらしい。例えば url: を前置して URL を書くと、それにリンクしているツイートを検索できるそうなので喜び勇んで appsweets.net とか github.com/akahuku とかやってみたのだが。それによってわかったことは、日本人はけものフレンズのセリフ起こしとかグラディウスとかには食いついてくるのだが、wasavi にはほとんど興味を示していないということだった。なるほど。

2017/07/31 6:25 am
Mapping more modes
Uncategorized, , ,

wasavi の issue として、bound/bound_line に normal ではない個別のマッピングを行いたい、というものがある。

現状では、normal/bound/bound_line は MapManager 内部の command マップに収斂、insert/overwrite は edit マップに収斂、それ以外のモードはマップ不可、という形になっている。したがって、要件に応えるには、単に bound/bound_line 用の個別のマップを設けるだけでいい。

ただ、インターフェースの問題がある。ex コマンド map は command マップを操作する。一方 map! は edit マップを操作する。! の有無の二者択一のため、第3のマップが入り込む余地がない。

vim では、これを nmap/vmap/xmap/smap/omap/imap/lmap/cmap… とむやみに ex コマンドを増やすことで対処している。さらに再帰的なマップ展開をしない版である nnoremap/vnoremap/xnoremap/snoremap/onoremap/inoremap/lnoremap/cnoremap… という群もあり、総数としてはかなりのものになっている。

これ、果たしてわかりやすい仕様なんだろうか。だいたいなんなの onoremap とか inoremap って。初見じゃあ己マップと祈れマップとしか読めないよ。何をするコマンドなのかさっぱりわからない。

どうもこんな感じに ex コマンドをホイホイ新設するのは良くない設計に思える。加えて自己記述性の低いコマンド名はもっと良くない。

そんなわけで、wasavi では noremap かどうかを指定するのは map コマンドに与えるアトリビュートという形式にしてある。アトリビュートとはつまり

:map [noremap] gh ^

などと LHS の前に角括弧つきで指定する部分のことだ。ちなみに noremap というアトリビュート名もなんかいまいちなので、例えば final にしようかと考えている。

で、定義先のマップもアトリビュートで指定するようにしてはどうだろうか。例えば

:map [bound,final]

みたいな感じ。map コマンドを投入してかつアトリビュートでマップを指定しなかった場合に選択されるデフォルトのマップは normal と bound の和集合になる。一方、map! コマンドの場合は対象は edit マップ。

また、引数なしで map/map! コマンドを投入した場合は現在定義されているマップを表示するが、その場合には対象となるマップも表示したほうがいいかもしれない。

2017/07/28 2:29 pm
Xmodmap alternatives?
Uncategorized

Xubuntuで、Caps と Ctrl を交換するだとか、その他細々としたキーボードのリマップを、xmodmap でやっている。が、なんだか知らないが、xmodmap はとっくの昔に Obsolete らしいのであった。さらに困ったことに、数時間おきに xmodmap によるリマップが勝手にリセットされるのだ。いや正確に言うと数時間おきというのも違い、ランダムというしかないタイミングでリセットされる。わからん。どういう嫌がらせなんだ。

で、xmodmap の代替は xkb らしいのだけど。ちょっと調べてみてなんかめんどくさそうだなーまあ xmodmap でいいかな…というのをかれこれ年に3回位繰り返している。

しかしせっかくなので、いろいろ試行錯誤してみた。xkb は基本的に言えば、物理キーに対してどの論理キーとして振る舞わせるかを制御する。また Shift−Level なんかも制御する。それらの情報は /usr/share/X11/xkb 以下にテキストファイルとして保持されている。各ユーザのホームに個別の .xkbrc ファイルみたいなのを置いて上書きするような仕組みはない。やろうとするなら、.xinitrc なり .xsession なりで setxkbmap を呼ぶことになると思う。

さて実際にキーの割当を記述するのは、symbols/ サブディレクトリ以下のファイル群となる。

/usr/share/X11/xkb $ ls symbols
af      by            es            hu      kz              mm          pt          terminate
al      ca            et            ie      la              mn          ro          th
altwin  capslock      eu            il      latam           mt          rs          tj
am      cd            eurosign      in      latin           mv          ru          tm
apl     ch            fi            inet    level3          nbsp        rupeesign   tr
ara     cm            fo            iq      level5          nec_vndr    se          tw
at      cn            fr            ir      lk              ng          sgi_vndr    typo
az      compose       fujitsu_vndr  is      lt              nl          sharp_vndr  tz
ba      ctrl          gb            it      lv              no          shift       ua
bd      cz            ge            jp      ma              nokia_vndr  si          us
be      de            gh            ke      macintosh_vndr  np          sk          uz
bg      digital_vndr  gn            keypad  mao             olpc        sn          vn
br      dk            gr            kg      md              pc          sony_vndr   xfree68_vndr
brai    ee            group         kh      me              ph          srvr_ctrl   za
bt      empty         hp_vndr       kpdl    mk              pk          sun_vndr
bw      epo           hr            kr      ml              pl          sy

ここにたくさんのファイルがあるわけだが、個々のファイルはそれら自身が行うキー定義量によって実質的に階層化されている。例えば pc ファイルはほぼすべてのキーに対して割当を定義する。言語コードっぽいファイルは各言語に応じた部分だけを定義する。ctrl や altwin、shift といったファイルは、それぞれの個別のキーをどのように振る舞わせるかだけを定義する。このようにレイアウトや言語から独立して、ほんの一部の定義だけを行うものを option と呼ぶ。

言語による定義の場合、さらにその言語内でいくつかのバリエーションが必要になる場合がある。その場合は、例えば us ファイルであればそのファイル内で、基本の定義を継承し、必要な部分だけを変更したものを定義する。そのような定義を variant と呼ぶ。

これらのファイルから任意のものをピックアップし、定義量の大きいファイルから小さいファイルへ順々に定義を行うことで任意のキーレイアウトが完成する。

で、実際にキーボードの種別を指定するには /etc/default/keyboard ファイルを

XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""

と言った感じに記述する。model -> layout -> variant -> option という並びがまさに前述の、定義量の大きい順から小さい順というトピックに対応している。

ということを踏まえた上で、行いたいリマップは:

  1. 左の Ctrl と、Capslock を交換する
  2. Menu キーを Compose キーにする
  3. 右の Alt キーを、F20 キーにする

1. と 2. については、標準でオプションが定義されているので、前述の keyboard ファイル中の XKBOPTIONS に “ctrl:swapcaps,compose:menu” という値を与えればいい。問題は 3. だ。3. を実現するには、us の variant を定義するか、あるいは新しい option を定義するか…が正道に思える。

しかし、実際に行うのはそのどちらでもない。というのは variant や option を新設するには、rules/ 以下のいろいろなファイルを併せていじる必要があり、とても面倒だからだ。しかもそれらの編集が間違っていると、X 上の文字入力が一切できない、つまりログインスクリーンから進めないというかなり困る状態になってしまう。実際にやらかして、アワワワワ…となった。

実際に行うのは、上記で参照している option の定義中に 3. の定義を忍び込ませるというものだ。かなりイケてないが、たぶんこれが xkb の定義ファイルを最小限いじるだけで済むベストな方法だ。us ファイルを使わないのは、それが定義順の左の方に位置するので、知らない定義で上書きされる可能性が高いからだ。option なら定義の最後なので上書きされる恐れはかなり小さい。

swapcaps の定義は ctrl ファイルの

// Swap the functions of the CapsLock key and the left Ctrl key.
partial modifier_keys
xkb_symbols "swapcaps" {
    replace key <CAPS> { [ Control_L ] };
    replace key <LCTL> { [ Caps_Lock ] };
};

というセクションなので、この中に

    replace key <RALT> { [ F20       ] };

という行を追加する。そして祈りながら再起動する。これで xmodmap でやっていたリマップを xkb で再現できた。

2017/07/23 9:17 pm
Screen Casting
Uncategorized, , ,

wasavi の Readme の最初の画像2つは、素の textarea と、それに対して wasavi を起動した状態の対となるものにしてある。

ところで Twitter でたまに wasavi について tweet される際、それは最初の画像を添付してあったりする。前述の通り最初の画像は単に素の textarea の画像なので、wasavi についての説明になっていない。例えば:

これを解消するために、2つの画像をまとめ、スクリーンキャストによる gif アニメーションをこさえたい。素の textarea から wasavi を起動し、編集し、書き込んで終了するまでを録画すればいい。というわけで、gtk-recordmydesktop をインストールし、録画し、ogg theora 動画を生成した。それを適当なオンラインのコンバータで gif に落とした。

gif に落とす際のオプションとかはなかったのでディザが目立つが、まあこんなもんだろう!

* * *

適当なオンラインのコンバータに頼るのはやめ、ogv → gif 変換はローカルで ffmpeg により行うようにした。見苦しいディザは追放した、はず。

2017/07/21 8:47 pm
Opening an options page
Uncategorized, , ,

wasavi のオプションページというものを開くために、manifest.json に options_page キーを含めているが、実はこれは旧式である。現行は options_ui キーになっている。options_ui でどのようにオプションページを開くかどうかについてさらに新旧があり、古い方はオプションページをタブで開き、新しい方は chrome://extensions ページにオーバーレイする形で開く。これは TabQueue などの他の Chrome エクステンションでも出てきた話題だ。

さて wasavi を WebExtensions で動かした場合、options_page キーを認識しないようだ。そこで options_ui の、旧式の方に移行した。旧式の方は公式に obsolete であり、今にも削除されそうな勢いである…ということは、ちょっと気にかけておかないといけない。

WebExtensions で動かした場合、options_ui 旧式の場合は、拡張の詳細ページにオプションページを開くボタンが追加される。新式の場合は、オーバーレイではなく、拡張の詳細ページにオプションページが埋め込まれた形で表示される。へー。

Chrome では個々のエクステンションの設定をエクステンション一覧の特別な、モーダルな状態として捉えているが、Firefox ではエクステンション一覧から遷移する独立したページとして捉えている。どちらかというと Firefox の設計のほうが優れてるように思える。ブラウザの設定も昨今の多くのブラウザでは Web ページの1つとして扱われている。であればやはり様々なページを遷移する UI であることを強く意識して設計すべきであり、オーバーレイというモーダルな状態に安易に頼るべきでない。

Archives