Web2C — это интегрированная коллекция программ, относящихся к TeXу: сам TeX, metafont, MetaPost, BibTeX, и т.д. Это сердце TeX Live.
Немного истории. Исходная имплементация была сделана Томасом Рокики, который в 1987 году создал первую систему TeX-to-C, адаптировав файлы изменений для Юникса, разработанные в основном Говардом Трики и Павлом Куртисом. Тим Морган стал поддерживать систему, и в этот период её имя сменилось на Web-to-C. В 1990 году Карл Берри взялся за работу, координируя работу десятков программистов, а в 1997 он передал руководство Олафу Веберу.
Система Web2C работает на Юниксе, 32-битовых Windows, MacOSX, и других операционных системах. Она использует оригинальные исходники Кнута для TeXа и других программ, написанных на языке web и переведённых на C. Основные программы системы:
Полностью эти программы описаны в документации к соответствующим пакетам и самой Web2C. Однако знание некоторых общих принципов для всей семьи программ поможет вам полностью использовать программы системы Web2C.
Все программы поддерживают стандартные опции GNU:
Для поиска файлов программы Web2C используют библиотеку Kpathsea. Эта библиотека использует комбинацию переменных окружения и конфигурационных файлов, чтобы найти нужные файлы в огромной системе TeX. Web2C может просматривать одновременно больше одного дерева директорий, что полезно для работы со стандартным дистрибутивом TeXа и его локальными расширениями. Для ускорения поисков файлов каждое дерево содержит файл ls-R, в котором указаны названия и относительные пути всех файлов в этом дереве.
Рассмотрим сначала общий алгоритм библиотеки Kpathsea.
Будем называть путём поиска набор разделённых двоеточием или точкой с запятой of элементов пути, представляющих из себя в основном названия директорий. Путь поиска может иметь много источников. Чтобы найти файл «my-file» в «.:/dir», Kpathsea проверяет каждый элемент пути по очереди: сначала ./my-file, затем /dir/my-file, возвращая первый (или, возможно, все) файл.
Чтобы работать с разными операционными системами, Kpathsea под системой, отличной от Юникса может использовать разделители, отличные от «:» и slash («/».
Чтобы проверить определённый элемент пути p, Kpathsea вначале проверяет, приложима ли к нему база данных (см. «База данных файлов» на стр. 74), т.е., есть ли база в директории, которая является префиксом для p. Если это так, спецификация пути сравнивается с содержимым базы данных.
Если база данных не существует, или не относится к этому элементу пути, или не содержит нужного элемента, проверяется файловая система (если это не запрещено спецификацией, начинающейся с «!!», и если файл должен существовать). Kpathsea конструирует список директорий, которые соответствуют элементу, и в каждой ищет нужный файл,
Условие «файл должен существовать» относится файлам «.vf» и файлам, которые открывает TeX по команде \openin. Такие файлы могут и не существовать (например, файл cmr10.vf), и было бы неправильно искать их на диске. Поэтому, если вы не обновите ls-R при установке нового файла «.vf», он никогда не будет найден. Каждый элемент пути ищется по очереди: сначала база данных, затем диск. Если нужный файл найден, поиск останавливается, и возвращается результат.
Хотя самых простой и часто встречающийся элемент — это название директории, Kpathsea поддерживает дополнительные возможности: разнообразные значения по умолчанию, имена переменных окружения, значения из конфигурационных файлов, домашние директории пользователей, рекурсивный поиск поддиректорий. Поэтому мы говорим, что Kpathsea вычисляет элемент пути, т.е., что библиотека преобразует спецификации в имя или имена директории. Это описано в следующих разделах в том же порядке, в котором происходит при поиске.
Заметьте, что имя файла при поиске может быть абсолютным или относительным, т.е. начинаться с «/» или «./» или «../», Kpathsea просто проверяет, существует ли файл.
Путь поиска может иметь разные источники. Kpathsea использует их в следующем порядке:
Вы можете увидеть каждое из этих значений для данного пути поиска, задав соответствующий уровень отладки (см. «Отладка» на стр. 82).
Kpathsea читает конфигурационные файлы texmf.cnf для задания своих параметров. Путь поиска для этих файлов называется TEXMFCNF (по умолчанию, такой файл находится в поддиректории texmf/web2c). Все найденные файлы texmf.cnf будут прочитаны и определения в более ранних файлах имеют преимущество перед определениями в более поздних. Таким образом, если путь поиска задан как .:$TEXMF, значения в ./texmf.cnf имеют преимущество перед значениями в $TEXMF/texmf.cnf.
Фрагмент конфигурационного файла, иллюстрирующий эти правила приведён ниже:
Kpathsea разпознаёт определённые специальные символы и конструкции в путях поиска, аналогичные конструкциям в стандартных оболочках Юникса. Например, сложный путь ~$USER/{foo,bar}//baz, означает все поддиректории директорий foo и bar в домашней директории пользователя $USER, которые содержат файл или поддиректорию baz. Это объяснено в следующем разделе.
Если путь поиска с наибольшим приоритетом (см. «Источники путей» на стр. 69) содержит дополнительное двоеточие (в начале, в конце, двойное), Kpathsea заменяет его следующим по приоритету путём. Если этот вставленный путь содержит дополнительное двоеточие, то же происходит со следующим путём. Например, если переменная окружения задана как
Поскольку было бы бесполезно вставлять значение по умолчанию более, чем один раз, Kpathsea изменяет только одно лишнее двоеточие, и оставляет остальные: она проверяет сначала двоеточие в начале, потом в конце, потом двойные двоеточия.
Полезна также подстановка скобок, из-за которой, например, v{a,b}w означает vaw:vbw. Вложенность возможна. Благодаря этому можно иметь несколько иерархий директорий, путём присвоения значения со скобками $TEXMF. Например, в файле texmf.cnf, можно найти следующее определение:
Благодаря этому можно писать такое:
что означает, что кроме текущей директории будет происходить поиск только в $HOMETEXMF/tex, $TEXMFLOCAL/tex, $VARTEXMF/tex и $TEXMFMAIN/tex (последние два используют файлы ls-R). Это удобно для поддержки двух параллельных структур, «замороженной» (например, на CD) и обновляемой по мере появления новых версий. Используя переменную $TEXMF во всех определениях, можно задать поиск в обновляемом дереве первым.
Два или более «/» в элементе пути вслед за именем директории d заменяются всеми поддиректориями d рекурсивно. На каждом уровне порядок поиска по директориям не определён.
Если вы определите компоненты имени файла после «//», только поддиректории с соответствующими компонентами будут включены. Например, «/a//b» даёт поддиректории /a/1/b, /a/2/b, /a/1/1/b, и т.д., но не /a/b/c или /a/1.
Возможны несколько конструкций «//» в одном пути, но «//» в начале пути игнорируются.
В следующем списке приводятся специальные символы в конфигурационных файлах Kpathsea.
Kpathsea старается минимизировать обращение к диску при поиске. Тем не менее в системах с большим количеством директорий поиск в каждой возможной директории может занять долгое время (это особенно верно, если надо проверить сотни директорий со шрифтами). Поэтому Kpathsea может использовать внешний текстовый файл, «базу данных» ls-R, который знает, где находятся файлы в директориях, что даёт возможность избежать частых обращений к диску.
Ещё одна база данных, файл aliases позволяет вам давать дополнительные названия файлам в ls-R. Это полезно, если вам нужно соблюдать правило DOS «8.3».
Как объяснено выше, основная база данных называется ls-R. Вы можете создать её в корне каждого дерева TeXа, которое просматривается Kpathsea (по умолчанию, $TEXMF); в большинстве случаев иерархия только одна. Kpathsea ищет файлы ls-R в пути TEXMFDBS.
Рекомендуемый способ создания и поддержки «ls-R» — скрипт mktexlsr, включённый в дистрибутив. Он вызывается разными скриптами «mktex». . . . В принципе этот скрипт выполняет команды типа
Если файл не найден в базе данных, по умолчанию Kpathsea ищет на диске. Если элемент пути начинается с «!!», то поиск происходит только в базе данных.
Программа kpsewhich выполняет поиск в соответствии с алгоритмом, описанным выше. Это может быть полезно в качестве варианта команды find для поиска файлов в иерархиях TeXа hierarchies (это широко используется в скриптах «mktex»).
Kpathsea рассматривает каждый аргумент, не являющийся опцией, как имя файла, и возвращает первый найденный файл. Нет опции вернуть все найденные файлы (для этого можно использовать программу «find»).
Наиболее важные опции описаны ниже.
Последние две строки в Таблице 3 — специальные случаи, когда пути и переменные окружения зависят от названия программы; имя переменной окружения конструируется преобразованием названия программы в верхний регистр, и добавлением INPUTS.
Переменные окружения устанавливаются по умолчанию в конфигурационном файле texmf.cnf. Если вы хотите переопеределить одно или несколько значений из этого файла, вы можете установить их явно.
Опции «--format» и «--path» не могут использоваться вместе.
Давайте посмотрим на Kpathsea в действии. Вот простой поиск:
Последнее — библиографическая база данных для статей журнала TUGBoat.
Теперь обратимся к заголовкам и конфигурационным файлам dvips. Вначале рассмотрим один из наиболее часто используемых файлов, пролог tex.pro для поддержки TeXа, а затем рассмотрим общий конфигурационный файл config.ps и карту шрифтов psfonts.map. Так как суффикс «.ps» неоднозначен, мы должные явно указать тип файла, который мы ищем: (dvips config) для файла config.ps.
Рассмотрим теперь файлы поддержки URW Times (PostScript). Префикс для этих файлов в стандартной схеме обозначения шрифтов «utm». Вначале мы рассмотрим конфигурационный файл, который содержит название карты шрифтов:
Из этих примеров очевидно, что вы можете легко найти заданный файл. Это особенно важно, если вы думаете, что программы находят не ту версию файла, поскольку kpsewhich показывает первый найденный файл.
Иногда необходимо проверить, как программа ищет файлы. С этой целью Kpathsea предлагает разные уровни отладки:
Значение -1 задаст все опции вышел именно это значение чаще всего используется на практике.
Аналогично, запустив программу dvips и используя сочетание этих опций, можно проследить подробно, как ищутся файлы. С другой стороны, если файл не найден, трассировка показывает, где его искали, так что можно понять, в чём состоит проблема.
Вообще говоря, поскольку большинство программ пользуются библиотекой Kpathsea, вы можете установить опцию отладки используя переменную окружения KPATHSEA_DEBUG, и установив её на комбинацию описанных выше значений.
(Примечание для пользователей Windows: в этой системе трудно перенаправить все сообщения в файл. Для диагностики вы можете временно установить SET KPATHSEA_DEBUG_OUTPUT=err.log).
Рассмотрим в качестве примера простой файл в формате LaTeX, hello-world.tex, со следующим содержанием:
Этот маленький файл использует только шрифт cmr10, так что давайте порсмотрим, как dvips создаёт файл в формате PostScript (мы хотим использовать версию шрифтов в формате Type 1, отсюда опция -Pcms).
debug:start search(file=texmf.cnf, must_exist=1, find_all=1,
path=.:/usr/local/bin/texlive:/usr/local/bin: /usr/local/bin/texmf/web2c:/usr/local: /usr/local/texmf/web2c:/.:/./teTeX/TeX/texmf/web2c:). kdebug:start search(file=ls-R, must_exist=1, find_all=1, path=~/tex:/usr/local/texmf). kdebug:search(ls-R) =>/usr/local/texmf/ls-R kdebug:start search(file=aliases, must_exist=1, find_all=1, path=~/tex:/usr/local/texmf). kdebug:search(aliases) => /usr/local/texmf/aliases kdebug:start search(file=config.ps, must_exist=0, find_all=0, path=.:~/tex:!!/usr/local/texmf/dvips//). kdebug:search(config.ps) => /usr/local/texmf/dvips/config/config.ps kdebug:start search(file=/root/.dvipsrc, must_exist=0, find_all=0, path=.:~/tex:!!/usr/local/texmf/dvips//). search(file=/home/goossens/.dvipsrc, must_exist=1, find_all=0, path=.:~/tex/dvips//:!!/usr/local/texmf/dvips//). kdebug:search($HOME/.dvipsrc) => kdebug:start search(file=config.cms, must_exist=0, find_all=0, path=.:~/tex/dvips//:!!/usr/local/texmf/dvips//). kdebug:search(config.cms) =>/usr/local/texmf/dvips/cms/config.cms
kdebug:start search(file=texc.pro, must\_exist=0, find\_all=0,
path=.:~/tex/dvips//:!!/usr/local/texmf/dvips//: ~/tex/fonts/type1//:!!/usr/local/texmf/fonts/type1//). kdebug:search(texc.pro) => /usr/local/texmf/dvips/base/texc.pro
kdebug:start search(file=cmr10.tfm, must\_exist=1, find\_all=0,
path=.:~/tex/fonts/tfm//:!!/usr/local/texmf/fonts/tfm//: /var/tex/fonts/tfm//). kdebug:search(cmr10.tfm) => /usr/local/texmf/fonts/tfm/public/cm/cmr10.tfm kdebug:start search(file=texps.pro, must\_exist=0, find\_all=0, ... <texps.pro> kdebug:start search(file=cmr10.pfb, must\_exist=0, find\_all=0, path=.:~/tex/dvips//:!!/usr/local/texmf/dvips//: ~/tex/fonts/type1//:!!/usr/local/texmf/fonts/type1//). kdebug:search(cmr10.pfb) => /usr/local/texmf/fonts/type1/public/cm/cmr10.pfb <cmr10.pfb>[1]
|
Программа dvips вначале ищет свои конфигурационные файлы. Сначала находится texmf.cnf, который содержит определения для путей поиска остальных файлов, затем база данных ls-R (для оптимизации поиска файлов) и файл aliases, который позволяет объявить несколько имён (например, короткие 8.3 и более длинные) для одного файла. Затем dvips ищет свой конфигурационный файл config.ps до поиска файла .dvipsrc (который в данном случае не найден). Наконец, dvips находит конфигурационный файл для шрифтов Computer Modern PostScript config.cms (это было задано опцией -Pcms в командной строке). Этот файл содержит список карт, которые определяют соотношения между файлами в форматах TeX, PostScript и названиями шрифтов:
В этот момент dvips сообщает о себе пользователю:
Найдя этот файл, dvips печатает дату и время, и информирует нас, что собирается генерировать файл hello-world.ps, что ей нужен файл cmr10, и что последний является «резидентным» (битмапы не нужны):
Ещё одна полезная возможность Web2C, это контроль параметров памяти (в особенности размер массивов) при запуске, во время чтения файла texmf.cnf библиотекой Kpathsea. Параметры памяти находятся в части 3 этого файла в дистрибутиве TeX Live. Вот самые важные:
Разумеется, это не замена настоящих динамических массивов и распределения памяти, но поскольку эти черты исключительно сложно осуществить в текущем TeXе, эти параметры дают полезный компромисс и некоторую гибкость.