Я активно использую на этом сайте и паре других проектов markdown разметку для написания текста, а потом генерирую из него html код. И в итоге я написал пару расширений, которые выполняют кое-какой специфичный функционал, который несколько облегчает поддержку генерирования html кода на моих проектах.
К примеру в одном из проектов в текст добавляются изображения, которые добавлены на сайт и прикреплены к посту. Соответственно, у изображений есть какой специфический url, по которому nginx отдаёт это изображение. Но я сделал так, что markdown код вставки изображения выглядить более просто для изображений, которые загружены на сайт.
Описание кода вставки изображения
То есть код вставки изображения в данном случае выглядит так
![](e272ed2bca9e46e8b017c20eddd1e5b2.webp)
В данном коде есть только имя файла изображения e272ed2bca9e46e8b017c20eddd1e5b2.webp . На том проекте, где это реализовано все изображения загружаются на одну директорию с уникальным генерированным именем с помощью uuid, а также изображение сжимается и конвертируется в формат WEBP. Подробнее вы можете ознакомиться, как это сделать в статье Как конвертировать изображение в формат WEBP при сохранении в ImageField .
Так вот, когда изображения прикреплены к посту, они на том проекте отображаются в виде галереии под текстом, но могут быть добавлены и внутрь текста поста. Но чтобы не смущать пользователей длинным url к изображению в markdown разметке, а также упростить дальшейшую потенциальную модификацию путей к изображению, был реализован функционал по генерированию html тега img из этого упрощённого кода изображения.
Добавление python markdown расширения
Генерирование html текста с помощью python markdown
Для генерирования HTML используется пакет Python-Markdown. Код генерироваия может выглядеть следующим образом:
def generate_html(markdown_text): return markdown.markdown( markdown_text, extensions=['markdown.extensions.attr_list', 'markdown.extensions.tables', 'markdown.extensions.fenced_code', 'markdown.extensions.nl2br', 'markdown.extensions.toc'], output_format='html5' )
Как видите, при генерировании возможно перечислить расширения, которые могут влиять на результат генерирования кода. Имеено в эти расширения мы и будем добавлять наше расширение.
Добавляем расширение
Допустим в проекте на Django у нас есть app с названием core. Создадим внутри него каталог extensions с __init__.py файлом, который инициализует каталог как пакет, а также файл с названием расширения. Это должно выглядеть следующим образом.
-
core/
-
extensions/
- __init__.py
- image.py
-
extensions/
Файл Image.py
А теперь добавим содержимое файла image.py .
# -*- coding: utf-8 -*- import markdown from markdown.util import etree class ImageExtension(markdown.Extension): def add_inline(self, md, name, klass, re): pattern = klass(re) pattern.md = md pattern.ext = self md.inlinePatterns.add(name, pattern, "<reference") def extendMarkdown(self, md, md_globals): self.add_inline(md, 'internal_image', InternalImage, r'!\[\]\((?P<internal_image>[a-zA-Z0-9]+).webp\)') class InternalImage(markdown.inlinepatterns.Pattern): def handleMatch(self, m): return render_image(m.group('internal_image')) def render_image(internal_image_name): img = etree.Element('img') img.set('src', '/media/photos/{}.webp'.format(internal_image_name)) img.set('class', 'd-block mx-auto mw-100 mvh-75') return img def makeExtension(**kwargs): return ImageExtension(**kwargs)
В данном случае мы создаём расширение
ImageExtension
, которое расширяет
Markdown
разметку с помощью шаблона
InternalImage
.
Данный шаблон применяется ко всем тегам изображения, которые соответствуют регулярному выражению, которое передаётся в метод add_inline, который в итоге добавляет шаблон в список шаблонов с обработчиком кода markdown.
Функция makeExtension вызывается под капотом Python-Markdown и регистрирует расширение.
Заключение
В качестве заключительного слова добавим ваше новое расширение в генерирование фашего html кода.
def generate_html(markdown_text): return markdown.markdown( markdown_text, extensions=['core.extensions.image', 'markdown.extensions.attr_list', 'markdown.extensions.tables', 'markdown.extensions.fenced_code', 'markdown.extensions.nl2br', 'markdown.extensions.toc'], output_format='html5' )
Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку:
подменять ее на свою типа:
Добрый день.
Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup