mado: Markdown をリアルタイムプレビューするツール作った

Markdown のリアルタイムプレビューを行う mado というツールを作った。 世の中 Markdown Previewer なんてごまんとありそうだけど、とりあえず作った。

mado | RubyGems.org

特徴

Web ブラウザ上で Markdown をプレビュー

Markdown を HTML 整形したものを Web ブラウザ上でプレビューできる。 Github Flavored Markdown に対応している。 好きなエディタで編集しつつ、横にブラウザを開いてどんな出力になるかを確認しながら使う感じ。

また、プレビューの見た目は Github 上での Markdown プレビューになるべく似せるようにしている。 Github に上げるプロジェクトの README.md を編集するのに便利ではないだろうか。

ちなみに、Github ライクな見た目の実現には github.css に手を加えたものを使用している。

Markdown ファイルの変更を検知して、プレビューをリアルタイムに更新

Markdown ファイルを編集すると、WebSocket を通じてプレビューがリアルタイムに更新される。 リロードする必要はない。

シンタックスハイライト

fenced code-block (バッククォート3つで囲むやつ) に書いたコードはシンタックスハイライトされる。 ハイライトの色は Github 上での色に準じている。

相対パス画像展開

ローカル上にある画像を相対パス指定で表示することができる。

![local image](img/hoge.png)

スクリーンショット

screenshot

インストール

gem として提供している。

$ gem install mado

起動

mado はコマンドラインツールである。 編集したい Markdown ファイルを指定して起動する。

$ mado README.md [-p PORT] [-h HOST]

デフォルトでは8080番ポートで Web サーバが立ち上がる。 Web ブラウザで http://localhost:8080 を開くと、README.md の HTML プレビューが表示される。 あとは好きなエディタで Markdown を編集するだけ。 変更に追従してプレビューが更新される。

今のところ、WebSocket サーバが8081番ポート固定で立ち上がるので注意が必要。 どうにかしたい。

TODO

  • チェックリスト対応
    • [ ] hoge みたいなやつ
  • WebSocket サーバのポートをパラメータ化する
    • 固定は良くない

ソースコード

dtan4/mado

Issue & PR お待ちしております。

人生初の Pull Request を出した

昨晩、GitLab (gitlabhq/gitlabhq) のドキュメントにデッドリンクを見つけたので、人生初の Pull Request を出した。

Fix dead links in ruby.md by dtan4 · Pull Request #6959 · gitlabhq/gitlabhq

最初は絶対パス指定の修正をしていたけど、相対パスのほうが好ましいですね〜というアドバイスをもらって追加コミットしたりした。 たぶん初めて squashpush -f を使った。

そして今日マージしていただけたので、めでたく one of the GitLab contributors になった。

こういう感じで OSS への貢献を増やしていきたい。

Markdown を Pukiwiki 記法に変換する gem 作った

講義の関係で、しばらく Pukiwiki 上でブログっぽいのを書き続けることになった。ただ Pukiwiki 記法を新しく覚えるのが面倒なので、普段書き慣れている Markdown で書けるように変換器を書いた。

md2pukiwiki | RubyGems.org

Install

$ gem install md2pukiwiki

Usage

md2pukiwiki というコマンドを用意してある。

引数に Markdown ファイルを指定することで、Pukiwiki 記法に変換されたテキストが標準出力に吐かれる。リダイレクトで別ファイルに出力するか、パイプ経由で pbcopy してクリップボードにコピーしたりするのが良い。

$ md2pukiwiki sample.md

Ruby コード内で変換を行うには、以下のように書く。

require "md2pukiwiki"
pukiwiki = Md2Pukiwiki.convert(markdown)

Example

この Markdown が

# header
* list1
* l**is**t2
    * list2.1

## subheader
1. nlist1
2. nl*is*t2
   1. nlist2.1

こういう Pukiwiki 記法に変換される。

*header
- list1
- l''is''t2
-- list2.1

**subheader
+ nlist1
+ nl'''is'''t2
++ nlist2.1

Source code

dtan4/md2pukiwiki

VAIO Pro に Arch Linux をインストールする

2014/02/20 再インストールに伴い数カ所修正


VAIO Pro 11 を買ったので、これまでの環境と同じく Arch Linux を入れました。(これまでは ArchBang を使っていたので)素の Arch を入れるのは初めて。

なお、以下の作業は 2013-10-28 時点のものです。現在でも大体このままで大丈夫だと思いますが、まずいところは ArchWiki など参照して適宜修正してください。

準備するもの

  • VAIO Pro
  • 有線ネットワーク環境
    • USB 有線 LAN アダプタ
  • DVD-R 4枚(or 同等の容量分の光学メディアか USB メモリ)
    • 光学メディアを使うなら USB 外付けドライブ
    • リカバリメディア用
  • USB メモリ
    • LiveUSB 用

Arch Linux LiveUSB を作る

  • Mac or Linux 上で作業していると仮定)
  • iso イメージをダウンロード
    • 日本におるなら jaist あたりのミラーを使うべき
  • USB メモリを刺す
  • すぐに sudo dmesg | tail -20
    • sda:sda1 とか表示されたのを覚えておく
  • iso を USB メモリに焼く
    • dd if=/path/to/iso of=/dev/sdX bs=1M
    • sdX はさっき覚えたやつ

Windows を処分する

  • 万一のために、リカバリディスクを作っておく
  • VAIO Update をかけて BIOS とか色々最新化しておく
  • ASSIST ボタンを押すか VAIO Care (Desktop) を開く
  • リカバリメディアの作成をする
    • フラッシュメモリか、外付け光学ドライブ + 光学メディアが必要
    • DVD-R 4.7GB を4枚
    • ディスク検証のチェックを外すとさっさと終わるはず
      • 外さなかったので、作成に1時間半くらい要した
  • シャットダウン

Arch Linux のインストール

BIOS をいじる

  • USB から起動できるように BIOS をいじる
  • シャットダウンした状態で ASSIST ボタンを押して起動
  • BIOS の設定」
  • BIOS をいじる
    • [2014/02/20 追記] Intel(R) AT Support System: disabled
    • Secure Boot: disabled
    • External Media: enabled
    • Boot Order は External Media を一番上に
  • Save して Shutdown

インストール

  1. USB を刺して起動
  2. ブートローダ画面が出たらすかさず e を押す
  3. カーネルパラメータの設定に移行するので、先頭に libata.force = noncq を追加する
    • これが無いと内蔵 SSD を読んでくれない?
  4. Enter 押して Linux を起動

パーティション

  • /dev/sda1 (/boot): 512MB
  • /dev/sda2 (/): 残り全部
  • gdisk /dev/sda
  • o で全部上書き指定
  • n で新規パーティション追加
    • First はデフォルト値、Last は 512M
    • Hex code は ef00
  • プロンプトに戻るのでもう一度 n、これは全部デフォルト値でOK
  • w でディスクにパーティション書き込み

ファイルシステムを設定してマウント

mkfs.vfat -F32 /dev/sda1
mkfs -t ext4 /dev/sda2

mount /dev/sda2 /mnt
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot

LAN につなぐ

いろいろ

  • 初期パッケージのインストール
  • /etc/pacman.d/mirrorlist は jaist とか tsukuba ミラーを一番上に
vi /etc/pacman.d/mirrorlist
pacstrap /mnt base
  • fstab の設定
genfstab -U -p /mnt >> /mnt/etc/fstab
arch-chroot /mnt
vi /etc/locale.gen
locale-gen
echo LANG=ja_JP.UTF-8 > /etc/locale.conf
[2014/02/20 修正]  ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/timezone
hwclock --systohc --utc
  • ホスト名設定
echo dtan4-vaio > /etc/hostname
  • root パスワード設定
passwd

ブートローダのインストール

  • インストールプロセスで最大の鬼門
  • 最初は GRUB 入れようとして失敗しまくったので、UEFI 専用の Gummiboot を使うことにした

gummiboot

# [2014/02/20 .img はコピーせずに進める 以下4行は無視]
# mkdir -p /boot/EFI/arch/
# cp /boot/vmlinuz-linux /boot/EFI/arch/vmlinuz-arch.efi
# cp /boot/initramfs-linux.img /boot/EFI/arch/initramfs-arch.img
# cp /boot/initramfs-linux-fallback.img /boot/EFI/arch/initramfs-arch-fallback.img
# [2014/02/20 ここまで]
mount -t efivarfs efivarfs /sys/firmware/efi/efivars
pacman -S gummiboot
gummiboot install
  • /boot/loader/loader.conf は以下のように設定
# /boot/loader/loader.conf
default arch
  • [2014/02/20 修正] /boot/loader/entries/arch.conf は以下のように設定。
# /boot/loader/entries/arch.conf
title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
root=PARTUUID=<SDA2_PARTUUID> rw quiet libata.force=noncq

シャットダウン

exit
umount /mnt/*
shutdown -h now

USB を抜いて起動する 直接 Arch Linux が起動したら成功、ブートメニューが出たりエラーになったりしたらやり直し

カーネルパラメータから、先ほど設定した libata.force = noncq を削除するのを忘れないこと

Linux インストール後

適宜、自分の好きな WM を入れたりしましょう

systemctl enable dhcpcd
systemctl start dhcpcd
pacman -S xf86-video-intel xf86-input-synaptics xfce4 xorg-server
pacman -S alsa-utils
pacman -S slim slim-themes

systemctl enable slim
pacman -S xorg-xmodmap
pacman -S bluez-utils

参考

nowtv: 現在放送中の番組一覧を確認するコマンド作った

2015-01-24 22:00 追記

利用させてもらっていた API が廃止されたようで、nowtv は現在データを取得できず使用することができません。 とりあえず gem の公開と Github でのソースの公開、そして本記事の公開は続けておきますが、コマンド自体は何もできないことをご留意ください。

以下は nowtv 公開時点での記事です。


現在放送中の番組を確認できるコマンドラインツール nowtv を作った。ご利用ください。

背景

今テレビで何放送しているかな、というのを確認するのに一々ブラウザ立ちあげて番組表サイトにアクセスするのが面倒だった。コンソール上でサクッと確認したかったので作ってみた。

インストール

RubyGems で配布しているので gem install nowtv

使い方

nowtv を呼ぶと、現在放送しているテレビ番組一覧を表示する。デフォルトでは東京都の番組表。

$ nowtv
NHK総合: 仕事ハッケン伝 [16:05 -> 16:55]
NHK Eテレ: 第68回国民体育大会~スポーツ祭東京2013~ [16:00 -> 17:00]
日本テレビ: 特選ぶらり途中下車の旅 [15:55 -> 16:53]
テレビ朝日: 相棒セレクション [15:57 -> 16:53]
TBSテレビ: Nスタ [15:50 -> 19:00]
テレビ東京: L4YOU! [16:00 -> 16:52]
フジテレビ: 踊る大捜査線 [15:50 -> 16:50]
TOKYO MX: スマイルプリキュア! [16:30 -> 17:00]
放送大学テレビ: 高齢者の生活保障第1回 [16:00 -> 16:45]

東京都以外の都道府県に住んでるなら、~/.nowtv に地域コードか都道府県名を書いておくことで nowtv で表示する都道府県を設定できる。地域コードはこれ参照してください。

nowtv osaka とか nowtv 愛知 とかすると、その都道府県で今何を放送しているか確認できる。出先で便利。

$ nowtv osaka
NHK総合: 仕事ハッケン伝 [16:05 -> 16:55]
NHK Eテレ: 第68回国民体育大会~スポーツ祭東京2013~ [16:00 -> 17:00]
MBSテレビ: ちちんぷいぷい [14:55 -> 17:50]
ABCテレビ: 相棒season7 [15:55 -> 16:50]
関西テレビ: CHANGE [15:53 -> 16:48]
読売テレビ: かんさい情報ネットten. 1部 [15:50 -> 17:53]
テレビ大阪: L4YOU! [16:00 -> 16:52]

$ nowtv 愛知
NHK総合: 仕事ハッケン伝 [16:05 -> 16:55]
NHK Eテレ: 第68回国民体育大会~スポーツ祭東京2013~ [16:00 -> 17:00]
東海テレビ: リーガル・ハイ [15:54 -> 16:49]
中京テレビ: キャッチ! [15:50 -> 17:53]
CBCテレビ: 水戸黄門 [15:56 -> 16:50]
メ~テレ: 科捜研の女12 [15:49 -> 16:49]
テレビ愛知: L4YOU! [16:00 -> 16:52]

注意すべきなのは、現在放送中の番組しか表示できないことである。過去や未来の番組表は表示できない点ご了承ください。

内部実装

番組一覧を取得できる JSONP API を見つけたので、それの結果をパースして色々している。

テレビ番組表を取得できる API、意外とどこも提供してないらしくググっても見つからなかった。どっかの番組表サイトをスクレイピングするのも考えたけど、番組表の HTML 構造ってけっこう複雑で、情報抽出が面倒そうだった。

そんな中、唯一現在放送中の番組を表示できたのが Goo 番組表 で、さらにこの番組表は JavaScript で動的に生成されていた。なので Chrome の inspector でゴニョゴニョすると Ajax で呼んでる JSONP API を見つけることができた。ググッても出てこないあたり外部非公開っぽい。region_code さえ指定すればちゃんと結果返してくれるっぽかったので、今回これを利用させていただくことにした。


地域コードは完全なローマ字表記じゃない(北海道: hokk、滋賀: siga、沖縄: nawa)ので、都道府県名の漢字入力でも呼べるようにした。あとは、JSON API で取得できる番組名が全角英数全角スペースだったのでそのへん半角に直してる。


テスト書くのに webmock 使ったけど、これみたいに外部 API 呼ぶツール書くのには非常に便利で良かったです。

API の説明書いてて

確認したら、普通の番組表も似たような JSONP API で取れるっぽかった…うーん

ソースコード

dtan4/nowtv

東京アメッシュをコマンドラインから利用できるツール ramesh を作った

昨日は多摩の方まで走りに行ったら、帰りがけにゲリラ豪雨にあってしまった。尾根幹の陸橋下で30分くらい雨宿りしとった。

東京都下水道局が提供する東京アメッシュという素晴らしいサービスが有る。現在から2時間前までの5分間隔で、南関東一帯の降水量を確認することができる。特に都内の観測範囲は緻密。ゲリラ豪雨が発生するとその地点が局地的に赤くなるので、「ゲリラ豪雨が近づいてきそうだ」という予測を立てるのも容易。

で、この素晴らしきサービスをコマンドラインから利用できるツール ramesh を作った。アメッシュ確認するのに一々ブラウザ開きたくない人ご利用ください。

なにこれ

東京アメッシュが提供している降水量レーダー画像をダウンロードするツール。現在の画像はもちろん、過去に遡っての画像取得も可能。

インストール

ImageMagick が必要。画像合成処理をしているので。

ramesh は gem として公開しているので普通に

$ gem install ramesh

でインストールできる。

つかいかた

引数を指定しないと、現在のレーダー画像をダウンロードする。

$ ramesh

過去の画像を取得することもできる。分は0-120の間、5分単位で指定する必要がある。以下の例だと90分前の画像をダウンロードする。

$ ramesh 90

範囲を指定して、複数枚の画像を取得することもできる。以下の例だと50分前から120分前まで5分間隔で、合計15枚の画像をダウンロードする。

$ ramesh 50-120

ソースコード

github - dtan4/ramesh

技術情報

ブラウザに表示されるアメッシュのレーダー画像は、3枚の画像が重なりあったものである。上から順に、

  • 都県名・都県境の画像 /map/msk000.png
  • 降水量メッシュ画像 /mesh/000/yyyyMMddhhmm.gif
  • 地形図 /map/map000.png

このうち、上2つは背景透過がなされているので、重ねるといい具合に表示できる。ramesh は3枚それぞれをダウンロードしてきて、それらを合成したものを1枚の gif として保存している。

また、現在アメッシュのサーバに保存されているメッシュ画像の一覧は以下の JavaScript ファイルに書いてある。これをパースすれば画像ファイル名をとれる。

http://tokyo-ame.jwa.or.jp/scripts/mesh_index.js

余談

今は自宅鯖で ramesh を cron で回してデータ蓄積しとる。10日間で3300枚、770MB 超。時折溜めた分引っ張ってきてパラパラ漫画見たくアニメーション作ったりしとる。

初めての gem なので、先人の書いた gem を色々参考にしながら書いてみた。とりあえず大体の流れはつかめた感じ。

GPS データ (GPX) から移動距離を求める

GPS データから走行距離を計算したくて、緯度経度を用いた距離計算法を調べてみた。そしてスクリプト書いた。

2点間距離を求める

緯度経度を用いて距離を測定するには、ヒュベニの公式を使うのがわりとポピュラーそうだった。この式は、3D地図ソフトのカシミール3Dで使われていたりする。

カシミール / 計算式に載っている式を転載すると、

D=sqrt((M*dP)*(M*dP)+(N*cos(P)*dR)*(N*cos(P)*dR))

       D:  2点間の距離(m)
       P:  2点の平均緯度
       dP: 2点の緯度差
       dR: 2点の経度差
       M:  子午線曲率半径
       N:  卯酉線曲率半径
       M=6334834/sqrt((1-0.006674*sin(P)*sin(P))^3)
       N=6377397/sqrt(1-0.006674*sin(P)*sin(P))

こんな感じ。

もう少し詳しい解説はこのページにのってる。今回はここを参考にした。

二地点の緯度・経度からその距離を計算する(日本は山だらけ〜)

基本上ページ Fig.1 の通りにプログラムを書けばいいけど、ヒュベニの公式で用いる緯度経度はラジアンであるのに注意しなければならない(ハマった)。GPS で記録される緯度経度は勿論なので変換する必要がある。

# deg(度)から rad(ラジアン)を求める
rad = deg * Math::PI / 180

高校数学を思い出す。

あと、子午線曲率半径の算出に長半径(赤道半径)・卯酉線曲率半径を求めるのに短半径(極半径)が必要だけど、今回は GPS に使われるらしい WGS84 基準のパラメータを用いた。

測定誤差

地球は楕円体だしということで、やっぱり計算結果に誤差は出てくる。下のページで検証がなされている。

緯度経度から2点間の距離を求める | ぷちのいず

上のページによると、ヒュベニの公式を用いた場合は50km以上から誤差が大きくなるらしい。今回は自転車の走行距離を(主に)算出したいので、結果は高々200kmといったところ。まあ問題ないということにした。

GPX ファイルから移動距離を計算する

以上の計算を、GPX ファイル(GPS データを格納する XML)に記録されたトラックポイント間に対して行う。

GPX ファイルの中身は XML になっている。構造の説明は置いといて、トラックポイントの緯度経度は trkpt タグに属性値として記録されている。こんな感じ。

<trkpt lat="35.765263255" lon="139.867893811">

こっから lat (緯度)と lng (経度)を正規表現抽出して配列に格納。全部抽出し終わったら先頭から各要素間の距離を求めていく。ラジアン変換も忘れずに。その総和が移動距離になる。

そうしてできたのがこの Ruby スクリプト。

Gist: gpx_distance.rb

実行

昨日は東京から印旛沼の風車までロングライドした。そのときの走行距離を調べてみる。

$ grep "<trkpt lat=" 130608.gpx | wc -l
    8550

この GPX ファイルには8550個のトラックポイントが記録されている。記録された移動距離は、

$ time ./gpx_distance.rb 130608.gpx
129.792 km
./gpx_distance.rb 130608.gpx  0.63s user 0.07s system 99% cpu 0.701 total

こんな感じで求まった。

ちなみにサイコン (CC-RD200) では126.99kmとなっている。まあ測定誤差測定誤差・・・

あと、ルートラボの距離のは6kmくらい少ないのが表示されてるけど、これは GPX を投稿する際に最初と最後を削った影響である。個人情報的なアレと8000ポイント制限で。

最後に

自転車乗りで、ログ取りたいけどガーミンとか手が出せない・・・って人は秋月で売っとる3000円以下のロガー買ったら幸せになれる。このへん別に記事書きたい。

USB接続GPSモジュール(GPSデータロガー)GT-730F/L

ルートラボ、良いんだけど Silverlight いい加減取りやめてくれませんかね・・・それか JS 版をもっと使えるレベルにしろと・・・