LwDITAのDITAVALの書き方
Creating Intelligent Content with Lightweight DITAをPODで購入したので読んでいる。 いや、電子書籍版を前に買ったのだが(Kindleでない)、実用に耐えないデスクトップアプリからしか読めなかったので あらためてAmazon PODから買った。
- 作者:Evia, Carlos
- 発売日: 2018/12/05
- メディア: ペーパーバック
ChairのCarlos氏が書いているので、内容の正確性は信用してよいだろう。 DITA-OTなどの実装側の挙動はまた別の話として。
記事タイトルの内容より雑感の方が多い。
LwDITAについては塩漬けしている同人誌でそれなりに詳しく書く予定なので、ここではざっくりと書く。 DITAについては「DITA 超入門」なんかを見て。 で、「XMLはナウでヤングな世代はあんまり扱わない」 「DITAは構造化文書初学者がこれから取り組むには仕組みも要素の数もヘヴィ」 「(GFM程度の)Markdown+−の表現力で書けるくらいの入門セット」大体そういう感じ *1。
で、+な要素である、DITA機能リミテッド版の1つにフィルタリングがある。
通常のDITAでは、<p product="<任意>" ></p>
のように書くところ、
XDITA(XML版LwDITA)では次のように書く。
<p props="<任意>"></p>
MDITA(Markdown版LwDITA)とHDITA(HTML5版LwDITA)では次のように書く。
~~~html
フィルタリングされる文章......
~~~
フィルタリング処理はDITAと同じくDITAVAL(XML)ファイルに書いていくのだが、通常DITAではここは
<val> <prop att=product" val="<任意>" action="exclude" /> </val>
のように書く。で、LwDITAでは次のようになるワケだが。
<val> <prop att="props" val="<任意>" action="exclude" /> <!-- XDITA --> <prop att="data-props" val="<任意>" action="exclude" /> <!-- MDITA, HDITA --> </val>
Creating Intelligent Content with Lightweight DITAで出てくるまで、フィルタリング機能をLwDITAで使うことは考えていなかった。 (Fullweight )DITAと併用できるという特性を考えればこういう書き方になるのは「それはそう」という感じだが、 「Lightweight DITA SC | OASIS」ではtopicとmap以外の書き方についてはほどんどなく、 「DITAのこれは制限されたこれが使えるよ」のような書き方なので、LwDITAからのDITA初学者が学ぶには大分厳しい。 lntroductionとは書いてあるが、DITAを知っている人間に向けたLwDITA Introductionのように感じた。LwDITAのコンセプトが 「DITA沼の浅いところを作ってそこからひきずりこみたいわね」であることを考えると*2どうなんだそれは。 DITA機能で特徴的なconref, keyref, フィルタリングといったものを使わない場合、Markdownのドキュメントツールとして GitBookやPandocより優位な点をLwDITAに見出すのは苦労すると思う。
2018年にLwDITAの仕様が1.0になったのだが、まとまった資料はCreating Intelligent Content with Lightweight DITAと、 DITA on Diet くらいに感じてしまう。DITAっぽい機能については Creating Intelligent Content with Lightweight DITA の方を読む必要があるが、 個人が学習をはじめる本としては5000円弱はちょっと躊躇らうのではなかろうか。
まあ、コミュニティ内部では色々回っているのかもしれないが。
DITAオーサリング対応ソフトやDITA対応のCCMSなどではLwDITA対応もされているようだが、 LwDITAから学ぼうとする人間がいきなりOxygenを買うかというと微妙なところでは。 XMLを書かない手段としてのMarkdownの話の延長でXMLエディタを買うだろうか。
P.S. DITA on Dietは私訳版を作成している。今進捗半分くらいだけど。CC-BY-SA 4.0なので公開は可能なはず。でもOje Mediaというところ、Twitterアカウントは活動している様子だけれど、WebsiteはGoDaddyのやつが出てくるんだが、どうなっているんだ。
P.S. もうちょっと直接的なサンプル群が公開されているな。
LwDITAの流れについての資料は「インテリジェントコンテンツにおけるAXの役割と考察 (関根, 2016)」もある。
ライトウエイト構造化と記法の種類数
この記事はEWBアドベントカレンダー2019の23日目の記事です。
EWBとRe:VIEWの記法の数
書籍用マークアップEWBとその影響を受けて作られたRe:VIEWは、軽量マークアップとしてはかなり記法の数は少ないものとなります。
組版トリガ或いはプリプロセッサのマークアップを外すと、そのほぼ全てが2種類程度に収まってしまいます。EWBでは
//トリガ[オプション]{値 //トリガ} //トリガ[オプション] 値
なので実質1つですし、Re:VIEWでは
@<inline>{値} //block[オプション]{ 値 //}
と、リスト記法程度です。テーブルは、ここではテーブルブロック内での独自の話とさせてください。
例えば強調のインラインは
It is //g{Emphasis//g}. It is @<em>{Emphasis}.
となります。つまり、専用の記法ではなく汎用の記法となります。
Markdownでは強調は*Emphasis*
ですね。Markdownに汎用記法がないという主張ではありません。それこそHTMLタグがそうなってしまうので。
あ、最初に書き損ねましたが、今回はお気持ちだけでエビデンスなしでやっていきます。
easybooks
Markdownの記法を使いつつ、必要な箇所はRe:VIEWで書いてコンパイルまで持っていけるようにするツールだそうです。 MarkdownでHTMLタグを使うところをRe:VIEWが担うという認識でいいんですかね。
とりあえずRe:VIEWにあった統一性のようなものが失われたとも言えますね。 EWBからRe:VIEWで他のLWMLから記法が追加されている(後継というワケではないので当たり前ですが)のに今更ですが。 即ち、専用シンタックスを持つマークアップ記法と汎用マークアップ記法の混在です。
まあEWBとRe:VIEWで近すぎる関係性ではあるので、もう1つの有名な専用記法と汎用記法を持つdocutils及びSphinxの話も持ってきます。
docutilsとSphinx(reStructuredText)
Pythonという巨大プロジェクトのドキュメントのために生み出されたこれらはreSTという軽量マークアップを使います。
特徴として、強調などには*Emphasis*
といったよく見られる専用の記法があり、それに留まらないものを記述できるroleとDirectiveがあります。
多くはインラインとブロックで対応しますが、まあ拡張次第ではあります。
プレーンテキスト上で*Emphasis*
と//g{Emphasis//g}
、どちらが見易いか或いは書き易いかと問えばどちらも前者である人が多いのではないでしょうか。
慣れの問題の側面もありますが、書き易さではまあ合意が得られるはずです。
XMLやSGMLは一般的に山括弧を用いる記法で統一されています。も、これは嘘ですが、\
と{
}
と があれば文書に必要なマークアップのための記法は調います。
これだけで構成された文書は人間には読みづらく、人は様々な互換記法を生み出してきました。
その多くは頻出する構造に対しショートハンドを与える形です(「そのように変換される」といった方が良いか)。
頻出する構造の全てに専用のマークアップをつける、それに近い試みはあるにはありますが、普及率はイマイチといえます。
人は数十種類の専用記法を覚えるのが苦手なので。
そこを割り切ったからこそのMarkdownの隆盛という見方も
よく見掛けるものです。
つまりreSTがライトウエイト構造化だったんだよ!(な、なんだってー
現在easybooksのようなアプリケーションが登場したのは、特定用途のときには統一的記法でよかったもの、 汎用・日常的な用途の延長として書き(見)易い装飾的な記法のバランシングが行き着く形の1つがお気に入りの素材によって再生産されると この辺りのバランスの試みがみられるということかもしれません。 reSTの設計の歴史はちゃんと調べていないので強引ではありますが、文書毎に専用の記述をしたい場合に汎用記法を利用して拡張を行う仕組みという バランスについてなので、この辺りは突っこまれると困る。 Pandocについては、SpanとDivがこの辺りに対応するという見方をすれば似た構造に見えてきます。
よくわかっていないツールと言語でよくわかっていないマークアップのCustom Writerをやっていく
この記事は
EWB アドベントカレンダー2019の21日目の記事です。
Pandocアドベントカレンダー2019の21日目の記事です。
https://adventar.org/calendars/4338
20日目は某ZR(ざんねん🙃) (@zr_tex8r) | Twitterさんで https://zrbabbler.hatenablog.com/entry/2019/12/04/234053でした。
最初に書いておくと完成してません。 明日夜だと思っていたタスクが朝締切だったりするなど、師走を実感しますね。
前置き
さて、EWBの情報を色々と集めてきたわけですが、
「reSTをEWBに!」「いいですとも!」
ということで、他の軽量マークアップ形式からEWBにして作成された書籍がありました。残念ながら変換処理については出版社内部で行われたようで詳細は分かりませんが、DocutilsはreST以外のReader、やHTML以外のWriterを独自に作ることもできるので、この辺りを活用するとちょっと楽そうですね。楽だとは言っていませんが。
そんな感じに記事のネタを探していたワケですが、うっかり21日にPandocアドベントカレンダーの登録をしていたことを思い出しました。
そういえば鹿野さんの記事でPandocとDocutilsの相似について言及されていました。
ヨシ!
EWBの記法おさらい
EWB文書本体のマークアップには 「組版トリガ」と「編集トリガ」 があります。このうち「組版トリガ」は書籍上の見た目に関わるものなので、今回Pandocで変換元とするMarkdownからは考えなくとも良さそうです。
編集トリガの基本文法は以下のようになります。実はブロックかインラインかは記法上は区別がなく、各トリガそれぞれで異なり、なんだったら書き換えられます。
//<文字列>{ ...//<文字列>}...
見出しなどは開始タグ閉じタグがつきません。
//i 見出し
リストの基本は以下のようになります。
///k1{ <記号> <文字列> <記号> <文字列> //k1}
テーブルはシンプルな構造であれば タブ文字区切りで似たことをやればよいので、基本は大体これでいける気がしてきました。
今回はこれらの基本的なところに絞り、 Custom Writerに挑戦してみます。
みりあやんないよ
- EWBでは改行が反映されますが、今回は正しく処理できるかは考慮しないものとします。一応
SoftBreak
設定してやれば動くハズ? - EWBで使える文字種はJIS全角範囲とされています。EWBで処理時にエラーを吐いてくれるはずなので今回はスルーします。
Pandoc Custom Writer
Pandocアドベントカレンダー2019にはReaderの記事がありますが、
Writerは既にPandocに渡っている構造の出力を弄るだけなのでより簡単、な筈、です。
カスタムライターを作るために、先ずはLuaにおける出力例の一覧を取得します*1。
これを書き換えていきます。
例えば
-- sample.lua function Emph(s) return "<em>" .. s .. "</em>" end
が
-- ewbfilter.lua function Emph(s) return "//g{" .. s .. "//g}" end
になる、といった感じですね。実際のEWBでは 文字エンコーディングはSJISかEUC-JPになりますが、そんなんは後で変換かければええ。
エスケープ
さて、出力毎に調整が必要な機能として エスケープがあります。
(Pandoc)Markdownでは問題の無かった表現がEWBではNG、というものですね。
EWBのトリガは先頭に//
があるので、ここから3種くらいの区切りまでがトリガとされます。//
がきたら特別な場合を除き
////
に直してやる必要があります。
/**hoge**
といった並びのとき、素朴な置換をすると///g{hoge//g}
となりますが、ここはEWB(ハンドブック)を信じてそのままに。
また、今回扱わないといった組版トリガも
Markdown文中に表われるのはけしからんのでエスケープします。@@
は@@@@
にします。
改行
function SoftBreak() return "\n" end function LineBreak() return "\n" end
箇条書き
BulletList
ある意味単純ですね。ネストも問題無いハズ。
項目先頭の記号はとりあえず・
でハードコーディング。
function BulletList(items) local buf = {} for _, items in pairs(items) do table.insert(buf, "・ //|" .. item .. "\n") end return "//k1{{" ..table.concat(buf, "\n") .. "\n//k1}" end
OrderedList
先程よりちょっと厄介なのは、やHTMLと違って自動インクリメントされるマークアップではないので、 数字をこちらで回すこと。まあそれだけのハズ。
function OrderedList(items) local buf = {} for i, item in pairs(items) do table.insert(buf, i .. ".//| " .. item .. "\n") end return "//k2{{" .. table.concat(buf, "\n") .. "\n//k2}}" end
DefinitionList
まあ箇条書きのグループとしてみれば、やることは大体同じでしょう。
function DefinitionList(items) local buffer = {} for _, item in pairs(items) do for k, v in pairs(item) do table.insert(buf, k .. " //| ".. v .."\n") end end return "//k3{" .. table.concat(buf, "\n") .. "//k3}" end
コードブロック
元のサンプルだとエスケープ処理挟んでたんですが、 アトリビュートはまあオプション引数に影響するにしても トリガ定義側でなんとかする奴なので今回は飛ばします。
ただ、コードブロック内部のコメントは特殊な処理をしてコメントであることを明示するようにしなければなりません。 えっアイデアが浮かばない。とりあえず空のローカル関数を定義して濁します。
function CodeBlock(s, attr) local cmt_parse = comment_perse(s) return "//list1{\n" .. cmt_perse .."\n//list1}" end local function comment_parse(s) return s end
水平線
function HorizontalRule() return "//kei\n" end
Caption付き図表
EWBでは、基本的には図表を文書中では扱いません。テーブル などは記述可能ですが、文書中には基本的にユニークな番号とキャプションの文字列だけです。実際に図表リストを別に作成するのは処理が複雑化するのでスルーします。 ユニークな番号に関しては数字以外でもいいはずですが、面倒なので数字ということにしましょう。実装も手を抜いて 使用直前にインクリメントでいきましょう。
local fignum = 0 function CaptionedImage(src, tit, caption, attr) fignum = fignum + 1 return '//f'.. fignum .. " " .. caption .. "\n" end
Table
EWBのテーブルはそれなりに複雑な図表も可能ですが、シンプルテーブルの入力を仮定します。 寄せの指定は簡単ですが、カラム幅の文字数指定って互換ありそうでないんですよね。今回はやりません。
function Table(caption, aligns, widths, headers, rows) local buf = {} local function add(s) table.insert(buf, s) end add("//table1") for _, align_raw in pairs(align) do local align = ewb_align(align_raw) add("[" .. align .. "]") end add("{\n") local header_row = {} local empty_header = true for i, h in pairs(headers) do empty_header = empty_header and h = "" end if empty_header then head = "" else add("//g{") for _, h in pairs(header_row) do add(h .. "\t") end add("//g}\n") for _, row in pairs(rows) do for i, c in pairs(row) do add(c .. "\t") end add("\n") end end add("//table1}") return table.concat(buf,'\n') end
未完
とりあえずlocal
でないsample.luaに出てくる関数を全部埋めれば完成するハズ。
Span
やDev
も、本格的に変換を作るなら編集トリガと対応を作るべきなんだろうなあ。
というワケで、Readerでの難しい話が嘘のようにWriterの出力を弄るのは楽かもしれないという結びです*2。
明日の枠も空いてるみたいですが、明日はSphinxをやっている予定なのでこの続きで埋めるとかはないです。
*1:(新・工事中)Pandocユーザーズガイド 日本語版 — 日本Pandocユーザ会 2019.02.21 ドキュメント
*2:ならなぜ完成してないんでしょうねぇ
動いているEWBを見るの巻
この記事はEWBアドベントカレンダー2019の20日目の記事です。
作成済みVMイメージの起動
以前の記事を読むと、最新FreeBSD環境でのEWB関連パッケージ展開に失敗してる有様が分かるかと思います。やりようはあるのかもしれませんが、とりあえずモチベは高くなかったので、例のDVDについてきたFreeBSD+EWB.vmdkのイメージをVirtual Boxで起動することに。ううっ。
まあ使うと決めたら難しいことはないんで、やるだけ。
やっていき
さっそくsampleディレクトリのファイルを触ってみます。
$ xemacs
で、おお、xemacs君が。適当にsample.ewb
を開いてみると。
あっ文字コードが。
$ echo $LANG
をするとja_JP.EUC
の表示。ターミナルはEUC-JPと。ではこのファイルはSJISとかかな。
$ nkf --guess sample.ewb
出ません。そう、思い出してください。当時のnkf
のバージョンは…… 1.9!
UTF-8なんかは知らない子扱いですよ。ちょっと扱いづらすぎますね。
とりあえずEWBが置いてある場所を見てみます。最新環境で入れてみることを諦めたわけではないですからね。
サーバのCUI探索気分はこのへんで。
「こんな不便な環境にいられるか! 俺はホスト環境に戻らせてもらう!」
というワケで、EWBをこのVM牧場で飼うことができました。 コンパイルやツールを試す予定だったんですが、集中が切れたので。
Next
明日Pandocアドベントカレンダーの担当だったんですがどうしましょう。 EWBアドベントカレンダーも担当ですね。 そうだ! PandocでEWBを出力しよう!(?)
:thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face::thinking_face:
次回! ひだるま死す! デュエルスタンバイ!
Perl to Goしようと思ったら結構既出だった
この記事はEWB アドベントカレンダー2019の19日目の記事です。
この一連の記事の最終的な目標は現代のTeXLive環境で動作するEWBを Invent*1することだというのは初めて書く気もします。アドベントカレンダー中には終わりませんが、長期的にはできるといいな。
さて、EWBを構成するツールはどれもこれもJavaかEmacsLispだと思っていたら、 そこそこPerlスクリプトがあることが過去の記事で判明したワケです。 Perl5が動かない現代的環境はほぼ無いので、これらはそのまま持ってきても 大体の環境で動作してくれるはずです。でも、気軽に達成感が得られそうな手段を放置するのはなんかアレだし、モチベーションアップのために手作業のあたたかみのある車輪を手に入れたい。
一般的な話として、「かつてPerlで書き捨てたスクリプトをGoに直したい」欲求は 多いようで、様々な記事が見つかります*2。例えば
のような。
あと19日が1時間もない状態でこの記事を書きはじめたので、ザッと見ていきましょう。
gettoc
サルベージしたスクリプト群からgettocの登場です。
読みこむewbファイルを登録したファイルを元に、Table of Contentsを作るという目的のツールですね。も読み込んだファイルの見出しからtocを生成してくれますが、
こちらはいつ使うんだ、という。各トリガなどの読み込みをしてEWBファイルとしての目次を出力します。\tableofcontents
でtexの処理になると、nitianの仕事になってしまうので、この独自tocを使っていくようです。
方針としては
- init処理 -> os/flagでやればよさそう
- トリガリスト取得 -> 読み込んだファイル中のトリガをstringのリストにする
- ファイル処理 -> メモリ容量を超越する超巨大ファイルは後で考えるとしてとりあえずio/utilかな
- 見出し文字列をファイルから取得 -> 一先ずreadLine()あたりで良さそう。少なくとも見出しは行頭スタートで見出しになる程度の文字数しかないと仮定すれば。
- 出力用ハードコード文字列 -> text/templateで別にした方が取り回しがいい?
といった感じですね。その後で元にないお節介機能を加えるなら、巨大ファイル対策、並列化、パスのOS間差異吸収あたりでしょうか。
Next
やっていきをしたいんですが、1日は24時間しかない。 尻切れトンボな25日目にならないようにはしたい。したいが。
技術書典7で頒布した同人誌の公開
この記事はアドベントカレンダー2019の19日目の記事です。
18日は Xs (@qp_mzzt) | Twitter さんの LaTeXで目次のカスタマイズをしてみた - Qiita でした。
間に合わなかったよ……
本来であれば本日は技術書典7にて頒布した「LuaLaTeX微文書作成入門」の改稿版を公開する予定となっておりましたが、 別の某アドベントカレンダーやら様々にバタバタしておりましたところ、嘘です、忙しさにかまけて自分の書いた文書から 目を逸らし改稿が遅々として進まなかったところ、この日を迎えてしまいました。本日は頒布した内容をそのまま公開させて いただきます。
何の本だったか
- LuaLaTeX入門本を目指すもの
- LaTeX入門書を読んでいる前提
- LuaLaTeX向けクラスファイルの紹介
- フォント設定
- tcolorboxでlistingができる
- TikZで図以外ができるよ
- ビルドツール紹介
- 分割ビルドとパッケージ
- LaTeX用Webサービス紹介
既知の要訂正箇所(2019年12月19日公開版では直っていません。改稿後直る箇所です。)
- ClutTeXの動作の訂正(正しい内容に関してはTeXConf 2019向けのClutTeX発表資料 | 雑記帳や だめぽラボ 「LaTeX文書処理自動化ツールClutTeX 使い方とその仕組み」にて正しい内容を得てください)
- 各パッケージの更新やGitHubActionsのステートといった頒布後にアップデートされた情報
- fontspecでのfakeboldについて(書典7での頒布時のバージョンではLuaLaTeXでは無効のはず)
- 本文フォントが小さい
- tcolorboxの紹介をしているのにtcolorboxを使った部分のデザインがアレ
- Luaマクロの適例がない
では、どうぞ
https://drive.google.com/file/d/19OQTORvLstkHt82yQ5woZ4O_Bf5Zav0X/view?usp=sharing
今後の更新
リファクタリングと一通りの更新が終わったらGitHubにてソースを含めた公開を行います。その際現在の旧版はアクセスできなくなる予定です。
ついでなので、改題し新表紙になる予定です。
明日のTeXLaTeXアドベントカレンダー
投稿とアドベントカレンダーに関する訂正
この記事は EWBアドベントカレンダー2019の18日目の記事です。
おわび
過去「EWBについて扱った書籍が1冊くらいしかない。しかもアスキー社からは出てない」旨の発言を何度かしておりましたが、訂正いたします。
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1989年に刊行されておりました書籍がEWBを扱ったものであるようです。
1989年となるとかなり素朴な1系についてのものでしょうか。積極的に探してみようと思います。