Markdownの文章をHTML化して同ネットワーク内の別デバイスから見られるようにするまで

普段、日本語文章による原稿はMacVimで書いてるのだけど(といっても日本語以外の文章は書いてないので「すべての原稿」と言うべきかもしれないが)、最近めずらしく原稿をMarkdown形式で納品する機会があったので、それに関連するハック。

前提

第一に、ぼくが普段Markdownで文章を書く場合、HTMLにレンダリングするということはほとんどない。

というのも、ぼくがMarkdownを使うとしたらそれは文章の「構造化」のためであって、「見栄え」のためではないから。

もう少し具体的に言うと、これは3月のYAPC::Okinawaの発表でもけっこう説明したのだけど、

(この動画の21分9秒ぐらいから。一応そこから始まるはず)

www.youtube.com

画像にするとこんな感じで、

gyazo.com

これはこれでちょっとわかりづらいんだけど、ようは左カラムにあるMarkdown形式の文章のうち、「#」や「##」で始まる見出し部分だけが右のサイドバーに列記されている。

で、これはVimプラグインのtagbarとか、ctagsの設定などを組み合わせて実現しているんだけど、この辺の作り方については上記の動画でも紹介したとおり、以下のSoftware Design誌で @mattn さんが詳しく説明していたのを参考にしてる。

これの何がいいかっていうと、左の文章全体の構造が、右の見出し一覧を見るだけで大体つかめるということ。

右の方をちょっと眺めれば、わざわざ文章全体を上に下にとスクロールしなくても、どの見出しの前後にどんな見出しがあるか、みたいな大まかな流れがわかる。

ちなみに、この画像にあるのはscholaという音楽全集の企画で「ロマン派音楽」を扱ったときのテキストだけど、クラシック音楽のビッグネームであるところのワーグナーやリストやブルックナーといった人たちの当時のリアルな関係、とくには時系列的なつながりが、素人にはなかなか把握できない入り組み方をしていて、作業の終盤に入っても「あの話題はあの話題より先だっけ、後だっけ・・」みたいな整理がつきづらかったので、この見出し一覧機能は本当に重宝した。

話を戻すと、こういうことが出来る、というのがぼくにとってのMarkdownの一番の利点であって、だからわざわざHTMLに変換して眺めることはほとんどない。

なんだけど、じゃあこのMarkdownファイルを他人に見せよう、あるいは仕上がりとして納品しよう、となったらまた事情が変わってくるわけで、とくに仕上がりデータとして渡すということは、渡された相手は当然、HTML変換後の姿を見るわけで、それなら僕もブラウザでの見え方を確認しながら文章を仕上げていかなくてはならない。

ということで、そういうときに役立つのがprevimというウルトラ神プラグインで、

github.com

これについては多分、このブログでも幾度となく紹介しているので多くは語らないけれど、ざっくり動画化してみるとこんな感じで。

gyazo.com

右側のVimに書いた内容が、左側のブラウザの方にリアルタイムに反映されていく。(このときはややもっさりしてるけど・・作業中はそんなに気にならず快適)

ただ、これも一人の作業だったらこれだけで十分なんだけど、他人との協業ということを考えると、「あ〜、今このブラウザで自分が見てる最新データ、そのまま他人にもリアルタイムで見れるようにしたいな〜!」なんて思ってしまう。

先回りして言っておくと、これ、べつにVimにこだわらなくていいなら、ScrapboxとかGoogleドキュメントを使えばそれで解決する。

とくにScrapboxは軽くて快適で、目的さえ一致すれば非エンジニアも含めて誰でも入りやすいツールなので良いと思う。

しかし問題はVimにあるというか、ぼくはあくまでMacVimという自分の執筆環境を維持しながら、また自分ではこのprevimを使いたいという前提があるので、それらを使わない選択肢はここでは外れる。

で、どうしたらいいのか・・といろいろ考えたり試したりしたのだけど、結論的には、

1. VagrantLinuxを立ち上げる。
2. その中でnginxを立ち上げる。
3. Rijiを使ってMarkdownファイルをブログ(HTML)化する。
4. 2のサーバーとVagrantの共有フォルダ機能を組み合わせて、3のHTMLページを同ネットワークから誰でも見られるようにする。

という方法が一番イメージに近いかなと思っている。

手順

ということで、以下はそれを実現する手順。

まず、Vagrantでnginxを立ち上げるところまでは、以前に書いたこの記事でほとんど行ける。

note103.hateblo.jp

ただし、その記事を書いたときからけっこう時間も経っていて、実際に今回やったこととは多少なりズレがあるので、この機会に少しアップデートしておく。

Vagrantの準備

初めにVirtualBoxVagrantをダウンロード&インストールしておく必要があるけど、その辺りの基本的な部分についてはドットインストールさんにお任せ。
(2013年のレッスンだけど、概念的なことは変わらないと思う)

https://dotinstall.com/lessons/basic_vagrant

その上で、以前の解説記事では ubuntu/trusty64 というVagrant boxを使っていたのだけど、今回は公式サイトのクイックスタートガイドで紹介されていたhashicorp/precise64というboxを使ってみる。*1

www.vagrantup.com

ではさっそく、今回作業するディレクトリを作って&入って、上述のboxを指定してvagrant init.

$ vagrant init hashicorp/precise64

このとき、もしまだこのVagrant boxを入れていなかったら、インストールにはけっこう時間がかかる。どのぐらいか? boxにもよるけど、5〜10分ぐらいは見ておいた方がいいかも。

Vagrant boxのインストール&initが完了すると、ディレクトリ内にVagrantfileができる。これはなんだろう、設計書みたいなもの? かどうかはわからないけど、ともかくそれをエディタで開いて、30〜35行目ぐらいに以下を挿入。

config.vm.network "public_network", ip: "10.0.1.100", bridge: "en0: Wi-Fi (AirPort)"

IPアドレスは経験的にその辺が間違いないので使っているけど、なぜそれを使っているかは自分でもわかってない。とりあえず雰囲気でそのアドレスにしている。

またその挿入箇所、実際には1行目でも100行目でもいいと思うのだけど、その近辺にこれがあるので、

  # config.vm.network "private_network", ip: "192.168.33.10"

自分の場合はその下にそれを並べている。

なお、今回共有したいページを他人のマシンや自分の他デバイスから見る必要がなければ、上記のpublic_networkは使わずに、そのprivate_networkのコメントアウトを外すだけでもOK。
ただし、それなら別にVagrant使わなくても、後述のRiji や、あるいは@mattnさんが作ったmemoアプリのサーバー機能を使って閲覧するだけでもいい気はする。

mattn.kaoriya.net

Vagrantfileの編集が終わったら、保存してからおもむろにvagrant up & ssh

$ vagrant up
$ vagrant ssh

これで、Ubuntuの中に入った状態。

nginxを動かす

次、nginxのインストールと起動。これはまったく以前の記事に書いたまま。

$ sudo apt-get update
$ sudo apt-get install nginx -y
$ sudo service nginx start

ステータスを確認。

$ service nginx status
 * nginx is running

で、先ほど設定した http://10.0.1.100/ を見にいくと・・

f:id:note103:20180613131605p:plain

OK。

共有フォルダの設定

次に、ローカルなHTMLファイルを今立ち上げたサーバー経由でブラウザから見られるようにする。

この手順も以前の記事とほぼ同じなんだけど、前に使ったubuntu/trusty64だと/usr/share/nginx/htmlというディレクトリにアクセスしていたのが、今回の場合は最後がhtmlではなくwwwなので、そこがちょっと違う。

具体的には、こんな感じで操作した。

$ cd /usr/share/nginx/
$ sudo cp -r www www_orig
$ ls
www www_orig
$ sudo rm -rf www
$ ls
www_orig
$ sudo ln -s /vagrant www
$ ls -F
www@ www_orig/
$ ls www
Vagrantfile

これで、ローカルの作業ディレクトリとサーバーがつながった状態。

では試しに、そこにhello.htmlなど作ってみる。(最小限で・・)

<!DOCTYPE html>
<body>
  <h1>Hello World!</h1>
</body>
</html>

で、アクセス。

f:id:note103:20180613135700p:plain

OK。(でかい)

ちなみに、この一連の環境構築作業、Vagrantfileにシェルスクリプトで設定してやると、最初の vagrant up コマンドだけで一気に終わる。かなり便利。

具体的には、こんな感じのコードを入れる。(ファイルの終盤にシェルスクリプト用のひな形が用意されていたので、一瞬で出来た)

  config.vm.provision "shell", inline: <<-SHELL
    sudo apt-get update
    sudo apt-get install -y nginx
    sudo service nginx start
    sudo cp -r /usr/share/nginx/www /usr/share/nginx/www_orig
    sudo rm -rf /usr/share/nginx/www
    sudo ln -s /vagrant /usr/share/nginx/www
  SHELL

たしかVagrantの理念というか思想として、「vagrant up 一発で全部終わるってふうにしたかった」的なことを何かの本で読んだけど、たしかにこれで事前にやりたいことはほぼ終わってるのでスゴイ。

Rijiとつなげる

さて、元はと言えば、手元のMarkdownファイルを簡便な方法で他者・他デバイスからも見られるようにしたい、という話だった。

で、ここまでの作業によって、ひとまず「HTMLページさえできていればどこからでも閲覧できる」という状況になっている。

よってここからは、「手元のMarkdownファイルをササッとHTML化する」方法に入るわけだけど、そのためにここで使うのが、Perl製のシンプルなMarkdown用ブログツール、Riji。

github.com

ぼくはPerlに馴染みがあるのでこれを使っているけど、JekyllやHugoでも似た感じにできる気はする。

Rijiの使い方については、作者の@songmuさんによるチュートリアルがわかりやすい。

Riji tutorial

もしまだモジュールが入ってなかったら、とりあえずcpanmでインストールしてから、今回のブログ環境をサクッとセットアップ。

$ cpanm Riji
$ riji setup --force

2行目でforceというオプションを入れているけど、これはデフォルトのsetupコマンドが空ディレクトリでの操作を前提にしているからで、すでにディレクトリ内に他のファイルが入っている場合は、このforceを付ける。

今回は作業ディレクトリにVagrantfileなどが入っているので、このオプションを入れている。

この時点でtreeを見ると、こんな感じ。

.
├── README.md
├── Vagrantfile
├── article
│   ├── archives.md
│   ├── entry
│   │   └── sample.md
│   └── index.md
├── cpanfile
├── hello.html
├── riji.yml
└── share
    └── tmpl
        ├── base.tx
        ├── default.tx
        ├── entry.tx
        ├── index.tx
        └── tag.tx

4 directories, 13 files

このうち、今回の主役であるMarkdownファイルをどこに収納すればいいかと言ったら、上から5番目のarticle/entryディレクトリに入れる。

また、RijiはMarkdownファイルをGit管理しながらブログ化していくので、新たなファイルを作ったり、更新したりした場合には、HTML化する前にコミットしておく。

その後、後述のブログ生成コマンド(riji publish)を叩くと、Vagrantfileやarticleディレクトリなどと同階層にblogというディレクトリができて、その中にHTMLファイルがダダダッと入ってくる。

今回は、すでにarticle/entryディレクトリの中にサンプルのMarkdownファイルが入っているので、それを表示してみる。

riji publish

RijiでMarkdownファイルからブログページ(HTML)を生成するには、本来であれば、以下のコマンドを使う。

$ riji publish

しかし、ここでひとつ注意点。いま「本来であれば」と書いたとおり、この機会ではそのコマンドだけでは足りない。

というのも、なぜかこのコマンドを打つと、HTMLファイルが生成されるblogディレクトリのパーミッションがそのつど700になってしまって、肝心のブログページがブラウザから見えなくなってしまうから。

よって、このコマンドにパーミッション処理も加えて、こんな感じにする。

$ riji publish && chmod 755 blog

と同時に、これを毎回打つのは苦しいので、.bashrcにこんなエイリアスを入れておく。

# .bashrc
alias rjp="riji publish && chmod 755 blog"

これでぼくの場合は、rjpと打てばそのつどMarkdownファイルがHTMLページに変換されることになる。

最後にもう一つ、ブログのルートディレクトリにriji.ymlという設定ファイルがあるのだけど、この中のsite_urlという項目にブログのトップページを仕込んでおくと大変便利になる。今回の場合は、こんな感じ。

site_url: 'http://10.0.1.100/blog/'

これで、ブログ内をリンクでスイスイ動けるようになる。

結果

ページ生成後のブログトップはこんな感じ。(MacBookGoogle Chromeから見たところ)

f:id:note103:20180614000901p:plain:w300

iPhoneSafariから見ると、こんな感じ。

f:id:note103:20180614112109p:plain:w300

そのままトップページからSampleページ(sample.mdで作ったもの)に移動すると、こんな感じ。

f:id:note103:20180614112124p:plain:w300

グレイト。

まとめ

一連の流れをまとめると、VagrantとRijiの設定をした上で、

  1. Markdownで記事を書く。
  2. 作業リポジトリの article/entry にファイルを置く。
  3. git add && commit
  4. riji publish (&& chmod 755 blog)

とすれば、上の例なら http://10.0.1.100/blog に行けばHTML化された同記事を見ることができる。

デザイン

以下はオマケ。ここまで来ると、もうひと押し、デザインにも少し手を入れたいと思えてくる。

デザインについては、チュートリアルのこの辺りでテンプレートの編集方法が解説されているので、参考になる。

http://songmu.github.io/p5-Riji/blog/entry/005_template.html

ぼくがどうしているかと言うと、まずshare/tmpl ディレクトリにあるbase.txを開いて、上の方にあるBootstrap CDNのリンクを別の好きなものに入れ替えている。

Bootstrap CDNについては、こちらがわかりやすかった。(サワリしか読んでいないけど)

codezine.jp

デザインはいろいろググった結果、ここから選ぶのが良さそうだった。

www.bootstrapcdn.com

今回はその中から、Unitedというのを試してみる。

Bootswatch: United

変更前のこれを・・

  <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/css/bootstrap.min.css" rel="stylesheet">

これにする。

  <link href="https://stackpath.bootstrapcdn.com/bootswatch/4.1.1/united/bootstrap.min.css" rel="stylesheet">

またついでに、現状だと全体に左上の方に寄っているので、少し右下に動かしたい。
さらについでに、フォントを少し大きくしたい。
ということで、諸々雑にこんな感じで追記。

<div style="margin-top : 30px">
<div style="margin-left : 5%">
<div style="margin-right : 5%">
<font size="+1">

変更前。

f:id:note103:20180614133053p:plain:w300

変更後。

f:id:note103:20180614133111p:plain:w300

iPhoneから見たところ。

f:id:note103:20180614151100p:plain:w300

オッケー。

感想

長文を書いていると、避けがたく誤字脱字や壊れた言い回しなどが生じてくるが、これに自分で気づくのはなかなか難しい。

その理由としては、書いている人間が「そこに何が書いてあるのか」を誰よりも知っているがゆえに、「あまりきちんと読み直さないから」ということがあるだろう。

言い換えれば、「飽きるから」。

しかしこのような、個人の日記レベルの文章ならばともかく、他人に見せる、それも仕事として渡す前提の文章だったら、「飽きるから」なんて理由で不備だらけの文章を作ることもできない。

そのようなとき、その「飽き」を解消する方法として有効なのは「他人になること」で、一番簡単なのは時間を空けてまた読むことだろう。

しかしそれだけの余裕もないのなら、読む環境を変えるのがいい。ここで言う「環境」とは、場所もそうだけど、おもにはデバイス
ついでに、ページの背景やフォントなどの見栄えが変わればなお新鮮に読めるかもしれない。

文章(ページ)の見え方が変わると、自分の中に擬似的な時間移動が生じて、まるで他人の書いた文章のようにそれを読むことができる。

同ネットワークにいる他人に読ませる方法としても、他人のような自分に読ませる方法としても、本記事の手法は地味に役立つように思う。

*1:以前はドットインストールさんの何かの解説動画でtrusty64を使っていたからそれに準拠したのだけど、今回念のため探したらその動画が見つからなかったのと、とりあえず公式のスタートガイドにあるものを使った方がより安心かと思ったので。