Я активно використовую на цьому сайті і кілька інших проектів 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