\chapter{Введение в \mpost}
\label{sec:intro}

\begin{flushright}
  Каждая иллюстрация "--- это целая история.
\end{flushright}

Люди делятся на тех, кто умеет рисовать, и тех, кто не умеет. Причём
вторых большинство. В этом нет ничего плохого или хорошего "--- такова
жизнь. Хороший иллюстратор "--- редкость. 

Компьютерные технологии дают возможность создавать высококачественные
документы особенно не концентрируясь на проблеме оформления. Всю
черновую работу делает за вас компьютер. Например, система \LaTeX{}
фактически заменяет собой электронную типографию, но, к сожалению,
создание иллюстраций выносится за рамки этого процесса. Умение
иллюстрировать свой текст является необходимым навыком для тех, кто
хочет делать свои книги самостоятельно от начала и до конца. Часто
бывает что основной смысл несут в себе именно рисунки.

Создание иллюстраций это длительный и тяжёлый процесс, но если целью
стоит совершенство вашей книги, то потраченное время того стоит.
Обучение в изостудии в младших классах подняло мой уровень рисования с
<<никуда не годного>> до <<терпимого, если отойти на сто метров>>. Как
художник я совершенно безнадёжен, но иллюстрации мне приходится делать
довольно часто. В основном это не сложные картинки к задачам по
физике. Когда мне говорят, что мои рисунки к задачам вызывают чувство
зависти "--- мне с одной стороны приятно, но с другой стороны очень
тяжело объяснить как же я этого достиг. Цель этого текста "---
популяризовать создание иллюстраций с помощью \mpost.

Желание контролировать всё в процессе создания книги в случае Дональда
Э.  Кнута (Donald E. Knuth) привело к созданию программ \TeX{} и
\mfont.

Изначально \mfont{} предназначался для создания шрифтов и результатом
его работы был растр с изображением шрифта. Позже аспирант Д.Э.\,Кнута
Джон Хобби (John Hobby) модифицировал \mfont{} таким образом, что
результатом работы программы стала картинка в формате
\texttt{EPS} (Encusulated PostScript).

\mpost{} "--- это программа для тех, кто может объяснить компьютеру что
он хочет. \mpost{} чрезвычайна полезен для случаев, когда картинку проще
описать логически, нежели образно. Даже если Вы не умеете рисовать,
результат может получиться вполне приличный, потому что <<виртуальный
карандаш>> под управлением компьютера дрожать не будет.

\mpost{} проектировался как простая программа, которую можно
относительно быстро настроить под свои нужды. Он вполне обозрим
и компактен. Многие <<правильные>> программы, работающие с векторной
графикой, такие как \texttt{gnuplot} и \texttt{xfig}, умеют
экспортировать в \mpost{}.

\section{Здравствуй, Мир!}
\label{sec:hello-world}

Когда изучается новая программная технология первое что надо сделать,
это сказать: <<Здравствуй, Мир!>>. Что и сделаем, правда, пока на
английском. Для этого следует создать файл \texttt{helloworld.mp} со
следующим содержанием:
\begin{lstlisting}
% Для просмотра
prologues := 1;
% Простой Hello, World!
beginfig(1);
  label("Hello, World!     ",(0,0));
endfig;
% <<конец обработки>> - необходимо вставить в конце файла
end.
\end{lstlisting}


Далее скомпилируем этот код:
\begin{lstlisting}[language=bash,frame=]
> mpost helloworld.mp
\end{lstlisting}
В результате полученный файл \texttt{helloworld.1} можно посмотреть с
помощью любой программой понимающей \texttt{PostScript}, например, с
помощью \texttt{gv}:
\begin{figure}[htbp]\centering
  \includegraphics[width=0.7\textwidth]{linuxformat.3.eps}
  \caption{Первый Hello World на \mpost}\label{fig:1hello}
\end{figure}

Разнообразим пример. Создадим файл \texttt{linuxformat.mp} со
следующим содержимым:
\begin{lstlisting}
% А теперь мы его завращали и раскрасили
beginfig(1);
  for alpha:=90 step -3 until 0:
    label(btex Linux Format etex
      scaled (5*(1-alpha/100)) rotated alpha,(0,0))
    withcolor (max(1-alpha/45,0)*red+
      min(alpha/45,2-alpha/45)*green+
      max(alpha/45-1,0)*blue);
  endfor;
endfig;
end.
\end{lstlisting}
Скомпилируем код и результат преобразуем в pdf:
\begin{lstlisting}[language=bash,frame=]
> mpost linuxformat.mp
> pstopdf linuxformat.1
\end{lstlisting}
Полученный в результате этой операции файл \texttt{linuxformat-1.pdf}
можно посмотреть, например, с помощью программы \texttt{acroread} или
\texttt{xpdf}.
\begin{figure}[htbp]\centering
  \includegraphics[width=0.7\textwidth]{linuxformat.1.eps}
  \caption{<<Продвинутый>> Hello World на \mpost}\label{fig:2hello}
\end{figure}



Всё, что находится между \texttt{btex} и \texttt{etex} обрабатываются
внешней программой. По умолчанию это \TeX. Чтобы воспользоваться
возможностями \LaTeX{} надо в самом начале \texttt{linuxformat.mp} 
строчки вида:
\begin{lstlisting}
verbatimtex \documentclass{article}
\begin{document}
etex;
\end{lstlisting}
Эти строчки указывают \texttt{mpost}, что при обработке любых текстовых
вставок им должны предшествовать команды \texttt{\bs
documentclass\{article\}} и \texttt{\bs begin\{document\}}. 

Добавим в \texttt{linuxformat.mp} ещё один рисунок. Для этого 
скопируем уже имеющийся код первого рисунка, вставим его до 
заключительной команды <<\texttt{end.}>> и немного подправим 
первые три строчки:
\begin{lstlisting}
% Математика вместо Hello, World!
beginfig(2);
  for alpha:=90 step -9 until 0:
    label(btex \(f(x)=\frac{1}{\sqrt{2\pi}\,\sigma}
             \int\limits_{-\infty}^{\infty}
                e^{-\frac{x^2}{2\sigma^2}}dx\) etex
|\ldots|
\end{lstlisting}

Создание новых картинок на базе уже имеющегося кода в
\mpost{} "--- обычное дело. Со временем накапливается \emph{своя}
библиотечка примитивов, что сильно облегчает создание новых иллюстраций. 
Кажущаяся сложность выражений компенсируется
исключительной гибкостью языка, позволяющая повторно использовать
набранный код.

Скомпилируем код ещё раз:
\begin{lstlisting}[language=bash,frame=]
> mpost -tex=latex linuxformat.mp
> pstopdf linuxformat.2
\end{lstlisting}
Таким образом можно отобразить любую сколь угодно сложную
математическую конструкцию:
\begin{figure}[htbp]\centering
  \includegraphics[width=0.6\textwidth]{pic.3.eps}
  \caption{Математическая вставка}\label{fig:mathhello}
\end{figure}


Вместо того чтобы запускать \texttt{mpost} с опцией
\texttt{-tex=latex}, можно установить переменную окружения \texttt{TEX}
равную \texttt{latex}. В \texttt{bash} это можно сделать так:
\begin{lstlisting}[language=bash,frame=]
> export TEX=latex
\end{lstlisting}

Как видно из предыдущего примера, \mpost{} и \LaTeX{} умеют неплохо
работать вместе. Усовершенствуем немного
\texttt{linuxformat.mp}. Заменим первые три строчки в файле на следующий код:
\begin{lstlisting}
verbatimtex \input{preheader}
\begin{document}
etex;
\end{lstlisting}
и создадим файл \texttt{preheader.tex} с примерно следующим содержанием:
\begin{lstlisting}[language=TeX]
\documentclass[12pt]{article} 
%простейшая кириллизация
\usepackage[koi8-r]{inputenc}
\usepackage[english,russian]{babel}
\usepackage{indentfirst}%first paragraph indent
\usepackage{graphicx}
\end{lstlisting}
%\usepackage[warn]{mathtext}%русские буквы в формулах
%\usepackage[T2A]{fontenc}
Это стандартный заголовок для файлов \LaTeX. Если Вы набираете свои
тексты в \LaTeX, то можете поместить в \texttt{preheader.tex} всю свою 
преамбулу и включить её с помощью команды \texttt{\bs input}. Это позволит
создавать текстовые вставки в картинках \mpost{} тем же шрифтом, что и в обычном
тексте, а также позволит пользоваться любыми предопределёнными вами
командами. 

Следует обратить внимание, что чем больше будет разрастаться
заголовок, тем дольше будет обрабатываться \meta-код. Для увеличения
скорости лучше всего воспользоваться классом \texttt{minimal}, вместо
\texttt{article} и убрать все ненужные для рисования картинок пакеты.

Добавим третью картинку в \texttt{linuxformat.mp}, чуть изменив первоначальный 
код: 
\begin{lstlisting}
verbatimtex \input{preheader}
\begin{document}
etex;

|\ldots|

%изменим направление вращения
beginfig(3) ;
  for alpha:=-90 step 3 until 0:
    label(btex LinuxFormat в России etex
      scaled (5*(1+alpha/100)) rotated alpha,(0,0))
    withcolor (max(1+alpha/45,0)*red+
      min(-alpha/45,2+alpha/45)*green+
      max(-alpha/45-1,0)*blue);
  endfor;
endfig ;
end.
\end{lstlisting}
Теперь мы можем говорить по русски.
\begin{figure}[htbp]\centering
  \includegraphics[width=0.6\textwidth]{linuxformat.2.eps}
  \caption{Говорим по русски}\label{fig:rushello}
\end{figure}


\section{\mpost{}-конвейер}
\label{sec:work-mpost}

\begin{figure}[t]\centering
  \includegraphics[width=0.8\textwidth]{mpost.1.eps}
  \caption{\mpost{}-конвейер}\label{fig:mpost}
\end{figure}

Чуть подробнее остановимся на том что же происходит.
На вход программы \texttt{metapost} подаётся
<<\meta-картинка>>.  <<\meta-кар\-тин\-ка>> "--- это  текстовый mp-файл с
инструкциями на языке \meta. В одном mp-файле можно хранить 
несколько описаний картинок. При компиляции с помощью \texttt{mpost} 
создаются файлы с
тем же именем, что и у исходного файла, но с расширениями в виде чисел,
которые указываются в декларации \texttt{beginfig}. Результирующие
файлы сразу можно вставлять в \LaTeX-тексты с помощью обычного
\texttt{\bs includegraphics}. Для этого достаточно в заголовок tex-файла
добавить команду из \LaTeX-пакета \texttt{graphicx}:
\begin{lstlisting}[language=TeX,frame=]
\DeclareGraphicsRule{*}{eps}{*}{} 
\end{lstlisting}
От <<правильных>> eps-файлов они отличаются
только тем, что в них \emph{не} <<внедрены>> шрифты, поэтому просмотреть их
без дополнительной обработки не удастся.

Шрифты можно внедрить посредством программ \texttt{latex} и
\texttt{dvips} с результатом в виде eps-файла или скрипта 
\texttt{mptopdf} с результатом в виде
pdf-файла. Эти картинки уже можно использовать независимо любой
программой, которая поддерживает эти векторные форматы.

\section{Среда разработки}
\label{sec:IDE}

Удобная среда разработки понятие весьма относительное. Удобство 
зависит исключительно от Ваших предпочтений. Здесь будет представлена 
среда удобная для~\emph{меня}. Подробности настройки и
установки упоминаемых здесь пакетов выходят за рамки этого теста. 

В качестве базовой операционной системы я использую GNU/Linux. Это
позволяет мне использовать для своей работы стандартные средства
обработки текстовых данных, которые поставляются с этой системой.
Например, ниже будет упомянута утилита \texttt{make}, которая
позволяет автоматизировать ряд стандартных действий.

В качестве базового дистрибутива \LaTeX{} я использую дистрибутив
\TeXLive. На сегодня этот дистрибутив является наиболее полным из
дистрибутивов \LaTeX. Установочный образ для CD можно взять на любом
из \texttt{CTAN}-архивов (Comprehensive \TeX{} Archive
Network). 

В качестве базового редактора я использую редактор \texttt{emacs}. Если Вы
работаете с текстами в \LaTeX-формате, то при
настройки этого редактора следует включить пакеты
\texttt{auctex}\footnote{Продвинутая система для работы с проектами
  \LaTeX.} и \texttt{reftex}\footnote{Автоматизация работы со
  ссылками.}. \texttt{emacs} имеет простейшую встроенную поддержку для
редактирования файлов в формате \mpost. 

Для автоматизации создания eps-картинок я использую \texttt{Makefile}
примерно следующего вида:
\begin{lstlisting}[language=make]
# временный файл
tmp_file := tmp_file
# программы
LATEX := latex 
MPOST := mpost -tex=latex 
DVIPS := dvips

all:
	@echo "run: make mpfile.n.eps"

%.eps:  % preheader.tex 
	@echo  "\input{preheader}">$(tmp_file).tex
	@echo  "\DeclareGraphicsRule{*}{eps}{*}{}">>\
                                       $(tmp_file).tex
	@echo  "\nofiles">>$(tmp_file).tex
	@echo  "\begin{document}">> $(tmp_file).tex
	@echo  "\thispagestyle{empty}">> $(tmp_file).tex
	@echo  "\includegraphics{$(basename $@)}">>\
                                       $(tmp_file).tex
	@echo  "\end{document}">> $(tmp_file).tex
	@$(LATEX) $(tmp_file)
	@$(DVIPS) -E -o $@ $(tmp_file)
	@rm $(tmp_file).*

clean:
	@rm  -f mpx* *~ *.log *.mpx
	@rm -f $(tmp_file).*

# Зависимости для mpost-картинок.
# По одной для каждого числа из beginfig
%.1: %.mp preheader.tex preheader.mp
	$(MPOST) $<
|\ldots|
%.64: %.mp preheader.tex preheader.mp
	$(MPOST) $<
\end{lstlisting}

Чтобы на выходе получить готовую eps-картинку с уже <<внедрёнными>>
шрифтами, которую можно вставить уже куда угодно достаточно выполнить следующую
команду: 
\begin{lstlisting}[language=bash,frame=]
> make <имя mp-файлы>.<номер картинки>.eps
\end{lstlisting}
Обычно, mp-файлам даются короткие имена.

Если в качестве результирующего формата картинок вас интересует
pdf-формат, то в \texttt{Makefile} можно добавить что-то 
вроде:
\begin{lstlisting}[language=make,escapechar=]
MPTOPDF := mptopdf
MV := mv

%.pdf:  % preheader.tex
	@$(MPTOPDF) $<
	@$(MV) `echo $< | sed -e \
                 "s/\.\([0-9]\+\)$$/-\1.pdf/"` $<.pdf
\end{lstlisting}



\section{Чуть-чуть о \meta{}}
\label{sec:meta}

В качестве базового языка, инструкции которого подаются на вход
программы \mpost{} используется язык \meta.

Язык \meta{} поддерживает следующие типы данных:
\begin{description}
\item[boolean] объект булева типа, то есть либо true, либо false,
\item[numeric] обычное число (по умолчанию, если переменная не описана
  то она считается numeric),
\item[pair] точка "--- пара чисел (x,y) в случае декартовых координат
  или \mbox{R\(*\)dir \(\alpha\)} в случае полярных координат,
\item[pen] перо "--- то, чем компьютер рисует (в подавляющем
  большинстве случаев используется круглое перо \texttt{pencircle}),
\item[color] цвет "--- тройка чисел (r,g,b),
\item[path] путь "--- совокупность точек с описанием соединения
  между ними,
\item[picture] картинка "--- совокупность путей и точек,
\item[string] строка "--- ASCII строка,
\item[transform] преобразования "--- линейные преобразования, которые
  можно применять к объектам типа \texttt{pair}, \texttt{pen},
  \texttt{path} и \texttt{picture}.
\end{description}

Имена переменных в \meta{} могут состоять из нескольких лексем. Лексемы
могут быть либо буквенными, либо числовыми. Например, переменная
\texttt{x1l} состоит из трёх лексем. Её можно переписать более
понятным способом \texttt{x[1].l}, то есть числовая лексема по сути
указывает на номер элемента в массиве, а следующая за ней буква
уточняет элемент структуры. Возможность упускать <<\texttt{[].}>> в
написании имён переменных упрощает в некоторых случаях восприятие кода
(\(x_{1l}\) "--- это x-координата границы линии слева по направлению
движения  для первой точки пути 
\texttt{z[]}) и сокращает объём программы. В замен, если Вам нужны 
просто переменные без подобных особенностей, то Вам придётся 
ограничиться только \emph{буквенными} комбинациями. 

Все переменные необходимо объявлять перед использованием. Исключением
являются переменные типа \texttt{numeric}. Массивы объявляются и 
используются следующим образом:
\begin{lstlisting}[frame=]
pair w[];
w1:=(10,5);
w[2]=w[1];
\end{lstlisting}
 

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

В \meta{} можно упускать некоторые из операторов для сокращения
записей, например, \texttt{2*x} соответствует записи \texttt{2x}. 
Но будьте осторожны, так как \texttt{1/2x} это \texttt{0.5x}, что 
более естественно с точки зрения математики, но не программирования.
В \meta{} сначала обрабатываются числовые лексемы. 

Набор стандартных вычислительных операций расширен с учётом
специализации языка. В частности поддерживаются операции 
пифагорова сложения \(a{+}{+}b=\sqrt{a^2+b^2}\), пифагорова вычитания
\(a{+}{-}{+}b\hm=\sqrt{a^2-b^2)}\), целочисленное деление \texttt{div} 
и возведение в степень  \(x{*}{*}y=x^y\). 

В языке присутствуют операторы цикла, условных переходов и тому
подобное. Отличительной особенностью \meta{} является возможность
решать линейные уравнения. Например, выражения вида
\mbox{\(\text{C}=1/2[\text{A},\text{B}]\)} означает, что точка C
находится ровно посередине между точками \mbox{A\,и\,B}.


Программу \texttt{metapost} можно использовать в режиме калькулятора
для вычислений на языке \meta{}. Это позволяет проверить правильность
ваших предположений относительно языка. Пример сеанса представлен ниже:
\begin{lstlisting}[language=bash]
baldin@evgueni:~$ mpost
This is MetaPost, Version 0.901 (Web2C 7.5.5)
**\relax

*a:=10;

*b:=8;

*c:=a+-+b;

*show c;
>> 6
*show (3-sqrt 5)/2;
>> 0.38197
*show angle(1,sqrt 3);
>> 60.00008
*show 2**10;
>> 1024.00003
*show infinity;
>> 4095.99998
*show epsilon;
>> 0.00002
*show infinity-infinity;
>> 0
*end
Transcript written on mpout.log.
\end{lstlisting}
После вывода приглашения \texttt{**} следует набрать команду
\texttt{\bs relax}. Далее можно вводить команды \mpost{}. Делайть это
надо аккуратно, так как этот режим не поддерживает <<истории
команд>>. В начале не
предполагалось, что \mpost{} можно использовать и так тоже. С помощью
команды \texttt{show} можно вывести результат на экран. Закончить
сеанс можно с помощью команды \texttt{end}.

Обратите внимание, что на просьбу вывести бесконечность
(\texttt{infinity}) \mpost{} выдал 4095.99998 "--- это максимальное
значение, которое может принемать переменная типа
\texttt{numeric}. Причём в процессе вычисления результат может
привышать <<бесконечность>>, но ответ должен быть меньше или равен её,
иначе будет выдана ошибка. Минимальный шаг изменения типа
\texttt{numeric} равен \texttt{epsilon}, или точнее
\(1/256/256\). При создании рисунка эти ограничения не существенны,
так как диапазон изменения чисел вполне велик, чтобы вместить все
элементы. Но в любом случае это тоже необходимо учитывать.

Если Вы хотите вычислить однострочное выражение, то на первоначальное
приглашение \texttt{**} можно ввести \texttt{expr}. В этом случае
\texttt{mpost} считает файл \texttt{expr.mf} и на любое ваше действие
будет выдаваться ответ:
\begin{lstlisting}[language=bash]
baldin@evgueni:~|\$| mpost
This is MetaPost, Version 0.901 (Web2C 7.5.5)
**expr
(/usr/local/texlive/2005/texmf-dist/metafont/base/expr.mf
gimme an expr: 2(a+3b)-2b
>> 4b+2a
gimme an expr: 1/3[a,b]
>> 0.33333b+0.66667a
\end{lstlisting}

\section{Литература}
\label{sec:lit}

Язык \meta, который используется в \mpost{} за некоторыми исключениями 
полностью соответствует диалекту \meta{}, который используется в
программе создания шрифтов \mfont. 

Основной книгой по языку \meta является <<Всё про \mfont>>
Дональда Э.\,Кнута. В 2003 году издательством Вильямс 
был выпущен русский перевод этой
классической книги (ISBN 5-8459-0442-0). Исходники англоязычного 
оригинала <<The \mfont{} book>> можно найти на любом 
\texttt{CTAN} архиве. Эта книга, как и другие произведения Д.Э.\,Кнута имеет
несколько уровней сложностей. Даже с нулевым начальным уровнем знания
предмета Вы можете прочитать книгу полностью "--- её строение это
позволяет, но для
дальнейшего продвижения эту книгу придётся перечитывать не один раз. 
Каждое прочтение приносит новое понимание. Если Вы имеете хоть
какое-то отношение к программированию, то книги Д.Э.\,Кнута
\emph{надо} читать. Именно благодаря подобным людям информатика
может претендовать на фундаментальность.

На русском языке информацию о \mpost{} можно найти в <<Путеводителе по
пакету \LaTeX{} и его графическим расширениям>> М.Гуссенса, С.Ратца и
Ф.Миттельбаха от издательства Мир (ISBN 5-03-003388-2).

Все остальные источники в основном англоязычные. Прежде всего это
<<A User's Manual for \mpost>> Джона Хобби (Jhon D. Hobby) "--- файл
\texttt{mpman.pdf}.  Этот текст можно найти в документации к 
дистрибутиву \mpost{}. Этому тексту предшестовало несколько
<<основополагающих>> статей, которые при желании можно легко найти в
интернете. Очень качественным руководством пользователя
отметился Андрэ Хек (Andr\'e Heck) 
\url{http://remote.science.uva.nl/~heck/Courses/mptut.pdf}.
Так же представляет интерес книга <<\texttt{metafun}>> 
от Ганса Хагена (Hans Hagen) "--- она находится в открытом
доступе, имя файла \texttt{metafun-p.pdf}.  


В интернете можно найти интересный ресурс под названием <<Metapost :
exemples>> от Vincent Zoonekynd \url{http://zoonek.free.fr/LaTeX/}. 
Это страничка с огромным количеством
простых примеров. Небольшое неудобство состоит в том, что это
франкоговорящий ресурс, с другой стороны текста там немного.
Зеркало расположено, например, здесь
\url{http://tex.loria.fr/prod-graph/zoonekynd/metapost/metapost.html}.


Ко всей перечисленной электронной документации можно получить доступ
через страничку CTAN, посвящённую \mpost:
 \url{http://www.tug.org/metapost.html}


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "mpillustration"
%%% End: 
