Скрипты на bash — Скрипт для преобразования Сишных исходников в красиво оформленный PDF файл.
Возникла у меня потребность перевести много исходников, написанных на C, в PDF файл, чтобы все это потом можно было распечатать на принтере. Хотелось иметь возможность выбора размера шрифта, нумерацию строк и подсветку ключевых слов.
Задумка была осуществлена при помощи LaTeX’а и скрипта на bash’е. Скрипт принимает один обязательный параметр – размер шрифта; список параметров можно узнать запустив скрипт без параметров.
Работа самого скрипта довольно проста – формируется латеховский исходник и в него включаются все исходные файлы из текущего каталога, затем удаляются все временные файлы, созданные в процессе работы.
Основная сложность была в формировании красивых листингов в латехе. Для этого я использовал пакет listings, который, как известно, весьма плохо работает с русскими комментариями в юникоде – он попросту сливает русские слова между собой: /* этокомментарийдемонстрирующийнаглядновышеозвученнуюпроблему */. В документации по пакету (стр. 55) было приведено решение этой проблемы, но возникла другая – теперь комментарии обрабатываются непосредственно LaTeX’ом и соответственно в них не должно символов наподобие “creat_pckt()” или “”. Эту новую проблему я, к сожалению, решил лишь частично – заменил во всем тексте программы символ “_” на “–”. Остальные запрещенные символы приходится править руками. Если придумать, как заменить эти запрещенные символы на “съедобные” латехом, причем только в комментариях (наподобие /* */, комментарии могут быть как однострочными так и многострочными), то проблема будет полностью решена.
Но, в принципе, и без этого скрипт работает для меня более менее удовлетворительно. Привожу его код:
Задумка была осуществлена при помощи LaTeX’а и скрипта на bash’е. Скрипт принимает один обязательный параметр – размер шрифта; список параметров можно узнать запустив скрипт без параметров.
Работа самого скрипта довольно проста – формируется латеховский исходник и в него включаются все исходные файлы из текущего каталога, затем удаляются все временные файлы, созданные в процессе работы.
Основная сложность была в формировании красивых листингов в латехе. Для этого я использовал пакет listings, который, как известно, весьма плохо работает с русскими комментариями в юникоде – он попросту сливает русские слова между собой: /* этокомментарийдемонстрирующийнаглядновышеозвученнуюпроблему */. В документации по пакету (стр. 55) было приведено решение этой проблемы, но возникла другая – теперь комментарии обрабатываются непосредственно LaTeX’ом и соответственно в них не должно символов наподобие “creat_pckt()” или “”. Эту новую проблему я, к сожалению, решил лишь частично – заменил во всем тексте программы символ “_” на “–”. Остальные запрещенные символы приходится править руками. Если придумать, как заменить эти запрещенные символы на “съедобные” латехом, причем только в комментариях (наподобие /* */, комментарии могут быть как однострочными так и многострочными), то проблема будет полностью решена.
Но, в принципе, и без этого скрипт работает для меня более менее удовлетворительно. Привожу его код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
#!/bin/bash # Данный скрипт преобразует исходники из текущего каталога (*.c, *.h, Makefile) # в оформленный PDF файл, посредством LaTeX. # временный TeX файл TEMP=`pwd | xargs basename` TEMPTEX="$TEMP.tex" # вывод справки show_help() { echo -e "Usage: $0 [-t|-s|-f|-S|-n|-l|-L|-h|-H]\n\t-t\ttiny\n\t-s\tscriptsize\n\t-f\tfootnotesize\n\t-S\tsmall\n\t-n\tnormalsize\n\t-l\tlarge\n\t-L\tLarge\n\t-h\thuge\n\t-H\tHuge\n" exit 0 } # получаем обязательный параметр - размер шрифта if [ "$#" -ne 1 ]; then show_help fi while getopts ":tsfSnlLhH" OPTN; do case $OPTN in t) LETTER_SIZE='{\tiny ' ;; s) LETTER_SIZE='{\scriptsize ' ;; f) LETTER_SIZE='{\footnotesize ' ;; S) LETTER_SIZE='{\small ' ;; n) LETTER_SIZE='{\normalsize ' ;; l) LETTER_SIZE='{\large ' ;; L) LETTER_SIZE='{\Large ' ;; h) LETTER_SIZE='{\huge ' ;; H) LETTER_SIZE='{\Huge ' ;; "?") echo "$OPTARG - unknown option!" exit 1 ;; *) echo "Unknown error while processing options!" exit 1 ;; esac done echo "Creating temp LaTeX file: $TEMPTEX" cat << EOFHDL >> $TEMPTEX \documentclass[a4paper, 12pt, notitlepage]{report} \usepackage[bottom=2cm, top=1cm, left=3cm, right=1cm]{geometry} \usepackage[T2A]{fontenc} \usepackage{ucs} \usepackage[utf8x]{inputenc} \usepackage[english, russian]{babel} \usepackage{color} \usepackage{listings} \lstloadlanguages{[ANSI]C,make} \lstset{extendedchars=\true, showstringspaces=false, numbers=left, tabsize=3, frame=shadowbox, breaklines=true, breakatwhitespace=true, rulesepcolor=\color{black}, inputencoding=utf8x, escapebegin=\begin{cyr}, escapeend=\end{cyr}} \pagestyle{plain} \begin{document} EOFHDL echo $LETTER_SIZE >> $TEMPTEX for file in *; do echo "$file" | grep -q '.\{1,\}\.[ch]$' if [ $? -eq 0 ]; then echo -n "Processing $file: " echo -n "is C source file." # Заменяем возможные символы "_" на понимаемые TeXом "\_" texffile=`echo "$file" | sed 's/_/\\\\_/g'` # Мы должны заменить комментарии вида /* */ на /*` '*/, иначе # TeX отобразит русские комментарии без пробелов между словами. # FIXME: поскольку текст комментариев интерпретируется самим TeX'ом мы должны # заменить в комментариях "_" на "\_". Я просто везде меняю "_" на "--". # FIXME: точно так же TeX реагирует на любые escape и служебные символы в комментариях. # Пока что, приходится менять руками /* "" */ на /* "\" */. =(( cat $file | sed 's/\/\*/\/\*'\`'/g' | sed 's/\*\//'\''\*\//g' | sed 's/_/--/g' > /tmp/$TEMP-$file.c echo "\lstinputlisting[escapeinside=\`', language=C, caption={$texffile}]{/tmp/$TEMP-$file.c}" >> $TEMPTEX echo fi echo "$file" | grep -q 'Makefile' if [ $? -eq 0 ]; then echo -n "Processing $file: " echo -n "is file for utility make." # Тут обычно вообще не бывает комментариев - ничего не меняем. echo "\lstinputlisting[escapeinside=\`', language=make, caption={$file}]{$file}" >> $TEMPTEX echo fi done cat << EOFEND >> $TEMPTEX } \end{document} EOFEND echo "Starting pdflatex. Please wait" pdflatex $TEMPTEX &> /dev/null echo "PDF file: $TEMP.pdf created." rm -vi $TEMP.aux $TEMP.log $TEMPTEX /tmp/$TEMP-*.c |