繁体   English   中英

Python-Markdown 可以支持图像板样式的链接吗?

[英]Can Python-Markdown support imageboard-style links?

我想向 Python-Markdown 添加一个额外的语法:如果n是正数 integer, >>n应该扩展为<a href="#post-n">n</a> (双尖括号 ( >> ) 是在图像板论坛中创建链接的常规语法。)

默认情况下,Python-Markdown 将>>n扩展为嵌套的块引用: <blockquote><blockquote>n</blockquote></blockquote> 有没有办法从>>n创建链接,同时保留 blockquote 的默认行为 rest? 换句话说,如果x是一个正数 integer, >>x应该扩展成一个链接,但如果x不是一个正数 integer, >>x应该仍然扩展成嵌套的块引用。

我已经阅读了相关的维基文章: Tutorial 1 Writing Extensions for Python Markdown 根据我在 wiki 中学到的知识,我编写了一个自定义扩展:

import markdown
import xml.etree.ElementTree as ET
from markdown.extensions import Extension
from markdown.inlinepatterns import Pattern


class ImageboardLinkPattern(Pattern):
    def handleMatch(self, match):
        number = match.group('number')
        # Create link.
        element = ET.Element('a', attrib={'href': f'#post-{number}'})
        element.text = f'>>{number}'
        return element


class ImageboardLinkExtension(Extension):
    def extendMarkdown(self, md):
        IMAGEBOARD_LINK_RE = '>>(?P<number>[1-9][0-9]*)'
        imageboard_link = ImageboardLinkPattern(IMAGEBOARD_LINK_RE)
        md.inlinePatterns['imageboard_link'] = imageboard_link


html = markdown.markdown('>>123',
                         extensions=[ImageboardLinkExtension()])
print(html)

但是, >>123仍然生成<blockquote><blockquote>123</blockquote></blockquote> 上面的实现有什么问题?

问题是您的新语法与先前存在的 blockquote 语法冲突。 如果您的扩展程序被调用,它可能会起作用。 然而,由于冲突,这从未发生过。 请注意,它们有五种类型的处理器。 记录在案

  • 预处理器在将源传递给解析器之前更改源。
  • 块处理器处理由空行分隔的文本块。
  • Tree Processors 修改构造的 ElementTree
  • 内联处理器是内联元素的常见树处理器,例如*strong*
  • 解析器的 output 在返回之前的后处理器 munge。

这里重要的是处理器按该顺序运行。 换句话说,所有块处理器都在运行任何内联处理器之前运行。 因此,blockquote 块处理器首先在您的输入上运行并删除双尖括号,将行的 rest 包装在双blockquote标记中。 当您的内联处理器看到文档时,您的正则表达式将不再匹配,因此永远不会被调用。

也就是说,内联处理器是实现链接语法的正确方法。 但是,您需要执行以下两项操作之一才能使其正常工作。

  1. 改变语法,使其不与任何先前存在的语法冲突; 或者
  2. 更改 blockquote 行为以避免冲突。

就我个人而言,我会推荐选项 1,但我知道您正在尝试从另一个环境中实现预先存在的语法。 所以,如果你想探索选项 2,那么我建议也许使 blockquote 语法更严格一些。 例如,虽然这不是必需的,但推荐的语法是始终在块引用中的尖括号后插入一个空格。 更改BlockquoteProcessor以要求空间应该相对简单,这将导致您的语法不再冲突。

这实际上很简单。 您可能会注意到,整个语法是通过一个相当简单的正则表达式定义的:

RE = re.compile(r'(^|\n)[ ]{0,3}>[ ]?(.*)')

您只需要重写它,以便不再接受 0 个空格( >而不是>[ ]? )。 首先导入现有处理器并将其子类化,然后覆盖正则表达式:

from markdown.blockprocessors import BlockquoteProcessor

class CustomBlockquoteProcessor(BlockquoteProcessor):
    RE = re.compile(r'(^|\n)[ ]{0,3}> (.*)')

最后,您只需告诉 Markdown 使用您自定义的 class 而不是默认值。 将以下内容添加到ImageboardLinkExtension class 的extendMarkdown方法中:

md.parser.blockprocessors.register(CustomBlockQuoteProcessor(md.parser), 'quote', 20)

现在 blockquote 语法将不再与您的链接语法冲突,您将有机会在文本上运行您的代码。 请注意始终为任何实际块引用包含现在所需的空间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM