niszetの日記

アナログCMOS系雑用エンジニアが頑張る備忘録系日記

Pandoc 2.7.2 に同梱されているLuaのバージョンの確認

簡単に書けるものなら色々作れそう。

さて、PandocのLuaフィルタについて少しずつ調べているのですが、簡単なものであればもう書けそうなので順次書いていく。

たとえば以下のような関数を作ってLuaフィルタとして使用する。

    function Str(elem)
      if elem.text == "{{LUA_VERSION}}" then
        return pandoc.Emph {pandoc.Str(_VERSION)}
      else
        return elem
      end
    end

で、Markdownの本文中に{{LUA_VERSION}}と書いておくと、変換後にここがLua 5.3となる。よって、Pandoc2.7.2に同梱されているLuaのバージョンは5.3であり、Programming in Lua Forth Editionに書かれていることを全部使えるということになる。

以上。

Enjoy!!

PandocのLuaフィルターを書いてみる

Luaの文法がまだ覚えきれていないのでまずはそっちを固めるべき

ひとまず、公式のマニュアルを読んだ。

pandoc.org

例はココにあるらしいが、まだ読んでいない。

github.com

また、通常のフィルターも少しだけ目を通したが、フィルタの実行環境を持っていない人にどうやって環境を渡すのかを考えるのが面倒なので、Pandoc2.0から本体に組み込まれ、そして他の言語よりも動作が速いと書かれていたLuaのフィルターを使うこととした。

pandoc.org

最近Luaの勉強をしていたのはそのためである ^[もうひとつ、FlashAirのためでもあるのだが]

マニュアルに書かれていないことが多くないですかね…。

とりあえずマニュアル読んだだけだと非常に簡単なものしか作れない。ちょっと習作ということで、強調を斜体に変更し、間にあるスペースを削除して詰めるフィルタを書いた。結果としてそうなったというだけで、はじめからそうしたかったわけではないのだが。

function Strong(elem)
  t = ""
  for k, v in pairs(elem.content) do
    if v.tag == "Str" then
        t = t .. v.text
    end 
  end
  return {pandoc.Emph(t)}
end

これで、**HU HU HU HU**と書いたものが*HUHUHUHU*と等価な出力となった。

この変換前の一文は

"C:/Program Files/RStudio/bin/pandoc/pandoc" -f markdown hoge.md -t native

のようにnative形式で出力すると

Para [Strong [Str "HU",Space,Str "HU",Space,Str "HU",Space,Str "HU"]]

に対応する。ここで、elem.contentはこの[Str "HU",Space,Str "HU",Space,Str "HU",Space,Str "HU"]を受け取ることになる。

さて、コードについて。function Strong(elem)でStrongが見つかったらこの関数をcallするような挙動 ^[実装がそうなっているのかは確認していない。]となる。ここでelemを引数に入れないとどうなるんだろ?あとでやってみる。

for文で各要素を見ていく。ここでkは要素のindex、vが実体になるようだ。この場合、ipairsの方が良いのかもしれない。あとでやってみる。

Spaceはtextを要素に持っていないのでnilが返る。nilと文字列は結合できないので先にvのtagがStrであることを確認している。もっと良い実装があるだろうけど。

  t = ""
  for k, v in pairs(elem.content) do
    if v.tag == "Str" then
        t = t .. v.text
    end 
  end

で、テキストを結合している。最初に空の文字列を与えないとこれまたnilとの結合になるので注意。Luaはundefinedは全部nilだ。

最後はtableにして返さないとダメっぽいが、ここは理由がちょっとよくわからない。他の例では大丈夫だったはずなのに。

  return {pandoc.Emph(t)}

ということで、はじめてのLuaフィルタの完成なのでした。

Word出力にする際にちょっとあれこれいじりたいところがあるので、Luaのfilterを使って何とかしたかったのですが、これならすぐできるかもしれないね。

Enjoy!!

「Rmarkdown でチャンクとその出力に行番号を付ける」をもうちょっと見てみる

自分でも理解するために。

さて、RMarkdownでコードを埋め込んだ際、行番号をいれたいという要求がありますね。Atusyさんの下記のブログのようにするとHTMLとPDF形式は対応できるようです。良かったよかった。

blog.atusy.net

補足をする。

先のページではhighlight: pygmentとしていますが、さっき書いた記事のとおりの他のhighlightでも有効です。ただし、何かしらのhighlightの指定が必要です。

niszet.hatenablog.com

これはhtml_documentがやっているのか、Pandocがやっているのか?

答えは後者。これは、

output: 
  html_document:
    highlight: tango
    keep_md: True

のように、keep_md: Trueを追加して中間ファイルであるMarkdownファイルが削除されないようにして確認すればわかる。対象となるコード部分になにも差異がないことがわかるだろう。ということは、Pandocが行っている(実際にはhighlightingを有効にしないと出てこないため、skylightingがやっているかもしれない。保留)

余談

ちなみに、コードブロック(Rのコードチャンクではなく、ここはコードのブロックですよと示す場合)はバッククォートでも良いが、チルダ(~)でも書ける。また、ブロックに対してcssでclassを指定する場合は{.numberLines}のように書けるので、

~~~ {.r .numberLines}
plot(iris)
3+3
~~~

のようにも書ける。実にどうでも良いことだが…。ちなみに、rの前に.をつけているのでこのコードは実行されない。というか、チルダの場合はR MarkdownのRのチャンクコード(実行可能なコード)としては扱われないので注意。

cssがやっているわけではないようだ。

ぱっと思いついたのはcssのカウンターで行番号をつけることをしているのだろう、そう思って検索してみたのです。以下に事例がある。

https://codepen.io/elomatreb/pen/hbgxp

www.sylvaindurand.org

www.studiomic.net

ただこれだと、各行がcodeとかspanとかのタグで囲われていないといけない。Pandocで変換されたhtmlファイルを確認するとわかるが、実際にはそのようになっておらず、全体をcodeタグで囲っている。つまり、この方法では行番号をつけることは出来ないことになる。

実際に動いている場所はココ

github.com

一部抜粋。

                  startNumber = firstNum,
                  lineAnchors = any (`elem`
                        ["line-anchors", "lineAnchors"]) classes,
                  numberLines = any (`elem`
                        ["number","numberLines", "number-lines"]) classes,

これを見ると、行番号を示すには"number","numberLines", "number-lines"のいずれかが指定されていればよいことがわかる。

実のところ、これはマニュアルに書いてあるのであった。

pandoc.org

このあたり読んでるはずなのに全部忘れてしまう…

宿題

ということで、skylightingライブラリが絡んでいるっぽいのでちょっと調べないとこれ以上はかけないことがわかりましたー。Pandocの沼は深いだけでなく広い…。

そして、Wordでも行番号が欲しいですね。調べましょう。

ということで、これらは宿題です。いかがでしたか?ブログになってしまいましたねぇ。まぁそんなこともあるさ。

Enjoy!!

(メモ)Pandocのsyntax highlighting

前書いたかもしれないけど。

とりあえず、出力の例はここで確認できる。

www.garrickadenbuie.com

詳しくはマニュアルを読むのが良い。何事も。

pandoc.org

さて、RStudioで使用しているPandocがどのhighlightのスタイル?を利用できるかは以下のようにして確認できる。

"C:/Program Files/RStudio/bin/pandoc/pandoc" --list-highlight-styles
pygments
tango
espresso
zenburn
kate
monochrome
breezedark
haddock

マニュアルより、The Haskell library skylighting is used for highlighting.とあるように、Haskellのskylightingライブラリが使用されている。

ハイライトされる言語は下記のように確認できる。

"C:/Program Files/RStudio/bin/pandoc/pandoc" --list-highlight-languages
abc
asn1
asp
ats
awk
actionscript
ada
agda
alertindent
apache
bash
bibtex
boo
c
cs
cpp
cmake
css
changelog
clojure
coffee
coldfusion
commonlisp
curry
d
dtd
default
diff
djangotemplate
dockerfile
doxygen
doxygenlua
eiffel
elixir
email
erlang
fsharp
fortran
gcc
glsl
gnuassembler
m4
go
html
hamlet
haskell
haxe
ini
isocpp
idris
fasm
nasm
j
json
jsp
java
javascript
javadoc
julia
kotlin
llvm
latex
lex
lilypond
literatecurry
literatehaskell
lua
mips
makefile
markdown
mathematica
matlab
maxima
mediawiki
metafont
modelines
modula2
modula3
monobasic
ocaml
objectivec
objectivecpp
octave
opencl
php
povray
pascal
perl
pike
postscript
powershell
prolog
protobuf
pure
purebasic
python
r
relaxng
relaxngcompact
roff
ruby
rhtml
rust
sgml
sml
sql
sqlmysql
sqlpostgresql
scala
scheme
tcl
tcsh
texinfo
mandoc
typescript
vhdl
verilog
xml
xul
yaml
yacc
zsh
dot
noweb
rest
sci
sed
xorg
xslt

かなりの数の言語に対応していることがわかる。

また、マニュアルにCurrently highlighting is supported only for HTML, EPUB, Docx, Ms, and LaTeX/PDF output.と書いてあるように、現時点では4つの出力フォーマットにのみ適用されるようだ。

長くなったので一旦ここまで。

過労っぽくて二日ほど寝てた

今日から本気出す

かくして、転・確・典・壇のイベントを終え、力尽きて二日ほど寝ていたのであった。 いやーもう無理できない歳ですね。

とはいえ、GW前に各種手続きをしておかないと大変なことになるので今週後半はゆるゆると復活していきます。温泉とか行ってゆっくりすべきなのかもしれないですが。来週あたまくらいに予定してみるか。

今週はちょっとだけダラダラして、来週からまた頑張っていきまする。。。

振り返りとかもその時に。

Programming in Lua Forth edition 2章

いきなりeight queenのコードが出てきた。

なんかほとんど説明なくeight queenのコードが出てきたので早速写経して動作を確認した。1発完動はなく、1文字typoがありましたが。 関数の定義や呼び出しなどなど色々な要素が詰まったコードなので、もう少し文法見てから解読するかな…読めなくはないんだけど…。

コードをそのまま転記するのはあれなのでやめておきますが、証拠写真は残しておこう。

f:id:niszet:20190415222054p:plain

時間がある今のうちに基本は押さえておきたいところですな…。

ちなみに、Luaを覚えるモチベーションは主にFlash AirとPandocのfilterを書くためです。

Programming in Lua Forth editionを購入した

Luaはいろんなところに使われているんだな。

ということで、重い腰を上げてLuaを勉強しようと思う。あまりLuaについての書籍は発行されておらず、特に和書はない。少し前のであればあるのだが、まぁ新しいものが良かろうということで(といってもこれも数年前のだが)Programming in Lua Forth editionを購入したのである。

少し余裕が出てきたので、1章だけさっと読んだところまでまとめ。なおこれはただの備忘録。

IDE

とりあえず気軽に試せるLuaの実行環境が欲しかったので、ZeroBrane StudioのIDEをインストールした。Windowsは32bit版しかないのか(といってもLuaで必要?ってのはあるのかな)

studio.zerobrane.com

MatlabとかRStudioみたいな、コンソールとソースのPangeとかがあるような普通?のIDEですね。特に手間取ることはなかった。

予約語

Luaにも予約語がある。本によれば

and break do else elseif end false for function goto if in local nil not or repeat return then true until while

とある。ただし、変数名は大文字小文字を区別するので、andは予約語だがAndやANDは予約語ではなく別の変数として扱われる。

インタプリタ上で実行時の挙動

Lua 5.3からは

a = 15 
a + 2 --> 17

という普通の書き方が出来る。Lua5.2以前は

a = 15 
= a + 2

のようにしないとダメだったみたいなことが書いてあるが、上記のIDE上ではそんなことなかった…。

関数は

function 関数名 (引数, 引数2)
  処理
end

という形になるようだ(まだ記述例が出ただけなので詳細は不明)

変数に使用できる文字とか

数字ではじまらない、任意の文字 ^[実際に試してみると日本語の変数名でも動いているのだが、多分避けた方が良いと思う] と数字とアンダースコア()を使うことが出来る。ただし、ではじまり、1文字以上の大文字が続くような変数名は避けた方が良い。Luaの中で特別な用途で使用されているようだ。たとえば、_VERSIONはLuaのバージョンを返している。これを使うと先のIDEでは5.1が使われているようなのだが、インタプリタの挙動は5.3のもののように見える…もう少し調べてみる。現時点ではわからない。

コメント

コメントは--以降がコメント。なので、先のコードの-->はコメントになるのでコードをそのままコピーして実行できる。

ブロックコメントは

--[[
コメント内なので実行されない
--]]

の形で書く。ここで、--[[---[[-を一つ足すとブロックコメントにならないので、コメントアウトが外れる(それぞれ別のコメントになる)とのこと。

変数

Luaの変数には未定義がない。ないものはnilとなる。また、変数にnilを与えることでその変数は未定義と同じ、nilを返すようになるのでそれらの差異はないようにふるまう

type()で調べられるようだ。また、type()の戻り値は文字列なので、`type(type(何か))‘は何かが何であってもcharacterを返す。

真偽値

nilとfalse以外はすべてtrueとなる。notで否定。

andとorが特殊で、

1 and 2 --> 2
nil and 10 --> nil
false and 10 --> false
3 or 4 --> 3
nil or 9 --> 9
false or 9 --> 9

のようになる。これは慣れるまで不思議に思いそう。andとorとしては確かにそうねという感じだが、真偽値を返すわけではないというところがミソか。

Cの3項演算子のような A ? B : C は (A and B) or C あるいは A and B or C と書く。()を外してよいのはandの方がorよりも演算の優先度が高いため。

セミコロン

邪悪な行末セミコロンは不要。ただしあっても挙動に差異がなく、1行に複数の行をまとめてしまいたいときは見やすさのために入れておくと良さそうである。

とりあえずここまで。