MarkdownをPythonライブラリとして使用する

初回公開:2018/01/01
最終更新:2018/01/13

Library Reference — Python Markdown」をつたない翻訳,勝手な解釈。

【 目次 】

まず第一にPython-Markdownは、Markdown構文をHTMLに変換するためにさまざまなプロジェクトで使用されるPythonライブラリモジュールとなる事を目指しています。

基本

markdownをモジュールとして使用するには:

import markdown
html = markdown.markdown(your_text_string)

詳細

Python-Markdownには、パブリッククラスmarkdown.Markdownをラップする2つのパブリック関数(markdown.markdownおよびmarkdown.markdownFromFile)が用意されています。
一度に1つのドキュメントを処理している場合、これらの関数が必要に応じて機能します。
ただし、複数のドキュメントを処理する必要がある場合は、markdown.Markdownクラスの1つのインスタンスを作成し、複数のドキュメントを渡すと便利です。
1つのインスタンスを使用する場合は、resetメソッドを適切に呼び出すようにしてください(下記を参照)。

markdown.markdown (text [, **kwargs])

markdown.markdown関数では、次のオプション(引数)を使用できます。

  • text (必須):ソースのUnicode文字列。

    重要

    Python-Markdownは、入力としてUnicodeを想定しています(いくらかのシンプルなASCII文字列でも動作するかもしれません)、
    そしてUnicodeとして出力を返します。
    エンコードされた文字列を渡さないでください!
    あなたの入力が(UTF-8などのように)エンコードされている場合、それをデコードするのはあなたの責任です。
    例えば:

    input_file = codecs.open("some_file.txt", mode="r", encoding="utf-8")
    text = input_file.read()
    html = markdown.markdown(text)
    

    出力をディスクに書き込む場合は、自分でエンコードする必要があります。

    output_file = codecs.open("some_file.html", "w", 
                              encoding="utf-8", 
                              errors="xmlcharrefreplace"
    )
    output_file.write(html)
    
  • extensions: extensionsのリスト。

    Python-Markdownは、第三者が独自の追加や変更を構文に追加してパーサーに拡張機能extensionsを記述するためのAPIを提供します。
    一般的に使用されるいくつかのextensionsが、markdownライブラリに付属しています。
    使用可能なextensionsのリストについては、extensionのドキュメントを参照してください。

    extensionsのリストは、extensionsのインスタンスおよび/またはextensionの名前を示す文字列を含むことができます。

    extensions=[MyExtension(), 'path.to.my.ext']
    

    注意

    好ましい方法は、extensionのインスタンスを渡すことです。
    文字列は、Extensionクラスを直接(コマンドラインまたはテンプレートから)インポートすることが不可能な場合にのみ使用してください。

    extensionのインスタンスを渡すときは、おのおののクラスのインスタンスはmarkdown.extensions.Extensionのサブクラスでなければならず、クラスインスタンスを開始するときはextension_configsキーワードを使用するのではなく、いくつかの設定オプション(configuration options)を定義すべきです。
    例えば:

    from markdown.extensions import Extension
    class MyExtension(Extension):
        # define your extension here...
    
    markdown.markdown(text, extensions=[MyExtension(option='value')])
    

    extension名が文字列として提供されている場合、そのextensionはPYTHONPATH上のPythonモジュールとしてインポート可能でなければなりません。
    Pythonのドット表記法がサポートされています。
    したがって、'extra' extensionをインポートするには、 extensions=['markdown.extensions.extra']とすることができます。

    さらに、名前にクラスを指定することもできます。 クラスは名前の末尾にあり、モジュールのコロンで区切られていなければなりません。

    したがって、このようなクラスをインポートする場合は、次のようにします。:

    from path.to.module import SomeExtensionClass
    

    名前付きextensionは次の文字列で構成されます。:

    "path.to.module:SomeExtensionClass"
    

    注意

    同じモジュール内で複数のextensionが定義されている場合は、クラス名を指定するだけで済みます。
    Python-Markdownに付属するextensionsには、クラス名を指定する必要はありません。
    そうすることで、パーサの動作には影響しません。

    extensionを名前(文字列)で読み込むときは、extension_configsキーワードを使用してextensionにコンフィギュレーションの設定を渡すことができます 。

    もまた参照

    extensionsを作成するための助けとして、Extension APIのドキュメントを参照してください。

  • extension_configs: extensionsのコンフィグ設定の辞書。

    すべてのコンフィギュレーション設定は、(文字列として)名前でロードされたextensionsにのみ渡されます。
    クラスのインスタンスとしてextensionsをローディングする時には、コンフィギュレーション設定は初期化時にクラスに直接渡される。

    注意

    好ましい方法は、extensionのインスタンスを渡すことです。
    extension_configsキーワードをまったく使用する必要はありません。
    詳細については、extensionsキーワードを参照してください。

    コンフィギュレーション設定の辞書は、次の形式である必要があります。

    extension_configs = {
        'extension_name_1': {
            'option_1': 'value_1',
            'option_2': 'value_2'
        },
        'extension_name_2': {
            'option_1': 'value_1'
        }
    }
    

    ヘルプに対して使われているextensionのドキュメントを参照してください。
    そのextensionのコンフィギュレーション設定を指定します。

  • output_format: 出力フォーマット。

    サポートされているフォーマットは:

    • "xhtml1": XHTML 1.x を出力 デフォルト
    • "xhtml5": HTML5のXHTMLスタイルタグを出力。
    • "xhtml": サポートされている最新バージョンのXHTML(現在のXHTML 1.1)を出力。
    • "html4": HTML4を出力。
    • "html5": HTML5のHTMLスタイルタグを出力。
    • "html": サポートされているHTMLの最新バージョン(現在HTML 4)を出力。

    値は、小文字でも大文字でもかまいません。

    警告

    より一般的なフォーマット("xhtml" or "html")として、その時点で意味がある場合、将来変化する可能性がある,より具体的なフォーマット("xhtml1", "html5", & "html4")を使う事が提案されます。

  • safe_mode: 生のHTMLを許可しません。

    警告

    "safe_mode`"は推奨されておらず、使われるべきではありません。

    BLEACHのような)HTMLサニタイザは、信頼できないユーザーによって提出されたmarkdownテキストに対応するためのより良い解決方法を与えます。

    import markdown
    import bleach
    html = bleach.clean(markdown.markdown(untrusted_text))
    

    詳細は、リリースノートを参照してください。

    受け入れられる値は次のとおりです。

    • False(デフォルト):生のHTMLは変更されずに渡されます。

    • replace:すべてのHTMLブロックをhtml_replacement_textに割り当てられたテキストに置き換えます。
      下位互換性を維持のため、safe_mode = Trueを設定すると、safe_mode = 'replace'と同じ効果が得られます。
      safe_mode = Truesafe_mode = 'replace'と同じ効果を持ちます。

      生のHTMLをデフォルト以外のものに置き換えるには、次のようにします。

      md = markdown.Markdown(safe_mode = 'replace'、 
                         html_replacement_text = ' -  RAW HTML NOT ALLOWED--')
      
    • remove:すべての生のHTMLは完全にテキストから取り除かれます。
      著者には警告はありません。

    • `escape':生のHTMLはすべてエスケープされ、文書に含まれます。

      たとえば、次のソースがあります。

      Foo <b>bar</b>.
      

      次のHTMLになります:

      <p>Foo &lt;b&gt;bar&lt;/b&gt;.</p>
      

    注意

    "safe_mode"はenable_attributes optionのデフォルト値も変更します。

  • html_replacement_text: テキストはsafe_modeがreplaceに設定された時に使われます。
    デフォルトは[HTML_REMOVED]です。

    Warning

    "html_replacement_text"は推奨されておらず、使われるべきではありません。
    詳細は、リリースノートを参照してください。

  • tab_length: ソースのタブの長さ。デフォルト:4

  • enable_attributes: 属性の変換を有効にします。
    デフォルトはTrue,もしsafe_modeが有効でないならその場合はFalseです。

    注意

    safe_modeはデフォルトを上書きするだけです。
    もしenable_attributes
    が明示的に設定されているなら、明示的な値は safe_modeに関係なく使用されます。
    けれども、これはあなたのドキュメントに信頼されないユーザのJavaScriptの注入を潜在的に許す事になります。

  • smart_emphasis: _connected_words_を知的に扱う。

  • lazy_ol: 順序付きリストの最初の項目の数値を無視します。
    デフォルト: True

    以下のリストが与えられます:

    4. Apples
    5. Oranges
    6. Pears
    

    デフォルトではmarkdownは最初の行が4から始まっている事実を無視して、HTMLリスト項目を1から始めます。
    もし、lazy_olFalseに設定されているなら、markdownのHTML出力は次のようになるでしょう:

    <ol start="4">
      <li>Apples</li>
      <li>Oranges</li>
      <li>Pears</li>
    </ol>
    

訳者による蛇足

markdown.markdownFromFile (**kwargs)

いくつかの例外を除いて、 markdown.markdownFromFilemarkdown.markdownと同じオプションを受け付ける。
text引数(またはUnicodeの)文字列は受け入れませんが、かわりに次の必須のオプションを受け付ける。
代わりに、次の必須オプションを受け入れます。

  • input (必須): ソーステキストファイル。

    input は3つのオプションのうちの1つを設定します:

    • ファイルシステム上の読み取り可能なファイルへのパスを含む文字列,
    • 読み取り可能なfile-like object,
    • もしくは None (デフォルト) これはstdinから読み込みます。
  • output: 出力が書き込まれるターゲット。

    output は3つのオプションのうちの1つが設定できます:

    • ファイルシステム上の書き込み可能ファイルへのパスを含む文字列,
    • 書き込み可能なfile-like object,
    • もしくは None (デフォルト) stdoutへ書き込みます。
  • encoding: ソーステキストファイルのエンコーディング。 デフォルトは "utf-8"。inputとoutput に対して常に同じエンコーディングが使われます。 xmlcharrefreplaceエラーハンドラは、出力をエンコードする際に使用されます。

    注意

    これは、Python-MarkdownにおいてUnicodeのデコードとエンコードを指定する唯一の場所です。
    このやや素朴な解決策(naive solution)が あなたの具体的な必要としている用途に沿わないなら、エンコード/デコードの用途に沿う処理をする独自のコードを書くことをお勧めします


訳者による蛇足

markdown.Markdown ([**kwargs])

クラスが初期化時にソーステキスト文字列を受け取らない事を除いて、markdown.Markdownクラスを初期化するときにもmarkdown.markdown関数と同じオプションが利用できます。
むしろ、ソーステキスト文字列を2つのインスタンスメソッドのいずれかに渡す必要があります。

  • Markdown.convert(source)

    sourceテキストはmarkdown.markdown関数のtext引数と同じ要件を満たさなければなりません。

    複数のテキストを、おのおののテキストに対して新しいインスタンスを作成する事なしに処理したいなら、このメソッドを使うべきです。

    md = markdown.Markdown()
    html1 = md.convert(text1)
    html2 = md.convert(text2)
    

    どのオプションおよび/またはextensionsが使用されているかに応じて、パーサは、
    convert関数への各呼び出しの間に状態をリセットする必要があります。
    さもないと、パフォーマンスが大幅におちる可能性があります。

    html1 = md.convert(text1)
    md.reset()
    html2 = md.convert(text2)
    

    より簡潔に記述するために、resetをメソッドチェインして使う事もまたできる:

    html3 = md.reset().convert(text3)
    
  • Markdown.convertFile(**kwargs)

    このメソッドの引数はmarkdown.markdownFromFile関数の同名の引数(input,output,encoding)と同じです。
    convertと同様に、おのおののドキュメントのためにクラスの新しいインスタンスを作成する事なしに、複数のファイルを処理するためにこのメソッドが使われるべきです。
    convertの場合のように、状態はおのおののconvertFileの呼び出しの間にresetされる必要があります。


訳者による蛇足

safe_modeenable_attributes

safe_modeenable_attributesの意味がよくわからなかったので、ググってみると

どうやらXSSの脆弱性対策のためのオプションらしい。

XSS(クロスサイトスクリプティング)

XSSによる脆弱性とは

静的ページでのmarkdownをhtmlに変換して表示するのは問題ないが、ユーザから入力されたmarkdownテキストを自動的にHTMLに変換して表示させるWebサイトを構築したとすると、markdownテキストにJavaScriptのコードが埋め込まれた(JavaScriptインジェクション)入力を受け取る可能性がある。
これmarkdownテキストをそのままhtmlに変換して表示してしまうと不正なJavaScriptのコードを実行させられてしまう。
これを防ぐためにはsafe_modeというオプションがあってサニタイジング等の処理をおこなってくれるらしい。

HTMLサニタイズ

しかし、safe_modeは非推奨であって、別途、BLEACHなどのHTMLサニタイズするライブラリを使って自前でHTMLサニタイズを行ったほうがいいらしい。
enable_attributessafe_modeと関係あるらしいのだがようわからん。

BLEACH

BLEACHというのは

HTMLパーサー

余談ではあるがHTMLパーサーというのがあって

BeautifulSoup

pythonではBeautifulSoupというHTMLパーサーが有名らしい。

smart_emphasis

smart_emphasisというのは、_によるemタグへの変換を単語の区切りかどうかを自動的に判断してより賢くおこなってくれるという事らしい。
smart_emphasisがFalseになっていると、単純に単語の区切りは無視して_が現れてから次の_までをemphasis(emタグに変換)するようだ。

import markdown

markdon_text='it is _connected_words_ or _connected_words_long_time_ for me'
print markdown.markdown(markdon_text)
print markdown.markdown(markdon_text,smart_emphasis=False);

実行結果

<p>it is <em>connected_words</em> or <em>connected_words_long_time</em> for me</p>
<p>it is <em>connected</em>words<em> or </em>connected<em>words</em>long<em>time</em> for me</p>

naive solution

naive solutionという文言をどう訳せばよいか迷ってしまったので

ページのトップへ戻る