Замените теги заголовков Markdown пользовательскими в Python Markdown

#python #markdown #python-markdown

#python #markdown #python-markdown

Вопрос:

Мы хотим заменить h теги по умолчанию, введенные markdown с помощью # , пользовательским тегом HTML. Для преобразования Markdown в HTML мы используем библиотеку Python Markdown.

Мы пытались зарегистрировать расширение, которое использует регулярное выражение H1. Это расширение использует регулярное выражение (#) (.*) для обнаружения элементов H1.

 import markdown
from markdown.extensions import Extension
from markdown.inlinepatterns import SimpleTagPattern

class CustomHeadings(Extension):
    def extendMarkdown(self, md, md_globals):
        H1_RE = r'(#) (.*)'

        h1_tag = SimpleTagPattern(H1_RE, 'span class="h1"')
        md.inlinePatterns['h1'] = h1_tag

md_extensions = [CustomHeadings()]

# [...]

def ds_custom_markdown_parse(value):
    return markdown.markdown(value, extensions=md_extensions)
  

Мы хотим иметь h{1-6} элементы в виде span class="h{1-6}" . Но анализатор Markdown по-прежнему сопоставляет строку # This is a h1 с <h1>This is a h1</h1> . Мы ожидаем, что результат будет <span class="h1">This is a h1</span>

Комментарии:

1. Это совершенно не так, и вы можете не контролировать это, но использование реальных <h1> тегов etc. объективно значительно лучше , чем использование <span class="h1"> etc. Важна семантика. Причин много, но доступность, вероятно, самая большая.

2. @Chris мы рассмотрели это, потому что это намного проще реализовать и так далее, Но мы решили сделать это другим способом по таким причинам, как только один H1 на страницу или чтобы пользовательский контент не мешал нашим собственным усилиям.

Ответ №1:

Заголовки являются элементами уровня блока и, следовательно, не анализируются inlinePatterns. перед запуском inlinePatterns , Python-Markdown запускает BlockParser, который преобразует все элементы уровня блока документа в объект ElementTree. Затем каждый элемент уровня блока передается через inlinePatterns по одному за раз, и анализируются элементы уровня диапазона.

Например, учитывая ваш заголовок # This is a h1 , BlockParser уже преобразовал его в тег H <h1>This is a h1</h1> , и inlinePatterns видят только текстовое содержимое этого тега This is a h1 .

У вас есть несколько вариантов решения этой проблемы:

  1. Вы могли бы переопределить BlockProcessor s, которые анализируют заголовки, чтобы они создавали нужные вам элементы с самого начала.
  2. Или вы могли бы оставить существующий анализатор блоков на месте и создать TreeProcessor, который выполняет пошаговый анализ завершенного объекта ElementTree и изменяет элементы, переопределяя имена тегов в соответствующих элементах.

Вариант 2 должен быть намного проще и, по сути, является методом, используемым несколькими существующими расширениями.

Полное раскрытие информации: Я являюсь ведущим разработчиком проекта Python-Markdown.