niszetの日記

細かい情報を載せていくブログ

Pandoc 2.7.4の気配を感じとろう

マイルストーンを見ていると、進捗が可視化されますね。

前も書いたかもしれないですが、こんなところにマイルストーンが。

github.com

今日の時点で8個close、4個openで、そろそろ2.7.4かなぁ?

…と思ったんですが、このマイルストーン機能、別に普段から使われているわけではなさそうで、ここだけ見ていればリリースのタイミングを予想できるって感じではなさそうですね…。

まぁ8月には更新入るんかなぁ…。

(Pandoc) MetaBlockの不思議な挙動。

このIssueはPandocの理解度upに参考になる…かも。

このIssue、現時点でopenなのですが、初見だとなかなか面白い挙動なので見ておくと良いです。

github.com

これを、以下のようにplain2をつくって渡してあげるとmb1とmb2は同じになります。1度でも参照してしまうとダメぽい。

local plain = {pandoc.Plain("test")}
local plain2 = {pandoc.Plain("test")}
local mb1 = pandoc.MetaBlocks(plain)
local mb2 = pandoc.MetaBlocks(plain2)

下記のようにしてあげればいいわけですが、これは書き方の例としてどこかにあった方が良い気はしますね…

function Pandoc (doc)
  doc.meta.b1 = doc.blocks
  doc.meta.b2 = doc.blocks
  return doc
end

MetaBlockはBlockと基本的に同じ挙動のはずなので、これ以外は特に変なものはない…と思うけど。

Issueを読むと、こういう使い方をする人がいるんだなぁと学びがありますねぇ…。

(Pandoc) pandoc.mediabagのdelete, empty, itemsは2.7.4から(?)

マニュアルが先行しすぎているシリーズ。

最新のソースをビルドすれば使用可能であるが、Pandoc 2.7.3の公式バイナリではLuaフィルタ内で使用するpandoc.mediabagモジュール内のdelete, empty, itemsの各関数は使用できませんでした。使い方自体はマニュアルに書いてある通りのようですが。

pandoc.org

Pandocはたまにマニュアルが先行してて使えない関数が存在することもあるので注意が必要ですね。Luaフィルタ使ってる人がどれだけいるのかわかりませんが…。

mediabagは挙動が良くわかってないところがあるのでもう少しいじってみないと…

(Pandoc) -sをつけると-t nativeでもMeta情報が出力される

基本かもしれないが…。

このIssueを見ていて気付いた。

github.com

これでMeta関係の調査がはかどります(大体終わってしまったけど)

2019/10/22 追記

具体例がなかったので。

たとえば、以下のように入力する 1

echo A | pandoc  -fmarkdown -tnative -s

と、以下のように出力される。echo A としているのは空だとエラーになってしまったため。

Pandoc (Meta {unMeta = fromList []})
[Para [Str "A"]]

Meta情報が完全に空の場合はこのようになる。なぜunMetaが出力される仕様なのかがわからないと言えばわからないが…。

複数行の入力をターミナルから直接行うのは大変なので、別途ファイルを作る。

---
title: aa
---

# hoge

fuga

これを同様に、以下のようにnative形式で表示する。

pandoc test.md -fmarkdown -tnative -s

すると、このように出力される。fromListの引数であるリスト内に、(Str, Meta [])のような形で 2 書かれるようだ。インライン要素の集まりとして定義されている。

Pandoc (Meta {unMeta = fromList [("title",MetaInlines [Str "aa"])]})
[Header 1 ("hoge",[],[]) [Str "hoge"]
,Para [Str "fuga"]]

メタ部分を

---
title: aa bb
author:
  - A
  - B
---

のように書き換えると次のようになる(メタ部分だけ抜粋)。

Pandoc (Meta {unMeta = fromList [("author",MetaList [MetaInlines [Str "A"],MetaInlines [Str "B"]]),("title",MetaInlines [Str "aa",Space,Str "bb"])]})

fromListに含まれるのはタプルのリストのまま変わらず、複数の要素をリストで含む場合はMetaListがそれぞれのMetaInlines []のリストの形で持つようになっている。MetaブロックであってもSpaceは有効である。つまりStrで検索してもマッチしない場合は空白文字を含む可能性を考慮すべきである。

…という風に結構メタ部分は読むのが少し大変になっている。もっと複雑な構造もあるが、それはまた別途記事にまとめよう…。


  1. 完全に余談だけど、-が1つのオプションはその値とつなげて書くことが出来る。--fromの場合はスペースを挟まないといけない。]

  2. この書き方不正確かもしれない。

(Pandoc) MetaStringは使用しないかも(メモ)

メタ情報関係を調べている…。

MetaStringはLua filterのマニュアルに載っているが、どうやればこれを生成できるのかが不明である(他のMeta***は生成できた)

pandoc.org

Issueを漁ってみると、

github.com

が見つかった。過去にはMetaString型で保持していたものが、MetaInline中のStrとなったようで、現在はMetaStringを返すことはなさそうに見える。後方互換で残されているかもしれないが、新規に作る分にはMetaStringを与えるような書き方は良くないと思うので辞めておいた方が良さげ。

(Pandoc) Hierarchical Elementは直接観測できなさそう(メモ)

イマイチ使い方がわからなかったので放置していたが…

この辺りの話。

pandoc.org

pandoc.Secでアクセスしようとするとnilで怒られるので、うーん、困ったな、と。

Issueはこの辺りが関係してそうだったが、読んでも良くわからず。native形式で吐いてもSecとかでないしなぁ…

https://github.com/jgm/pandoc/pull/3712

と思ってコード読み漁っていましたが、hierarchicalizeでPandocのリポジトリを検索すると、特定のフォーマットのWriterにて使われていそうであることがわかった。

どうやら階層構造をドキュメント内で表現しておく必要がある場合に使われているようで、ちょっと特殊なことをしないとSecのオブジェクトをLuaの方で作るのは難しそうだ(テスト用のコードを見たらわかるようになったが)

ということで、これはいったん後回し。 他の要素を調べてから手を付ける。

(Pandoc) east_asian_line_breaksの実装を読む

Haskell自体を理解していく…。

当たり前かもですが、Pandocの各オプションに対して対応する関数が存在します。そのため、各オプションに対応する関数を少しずつ読むことでHaskellとかPandocの理解が深まるのでは?ということでやっていく。今回はeast_asian_line_breaksオプションに関連する箇所。

コードはこんな感じ。

-- | Remove soft breaks between East Asian characters.
eastAsianLineBreakFilter :: Pandoc -> Pandoc
eastAsianLineBreakFilter = bottomUp go
  where go (x:SoftBreak:y:zs) =
         case (stringify x, stringify y) of
               (xs@(_:_), c:_)
                 | charWidth (last xs) == 2 && charWidth c == 2 -> x:y:zs
               _ -> x:SoftBreak:y:zs
        go xs = xs

コード自体はここから追っても良いかも。 https://hackage.haskell.org/package/pandoc-2.7.2/docs/Text-Pandoc-Shared.html

SoftBreak前後にある要素に対して、文字として扱ったときにcharWidthがともに2となる場合にSoftBreakを削除するような挙動をしている。

…っぽいことはわかるのですが、bottomUpがどこから来ているのか、とかwhere以降をちゃんと読み解けているのか?などは疑問…。

stringifyで文字列化したあとに、xsの末尾とcがcharWidth==2を満たしているかどうかを見ているのはわかるぽいのだけど、なぜxsをas構文で:の形にしないといけないのか?とかが良くわかっていない。Stringじゃなくて明示的に[Char]として扱うためかな…?

みたいなレベルなので、もうちょっと基礎的なところもあわせて勉強していこう…。