Evgenii Legotckoi
Evgenii Legotckoi16 травня 2023 р. 15:52

Django - Урок 064. Як написати розширення для Python Markdown

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

Файл 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'
            )
Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

ИМ
  • 05 жовтня 2024 р. 07:51
  • (відредаговано)

Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку:

<ul>
    <li></li>
    <li></li>
</ul>

подменять ее на свою типа:

<ul class='my_ul_class'>
    <li class='my_li_class'></li>
    <li class='my_li_class'></li>
</ul>
Evgenii Legotckoi
  • 31 жовтня 2024 р. 14:37

Добрый день.
Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
Ua

Qt - Тест 001. Сигналы и слоты

  • Результат:84бали,
  • Рейтинг балів4
Ua

Qt - Тест 001. Сигналы и слоты

  • Результат:42бали,
  • Рейтинг балів-8
ОК

Qt - Тест 001. Сигналы и слоты

  • Результат:47бали,
  • Рейтинг балів-6
Останні коментарі
ИМ
Игорь Максимов22 листопада 2024 р. 11:51
Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii Legotckoi31 жовтня 2024 р. 14:37
Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZE19 жовтня 2024 р. 08:19
Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов05 жовтня 2024 р. 07:51
Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas505 липня 2024 р. 11:02
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Тепер обговоріть на форумі
Дмитрий
Дмитрий03 лютого 2025 р. 06:24
Создание deb-пакета. Как создать ярлык на рабочем столе после установки собственного deb-пакета? Всем привет. Сделал свой deb-пакет с программой. Всё устанавливается и работает. Ставлю по пути /usr/bin/my_application. Как для пользователя при установке пакета сразу создать ярлык на раб…
NW
Nayo Wai30 січня 2025 р. 09:22
не запускается компьютер!!! Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
n
nkly03 січня 2025 р. 02:52
Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
M
Marsel16 серпня 2023 р. 14:26
OAuth2.0 через VK, получение email Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.
Evgenii Legotckoi
Evgenii Legotckoi24 червня 2024 р. 15:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.

Слідкуйте за нами в соціальних мережах