2011年04月25日

Python文字コード作法 〜 FreeMindの吐くHTMLソースを日本語に

 Pythonでも、かつてはOS依存の文字コードでコーディングすることが当り前の時代もあったが、今ではUTF-8で記述することを本則とすることになっている。そして、その入出力ではcodecsモジュール等を使い他の文字コードのデータをUnicode化し、内部処理は全てUnocodeで行なわれる様にする訳だ。その流れでPython3に至っては文字列は全てUTF-8であることが前提となっているが、今回はまだPython2.6のコードである。


 さて、お題の説明からさせて頂くが、FreeMindには、多種の規格の文書ファイルにexportする機能があり、一見すると日本語でも問題なく利用出来る様に作られている。しかし、HTMLの場合、日本語等のマルチバイト文字については、文字そのものでなく、𞉀の様に10進数の文字番号で埋め込まれており、ソースを覗くと何を書いているのか全く分からないということになる。
 ブラウザで表示すればちゃんと読めるので、通常の利用ではなんら問題ない仕様であるので、文句は言えないが、例えば、 FreeMindでまとめたものをHTMLファイルでexportし、必要な部分のHTMLをソースからコピペで、ブログに貼りつけると言ったことをしたい時には、𞉀という表記ではどこを取出したらよいのか判り難くく、難しい作業となってしまう。
 そこで、本日は、FreeMind0.9.0でexportしたHTMLファイルをちゃんと日本語に置換する為のフィルタプログラムを作ったと言うことである。

 本音で言うと出来るなら、学習を始めたばっかりのJavaでもやって試たかったのだが、まだまだ、能力不足で文字コードの暴れを補正する方法を知らないので、今回はオハコのPythonのみだ。


 さて、作るに当り、FrrMindの吐くHTMLファイルの特徴を明記しておこう。

  1.  Windows上のFreeMind0.9.0の場合、日本語設定の場合、ファイル自体はShift_JISで作成する様になる様で、恐らくOSの言語に合わせ指定されてしまう様である。
  2.  HTMLのペッダー情報には、そのファイルの文字コードが明記されていない。
  3.  そして、マルチバイト文字については、全て𞉀形式のUNICODEの文字コードの10進数で表示している


 これを、Pythonで、変換するには、次のことを押さえて置く必要がある。

  1.  OSに依存する既定の文字コードを意識してファイルを読み込んで処理するには、普通のopen()関数でなく、codecsモジュール内のopen関数を使う必要がある。その為には、読込む前に、「from codecs import open」としてopen()をcodecs.open()に置換え、第3引数に読込みファイルの文字コードを文字列名で指定する必要がある。そうすることで、Pythonのソースファイルの文字コードとして指定したものに自動変換されるので、OS依存を解消出来ることになる。pythonの
  2.  さて、その上で、読込んだ文字列データの中から、𞉀形式のUNICODEの文字コードを抽出し、それに対応する文字のリストを作成する。その為には、やはり正規表現r'&#[0-9]*;'と言うパターンを指定して、モジュール「re」のfindall()で文字列全体を舐め回して抽出、その数字部分をスライス「抽出文字列[2:-1]」して&#と;を除くことで取得、それを int()で整数化し、unichr()に入れれば対応するUnicode文字を取得出来る。そして、それをリスト型でなく辞書型変数に納めれば、同じものは省かれて便利である。
  3.  その置換は、文字列メソッドのreplace()で簡単に済んでしまう
  4.  必要により整形し出力すればよい


 今回の場合ファイル名の指定が面倒だったので、入力ファイル名は、第2パラメータとして指定し、画面出力で逃げることにした。従って利用は「python 〜.py 入力ファイル名 > 出力ファイル名」と入力することになる。 サンプルのFreeMindのファイルは次の様なものを用いた。このHTML を Export したものは、末尾に掲載して置く。
FreeMind0.9.0では、横方向にだけは自由にノードを移動出来る様になった








Pythonで書くと次の通り。実際のコーディングでは、随所でprint文を挟み実行し動作を確認しながら作成している。
          HTML_EntNum2Char.py 


#!c:\\Python26\\python.exe
# -*- coding: UTF8 -*-
# ※ Windows の場合1行目はdummyです。
"""
MindMapの吐くHTMLの10進コード表記の
日本語文字をUTF-8文字列に変更する
"""
__author__ = "Mire in Japan"
__version__ = '0.0.1'
__copyright__ = 'Copyright (c) 2011 Mire'
__license__ = 'GPL'
__url__ = 'http://pythonlife.up.seesaa.net/'

def HTML_Decimal2Char(filename, coding='Shift_JIS'):
"""
ファイル名を指定して、そのファイルを指定コードのものとして読込み
一行ずつ、Unicode文字に変換する関数EntNum2Char()に渡す。
"""
from codecs import open
utf8_lines=u""
fpi = open(filename,'r', coding) # MindMapの吐くHTMLは何故か
lines=fpi.readlines() # Shift_JISのファイルとなって
for line in lines: # いるので、それとして読込み、
utf8_lines = '%s\n%s' % (utf8_lines # Unicode番号表記を文字に
,Decimal2Char(line)) # したものを文字列化する
return utf8_lines


def Decimal2Char(line):
"""
文字列内の10進コード表記の日本語文字をUTF-8文字に変換し
その文字列リストを返す関数
"""
import re
pat = re.compile('&#[0-9]*;')
ms = re.findall(pat,line)
pat_dic={}
for m in ms:
try:
h = unichr(int(m[2:-1]))
if len(m)>6:
pat_dic[m]=h
except:
pass
for m in pat_dic:
h = u'%s' % (pat_dic[m])
try:
line = line.replace(m, h)
except:
print pat_dic,m,h

if line.strip()=="": # 空行を省く為、空文字列を返す
return ''
else:
return line.rstrip() # 末尾の空白文字(改行記号)を除去


#####################################################################
#実行ブロック
if __name__ == "__main__":
from sys import argv
#print argv
filename = argv[1]
str = HTML_Decimal2Char(filename)
print str, #[str]
 で、今の関心は、Javaではどうするのかと言うことだ。今のところ、Vista上での学習では素直にShift_JISで行ない、Androidの学習ではEclipsの設定をUTF-8にしてAndroidの国際化の仕組みを使っている。Javaの道は長い様だ。


          Html_File_Format_of_FreeMind.mm.html 


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>FreeMind &#12398;&nbsp;HHML&#12501;&#12449;&#12452;&#12523;</title>
<style type="text/css">
li { list-style: none; margin: 0; }
p { margin: 0; }

span.l { color: red; font-weight: bold; }

a.mapnode:link {text-decoration: none; color: black; }
a.mapnode:visited {text-decoration: none; color: black; }
a.mapnode:active {text-decoration: none; color: black; }
a.mapnode:hover {text-decoration: none; color: black; background: #eeeee0; }

</style>
<!-- ^ Position is not set to relative / absolute here because of Mozilla -->
</head>
<body>
<p><span style="color: #000000;font-size: 181%;font-family: メイリオ, sans-serif;
">FreeMind &#12398;&nbsp;HHML&#12501;&#12449;&#12452;&#12523;</span>
<ul><li><span style="color: #0033ff;font-size: 163%;font-family: メイリオ, sans-serif;
">&#24418;&#24335;</span>
<ul><li><span style="color: #00b439;font-size: 145%;font-family: メイリオ, sans-serif;
"><img src="images/icons/help.png" alt="[?]">&#25991;&#23383;&#12467;&#12540;&#12489;
&#12399;OS&#20381;&#23384;?</span>
<ul><li><span style="color: #990000;font-size: 127%;font-family: メイリオ, sans-serif;
">Win&#12391;&#12399;Shift_JIS&#12395;&#12394;&#12387;&#12390;&#12356;&#12427;</span>

</li>

</ul>
</li>
<li><span style="color: #00b439;font-size: 145%;font-family: メイリオ, sans-serif;
"><img src="images/icons/messagebox_warning.png" alt="[!]">&#12506;&#12483;&#12480;
&#20869;&#12395;&#12399;&#26126;&#31034;&#28961;&#12375;</span>

</li>
<li><span style="color: #00b439;font-size: 145%;font-family: メイリオ, sans-serif;
"><img src="images/icons/clanbomber.png" alt="[危険]">&#26085;&#26412;&#35486;&#25991;
&#23383;&#12399;&#12300;&amp;#123456;&#12301;&#12391;</span>
<ul><li><span style="color: #990000;font-size: 127%;font-family: メイリオ, sans-serif;
"><img src="images/icons/smily_bad.png" alt="[不機嫌]">&#19968;&#33324;&#21033;&#29992;
&#12399;&#21839;&#38988;&#12394;&#12356;&#12364;&#12477;&#12540;&#12473;&#21033;&#29992;
&#12391;&#12399;</span>

</li>

</ul>
</li>

</ul>
</li>
<li><span style="color: #0033ff;font-size: 163%;font-family: メイリオ, sans-serif;
">&#24418;&#24335;&#12434;&#22793;&#26356;</span>
<ul><li><span style="color: #00b439;font-size: 145%;font-family: メイリオ, sans-serif;
">Python&#12391;&#12399;</span>
<ul><li><span style="color: #990000;font-size: 127%;font-family: メイリオ, sans-serif;
"><img src="images/icons/idea.png" alt="[アイディア]"
>codecs.open()&#12391;&#25991;&#23383;&#12467;&#12540;&#12489;&#25351;&#23450;&#35501;
&#36796;&#12415;</span>

</li>
<li><span style="color: #990000;font-size: 127%;font-family: メイリオ, sans-serif;
">re.findall()&#12391;&#22793;&#25563;&#20505;&#35036;&#12434;&#25277;&#20986;</span>

</li>
<li><span style="color: #990000;font-size: 127%;font-family: メイリオ, sans-serif;
">&#20505;&#35036;&#12434;&#36766;&#26360;&#22411;&#22793;&#25968;&#12395;&#20837;
&#12428;&#12427;</span>

</li>
<li><span style="color: #990000;font-size: 127%;font-family: メイリオ, sans-serif;
">&#25991;&#23383;&#21015;&#12513;&#12477;&#12483;&#12489;&#12398;replace()&#12391;
&#32622;&#25563;</span>

</li>
<li><span style="color: #990000;font-size: 127%;font-family: メイリオ, sans-serif;
">&#20837;&#20986;&#21147;</span>
<ul><li><span style="color: #111111;font-size: 109%;font-family: メイリオ, sans-serif;
">&#21462;&#25954;&#12360;&#12378;&#12289;&#35501;&#36796;&#12415;&#12501;&#12449;
&#12452;&#12523;&#12399;&#31532;&#65298;&#12497;&#12521;&#12513;&#12540;&#12479;
&#12391;&#25351;&#23450;</span>

</li>
<li><span style="color: #111111;font-size: 109%;font-family: メイリオ, sans-serif;
">&#20986;&#21147;&#12399;&#30011;&#38754;&#12391;</span>

</li>
<li><span style="color: #111111;font-size: 109%;font-family: メイリオ, sans-serif;
">&#12501;&#12449;&#12452;&#12523;&#21270;&#12399; &#12300;&gt; &#20986;&#21147;
&#12501;&#12449;&#12452;&#12523;&#21517;&#12301;&#12391;&#28168;&#12414;&#12379;
&#12427;&#12290;</span>

</li>

</ul>
</li>

</ul>
</li>
<li><span style="color: #00b439;font-size: 145%;font-family: メイリオ, sans-serif;
"><img src="images/icons/help.png" alt="[?]">Java&#12394;&#12425;?</span>

</li>

</ul>
</li>

</ul></body>
</html>

2011-9-29追記: 本文内の&の &amp;でのエスケープ処理が漏れていた為、ページが適切に表示されていませんでした。これ迄気付かず誠に失礼しました。m(_ _)m
タグ:Freemind Python
posted by Mire at 20:26 | Comment(1) | TrackBack(0) | Pythonプログラミング | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
とても魅力的な記事でした!!
また遊びにきます。
ありがとうございます!!
Posted by ビジネスマナー at 2011年09月24日 21:16
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
月額見放題1,000円開始キャンペーンバナー(画像ありver)
紺碧の艦隊 ルパン三世 GREAT CHASE クリックプロモーション
<< 2013年01月 >>
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
カテゴリ
タグクラウド
ファン
利用中のオープンソース
最近のコメント
最近の記事
過去ログ
QRコード
レガシーなアプリはいかが?
Dell 法人のお客様ページ
  • 【法人様向け】デル、お得なキャンペーン情報
  • 法人のお客様向け ストレージソリューション
  • 法人のお客様向け ネットワークソリューション
  • 【SOHO法人様向け】デル・オンライン広告限定ページ
  • デル-個人のお客様ページ
  • 【個人のお客様向け】デル・オンライン広告限定ページ
  • オンライン広告限定キャンペーンページ
  • ソフトウェア&周辺機器 パソコン工房
    ツートップインターネットショップ(twotop.co.jp) マウスコンピューター/G-Tune
  • ×

    この広告は1年以上新しい記事の投稿がないブログに表示されております。