feed
2014年06月14日, 編集履歴
Jekyllでは、YAML Front-matterでtags
変数にタグを割り当てることで、ブログ記事にタグを付けることができる。たとえばこの記事のFront-matterは以下のようになっている。
---
title: Jekyllで空白を含むタグを付ける
layout: post
tags: jekyll development
---
タグはスペース区切りで割り当てる。この場合はjekyll
、development
というふたつのタグが付けられることになる。
タグ名にスペースが含まれない場合は上記の記法で良い。タグ名にスペースを入れたい場合は、YAMLのリスト形式を用いる。
たとえば「Mailto Interceptorをリリースしました 」という記事にはmailto interceptor
やos x
というスペース含みのタグが付けられている。この記事のFront-matterは以下のようになっている。
---
title: Mailto Interceptorをリリースしました
layout: post
tags: [os x, release, mailto interceptor]
---
[]
でくくった中に,
区切りでタグ名を指定する。このようにすれば、空白含みのタグを付けられるようになる。
2014年06月06日, 編集履歴
Mailto InterceptorというOS Xアプリケーションをリリースしました。
ウェブブラウズ中にmailto:
リンクをクリックしてしまい、意図せずメイルアプリケーションが起動してしまったことがありませんか? Mailto Interceptorを使えば意図しないメイルアプリケーションの起動を抑制します。
Mailto Interceptorはシステムからはメイルアプリケーションとして認識されます。Mailto Interceptorをシステムのディフォルトメイルアプリケーションとして設定することでmailto:
リンクのクリック等に反応して起動するようになります。
通常のメイルアプリケーションであれば、起動後メイル作成画面を開きますが、Mailto Interceptorは設定された動作を実行後、自動終了します。Mailto Interceptorで設定可能な動作は以下の通りです。
mailto:
リンクを無視(なにもしない)
メイルアドレスをコピィ
Gmailの作成画面を開く
上記の動作とメイルアプリケーションの起動を選択できるメニューをポップアップ(推奨動作)
Mailto Interceptorがmailto:
に反応して起動した場合、Dockへのアイコン表示、およびDockアイコンのバウンドアニメーション等はしないので、ユーザはMailto Interceptorの存在を意識することなく上記の動作を実行させることができます。
上記デモアニメーションは、メニューをポップアップする動作を行ったときのものです。mailto:
リンクをクリックすると、システムがディフォルトのメイルアプリケーションを起動します。Mailto Interceptorをディフォルトメイルアプリケーションにしている場合、Mailto Interceptorが起動し、指定動作を実行します(上記デモアニメーションの場合はメニューのポップアップ)。
デモアニメーションで”Copy Email Address”をしているメニューは通常のコンテキストメニューではなく、Mailto Interceptorが表示しているメニューです(”Paste”しているメニューは通常のコンテキストメニュー)。前述のように、このときDockにアイコンが表示されたりはしません。
不意にメイルアプリケーションが起動してしまい、イラっとしたことがあるひとはぜひMailto Interceptorをお試しください。
余談
Mac App Storeでの文言は英語になっていますが、アプリケーション自体は日本語化されています。Mac App Storeでの日本語文言の準備を後回しにしていたら、それより早くリリースされてしまい、日本語文言の追加ができなくなってしまいました……。次回アップデート時にはちゃんと日本語追加します。
2014年06月04日, 編集履歴
(この記事の内容よりも良い方法を「動画ファイルからより良いアニメーションGIFを作る 」に書きました)
QuickTime Playerで「ファイル」→「新規画面収録」することで、画面の操作をMOVファイルの動画にすること(スクリーンキャプチャ)ができる。そのMOVからある程度きれいでファイルサイズが小さいアニメーションGIFを作ることを考える。
用意するもの(括弧内のヴァージョンは筆者の環境。他のヴァージョンでもたぶん可):
QuickTime Player (version 10.3) で画面収録したMOVファイル
ffmpeg (version 2.2)
ImageMagick (version 6.8.8-10)
手順:
ffmpegを使って動画を連番画像に切り出す
ImageMagickのconvertコマンドで連番画像をアニメーションGIFに纏める
ffmpegを使って動画を連番画像に切り出す
まずはffmpegを用いてMOVをフレーム毎に連番画像に切り出す。
ここで、アニメーションGIFのフレーム間の間隔は0.01秒単位である。したがって、フレーム間隔0.01秒で100fps(fps = 秒間フレーム数)となり、以後、0.02秒で50fps、0.03秒で33.33fps、0.04秒で25fps……となる。
QuickTime Playerで画面収録した場合、収録サイズやマシンスペックによって出力される動画のfpsは変動するので、アニメーションGIFの仕様に合わせたfpsで画像切り出しを行う。
$ ffmpeg -i input.mov -r 50 frames/%03d.png
この例では、カレントディレクトリィ下のframesディレクトリィに、3桁の連番をファイル名としたpng画像群が出力される。入力動画が60fpsで収録されていたので、アニメーションGIFの仕様に一番近い50fpsでの切り出しを行っている(したがって、秒間10フレーム分間引かれる)。そのために-r
オプションでフレーム数50
を指定した。
Internet Explorerの古いヴァージョンではフレーム間隔0.06秒以下(= 16.67fps以上)のアニメーションGIFは正常に再生できないらしいが、今回は無視する(参考:あなたは大丈夫?高速GIFアニメになってしまう症状 知らなきゃ絶対損するPCマル秘ワザ )。
ImageMagickのconvertコマンドで連番画像をアニメーションGIFに纏める
次に出力された連番画像をImageMagickのconvertコマンドを用いてアニメーションGIFに纏める。
$ convert -delay 2 -layers optimize frames/*.png output.gif
上記のようにすればframesディレクトリィ下の連番画像がアニメーションGIFになる。-delay
オプションでフレーム間隔を0.01秒単位で指定する。ここでは上述の動画切り出しfpsに合わせて2
(= 0.02秒間隔 = 50fps)を指定した。
-layers optimize
オプションを使用することでいい感じにアニメーションGIFを最適化してくれる(フレーム間で差分のあるところだけを使うとか)。このオプションを指定しない場合、50fpsで約9秒のアニメーションGIFのファイルサイズが約7.8MB、指定した場合は約552KBと、大幅なファイルサイズ削減効果があった。それでいて見た感じの画質の劣化等は全然解らないので、-layers optimize
オプションを指定することをおすすめする(動画の内容によるかも)。
以上のようにして生成したのが以下のアニメーションGIFである。
ターミナルでの操作が嫌なひとは以下のようなGUIアプリケーションがあるので参考まで。
LICEcap
LICEcapはWindows/OS X両方で使える。スクリーンキャプチャから一貫してこのアプリひとつでできるのでお手軽。出力の質は本稿の手法より劣ると思う。無料。
GIF Brewery
GIF Breweryは動画ファイルをアニメーションGIFに変換するOS X用のアプリケーション。GUIでクロップやリサイズ、オーヴァレイとかできる(本稿の手法でもImageMagickでがんばればクロップやリサイズ等できる)。出力の質は本稿の手法以上。有料。
余談
ちなみに上記のアニメーションGIFは2014年6月4日現在Mac App Storeに申請中のアプリケーションのデモアニメーションです。mailto:
リンクのクリックによる意図しないメイルアプリケーションの起動を抑制します。メイルアプリケーションの起動の代わりにアドレスをコピィしたり、Gmailの作成画面を開いたりできるようになるアプリケーションです。
追記:上記アプリケーションをリリースしました(「Mailto Interceptorをリリースしました 」)。
参考
2014年04月22日, 編集履歴
Kindleストアでは購入時にポイントが付くセールをよくやっている。しかし、付与されるはずのポイントが使用可能な確定ポイントではなく、使用できない仮ポイントになってしまっていることがよくある。
私がこれまで経験した十数冊分を鑑みると——ポイントが付くKindle本を、取得済みのポイントを用いて購入すると仮ポイントになってしまう傾向があるように思う(未確定)。なのでポイント還元セールでまとめ買いなんかすると、よく仮ポイントになっている。そのうち確定ポイントになるだろうと放置していても、一ヶ月近くたっても確定ポイントにはなってくれない。
どうやらAmazonからは動いてくれないようなので、こちらから問い合わせをする必要がある。
Kindleストアの「カスタマーサービスに連絡 」ページにアクセス(要ログイン)
「お問い合わせの種類」は「注文」を選択
仮ポイントになってしまっている注文が一件の場合は、注文番号入力欄に入力。複数の注文を纏めて問い合わせる場合は、注文番号入力欄は空欄で、後述のメッセージ欄に入力しても良いと思う
「お問い合わせの内容」は「Amazonポイント」を選択
「お問い合わせの方法」は「チャット」か「Eメール」。電話でも良いけど、注文番号とか伝える必要があるので、口頭よりは文字ベースの方がやりやすいと思う
メッセージ入力欄に、仮ポイントになってしまっている旨、およびその注文番号、タイトル等を入力する
私はEメールで問い合わせをしたが、三十分ほどで確定ポイントに変更してくれる旨の返信が来、その後一日程度で実際に変更が反映された。
仮ポイント問題を放置していてもAmazonからはなかなか動いてくれないようだが、こちらからの問い合わせへの反応は迅速である。仮ポイントのままでは持ち腐れなので、気づいたらカスタマーサービスに問い合わせすることをおすすめする。
2014年04月17日, 編集履歴
Jekyll を用いたブログで、ブログ記事に付けたタグをソートして一覧することを考える。サイト内の全タグを一覧する場合と、とあるひとつの記事に付けられたタグを一覧する場合のふたつを考える。
サイト内の全タグをソートして一覧する
タグクラウド的にサイト内の全タグを一覧する場合を考える。Alphabetizing Jekyll Page Tags In Pure Liquid (Without Plugins) – Michael Lanyon’s Blog を参考にした。
Jekyll処理対象ファイル内で使えるグローバル変数site
のsite.tags
に、サイト内の全タグ情報がハッシュとして入っている。タグ名がキィ、そのタグが付けられた記事のハッシュが配列として値になっている。たとえば{{ site.tags['jekyll'][0].title }}
とすれば、jekyll
というタグが付けられた日付順で一件目の記事のタイトルが出力される。
ハッシュそのままではキィをソートできない。配列であれば{{ array | sort }}
のようにsort
フィルタでソートすることが可能。そこで、site.tags
ハッシュからキィを取り出し、それを配列に入れてソートすることを考える。ここでは{% capture %}
と{% for %}
を使う方法を紹介する。
Jekyll(Liquid)の{% capture %}
タグを使うと、その中で出力される文字列を変数に詰め込むことができる。
{% capture myString %}hoge foo bar{% endcapture %}
のようにすれば、myString
にはhoge foo bar
という文字列が入る(実際の出力にはhoge foo bar
は反映されない)。
一方、{% for %}
文の機能について、{% for %}
文をハッシュに対して使うと、以下のように各キィ・値ペアが配列になってitem
変数に入る(配列のインデックス0
がキィ、1
が値)。
{% for item in hash %}
key: {{ item[0] }}, value: {{ item[1] }}
{% endfor %}
{% capture %}
の中で{% for %}
文をハッシュに対して用いてキィを取り出し、,
区切りのひとつの文字列を作る。
{% capture tagNamesString %}{% for tag in site.tags %}{{ tag[0] }}{% unless forloop.last %},{% endunless %}{% endfor %}{% endcapture %}
上記の例では、tagNamesString
にsite.tags
ハッシュのキィ(タグ名)が,
区切りのひとつの文字列として入る。ここで、上記の例を見た目上解りやすく改行、インデント等すると、それらも含めてtagNamesString
に入ってしまうので、余計な改行、空白は入れないように注意する。
次にtagNamesString
をsplit
フィルタで配列に変換、sort
フィルタでソートして変数に割り当てる。変数割り当ては{% assign %}
タグを用いる。
{% assign sortedTagNames = tagNamesString | split:',' | sort %}
これでsortedTagNames
はソートされたタグ名の配列になる。あとはsortedTagNames
配列を{% for %}
文に掛けてやれば、サイト内で使われている全タグをソートして一覧できる。
<ul>
{% for tagName in sortedTagNames %}
<li>{{ tagName }}</li>
{% endfor %}
</ul>
配列を{% for %}
文に掛けた場合は、各要素がそのまま一時変数に入る。上記では単にリストとして出力しているが、ハイパーリンクとして出力する際は別途タグ毎のページを作るなりしてそこへリンクを張る。当ブログでは簡易的な検索機能を実装し 、そこでタグを付けられた記事を列挙するようにしている。
ひとつのブログ記事に付けられたタグを一覧する
とあるひとつのブログ記事を出力する際に、その記事に付けられているタグを一覧する場合を考える。
記事内で使えるpage
変数のpage.tags
に、その記事に付けられたタグの文字列が配列として入っている。site.tags
ハッシュとは違い、page.tags
は文字列の配列である。したがって、そのままsort
フィルタを用いることができる。
{% assign sortedTagNames = page.tags | sort %}
<ul>
{% for tagName in sortedTagNames %}
<li>{{ tagName }}</li>
{% endfor %}
</ul>
page.tags
にはYAML Front-matterで設定した順にタグ文字列が配列として入っている。page.tags
をsort
フィルタに掛けてアルファベット順にソートし、{% assign %}
で新しい変数に割り当てる。上記の例ではsortedTagNames
にソートされたタグ文字列の配列が入る。
あとはsortedTagNames
を{% for %}
文に掛けてタグ一覧を出力するだけ。ここでも前項と同様単なるリスト要素として出力している。ハイパーリンクとして出力する際には別途タグ毎のページを作るなりして、そこへリンクを張る。当ブログでは簡易的な検索機能を実装し 、そこでタグを付けられた記事を列挙するようにしている。