TL;DR: Как запостить Markdown пост с примерами кода (и картинками) в бложик, поддерживающий только HTML
# install using pip pip install -U markdown Pygments # or (on Debian based) sudo apt install python3-markdown python3-pygments edit post.md (echo '<style>'; pygmentize -S native -f html -a .codehilite; echo '</style>'; markdown_py post.md -x codehilite -x fenced_code ) > post.html
Вчера написал пост с заметками по ходу решения задач к Coq'Art. Начал я его писать как короткий комментарий в локальный tg чат с друзьями. Но сначала понял, что хочется поделиться на большую аудиторию (может кто прокомментирует чего полезного), поэтому решил запостить в point.im или juick.com в которые изредка что-то пишу, а потом, пока писал, обнаружил, что размер поста уже больше подходит для полноценного поста в бложек. На этом месте я вспомнил что у меня даже был такой).
Размечал текст я по привычке в Markdown - это очень простой, привычный мне формат, и он легко переделывается в другие вики разметки, поэтому я в нём часто пишу даже заметки рядом с кодом и пр. Ну и про поддержку в GitHub не забываем. Когда же я открыл blogspot, то обнаружил, что там только два варианта ввода разметки: HTML и их редактор. Поэтому пришлось вспоминать, как собирать из Markdown файлов HTML.
Припоминалось, что я уже этот вопрос как-то исследовал, но никаких заметок или следов этого обнаружить не удалось. Видимо слишком давно это было. Однако удалось вспомнить, что в прошлый раз я остановился на Python-Markdown. К тому же он уже оказался установлен (варианты см. в начале статьи). Так что решил попробовать по-быстрому заюзать его, и только если что-то не получится, то уже смотреть другие варианты.
Простого вызова markdown_py post.md -f post.html
уже бы хватило, если бы в посте не было вставок с кодом. Но т.к. они были, то сначала обнаружилось, что блоки в бэктиках
``` ```
это нестандартная фича, и весь код у меня слился с текстом.
Этот и следующий скриншоты - из Firefox'а в reader view, чтобы лишний раз в blogspot не лезть, но и чтобы от белого фона глаза не вытекали.
Картинки, к слову, в Markdown тоже можно вставлять, но надо сначала их куда-то захостить. Пока ручками сложил в Dropbox и воспользовался рецептом (поменять в публичной ссылке ?dl=0
на ?raw=1
), чтобы получить прямую ссылку на картинку. Надо попробовать перехостить всё это дело на GitHub Pages - там такой проблемы быть не должно, да и с форматированием меньше возни. Или как-нибудь автоматизировать заливку картинок.
Чтобы поправить отображение блоков с кодом, надо подключить (идущее в комплекте) расширение Fenced Code Blocks.
И, конечно, сходу нет никакой подсветки для блоков с кодом, поэтому надо ещё подключить расширение CodeHilite, которое тоже идёт в коробке, но зависит от библиотеки Pygments, которую надо ставить отдельно.
Т.о. получилась такая команда:
markdown_py post.md -x codehilite -x fenced_code -f post.html
Выглядит уже прилично, но код всё ещё не раскрашен. Это потому, что надо сгенерировать стили для Pygmets. Об этом написано в инструкции к CodeHilite:
pygmentize -S default -f html -a .codehilite > styles.css
Ну и вставил это дело в результирующий html максимально тупым способом:
(echo '<style>'; cat styles.css; echo '</style>'; markdown_py post.md -x codehilite -x fenced_code) > post.html
Уже совсем хорошо. Но когда запостил в blogspot, то понял, что фон явно указан белый.
Это уже скрин с blogspot, чтобы была понятна проблема.
Поглядел другие темы и выбрал native
. Окончательное решение одной командой приведено в начале статьи.
Выглядит так:
Пока писал этот пост ещё захотелось скриншоты выделить в рамку, чтобы с текстом не путались, и размер зафиксировать поменять. Поэтому решил добавить ещё кастомный CSS файлик с чем-то вроде
img { border: 1px solid darkgrey; width: 400px; }
Стиль рамки, правда в итоге чем-то переопределяется, ну да и чёрт с ним.
В целом, для первого подхода, этого должно бы уже хватить. Но я подумал, что стоит записать команды на память, чтобы для последующих постов, если такие будут, не вспомнить или не выискивать их в истории команд. А лучшая заметка - это исполняемый код! Соответственно рассмотрел два варианта: написать скрипт или пихнуть нужные команды в Makefile
. Т.к. если постов будет несколько, то прописывать каждый раз при генерации пути ко входу и выходу лень, и к тому же тут уже несколько ресурсов, то решил остановиться на втором варианте.
Сразу обнаружил, что мейком то я пользоваться, оказывается толком не умею. И пришлось долго читать ман и интернеты прежде чем у меня получилось его заставить выполнять одну и ту же команду на каждой паре *.md -> *.html
, но в итоге я написал вот такой Makefile
:
# задаём цель по умолчанию default: all # следующие цели - это не файлы .PHONY: all clean list-md-files list-html-files # получаем список Markdown файлов с помощью функции wildcard # см. https://www.gnu.org/software/make/manual/html_node/File-Name-Functions.html # '::=' - это полустандартное присваивание нерекурсивной переменной # см. https://www.gnu.org/software/make/manual/html_node/Flavors.html MD_FILES ::= $(wildcard *.md) # Строим по списку md файлов список html файлов. # Будем складывать их в ./out # patsubst делает замену по шаблону # см. https://www.gnu.org/software/make/manual/html_node/Text-Functions.html HTML_FILES ::= $(patsubst %.md,out/%.html,$(MD_FILES)) # команды для диагностики list-md-files: @echo $(MD_FILES) list-html-files: @echo $(HTML_FILES) # т.к. clean удаляет папку ./out полностью, то надо её пересоздавать out: mkdir -p out # стили для раскраски out/pygments.css: out pygmentize -S native -f html -a .codehilite > out/pygments.css # Самая магия. Не разобрался, как использовать тут MD_FILES и HTML_FILES, # чтобы для каждой пары md и html генерилось отдельное правило, # поэтому воспользовался шаблонами с %: # https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html # '$<' и '$@' - это "автоматические переменные" # https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html out/%.html: %.md out styles.css out/pygments.css ( echo '<style>'; cat styles.css out/pygments.css; echo '</style>'; \ markdown_py $< -x codehilite -x fenced_code ) > $@ # в текущей версии MD_FILES и HTML_FILES нужны только для того, # чтобы подвязать все цели по генерации html в all all: $(HTML_FILES) # чтобы точно не оставлять мусора (при удалении md файлов например) # удаляем папку ./out целиком clean: rm -rfv out
Теперь обновление html файлов делается с помощью команды make
(для генерации можно без аргументов). Как я написал в комментах, тут имеется раздражающее дублирование, и вообще я в make, как оказалось, не умею. Так что предложения, как это переписать получше, приветствуются.
стиль "img { width: 400px; }" мне очень классно поломал вёрстку на странице, поэтому дописал в квалификатор вперёд ещё ".post-body" и сразу ещё и стиль рамки починился)
ОтветитьУдалитьПо сути, получился практически готовый генератор статического блога. Но хостить блог самостоятельно - не очень благодарная затея. К тому же тогда придётся ещё изобретать навигацию, облако тэгов, и прикручивать комменты. И это всё вместе уже несколько более затратно
ОтветитьУдалить