PureBuilder Simplyと新しいサイトのお話

PureBuilder Simply

デザイン

PureBuilder Simplyは従来とは大幅に考え方を変えた。

従来は基本的に「いっぺんの処理ですべて行う」というものであった。 このため、特に難しかったのが、ACCSにおける「前後の記事へのリンク」である。

PureBuilder Simplyは処理が分離されている。 一番基準となるスクリプトはデフォルトで全記事を処理する。 そして、全記事のメタデータをデータベースに書き出すのである。

従来はPureDocメタセクションに直接書くという方法をとってきた。 そのため、ドキュメントが処理時に変更されるのだが、これは扱いにくい側面が結構あった。

従来のPureBuilderはドキュメントごとに処理するようになっており、 メタデータはドキュメントにある。 そのため、処理時には「そのドキュメントのメタデータしか知らない」状態であった。

今回のPureBuilderもすべてのドキュメントのメタデータを読み込むことはしないが、 すべてのドキュメントのメタデータの書き出しは行う。

メインスクリプト以外については、このスクリプトが書き出したデータベースに基づいて処理を行うため、 すべてのドキュメントのメタデータを知った状態で処理することができる。

Frontmatter

もともとPureBuilderはPureDocを前提としていて、Markdown supportはPureBuilder2で採用された。

Markdown Supportを採用したのはWindowser向けのフレンドリーシュガーであり、 Mimir Yokohamaでサービスを展開するにあたって、記述の難しいPureDocではなく、 記述しやすいMarkdownで書けるようにすることで「ユーザーによる更新の容易さ」を向上させる目的があった。

この時点でMarkdown YAML Frontmatterのことを知らなかった。 そのため、従来のPureBuilderではMarkdownドキュメント中にHTMLコメントを入れ、その中にPureDoc meta headerを入れるという仕様になっていた。

だが、そもそもMarkdownにYAMLでメタデータを書ける仕様である。 同じYAMLのメタデータなのだから、これに従うべきだ。

そのため、PureBuilder SimplyではMarkdownドキュメントのFrontmatterを必須としており、 frontmatterが存在する前提で処理する。 (titleメタデータが必須であるため、どのみちfrontmatterは必須となる)

さらにReStructured Textに対応したが、これも先頭にコメントを入れてYAMLでヘッダを書く、という仕様とした。 次のような具合である。

ReSTなら

Pandoc

PureBuilder Simplyはドキュメント処理をPandocにゆだねている。

これは別に手抜きというわけではない。従来にしてもMarkdownの処理はKramdownによって行っているのであり、 PureDocの実装は別なので特にPandoc採用でアウトソーシングしたという感はない。

Pandocの利便性と「標準性」から、「Pandocを主としてPureBuilderは補助であるほうがユーザービリティが高い」と判断したのだ。

PureBuilder Refinedでは新しいPureDoc Zをサポートする予定だが、 PureBuilder Refined自体がPureBuilder Simplyでは不足の場合に限られるので微妙かもしれない。

「事前生成」戦略

PureBuilderは言葉の意味としてはCMSで合っているのだが、どちらかというとCCS(Content construction system)に近い。 基本的に生成機能だけで、管理に関してはシステムの標準的機能でなるべく簡単てにできるようにしている。

一般的なCMSとの最大の違いは、「Webアプリケーションとして動作しない」ということだろう。 原則としてPureBuilderは(ホームページビルダーなどで書いた場合と同様に)ローカル環境でウェブページを組み上げ、そのままアップロードすることで動作する。

従来のPureBuilderにあった、Webアプリケーションとして動的に生成するためのプラガブルな仕様は現時点ではPureBuilder Simplyにはない。 予定もされていない。単一ページのサポートは限定的で、原則としてディレクトリ単位でビルドを行う。 全体ビルド機能も排除された。

より「サイトを構築するためのスクリプト」という点に特化した。

私のウェブコンテンツ生成は可能な限り「事前生成戦略」をとっている。 通常、ページは書く回数よりも読まれる回数が多いので、コストのかかる処理は1度だけ行いたい、という方式だ。

これは構造的に最速の方式でもある。

ウェブサイトの仕組みを考えればわかるが、たとえばWordPressでは

  1. ウェブサーバーが接続を受け付ける
  2. ウェブサーバーがPHPプロセスにWordPressを渡す
  3. WordPressがデータベースにアクセスする
  4. データベースから必要なデータを受け取ったWordPressがページを生成して返す
  5. ウェブサーバーが応答する

という手順になる。 WordPressのキャッシュ機能ではWordPressはデータベースから受け取った結果を処理せずにそのまま応答するため、高速化するのだが、 それでもこの接続にかかる時間が決して小さくない。

対して、静的ファイルならば

  1. ウェブサーバーが接続を受け付ける
  2. ウェブサーバーがファイルを読み込んで応答する

とプロセスが少なくなり、より高速だ。 WordPressの高速化手法も、PureBuilderが同様の手法を適用すればさらに高速する。

さらに、ウェブサーバーにとって静的ファイルの応答は基本的機能であるため、 より高速なウェブサーバーが選択できる、というメリットがある1

また、静的ファイルのみでウェブサイトの構築が可能なことで、ウェブサーバーの選択肢が増える。 PHPが動作しないGeocitiesやGitHub Pagesでも構築可能だ。

Mimir Yokohama新サイト

新サイト開設

Mimir Yokohamaの新ウェブサイト開設は、主に「異様にサイトが重くなっている」という事情からきているのだが、 実はそもそもPureBuilder Simplyはこの新サイト構築のために書き直した。

Aki SIE新サイト開設時もそのためにPureBuilder2を作ったのだが、 PureBuilder2が6ヶ月も要したのに対して、作業時間で4日、経過時間でも9日と非常に速く書き上がった。 やはりデザインは大事だ。

そして当然ながら、Mimir YokohamaウェブサイトがPureBuilder Simplyのデビュー戦となった。

「楽」という言葉の意味

Mimir Yokohamaのウェブサイトの出来には非常に満足している。

だが、この開発において“PureBuilder Simplyの開発”は全行程における30%程度でしかなかった。

PureBuilder Simplyを使ったサイトは非常に「楽」であり、「簡単」なのだが、誤解してはいけない部分がある。

今回はWordPressからの移行であるため、WordPressで利用している機能に近い状態を狙った。 デザイン的にも近く、バックエンドの変更や、それによって品質が低下した印象を与えないようにしている。

まず言っておくと、「WordPressのサイトを欲している」のであれば、PureBuilderを採用するよりも、 WordPressを採用したほうが確実に楽にできる。 なぜならば、そもそも欲しているのはWordPressなのだから、WordPressよりも楽にはならない。

そもそもPureBuilder Simplyによる構築と、WordPressによる構築はちょっと話が違うのだ。

WordPressの場合、テーマ機能やプラグインなどは既に揃っている段階から話をはじめる。 PureBuilder SimplyはそもそもWordPressではできない完全なカスタマイズを実現するという前提があり、 WordPressで言えばテーマやプラグイン、CSSなどを「すべて0から記述するところからはじめる」というのと同じ位置にある。

もしもWordPressをその位置ではじめるという形で条件を揃えたならば、PureBuilder Simplyのほうが「楽だ」と断言できる。

実際はそのような条件では比べないと思うのだが、逆にWordPressに合わせて構造やビルドの仕組み、テンプレートやCSSなどがすべて揃った状態からはじめるならば、 これもPureBuilderとしてはそこまで分の悪い勝負ではない。

なぜならばその状態で必要なことは

  • 文書を配置したい場所に新しくファイルを作り、MarkdownまたはReSTで書く
  • PureBuilderのバッチスクリプトを実行する
  • Gitでcommit&pushする

というだけのことだからだ。

「設定ファイルを書く」「コマンドを実行する」というあたりに、「Unixer的な楽さ」の感覚があるが、 これに関しても別にお客様に納品するときにはちょちょいと調整すれば良い話だ。 若干手順が多いようにも感じられるが、実際はWordPressの場合は

  • ログインページにアクセスしてログインする
  • ダッシュボードから新規記事の投稿を選択する
  • ページ上で文章を書き、タイトルやカテゴリなどを選択する
  • 投稿ボタンを押す

という手順で、慣れてしまえば麻痺するが、かなり手順は多い。 私が使っているWordPressサーバーは遅く、1クリックあたり1分とか待たされるので、 「WordPressは手順が多くて面倒」という印象が強い。 あちこち飛んではキーボードとマウスを持ち帰るUIも嫌いだ。

もし、PureBuilder Simplyでできることと相当のものとして、 「WordPressもデザインや挙動をカスタマイズする」 という条件にしたならば、これはPureBuilder Simplyが有利だろう。

PureBuilder Simplyを採用するのは「入り口」

だが、実際はPureBuilder Simplyの採用というのは全行程においてそこまで大きなものではない。 おそらく、PureBuilder Simplyのデフォルトで作られたサイトには誰もが失望するだろう。

PureBuilder Simplyの場合、「テンプレート」と「CSS」という要素がある。 これを書くのは、PureBuilder Simplyで「簡単にしている」部分ではないところであり、技術者の腕のみせどころだ。

最近はwebといってもCMSありきのエンジニアが増えていて、HTMLやCSSを直接記述することができない人が増えている。 だが、それはCMSの枠の中でしか仕事ができていない。 PureBuilder Simplyはそれをイチから作るのであり、ウェブデザイナーとエンジニアの腕の見せ所だ。

PureBuilder SimplyのテンプレートはPandocのHTMLテンプレートである。 ただし、「Pandocの出力に対してeRubyで処理できる」ようになっている。 結果、テンプレートの展開は2度行われる。

Pandocのテンプレート機能は意外なほど強力だが、 「値が○○だったら」という式はかけない。

eRubyは完全なプログラムであり、「なんでもあり」である。

比較的単純な(PHPやSSLで行うような)ものに関してはPandocテンプレートで処理できる。 実際、現時点でMimir YokohamaのウェブサイトはeRubyでの処理を無効にしている。

PureBuilder Simplyにおけるテンプレートの作成は「若干の、もしくは本格的なロジックを含むHTMLテンプレートを書く」という作業である。 もちろん、それはデザインが必要であり、CSSと連動した「ページ設計」が必要となる。 ページ設計はかなりエンジニアリングレベルの高い作業だし、 最も単純にはデフォルトテンプレートを使っても良いのだが

CSSと連動した高度なロジックを使いたいといった場合には難易度は上がる。

プログラミングではないけれど、ロジカルに考える

もちろん、CSSを書くのはプログラミングに近い次元になってくる場合もある。

今回のMimir YokohamaのウェブサイトはハンバーガーメニューとドロワーについてはJavaScriptを一切使用していない。 これはAki SIEウェブサイトで使用されていたものの改善版である。

だがそのために、配置や仕組みに関してはかなりロジックが含まれている。 CSSにはロジックはほとんど含まれないが、「ロジックをほとんど含むことのできないものによって動的なフローを実現する方法」を考えるところにロジックが行使されているのだ。

プロモーションモードのページでは下からフェードインするようなページデザインになっているが、 これもJavaScriptは使用していない。

これは単純にHTMLとCSSで実現するウェブサイトを構築するときに、 「単に書くのではなく、そこにロジックを含んだ構造をもたせる」ときに必要となるものだ。

PureBuilder Simplyはウェブサイト構築ツールであって、 デザインに関しては感知しない。 だから、そこに関しては「自分で作る」必要があるのだ。

今回も難易度や作業量としては、テンプレートとCSSを書くことのほうが大きかった。

PureBuilderはサイトの内容については感知しないのだから、別にJavaScriptを含んでもいい。 特にそれを禁止はしていないし、支援もしていない。 別にWordPressのクローンを作ることも、できなくはないのだ。

「サイトを構築する」手間で考えると…

単純に「見栄えするサイトを作りたい」という条件で考えた場合、 WordPressのほうがずっと楽だ。 なぜならば、デザインやロジックが既に存在していて、それを選ぶだけだからだ。

PureBuilderが担っている部分に関してはWordPressよりも楽かもしれないが、 WordPressにはあるがPureBuilderにはない部分がある。 それについてはどうしてもWordPressでは発生しない労力を払わざるをえない。

だから、サイトを構築する手間がWordPressよりも軽いということはない。 WordPressのインストールの労力を含めてもだ。

だが、そのような「敷居の低さ」を求める人がPureBuilder Simplyを自らインストールしてサイトを構築することは想定していない。 PureBuilder Simplyで自ら構築する人は、そんなものがなかったとしてもテンプレートを書き、CSSを書き、JavaScriptを書く人だ。 私がお客様にPureBuilderの簡便性を説くときは、そのような想定で話しているわけではない。 構築はこちらで行って、更新をお客様がされる際には難しくない、ということを言っているのだ。

テンプレートやCSSやJavaScriptは自分で書く、という前提のもとでは、PureBuilder Simplyの採用はかなり労力を削減することができる。 PureBuilder2と比べ管理の手間もかなり減り、非常に楽になった。

新サイトのデザイン、ポリシー

PureBuilderの強みは事前生成による高速性である。

さらにMimir Yokohamaでもポリシーとしている「軽量さ」と「アクセシビリティ」に重きをおいたデザインとなっている。

ただし、Aki SIEのウェブサイトは発想力をアピールする意図もあったのだが、デザインがちょっと古くさい2。 今回Mimir Yokohamaのサイトではよりモダンなデザインを採用することにした。

といっても、そのデザインはほとんどがWordPressで使用していたテーマのビジュアルを踏襲している。 ただし、全く同じというわけではなく、もとがシンプルなデザインであったために「ブロックごとに端までボーダーをひっぱる」「白に対してグレーのラインを引くモノトーン調」「右側サイドバーの2カラム」といったことを踏襲しているだけで、 メニューデザインなどは異なるし、実はカラーテーマも違う。 このあたりは「変えることが目的だった」わけではなく、そもそももとのブログでもカスタマイズしたかった部分なのだ。

ちなみに、ブログではそんなシンプルなデザインであるにもかかわらず、ちょっと古い環境(IEなど)では表示が崩れる。 なんでその程度のもので崩れてしまうのか、私には疑問でならない。

前述の通り、ハンバーガーメニューやフェードインテキストなどはCSSで記述されている。 これは、主に次のような意図だ。

  • JavaScript禁止の環境や、JavaScriptを搭載しないブラウザでもエクスペリエンスを損ねない
  • JavaScriptを使用していない分容量的に軽量
  • HTMLを「意味」を欠落させない

ただし、古いブラウザでのエクスペリエンスは若干犠牲になっている。 だが、それは「アニメーションが表示されない」程度の話で、表示自体はChrome 1.0, Firefox 1.7, Opera 9.0, Safari 3.1で対応している。 あまり言いたくはないが、IEは9.0からの対応だ。

実は今回のサイトではHTML中に同じメニューが2回登場する。これは、上記環境よりも古い環境においてはドロワーが表示できない代わりにサイドバーにメニューを表示させるようにするためだ。 これはアクセシビリティのための処置だが、場合によっては1kB程度はサイズが増加するため、ちょっと残念なところだ。 このメニューはごく初期のCSSしかサポートしない環境でも正常に表示される。 CSSを全くサポートしない環境の場合、メニューは2つ表示される。 この場合上のメニューは記事タイトルよりも上になり、高さもあるため見栄えしないが、そのような環境では仕方ないし、十分許容範囲だろう。 むしろタイトルと記事の間に入るよりはずっと良いと考えられる。

軽量性重視だが、従来と違い飾りとしての画像がところどころに入っている。 従来があまりにも殺風景すぎたという反省であり、このあたりはブログの時点で投入しているものを継承している。

プロモーションページの実現

全く印象の異なるプロモーションページだが、書き方はほとんど同じである。 別にテンプレートをかき分けることもしていないし、普通にMarkdownで書かれたページだ。

プロモーションページの印象の違いは、テンプレートにおける若干の工夫と、CSSによって実現されている。 frontmatterでプロモーションページであることを指定すると、Pandocテンプレートによってそれがクラス設定される。 あとはそのクラス設定に基づいてCSSで見せたくない要素を消去し、一部レイアウトを変更する。

こうした発想力は、やっぱりロジカルシンキングなのだ。

プロモーションページもかなりシンプルだが、 見出しには画像を使いたかった、という気持ちがある。

そうしていないのは、「適切な画像」の選定が非常に困難だったことと、 ヘッダーごとに画像を選択するためにはそれなりにあまりスマートでない余計なロジックを追加する必要があったからだ。

もしもこれぞという画像があれば採用することだろう。

ちなみに、プロモーションページはスマートフォンの商品プロモーションページをイメージしている。 なるべく説明的にならないようにしたのだが、後に書いたものほど説明的になってしまった。 どこまでイメージで語り、どこまで具体的に語るかは難しいところだ。

速度

実際のところ、Mimir Yokohamaにおける制作ポリシーと同一ポリシーで制作したのであり、「最速を目指す」という方式ではない。3

だがそれでも、旧WordPressサイトの10倍程度の速度になっている。 高速化のために使用した手段は以下のようなものだ

高速なサーバーを選択
ConoHaはSSDを採用しており、ネットワーク帯域も太く高速だ。 Nginxを採用
静的ファイルの応答に関してはNginxは最速に近い コンパクトなHTML
できるだけ冗長な表現を避けてコンパクトなHTMLが生成されるようにした。ただし、アクセシビリティを優先してメニューは重複している 可能な限りCSS
JavaScriptなしで動作するようにしたのは「JavaScript無効というオプションを与えるため」だが、ロジックの最適化によってある程度の容量削減に繋がっている WebP
WebPをサポートするのはChrome/Chromium系列だけだが、WebPは「アルファチャンネルつきロッシー圧縮」が可能なため、PNGよりもだいぶ軽くなる。一部PNG画像についてはobjectタグによりWebPを優先して使用するようにしている。アクセシビリティを重視し、重要な画像ではこの処理は行われずimg画像を使用している。 画像よりもCSS
「デザインはセンスでがんばる」方式で、画像などのアイテムの使用数は非常に少ない。寂しさはグラデーションで埋めているが、華やかさに欠ける感は否めない。

高速性ということでいえば、「CSSが重い」ということは感じるが、改善は若干難しい。 もちろん、minifyなどのテクニックである程度は小さくなるが、保守性を重視しているためだ。

また、CSSを3つから1つに減らすというアイディアもあったのだが、比較的サイズの大きいファイルであり、並列ダウンロードしてもらったほうが速いことから分割に戻した。

ミーミルのロゴなどは埋め込んだほうが高速化するだろうが、軽量化には寄与しないし、アクセシビリティが下がるので実施していない。 トップページで51.5KB、低速なうちの環境でTTFBは14.08ms、DNS lookupとfaviconを除いた時間は101.36msとなった。 従来が500kB/5s程度だったことを考えると、この計測では1/10の容量、50倍の高速化となっている。

MarkdownとReST

今回、Pandocの採用によってMarkdown以外のソースフォーマットに対応することが可能になった。 そして、最初に採用したのがReStructured Text(ReST)である。

Pandocがサポートする中で最もMarkdownに近い汎用性があるのはReSTである。 他にそのようなフォーマットはないが、あるいは専門分野での記述用にDocBookなどをサポートする可能性はある。

なお、入力ソースとしてのHTMLは、判別しがたさの観点からサポートは行わない。

ReSTはMarkdownと比べて表現力に優れている。 記述の簡便性も「好みの問題」と言えるような差異だ。 ただし、ReSTが優れている点について必ずしもそのまま適用できるわけではない。 なぜならばPandocがReSTをフルサポートしていないからだ。

実際のところ他フォーマットへの変換を想定しないのであれば、HTMLを直接記述できるMarkdownの優位性は揺らがない。


  1. 今回はNginxを使ったが、基本的にNginxも静的HTMLファイル向けのサーバーで、アプリケーションは他のサーバーに接続するリバースプロキシとして動作する方式だ。Thinなどを使う手もあるかもしれないが、Nginxよりも高速化するかは疑問。

  2. 800pxのブロックが中央にフロートしているデザインは2005年ころから流行したブログデザインと類似のものだ。今でもamebloなんかはこのデザインなのだが、新規にサイト立ち上げると画面めいっぱいまで使うデザインがデフォルトになっている。

  3. 最速を目指すのであればコードゴルフやminified、画像の排除や機能の統一化なども考えられる。実際のところ「速度は上がるがアクセシビリティが下がる」方式は取ってないし、コスト過剰にもならないようにしている。

ConoHaへのサーバー引っ越しレジュメ (DeleGate-Nginx/Postfix/Dovecot, Let’s Encrypt)

概要

作業概要は以下の通りだ

  • サーバーをDTI(@ServerMan)からConoHaに変更する
  • サーバーOSをCentOS (6.9)からArch Linuxに変更する
  • WebサーバーをDeleGateからNginxに変更する
  • WebコンテンツシステムをPureBuilder2からPureBuilder Simplyに変更する
  • Mimir YokohamaのWebコンテンツを別サーバーのWordPressから新サーバーのPureBuilder Simplyに変更する
  • Webメニューを完全JavaScriptフリーにする
  • Postfix/Dovecotを引っ越しする
  • DNSサーバーをConoHaとし、DNSの設定を変更する
  • 一部のドメインを廃止とする
  • 一部のドメインの役割を変更する
  • Let’s EncryptによるSSL証明書を取得し、HTTPSに対応する
  • 同証明書にメールも対応させる

なお、あまり詳細な解説はしていない。 Linuxやサーバーに関する基本的な事項に対して理解していないまま実施するのは危険であるため、 「コピペ仕様」にはしていない。 詳細に対してエラーが生じるなどの理由でより情報が欲しい場合はあるだろうが、 「言っていることが理解できない」のであれば、サーバー構築をするにはまだ危険なレベルにあると思ったほうが良いだろう。

承前: 開発

PureBuilder Simplyの開発

今回のために新しいコンテンツシステムであるPureBuilder Simplyを開発した。 この詳細は別に譲ろう。

テンプレートの開発

PureBuilder SimplyはPandocテンプレート+eRubyテンプレートというテンプレートを扱うことができる。 PureBuidler Simplyにテーマファイルがあるわけではないので自分で書く前提である。

今回は複数の表示デザインがあるのだが(現在のところは表示されるのはアーティクルモードとプロモーションモードの2つだけだが)これは全てPandocテンプレートとCSSで実現している。

もちろん、このようなテンプレートの開発はWeb屋の腕の見せ所だろう。

CSS

サイトはそれほど華やかなデザインではないが、技術的に劣っているわけではない。 その最たるものがCSSのみで書かれたハンバーガーメニューとドロワーだろう。

ポイントを簡単に言うと

  • ドロワーはfixedで上部に最初からある。display: noneで、高さは比較的新しい単位であるvhである
  • ハンバーガーメニューはtransitionを使っている
  • z-indexでメニューのほうが上になるようにする
  • 状態変遷は次のような方法でコントロールしている
    • 表示されないチェックボックスを用意し、操作対象をlabelで関連づける。これによりlabelで囲まれた要素をクリックするとチェックボックスがトグルする
    • CSSの+セレクタは同じ親要素を持つ次の兄弟要素に適用される
    • チェックボックスにはチェックが入っているときに適用される疑似要素:checkedがある
    • そこで、チェックボックス本体の直後に対象となるセクションコンテンツを置くことでチェック状態によって状態をトグルできる
    • ドロワーはfixedなのでどこに書いても構わないので、このセクションコンテンツの中におく。場所としてはメニューの位置に基づくのが良いだろう

見た目はWordPress時とあまり変わっていないが、性能は大幅に向上した。

速度

キャッシュの効かない初回アクセスで従来のWordPressページが5.57s、新しいページは約400msと10倍程度高速化した。

ConoHaサーバーのスタートアップ

立ち上げ

ConoHaのサインアップは10分もあれば可能で、即座にサーバーを使いはじめられる。

サーバー仕様は東京リージョンの1GBプランである。

512GBプランは安いが、性能が十分でなく、またマイグレーションができないため、1GBプランとしている。

この時点でサーバー選択が可能なので、Arch Linuxを選択する。 また、この時点である程度のセットアップが可能だ。 ここでSSH公開鍵の登録が可能である。

のようにして専用に生成しておく。 そしてconoharoot.rsa.pubを登録する。 名前からもわかるように、ここで登録する鍵はroot鍵である

また、開放するポートも選択できる。 ここで開放するポートはサーバーよりも上流でフィルタリングされる。 ここで透過していないポートに対するアクセスはサーバーに到達しない。

ただし、結果的にSSHポートの変更はサーバーに負担がかかるものになっている。 少なくともパスワードログインは禁止すべきだろう。

現時点ではSSHのみを通過させる。

初期設定

ConoHaのArch Linuxは標準インストールではなく、ある程度調整されている。 主にSSHログインが可能で、SSH公開鍵が登録され、パスワード認証不可となっている、といったことだ。 こうした内容は/etc/cloud/conoha-init/conoha-init.shによって確認可能だ。

複数のサーバーを接続する予定であれば変更すべき点は多いが、そうでなければ作業は平凡だ。

アップデート

まずはアップデートする。 20MB/sも出るため、超早い。

Zsh

私としてはZshがないと話にならないので入れておく。

これ移行はZshでの作業

一般ユーザーの追加

もちろん、一般ユーザーは登録されていない。

この時点で一旦再起動しないとパスワード設定ができないので、再起動しておく。

パスワードの設定

その上でvisudoを使って%wheelに対するsudoを許可する。

pacaurとyaourtのインストール

AURパッケージも扱う予定であるため、pacaurを入れておく。

# su - jrh
% gpg --recv-keys 487EACC08557AD082088DABA1EB2638FF56C0C53
% sudo pacman -S git

%git clone --depth=1 "https://aur.archlinux.org/cower.git"
%cd cower
%makepkg -si
%cd ..

%cower -d pacaur
%cd pacaur
%makepkg -si

これでAURからのパッケージインストールが可能になったので、Yaourtを入れておく。 作業が明確に自動化されていたり、システマチックに行えるのならYaourtはいらないかもしれないが、 まとめて検索するためには欲しい。

% pacaur -S yaourt

必要なソフトのインストール

ここでいう「必要なソフト」は私の取り扱い上の話だ。

% yaourt -S ruby openbsd-netcat rsync mercurial postfix dovecot nginx fcgiwrap certbot certbot-nginx vim

一般ユーザーでの鍵ログインの準備

サーバーで受け入れの準備をする

% mkdir .ssh

ローカルで鍵を生成しておく。

% ssh-keygen -f ~/.ssh/conoha.rsa

~/.ssh/configに設定する。 これは名前によるアクセスを可能にするためである。 (同一ホストに対する異なる鍵でのアクセスのため、鍵を指定せずに済むようにでもある) もちろん、読み替えること;

Host conoha-root
  User root
  Port 22
  HostName conoha.site.static.cnode.io
  IdentityFile ~/.ssh/conoharoot.rsa

Host conoha
  User jrh
  Port 22
  HostName conoha.site.static.cnode.io
  IdentityFile ~/.ssh/conoha.rsa

rootでは作業できるので、転送する。

% ssh conoha-root 'cat > /home/jrh/.ssh/authorized_keys' < ~/.ssh/conoha.rsa.pub

サーバー側でパーミッションの設定を行う

% sudo chown -R jrh:jrh .ssh
% chmod go-a -R .ssh
% chmod go-a .

そしてsshdリロード

% sudo systemctl reload sshd

DNS設定

ドメインを複数持っていない場合はいきなり完全移行できなかったりするので、 一時的にサブドメインを作るなどする必要がある。

ConoHaコントロールパネルのDNSからDNSの設定を行う。 (DNSの設定ってなんだ、という者はサーバーを立てるにはまだ早い。修行してくるべし)

これは本番サーバーのものを含む。 ただし、稼働中の本番サーバーのアドレスをこの時点で変更してはならない

そして、DNSサーバーをConoHaのものに変更する。

今回の場合従来はドメインサービス提供のDNSを使用していたため、同サービスのメニューから変更を行った。

WebとLet’s Encrypt

Nginxの立ち上げとテスト

従来がDeleGateで、Nginxにするため互換性は全くない。

Nginxは単純にstartすればアクセス可能な状態だが、移行のための準備をしていく。

まずは、Archの記述に合致するようにserver-avilableディレクトリを読むようにしたほうが良いだろう。

http {
    include       mime.types;
    include       /etc/nginx/servers-avilable/*;
    ...
}

これで/etc/nginx/server-avilableを作ればそこに配置したファイルを読むようになった。 この時点でrestartすると…

Dec 19 18:45:42 archlinux nginx[9339]: 2017/12/19 18:45:42 [warn] 9339#9339: could not build optimal types_hash, you should increase either types_hash_max_size: 1024 or types_hash_bucket_size: 64; ignoring types_hash_bucket_size

とのことなので増やす。

http {
    include       mime.types;
    include       /etc/nginx/servers-avilable/*;
    default_type  application/octet-stream;

    server_names_hash_bucket_size       128;
    types_hash_max_size                 4092;
    ...
}

配置するファイルはArchwikiに従ったもので大丈夫だ。

server {
  listen 80;
  listen [::]:80;
  server_name domain.tld;
  root /usr/share/nginx/html;
  location / {
    index index.htm index.html;
  }

  # ACME challenge
  location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /var/lib/letsencrypt;
  }
}

domain.tldは適切なドメインに置き換えること。

ここで、あまり書かれていない重要なこと。

rootというのはドキュメントルートで、locationの起点となる。 つまり、

location /foo {
  root /usr/share/nginx/html;
}

であるとき、/foo/bar.htmlにアクセスすると読まれるファイルは/usr/share/nginx/html/foo/bar.htmlであって、/usr/share/nginx/html/bar.htmlではない

そのような単純なマッピングを行いたい場合はrootではなくaliasを使う。

ACME challengeはhttp://domain.tld/.well-known/acme-challenge/randomnumberに対して行われるため、 rootで正しい。

だが、このディレクトリがないので作っておいたほうが良いようだった。

% sudo mkdir -p /var/lib/letsencrypt/.well-known/acme-challenge

あとはcertbotを使えば良いのだが…

% sudo certbot certonly --email webmaster@domain.tld --webroot --webroot-path /var/lib/letsencrypt/ -d domain.tld

その前にConoHaのサーバー設定でHTTPをあけておかなくてはならない。 そして、IPv4とIPv6両方をあけておくこと。 別々になっていることに気づかず、ACME Challengeのリクエストが到達せずに(/var/log/nginx/access.logを見ても記録されていない)随分とハマってしまった。

移行作業

各ドメインごとのドキュメントルートを作り、ファイルを配置、 さらに対応したドメインごとの設定ファイルを作る。

今回の場合、Mimir Yokohamaのページは既にPureBuilder Simplyによる静的ファイルへのビルドが完了しているし、 移行対象のものに関してもPureBuilder2で静的ファイルにビルドされているものなので、単純にファイルを配置するだけの簡単なお仕事である。

Aki SIE関連のアドレスはdiscontinuedなので、301を返す。

server {
        listen 80;
        listen [::]:80;
        server_name aki-sie.com akisie.com aki-sie.yokohama akisie.yokohama;

        return 301 http://www.mimir.yokohama/;
}

http://journal.reasonset.net/に関しては301でリダイレクトしていたので、これも反映する

server {
        listen 80;
        listen [::]:80;
        server_name journal.reasonset.net;
        return 301 http://chienomi.reasonset.net$request_uri;
}

NginxのLet’s encryptの対応

メールサーバーの移行まで完了した時点で作業を行うのだが、 certbotで必要なドメインをすべて署名してもらったら、1SSL対応化を行う。

設定例は以下

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:433 ssl http2;

  ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/domain.tld/chain.pem;
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_session_tickets off;
  ssl_prefer_server_ciphers on;
  add_header Strict-Transport-Security max-age=15768000;
  ssl_stapling on;
  ssl_stapling_verify on;

  server_name domain.tld;

  index index.html;
  location / {
    root /var/www/domain.tld/doc;
  }

  # ACME challenge
  location ^~ /.well-known/acme-challenge {
    root /var/lib/letsencrypt;
  }
}

メールサーバーの移行

機能させるために一旦古い証明書で作業しているため、Let’s Encryptの証明書が取れたら証明書ファイルを変更してreload/restartすること。

Postfix

Postfixに関してはCentOS 6とArch Linuxではファイル配置が異なり、 バージョンの違いから設定ファイルの違いも大きく互換性に乏しい。

そこで、CnetOSの設定ファイルを/etc/postfix.centとしてコピーする。 このほか、/etc/alias*も忘れずに移行する必要がある。 また、一旦古い証明書ファイルもコピーした。

設定ファイルの違いを見るため、diffを取る。

% diff /etc/postfix.cent/main.cf /etc/postfix/main.cf > main.diff
% diff /etc/postfix.cent/master.cf /etc/postfix/master.cf > master.diff

このdiffファイルをkwriteで2開く。 今回はNemoのsftp機能を使って開いた。

このdiffを元に手作業で変更箇所を反映していく。 主にssl, auth, virtual関連の変更を反映する必要があった。

virtual関連のファイルは/home/mailuserにあったため、これをコピーする。 ただし、これはvirtualメールボックスを含むため、移行完了までは継続的にアップデートする必要がある。 この前にvirtual用に設定していたmailuserを設定する必要もあった。

% sudo useradd --no-create-home --uid=20000 --shell /bin/nologin --system -U -M mailuser

だが、これだけではグループが適正な値にならない。 そこで、グループIDを変更した上で、ユーザーの所属する主グループIDも変更する。

% sudo vigr
% sudo vipw

Postfixをrestartして完了。

Dovecot

Dovecotに関しては設定ファイルをコピーしてそのまま使うことができた。

Dovecotの設定ファイルとして/home/mailを使っていたので、これをコピーする。

Dovecotをrestartして完了。

上流

DNSを変更してもDNSキャッシュの関係でまだ旧サーバーにもメールが届く。 ある程度はaliasを使って転送しても良いのだが、素直にPostfixで受け取りつつ、Maildirのファイルを同期していくのが良いだろう。

DeleGateを使っていたため、DeleGateのSMTP転送機能を使う方法もあるのだが、うまく動作しなかったのと、TLS接続を受け付けることができないため、諦めた。

セキュリティ関連

複雑な話になるので省略。

そこまで難しいことをしているわけではないが、 普通の対策と、らしい対策とで簡単には突破できないようにしている。

後処理(旧サーバー)

DovecotとDeleGateは停止してしまう。

Postfixは5日程度稼働したら停止してしまっていいだろう。3

その後、バックアップ(主にログや設定など)をとったらサーバー破棄である。

おまけ: ConoHaについて

DNS

ConoHaのDNSは高速である上に非常に設定しやすい。

これまで使用していたお名前.comのもの、XDomainのものは非常に設定しづらかったので、 これだけでもConoHaにする価値はあるレベルだ。

料金

コンピューティングリソースはDTIとあまり変わらないが、料金は約倍になった。

ただし、ConoHaの柔軟性やメリットを考えればそう悪くない。 両方持つと少々負担は大きいが4、一気に完全移行したためDTIを解約でき5、許容すべきコストアップだろう。

速度

速い。

「コンピューティングリソースは大きく変わらない」といったが、速度は明らかにあがった。 特にネットワークの高速化とストレージの高速化の恩恵は大きく、Webの応答性は明確に向上した。

柔軟性

DTI VPSは色々と柔軟性が足りず、困った。 特に、OSのバージョンをあげようにもサーバーがひとつしかないので、できない。 ConoHaなら

  • インスタンスが立てられるのでサーバー仕様変更もできる
  • OSが選べる。さらにカスタムイメージのアップロードも可能
  • サーバーのアップグレードが簡単にできる(512MBプランを除く)

ファイアウォール

上流でフィルタリングしてくれるのはとても嬉しい。 設定が楽になる、というのもあるが、サーバーの耐障害性が勝手にあがる上に、まあまあ重いiptablesでの処理量が減るため、パフォーマンスが改善する。 リソースが限られている中では非常に嬉しい。


  1. Let’s Encryptの証明書はSAN(Subject Alternative Name)に 対応したもので、fullchain.pemが全てのドメインに対応したものになる

  2. Kwrite/Kateにはdiffのハイライト機能があるからだ

  3. TTLは3600だったため、それに従うならば1時間待てば良いのだが…

  4. DTIが月額500円ほど(年間6000円程度), ConoHaが900円ほど(年間10800円程度)である

  5. といっても、私はDTI SIMの契約があるため、DTIの契約そのものが終了するわけではない

Markdownにまつわるお話

ことの起こり

なんだか急にMarkdown関連のことが盛り上がってきた。

Commonmark絡みなのかもしれないけれど、ちょっと私にも言いたいこともある。

Takeshi KOMIYA‏さんによるツイートその1

Markdown は記法に限りがあるというシンプルさが強みであり、弱みだよね。表がないのが非常に不満だけど、それ以外は大体これで十分だよね。それ以降、いろんな人がいくつも派生記法を作っているけれど、どれも方言の域を出ていない。脚注や参照はなくても生きていけるんだ。

その2

もちろん、それで満足が行かない人たちがいるのは知っているし、ある用途 (執筆やら巨大なリファレンスの管理とか) では不十分なのは分かるけど、それは特別なユースケースであって、Markdown のそれから外れているだけなんだよね。そういう人たちは別のものを使う方が幸せになれる

へぇ、テーブルってMarkdownの標準じゃなかったんだぁ…というのはおいといて、私が言いたいのはこんな感じ。

少なくとも私はPandocのMarkdownに9割は満足している。 Kramdownでも良い

そして、Markdownの優れているところは単にシンプルたからではない。DocbookやPODやroffやtrfやXMLのようなドキュメントメタフォーマットと比べても多くの人に取って受け入れやすく、だからこそメタフォーマットとして非常によく機能することだ。

私には自分で作ったPureDocがある。けれど、Markdownのほうがよく使う。そのほうか変換の余地が大きく汎用性が高い。つまりはドキュメントメタフォーマットとして優れているのだ。 そして、Markdownは処理系依存でもそれほど困らないが、PureDocは他に処理系はない。

Markdownの拡張が気に食わない、そんな人はMarkdownでないものを使え、というなら、拡張されたMarkdownはMarkdownではない別のフォーマットだと思えばいいではないか。Markdownを名乗らなければいいのか?それとも、似た記法を使うなんてけしからんということか?

MarkdownはHTMLを含めることすら許しているんだ。足りなければ自分で拡張したっていいんだよ。好きなものを使えばいいさ。強制することなんかない。

そんなくだらないことで言い争わないで、空を見てご覧よ。今日は満月。天使が降りてきそうな素敵な星空だよ。こんなに月が明るいのに2等星までよくみえる。

ドキュメントメタフォーマット

とりあえず紹介

ブログに書くのだからもう少し補足しよう。

ドキュメントメタフォーマットというのは、なにか別の文書形式に変換することを前提としたドキュメント形式のことである。

例えばPODはそれ自体が読みやすいテキストではあるが、「意味付け」ということはできても、それがplain textの状態で「フォーマットすることで意味付けを感じられる」というようなものではない。 PODはトランスレータと呼ばれるソフトウェアに通すことを前提としており、これにより様々な形式に変換する。 対応形式はplain, man, html, latexが標準で付属し、そのほかにも様々な形式に変換可能だ。 Perl cookbookはPODで書かれているという。

RDocも似たようなもので、こっちはもっと「Wiki」っぽい。 こちらはriと呼ばれるtexinfo形式を標準としているが、HTMLにも変換できる。

Wiki記法、はてな記法はマークアップ形式だが、あくまでもHTMLに変換することを前提としている。 HTMLよりも楽に書けるとことがその価値であり、「HTMLの簡易記法」であるといえる。

plain2, reStructuredText, Re:view, AsciiDocはMarkdownに近いものだ。 plain2はLaTeXへの変換に限られているが、ReStructuredTextはSphinxを介して

  • HTML
  • LaTeX
  • ePub
  • Texinfo
  • man
  • plain

に変換することができ、Re:viewは

  • EPUB
  • PDF (LaTeX)
  • InDesign (IDGXML)
  • Markdown
  • plain text (TOPBuilder Text Markup Language)

asciidocは、(公式プロセッサではなく)asciidoctorが

  • HTML (HTML5)
  • XHTML (XHTML5)
  • DocBook (DocBook5, DocBook 4.5)
  • manpage
  • PDF
  • ePub 3
  • LaTeX
  • Mallard

に変換する。

これらのフォーマットは「そのフォーマットをplain textとして書いて、他の形式に変換する」ことを前提としているのだ。

ちなみに、これから執拗にDocBookの話をするが、DocBookもまた他の形式に変換するためのドキュメントメタフォーマットなのだが、「XMLまたはSGMLで書かれている」という特徴がある。 はっきり言えば、前述の形式と比べて圧倒的に読みにくく、書きにくい。 前述のフォーマットがHTMLよりも簡易な記述法を使っているのに対して、むしろODFやHTML, EPUBのようなドキュメント形式として作られたものだと考えたほうが良い。

だが、DocBookに執拗に言及するのは、DocBookが技術文書の形式として普及したからであり、かつトランスレータが多様であるからだ。標準処理系で

  • HTML
  • PostScript
  • PDF
  • RTF
  • DVI
  • plain

に対応している。

ちなみに、PureDocというのは私が作ったもので、RubyをベースとしたDSLである。 これは、Markdownのようなフォーマットが目指しているものとはちょっと方向性が違う。HTMLよりも簡易な記述とHTMLよりも強力な表現を求めており、実際変換したものはHTMLを拡張したものになる(XMLネームスペースを使って独自のタグを追加する)。

RubyのDSLであるため、「ロジックを含めた記述ができる」というのがポイントになっている。

読みやすいか??

まず言っておくが、どのフォーマットが優れているかということに関しては、もはや宗教であり、好みによる。

個人的にはReStructuredTextはかなり好きだ。 plain textの状態でも読みやすいし、表現力も高い。 Python(私は好きでない)のくせにやるじゃないか、と思う。

Re:View形式と、asciidoc形式はあまり好きではない。 PureDocがそんな感じじゃないかというかもしれないが、 plain textとしての自然さがないのだ。

例えば強調は、MarkdownやReStructuredTextでは

*強調されたテキスト*

となるが、Re:Viewは

@<em>{強調されたテキスト}

であり、asciidocには強調という概念がない。 (asciidocは「見た目」での定義であり、どちらかというとTeXなどに近い)

PureDocでは

e "強調されたテキスト"

となる。DocBook/XMLは完全に技術マニュアル用であり、そもそも「エレメントを定義しろ」とあるので、こちらも強調はない。 HTMLでは

<em>強調されたテキスト</em>

となる。RDocも見た目定義だが、一応「イタリックにするとiではなくemを使う」仕様なので

_強調されたテキスト_

となる。PODにも強調はなく、一応はイタリックを強調としているので

I<強調されたテキスト>

となる。

好みはともかくとして、ドキュメントメタフォーマットとしては「読みやすさ」は「表現力」に並ぶ重要な価値だ。 なぜならば、ドキュメントメタフォーマットはそもそもMicrosoft Word形式などのプロプライエタリフォーマットに対するアンチテーゼとしての意味合いがあるからだ。

そして、同時に「書きやすい」ことは、HTMLが簡易なマークアップ言語とはいえ、「普通の人が書くにはハードルが高い」という側面があったためで、より誰にでもかけて、HTMLのように面倒な(タグ表現が妙に長い上に、「なぜ終端にまでタグを書かなければいけないのか」という冗長さを避けたかったということから来ているように思う。

そもそも「書きやすいフォーマット」というのはWiki記法から流行り始めたように思うし、 徐々にブログなどでもHTMLではなくより簡易な記法でマークアップを可能にした。

ドキュメント形式なのにロジックがあるPureDoc

ちなみに、PureDocはRuby DSLであるため、

3.times do |i|
  p { "Hello!" }
end

なんてことができ、この結果

<p>Hello!</p>
<p>Hello!</p>
<p>Hello!</p>

という出力が得られる。 全く一般向けではない仕様だ。

さらに言えばZshで書かれたPureDoc Zのほうは

repeat 3
do
  p Hello
done

とすれば同じような結果が得られる。 これを「読みやすい」と思う人はどうかしていると思う。 PureDocは「書きやすい」ようにはしているが、「読みやすい」ようにはしていない。

PureDocはほぼすべてのテキスト系HTMLタグを使用することができ、かつオプションも指定できる。 さらにnoteなども備えていて、「HTML以上」であることが前提だ。 実のところ「ロジックで書ける」のも「HTML以上」の一部であり、「仕様」だったりする。

PureDocはinstance_evalを使ってRubyコードとして評価しているし、PureDoc Zに至ってはドキュメント中でライブラリをincludeすることでDSL的に使うための語彙がshell functionとして追加されるだけのものだ。

「メタフォーマット」としての価値

WikiなどはHTMLを簡単に書くためのものなのだから、特に変換先としての意味はないのだが、 メタフォーマットとしての価値は、「一度書けば表示向けにも印刷向けにもできる」ということにある。 基本的にはHTMLとPDFにできれば良いだろうという考え方が成り立つのだが、例えば「自分はコマンドドリブンなマークアップで書けば良いけれど、みんなはWordだからDocxで吐きたい」というケースはあるものであり、多様なフォーマットでの出力というのは割と重要な価値である。

実は、私はMarkdown/Pandocと出会うまでずっとPODで書いていた。 PODの多彩な変換形式に助けられてきたからだ。

だが、PODは純粋に汎用というわけではなかったし、 「DOCよりも多くのフォーマットに変換でき、より汎用性と表現力がある形式」を求めていた。

Pandocは極めて強力な変換ツールであり、入力形式はMarkdownに限ったわけではないのだが、 一応、Markdownを軸にしている…のだと思う。

そのため、PandocをMarkdownツールだと考えれば、Markdownは圧倒的なアドバンテージがある。 (もちろん、PandocがReStructuredTextをMarkdownと同等に変換できるのであれば、特にMarkdownにアドバンテージがあるわけではなくなる)

実はPandocは多彩なフォーマットが仇となり、適切に変換されないケースがそこそこある。 さすがに完璧に…というのは相当難しいのだろう。

Markdownにはもうひとつ、様々な処理系があるということがある。 KramdownはRubyで書かれており、Rubyプログラムにおいて使いやすい処理系だ。 KramdownもLaTeXへの出力に対応しており、割と使いやすい。

方言の話

Kramdownがinput formatとして

  • Kramdown
  • Markdown
  • GitHub Flavored Markdown

の3つを挙げていることに既に闇を感じるが、 実は処理系それぞれがMarkdownを拡張していて、一口にMarkdownといっても書き方に互換性がない、という問題が存在する。 冒頭で言及されていたのはそういうことだろう。

だが、それほど問題があるとは思わない。

まず、「多彩な処理系があるマークアップ言語」自体珍しく、Re:Viewなんてほとんどないし、ReStructuredTextだってそう多くはない。 なので、「特定の処理系向けに書かれたMarkdown」がそんなに問題なのか、という疑問がまずある。

さらに、MarkdownはGFMとPHP Markdown Extraが普及していて、これらの記法はだいたい通用する。 だから、純粋なMarkdownでは表現力はかなり限られるが、これらの記法を取り込めばかなりの表現力を持つし、これらの記法を取り込んでなお複数の処理系で取り扱うことができるのだ。

拡張記法のせいで無駄に「意味」をとられるのが気に入らないのであれば、 KramdownのようにMarkdown Standardに従った処理をできる処理系を使えば良い。

Markdownが良いという話

Markdownの記法が完璧だとは思わないが、少なくともPandoc Markdownは表現力にほとんど不満はないし、Pandocの変換フォーマットにも不足はない。

Markdownという記法について「及第点」で、変換という実用面に不満がないのだから、 それで文句を言うべきことなどない。

だから、別に「Markdownじゃ足りない」というのであれば拡張すれば良いし、それが許されてもいる。 拡張されたMarkdownを使ってはいけないということはないだろうし、素のMarkdownと拡張Markdownは別物だと考えれば使い分けだって成立する。

あるいは、「簡素さ優先のMarkdown」と「高機能なGFM」のように考えればよいではないか、ということだ。

無理に「Markdownとはこうだ」ということを押し付け合う必要もないし、Markdownはいままでの苦痛を緩和してくれる、「良いもの」なのだ。

そうでないというのならば、試しに大量のドキュメントをDocBookで書いてみればいい。 DocBookは確かに技術文書を書くのに適しているが、相当に苦痛だろう。 書く量が膨大で、しかもテキストはほとんどエレメントに埋もれてしまう。

別にHTMLで書いても構わない。 Markdownよりも優れていると思うのであれば。

Markdownが好きで、しかし機能が足りないから拡張しようという気持ちはなにも間違っていないし、それはまた別のものだと考えればごく自然なものなのだ。 方言があってはいけないというものではないし、が方言があったところでMarkdownは十分に共通性があると思う。

このブログもMarkdownで書いて、Kramdownで変換している。

ツールや記法でいがみあうことなどなにもない。 誰かに何かを強制する必要などないのだ。 あなたが幸せになるように使えばいい。

Pandoc + TexLive (LuaTex)によるPDF生成と和文フォント

Pandocは非常に便利なツールだが、オプションがなかなか複雑で、特にPDFにする場合などは長くて毎回打つのはしんどい。 このことは初心者にとって使いにくい理由のひとつになっていると思い、簡単に扱うためのZshスクリプトを書いた

だが、この際に思わぬことに気づいた。

LuaTeX(TexLive)経由でPDF化する際に、ドキュメントクラスがarticlereportなら-V mainfontが効くのだが、ltjarticleltjsarticleでは効かない。 正確には、欧文にしか効かない。

追いかけると、LuaTeXはmainfontは欧文フォントの指定であり、和文フォントは独立してmainjfontを用いること、とある。 しかし、-V mainjfont=...は効かない。

検索するとmainfontを指定すれば良い、というページばかりヒットするのだが。 諸君は本当に試したのか。見聞きしたままコピペしてないか。

というわけで、Pandoc 日本ユーザー会の[藤原 惟さん(すかいゆきさん, @sky_y)](https://twitter.com/sky_y)にご報告させていただいた。

すると、一時間ほどでご回答いただけた。

-V CJKmainfont=...とすると和文フォントが指定できる、と。

-V mainfont=...で欧文フォント、-V CJKmainfont=...で和文フォントの指定。 早速スクリプトにも反映した。

今回の解決はすべて藤原惟さんのおかげである。 改めて、この場を借りて感謝申し上げたい。

さて、Pandocは非常に便利なツールなのだが、多様なフォーマットに変換する都合からか、微妙なバグが割と多い。 そのバグが変換先エンジンの問題なのか、Pandocの問題なのか切り分けにくいので毎度なかなか辛い。

現時点では--pdf-engine=lualatex環境下において

  • テーブルが右に突き抜けてしまうことがある (発生するテーブルであれば、書き方を変えても駄目)
  • ページを下に突き抜けてしまうことがある (脚注やページ番号にはかぶってページの外に出る。 表と画像を併用すると発生しやすい)

ということを把握している。 どちらもPandocよりはTexLiveが原因のような気がするが、発生原因が特定できず、現在のところ謎バグである。

また、

  • インラインコードの--がTeXのハイフンに変換される
  • コード中の"がTeXの引用符に変換される

という問題もあるのだけれど、これも冒頭で紹介したスクリプトにおいては発生せず、

pandoc -s --filter pandoc-crossref -f markdown -V geometry=a4paper -V geometry:margin=1in -V mainfont="Source Han Serif JP" -V monofont="VL Gothic" -V documentclass=ltjarticle --pdf-engine=lualatex --toc "$1" -o "${1:r}.pdf"

とすると発生する。CJKフォントを指定しても発生する。ドキュメントクラスをltjsarticleにしても発生する。 けれど、スクリプトが実行しているデフォルトの内容としては

pandoc -s -f markdown -V geometry=a4paper -V documentclass=ltjsarticle --pdf-engine=lualatex --toc -o test.pdf test.md

なのだけど発生しない。元のコマンドでフォント指定をやめると発生しなくなる。 どうも試していくとmonofontを指定するとフォントがなんであれ駄目っぽい。

Manjaro Linux 0.8.13 セットアップ (5) Z400編

はじめに

システム更新

$ sudo pacman -Syuu

Grub設定。nomodesetを入れる

$ sudo nano /etc/default/grub

最新カーネル

$ sudo mhwd-kernel -i linux42

ビデオカード

$ sudo mhwd-gpu --setgl nvidia

再起動。

パッケージインストレーション

  • nss-mdns
  • bind-tools
  • encfs
  • ctags
  • leafpad
  • zsh

ホスト設定を行う。

必要ならchsh

  • medit
  • geany
  • geany-plugins
  • smplayer
  • smplayer-themes
  • smplayer-skins
  • opera-developer
  • cinnamon
  • plasma
  • kde-applications
  • fcitx-kkc

X関係に問題が出るので、Zshでホームディレクトリ上で(多分、extended_globを伴って)

$ rm .[xX](^(profile))

入力関係の設定をしておく。

  • emacs
  • xsane
  • fetchmail
  • spamassassin
  • razor
  • tasque
  • skype
  • skype-call-recorder
  • openssh
  • sshfs

sshの設定

  • lv
  • w3m
  • amarok
  • audacious
  • audacious-plugins
  • libcue
  • audacity
  • sox
  • zsh
  • gtkhotkey
  • libgcrypt15
  • inkscape-gtk3-bzr
  • sylpheed
  • ttf-tahoma
  • fcitx-anthy
  • ttf-ricty
  • ttf-migmix
  • ttf-rounded-mplus
  • ttf-migu
  • ttf-sawarabi-gothic
  • ttf-hanazono
  • ttf-mikachan
  • ttf-sawarabi-mincho
  • ttf-mona
  • ttf-sazanami
  • ttf-monapo
  • ttf-kibitaki
  • ttf-mplus
  • ttf-ume
  • ttf-kochi-substitute
  • ttf-ohruri
  • ttf-vlgothic
  • ttf-koruri
  • ttf-vlkoruri

Infinality, Java, Mozc-UTは猛烈に時間がかかる。

  • cairo-infinality
  • fontconfig-infinality
  • freetype-infinality
  • jre8-openjdk-infinality
  • fcitx-mozc-ut

続き

  • kde-gtk-config
  • ttf-tahoma
  • bundler
  • fcitx-anthy

    nVidia向けのビデオ関連。

  • libva-vdpau-driver
  • gst-vaapi

続き

  • gtk-theme-preference
  • font-manager
  • gtk-chtheme
  • alsaplay
  • gedit
  • gedit-code-assistance
  • gedit-plugins
  • evince
  • gnome-terminal
  • tomboy
  • mcomix
  • gnome-screenshot

Gnome Screenshotは設定が必要

  • xlhtml
  • vivaldi

Vivldiは必要か??
Wine関連

  • wine
  • winetricks
  • twine
  • wine-mono
  • q4wineyaourt
  • wine_gecko

Haskell (for pandoc)

  • ghc
  • cabal-install
  • alex
  • happy
  • texlive-core
  • texlive-langcjk

続き

  • chromium-pepper-flash
  • dialog
  • perl-tk
  • psutils
  • ruby-kramdown
  • livestreamer

ウェブブラウザ。

  • midori
  • qupzilla
  • rekonq

続き

  • xnviewmp
  • nkf

Gtk+2テーマ関連

  • oxygen-gtk2
  • lib32-qtcurve-gtk2-1.8.18-1
  • lib32-qtcurve-qt4-1.8.18-1
  • lib32-qtcurve-utils-1.8.18-1
  • qtcurve-gtk2-1.8.18-3
  • qtcurve-qt4-1.8.18-3
  • qtcurve-qt5-1.8.18-3
  • qtcurve-utils-1.8.18-3

Gtkテーマ, Sylpheed, Leafpad

Gtk+2アプリケーションの中に、Gtkテーマを原因にSegmentation faultを起こす奴がいる。

SylpheedはGtk+2専用テーマでなければいけない。場合によってはフォールバックできるが、できない場合もある。フォールバックできる場合も起動時間が全く異なってくる。

そこで、Gtk+ 2専用のOxygen-Gtkにしたのだが、なんとLeafpadはOxygen-Gtkで動かない(!)

QtCurveが最も簡単に解決してくれるが、それも嫌なので、Leafpadだけは代替プログラムを書いた。

#!/bin/sh

export GTK2_RC_FILES=$HOME/lib/alt-gtkrc-2.0

exec leafpad

で、alt-gtkrc-2.0でQtCurveを指定している。

Gtk+2フルなテーマは

  • Clearlooks
  • Industrial
  • Mist
  • Redmond
  • ThinIce
  • Xfce-redmondxp
  • Xfce-kolors
  • Xfce-dawn
  • Xfce-dusk
  • Xfce-cadmium
  • Silver

もしかするとoxygen-gtk3-gitを入れるとダメかもしれない。

なお、Gtk3はCinnamonで、Gtk2はgtk-chthemeで設定。

文字入力設定

入力関係のため、~/.xprofile

export GTK_IM_MODULE=fcitx
export GTK2_IM_MODULE=fcitx
export GTK3_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS="@im=fcitx"
export DefaultIMModule=fcitx
export PATH=/home/aki/bin:$PATH

ログアウトしてログインしなおしたほうが良い。
gtk-query-immodules-*は必要なかった。

Gnome Screenshot

デフォルトの保存場所を変更する。

gsettings set org.gnome.gnome-screenshot auto-save-directory /path/to/directory

Maxthon

リポジトリ落ちしているので

$ git clone --depth=1 git://pkgbuild.com/aur-mirror.git
$ cd aur-mirror/maxthon-browser
$ makepkg
$ sudo pacman -U maxthon-browser-1.0.5.3-4-x86_64.pkg.tar.gz

英数キーでCaps Lockになる

Archのevdevがいうこときかなくなっているので、.xprofileあたりに

setxkbmap -model jp106 -layout jp

Pandoc

$ export PATH=$HOME/.cabal/bin
$ cabal update
$ cabal install pandoc

openSSH

$ sudo systemctl start sshd
$ sudo systemctl enable sshd

ホスト設定

MDNS (Zeroconf)

/etc/nsswitchhost項目にmdns_minimalを追加。filesよりも後に。

fcitx-mozc-utのために

/etc/hostsdig japanese-usage-dictionary.googlecode.comした結果に基づき、このホストをIPv4で決め打ち。

ビデオの設定

Quadro2000でのVDPAUについては、単純にnon-freeでインストールしていれば、有効になっている。
nvidia-utilsでOKだからだ。

VA-APIについては、libva-vdpau-driverをインストールし、環境変数$LIBVA_DRIVER_NAMEの値にvdpauをセットするようにすれば良い。
私は~/.xprofileに記載した。

Smplayerは「ビデオ」タブで出力ドライバーvdpauに、
パフォーマンスタブのハードウェアデコードvdpauにする。

VLCについては、ハードウェアアクセラレーションによるデコードX11のVA-APIビデオデコーダーに設定する。

Flashは/etc/adobe/mms.cfgのコメントアウトされているEnableLinuxHWVideoDecodeを有効にする。


追記

Conkyを触ってみたのだが、AMD APUで発生していた

  • execiしていると2回目から表示が消える
  • RSSが取れないことが多い

RSSがとれないというのは、RSSのエントリが表示されない状態になる。Conkyの組み込みrssの話だ。取れたかとれなかったかの状態は永続するが、取れないことが圧倒的に多く、5つのRSSをまとめている部分に関しては、何十回も起動・停止しなければ十分に表示できなかった。

また、Conkyの負担もかなり大きかったので、結局使用をやめていたけれど、Z400になってなんの問題もなくなった。

やはりLinuxにはQuadroだ。

壊れたシステムの修復のためのManjaro 0.8.13インストール

update-grubできない問題は根が深く、様々なところで訊いてはみたものの、結局答えが出ない。

Manjaro 0.8.13について

Manjaro Linuxは0.9.0リリースを控えていたが、新インストーラのCalamaresのバグがなかなか解消できず、結局0.8.12でCalamaresを採用したものの、インストーラをThusに戻した0.8.13をリリースするに至った。

Manjaro Linuxの日本語を一手に引き受け、Manjaro JPも開発するrago1975さんによれば、0.9.0のThusインストーラバージョン的なものだとという。

実際にそのように感じる。というのは、XFceはGTK3を採用する4.12、KDEはPlasma5なので、デスクトップが別物になっている。 XFce版だとDMも完全に別物となっており(もしかしたらMDMから差し替えられたのかもしれないが)、雰囲気はがらっと変わった。

XFceは0.8.12でも4.12の開発版である4.11を採用しており、現行のManjaroテーマも既に採用されていたため、0.8.12からの目新しさは特にない。 とはいえ、それまでの0.8.11からすれば劇的に変わり、垢抜けないデザインが特徴だったXFceもぐっとスタイリッシュになった。0.8.12と比べてもやはり部分的に見た目も変更されている。

アップデートでは見た目に関する部分は変わらないため、「見た目が変わった」というのは、入れ替える動機にもなるかとは思うが(Plasma4がPlasma5に置き換えられるのは当面先だろうから、入れ替えはかなり大変だと思う)、今回はThusの改良に非常に力が入れられていた。

まず、Thusインストーラの起動はすごく速くなった。これまでは、忘れた頃に起動する勢いだったが、すぐに起動するようになった。

Thusは手動パーティショニングをしてもLUKSの利用ができるようになったはずだが、それについては今回試していない。

LUKSパスフレーズについては、「特殊な文字を使うな」という注意書きが増えた。「LUKSパスフレーズに記号を含めると復号化できなくなる」という問題に対応したのか。

またブートローダーはGRUB2とGummibootを選択できるようになった。しかし、Gummibootを選択するとブートローダーはインストールされない。 また、Gummibootを選択した場合、ブートできない可能性があるのでウェブサイトを見るかと聞かれる。

Thusはかなり改善されたことを感じられる。

また、0.8.11まではUEFIでインストールしても第1パーティションにGRUB_BOOTを切っていたが、これをやめて3パーティション構成になった(ESP, BOOT, LVM)。Gummibootにすると、2パーティションになる。

Gummibootにきちんと対応してくれると嬉しかったのだが…

なお、Manjaro 0.8.11をそのままにしてインストールすると、GRUB2でも起動しなかった。 事前にGPTを作成しておくことで無事に起動できた。

ただし、UEFIブートメニューに謎の無効な空欄エントリがあるということは変わらない。

導入しようにも…

しかし、Alternative HDD (500GB)に入れても、そこで構築してSSDに移す、というのはかなり大変な作業になる。SSDのほうが小さいからだ。

かといって、環境をイチから作るのに、現行の環境を潰してしまうと、だいぶ長く仕事ができなくなってしまう可能性がある。

散々悩んだ挙句、結局はSSDをもう1台追加することにした。 ケーブルも併せてだいたい12000円の出費。なかなか痛い。 だが、仕事を見通しが立たないまま止めるわけにもいかないし、かといって更新できない状態でも放置できないので、やむなしか。

ケーブルはAmazonで、SSDはNTT-Xで購入。NTT-Xは仕事でも使えるようなので、これからかなりお世話になることになるだろう。

ケーブルは当日、SSDは翌日に到着した。

インストール作業

インストール

まずは単純に、SSDを組み込んで元のSSDとAlternative HDDを外し、予めGPTを作成した上でThusインストーラでインストールする。

UEFIでLVM, LUKS, /home分割はon, GRUB2を選択、なお起動時にはnomodesetnokmsbootオプションが必要。

ただし、インストール後はnomodeset及びnokmsbootは必要なかった。

基本セッティング

まずはworldencmountの必要なファイルをtarで展開する。これでbtrfsボリュームのマウントが可能になる。

そしてzshのインストール。 なお、zsh-configについてはかなり癖がある設定の上に、手元の.zshrcで設定できなくなるので私は好まない。

これでマウントできるようになったら、btrfsをroでマウントし、最低限のファイルをコピーする。主要な設定ファイルは

cp ~/share/manjaro-home-transition/*(#q@) .

で以降できる。データ本体は~/shareにあるため、データの以降は必要ない。

日本語フォントはあるが、日本語入力ができない状態でスタートするため、とりあえず

yaourt -S fcitx-mozc-ut

インストール前にPKGBUILDをいじってニコと英語dicを有効にしてインストール。 ただし、googlecode.comのIPv6問題があるため、その前に

yaourt -S dnsutils

してdigを使えるようにし、

dig japanese-usage-dictionary.googlecode.com

して/etc/hostsにIPv4で決め打ちする。

私のプログラムは多くがRubyを使うため、Rubyも設定しておく必要がある。 これは次の方法で行う。元々

pacman -Q > pacman-q

としてあり、ここから

grep -F ruby pacman-q | cut -d " " -f 1 > rubypkg

として抽出。このうちインストール済みのものは必要ないので、

pacman -Q | cut -d " " -f 1 > pacman-qq

と現状のものを取得し

cat pacman-qq pacman-qq rubypkg | sort | uniq -u > target-ruby

とする。あとは

yaourt -S $(cat target-ruby)

でOKだ。

同様の方法でTTFファイルもインストール。

また、EncFSをコアに入れているので、EncFSをインストール。

yaourt -S encfs

また、nemoはテンプレートディレクトリにシンボリックリンクを許容するが、Thunarはしないので、シンボリックリンクをやめて、コピーに

rm template
cp -R share/template .

さらに、エスケープしたfstabをベースにfstabを修正する。 その前にVIもVimもなくて混乱するため(例えばvipwはあるのに、vipwはできない)、インストールしておく。

yaourt -S gvim vi

とりあえずエディタはmousepadが使える。とりあえずはmousepadで修正しリブート。

日本語周り

fcitx-mozc-utだけ入れたが、それさえ入っていなかった。 そして、日本語周りはManjaro JPベースではないため、それなりに複雑だ。

まず、fcitx-mozc-utがベースになるので、それをインストール。

yaourt -S fcitx-mozc-ut

各ツールキットに対して入力するためのパッケージと、設定のためのパッケージも導入

yaourt -S fcitx-gtk2 fcitx-gtk3 fcitx-qt4 fcitx-qt5 fcitxconftool

これだけでは入力できないため、~/.xprofileに追記

export GTK_IM_MODULE=fcitx
export GTK2_IM_MODULE=fcitx
export GTK3_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS="@im=fcitx"
export DefaultIMModule=fcitx
export PATH=/home/aki/bin:$PATH

$PATHは別件だが、ついでに書いておいた。XMODIFIERSXMODIFERSと書いており、LINEやSkypeに対して日本語入力できないという問題が発生して若干ハマった。

なお、さらに後ほど突如としてGTKアプリケーションに対してfcitxが有効にならず、

gtk-query-immodules-2.0 --update-cache 
gtk-query-immodules-3.0 --update-cache 

しても直らず、結局両パッケージをアンインストールした上で再インストールしたら直った、などということもあった。

そして再起動。

パッケージインストール part1

先にいくつか使われるのがわかっている~/.config以下のファイルをコピーしておく。 .config以下はそのままシンボリックリンクに変換できないからだ。

cp ~/share/manjaro-home-transition/.config/usr-dir* .config/
cp -R ~/share/manjaro-home-transition/.config/opera-developer .config/
cp -R ~/share/manjaro-home-transition/.config/tasque .config/
cp -R ~/share/manjaro-home-transition/.config/fontconfig .config/

そして次のパッケージをインストールしていく。

  • ctags
  • leafpad
  • medit
  • geany, geany-plugins
  • smplayer, smplayer-themes, smplayer-skins
  • opera-developer
  • linux405
  • infinality*
  • wine
  • plasma
  • kde-applications
  • kopete

Wine * LINEで文字が非常に汚い、という問題があったが、いつの間にか直った。

KDE5関連はplasmaパッケージで、kde-applicationと合わせるとかなりの部分がインストールされる。

kopeteのファイルは~/.kde4以下にあるので、これをコピーする。

cp -R ~/share/manjaro-home-transition/.kde4/share/apps/koepte ~/.kde4/share/apps/
cp  ~/share/manjaro-home-transition/.kde4/share/config/kopeterc ~/.kde4/share/config

KDE5

KDE5は、KDE4よりもさらにスタイリッシュにはなったが、スマホっぽいふらっとUIになり、洗練されたがいかにも重量級な「すごい演出」は損なわれた。

また、非常に多くの機能が未実装だ。

マルチディスプレイの対応についてはkscreenパッケージで対応できるが、細かく設定ができない。 Catalystで設定することはできるが、永続しない。

また、systrayが未実装(!)。libappindicatorとsni-qtを使えばいけるような話なのだが、実際はいくつかのアプリケーションがこれでもsystrayに入らない。

相変わらずKDEで設定が効かない部分があるので、

  • kde-gtk-config
  • kcm-gtk

を導入、さらにqtconfig-qt4を使って設定する。

悪くはないけれど、KDE4から乗り換えるには早いか。 アニメーションはKDE5のほうがパワーアップしているが、KDE4よりも良いかと言われると悩むところ。 少なくとも、設定の問題でKDE4のほうが現状は良いと思う。

KDEとXFce

そして、KDEで設定するとXFceのUIが壊れたりするのでたちが悪い。 この設定はかなり難しいが、基本的には「設定マネージャー→外観」でテーマ設定してからgtk-theme-configで調整すれば良い。

ちょっとややこしいが、gtk-theme-configはextraに"gtk-theme-preferences"という名前でパッケージがあり、さらにAURに"gtk-theme-config"というパッケージもある。 恐らくは公式入りしたが、AURのパッケージ作者がメンテナになっているわけではないのだろう。

より細かく設定するならばxfce-theme-managerがあれば良いが、場合によってはより迷宮入りする。KDEといったり来たりすることになるだろう。

なお、一度XFceが起動不能になり、~/.config/xfce4を吹き飛ばして作りなおすはめになった。この場合、skelからコピーするのが近道。

パッケージインストールpart2

  • cinnamon
  • xsane
  • xfce4-theme-manager
  • fetchmail
  • spamassassin
  • razor
  • virtualbox*
  • tasque
  • skype, skype-call-recorder
  • openssh, sshfs
  • lv
  • w3m
  • nss-mdns
  • amarok
  • audacious, audacious-plugins
  • libcue
  • audacity
  • inkscape-gtk3-bzr

Inkscapeは猛烈に長い。

Zeroconfの設定は、これに加え/etc/nsswitch.confにmdns-minimalを書くこと。avahi-daemonは標準で起動。

Pandoc

相変わらずhaskell-pandocパッケージが入らないので

yaourt -S ghc cabal happy alex

してから

export PATH=$HOME/.cabal/bin
cabal update
cabal install pandoc

PDF出力用に…

yaourt -S texlive-core texlive-langcjk

うまくいった。

TODO

今わかっているのは、Spamassassinのsa_learnで学習したデータを持ち込んでいないこと。

あと、SOXもまだインストールしていない。 それ以外は恐らくは必要になったら足す形で、ゴミパッケージをなるべく増やさないようにするだろう。結局使えなかったものをためこんでしまったからだ。

また、英数キーを押すと問答無用でCapsLockになる、というトラブルも出ている。

Manjaro LinuxでMarkdown

ManjaroでMarkdownを活用しようと思ったのだが、案外苦労したのでレジュメを兼ねて記載する。

MarkdownはGitHubでおなじみの書式だ。この書式については車輪の再開発となるので省略する。

その変換を行うのがmarkdownプログラムだが、この実装はRuby、Rythonなど他にも色々とある。だが、markdownは単純なプログラムで単純なHTMLを出力する。そのため、組み込んで使いやすいが、今回は完全なHTMLがほしい。

そこでpandocを使うことにした。だが、どうもHaskellまわりがぐちゃぐちゃしている。結局インストールしたパッケージは

  • ghc
  • alex
  • happy
  • pandoc-static

さらにPDF出力のために以下をインストール

  • texlive-most
  • texlive-langcjk

CSSファイルを指定してHTMLを出力。

pandoc \ # Pandoc
-s ~/doc/work/si/twitter.md \ # ソースファイルの選択
-t html5 \ # HTML5で出力
-o ~/tmp/twitter.html \ #出力ファイルパス
-c ~/doc/materials/markdown.css/github.css # CSSファイルの指定。埋め込みはしない。

TeX経由のPDF出力

pandoc \ # Pandoc
-s ~/doc/work/si/twitter.md \ #ソースファイル
-o ~/tmp/twitter.pdf \ #出力ファイル
-V documentclass=ltjarticle \ #日本語出力のためのオプション
--latex-engine=lualatex #LuaLaTeXを使用

フォント指定のためのTeXファイルを作成

\setmainfont{Rounded-X M+ 2c medium}
\setsansfont{07YasashisaGothic}
\setmonofont{Ricty}

フォント指定の上PDF出力

pandoc \ # Pandoc
-s ~/doc/work/si/twitter.md \ #ソースファイル
-o ~/tmp/twitter.pdf \ #出力ファイル
-V documentclass=ltjarticle \ #日本語出力のためのオプション
--latex-engine=lualatex #LuaLaTeXを使用
-H ~/tmp/fontdefine.tex #フォント設定を行ったTeXファイル