詩と創作・思索のひろば

ドキドキギュンギュンダイアリーです!!!

はてな記法 ⇔ Markdownコンバータ(pandoc のはてな記法対応)

最近の若者ははてな記法を書けないらしい……などと言っているだけではアレなのでコンバータを書いてみた。リストを書こうとして見出し(*)になっちゃうんですよね。あるある。

タイトルにあるとおり、pandoc という有名なマークアップコンバータにはてな記法を実装してみた形です。

github.com

フォークした1ブランチとしてソースコードがあるのみで、バイナリの配布とかはしてない。Haskell 製なので Stack をインストール(Homebrew なら haskell-stack)しておいて、make したらビルドできると思います。

pandoc の reader(マークアップの読み取り)および writer(マークアップの書き出し)として hatena を追加しているので、

pandoc -f hatena -t markdown_github < file.hatena

のように引数に指定して記法を変換できます。Markdown と書いたけど、pandoc がすごいので HTML や他のフォーマットにも変換可能。

parsec の思い出

pandoc の記法リーダの実装は parsec というライブラリに依っている。自分は Pugs という Haskell で書かれた Perl6 実装が話題になったころに Haskell でナイーブな JavaScript のインタプリタを書いてみたときに使って、そのとき以来触った覚えはなかったのだけど、意外とハマることも少なくすんなり実装できた。パフォーマンスはともかく。

調べてみたら Pugs は 10 年も前の話で、その頃の知識が今もまだ使えていることになんだか不思議な感じがある。

ミニマルはてな記法

先日のそうだGo、京都。でも話があったらしいが、はてな記法は実装の数だけ存在していて、単純なマークアップの範疇を越える仕事もしているので(:title による自動ページタイトル取得など)簡単に統一することはできないのだけど、そうは言っても実装する人たちの中で共通している認識はあるはずだと思っている。それをミニマルはてな記法と勝手に呼んで、それを実装してみた。公式なものではありません。

できれば仕様を書きたかったのだけど、大変なので、さしあたり以下のサンプルを用意した。これを意図通りに読み書きできるようなものとして実装した。pandoc を使って Markdown に変換したものもあわせて Gist に載せているので、どんなふうに解釈されるかわかりやすいと思う。

YAPC::Kansai 2017 OSAKAで『はてなシステムの考古学』というトークをおこないました #yapcjapan

先日開催された YAPC::Kansai 2017 OSAKAで、『はてなシステムの考古学』というタイトルで発表しました。

スライド中のリンクが効かないのであまり意味がないのですが、一応 Speakerdeck にも上げてあります: はてなシステムの考古学 / History of development at Hatena // Speaker Deck

はてなの開発の歴史を Perl エンジニア視点からふり返るというもので、どちらかというと『はてなの開発の歴史学』とでも読んだほうがしっくりくる内容になりました。

具体的な成果物を伴わない話をするのは苦手なほうだと思っていましたが、今回はあえてこんな内容でトークすることになりました。その背景には、いつの間にか自分が社内でも古参のエンジニアになっていたこと、また、事業や組織の拡大とともに開発のあり方が多様化してきて、それまで暗黙的に共有されてきたものに頼ることが困難になってきた感覚があったのだと思います。

なぜ歴史を語るのか

発表の参考にした『歴史とは何か』より、

歴史とは歴史家と事実との間の相互作用の不断の過程であり、現在と過去との間の尽きることを知らぬ対話なのであります。

と発表中に引用したとおり、歴史とは過去を語るだけでなく、過去のほうからも現在(と自分自身)を語ることでもあります。たとえばスライドでいうところの近代以降、フレームワークは時代の空気とでも呼べるものになったわけですが、普通にしていては明らかではないその実体に、歴史を通じて光を当てることができるのではないかという試みでもありました。

また同書より、

歴史というのは、獲得された技術が世代から世代へと伝達されて行くことを通じての進歩ということなのです。

歴史における進歩は、[…]獲得された資産の伝達を基礎とすること、[…]この資産は、物質的所有物と、自分の環境を支配し変更し利用する能力との両方を含んでいます。

……ということで、継承されてきた技術や思想、という観点から現在の自分たちの開発の現状を省みることで、新たに入社した人たちにもなぜ今がそうあり、未来にどうなっていくべきなのかということが、点ではなく線のようにイメージできるのではないかと考えたのでした。

準備にあたっては、エンジニアたちの過去の発表資料が当時を語るものとして非常に役に立ちました。少し前までは、はてなのエンジニアの大きな発表機会といえば YAPC::Asia で、京都から何人も出張するのでお祭り感があった(今もそうだけど)ものでしたが、つい最近であれば try! Swift や DroidKaigi ほか、それぞれの言語や技術分野コミュニティの大きな集まりにエンジニアたちが積極的に顔を出していて、あるべき姿に多様化してきているのだなと感じます。

そして振り返ってみるとこういう外部への発表こそが、自分たちの内に暗黙知として蓄えられていたものを整理する、SECIモデルでいうところの形式知への表出化の機会でもあったのかな、とも思います(この発表も、それがないとここまでちゃんと考えなかっただろうということも含めて)。

歴史とは何か (岩波新書)

歴史とは何か (岩波新書)

知識創造企業

知識創造企業

リンク集

スライド中で言及した・作成の参考にした資料へのリンクを記しておきます。

go-sql-driver/mysql の接続に SOCKS5 プロキシを利用する

Go では proxychains みたいな方法が利用できないので、プログラム側で対応してやる必要がある。Go で SOCKS5 プロキシを利用する - 詩と創作・思索のひろば と同様に golang.org/x/net/proxy を利用して実現できる。

import (
    "database/sql"
    "net"
    "golang.org/x/net/proxy"
    "github.com/go-sql-driver/mysql"
)

func main() {
    dialer := proxy.FromEnvironment()
    mysql.RegisterDial("tcp", func(network string) (net.Conn, error) {
        return dialer.Dial("tcp", network)
    })

    db, err := sql.Open("mysql", dsn)
    ....
}

という感じ。DSN を変える必要はない。

all_proxy=socks5://127.0.0.1:10000 などと環境変数を設定して起動してやる。