LoginSignup
9
11

More than 5 years have passed since last update.

PythonでMarkdownからHTMLに変換する

Last updated at Posted at 2016-12-08

DjangoやBottleでウェブアプリの開発をしていると、入力されたテキストに対してPythonでMarkdownのレンダリングをしたくなることがあります。そこで今回はmistuneというOSSのパッケージを利用して、Python側でHTMLに変換することを試してみます。

シンプルな使い方

mistuneのREADMEに書かれているサンプル通り動かすと、以下のようになります。ポイントとしては、通常のテキストの場合は段落ごとに<p>タグで囲われており、その中で強調表示や斜体などが展開されます。リスト表記などの場合は、対応するタグで囲われるという感じです。

In [1]: import mistune

In [2]: mistune.markdown('I am using **mistune markdown parser**')
Out[2]: '<p>I am using <strong>mistune markdown parser</strong></p>\n'
In [3]: txt = """段落1
   ...: 
   ...: 段落2"""

In [4]: mistune.markdown(txt)
Out[4]: '<p>段落1</p>\n<p>段落2</p>\n'

In [5]: txt = """- リスト1
   ...: - リスト2
   ...: - リスト3"""

In [6]: mistune.markdown(txt)
Out[6]: '<ul>\n<li>リスト1</li>\n<li>リスト2</li>\n<li>リスト3</li>\n</ul>\n'

またオプションとして、入力されたHTMLタグをエスケープするかどうかのescape(デフォルトではTrue)や、空白行を入れない改行の際に<br/>タグを含めるhard_wrapというものがあります(デフォルトではFalse)。

自作のLexerとRenderを使う

さて、mistuneでは一通りのmarkdownの仕様に従った変換はデフォルトで提供されていますが、加えて独自の表記や記号に対してもルールを指定してHTML変換する機能もあります。

mistuneでは標準でhttp/httpsのリンク付与機能を提供していますが、他のftpやsmbなどのプロトコルには対応していません。ここでは例として、リンクに自動でaタグを付与する機能を追加してみます。

方法としては、Lexerに独自ルールの記載して、Rendererに対応する変換方法を指定するというものです。ここでは、LexerでftpやsmbのプロトコルのURLを正規表現で抜き出して、Rendererで前後に<a>タグを付与するということをしています。

import re
from mistune import Renderer, InlineLexer


class DocumentLinkRenderer(Renderer):

    def document_link(self, link):
        return '<a href="{l}">{l}</a>'.format(l=link)


class DocumentLinkInlineLexer(InlineLexer):

    def enable_document_link(self):
        self.rules.document_link = re.compile(r'''^((https?|smb|ftp|file):\/\/[^\s<]+[^<.,:;"')\]\s])''')
        self.default_rules.insert(3, 'document_link')

    def output_document_link(self, m):
        text = m.group(1)
        return self.renderer.document_link(text)

使い方としては、mistune.Markdown()にカスタムのRendererとInlineLexerを指定します。

renderer = DocumentLinkRenderer()
inline = DocumentLinkInlineLexer(renderer)
inline.enable_document_link()
markdown = mistune.Markdown(renderer, inline=inline)

markdown("markdown text")

実際に利用してみると、以下のようにftpのURLに対しても自動でリンクが作成されていることがわかります。

In [20]: markdown("ftp://path/to/file")
Out[20]: '<p><a href="ftp://path/to/file">ftp://path/to/file</a></p>\n'

この機能を使えば、はてなキーワードみたいに特定の単語にリンクを貼ったり、RedmineやBacklogのチケットのように記事のIDとURLの紐付けを行うことができます。

参考

9
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11