mdm
mermaid
GitHub、Markdown構文でフローチャートやクラス図、ガントチャートなどのダイアグラムを表示できる「Mermaid」をサポート開始
About Mermaid を見ると、javascriptで出来ているみたい。 GitHub、Mermaidを用いてMarkdownファイルに図表を挿入する方法を紹介 に、多少からくりが説明されてた。
最近はもうブラウザー上でなんでも出来ちゃうのね。標準入出力装置だからね。取り敢えずブラウザーに出力出来ればいいよとな。
でも、 Graphvizの再発明のような雰囲気だな。
Markdown
上の話は、どうでもよくて、オイラーには切実な問題がある。
rustを使っていると、木箱をgitからお取寄せになる。後で内容を確かめようと cargo vendor して、それぞれの木箱の中の説明書 README.md を見る亊になる。
こやつhtmlの元になる原稿だ。そのままではただのテキストなんで、変換器でhtmlにしないと、リンクを辿って飛んで行くとかが出来無い。
何とかしたいぞ。まずはmdファイルの書式確認だな。
GitHub Flavored Markdown Spec が、仕様書だ。こいつの至らない点を指摘してる人がおられた。 GitHub Flavored Markdown は何であって何でないか
そんじゃ、物は試しに、変換器をOpenBSDのportsの中で探してみる。合言葉はmarkdownぐらいでいいか。あるわあるわ、pythonのやつperlのやつrubyのやつとさまざまだ。こういう変換器は、インタープリタの格好の餌食なんだろうね。
オイラーは臍曲がりなんで、lua製をチョイスしてみた。
vbox$ lua /usr/local/share/lua/5.1/markdown.lua -h Usage: markdown.lua [OPTION] [FILE] Runs the markdown text markup to HTML converter on each file specified on the command line. If no files are specified, runs on standard input. No header: -n, --no-wrap Don't wrap the output in <html>... tags. Custom header: -e, --header FILE Use content of FILE for header. -f, --footer FILE Use content of FILE for footer. Generated header: -c, --charset SET Specifies charset (default utf-8). -i, --title TITLE Specifies title (default from first <h1> tag). -s, --style STYLE Specifies style sheet file (default default.css). -l, --inline-style Include the style sheet file inline in the header. Generated files: -a, --append Append .html extension (instead of replacing). Other options: -h, --help Print this help text. -t, --test Run the unit tests.
ファイル一つなんで、どこへでも持っていける。FreeBSDも何故か、lua(52,53)と、豪華に揃い 踏みしてたんで、お試し。
[sakae@fb ~/.cargo/registry/src/github.com-1285ae84e5963aae]$ wc */README.md|sort -n 3 8 47 headers-core-0.2.0/README.md : 449 2155 18023 tracing-0.1.29/README.md 820 4392 30709 encoding_rs-0.8.30/README.md
やる気の無いREADME.mdから、これでもかって気合の入った物まで、様々。一番巨大なやつを試験してみる。
[sakae@fb /tmp]$ ./markdown.lua README.md [sakae@fb /tmp]$ w3m README.html
これで、解決。以上終了、じゃつまんなので、rustでこれをやったら、どうなるか試してみるか。
mdm
名前firstって亊で、mdmって亊にする。これ、w3mのパクリ。w3(www) を m(miru)。
md を m(iru)ね。
目標は、下記のように使える変換器(兼表示器)を作る亊だ。
[sakae@fb /tmp]$ cat README.md | ./markdown.lua | w3m -T text/html
こやつにmdmって名前を付けたい訳ね。これがunix流のtext文化ですよ。
sakae@deb:/tmp/t$ cat mdm #!/bin/sh cat README.md | \ markdown.lua | \ w3m -T text/html
Debianにluaを入れた記念に、スクリプト化した。
catlog参照
楽しい々カタログを眺める時間。mdのフォーマットを解析するプログラムなんて自分で作ると終らなくなるんで、楽しようと言う魂胆。
Lib.rs で探しましょ。検索語は、markdown。更に絞るなら、html なんて語句を追加すればよい。以下は、適当そうなものを選んだ例だ。
ああ、検索は、crates.ioもお忘れなく。
最近、 Google検索は死につつあるなんて記事を読んだよ。rustの場合のカタログ検索は、どちらがGoogle相当なのだろうか?
markdown.rs
cargo search markdown して、先頭に出て来る有名なや。
comrak
A 100% CommonMark-compatible GitHub Flavored Markdown parser and formatter
人気があるみたいで多数DLされてる。けど、色々な木箱のやっかいになり過ぎの感じがするぞ。
markdown-to-html
今回の目的には似わないけど、流行のWASMとかYewとか言うweb frameworkを使っていて、リナだったら、楽しめそう。
mini-markdown
pure rustで書かれた半製品。Libs.rsのトップ画面にあるカテゴリー分類でVisualizationの部分に登場してたぞ。ビルボードの赤丸上昇中みたいだな。
cargo-registry-markdown
上で出て来た、comrakを使ったライブラリィー。テスト部分が参考になるかな。
markdown2html-converter
そのものずばりの名前が付いている。やはりcomrakを使ってる。comrakはこの分野のデファクト・スタンダードなのか。
select mini-markdown
市場調査では色々と見付かったけど、余計な木箱が必要無いという理由で、 mini_markdown
を使ってみる亊にする。
本来なら、テストコードの参考にtestを参照するのが筋だろうけど、そんなに難しいインターフェースではなさそうなので、いきなり実験コードを作ってみる。
実験基盤で動作確認
Cargo.toml mini_markdown = "0.2.7"
を追加する。そして、main.rs
use mini_markdown::parse; use mini_markdown::lex; pub fn render(source: &str) -> String { parse(&lex(source)) } fn main() { let mds = " # My first code ``` fn add(x: i32, y: i32) -> i32 { x + y } ``` Is it ok? [MIT](https://choosealicense.com/licenses/mit/) "; let html = render(mds); println!("{}", html); }
mdsの長ったらしい文字列は、最小のREADME.mdを模したものだ。結果は、
ob$ cargo r Finished dev [unoptimized + debuginfo] target(s) in 0.03s Running `target/debug/mdm` <h1 id="my-first-code">My first code</h1> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre cl ass="highlight"><code>fn add(x: i32, y: i32) -> i32 { x + y &r brace; </code></pre></div></div> <p>Is it ok? <a href="https://choosealicense.com/licenses/mit/" referrerpolicy="no-referrer">MIT</a></p>
htmlに仕立てる
上の結果では、見栄えが解らないので、前後に太ったhtmlの括弧を挟んであげる。
println!("<html><head><title>README.md</title></head><body>"); println!("{}", html); println!("</body></head>");
そして、この結果をw3mに喰わせてみる。
ob$ target/debug/mdm | w3m -T text/html
w3mは、こんな風に表示してきた。
My first code fn add(x: i32, y: i32) -> i32 { x + y } Is it ok? MIT
惜しいな、波括弧の表現が、時代の流れに追従出来無くて、そのまま表示されちゃってる。 まて、 emacsに備付のブラウザー eww が有るじゃない。こちらでも確かめてみる。
M-x eww-open-fileRET File: /tmp/mdm/zzz.html
結果はw3mと一緒だった。
これはもう、脳内変換してくださいって亊かな。 それに欲を言うと、コード部分を、それと分るようにしたいな。簡単に改造出来るか?
第1版
世間の荒波に揉まれない亊には、満足する物にはならないだろう。ってな亊で、決めうちでREADME.mdを読み込んで、それをhtmlファイルに変換するように作ってみた。出力はstdoutに流れてくるので、パイプでw3mに接ぐなり、一旦ファイルに落して、firefoxに喰わせるなりすればよい。
use mini_markdown::lex; use mini_markdown::parse; pub fn readfile() -> String { std::fs::read_to_string("README.md").expect("Need README.md") } pub fn render(source: &str) -> String { parse(&lex(source)) } fn main() { let mds = readfile(); let html = render(&mds); println!("<html><head><title>README.md</title></head><body>"); println!("{}", html); println!("</body></head>"); }
出来上がったアプリのサイズが、とんでもなく大きいのが気になる。こんなものなのか。
sakae@deb:/tmp/mdm$ ls -l target/debug/mdm target/release/mdm -rwxr-xr-x 2 sakae sakae 4826016 Feb 24 07:53 target/debug/mdm* -rwxr-xr-x 2 sakae sakae 3506268 Feb 24 08:16 target/release/mdm*
problem
ちょいと問題点を2通、挙げておく。
mini_markdown/README.md
をhtml化すると、前半部分(Syntax/Italic text当たりまで)が、正しくパースされない。
serde_json-1.0.78/README.md
とか cc-1.0.73/README.md をhtml化しようとすると、ハングアップする。
DIY
木箱になってる mini_markdown
を、取り込んで、自由に改造してみたい。その為にlib.rsとlexer.rsを下記のように配置とlib.rsの名前変更を行う。
ob$ tree src/ src/ |-- main.rs ;; need modfy |-- mini_markdown ;; make new dir | `-- lexer.rs ;; cp from mini_markdown `-- mini_markdown.rs ;; rename lib.rs and modfy (org mini_markdown)
main.rsの修整。
ob$ diff -u /home/sakae/mdm/src/main.rs src/main.rs --- /home/sakae/mdm/src/main.rs Wed Feb 23 16:22:37 2022 +++ src/main.rs Thu Feb 24 14:35:48 2022 @@ -1,6 +1,6 @@ -use mini_markdown::parse; -use mini_markdown::lex; +mod mini_markdown; +use crate::mini_markdown::parse; +use crate::mini_markdown::lex;
それから mini_markdown.rs
(org lib.rs)の修整。
--- /home/sakae/mini_markdown/src/lib.rs Tue Feb 22 16:35:06 2022 +++ src/mini_markdown.rs Thu Feb 24 14:42:47 2022 @@ -1,5 +1,5 @@ pub mod lexer; -use crate::lexer::*; +use crate::mini_markdown::lexer::*;
src/mini_markdown.rs:388:8
render は不必要なので、コメントアウトする。
そして、CUIなブラウザーで見やすいように修整。(簡易diff -uで失礼)
- "<div class=\"language-{} highlighter-rouge\"><div class=\"high light\"><pre class=\"highlight\"><code>{}</code></pre></div></div>", + "<div class=\"language-{} highlighter-rouge\"><div class=\"high light\"><pre class=\"highlight\">======<br><code>{}</code>------</pre></div></di v>", - .replace('{', "{") - .replace('}', "}") +// .replace('{', "{") +// .replace('}', "}")
修整結果。w3mの画面ダンプ
My first code ====== fn add(x: i32, y: i32) -> i32 { x + y } ------ Is it ok? MIT
希望の通り、コード部分は、それと分るように区分けできた。波括弧も復活。サニタイズをこれでもかって具合にやってるけど、ローカルで使うんで許してね。