Docutilsのインラインマークアップを自作する
以前、Docutilsのディレクティブを自作する - saito’s blogでreStructuredTextのディレクティブを自作する方法を紹介しました。サンプルプログラムでは、はてな記法のリンク作成支援に似た機能をreStructuredTextに追加しました。しかし、ディレクティブはインラインで書くことが出来ないので、前回のサンプルでは、
* google記法 : |google記法| * amazon記法 : |amazon記法| * wikipedia記法 : |wikipedia記法| * isbn記法 : |isbn記法| .. |google記法| google:: はてな .. |amazon記法| amazon:: はてな .. |wikipedia記法| wikipedia:: はてな_(企業) .. |isbn記法| isbn:: 4798110523 近藤(2006)
のように、わざわざ置換を用いて文中にリンクを挿入していました。
Docutilsではインラインマークアップを自分で定義することができ、前回のサンプルのような用法の場合インラインマークアップを使うべきだということが分かったので、改めてそちらの方法を紹介します。
Docutilsでインラインマークアップを定義する方法はこちらのページで紹介されています。
インラインマークアップを定義するには、まず、次のようなシグネチャを持つ関数を定義します。
def role_fn(name, rawtext, text, lineno, inliner, options={}, content=[]): code...
この関数で2つの戻り値を返すようにします。1つ目はdocutils.nodes.Nodeのサブクラスのインスタンスのリストで、2つ目はシステムメッセージ(おそらくエラー処理などの目的に使う)のリストです。各戻り値は空のリストにすることもできます。関数を定義したら、docutils.parsers.rst.roles.register_local_roleを使って関数を登録します。
次のサンプルプログラムでは、Google検索へのリンクを作成するための記法をreStructuredTextに追加します。
import urllib from docutils.core import publish_parts from docutils import nodes from docutils.parsers.rst import roles def google(role, rawtext, text, lineno, inliner, options={}, content=[]): q = text title = u"google:%s" % q refuri = "http://www.google.com/search?q=%s" % urllib.quote_plus(q.encode("utf-8")) ref_node = nodes.reference(refuri=refuri, name=title) ref_node += nodes.Text(title) return [ref_node], [] roles.register_local_role("google", google) if __name__ == '__main__': value = ":google:`はてな`" parts = publish_parts(source=value, writer_name="html4css1") html = parts["fragment"] print html.encode("utf-8")
このプログラムを実行すると、次のようなHTMLが出力されます。
<p><a class="reference external" href="http://www.google.com/search?q=%E3%81%AF%E3%81%A6%E3%81%AA">google:はてな</a></p>