h1 簡易なおれおれマークダウン 2019秋 index 2 ---- h2 はじめに 以前に [[ http://kondoh.html.xdomain.jp/ezhtml/index.html | 簡易なHTMLパーサ 2018秋 ]] を作成しました。 以降、HTML形式のものを作るときは、まずYAML形式で作成。 それから自作のツールezhtml.pyを使って、YAML形式からHTML形式に変換するようになりました。 ですがここにきて、YAML形式の作成も「かったるく」なってしまいました。 例えば、次のような既存のテキストの場合 [[ foo.txt ]] pre $ cat foo.txt Python2とPython3での日本語文字列対応について 毎回、同じようにつまづいて、同じような感じで対応してます。 なので、いいかげん自分に判りやすいようにまとめておきます。 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 データはYAML形式のファイルで用意。 そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回「うぅっ」とうなってます。 結論 日本語を含む文字列処理で .foramt() や .join() を使いたい Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。 Python3 では日本語の有無に関係なく、素直にstrのままでよし。 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい Python2 では素直に sys.stdin/sys.stdout を read/write。 Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。 Python2 の世界には .buffer は存在しないので注意。 / p まずはYAML形式で [[ foo.yaml ]] pre $ cat foo.yaml html: - head: - meta http-equiv="Content-Type" content="text/html;charset=iso-2022-jp": / - title: py23str - style: 'pre{ background: lightgray; }' - style: 'img{ max-width: 100%; height: auto; }' - style: 'h3{ border-left: solid gray; padding: 1em 0.5em; }' - body: - h1: Python2とPython3での日本語文字列対応について - p: - 毎回、同じようにつまづいて、同じような感じで対応してます。 - p: - なので、いいかげん自分に判りやすいようにまとめておきます。 - p: - 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 - p: - データはYAML形式のファイルで用意。 - p: - そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 - 毎回「うぅっ」とうなってます。 - h2: 結論 - h3: 日本語を含む文字列処理で .foramt() や .join() を使いたい - p: - Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。 - p: - Python3 では日本語の有無に関係なく、素直にstrのままでよし。 - h3: 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい - p: - Python2 では素直に sys.stdin/sys.stdout を read/write。 - p: - Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。 - p: - Python2 の世界には .buffer は存在しないので注意。 / p を作成しておいて pre $ ./ezhtml.py y < foo.yaml | nkf -j > foo.html $ nkf -g foo.html ISO-2022-JP $ cat foo.html | nkf -u
毎回、同じようにつまづいて、同じような感じで対応してます。
なので、いいかげん自分に判りやすいようにまとめておきます。
日本語対応といっても、ソースコード中に日本語を書くつもりはありません。
データはYAML形式のファイルで用意。
そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回「うぅっ」とうなってます。
Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。
Python3 では日本語の有無に関係なく、素直にstrのままでよし。
Python2 では素直に sys.stdin/sys.stdout を read/write。
Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。
Python2 の世界には .buffer は存在しないので注意。
/ p に変換。 [[ foo.html ]] このように表示されます。 ですが、このYAML形式を作成するのが結構ツライです。 できれば [[ foo.txt ]] から [[ foo.yaml ]] の形式に変換できないものか... 世の中にはマークダウン形式の規格・仕様は存在します。 ですが、ここはひとつ目をつむって「簡易おれおれマークダウン」な仕様の 変換ツールを作ってみる事にします。 ---- h2 headとbody [[ foo.yaml ]] の段階で、headとbodyに分かれてます。 そしてbody以降は、最低スペース2つの字下げが必ず入ってます。 headでfoo.txtからの固有の情報は pre - title: py23str / p だけで、あとはほぼお決まりで固定です。 headのtilteはあとで編集するとして、bodyだけ何とか変換するように目指してみます。 まずは [[ foo_head.yaml ]] を用意。 pre $ cat foo_head.yaml - meta http-equiv="Content-Type" content="text/html;charset=iso-2022-jp": / - title: py23str - style: 'pre{ background: lightgray; }' - style: 'img{ max-width: 100%; height: auto; }' - style: 'h3{ border-left: solid gray; padding: 1em 0.5em; }' / p そして [[ foo.txt ]] から、これから作成を目指すツールで、何とか [[ foo_body.yaml ]] を自動生成します。 pre $ cat foo_body.yaml - h1: Python2とPython3での日本語文字列対応について - p: - 毎回、同じようにつまづいて、同じような感じで対応してます。 - p: - なので、いいかげん自分に判りやすいようにまとめておきます。 - p: - 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 - p: - データはYAML形式のファイルで用意。 - p: - そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 - 毎回「うぅっ」とうなってます。 - h2: 結論 - h3: 日本語を含む文字列処理で .foramt() や .join() を使いたい - p: - Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。 - p: - Python3 では日本語の有無に関係なく、素直にstrのままでよし。 - h3: 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい - p: - Python2 では素直に sys.stdin/sys.stdout を read/write。 - p: - Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。 - p: - Python2 の世界には .buffer は存在しないので注意。 / p あとはスクリプトなり何なりで、例えば pre $ ( echo '' ; ./ezhtml.py y < foo_head.yaml ; echo '' ; ./ezhtml.py y < foo_body.yaml ; echo '' ) | nkf -j > foo2.html $ nkf -g foo2.html ISO-2022-JP $ nkf -u foo2.html毎回、同じようにつまづいて、同じような感じで対応してます。
なので、いいかげん自分に判りやすいようにまとめておきます。
日本語対応といっても、ソースコード中に日本語を書くつもりはありません。
データはYAML形式のファイルで用意。
そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回「うぅっ」とうなってます。
Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。
Python3 では日本語の有無に関係なく、素直にstrのままでよし。
Python2 では素直に sys.stdin/sys.stdout を read/write。
Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。
Python2 の世界には .buffer は存在しないので注意。
/ p [[ foo2.html ]] となります。 ---- h2 タグ おれおれ仕様のツールなので、 自分がよく使うHTMLのタグだけ対応して、 滅多に使わないものは、最後に手動で編集する事にします。 HTMLのbodyの中で、自分がよく使うタグは何か? ul h1, h2, h3, ... p pre ul, li a hr img video s p とりあえず、このくらい。 最初はここから [[ foo.txt ]] の範囲だけに絞って ul h1, h2, h3, ... p p だけで骨組みを考えてみます。 ---- h2 簡易にモード切り替えで [[ foo.txt ]] から [[ foo_body.yaml ]] を生成したい訳ですが、 テキストを、属してるタグで切り分けてみると pre ;;; --> h1 Python2とPython3での日本語文字列対応について ;;; <-- h1 ;;; --> p 毎回、同じようにつまづいて、同じような感じで対応してます。 なので、いいかげん自分に判りやすいようにまとめておきます。 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 データはYAML形式のファイルで用意。 そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回「うぅっ」とうなってます。 ;;; <-- p ;;; --> h2 結論 ;;; <-- h2 ;;; --> h3 日本語を含む文字列処理で .foramt() や .join() を使いたい ;;; <-- h3 ;;; --> p Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。 Python3 では日本語の有無に関係なく、素直にstrのままでよし。 ;;; <-- p ;;; --> h3 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい ;;; <-- h3 ;;; --> p Python2 では素直に sys.stdin/sys.stdout を read/write。 Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。 Python2 の世界には .buffer は存在しないので注意。 ;;; <-- p / p HTML形式だと、開始タグと終了タグで、まさにこのような感じで領域を指示します。 おれおれマークダウンでは、簡易な記述を目指すので、モード(状態)を持たせます。 テキストの先頭から末尾に向かって、状態を切り替えて、どのタグの領域かを指示する事にします。 例えば、次のように。 pre h1 Python2とPython3での日本語文字列対応について p 毎回、同じようにつまづいて、同じような感じで対応してます。 なので、いいかげん自分に判りやすいようにまとめておきます。 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 データはYAML形式のファイルで用意。 そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回「うぅっ」とうなってます。 h2 結論 h3 日本語を含む文字列処理で .foramt() や .join() を使いたい p Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。 Python3 では日本語の有無に関係なく、素直にstrのままでよし。 h3 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい p Python2 では素直に sys.stdin/sys.stdout を read/write。 Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。 Python2 の世界には .buffer は存在しないので注意。 / p p, h1, h2, h3をモード名として、モード名だけの行が現れると、 現在のモードをそのモードに切り替えます。 h3 h1, h2, h3モード 他のモードに切り替わるまでの間の複数行のテキストについて ul 各行の先頭、末尾の空白文字は無視。 空行は無視。 各行の有効な文字列を結合して、タグの中身の文字列とします。 pre h1 Python2とPython3での日本語文字列対応について p / p は pre - h1: Python2とPython3での日本語文字列対応について / p てな具合に。 h3 pモード 他のモードに切り替わるまでの間の複数行のテキストについて ul 各行の先頭、末尾の空白文字は無視。 空行があると、pタグの打ち直し。 各行の有効な文字列を結合して、タグの中身の文字列とします。 pre p 毎回、同じようにつまづいて、同じような感じで対応してます。 なので、いいかげん自分に判りやすいようにまとめておきます。 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 データはYAML形式のファイルで用意。 そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回「うぅっ」とうなってます。 h2 / p は pre - p: - 毎回、同じようにつまづいて、同じような感じで対応してます。 - p: - なので、いいかげん自分に判りやすいようにまとめておきます。 - p: - 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 - p: - データはYAML形式のファイルで用意。 - p: - そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 - 毎回「うぅっ」とうなってます。 / p てな具合に。 ---- h2 バージョン1 (h,pタグ) ではこの仕様で、骨組みのコーディング。 [[ ezmd.py ]] pre $ cat ezmd.py #!/usr/bin/env python import yaml import nkf heads = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8', 'h9' ] end = '$$$_end_$$$' modes = heads + [ 'p', end ] def do_mode(mode, buf, res): if mode in heads: buf = list( map( lambda s: s.strip(), buf ) ) buf = list( filter( lambda s: s!='', buf ) ) s = ''.join(buf) res.append( { mode: s } ) elif mode == 'p': buf = list( map( lambda s: s.strip(), buf ) ) buf.append('') (lsts, lst) = ( [], [] ) for s in buf: if s: lst.append(s) elif lst: lsts.append(lst) lst = [] for lst in lsts: res.append( { 'p': lst } ) def ezmd(lst): lst = ['p'] + lst + [end] (buf, res) = ( [], [] ) mode = '' while mode != end: s = lst.pop(0) if s in modes and s != mode: do_mode(mode, buf, res) mode = s buf = [] else: buf.append(s) return res if __name__ == "__main__": b = nkf.get_stdin() (s, nkf_opt) = nkf.to_str(b) lst = s.split('\n') lst = ezmd(lst) u8 = yaml.dump( lst, default_flow_style=False, allow_unicode=True, encoding='utf-8' ) b = nkf.cvt(u8, nkf_opt) if nkf_opt != '-u' else u8 nkf.put_stdout(b) # EOF / p 日本語の文字コードの問題やPython2, Python3の問題は、すべて nkf.py が吸収してくれてるはずと信じて、進めまてみます。 [[ http://kondoh.html.xdomain.jp/ezhtml/index.html | 簡易なHTMLパーサ 2018秋 ]] から [[ ezhtml.py ]] nkf.py は使いまわしつつ、互換性を保ちながらアップデートしてきたので、 [[ http://kondoh.html.xdomain.jp/argmnt/index.html | テキスト配置ツール ]] から最新版の [[ nkf.py ]] を配置しておきます。 おれおれ仕様のテキストファイルは [[ foo2.txt ]] pre $ cat foo2.txt h1 Python2とPython3での日本語文字列対応について p 毎回、同じようにつまづいて、同じような感じで対応してます。 なので、いいかげん自分に判りやすいようにまとめておきます。 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 データはYAML形式のファイルで用意。 そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回「うぅっ」とうなってます。 h2 結論 h3 日本語を含む文字列処理で .foramt() や .join() を使いたい p Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。 Python3 では日本語の有無に関係なく、素直にstrのままでよし。 h3 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい p Python2 では素直に sys.stdin/sys.stdout を read/write。 Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。 Python2 の世界には .buffer は存在しないので注意。 / p それでは実行。 pre $ ./ezmd.py < foo2.txt - h1: Python2とPython3での日本語文字列対応について - p: - 毎回、同じようにつまづいて、同じような感じで対応してます。 - p: - なので、いいかげん自分に判りやすいようにまとめておきます。 - p: - 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 - p: - データはYAML形式のファイルで用意。 - p: - そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 - 毎回「うぅっ」とうなってます。 - h2: 結論 - h3: 日本語を含む文字列処理で .foramt() や .join() を使いたい - p: - Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。 - p: - Python3 では日本語の有無に関係なく、素直にstrのままでよし。 - h3: 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい - p: - Python2 では素直に sys.stdin/sys.stdout を read/write。 - p: - Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。 - p: - Python2 の世界には .buffer は存在しないので注意。 / p 出力されたHTML形式をさらにezhtml.pyにつないでHTML形式に。 pre $ ./ezmd.py < foo2.txt | ./ezhtml.py毎回、同じようにつまづいて、同じような感じで対応してます。
なので、いいかげん自分に判りやすいようにまとめておきます。
日本語対応といっても、ソースコード中に日本語を書くつもりはありません。
データはYAML形式のファイルで用意。
そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回「うぅっ」とうなってます。
Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。
Python3 では日本語の有無に関係なく、素直にstrのままでよし。
Python2 では素直に sys.stdin/sys.stdout を read/write。
Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。
Python2 の世界には .buffer は存在しないので注意。
/ p 大丈夫そうですね。 headとつなげて仕上げを。 仕上げ用のツールを用意しときます。 [[ to_html.py ]] pre $ cat to_html.py #!/usr/bin/env python import sys import subprocess if __name__ == "__main__": if len(sys.argv) < 3: print( 'Usage: {} head.yaml body.txt'.format( sys.argv[0] ) ) sys.exit(1) cmd = "( echo '' ; ./ezhtml.py y < {} ; echo '' ; ./ezmd.py < {} | ./ezhtml.py y ; echo '' ) | nkf -j"; cmd = cmd.format( sys.argv[1], sys.argv[2] ) subprocess.call(cmd, shell=True) # EOF $ ./to_html.py foo_head.yaml foo2.txt > foo3.html $ nkf -g foo3.html ISO-2022-JP / p [[ foo3.html ]] OK。 todo ul [[-|h1, h2, h3, ...]] [[-|p]] pre ul, li a (href) hr img video s ---- h2 バージョン2 (preタグ) ul pre p 追加してみます。 h3 preモード preタグの場合、どこまでがpreタグの中か? 次のモードへの切り替えの判定が微妙です。 このモードは特別に、'/'だけの行でモード終了としてみます。 行頭に'/'だけ表示したい事はまぁ無いだろうし、 あったとしても、' ' + '/' にして行頭にスペースを入れてしのぐ事にします。 モードが終了するまでの間の複数行のテキストについて ul モード開始直後の複数連続の空行は無視。 モード終了直前の複数連続の空行は無視。 タグの中身として、各行末尾に改行追加で連結した文字列とします。 p preタグのYAMLへの変換は [[ http://kondoh.html.xdomain.jp/ezhtml/index.html | 簡易なHTMLパーサ 2018秋 ]] [[ http://kondoh.html.xdomain.jp/ezhtml/index.html#pre_yaml_dump | preタグのyamlダンプ ]] でこしらえた yaml_dump() を流用しておきます。 ezhtml.pyのオリジナルのyaml_dump()ではstrを返す仕様にしてました。 今回の場面ではUTF-8のままで良いので、そのように修正して使います。 モード終了指示の方式にすると、 '/' で終了してから、次のモードまでの滞空期間ができてしまいます。 モードが何者でもないその間は、とりあえずデフォルトのpモードで。 pモード中に何もテキストがなく、続く別のモードが始まれば、 デフォルトpモードでは何も表示しないので、大丈夫でしょう。 [[ v2.patch ]] pre $ cat v2.patch | patch -p1 / p [[ foo_2.txt ]] pre $ cat foo_2.txt h1 Python2とPython3での日本語文字列対応について p 毎回、同じようにつまづいて、同じような感じで対応してます。 なので、いいかげん自分に判りやすいようにまとめておきます。 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 データはYAML形式のファイルで用意。 そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回「うぅっ」とうなってます。 h2 結論 h3 日本語を含む文字列処理で .foramt() や .join() を使いたい p Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。 Python3 では日本語の有無に関係なく、素直にstrのままでよし。 h3 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい p Python2 では素直に sys.stdin/sys.stdout を read/write。 Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。 Python2 の世界には .buffer は存在しないので注意。 pre $ cat p2.py #!/usr/bin/env python2 import sys import yaml if __name__ == "__main__": s = sys.stdin.read() d = yaml.load(s) foo = d.get('foo') bar = d.get('bar') d['hoge'] = foo + ' ' + bar d['fuga'] = 'foo={} bar={}'.format(foo, bar) d['guha'] = '(^_^)'.join( d.values() ) s = yaml.dump(d, default_flow_style=False) sys.stdout.write(s) # EOF / ここはデフォルトp p ここは明示的にp pre ここはpre p ここもpre h1 ここもpre / p ここはp / p 実行してみます。 pre $ ./ezmd.py < foo_2.txt - h1: Python2とPython3での日本語文字列対応について - p: - 毎回、同じようにつまづいて、同じような感じで対応してます。 - p: - なので、いいかげん自分に判りやすいようにまとめておきます。 - p: - 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 - p: - データはYAML形式のファイルで用意。 - p: - そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 - 毎回「うぅっ」とうなってます。 - h2: 結論 - h3: 日本語を含む文字列処理で .foramt() や .join() を使いたい - p: - Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。 - p: - Python3 では日本語の有無に関係なく、素直にstrのままでよし。 - h3: 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい - p: - Python2 では素直に sys.stdin/sys.stdout を read/write。 - p: - Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。 - p: - Python2 の世界には .buffer は存在しないので注意。 - pre: | $ cat p2.py #!/usr/bin/env python2 import sys import yaml if __name__ == "__main__": s = sys.stdin.read() d = yaml.load(s) foo = d.get('foo') bar = d.get('bar') d['hoge'] = foo + ' ' + bar d['fuga'] = 'foo={} bar={}'.format(foo, bar) d['guha'] = '(^_^)'.join( d.values() ) s = yaml.dump(d, default_flow_style=False) sys.stdout.write(s) # EOF - p: - ここはデフォルトp - p: - ここは明示的にp - pre: | ここはpre p ここもpre h1 ここもpre - p: - ここはp / p 大丈夫そうですね。 pre $ ./to_html.py foo_head.yaml foo_2.txt > foo_2.html / p [[ foo_2.html ]] todo ul [[-|h1, h2, h3, ...]] [[-|p]] [[-|pre]] ul, li a (href) hr img video s ---- h2 バージョン3 (ul,liタグ) ul ul, li p 追加してみます。 h3 ulモード 全体の簡単にするためにモードの開始、終了をトップレベルの状態の遷移だけにしました。 なので、基本的に「入れ子」の構造を諦めてます。 が、ですが、このulモードの中だけは「入れ子」を結構使ってます。 例えば pre - ul: - li /: 標準入力からYAML形式のテキストを読み込み - li /: yaml.load()でテキストをデータに - li /: データの文字列2つを - li /: ごにょごにょいじって - ul: - li /: foo + ' ' + bar - li /: .format() - li /: .join() - li /: yaml.dump()でデータをYAML形式のテキストにして - li /: 標準出力に書き出し / p こうして preそして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、
毎回
「うぅっ」
「ぬはぁ」とうなってます。
2: の場合
:4 の場合
2:3 の場合
2 の場合
3 の場合