以前に 簡易なHTMLパーサ 2018秋 を作成しました。
以降、HTML形式のものを作るときは、まずYAML形式で作成。
それから自作のツールezhtml.pyを使って、YAML形式からHTML形式に変換するようになりました。
ですがここにきて、YAML形式の作成も「かったるく」なってしまいました。
例えば、次のような既存のテキストの場合
$ 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 は存在しないので注意。
まずはYAML形式で
$ 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 は存在しないので注意。
を作成しておいて
$ ./ezhtml.py y < foo.yaml | nkf -j > foo.html
$ nkf -g foo.html
ISO-2022-JP
$ cat foo.html | nkf -u
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-2022-jp">
<title>py23str</title>
<style>pre{ background: lightgray; }</style>
<style>img{ max-width: 100%; height: auto; }</style>
<style>h3{ border-left: solid gray; padding: 1em 0.5em; }</style></head>
<body><h1>Python2とPython3での日本語文字列対応について</h1>
<p>毎回、同じようにつまづいて、同じような感じで対応してます。</p>
<p>なので、いいかげん自分に判りやすいようにまとめておきます。</p>
<p>日本語対応といっても、ソースコード中に日本語を書くつもりはありません。</p>
<p>データはYAML形式のファイルで用意。</p>
<p>そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、
毎回「うぅっ」とうなってます。</p>
<h2>結論</h2>
<h3>日本語を含む文字列処理で .foramt() や .join() を使いたい</h3>
<p>Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。</p>
<p>Python3 では日本語の有無に関係なく、素直にstrのままでよし。</p>
<h3>日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい</h3>
<p>Python2 では素直に sys.stdin/sys.stdout を read/write。</p>
<p>Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。</p>
<p>Python2 の世界には .buffer は存在しないので注意。</p></body></html>
に変換。
このように表示されます。
ですが、このYAML形式を作成するのが結構ツライです。
できれば foo.txt から foo.yaml の形式に変換できないものか...
世の中にはマークダウン形式の規格・仕様は存在します。
ですが、ここはひとつ目をつむって「簡易おれおれマークダウン」な仕様の 変換ツールを作ってみる事にします。
foo.yaml の段階で、headとbodyに分かれてます。
そしてbody以降は、最低スペース2つの字下げが必ず入ってます。
headでfoo.txtからの固有の情報は
- title: py23str
だけで、あとはほぼお決まりで固定です。
headのtilteはあとで編集するとして、bodyだけ何とか変換するように目指してみます。
まずは
を用意。
$ 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; }'
そして foo.txt から、これから作成を目指すツールで、何とか foo_body.yaml を自動生成します。
$ 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 は存在しないので注意。
あとはスクリプトなり何なりで、例えば
$ ( echo '<html><head>' ; ./ezhtml.py y < foo_head.yaml ; echo '</head><body>' ; ./ezhtml.py y < foo_body.yaml ; echo '</body></html>' ) | nkf -j > foo2.html
$ nkf -g foo2.html
ISO-2022-JP
$ nkf -u foo2.html
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=iso-2022-jp">
<title>py23str</title>
<style>pre{ background: lightgray; }</style>
<style>img{ max-width: 100%; height: auto; }</style>
<style>h3{ border-left: solid gray; padding: 1em 0.5em; }</style>
</head><body>
<h1>Python2とPython3での日本語文字列対応について</h1>
<p>毎回、同じようにつまづいて、同じような感じで対応してます。</p>
<p>なので、いいかげん自分に判りやすいようにまとめておきます。</p>
<p>日本語対応といっても、ソースコード中に日本語を書くつもりはありません。</p>
<p>データはYAML形式のファイルで用意。</p>
<p>そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、
毎回「うぅっ」とうなってます。</p>
<h2>結論</h2>
<h3>日本語を含む文字列処理で .foramt() や .join() を使いたい</h3>
<p>Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。</p>
<p>Python3 では日本語の有無に関係なく、素直にstrのままでよし。</p>
<h3>日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい</h3>
<p>Python2 では素直に sys.stdin/sys.stdout を read/write。</p>
<p>Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。</p>
<p>Python2 の世界には .buffer は存在しないので注意。</p>
</body></html>
となります。
おれおれ仕様のツールなので、 自分がよく使うHTMLのタグだけ対応して、 滅多に使わないものは、最後に手動で編集する事にします。
HTMLのbodyの中で、自分がよく使うタグは何か?
とりあえず、このくらい。
最初はここから foo.txt の範囲だけに絞って
だけで骨組みを考えてみます。
foo.txt から foo_body.yaml を生成したい訳ですが、 テキストを、属してるタグで切り分けてみると
;;; --> 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
HTML形式だと、開始タグと終了タグで、まさにこのような感じで領域を指示します。
おれおれマークダウンでは、簡易な記述を目指すので、モード(状態)を持たせます。
テキストの先頭から末尾に向かって、状態を切り替えて、どのタグの領域かを指示する事にします。
例えば、次のように。
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, h1, h2, h3をモード名として、モード名だけの行が現れると、 現在のモードをそのモードに切り替えます。
他のモードに切り替わるまでの間の複数行のテキストについて
h1 Python2とPython3での日本語文字列対応について p
は
- h1: Python2とPython3での日本語文字列対応について
てな具合に。
他のモードに切り替わるまでの間の複数行のテキストについて
p 毎回、同じようにつまづいて、同じような感じで対応してます。 なので、いいかげん自分に判りやすいようにまとめておきます。 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 データはYAML形式のファイルで用意。 そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回「うぅっ」とうなってます。 h2
は
- p: - 毎回、同じようにつまづいて、同じような感じで対応してます。 - p: - なので、いいかげん自分に判りやすいようにまとめておきます。 - p: - 日本語対応といっても、ソースコード中に日本語を書くつもりはありません。 - p: - データはYAML形式のファイルで用意。 - p: - そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 - 毎回「うぅっ」とうなってます。
てな具合に。
ではこの仕様で、骨組みのコーディング。
$ 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
日本語の文字コードの問題やPython2, Python3の問題は、すべて nkf.py が吸収してくれてるはずと信じて、進めまてみます。
nkf.py は使いまわしつつ、互換性を保ちながらアップデートしてきたので、 テキスト配置ツール から最新版の
を配置しておきます。
おれおれ仕様のテキストファイルは
$ 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 は存在しないので注意。
それでは実行。
$ ./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 は存在しないので注意。
出力されたHTML形式をさらにezhtml.pyにつないでHTML形式に。
$ ./ezmd.py < foo2.txt | ./ezhtml.py
<h1>Python2とPython3での日本語文字列対応について</h1>
<p>毎回、同じようにつまづいて、同じような感じで対応してます。</p>
<p>なので、いいかげん自分に判りやすいようにまとめておきます。</p>
<p>日本語対応といっても、ソースコード中に日本語を書くつもりはありません。</p>
<p>データはYAML形式のファイルで用意。</p>
<p>そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、
毎回「うぅっ」とうなってます。</p>
<h2>結論</h2>
<h3>日本語を含む文字列処理で .foramt() や .join() を使いたい</h3>
<p>Python2 では日本語を含む文字列は .encode('utf-8')して UTF-8 で保持。</p>
<p>Python3 では日本語の有無に関係なく、素直にstrのままでよし。</p>
<h3>日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい</h3>
<p>Python2 では素直に sys.stdin/sys.stdout を read/write。</p>
<p>Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。</p>
<p>Python2 の世界には .buffer は存在しないので注意。</p>
大丈夫そうですね。 headとつなげて仕上げを。
仕上げ用のツールを用意しときます。
$ 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 '<html><head>' ; ./ezhtml.py y < {} ; echo '</head><body>' ; ./ezmd.py < {} | ./ezhtml.py y ; echo '</body></html>' ) | 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
OK。
todo
追加してみます。
preタグの場合、どこまでがpreタグの中か? 次のモードへの切り替えの判定が微妙です。
このモードは特別に、'/'だけの行でモード終了としてみます。
行頭に'/'だけ表示したい事はまぁ無いだろうし、 あったとしても、' ' + '/' にして行頭にスペースを入れてしのぐ事にします。
モードが終了するまでの間の複数行のテキストについて
preタグのYAMLへの変換は
簡易なHTMLパーサ 2018秋 preタグのyamlダンプ でこしらえた yaml_dump() を流用しておきます。
ezhtml.pyのオリジナルのyaml_dump()ではstrを返す仕様にしてました。 今回の場面ではUTF-8のままで良いので、そのように修正して使います。
モード終了指示の方式にすると、 '/' で終了してから、次のモードまでの滞空期間ができてしまいます。
モードが何者でもないその間は、とりあえずデフォルトのpモードで。
pモード中に何もテキストがなく、続く別のモードが始まれば、 デフォルトpモードでは何も表示しないので、大丈夫でしょう。
$ cat v2.patch | patch -p1
$ 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
実行してみます。
$ ./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
大丈夫そうですね。
$ ./to_html.py foo_head.yaml foo_2.txt > foo_2.html
todo
追加してみます。
全体の簡単にするためにモードの開始、終了をトップレベルの状態の遷移だけにしました。
なので、基本的に「入れ子」の構造を諦めてます。
が、ですが、このulモードの中だけは「入れ子」を結構使ってます。
例えば
- ul:
- li /: 標準入力からYAML形式のテキストを読み込み
- li /: yaml.load()でテキストをデータに
- li /: データの文字列2つを
- li /: ごにょごにょいじって
- ul:
- li /: foo + ' ' + bar
- li /: .format()
- li /: .join()
- li /: yaml.dump()でデータをYAML形式のテキストにして
- li /: 標準出力に書き出し
こうして
<ul><li>標準入力からYAML形式のテキストを読み込み <li>yaml.load()でテキストをデータに <li>データの文字列2つを <li>ごにょごにょいじって <ul><li>foo + ' ' + bar <li>.format() <li>.join()</ul> <li>yaml.dump()でデータをYAML形式のテキストにして <li>標準出力に書き出し</ul>
こうなって
このように。
ここまでのモードの関連に従うならば、 例えば上記の結果になる元のテキストは
ul
標準入力からYAML形式のテキストを読み込み
yaml.load()でテキストをデータに
データの文字列2つを
ごにょごにょいじって
foo + ' ' + bar
.format()
.join()
yaml.dump()でデータを \
YAML形式のテキストにして
標準出力に書き出し
こうありたい。
ulモード中では、行頭の字下げの数で「入れ子」の指示になるという仕様で、 何とか考えてみました。
$ cat v3.patch | patch -p1
$ cat foo_3.txt
:
p
ここはp
ul
標準入力からYAML形式のテキストを読み込み
yaml.load()でテキストをデータに
データの文字列2つを
ごにょごにょいじって
foo + ' ' + bar
.format()
.join()
yaml.dump()でデータを \
YAML形式のテキストにして
標準出力に書き出し
pre
ここはpre
実行してみます。
$ ./ezmd.py < foo_3.txt
:
- p:
- ここはp
- ul:
- li /: 標準入力からYAML形式のテキストを読み込み
- li /: yaml.load()でテキストをデータに
- li /: データの文字列2つを
- li /: ごにょごにょいじって
- ul:
- li /: foo + ' ' + bar
- li /: .format()
- li /: .join()
- li /: yaml.dump()でデータをYAML形式のテキストにして
- li /: 標準出力に書き出し
- pre: |2
ここはpre
大丈夫そうですね。
$ ./to_html.py foo_head.yaml foo_3.txt > foo_3.html
todo
追加してみます。
自分のa href="xxx"タグの使い方を振り返ると、 ほとんどpタグの中かulタグの中です。
なのでとりあえず、pモードとulモードの文字列処理の箇所だけに、対応を入れてみます。
a (href)の場合、トップレベルのモードを遷移させるまでもなさそうです。
文字列中に [[ xxx | yyy ]] の記載があれば YAML形式の - a href="xxx": yyy を経て HTML形式で <a href="xxx"> yyy </a> に 文字列中に [[ xxx ]] の記載があれば YAML形式の - a href="xxx": xxx } を経て HTML形式で <a href="xxx"> xxx </a> に
このくらいの仕様でやってみます。
$ cat v4.patch | patch -p1
$ cat foo_4.txt : p ここは明示的にp [[v2.patch]] バージョン2のための[[ v2.patch | パッチ ]] となります。 [[http://kondoh.html.xdomain.jp/ezhtml/index.html | 簡易なHTMLパーサ 2018秋]] これは[[http://kondoh.html.xdomain.jp/p3d/index.html#v3_import | pythonのモジュールのインポート]]について。 pre ここはpre p ここもpre h1 ここもpre / ul [[v2.patch]] [[v3.patch]] バージョン2のための[[ v2.patch | パッチ ]] となります。 これは[[http://kondoh.html.xdomain.jp/p3d/index.html#v3_import | pythonのモジュールのインポート]]について。 p ここはp :
実行してみます。
$ ./ezmd.py < foo_4.txt
:
- p:
- ここは明示的にp
- p:
- a href="v2.patch": v2.patch
- p:
- バージョン2のための
- a href="v2.patch": パッチ
- となります。
- p:
- a href="http://kondoh.html.xdomain.jp/ezhtml/index.html": 簡易なHTMLパーサ 2018秋
- p:
- これは
- a href="http://kondoh.html.xdomain.jp/p3d/index.html#v3_import": pythonのモジュールのインポート
- について。
- pre: |
ここはpre
p
ここもpre
h1
ここもpre
- ul:
- li /:
a href="v2.patch": v2.patch
- li /:
a href="v3.patch": v3.patch
- li /:
- バージョン2のための
- a href="v2.patch": パッチ
- となります。
- li /:
- これは
- a href="http://kondoh.html.xdomain.jp/p3d/index.html#v3_import": pythonのモジュールのインポート
- について。
- p:
- ここはp
大丈夫そうですね。
$ ./to_html.py foo_head.yaml foo_4.txt > foo_4.html
todo
追加してみます。
複数のハイフンだけの行が現れると、横線に変換する事にしてみます。
ハイフン2つだけとかなら他に何か意味ありそうなので、 一応4個以上の場合に有効とします。
自分のhrタグの使用箇所は、そのほとんどが
- p: { hr: / }
経ての
<p><hr></p>
として使ってます。
ハイフン4個以上の行が複数行続く場合も、その行数の横線になるように。
横線指示の直後にモード指定が無い場合は、 デフォルトのモード'p'として扱う事にします。
$ cat v5.patch | patch -p1
$ cat foo_5.txt
:
毎回「うぅっ」とうなってます。
----
h2
結論
:
Python2 の世界には .buffer は存在しないので注意。
----
pre
$ cat p2.py
#!/usr/bin/env python2
:
p
ここはp
---
----
----
ここは暗黙のp
h3
ここはh3
---
----
----
---
p
ここはp
ul
標準入力からYAML形式のテキストを読み込み
:
実行してみます。
$ ./ezmd.py < foo_5.txt
:
- 毎回「うぅっ」とうなってます。
- p:
hr: /
- h2: 結論
:
- p:
- Python2 の世界には .buffer は存在しないので注意。
- p:
hr: /
- pre: |
$ cat p2.py
#!/usr/bin/env python2
:
- p:
- ここはp
- p:
- '---'
- p:
hr: /
- p:
hr: /
- p:
- ここは暗黙のp
- h3: ここはh3---
- p:
hr: /
- p:
hr: /
- p:
- '---'
- p:
- ここはp
- ul:
- li /: 標準入力からYAML形式のテキストを読み込み
:
大丈夫そうですね。
$ ./to_html.py foo_head.yaml foo_5.txt > foo_5.html
todo
追加してみます。
img, video ともに自分で使うときのパターンはほぼお決まりで、 a (href)タグと似たようなものです。
なので仕様もa (href)タグと同じような感じにします。
a (href)タグ同様に、pモードとulモードの文字列処理の箇所だけに、対応を入れます。
文字列中に [[ img | xxx ]] の記載があれば YAML形式の - img srcf="xxx": / を経て HTML形式で <img src="xxx"> に 文字列中に [[ video | xxx ]] の記載があれば YAML形式の - video src="xxx" controls playsinline: "" を経て HTML形式で <video src="xxx" controls playsinline></video> に
形式をa (href)タグの場合と合わせたので、 a (href)タグの箇所をちょっと改造するだけの対応になります。
$ cat v6.patch | patch -p1
$ cat foo_6.txt
:
p
Python2 では素直に sys.stdin/sys.stdout を read/write。
Python3 では sys.stdin.buffer , sys.stdout.buffer を使う。
Python2 の世界には .buffer は存在しないので [[img|beat.jpg]] 注意。
:
ul
[[v2.patch]]
[[v3.patch]]
バージョン2のための[[ v2.patch | パッチ ]] となります。
これは[[http://kondoh.html.xdomain.jp/p3d/index.html#v3_import | pythonのモジュールのインポート]]について。
[[ img | beat.jpg ]]
[[ video | cut.mp4 ]]
p
ここはp
:
p
ここはp
[[video|http://kondoh2.html.xdomain.jp/rt/out_v44/fix_1.mp4]]
ul
標準入力からYAML形式のテキストを読み込み
:
実行してみます。
$ ./ezmd.py < foo_6.txt
:
- 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 は存在しないので
- img src="beat.jpg": /
- 注意。
:
- ul:
- li /:
a href="v2.patch": v2.patch
- li /:
a href="v3.patch": v3.patch
- li /:
- バージョン2のための
- a href="v2.patch": パッチ
- となります。
- li /:
- これは
- a href="http://kondoh.html.xdomain.jp/p3d/index.html#v3_import": pythonのモジュールのインポート
- について。
- li /:
img src="beat.jpg": /
- li /:
video src="cut.mp4" controls playsinline: ''
- p:
- ここはp
:
- p:
- ここはp
- p:
- video src="http://kondoh2.html.xdomain.jp/rt/out_v44/fix_1.mp4" controls playsinline: ''
- ul:
- li /: 標準入力からYAML形式のテキストを読み込み
大丈夫そうですね。
$ ./to_html.py foo_head.yaml foo_6.txt > foo_6.html
todo
追加してみます。
sタグは「打ち消し線」の指定です。
これまた a (href)タグ同様に、pモードとulモードの文字列処理の箇所だけの対応で。
形式も強引にa (href)タグに合わせてしまいます。(^_^;
文字列中に [[ - | xxx ]] の記載があれば YAML形式の - s: xxx を経て HTML形式で <s> xxx </s> に
形式を強引にもa (href)タグの場合と合わせたので、 変更箇所は驚くほど軽微です。
$ cat v7.patch | patch -p1
$ cat foo_7.txt : そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回[[ - |「うぅっ」]] 「ぬはぁ」とうなってます。 ---- : ul 標準入力からYAML形式のテキストを読み込み yaml.load()でテキストをデータに [[-|データの文字列2つを]] ごにょごにょいじって :
実行してみます。
$ ./ezmd.py < foo_7.txt
:
- p:
- そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、
- 毎回
- s: 「うぅっ」
- 「ぬはぁ」とうなってます。
- p:
hr: /
:
- ul:
- li /: 標準入力からYAML形式のテキストを読み込み
- li /: yaml.load()でテキストをデータに
- li /:
s: データの文字列2つを
- li /: ごにょごにょいじって
:
大丈夫そうですね。
$ ./to_html.py foo_head.yaml foo_7.txt > foo_7.html
todo
目次を自動生成する機能を追加してみます。
さすがにこの機能は2 passになります。
'index'だけの行が現れると目次モード。
そこから他のモードになるまでの区間に目次を挿入します。
目次モード中の箇所に、目次作成のためのパラメータを指定します。
index パラメータ
パラメータは、目次にするヘッダタグの種別の範囲を指定します。
範囲指定はPythonのリストのスライスの指定のようにします。
index 2:5
lst[2:5] なので目次にする対象は h2, h3, h4
index 3:
lst[3:] なので、目次にする対象は h3, h4, ....
index :3
lst[:3] なので、目次にする対象は h1, h2
index
パラメータの指定がなければ lst[:] 扱いで、全てのヘッダタグを対象にします。
目次の形式は、ヘッダタグの階層に従って ulタグの入れ子の構成にします。
ulタグの処理は既に実装してるので、 ヘッダの番号に応じて字下げしたテキストデータを作り、 ulタグとして処理すれば楽チンですね。
$ cat v8.patch | patch -p1
$ cat foo_8.txt : そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回[[ - |「うぅっ」]] 「ぬはぁ」とうなってます。 ---- index ---- p 2: の場合 index 2: ---- p :4 の場合 index :4 ---- p 2:3 の場合 index 2:3 ---- p 2 の場合 index 2 ---- p 3 の場合 index 3 ---- h2 結論
実行してみます。
$ ./ezmd.py < foo_8.txt
:
- p:
- そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、
- 毎回
- s: 「うぅっ」
- 「ぬはぁ」とうなってます。
- p:
hr: /
- ul:
- li /:
a href="#c_1_0": Python2とPython3での日本語文字列対応について
- ul:
- li /:
a href="#c_2_1": 結論
- ul:
- li /:
a href="#c_3_2": 日本語を含む文字列処理で .foramt() や .join() を使いたい
- li /:
a href="#c_3_3": 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい
- li /:
a href="#c_3_4": ここはh3---
- p:
hr: /
- p:
- '2: の場合'
- ul:
- li /:
a href="#c_2_1": 結論
- ul:
- li /:
a href="#c_3_2": 日本語を含む文字列処理で .foramt() や .join() を使いたい
- li /:
a href="#c_3_3": 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい
- li /:
a href="#c_3_4": ここはh3---
- p:
hr: /
- p:
- :4 の場合
- ul:
- li /:
a href="#c_1_0": Python2とPython3での日本語文字列対応について
- ul:
- li /:
a href="#c_2_1": 結論
- ul:
- li /:
a href="#c_3_2": 日本語を含む文字列処理で .foramt() や .join() を使いたい
- li /:
a href="#c_3_3": 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい
- li /:
a href="#c_3_4": ここはh3---
- p:
hr: /
- p:
- 2:3 の場合
- ul:
- li /:
a href="#c_2_1": 結論
- p:
hr: /
- p:
- 2 の場合
- ul:
- li /:
a href="#c_2_1": 結論
- p:
hr: /
- p:
- 3 の場合
- ul:
- li /:
a href="#c_3_2": 日本語を含む文字列処理で .foramt() や .join() を使いたい
- li /:
a href="#c_3_3": 日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい
- li /:
a href="#c_3_4": ここはh3---
- p:
hr: /
- h2:
a name="c_2_1": 結論
さすがにこれは、パッとみて大丈夫かどうか分かりかねますね。
$ ./to_html.py foo_head.yaml foo_8.txt | tee foo_8.html | nkf -u : <p>そして、YAML形式データファイル中の文字列を、UTF-8で日本語に置き換えようとして、 毎回 <s>「うぅっ」</s> 「ぬはぁ」とうなってます。</p> <p><hr></p> <ul><li><a href="#c_1_0">Python2とPython3での日本語文字列対応について</a> <ul><li><a href="#c_2_1">結論</a> <ul><li><a href="#c_3_2">日本語を含む文字列処理で .foramt() や .join() を使いたい</a> <li><a href="#c_3_3">日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい</a> <li><a href="#c_3_4">ここはh3---</a></ul></ul></ul> <p><hr></p> <p>2: の場合</p> <ul><li><a href="#c_2_1">結論</a> <ul><li><a href="#c_3_2">日本語を含む文字列処理で .foramt() や .join() を使いたい</a> <li><a href="#c_3_3">日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい</a> <li><a href="#c_3_4">ここはh3---</a></ul></ul> <p><hr></p> <p>:4 の場合</p> <ul><li><a href="#c_1_0">Python2とPython3での日本語文字列対応について</a> <ul><li><a href="#c_2_1">結論</a> <ul><li><a href="#c_3_2">日本語を含む文字列処理で .foramt() や .join() を使いたい</a> <li><a href="#c_3_3">日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい</a> <li><a href="#c_3_4">ここはh3---</a></ul></ul></ul> <p><hr></p> <p>2:3 の場合</p> <ul><li><a href="#c_2_1">結論</a></ul> <p><hr></p> <p>2 の場合</p> <ul><li><a href="#c_2_1">結論</a></ul> <p><hr></p> <p>3 の場合</p> <ul><li><a href="#c_3_2">日本語を含む文字列処理で .foramt() や .join() を使いたい</a> <li><a href="#c_3_3">日本語を含むUTF-8のテキストを標準入力、標準出力で扱いたい</a> <li><a href="#c_3_4">ここはh3---</a></ul> <p><hr></p> <h2><a name="c_2_1">結論</a></h2> :
むー、まぁ、百聞は一見にしかず
大丈夫そうですね。
todo
自分ではいつもheadタグには日本語は書かないので、 ここは安易に
$ cat v9.patch | patch -p1
実行してみます。
$ ./to_html.py Usage: ./to_html.py head.yaml body.txt [title] $ ./to_html.py foo_head.yaml foo_8.txt | grep title <title>py23str</title> $ ./to_html.py foo_head.yaml foo_8.txt 'sample page' | grep title <title>sample page</title> $ ./to_html.py foo_head.yaml foo_8.txt 'sample page' > foo_9.html
OK
todo
色々試してみて不具合でました。
ulタグの処理前に、字下げの絡みで行の結合をする箇所。
def esc_join(lst): res = [] for s in lst: if res and res[-1] and res[-1][-1] == '\\': t = res[-1][:-1] res[-1] = strip_tail(t) + strip_head(s) else: res.append(s) return res
res[-1]が空文字列''の場合に、''[-1]になってアクセスでエラーが出る事がありました。
- if res and res[-1][-1] == '\\': + if res and res[-1] and res[-1][-1] == '\\':
な修正をしておきます。
次の調整を入れておきます。
$ cat v10.patch | patch -p1
では満を持して、このページ自身もこの仕様のテキストで書いてみましょう。
このテキストファイルから
$ ./to_html.py head.yaml index.ez.txt ezmd > index.html
となります。
(再帰だ〜)
todo