首页 > 解决方案 > 我可以在 Python Markdown 中将标签列入白名单吗?

问题描述

问题

我想在转换期间指定要列入白名单的标签列表。例如,如果我只想转换<p><ol><li>和其他几个标签,而忽略所有其他标签,则给出如下值:

### Header

This is a paragraph.

    # Code snippet
    def spam():
        pass

1. One
2. Two
3. Three

我希望将其准确转换为:

### Header

<p>This is a paragraph.</p>

    # Code snippet
    def spam():
        pass

<ol>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
</ol>

我意识到我可以使用Bleach清除我不想要的标签,但如果可能的话,我宁愿不首先转换它们。

笔记:

我指的是https://pypi.org/project/Markdown/

标签: pythonmarkdown

解决方案


不,您不能将标签“列入白名单”,但您可以使用扩展 API来更改解析器的各个部分。但是,您可能并不真的想要那样。

例如,如果您不想解析标头和代码块,则可以删除这些处理器:

from markdown.extensions import Extension

class MyExtension(Extension):
    def extendMarkdown(self, md):
        md.parser.blockprocessors.deregister('hashheader')
        md.parser.blockprocessors.deregister('setextheader')
        md.parser.blockprocessors.deregister('code')

但是,这不会为您提供所需的结果,因为解析器将退回到将该文​​本包装在<p>标签中。事实上,这是 Markdown 语法所固有的。任何未被识别为其他内容的内容都被视为段落。

因此,您的输入可能会导致以下输出:

<p>### Header</p>

<p>This is a paragraph.</p>

<p>    # Code snippet
    def spam():
        pass</p>

<ol>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
</ol>

更复杂的是 HTML 对“无关紧要的空白”的处理。具体来说,除非直接指示不要(例如在代码块中),否则在浏览器中呈现 HTML 时,所有空格都会压缩为一个空格。因此,包含未解析代码块的段落将相当难以阅读:

# 代码片段 def spam(): pass

如果这不是您想要的,那么您可能需要用您自己的自定义处理器替换现有处理器,这些处理器识别代码块和标头,但返回默认 HTML 以外的其他内容,以避免它们被包装在<p>标签中。但是,这将有效地涉及替换大部分解析器。

此外,不包含在任何标签中,纯文本将全部压缩成一个段落。例如,这个输入:

# Header 1

    # code snippet
    def spam():
        pass

## Header 2

会像这样呈现:

# Header 1 # 代码片段 def spam(): pass ## Header 2

这可能不是你想要的。将文本包装在<p>标签中实际上是一个更理想的结果,因为这至少会呈现为:

# 标题 1

# 代码片段 def spam(): pass

## 标题 2

顺便说一句,这就是 Markdown 解析器不提供“白名单”选项的原因。结果永远不是那些想要选择的人所期望的。

全面披露:我是 Python-Markdown 项目的首席开发人员。


推荐阅读