@ 2015-10-21 @ 17:32
Комментирование в markdown и однострочниках bash файлов
LUKE: Is Perl better than Python?
YODA: No... no... no. Quicker, easier, more seductive.
LUKE: But how will I know why Python is better than Perl?
YODA: You will know. When your code you try to read six months from now.
(c) Хороший код (и хороший текст) всегда должен быть откомментирован. В последнее время я много пишу на markdown'не, который по ходу дела обрабатывается pandoc'ом и sed'ом, причем все это сведено в один makefile, который со временем разрастается до довольно больших размеров.
читать дальше в wordpress Как проставить комментарии в маркдауне? Вопрос нетривиальный.
Конечно, можно сделать это с помощью html:
Однако, читается он плохо, в нем сложно делать моделайны для vim и - самое нехорошее - это то, что он проскакивает сквозь парсер и остается в тексте - а комментарии должны убираться уже на стадии конверсии. В этом плане мне гораздо больше понравился другой вариант, со
стековерфлоу:
[//]: # ( Это комментарий! )
[//]: # ( vim: set ft=book conceallevel=2 go-=m go-=T go-=r go-=L go-=e foldlevel=2 comments=:% : )
- комментарии в башевских однострочниках
Еще
интересный вариант - когда комментирование должно приходится рядом с однострочником или длинным-длинным конвейером на bash или sed.
Например, в процессе расчистки того, что получается на выходе после преобразования ipython -> markdown -> html я использую такой вот однострочник:
#!/bin/bash
# зачистка html
filename=$@
cat -s "${filename}" | sed 's-\(
]*\)\(/>\)-\1 width="99.99%" height="auto" \2-' | sed 's+\(++' | sed 's+
png
++' | sed 's+\[<matplotlib.*\]++' | sed 's+\<matplotlib.colorbar.*;++' > "${filename}.clean.html"
Он убирает мусор, который получается при конвертировании из ipynb в markdown и подгоняет формат так, чтобы он "лег" в методичку (дальше в игру вступает составной odm-документ, к которому коннектится полученный html, но это - отдельная история).
Менять такой однострочник тяжело - все быстро забывается. Первое, что приходит в голову - разбить его построчно. Длинную строку в баше можно разбить, перенося отдельные строки с помощью обратного слэша (\). И скрипт сразу становится понятнее - по крайней мере визуально.
#!/bin/bash
# зачистка html
filename=$@
cat -s "${filename}" |
sed 's-\(
]*\)\(/>\)-\1 width="99.99%" height="auto" \2-' \
| sed 's+\(++' \
| sed 's+
png
++' \
| sed 's+\[<matplotlib.*\]++' \
| sed 's+\<matplotlib.colorbar.*;++' \
> "${filename}.clean.html"
Примерно так же я поступил, когда написал
большой скрипт для развертывания openbox'а - там длинный инсталл тоже разбит на разные строки, хотя по сути представляет собой одну длинную строку.
Уже лучше. Но все равно - хочется хоть каких-нибудь пояснений.
Оказывается, код в bash можно разбивать не только обратными слэшами, но вполне допустимо разнести код по пайпам (то есть символ ковейера | сам по себе работает как разбиватель строки), при этом ничего дополнительно не нужно переносить - баш понимает это сам. При этом сразу после пайпа можно указывать коммментарий:
#!/bin/bash
# зачистка html
filename=$@
cat -s "${filename}" | # убираем лишние пробельные строки
sed 's-\(
]*\)\(/>\)-\1 width="99.99%" height="auto" \2-' | # приводим в чувство ширину картинок
sed 's+\(++' | # надоедливый коммент в libreoffice
sed 's+
png
++' | # убираем хвосты ipnb... ->
sed 's+\[<matplotlib.*\]++' |
sed 's+\<matplotlib.colorbar.*;++' \
> "${filename}.clean.html"
Это очень просто и хорошо в случае, когда однострочник представляет собой конвейер текстовой обработки - тогда его легко разнести по пайпам - один проход конвейера на одну строку. Но длинный однострочник может быть не только конвейером.
Для этого можно использовать еще один способ:
...
sed 's+
png
++' `# убираем хвосты ipnb...` |
...
Двойные бэктики (backticks) в bash-скрипте истолковываются как
"вставить на это место результат команды, выполненной в шелле". А результатом команды, которая начинается на # - как раз будет комментарий, то есть
`# убираем хвосты ipnb...`
Не вернет вообще ничего. Это позволяет комментировать все, что угодно - особенно удобно это в многострочниках, которые не есть конвейеры.
Вот как у меня инсталлируется "вторая очередь системы" - программы которые не самые важные и которые ставятся по принципу "когда дойдут руки".
Если взять этот однострочник as is - получится такая вот длинная "колбаса":
#!/bin/bash
sudo apt-get install okular okular-extra-backends recoll antiword catppt djvutxt lyx pstotext unrtf untex wpd2html xls2csv python-chm python-midiutil python-mutagen libimage-exiftool-perl
Если разнести "колбасу" по строкам - получится гораздо лучше:
#!/bin/bash
sudo apt-get install \
okular okular-extra-backends \
recoll \
antiword catppt djvutxt lyx pstotext \
unrtf untex wpd2html xls2csv \
python-chm python-midiutil python-mutagen libimage-exiftool-perl
А теперь откомментируем ее "бэктиковыми" комментариями:
#!/bin/bash
sudo apt-get install `# установка софта второй очереди` \
okular okular-extra-backends `# ставим okular и бэкэнды к нему` \
recoll `# десктопный поисковик ` \
antiword catppt djvutxt lyx pstotext `# конвертеры к recoll'у ` \
unrtf untex wpd2html xls2csv `# еще конвертеры к recoll'у ` \
python-chm python-midiutil python-mutagen libimage-exiftool-perl # просто нужные дополнения
Я не очень старался соблюдать принцип понятности - поскольку случай тривиальный, но как по мне тако скрипт выглядит гораздо читабельнее и юзабельнее, чем просто длинная колбаса.