ZopeのreStructuredTextでYouTube動画を扱えるようにする
- 公開日: 2009/04/22(水) 07:17[JST]
僕はこのサイトの文書を主にreStructuredTextで書いている。てか、もうHTMLを忘れかけている。
で、Youtube動画を扱うようになったので、何とかreStructuredTextのディレクティブでyoutube動画を埋め込めないかと思案していた。検索したこところ、Countergram LLC
のサイトにて、Jason Stitt氏により、reStructuredTextを拡張する方法
が説明されていた。
で、同氏の説明に基づいて、zopeに組み込まれているreStructuredTextを拡張してみた。コードはJason Stitt氏のものをほぼそのまんま流用した。手順は以下の通り(環境はFreeBSD RELENG_6.3とportsで入れたZope2.9)。
まず、zopeのreStructuredTextのディレクティブを定義しているディレクトリに移動する。ディレクトリは、環境によって違うと思うけど、例えばzopeのルートディレクトリから相対的にlib/python/docutils/parsers/rst/directivesと掘っていった所。
そのディレクトリに、以下の内容でyoutube.pyというファイルを作る。
from docutils import nodes
from docutils.parsers.rst import directives
CODE = """\
<object type="application/x-shockwave-flash"
width="%(width)s"
height="%(height)s"
class="youtube-embed"
data="http://www.youtube.com/v/%(yid)s">
<param name="movie" value="http://www.youtube.com/v/%(yid)s"></param>
<param name="wmode" value="transparent"></param>%(extra)s
</object>
"""
PARAM = """\n <param name="%s" value="%s"></param>"""
def youtube(name, args, options, content, lineno,
contentOffset, blockText, state, stateMachine):
""" Restructured text extension for inserting youtube embedded videos """
if len(content) == 0:
return
string_vars = {
'yid': content[0],
'width': 425,
'height': 344,
'extra': ''
}
extra_args = content[1:] # Because content[0] is ID
extra_args = [ea.strip().split("=") for ea in extra_args] # key=value
extra_args = [ea for ea in extra_args if len(ea) == 2] # drop bad lines
extra_args = dict(extra_args)
if 'width' in extra_args:
string_vars['width'] = extra_args.pop('width')
if 'height' in extra_args:
string_vars['height'] = extra_args.pop('height')
if extra_args:
params = [PARAM % (key, extra_args[key]) for key in extra_args]
string_vars['extra'] = "".join(params)
return [nodes.raw('', CODE % (string_vars), format='html')]
youtube.content = True
見ての通り、Jason Stitt氏のコードから最後の一行を削っただけである。
次に、__init__.pyを編集する。このファイルの中で、使用可能なディレクティブの一覧が、_directive_registry = {以下の行に列記されているので、その中に、
'youtube': ('youtube', 'youtube'),
という一行を追加する。
最後に、zopeを再起動すればOK。とりあえず僕の環境では特に問題なく動作しているようだ。