« アルティメットガール西へ | トップページ | サルでもできるブログ教室:ウェブログ虎の穴 其の十四 »

2005年2月22日

Python のリテラル形式を使って HTML を作る

世の中には HTML(XML) を作れる構造化書式が色々ありますがどれも大げさなツールを使い例外規則の山を築いたあげく HTML(XML) で出来るはずの表現を(普通に書ける範囲だと)制限している物が多い感じ。

でもよく考えたらプログラム言語(およびその構文エディター)なら元からデータ構造を記述出来、そしてエラーチェックまでしてくれるわけで。試しにちょっとしたツールを作ってみました。

まず以下のスクリプトを html.py という名前で保存してモジュールとしてください。

from xml.sax.saxutils import escape as _escape
INS, DEL = "ins", "del"
HEAD, BODY = "head", "body"
HTML = "html"
_BLOCK = ("p", "pre", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "frameset",
          "frame", "noframes", "address", "blockquote", "style", "div",
          "center", "ul", "ol", "dl", "dir", "menu", "form", "fieldset",
          "table", "noscript")
(P, PRE, H1, H2, H3, H4, H5, H6, HR, FRAMESET,
 FRAME, NOFRAMES, ADDRESS, BLOCKQUOTE, STYLE, DIV,
 CENTER, UL, OL, DL, DIR, MENU, FORM, FIELDSET,
 TABLE, NOSCRIPT) = _BLOCK
_INLINE = ("a", "bdo", "iframe", "abbr", "acronym", "q", "cite", "em",
           "strong", "code", "dfn", "kbd", "samp", "var", "span", "font",
           "basefont", "big", "small", "b", "i", "s", "strike", "u", "tt",
           "sub", "sup", "form", "input", "button", "textarea", "select",
           "label", "isindex", "caption", "object", "applet", "script",
           "ruby", "rb", "rt", "rp", "br", "img")
(A, BDO, IFRAME, ABBR, ACRONYM, Q, CITE, EM,
 STRONG, CODE, DFN, KBD, SAMP, VAR, SPAN, FONT,
 BASEFONT, BIG, SMALL, B, I, S, STRIKE, U, TT,
 SUB, SUP, FORM, INPUT, BUTTON, TEXTAREA, SELECT,
 LABEL, ISINDEX, CAPTION, OBJECT, APPLET, SCRIPT,
 RUBY, RB, RT, RP, BR, IMG) = _INLINE
_INLINE += (INS, DEL)
_EMPTY = (BR, IMG, HR)
def ruby(base, ruby):
    return (RUBY, (RB, base), (RP, "("), (RT, ruby), (RP, ")"))
def to_html(data, inline=False):
    if isinstance(data, basestring):
        return _escape(unicode(data))
    tag = str(data[0])
    if tag in _INLINE: # ブロック要素としての ins, del が使えないバグ有り
        inline = True
        lb = ""
        if tag == BR:
            lb = "\n"
    else:
        if inline:
            raise "A block element is in an in line element: %s" % data
        lb = "\n"
    if len(data) > 1 and isinstance(data[1], dict):
        attr = " ".join([('%s="%s"' % (unicode(k), unicode(i)))
                         for (k, i) in data[1].items()])
        if tag in _EMPTY:
            if len(data) != 2:
                raise "There is too much data: %s" % data
            return "<%s %s />%s" % (tag, attr, lb)
        else:
            return "<%s %s>%s%s</%s>%s" % (tag, attr, lb, "".join([
                to_html(x, inline) for x in data[2:]]), tag, lb)
    else:
        if tag in _EMPTY:
            if len(data) != 1:
                raise "There is too much data: %s" % data
            return "<%s />%s" % (tag, lb)
        else:
            return "<%s>%s%s</%s>%s" % (tag, lb, "".join([
                to_html(x, inline) for x in data[1:]]), tag, lb)
# 好きに流用してください

後は、例えば

from html import *
data = (
    BODY,
    (P,u"シリーズ後半に入った ",
     (A,{"href":"http://www.pc-moe.com/ug/"},u"UG☆アルティメットガール"),
     u" 微妙絶妙なおかしみのある回でした。"),
    (P,(STRONG,u"光の国"),u"観光のバスに乗り",u"ヒロイン達の",
     (STRONG,u"双子山"),u"学園2年",(STRONG,u"M78"),u"組は修学旅行ですが。"),
    (P,(EM, {"title":u"アルティメットガール・ロリ"}, u"つぼみ"),u"の歌う",
     (CITE,u"『UFOマンの歌』"),u"(?)での ", (Q,u"マッハの腰つき"),u" で ",
     (Q,u"勝利のエクスタシー"),u" を ", (Q,u"飛ばすぜ"),u" って、やっぱり",
     (EM,u"UFOマン"),u"が怪獣を倒していた頃もそんな倒し方をしていたので",
     u"しょうか。"),
    (P,u"しかしクラス丸々一緒に乗っているバスの中から ",
     (Q, ruby(u"白絹", u"シルク"),u"、頑張れ!"),u" と声援を送る",
     (EM,u"ヴィヴィ"),u" & ",(EM,u"つぼみ"),u"、それってヤバくないですか?"),
    (HR,),
    (P,(Q,u"真の女体芸術を追求する"),u" ",(EM,u"クラシック怪獣マーラー"),
     u" & ",(EM,u"UFOマン"),u" & ",
     (EM,{u"title":u"コメンテーター"},u"岡村与作"),u"はともかくとして。"),
    (P,u"怪獣に感じさせられまくった上、",(EM,u"真"),u"とタンデムシートで",
     (STRONG,u"密着"),u"。セクハラ怪獣 & コメンテーターによる表面上の騒ぎ",
     u"より深い部分もエロですね。"),
    (P,(CITE,u"『あるてぃめっとれいでぃお』第6回「熱い男がやって来た!」"),
     u"の方でも今回特別に",(EM,{"title":u"ヒーロー"},u"諸星真"),u"役の",
     (DEL,u"変態"),(EM,{"title":u"正真正銘ロリコン"},(INS,u"泰"),u"勇気"),
     u"氏をゲストに迎え、色気のあるネタで盛り上がってますし。"),
    (P,u"後半に入って浅いエロから深いエロに進化して来ている感じ。")
    )
print to_html(data)

というようにして使います。(ちなみにこれの実行例が一つ前のアレ)

このまま実用に使うにはちょっと辛いですが、どこにでもある Python にちょっとしたスクリプトを加えるだけで、要素名の正当性やタグの交差までチェックしてくれる HTML エディターとして使えるわけですからアイデアとしては悪くないかも。

元々が Python のソースなわけですから変数も関数も使えるわけで。そこで定義してある ruby 関数のようなサポート関数をさらに追加して行けば使い勝手も良くなるでしょう。

« アルティメットガール西へ | トップページ | サルでもできるブログ教室:ウェブログ虎の穴 其の十四 »

パソコン・インターネット」カテゴリの記事

Python」カテゴリの記事

トラックバック


この記事へのトラックバック一覧です: Python のリテラル形式を使って HTML を作る:

« アルティメットガール西へ | トップページ | サルでもできるブログ教室:ウェブログ虎の穴 其の十四 »

他のアカウント

ブログ妖精

  • ココロ

Affiliate

無料ブログはココログ