Литмир - Электронная Библиотека
Содержание  
A
A

И, наконец, поскольку

eqn
выделяет курсивом любую строку букв, которые она не распознает, довольно просто выделять обычные слова курсивом. Последовательность
@Word@
например, печатается как Word. Но будьте внимательны:
eqn
распознает некоторые обычные символы (такие, как
from
и
to
) и специальным образом их рассматривает: она "глотает" пробелы, поэтому указанный прием следует применять с осторожностью.

Получение выходного потока

Как только ваш документ готов, вы должны соединить все препроцессоры и

troff
в цепочку, чтобы получить выходной поток. Порядок команд следующий:
tbl
,
eqn
,
troff
. Если вы просто используете
troff
, то печатайте

$ troff -ms <i>имена_файлов</i>
(или
-mm
)

Иначе вам придется задать аргумент

<i>имена_файлов</i>
первой команде в цепочке и дать остальным командам читать их стандартный входной поток, как показано ниже:

$ eqn <i>имена_файлов</i> | troff -ms

или

$ tbl <i>имена_файлов</i> | eqn | troff -ms

Неудобно следить за тем из препроцессоров, который действительно должен печатать какой-то отдельный документ. Мы сочли уместным написать программу

doctype
, обеспечивающую вывод соответствующей последовательности команд:

$ doctype ch9.*

cat ch9.1 ch9.2 ch9.3 ch9.4 | pic | tbl | eqn | troff -ms

$ doctype hoc.ms

cat hoc.ms | tbl | eqn | troff -ms

$

Программа

doctype
реализована с помощью инструментов, рассмотренных в гл. 4. В частности, программа
awk
отыскивает последовательность команд, используемую препроцессорами, и печатает строку команд, которые нужно вызвать, чтобы отформатировать документ. Она также находит команду
.PP
(абзац) для форматирования пакетом запросов
ms
.

$ cat doctype

# doctype: synthesize proper command line for troff

echo -n &quot;cat $* | &quot;

egrep -h (EQ|TS|\[|PS|IS|PP)' $* |

sort -u |

awk '

 /^\.PP/ { ms++ }

 /^\.EQ/ { eqn++ }

 /^\.TS/ { tbl++ }

 /^\.PS/ { pic++ }

 /^\.IS/ { ideal++ }

 /^\.\[/ { refer++ }

 END {

  if (refer &gt; 0) printf &quot;refer | &quot;

  if (pic &gt; 0) printf &quot;pic | &quot;

  if (ideal &gt; 0) printf &quot;ideal | &quot;

  if (tbl &gt; 0) printf &quot;tbl | &quot;

  if (eqn &gt; 0) printf &quot;eqn | &quot;

  printf &quot;troff &quot;

  if (ms &gt; 0) printf &quot;-ms&quot;

  printf &quot;\n&quot;

 } '

$

(Флаг

-h
заставляет ее подавлять заголовки имен файлов на каждой строке: к сожалению, этот аргумент есть не во всех версиях системы.) При сканировании входного потока собирается информация о том, какие компоненты используются. После просмотра входной поток обрабатывается в требуемой последовательности для печати выходного текста. В формировании документов
troff
со стандартными препроцессорами есть специфика, и главная задача состоит в том, чтобы заставить "думать" об этом саму машину.

Программа

doctype
в нашем примере подобна
bundle
-программе, которая создает программу. Однако в таком виде она требует от пользователя вновь вводить строку для
shell
. В одном из приводимых ниже упражнений вам предлагается это исправить.

Когда дело дойдет до запуска реальных команд

troff
, не забывайте, что поведение программы зависит от системы: на некоторых установках она управляет наборным устройством непосредственно, в то время как на других выдает в стандартный выходной поток информацию, которая должна быть послана на наборное устройство отдельной программой.

Между прочим, в новой версии этой программы не предусмотрена программа

egrep
или
sort
;
awk
сама просматривает весь входной поток. Для больших документов такой вариант оказывается слишком медленным, поэтому для ускорения поиска мы добавили
egrep
и затем
sort -u
, чтобы избавиться от дублирования. При построении типичных документов накладные расходы по созданию двух дополнительных разбирающих данные процессов меньше, чем запуск
awk
в тех же целях с большим объемом входного текста.

В качестве иллюстрации сравним

doctype
с версией, только запускающей
awk
применительно к содержимому данной главы (около 52 000 символов):

$ time awk '... doctype without egrep ...' ch9.*

cat ch9.1 ch9.2 ch9.3 ch9.4 | pic | tbl | eqn | troff -ms

real 31.0

user 8.9

sys 2.8

$ time doctype ch9*

cat ch9.1 ch9.2 ch9.3 ch9.4 | pic | tbl | eqn | troff -ms

real 7.0

user 1.0

sys 2.3

$

Сравнение, очевидно, в пользу версии с тремя процессами. (Работа была выполнена в однопользовательском режиме; соотношение значений времени показало бы даже более значительное преимущество версии

egrep
и при повышенной нагрузке на систему.) Отметим, что, прежде чем начать оптимизацию, мы получили сначала простую работающую версию.

132
{"b":"248117","o":1}