66128


こんにちは。  
PythonのmarkdownモジュールでMarkdownをHTMLに変換しようとしています。  
しかし、変換を実行すると、下記の実行結果のように行頭のスペースが削除されてしまい、困っています。  
何かよい方法はないでしょうか。  
もしくは代替えとなりそうなモジュールがあれば、教えていただけますと幸いです。  
環境は、Windows10 64ビット、Python 3.7です。

## 変換用のソースコード

[code]

    import markdown, sys
    from markdown.extensions.toc import TocExtension
    from os import path
    
    if len(sys.argv) != 2:
        print("変換するファイルを指定してください。")
        sys.exit()
    
    input_file = sys.argv[1]
    if not path.exists(input_file) or not path.isfile(input_file):
        print("指定されたファイルが見つかりません。")
        sys.exit()
    
    with open(input_file, "r", encoding="utf-8") as f:
        data = f.read()
    
    md = markdown.Markdown(extensions=['extra', TocExtension(toc_depth="2-6"), 'tables'])
    print(md.convert(data))
    
[/code]

## 実行方法

[code]

    convert.py input.md>output.html
    
[/code]

## 変換元のMarkdown

[code]

    # テストページ
    
    ## 目次
    
    [TOC]
    
    ## 見出し1
    
    　これは、テストページです。
    
    ## 見出し2
    
    　これは、テストページです。
    
[/code]

## 実行結果

[code]

    <h1>テストページ</h1>
    <h2 id="_1">目次</h2>
    <div class="toc">
    <ul>
    <li><a href="#title">title: テストページ</a></li>
    <li><a href="#_1">目次</a></li>
    <li><a href="#1">見出し1</a></li>
    <li><a href="#2">見出し2</a></li>
    </ul>
    </div>
    <h2 id="1">見出し1</h2>
    <p>これは、テストページです。</p>
    <h2 id="2">見出し2</h2>
    <p>これは、テストページです。</p>
    
[/code]

* * *

以上、よろしくお願いいたします。


CC BY-SA 4.0
2020-04-29T14:15:30.677
66122
2020-04-29T17:31:07.210
2020-04-29T14:32:00.133
3060
29034
question
python markdown
PythonのMarkdownモジュールで行頭のスペースが削除されるのを防ぐ方法


Markdownでは行頭の空白が無視されるので、代わりに `&nbsp;` を入力しておくのはどうですか？


CC BY-SA 4.0
2020-04-29T14:25:29.857
66123
2020-04-29T14:25:29.857
3060
66122
answer


行頭のスペースが削除されてしまうのは、[markdown/blockprocessors.py](https://github.com/Python-
Markdown/markdown/blob/master/markdown/blockprocessors.py#L592) で `lstrip()`
を実行しているためです。

[code]

    class ParagraphProcessor(BlockProcessor):
        """ Process Paragraph blocks. """
                   :
        def run(self, parent, blocks):
                   :
    
                # Create a regular paragraph
                p = etree.SubElement(parent, 'p')
                p.text = block.lstrip()
    
[/code]

markdown module では以下の様に HTML タグ別に parser を登録しています。

[markdown/blockprocessors.py](https://github.com/Python-
Markdown/markdown/blob/master/markdown/blockprocessors.py#L54)

[code]

    def build_block_parser(md, **kwargs):
        """ Build the default block parser used by Markdown. """
        parser = BlockParser(md)
                   :
        parser.blockprocessors.register(ParagraphProcessor(parser), 'paragraph', 10)
        return parser
    
[/code]

つまり、parser を入れ替える事が可能で、具体的には以下の様にします。

[code]

    import markdown, sys
    from markdown.extensions.toc import TocExtension
    from markdown.util import etree
    from os import path
    
    class _ParagraphProcessor(markdown.blockprocessors.BlockProcessor):
        """ Process Paragraph blocks. """
    
        def test(self, parent, block):
            return True
    
        def run(self, parent, blocks):
            block = blocks.pop(0)
            if block.strip():
                if self.parser.state.isstate('list'):
                    sibling = self.lastChild(parent)
                    if sibling is not None:
                        # Insetrt after sibling.
                        if sibling.tail:
                            sibling.tail = '%s\n%s' % (sibling.tail, block)
                        else:
                            sibling.tail = '\n%s' % block
                    else:
                        # Append to parent.text
                        if parent.text:
                            parent.text = '%s\n%s' % (parent.text, block)
                        else:
                            parent.text = block.lstrip()
                else:
                    # Create a regular paragraph
                    p = etree.SubElement(parent, 'p')
                    ## Do not delete the spaces at the beginning of a line
                    p.text = block
    
    if __name__=='__main__':
    
        if len(sys.argv) != 2:
            print("変換するファイルを指定してください。")
            sys.exit()
    
        input_file = sys.argv[1]
        if not path.exists(input_file) or not path.isfile(input_file):
            print("指定されたファイルが見つかりません。")
            sys.exit()
    
        with open(input_file, "r", encoding="utf-8") as f:
            data = f.read()
    
        md = markdown.Markdown(extensions=['extra', TocExtension(toc_depth="2-6"), 'tables'])
        ## Remove orignal processor
        md.parser.blockprocessors.deregister('paragraph')
        ## Register new processor
        md.parser.blockprocessors.register(_ParagraphProcessor(md.parser), 'paragraph', 10)
    
        print(md.convert(data))
    
[/code]


CC BY-SA 4.0
2020-04-29T17:03:47.503
66128
2020-04-29T17:03:47.503
66122
answer


Markdown で行頭のスペースが無くなるのは Markdown の想定挙動です（全角スペースでも除去すべきかは議論が分かれるところですが、たとえば
CommonMark は除去します）。また仮にスペースが削除されなかったとしても HTML としてレンダリングされる際に意味が無くなってしまいます。

もしこれが段落始めの字下げなのであれば、スペースで字下げするのではなく CSS の `text-indent`
でスタイルを後から付けて字下げするのは如何でしょうか。


CC BY-SA 4.0
2020-04-29T17:31:07.210
66129
2020-04-29T17:31:07.210
19110
66122
answer