Evgenii Legotckoi
Evgenii Legotckoi17 мая 2023 г. 1: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 хостинг.

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Lz

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:70баллов,
  • Очки рейтинга1
РК

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

  • Результат:84баллов,
  • Очки рейтинга4
ВМ

C++ - Тест 001. Первая программа и типы данных

  • Результат:80баллов,
  • Очки рейтинга4
Последние комментарии
k
kmssr8 февраля 2024 г. 18:43
Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко5 февраля 2024 г. 1:50
Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 декабря 2023 г. 10:30
Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 декабря 2023 г. 8:38
Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik18 декабря 2023 г. 21:01
Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Сейчас обсуждают на форуме
NSProject
NSProject23 июня 2024 г. 13:48
добавить qlineseries в функции А куда собстаенно делся Евгений раз на сайте такой бордак творится?
BlinCT
BlinCT5 мая 2024 г. 5:46
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
Evgenii Legotckoi
Evgenii Legotckoi2 мая 2024 г. 14:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
IscanderChe
IscanderChe30 апреля 2024 г. 4:22
Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…
G
Gar22 апреля 2024 г. 5:46
Clipboard Как скопировать окно целиком в clipb?

Следите за нами в социальных сетях