[英]How do I get python-markdown to additionally “urlify” links when formatting plain text?
[英]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 语法更严格一些。 例如,虽然这不是必需的,但推荐的语法是始终在块引用中的尖括号后插入一个空格。 更改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.