Markdown でビジネス文書を作成する

まとめ

  • Pandoc’s Markdown という一方言には::: という汎用Divに対応する記法がある。
  • {markdown, latex} → html は pandoc のみでできる。別途 css を用意するといい。
  • {html, latex} → markdown は pandoc のみでできる。
  • {html, markdown} → latex はフィルタが必要。別途 sty を用意するといい。

ビジネス文書

しばらく前に「公文書を Markdown で」という話題があった。図入りの面倒くさいものや白書のような普通の書籍ほどの長大なものや法律の条文のような特殊なものは別として、圧倒的に多いであろう1枚ペラ程度の通達の類の文書には、 Markdown はとても向いていると思う。簡単なものほど Word のような高機能文書作成ソフトを使わずに Markdown で済ませたい。

この様式[1]は、役所が作成する公文書[2]から会社、さらには小学校や PTA、町内会までよく浸透している。

しかし Markdown では、この類の文書の様式に欠かせない右寄せ(右揃え)ができないのが最大のネックだ。意味見た目の分離という観点から言えば右寄せ(右揃え)は見た目なのだが、ここではもうそう呼ぶ ことにする。

Markdown

機能を絞り込んで簡潔であることが Markdown の特長なのだから、あれもこれも盛り込んでいけば最初から HTML を使えばいいとなって元も子もない。とは言え不満はなんとかしたい。Markdown で書きながらも最終的には HTML にすることを想定して直接 HTMLタグ (<div style="text-align:right">)を書いてしまうという手段もあるのだが、せっかくの Markdown なのだし他の形式への変換も考えるとなるべくそういうことはやりたくない。

ここは Markdown 記法に HTML の汎用タグ <div><span> を表せるものがあれば万能なのになあ……と思っていたら、Pandoc’s Markdown という一方言にはこれが存在していることに今さらながら気がついた。

Pandoc の Markdown 拡張

Pandoc’s Markdown という一方言には::: という汎用の Div に対応する記法がある。ここでは触れないが、汎用の Span に対応する []{} 記法もある。

この記法は Pandoc で考案されたようだ[3]。他の方言ではあまりサポートされていないようだ。HackMD (CodiMD, HedgeDoc) では ::: はやや違った意味にされ、記法も違い限定された語だけしか使えないようだ。

汎用タグを使いすぎれば意味見た目の分離が台なしになることは解っているのだが、最終手段として便利であることは間違いない。

たとえばファイル名 input.md に、Pandoc’s Markdown で書く。

::: {.myaddress}
○△□町会\
会長 ▼▲ ■◆
:::

Markdown から HTML へ

pandoc の標準機能で、特に何もしなくてもいい。コマンドラインで

pandoc --from markdown input.md -to html -o output.html

これにより作成される output.html は次のようになる。

<div class="myaddress">
<p>○△□町会<br />
会長 ▼▲ ■◆</p>
</div>

つまり、Markdown で書いた {.myaddress} がクラス名になる。このクラス名に対応する CSS は別途用意しておく。たとえばファイル名 myaddress.css に

.myaddress {
        text-align: right;
        text-indent: 0pt;
}

と書いておき、コマンドラインで

pandoc --from markdown input.md --to html --output output.html --css myaddress.css --standalone

として利用する。スタイルシートへのリンクがドキュメントヘッダに含まれるため、–standalone オプションも同時に付ける必要がある。

Markdown から LaTeX へ

出力形式を LaTeX とすると、::: は除去されてしまう。つまりコマンドラインで

pandoc --from markdown input.md --to latex --output output.tex

とすると、作成されるファイル output.tex は次のようになる。

○△□町会\\
会長 ▼▲ ■◆

pandoc の作者によるフィルタの例 latexdivs.py を使う[4]と、出力を

\begin{myaddress}

○△□町会\\
会長 ▼▲ ■◆

\end{myaddress}

のようにできる。これを実際に LaTeX で処理するには、 myaddress 環境を別途定義しておく必要がある。たとえば myaddress.sty に

% myaddress
\newenvironment{myaddress}
{\begin{flushright}}
  {\end{flushright}}

と書いておき、コマンドラインで --include-in-header で読み込ませる。

pandoc --from markdown input.md --to latex --output output.tex --include-in-header myaddress.sty --standalone

これにより作成される出力ファイルの内容は

\documentclass (略)
  (略)
% myaddress
\newenvironment{myaddress}
{\begin{flushright}}
  {\end{flushright}}
  (略)
\begin{document}

\begin{myaddress}

○△□町会\\
会長 ▼▲ ■◆

\end{myaddress}

\end{document}

のようになる。

形式の相互変換

以上、markdown → {html, latex} の例を示した。

自分のよく使う markdown, html, latex の相互変換についてまとめると、

  • {markdown, latex} → html は pandoc のみでできる。別途 css を用意するといい。
  • {html, latex} → markdown は pandoc のみでできる。
  • {html, markdown} → latex はフィルタが必要。別途 sty を用意するといい。

となる。

具体的な例

変換された html で利用する CSS ファイル
business.css
latex 出力のための pandoc フィルタ
business_md.py
latex 出力が利用する sty ファイル
business.sty
入力ファイル (markdown)
business-sample.md
pandoc --from markdown --to html --css business.css --standalone --output business-sample.html business-sample.md での出力ファイル (html)
business-sample.html
pandoc --from markdown --to latex --filter=./business_md.py --include-in-header business.sty --standalone --output business-sample.tex business-sample.md[5]での出力ファイル (latex)
business-sample.tex
pandoc --from markdown --to pdf --filter=./business_md.py --include-in-header=./business.sty --output business-sample.pdf business-sample.md[6]での出力ファイル (pdf)
business-sample.pdf
  1. 英文レターの形式を調べると、アメリカ式「フル・ブロック・スタイル」とイギリス式「フル・インデント・スタイル」が見つかる。日本のいわゆるビジネス文書はこのイギリス式「フル・インデント・ス タイル」にとてもよく似ている。特に電磁的文書ならアメリカ式がとても楽だし合理的だと思うのだが、なんと言っても理屈ではない習慣だからそう簡単に廃れることはないだろう。
  2. 検索すると多くの自治体の規程が見つかる。たとえば墨田区佐伯市など。
  3. Syntax for divs
  4. サンプルのフィルタ latexdivs.py をそのまま使うには、入力ファイルのクラス名を書くところに .latex を加えておく必要がある。つまり input.md は ::: {.latex .myaddress} のように書く。
  5. PDF に変換させるには、オプションはこれだけでは実は足りず、ここの例では --pdf-engine=lualatex -V documentclass=bxjsarticle -V classoption=pandoc -V classoption=jafont=auto -V indent=1zw -V pagestyle=empty を加えている。
  6. 前註に同じ。

dvipdfmx の map の置き場所

TeXLive 2016 から 2017 での変化なのか、Debian 固有の問題なのかわからないが、メモ。

LaTeX から PDF を作るのに dvipdfmx を使っている。いまどきは、はじめから pdfLaTeX とか LuaLaTeX を使うのだろうが、もう10年ほどもこの方法で、スクリプトにしてやっているからそのままだ。

つい最近、Debian Testing (Buster) でパッケージを更新したら TeXLive が 2016 から 2017 になったようで、dvipdfmx でフォントを埋め込む際に参照する map ファイルが見つけられず PDF を作れなくなってしまった。map ファイルは /etc/texmf/dvipdfmx/ 以下にある。

調べてみると、/usr/share/texlive/texmf-dist/web2c/texmf.cnf で、以前も今も

TEXMFSYSCONFIG = /etc/texmf

は変わらないが、

TEXMF = {$TEXMFCONFIG,$TEXMFVAR,$TEXMFHOME,$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFLOCAL,!!$TEXMFDEBIAN,!!$TEXMFDIST}

TEXMF = {$TEXMFAUXTREES$TEXMFCONFIG,$TEXMFVAR,$TEXMFHOME,!!$TEXMFLOCAL,!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFDEBIAN,!!$TEXMFDIST}

になり、

TEXMFDBS = {!!$TEXMFSYSVAR,!!$TEXMFLOCAL,!!$TEXMFDEBIAN,!!$TEXMFDIST}

TEXMFDBS = {!!$TEXMFLOCAL,!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFDEBIAN,!!$TEXMFDIST}

に変更されていた。要するに $TEXMFSYSCONFIG に !! が付き、それが $TEXMFDBS に含められている。

対処としては texmf.cnf の設定を以前と同じようにすればいいのかもしれないが、/etc/texmf/ls-R を (mktexlsr で) 作成すれば、すんなり元のように PDF を作れるようになった。どちらのほうがいいのだろう。

先取りなのか回り道なのか—さんすう編—

長いあいだこのブログも更新していなかったが、そうするうちにスウちゃん(仮名)は1年生になった。

8か月ほど前に「ドミノとさんすう」で、その頃の“さんすうのおべんきょう”について書いてみたのだが、現在の状況についてメモしておこう。なお家での独自の“べんきょう”についてであって、学校でのさんすうや宿題は、これとはまた別にあるのは言うまでもない。

前の記事の『ふたたび「さんすう」』の節にも書いたとおり、筆算(縦書き)をかなり早めに(ほとんど意味がないと思える1桁どうしの計算のころから)教えてきた。また、ブロックを使っていたものが2桁どうしになるとほぼ無理となり、簡単な図を描くように変わってきた。

現在(小学校1年生の6月末)は、2桁どうし[1]のたし算・ひき算の筆算を、脇に図を書きながらやっている。とにかくたし算・ひき算だ。かけ算は1桁どうしもやっていなければ、図形もやっていない。

こちらが問題を考えて作ってやるのが面倒なので、半自動で作成するようにした。つまり、LaTeX の emath マクロを利用して、その中の

を使って、A4横置きの紙に20問(たし算かひき算かはランダム)を出力するようにした。スウちゃんは気が向いたら(それは退屈でほかにやることがないときか)これをプリントして、やっている。

繰り上がりや繰り下がりのときの「筆算でのテクニック」—上に1を書くだの—は教えていない[2]。そのため、脇に図を描いては「10の束が何本、ばらが何個」というふうにやっている。わりと間違えないし、そこそこ速くできるものだ。

「テクニック」はそのうち学校で教わるだろう。そのときにあっと思ってくれればいい。テクニックばかり先に覚えてしまうとその元になっている考え方は忘れてしまうだろう。そういえばいま学校では1桁のたし算(結果が10まで)をやっている。宿題で「けいさんカード3回」などが出る。単語カードのようなものの表側に「2+5」「3+1」「4+4」と書かれていて(たとえばこんなようなもの)、それをすばやくめくりながら「なな!」「よん!」「はち!」と声を出すのだ。たし算のしくみはきっちり教えられたうえで、いまはこのカードなのだと思いたい。

筆算の「テクニック」は学校で教わるころまで措いておくことにして(そのうち自分で“発見”するかもしれないしね)、今日もまた棒と丸の図を描いているのであった。

  1. 計算の結果が3桁になることもある。
  2. ただし繰り上がり(「10束が1本できるよね」)や繰り下がり(15-7など)そのものの考え方については教え、何度もブロックで手を動かしてきた。

pandoc の使い方メモ — 相互参照について

やりたいことは「元の文章を markdown で複数のファイルに分割して書き、それをウェブで公開するために個々に HTML に変換したい。もう一方では印刷できるような一括した PDF を LaTeX 経由で作りたい。ついでに EPUB も作りたい」です。割とありがちなケースだと思うので、もっとすっきりした方法があるように思うのですが、うまく見つけられませんでした。

相互参照とは、HTML では id 属性と a タグで実現されるもの、LaTeX では \label{}\ref{} で表現されるものです。

索引は、LaTeX では後で処理するために \index{} で印を付けておくものです。HTML と EPUB では使いません。

例を挙げます。

a.md

はじめに {#hajimeni}
========

...

用意するもの
============

...

道具 {#dougu}
----

* 包丁
* まな板
* ...

これらは[「下ごしらえ」](b.html#shita)で使います。

* 大きな鍋\index{おおきななべ@大きな鍋}
* ...

これらは[「調理」](b.html#chouri)で使います。

材料 {#zairyo}
----

...

b.md

手順
====

下ごしらえ {#shita}
----------

ここで使う材料は[「材料」](a.html#zairyo)にまとめてあります。
...

調理 {#chouri}
----

...
大きな鍋\index{おおきななべ@大きな鍋}([「道具」](a.html#dougu)を参照のこと)を使います。
...

盛り付け {#moritsuke}
--------

おわりに
========

...


という文書が元になります。

HTML

a.md → a.html, b.md → b.html のように個々のページを独立して生成することにします。それを見越して、md ではリンクの書式のところにこれらのファイル名を入れておきます。

md を pandoc

pandoc -o a.html a.md
pandoc -o b.html b.md

と処理すると

a.html
<h1 id="hajimeni">はじめに</h1>
<p>...</p>
<h1 id="用意するもの">用意するもの</h1>
<p>...</p>
<h2 id="dougu">道具</h2>
<ul>
<li>包丁</li>
<li>まな板</li>
<li>...</li>
</ul>
<p>これらは<a href="b.html#shita">「下ごしらえ」</a>で使います。</p>
<ul>
<li>大きな鍋</li>
<li>...</li>
</ul>
<p>これらは<a href="b.html#chouri">「調理」</a>で使います。</p>
<h2 id="zairyo">材料</h2>
<p>...</p>
b.html
<h1 id="手順">手順</h1>
<h2 id="shita">下ごしらえ</h2>
<p>ここで使う材料は<a href="a.html#zairyo">「材料」</a>にまとめてあります。 ...</p>
<h2 id="chouri">調理</h2>
<p>... 大きな鍋(<a href="a.html#dougu">「道具」</a>を参照のこと)を使います。 ...</p>
<h2 id="moritsuke">盛り付け</h2>
<h1 id="おわりに">おわりに</h1>
<p>...</p>

ができます。LaTeX の索引のために挿入しておいた \index{} は無視されるので、特に気にすることはありません。

LaTeX 経由 PDF

ソースは複数ファイルに分割されていても最終的な成果物はひとつであってほしいため、main.tex を用意しておき、

main.tex
\documentclass[a5paper]{jarticle}
\usepackage[dvipdfmx]{hyperref}
\usepackage{makeidx}
\makeindex
\begin{document}
\tableofcontents
%
\input{a}
\input{b}
%
\printindex
\end{document}

これから dvi を作り、さらにそれから pdf を作ることにします(pandoc から PDF を出力させることもできるようですが、日本語のとおる環境を設定したり次に述べる処理を挟んだりするのがやりにくいので、こういうやり方にします)。

さて、ここで読み込まれる a.tex, b.tex を md から pandoc で生成するのですが、単純にやるだけでは、HTML 向けに書いていたリンクのところが

これらは\href{b.html\#shita}{「下ごしらえ」}で使います。

のようになってしまいます。これではよろしくないので、

sed 's/\(\[[^\]*\]\)[\(][^#]*\(#[^\)]*\)[\)]/\1(\2)/g' a.md \
| pandoc -t latex \
| sed 's/\(\\hyperref\[\([^\]*\)\]\)[\{][^\}]*[\}]/\1\{\\ref\{\2\}\}/g' \
> a.tex

のようにします。バックスラッシュと括弧だらけでわかりにくいですが、前段の sed

[「下ごしらえ」](b.html#shita)

[「下ごしらえ」](#shita)

のように、丸カッコ内のファイル名相当の部分を削除します。これで生成物の当該部分は

\hyperref[shita]{「下ごしらえ」}

となるので、後段の sed でこれを

\hyperref[shita]{\ref{shita}}

のように書き換えます。

これにより、生成物は

a.tex
\section{はじめに}\label{hajimeni}

\ldots{}

\section{用意するもの}\label{ux7528ux610fux3059ux308bux3082ux306e}

\ldots{}

\subsection{道具}\label{dougu}

\begin{itemize}
\itemsep1pt\parskip0pt\parsep0pt
\item
  包丁
\item
  まな板
\item
  \ldots{}
\end{itemize}

これらは\hyperref[shita]{\ref{shita}}で使います。

\begin{itemize}
\itemsep1pt\parskip0pt\parsep0pt
\item
  大きな鍋\index{おおきななべ@大きな鍋}
\item
  \ldots{}
\end{itemize}

これらは\hyperref[chouri]{\ref{chouri}}で使います。

\subsection{材料}\label{zairyo}

\ldots{}
b.tex
\section{手順}\label{ux624bux9806}

\subsection{下ごしらえ}\label{shita}

ここで使う材料は\hyperref[zairyo]{\ref{zairyo}}にまとめてあります。 \ldots{}

\subsection{調理}\label{chouri}

\ldots{}
大きな鍋\index{おおきななべ@大きな鍋}(\hyperref[dougu]{\ref{dougu}}を参照のこと)を使います。
\ldots{}

\subsection{盛り付け}\label{moritsuke}

\section{おわりに}\label{ux304aux308fux308aux306b}

\ldots{}

となります。

これで相互参照が正しくなった中間ソース a.tex, b.tex ができましたので、main.tex を

platex main
platex main
mendex main
platex main
dvipdfmx main

と処理して、最終的に main.pdf を得ることができます。

EPUB

pandoc は EPUB 形式を出力することもできます。

ソースは複数ファイルに分割されていても成果物はひとつにまとまっていたほうがいいので cat でつなぎます。また、HTML 向けに付けていたリンクの書き方を変更して(LaTeX の場合の前処理と同じです)、pandoc にかけます。

cat a.md b.md \
| sed 's/\(\[[^\]*\]\)[\(][^#]*\(#[^\)]*\)[\)]/\1(\2)/g' \
| pandoc --self-contained -o main.epub

これで最終成果物の main.epub ができます。LaTeX の索引のために挿入しておいた \index{} は無視されるので、特に気にすることはありません。

HTML や LaTeX、EPUB を出力する際には、もっと適切な pandoc のオプションを付けたり、テンプレートを用意したほうがいいのですが、ここでは相互参照に絞って説明するため、これらを割愛しました。

dvips

しばらく前からdvips(dvipsk-ja)が dvips: ! Couldn’t find header file 8r.enc というエラーを吐いて動かない。いろいろ探しまわって、[[http://2chlinux.dtdns.net/2ch-debian/1139890780/79.html|2ちゃんねるDebianスレ]]で、 /etc/texmf/texmf.d/70dvipsj.cnfを TEXPSHEADERS.dvips = .;$TEXMF/{dvipsj,dvips,pdftex,tex,fonts/type1,fonts/enc}// と書き直せばいいことがわかった。 と思ったら、今度は mktexpk: don’t know how to create bitmap font for rml のエラー。これまた探しまわって、 >現在testingのdvipsk-jaは/etc/texmf/dvipsj以下のmapを読まないようなので というのをやはり[[http://2chlinux.dtdns.net/2ch-debian/1139890780/105.html|2ちゃんねるDebianスレ]]に見つけた。dvipsj/ は読まないが dvips/は読むということらしい。うちには/etc/texmf/dvips/というディレクトリはなかったので、 ln -s dvipsj dvips としたらたちまち動き出した。