% $Id: mpman.tex 513 2008-04-29 12:03:53Z stephanhennig $ % MetaPost manual, by John Hobby. License at end. % Russian translation, 2008/05/10 \listfiles \RequirePackage{ifpdf} \ifpdf \ifnum\pdftexversion<140 \else \pdfminorversion=5 \pdfobjcompresslevel=1% Use compressed object streams. \fi \RequirePackage{cmap} \documentclass{article} % article is NOT the original style %%\usepackage[nofancy]{svninfo}% Access VCS information. %%\svnInfo $Id: mpman.tex 513 2008-04-29 12:03:53Z stephanhennig $ \newcommand*{\mpversion}{1.004} %%\usepackage[T1]{fontenc} %%\usepackage{lmodern} %%\usepackage{textcomp} \usepackage{mflogo} \usepackage{makeidx} \usepackage{fancyvrb} \usepackage{ctabbing} \RecustomVerbatimEnvironment {verbatim}{BVerbatim}{baseline=c} \usepackage{graphicx} \newcommand\qq{"} % quotation mark is active in Russian Babel! \usepackage{amssymb} \usepackage{cmap-cyr-vf} \usepackage[LCYW]{fontenc} \usepackage[koi8-r]{inputenc} \usepackage[english,russian]{babel} %%\usepackage[latin1]{inputenc} \usepackage[textwidth=6in,textheight=8.65in]{geometry} \usepackage{tocloft} \setlength\cftbeforesecskip{1.3ex plus 0.3ex minus 0.3ex} \usepackage{ltxtable} \def\ttindex#1{{\tt #1}\index{#1?\texttt{#1}}} \def\ttt{\texttt} % I get tired of typing this out \def\ConTeXt{Con\TeX t} \newcommand\descr[1]{{\langle\hbox{#1}\rangle}} \newcommand\invisgap{\nobreak\hskip0pt\relax} \newcommand\tdescr[1]{$\langle$\invisgap#1\invisgap$\rangle$} \newcommand\pl{\dag} \newcommand\bx{$*$} \newcommand\mathcenter[1]{\vcenter{\hbox{#1}}} \renewcommand{\topfraction}{.85} \renewcommand{\bottomfraction}{.7} \renewcommand{\textfraction}{.15} \renewcommand{\floatpagefraction}{.5} \renewcommand{\dbltopfraction}{.66} \renewcommand{\dblfloatpagefraction}{.66} \setcounter{topnumber}{9} \setcounter{bottomnumber}{9} \setcounter{totalnumber}{20} \setcounter{dbltopnumber}{9} \makeindex \usepackage{multicol} \usepackage[rgb,x11names]{xcolor}% Optimize for screen reading. \usepackage{hyperxmp} \usepackage{hyperref} \hypersetup{ pdftitle={A User's Manual for MetaPost (translated to Russian)}, %% pdftitle={A User's Manual for MetaPost}, pdfauthor={John D. Hobby and the MetaPost development team}, pdfkeywords={MetaPost, PostScript, vector graphics language, MetaFont, TeX, Russian} %% pdfkeywords={MetaPost, PostScript, vector graphics language, MetaFont, TeX} } \hypersetup{ pdfstartview={XYZ null null null},% Zoom factor is determined by viewer. colorlinks, linkcolor=RoyalBlue3, urlcolor=Chocolate4, citecolor=SpringGreen3 } \usepackage[all]{hypcap} \begin{document} \VerbatimFootnotes %%% Title page layout documentation is missing. \begin{titlepage} \vbox to \textheight {% \vskip0pt \vfil \vfil \vfil \centerline{\resizebox{3.5in}{!}{\fontseries{b}\selectfont\MP}} \vskip10bp% actually 21bp (-11bp) \centerline{\includegraphics{manfig-ru-60.mps}} \vskip15bp% actually 21bp (-6bp) \centerline{% \resizebox{3.5in}{!}{% \scshape% \fontsize{28bp}{28bp}\selectfont \strut\lowercase{РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ}% %% \strut\lowercase{A USER\kern-2bp\lower3bp\hbox{'}S MANUAL}% }% } \vskip-11bp \vfil \vfil \centerline{\large John D. Hobby} \vskip3bp \centerline{и команда разработки MetaPost} %% \centerline{and the MetaPost development team} \vskip20.8bp% actually 31.8bp (-11bp) \centerline{\large версия документа: \mpversion} %% \centerline{\large documented version: \mpversion} \vskip3bp %% \centerline{\svnToday} \vfil \vfil \vfil } \end{titlepage} \section*{Примечания переводчика} В версии 1.004 MetaPost руководство пользователя для пакета \texttt{boxes} было вынесено в отдельный документ. В переводе этого разделения не произошло, но добавления к документации были учтены. Создания этого перевода было бы невозможным без Ольги Гагаркиной. \begin{flushright}Владимир Лидовский, \url{litwr@yandex.ru}\end{flushright} \thispagestyle{empty} \newpage \setlength{\columnsep}{2.5em} \begin{multicols}{2} \tableofcontents \end{multicols} \section{Введение} %%\section{Introduction} \label{intro} MetaPost --- это язык программирования, очень похожий на \MF\footnote{\MF\ --- это торговая марка компании Addison Wesley Publishing.}\index{metafont?\MF}~\cite{kn:c} Кнута с тем исключением, что он производит PostScript-программы вместо растровых картинок. %%MetaPost is a programming language much like Knuth's \MF\footnote{\MF\ %%is a trademark of Addison Wesley Publishing %%company.}\index{metafont?\MF}~\cite{kn:c} except that it outputs %%PostScript programs instead of bitmaps. Заимствования из \MF --- это базовые средства для создания и манипулирования картинками. %%Borrowed from \MF\ are the %%basic tools for creating and manipulating pictures. Они включают числа, координатные пары, кубические сплайны, аффинные трансформации, текстовые строки и булевы величины. %%These include %%numbers, coordinate pairs, cubic splines, affine transformations, text %%strings, and boolean quantities. Дополнительные средства делают возможными соединение текста и графики и доступ к специальным возможностям PostScript\footnote{PostScript --- это торговая марка Adobe Systems.}\index{PostScript} таким как вырезка, затенение, пунктирные линии. %%Additional features facilitate %%integrating text and graphics and accessing special features of %%PostScript\footnote{PostScript is a trademark of Adobe Systems %%Inc.}\index{PostScript} such as clipping, shading, and dashed lines. Другое свойство, заимствованное у \MF, --- это способность решать заданные неявно линейные уравнения, что позволяет писать многие программы в значительной мере в декларативном стиле. %%Another feature borrowed from \MF\ is the ability to solve linear %%equations that are given implicitly, thus allowing many programs to be %%written in a largely declarative style. Мощь и гибкость MetaPost достигаются построением сложных операций из более простых. %%By building complex operations %%from simpler ones, MetaPost achieves both power and flexibility. MetaPost особенно хорошо приспособлен для генерации картинок для технических документов, где некоторые свойства рисунка могут контролироваться математическими или геометрическими ограничениями, которые наилучшим образом выражаются в символьной форме. %%MetaPost is particularly well-suited to generating figures for technical %%documents where some aspects of a picture may be controlled by %%mathematical or geometrical constraints that are best expressed %%symbolically. Другими словами, MetaPost не занимает место средств для ручного рисования или даже интерактивных графических редакторов. %%In other words, MetaPost is not meant to take the place %%of a freehand drawing tool or even an interactive graphics editor. Это настоящий язык программирования для генерации графики и, особенно, иллюстраций для документов \TeX\footnote{\TeX\ --- это торговая марка American Mathematical Society.}\index{TeX?\TeX} и troff\index{troff}. %%It %%is really a programming language for generating graphics, especially %%figures for \TeX\footnote{\TeX\ is a trademark of the American %%Mathematical Society.}\index{TeX?\TeX} and troff\index{troff} documents. Для использования MetaPost вы должны приготовить входной файл с Metapost-кодом и затем вызвать сам MetaPost при помощи, как правило, команды в форме \index{mpost?\texttt{mpost}} $$ {\tt mpost}\, \descr{имя файла} $$ %%To use MetaPost, you prepare an input file containing MetaPost code and %%then invoke MetaPost, usually by giving a command of the %%form\index{mpost?\texttt{mpost}} %%$$ {\tt mpost}\, \descr{filename} $$ Синтаксис и имя программы являются системо-зависимыми, иногда она зовется \texttt{mp}. %%The syntax and program name itself are system-dependent; sometimes it is %%named \texttt{mp}. Входные файлы для MetaPost\index{файлы!ввод} обычно имеют имена, заканчивающиеся на ``{\tt .mp}'', и эта часть имени может опускаться при вызове MetaPost. %%MetaPost input %%files\index{files!input} normally have names ending ``{\tt .mp}'' but %%this part of the name can be omitted when invoking MetaPost. Например, для входного файла {\tt foo.mp} $$ \hbox{\tt mpost foo} $$ вызовет MetaPost и произведет выходные файлы с именами типа {\tt foo.1} и {\tt foo.2}. %%For an %%input file {\tt foo.mp} %%$$ \hbox{\tt mpost foo} $$ %%invokes MetaPost and produces output files with names like {\tt foo.1} %%and {\tt foo.2}. Все сообщения, появляющиеся на терминале, собираются в файл-дубликат\index{файлы!дубликат}\index{файл-дубликат} с именем {\tt foo.log}. %%Any terminal I/O is summarized in a %%transcript\index{files!transcript}\index{transcript file} file called %%{\tt foo.log}. Туда включаются сообщения об ошибках и все команды MetaPost, введенные интерактивно.\footnote{Знак {\tt *}\index{*?\texttt{*}} используется для приглашения к интерактивному вводу и знак {\tt **}\index{**?\texttt{**}} показывает, что ожидается имя входного файла. Диалога можно избежать вызовом MetaPost с файлом, который заканчивается командой {\tt end}\index{end?\texttt{end}}.} %%This includes error messages and any MetaPost commands %%entered interactively.\footnote{A {\tt *}\index{*?\texttt{*}} prompt is %%used for interactive input and a {\tt **}\index{**?\texttt{**}} prompt %%indicates that an input file name is expected. This can be avoided by %%invoking MetaPost on a file that ends with an {\tt %%end}\index{end?\texttt{end}} command.} \label{Dmpversion}Файл-дубликат начинается с заголовочной строки, идентифицирующей используемую вами версию MetaPost. %%\label{Dmpversion}The transcript file starts with a banner line that %%identifies the version of MetaPost you are using. Вы можете также определить текущую версию из программы MetaPost через строковую константу \texttt{mpversion} (это стало возможным с версии 0.9). %%You can also determine %%the current version from within a MetaPost program via the %%\texttt{mpversion} predefined constant string (this was introduced in %%version 0.9). Например, %%For instance: $$\begin{verbatim} if known mpversion: message "mp = " & mpversion; if scantokens(mpversion) < 1: message "Поддержка цветов CMYK недоступна!" fi fi \end{verbatim} $$ печатает %%prints $$\begin{verbatim}[commandchars=\\\{\}] mp = \mpversion \end{verbatim} $$ Команда {\tt scantokens} описана на с.~\pageref{Dscantokens} и может быть употреблена для конвертирования строк в числа. \index{Комментарий Creator в выводе PostScript}% %%The {\tt scantokens} command is described on p.~\pageref{Dscantokens} %%and can be utilized to convert strings to numbers. %%\index{Creator comment in PostScript output}% Номер версии также включается в комментарий \texttt{Creator} в Postscript-выводе. %%The version number is also included in the \texttt{Creator} comment in %%the PostScript output. Этот документ представляет язык MetaPost, начиная с простейших для использования и наиболее важных для простых приложений свойств. %%This document introduces the MetaPost language, beginning with the %%features that are easiest to use and most important for simple %%applications. Чтение руководства не требует знания \MF\ или доступа к {\sl The \MF book}, но обе возможности будут полезными. %%Reading the manual does not require knowledge of \MF\ or %%access to {\sl The \MF book}, but both are beneficial. Первые несколько разделов описывают язык таким, каким он кажется пользователю-новичку с ключевыми параметрами, зафиксированными на предопределенных значениях. %%The first few sections describe the language as it %%appears to the novice user with key parameters at their default values. Некоторые свойства, определяемые в этих разделах, --- часть макропакета с именем Plain. %%Some features described in these sections are part of a predefined macro %%package called Plain. Следующие разделы охватывают весь язык и отличают примитивы от макросов из автоматически загружаемого макропакета Plain\index{макросы Plain}. %%Later sections summarize the complete language %%and distinguish between primitives and preloaded macros from the Plain %%macro package\index{Plain macros}. Вследствие того, что большая часть языка идентична \MF\ Кнута, приложение дает детальное сравнение таким образом, что опытные пользователи смогут узнать больше о MetaPost, читая {\sl The \MF book\/} \cite{kn:c}. %%Since much of the language is %%identical to Knuth's \MF, the appendix gives a detailed comparison so %%that advanced users can learn more about MetaPost by reading {\sl The %%\MF book\/} \cite{kn:c}. Документация к MetaPost дополняется ``Drawing Boxes with MetaPost'' --- руководством к пакету \texttt{graph}, изначально разработанному Джоном~Д. Хобби. %%MetaPost documentation is completed by ``Drawing Boxes with MetaPost'' %%and ``Drawing Graphs with MetaPost''---the manuals of the \texttt{boxes} %%and \texttt{graph} packages originally developed by John~D. Hobby. Домашняя страница MetaPost --- \url{http://tug.org/metapost}. %%The MetaPost home page is \url{http://tug.org/metapost}. Она содержит ссылки на много дополнительной информации, включая множество статей, которые написаны о MetaPost. %%It has links %%to much additional information, including many articles that have been %%written about MetaPost. При поиске подсказки попробуйте рассылку на \url{metapost@tug.org}; вы можете подписаться туда на \url{http://tug.org/mailman/listinfo/metapost}. %%For general help, try the %%\url{metapost@tug.org} mailing list; you can subscribe to this list at %%\url{http://tug.org/mailman/listinfo/metapost}. Текущая разработка размещена на \url{https://foundry.supelec.fr/projects/metapost/}; посетите этот сайт для контактов с членами текущей команды разработчиков, загрузки исходников и многого другого. %%The development is currently hosted at %%\url{https://foundry.supelec.fr/projects/metapost/}; visit this site %%for the current development team members, sources, and much else. Пожалуйста, сообщайте об ошибках и требуемых улучшениях в список на \url{metapost@tug.org} или через адреса, приведенные выше. %%Please report bugs and request enhancements either on the %%\url{metapost@tug.org} list, or through the address given above. Пожалуйста, не посылайте больше отчеты напрямую Dr.\ Hobby. %%(Please do not send reports directly to Dr.\ Hobby any more.) \section{Базовые команды для рисования} %%\section{Basic Drawing Statements} \label{basic} Простейшие команды рисования --- для генерации прямых линий. %The simplest drawing statements are the ones that generate straight lines. Таким образом\index{draw?\texttt{draw}}\index{-{}-?\texttt{-{}-}}, %%Thus\index{draw?\texttt{draw}}\index{-{}-?\texttt{-{}-}} $$ \hbox{\verb|draw (20,20)--(0,0)|} $$ рисует\index{draw?\texttt{draw}} диагональную линию и %%draws\index{draw?\texttt{draw}} a diagonal line and $$ \hbox{\verb|draw (20,20)--(0,0)--(0,30)--(30,0)--(0,0)|} $$ рисует ломаную линию, подобную этой: %%draws a polygonal line like this: $$ \includegraphics{manfig-ru-1} $$ \label{Ddrawdot}MetaPost также имеет команду \ttt{drawdot} для печати одной точки, например, \ttt{drawdot(30,0)}. %%\label{Ddrawdot}MetaPost also has a \ttt{drawdot} command to print a %%single point, as in \ttt{drawdot(30,0)}. Что означается координатами подобными \verb|(30,0)|? %%What is meant by coordinates like \verb|(30,0)|? MetaPost использует ту же самую типовую систему координат, что и PostScript\index{PostScript!система координат}. %%MetaPost uses the same %%default coordinate system that PostScript\index{PostScript!coordinate %%system} does. Это значит, что \verb|(30,0)| --- это 30 единиц вправо от начала координат, где единица --- это $1\over72$ дюйма. %%This %%means that \verb|(30,0)| is 30 units to the right of the origin, where a %%unit is $1\over72$ of an inch. Мы будем ссылаться на эту единицу измерения по-умолчанию как на {\sl PostScript-пункт}\index{PostScript!пункт}\index{пункт!PostScript} для отличения его от стандартного для принтеров пункта\index{пункт!принтера}, который равен $1\over72.27$ дюйма. %We shall refer to this default unit as a %{\sl PostScript point\/}\index{PostScript!point}\index{point!PostScript} %to distinguish it from the standard printer's %point\index{point!printer's} which is $1\over72.27$ inches. MetaPost использует те же имена для единиц измерения, что и \TeX\ и \MF. %%MetaPost uses the same names for units of measure that \TeX\ and \MF\ %%do. Таким образом, \verb|bp|\index{bp?\texttt{bp}}\label{Dbp} ссылается на PostScript-пункты (``большие пункты''), а \verb|pt|\index{pt?\texttt{pt}}\label{Dpt} --- на пункты принтера. %%Thus \verb|bp|\index{bp?\texttt{bp}}\label{Dbp} refers to %%PostScript points (``big points'') and %%\verb|pt|\index{pt?\texttt{pt}}\label{Dpt} refers to printer's points. Другие единицы измерения включают \verb|in|\index{in?\texttt{in}}\label{Din} для дюймов, \verb|cm|\index{cm?\texttt{cm}}\label{Dcm} для сантиметров и \verb|mm|\index{mm?\texttt{mm}}\label{Dmm} для миллиметров. %%Other units of measure include %%\verb|in|\index{in?\texttt{in}}\label{Din} for inches, %%\verb|cm|\index{cm?\texttt{cm}}\label{Dcm} for centimeters, and %%\verb|mm|\index{mm?\texttt{mm}}\label{Dmm} for millimeters. Например, %%For example, $$ \hbox{\verb|(2cm,2cm)--(0,0)--(0,3cm)--(3cm,0)--(0,0)|} $$ генерирует больший вариант диаграммы выше. %%generates a larger version of the above diagram. Будет верно сказать \verb|0| вместо \verb|0cm|, потому что {\tt cm} в действительности только множитель преобразования и {\tt 0cm} только умножает этот множитель на ноль. %%It is OK to say %%\verb|0| instead \verb|0cm| because {\tt cm} is really just a conversion %%factor and {\tt 0cm} just multiplies the conversion factor by zero. (MetaPost понимает конструкции подобные {\tt 2cm}\index{умножение, неявное} как сокращение для \verb|2*cm|). %%(MetaPost understands constructions like {\tt %%2cm}\index{multiplication, implicit} as shorthand for \verb|2*cm|). Удобно ввести свой собственный масштабирующий множитель, скажем $u$. %%It is convenient to introduce your own scale factor, say $u$. Затем вы можете определить координаты относительно $u$ и позже решать, хотите ли вы начать с \verb|u=1cm| или \verb|u=0.5cm|. %%Then you %%can define coordinates in terms of $u$ and decide later whether you want %%to begin with \verb|u=1cm| or \verb|u=0.5cm|. Это даст вам контроль над тем, что масштабируемо и над тем, что нет, т.~к. изменение $u$ не повлияет на такие свойства как толщина линий. %%This gives you control %%over what gets scaled and what does not so that changing $u$ will not %%affect features such as line widths. Есть много путей изменять вид линии сверх простого изменения ее толщины, однако механизмы управления шириной вводят много общих понятий, которыt нам пока еще не нужны. %%There are many ways to affect the appearance of a line besides just %%changing its width, so the width-control mechanisms allow a lot of %%generality that we do not need yet. Соответствующие команды могут странно выглядеть, например, команда\index{pickup?\texttt{pickup}}\index{pencircle?\texttt{pencircle}}% \index{scaled?\texttt{scaled}} %%This leads to the strange looking %%statement\index{pickup?\texttt{pickup}}\index{pencircle?\texttt{pencircle}}% %%\index{scaled?\texttt{scaled}} $$ \hbox{\verb|pickup pencircle scaled 4pt|} $$ устанавливает толщину линии в 4 пункта для последующей команды \verb|draw|. %%for setting the line width for subsequent \verb|draw| statements to 4 points. (Это примерно в 8 раз больше стандартной толщины линии). %%(This is about eight times the default line width). С такой большой толщиной даже линия длины ноль выглядит как большая жирная точка\index{точки}. %%With such a wide line width, even a line of zero length comes out as a big bold %%dot\index{dots}. Мы можем это использовать для создания решетки из жирных точек, имея одну команду \verb|drawdot| для каждого узла решетки. %%We can use this to make a grid of bold dots by having one %%\verb|drawdot| statement for each grid point. Такая повторяющаяся последовательность команд \verb|draw| записывается наилучшим образом как пара вложенных циклов:\index{циклы}% \index{for?\texttt{for}}\index{endfor?\texttt{endfor}} %%Such a repetitive sequence of \verb|draw| statements is %%best written as a pair of nested loops:\index{loops}% %%\index{for?\texttt{for}}\index{endfor?\texttt{endfor}} $$\begin{verbatim} for i=0 upto 2: for j=0 upto 2: drawdot (i*u,j*u); endfor endfor \end{verbatim} $$ Внешний цикл исполняется для $i=0,1,2$, а внутренний --- для $j=0,1,2$. %%The outer loop runs for $i=0,1,2$ and the inner loop runs for $j=0,1,2$. Результат --- решетка три на три из жирных точек, как показано на рис.~\ref{fig1}. %%The result is a three-by-three grid of bold dots as shown in Figure~\ref{fig1}. Этот рисунок включает также больший вариант ломаной линии, которую мы видели раньше. %%The figure also includes a larger version of the polygonal line diagram that we %%saw before. \begin{figure}[htp] $$ \begin{verbatim} beginfig(2); u=1cm; draw (2u,2u)--(0,0)--(0,3u)--(3u,0)--(0,0); pickup pencircle scaled 4pt; for i=0 upto 2: for j=0 upto 2: drawdot (i*u,j*u); endfor endfor endfig; \end{verbatim} \quad \mathcenter{\includegraphics{manfig-ru-2}} $$ \caption{Команды MetaPost и результирующий вывод} %%\caption{MetaPost commands and the resulting output} \label{fig1} \end{figure} Заметьте, что программа на рис.~\ref{fig1} начинается с \verb|beginfig(2)|\index{beginfig?\texttt{beginfig}} и заканчивается с \verb|endfig|\index{endfig?\texttt{endfig}}. %%Note that the program in Figure~\ref{fig1} starts with %%\verb|beginfig(2)|\index{beginfig?\texttt{beginfig}} and ends with %%\verb|endfig|\index{endfig?\texttt{endfig}}. Эти макросы, выполняющие административные функции, гарантируют, что результаты всех команд \verb|draw| собираются вместе и транслируются в PostScript. %%These are macros that %%perform various administrative functions and ensure that the results of %%all the \verb|draw| statements get packaged up and translated into %%PostScript. Входной файл для MetaPost обычно содержит последовательность пар \verb|beginfig| и \verb|endfig| с командой {\tt end}\index{end?\texttt{end}} после последней пары. %%A MetaPost input file normally contains a sequence of %%\verb|beginfig|, \verb|endfig| pairs with an {\tt %%end}\index{end?\texttt{end}} statement after the last one. Если этот файл именован {\tt fig.mp}, то вывод от команд \verb|draw| между \verb|beginfig(1)| и следующей \verb|endfig| пишется в файл {\tt fig.1}\index{файлы!вывод}. %%If this file %%is named {\tt fig.mp}, the output from \verb|draw| statements between %%\verb|beginfig(1)| and the next \verb|endfig| is written in a file {\tt %%fig.1}\index{files!output}. Другими словами, числовой аргумент в макросе \verb|beginfig| определяет имя соответствующего выходного файла. %%In other words, the numeric argument to the %%\verb|beginfig| macro determines the name of the corresponding output %%file. Что делать со всеми этими PostScript-файлами? %%What does one do with all the PostScript files? Они могут быть включены как рисунки в документы \TeX\index{TeX?\TeX} или troff\index{troff}, если вы имеете драйвер, который может работать с PostScript-картинками. %%They can be included as %%figures in a \TeX\index{TeX?\TeX} or troff\index{troff} document if you %%have an output driver that can handle encapsulated PostScript figures. Они также могут быть предварительно просмотрены до их включения в документ с тысячей страниц. %%They can also be previewed before they are included in a thousand pages %%document. Следующие разделы дают больше информации. %%The next sections give some more information. \section{Управление выводом MetaPost} %%\section{Handling MetaPost output} \label{Dmpoutput} Взаимодействие между \TeX\ и MetaPost может быть двояким. %%There can be a two-fold interaction between \TeX\ and MetaPost. С одной стороны, графика MetaPost может импортироваться в документы, набираемые \TeX\ и его друзьями. %%On one %%hand, MetaPost graphics can be imported into documents typeset by \TeX\ %%and friends. С другой стороны, MetaPost может поручить набор текстовых элементов \TeX, \LaTeX\ или \emph{troff}, например, текстовых меток или математических формул в графике. %%On the other hand, MetaPost can delegate typesetting %%textual elements to \TeX, \LaTeX\ or \emph{troff}, e.g., text labels or %%mathematical formulas in a graphic. Таким способом графика MetaPost может легко принять стиль документа (шрифт, размер шрифта и т.~п.) и соответствовать качеству его набора (использовать кернинг, лигатуры и т.~п.). %%That way, MetaPost graphics can %%easily adopt the style of a document (type, type size, etc.) and fit its %%typesetting quality (use kerning, ligatures, etc.) Это делает MetaPost идеальным инструментом для приготовления высококачественной графики для документов \TeX\ или \emph{troff}. %%This makes MetaPost %%an ideal tool for preparing high-quality graphics for \TeX\ or %%\emph{troff} documents. Этот раздел относится к первой стороне взаимодействия \TeX--MetaPost: импорту графики MetaPost в \TeX\ и его друзей. %%This section deals with the first aspect of \TeX--MetaPost interaction, %%the import of MetaPost graphics into \TeX\ and friends. Набор текстов в MetaPost обсуждается в разделе~\ref{text}. %%Typesetting %%text in MetaPost is discussed in section~\ref{text}. \subsection{Предварительный просмотр графики MetaPost} %%\subsection{Previewing MetaPost graphics} \label{Dpreview} \index{предпросмотр} %%\index{previewing} Вывод MetaPost --- это вариант PostScript, называемый Encapsulated PostScript\index{PostScript!структурный} (EPSF\index{EPSF}). %%The output of MetaPost is a variant of PostScript, called Encapsulated %%PostScript\index{PostScript!structured} (EPSF\index{EPSF}). Графика MetaPost может, следовательно, быть просмотрена в любом PostScript-просмотрщике, например, GSview\index{GSview}. %%MetaPost %%graphics can therefore be previewed with any decent PostScript viewer, %%e.\,g., GSview\index{GSview}. Ситуация становится только немного сложнее, когда вывод MetaPost содержит текст. %%The situation becomes only a little bit fussy when MetaPost output %%contains text. Обычно MetaPost не производит самодостаточные EPS-файлы, например, шрифты и таблицы кодировок не помещаются в вывод. %%By default, MetaPost doesn't produce self-contained EPS %%files, e.\,g., font resources and encoding vectors are not stored in %%the output. Поэтому вывод MetaPost, содержащий текст, может быть показан с неверными шрифтами, неверными символами или вообще без текста в PostScript-просмотрщике. %%For that reason MetaPost output containing text may be %%rendered with wrong fonts, wrong glyphs or with no text at all in a %%PostScript viewer. Долгое время, наиболее надежный путь для просмотра был в подготовке тест-документа, включающего все картинки MetaPost, обработке его либо \TeX, либо \LaTeX, затем \ttindex{dvips} и показу результирующего \ttt{ps}-файла в PostScript-просмотрщике.\footnote{Хотя есть и альтернативы: \ttindex{mpstoeps} --- это Perl-сценарий, который автоматизирует процесс, обозначенный выше, а \ttindex{mptopdf} --- это другое средство, которое конвертирует MetaPost-файлы в PDF.} %%For a long time, the most reliable way for %%previewing was to prepare a test document that includes all MetaPost %%figures, process that with \TeX\ or \LaTeX\ and \ttindex{dvips} and %%display the resulting \ttt{ps} file in a PostScript %%viewer.\footnote{There are alternatives, though. \ttindex{mpstoeps} is %%a Perl script that automates the process outlined above. %%\ttindex{mptopdf} is another tools that converts MetaPost files to %%PDF.} Однако, с версии 1.000 MetaPost ситуация изменилась. С этой версии MetaPost способен производить самодостаточные файлы EPS, которые могут быть достоверно просмотрены в независимости от того, есть ли в них текст или нет. %%However, with MetaPost version~1.000 the situation changed. Since that %%version MetaPost is able to produce self-contained EPS files, that can %%reliably be previewed, may they contain text or not. Новые возможности могут быть включены установкой внутренней переменной MetaPost \ttt{prologues}\index{prologues?\texttt{prologues}} в~3. %%The %%new behaviour can be triggered by setting MetaPost's internal variable %%\ttt{prologues}\index{prologues?\texttt{prologues}} to~3. Смотри раздел~\ref{Dbtex} для большей информации о \ttt{prologues}. %%See %%section~\ref{Dbtex} for more information on \ttt{prologues}. \subsection{Использование графики MetaPost в \TeX, \LaTeX, pdf\LaTeX, pdf\TeX, Con\TeX{}t и troff} %\subsection{Using MetaPost graphics in \TeX, \LaTeX, pdf\LaTeX, pdf\TeX, Con\TeX{}t and troff} \label{Dteximport} \index{TeX?\TeX!импорт файлов MetaPost} \index{LaTeX?\LaTeX!импорт файлов MetaPost} \index{pdfLaTeX?pdf\LaTeX!импорт файлов MetaPost} \index{pdfTeX?pdf\TeX!импорт файлов MetaPost} \index{ConTeXt?Con\TeX t!импорт файлов MetaPost} \index{troff!импорт файлов MetaPost} %%\index{TeX?\TeX!importing MetaPost files} %%\index{LaTeX?\LaTeX!importing MetaPost files} %%\index{pdfLaTeX?pdf\LaTeX!importing MetaPost files} %%\index{pdfTeX?pdf\TeX!importing MetaPost files} %%\index{ConTeXt?Con\TeX t!importing MetaPost files} %%\index{troff!importing MetaPost files} То как рисунки MetaPost могут быть интегрированы с документами, подготовленными в \TeX\ и родственных \TeX\ программах, зависит от формата документов и драйвера вывода. %%How MetaPost figures can be integrated into documents prepared with %%\TeX\ and friends depends on the exact format and output driver. Рис.~\ref{fig0} показывает процесс работы для plain \TeX, \LaTeX\ и свободно доступной программы \ttindex{dvips}\footnote{Исходники на C для \ttt{dvips} находятся вместе с web2c \TeX-дистрибутивом. Подобные программы доступны и в других местах.}. %%Figure~\ref{fig0} shows the workflow for plain \TeX, \LaTeX\ and the %%freely available program \ttindex{dvips}.\footnote{The C source for %%\ttt{dvips} comes with the web2c \TeX\ distribution. Similar programs %%are available from other sources.} Схожая процедура работает с troff: процессор вывода \ttt{grops} включает рисунки на PostScript, когда они запрашиваются через команду troff \ttt{\string\X}. %%A similar procedure works with %%troff: the \ttt{grops} output processor includes PostScript figures when %%they are requested via troff's \ttt{\string\X} command. С использованием PDF с \TeX\ и \LaTeX\ ситуация несколько иная. %%For the PDF %%flavour of \TeX\ and \LaTeX\ the situation is a little bit different. Следующие абзацы дают краткую информацию по некоторым популярным \TeX-форматам и драйверам вывода. %%The next paragraphs give brief information on some popular \TeX\ formats %%and output drivers. \begin{figure}[htp] $$ \includegraphics{manfig-ru-0} $$ \caption[Диаграмма обработки для документа с рисунками MetaPost] {Диаграмма обработки для \TeX-документа с рисунками в MetaPost} %%\caption[A diagram of the processing for a document with MetaPost figures] %% {A diagram of the processing for a \TeX\ document with figures %% in MetaPost} \label{fig0} \end{figure} \paragraph{\TeX} Пользователи \TeX\ могут импортировать графику, загрузив сначала пакет \ttt{epsf}\index{epsf.tex?\texttt{epsf.tex}} через \verb+\input epsf+ и затем введя команду $$ \verb+\epsfbox{+\descr{имя файла}\verb+}+ $$% \index{epsfbox?\texttt{\string\epsfbox}} для загрузки EPS-файла, например, \verb+\epsfbox{fig.1}+. %%\TeX\ users can import EPS graphics by first loading package %%\ttt{epsf}\index{epsf.tex?\texttt{epsf.tex}} via \verb+\input epsf+ and %%then issuing the command %%$$ \verb+\epsfbox{+\descr{filename}\verb+}+ $$% %%\index{epsfbox?\texttt{\string\epsfbox}} %%to load an EPS file, e.\,g., \verb+\epsfbox{fig.1}+. \paragraph{\LaTeX} Для документов \LaTeX\ процедура похожая: первый пакет \ttindex{graphicx} должен быть загружен размещением \verb+\usepackage{graphicx}+ в преамбулу документа и затем EPS-файлы могут быть загружены через $$ \verb+\includegraphics{+\descr{имя файла}\verb+}+, $$% \index{includegraphics?\texttt{\string\includegraphics}}% например, \verb+\includegraphics{fig.1}+. %%For \LaTeX\ documents the procedure is similar: first package %%\ttindex{graphicx} has to be loaded by putting %%\verb+\usepackage{graphicx}+ into the document preamble and then EPS %%files can be loaded via %%$$ \verb+\includegraphics{+\descr{filename}\verb+}+ $$% %%e.\,g., \verb+\includegraphics{fig.1}+. Как можно заметить на рис.~\ref{fig0} графические файлы никогда не включаются при исполнении \TeX\index{TeX?\TeX!импорт файлов MetaPost} или \LaTeX\index{LaTeX?\LaTeX!импорт файлов MetaPost}. %%As can be seen in figure~\ref{fig0} graphic files are never included in a %%\TeX\index{TeX?\TeX!importing MetaPost files} or %%\LaTeX\index{LaTeX?\LaTeX!importing MetaPost files} run. Вместо этого \TeX\ и \LaTeX\ только читают информацию об охватывающих рамках из PostScript-файла, резервируя столько места на странице, сколько занимает графика и записывая ссылку на соответствующий файл в \ttt{dvi}-выводе. %%Instead, %%\TeX\ and \LaTeX\ only read bounding box information off the PostScript %%file, reserve as much space on a page as the graphic %%occupies and write a reference to the corresponding file into the %%\ttt{dvi} output. Графический файл включается только при последующем исполнении драйвера вывода, который может обрабатывать PostScript-файлы, например, \ttindex{dvips}. %%The graphic file is only included in the subsequent %%run of an output driver, that can handle PostScript files, e.\,g., %%\ttindex{dvips}. \paragraph{pdf\LaTeX} Приложение pdf\LaTeX, когда исполняется в режиме PDF, является сразу и \LaTeX-интерпретатором, и драйвером вывода для документа в PDF-формат. %%The application pdf\LaTeX, when run in PDF mode, is both, a %%\LaTeX\ interpreter and an output driver for the PDF document format. Поэтому графические файлы включаются во время исполнения pdf\LaTeX, за один проход. %%For that reason graphic files are included in a single %%pdf\LaTeX\ run. В отличие от \ttt{dvips}, pdf\LaTeX\ не может обрабатывать обычные PostScript-файлы --- он может работать только с так называемыми очищенными EPS\index{PostScript!очищенный}-файлами, которые могут использовать только ограниченное множество возможностей языка PostScript. %%In contrast to \ttt{dvips}, pdf\LaTeX\ can't process %%general PostScript files, but only so-called purified %%EPS\index{PostScript!purified} files, which may only use a restricted %%set of PostScript language features. К счастью, вывод MetaPost --- это и \emph{есть} очищенный EPS, так что тут нам повезло. %%Fortunately, MetaPost output %%\emph{is} purified EPS, so we are in luck. Из того, что \ttt{mps}\index{файлы!mps?\texttt{mps}} --- это типовое расширение pdf\LaTeX\ для очищенных EPS-файлов, а вывод MetaPost обычно имеет расширения-числа, мы должны %%Since %%pdf\LaTeX's default extension for purified EPS files is %%\ttt{mps}\index{files!mps?\texttt{mps}}, but MetaPost output by %%default has a number as extensions, we either have to \begin{itemize} \item сказать pdf\LaTeX\ обрабатывать занумерованные файлы MetaPost согласно правилам для файлов \ttt{mps} или %%\item tell pdf\LaTeX\ to handle MetaPost's numbered files according to %%\ttt{mps} file rules, or \item изменить расширение файла вывода MetaPost на \ttt{mps}. %%\item change the file extension of MetaPost output to \ttt{mps}. \end{itemize} При первом подходе мы должны добавить строку %%For the conventional first approach we have to add the line $$ \verb+\DeclareGraphicsRule{*}{mps}{*}{}+ $$% \index{DeclareGraphicsRule?\texttt{\string\DeclareGraphicsRule}}% к преамбуле документа после загрузки пакета \ttt{graphicx}. %%to the document preamble after loading package \ttt{graphicx}. Эта декларация скажет pdf\LaTeX\ загружать \emph{все} файлы с неизвестным расширением как \ttt{mps}-файлы. %%That %%declaration tells pdf\LaTeX\ to load \emph{all} files with unknown file %%extensions as \ttt{mps} files. См. документацию по пакетам \ttt{graphicx} и \ttt{graphics} для дополнительной информации. %%Refer to the documentation of the %%\ttt{graphicx} and \ttt{graphics} packages for more details. С версии MetaPost 1.000 рекомендован второй подход.\footnote{Для обработки расширений MetaPost-файлов предположительно более естественно вместо \LaTeX-исходников использовать исходники MetaPost. Тем более, что установка расширения MetaPost-файла в \ttt{mps} предохраняет от загрязнения избытком расширений --- вам будет нужно зарегистрировать только одно расширение для вашего PostScript-просмотрщика --- \ttt{.mps}, вместо \ttt{.0}, \ttt{.1}, \ttt{.2} и т.~д.} %%Since MetaPost version~1.000 the second approach is %%recommended.\footnote{For handling MetaPost file extensions in MetaPost %%source files seems to be the more natural place than \LaTeX\ sources. %%Moreover, setting the MetaPost file extension to \ttt{mps} prevents from %%file extension pollution and you only have to register one new extension %%with your PostScript viewer, \ttt{.mps}, instead of \ttt{.0}, \ttt{.1}, %%\ttt{.2}, etc.} Примитив MetaPost \verb+filenametemplate+ может быть использован для установки расширения файла вывода MetaPost в \ttt{mps} (см. раздел~\ref{Dfilenametemplate}) %%The MetaPost primitive \verb+filenametemplate+ can be %%used to set the file extension of MetaPost output to \ttt{mps} (see %%section~\ref{Dfilenametemplate}). Поэтому декларация \verb+\DeclareGraphicsRule+ здесь не нужна. %%Hence, no \verb+\DeclareGraphicsRule+ %%declaration is needed. Более того, расширение может опускаться в команде \verb+\includegraphics+. %%Moreover, the file extension can then be omitted %%in the \verb+\includegraphics+ command. \paragraph{\LaTeX\ и pdf\LaTeX} Если вы хотите сохранить гибкость и возможность компилировать как \LaTeX, так и pdf\LaTeX, то нужно позаботиться о некоторых вещах. %%If you want to keep flexible and be able to compile your documents with %%both, \LaTeX\ and pdf\LaTeX, there are some things to take care of. Стандартная декларация \verb+\DeclareGraphicsRule+ может быть активирована только, если pdf\LaTeX\ исполняется в PDF-режиме. %%If %%you're using the conventional \verb+\DeclareGraphicsRule+ declaration, %%that may only be activated if pdf\LaTeX\ runs in PDF mode. Поэтому универсальная декларация должна выглядеть подобно этой: %%A fully-featured declaration should therefore look like this: $$ \begin{verbatim} \usepackage{graphicx} \usepackage{ifpdf} \ifpdf \DeclareGraphicsRule{*}{mps}{*}{} \fi \end{verbatim} $$ Если вы используете метод \ttt{filenametemplate}, то расширение файла \ttt{mps} не следует опускать в команде \verb+\includegraphics+, т.~к. \ttt{mps} --- это не часть имени \LaTeX-файла, заполняемая по-умолчанию. %%If you're using the \ttt{filenametemplate} method the \ttt{mps} file %%extension should not be omitted in \verb+\includegraphics+ commands, %%since \ttt{mps} is not part of \LaTeX's file name completion scheme, by %%default. Если расширение \ttt{mps} присутствует, то \LaTeX\ обрабатывает эти файлы как \ttt{eps}-файлы, что очевидно является корректным. %%If the \ttt{mps} extension is present, \LaTeX\ handles those %%files as \ttt{eps} files, which is obviously correct. Для дополнительной информации см. описание \verb+\DeclareGraphicsExtensions+% \index{DeclareGraphicsExtensions?\texttt{\string\DeclareGraphicsExtensions}} и \verb+\DeclareGraphicsRule+ в документации пакетов \ttt{graphicx} и \ttt{graphics}. %%For more %%information see the description of \verb+\DeclareGraphicsExtensions+% %%\index{DeclareGraphicsExtensions?\texttt{\string\DeclareGraphicsExtensions}} %%and \verb+\DeclareGraphicsRule+ in the documentation of packages %%\ttt{graphicx} and \ttt{graphics}. \paragraph{pdf\TeX} Пользователи plain pdf\TeX\ должны ознакомиться с отдельной программой \ttindex{mptopdf}, которую можно найти в \url{http://context.aanhet.net/mptopdf.htm}. %%Users of plain pdf\TeX\ should refer to the standalone macros of the %%\ttindex{mptopdf} bundle, that can be found at %%\url{http://context.aanhet.net/mptopdf.htm}. \paragraph{Con\TeX t} В Con\TeX t\index{ConTeXt?Con\TeX t} поддержка MetaPost интегрирована в ядро. %%In Con\TeX t\index{ConTeXt?Con\TeX t} support of MetaPost is integrated %%in the kernel. Отдельно от встроенной графики (см. руководство по MetaFun\index{MetaFun}) можно также встраивать графику извне командой \verb+\externalfigure+% \index{externalfigure?\texttt{\string\externalfigure}}. %%Apart from inline graphics (see MetaFun\index{MetaFun} %%manual), one can embed graphics explictely with the %%\verb+\externalfigure+% %%\index{externalfigure?\texttt{\string\externalfigure}} command. Занумерованные файлы распознаются автоматически, как графика с \ttt{mps}-расширением. %%Numbered graphics are recognized automatically, as are graphics with the %%\ttt{mps} suffix. Специальные свойства, такие как затенение, прозрачность, включение рисунков, цветовое пространство и подобные обрабатываются автоматически. %%Special features like shading, transparency, image %%inclusion, color spaces and such are handled automatically. Практически пользователи Con\TeX t будут вероятно определять графику MetaPost в документе-исходнике, который использует некоторые новшества, например, более естественный интерфейс со свойствами документа, поддержка шрифтов и автоматическая обработка. %%In practice %%Con\TeX t users will probably define MetaPost graphics in the document %%source which has some advantages, like a more natural interfacing with %%document properties, font support, and automatic processing. Поддержка включений MetaPost представлена в версиях MkII и MkIV, но используемые методы слегка различаются. %%Support %%for MetaPost inclusion is present in the versions MkII as well as MkIV, %%but the used methods are slightly different. Будущие версии MkIV будут поддерживать даже более тесную интеграцию. %%Future versions of MkIV %%will support an even more tight integration. \paragraph{troff} Также возможно включать вывод MetaPost в GNU \emph{troff}-документ. %%It is also possible to include MetaPost output in a GNU \emph{troff} %%document. Макропакет \ttt{-mpspic}\index{mpspic?\texttt{-mpspic}} определяет команду \verb|.PSPIC|\index{PSPIC?\texttt{.PSPIC}}, которая включает EPS-файл. %%The \ttt{-mpspic}\index{mpspic?\texttt{-mpspic}} macro %%package defines a command \verb|.PSPIC|\index{PSPIC?\texttt{.PSPIC}} %%that includes an encapsulated PostScript file. Например, команда \emph{troff} %%For instance, the \emph{troff} command $$ \hbox{\verb|.PSPIC fig.1|} $$ включает \ttt{fig.1}, используя заданные в файле охватывающей рамкой естественные высоту и ширину образа. %%includes \ttt{fig.1}, using the natural height and width of the %%image as given in the file's bounding box. \subsection{Шаблоны имен файлов} %%\subsection{File name templates} \suppressfloats[t] MetaPost поддерживает шаблоны для выходных файлов. %%MetaPost has support for output file name templates. Эти шаблоны используют стиль \ttt{printf} escape-последовательностей и пересчитываются перед тем, как рисунок записывается на диск %%These templates %%use \ttt{printf}-style escape sequences and are re-evaluated before %%each figure is written to disk. Здесь используется команда \ttt{filenametemplate}% \index{filenametemplate?\texttt{filenametemplate}}\label{Dfilenametemplate}, которая воспринимает строку-аргумент. %%The command to use is \ttt{filenametemplate}% %%\index{filenametemplate?\texttt{filenametemplate}}\label{Dfilenametemplate}, %%and it accepts a string as argument. Ее несложный синтаксис: %%The syntax is as simple as: \begin{center}\begin{tabular}{l} \verb|filenametemplate "%j-%3c.mps";|\\ \verb|beginfig(1);|\\ \verb| draw p;|\\ \verb|endfig;| \end{tabular}\end{center} Если исходный файл сохранялся как \ttt{fig.mp}, то будет создан выходной файл \ttt{fig-001.mps} вместо \ttt{fig.1}. %%If the file is saved as \ttt{fig.mp}, then this will create the output %%file \ttt{fig-001.mps} instead of \ttt{fig.1}. Маленькое множество возможных escape-последовательностей см. в таблице~\ref{tab:fntmpl}. %%A small set of escape %%sequences are possible, see table~\ref{tab:fntmpl} for details. \def\d{$\langle$0-9$\rangle$} \begin{table} \centering \begin{tabular}{|>{\ttfamily}l|l|} \hline \multicolumn1{|c|}{Escape-последовательность} & \multicolumn1{c|}{Смысл}\\\hline %%\multicolumn1{|c|}{Escape sequence} & \multicolumn1{c|}{Meaning}\\\hline \%\% & Знак процента \\ %%\%\% & A percent sign \\ \%\,j & Имя текущей работы\\ %%\%\,j & The current jobname\\ \%\d c & Значение {\tt charcode}\\ %%\%\d c & The charcode value\\ \%\d y & Текущий год\\ %%\%\d y & The current year\\ \%\d m & Номер месяца\\ %%\%\d m & The numeric month\\ \%\d d & День месяца\\ %%\%\d d & The day of the month\\ \%\d H & Час\\ %%\%\d H & The hour\\ \%\d M & Минута\\ %%\%\d M & The minute\\ \hline \end{tabular} \caption{Разрешенные escape-последовательности для \ttt{filenametemplate}} %%\caption{Allowed escape sequences for \ttt{filenametemplate}} \label{tab:fntmpl} \end{table} Примитив \ttt{filenametemplate} может быть также полезным для именования графических файлов индивидуально и еще для хранения всех MetaPost-исходников в одном файле. %%The \ttt{filenametemplate} primitive can also be helpful for naming %%graphic files individually, yet keeping all MetaPost sources in one file. Например, соберем исходники разных диаграмм в один файл \ttt{fig.mp} %%E.\,g., collecting different diagram sources in a file \ttt{fig.mp} $$ \begin{verbatim} filenametemplate "fig-quality.mps"; beginfig(1); ... endfig; filenametemplate "fig-cost-vs-productivity.mps"; beginfig(2); ... endfig; \end{verbatim} $$ --- может оказаться проще вспомнить правильное имя диаграммы в документе \TeX, чем нумерованное имя файла. %%it might be easier to recall the correct diagram names in a %%\TeX\ document than with numbered file names. Заметьте, что аргумент \ttt{beginfig} не используется при отсутствии образца \ttt{\%c} в строке шаблона имени файла. %%Note, the argument to %%\ttt{beginfig} is not relevant as long as there's no \ttt{\%c} pattern %%in the file name template string. Для обеспечения совместимости со старыми файлами начальное значение \ttt{filenametemplate} устанавливается в \verb|%j.%c|. %%To ensure compatibility with older files, the default value of %%\ttt{filenametemplate} is \verb|%j.%c|. Если вы присвоите пустую строку, то это будет означать возврат к начальному значению. %%If you assign an empty string, it will revert to that default. \section{Кривые} %%\section{Curves} \label{curves} MetaPost совершенно счастлив при рисовании как кривых, так и прямых линий. %%MetaPost is perfectly happy to draw curved lines as well as straight ones. Команда \verb|draw| с разделенными \verb|..|\index{..?\texttt{..}} аргументами-точками рисует плавную кривую через эти точки. %%A \verb|draw| statement with the points separated by %%\verb|..|\index{..?\texttt{..}} draws a smooth curve through the points. Например, посмотрите на результат %%For example consider the result of $$ \hbox{\verb|draw z0..z1..z2..z3..z4|} $$ после определения пяти точек таким образом: %%after defining five points as follows: $$\begin{verbatim} z0 = (0,0); z1 = (60,40); z2 = (40,90); z3 = (10,70); z4 = (30,50); \end{verbatim} $$ Рис.~\ref{fig2} показывает кривую через точки, помеченные от \verb|z0| до \verb|z4| %%Figure~\ref{fig2} shows the curve with points \verb|z0| through \verb|z4| %%labeled. \begin{figure}[htp] $$ \includegraphics{manfig-ru-3} $$ \caption[Кривая через точки 0, 1, 2, 3 и 4] {Результат {\tt draw z0..z1..z2..z3..z4}} %%\caption[A curve through points 0, 1, 2, 3, and 4] % {The result of {\tt draw z0..z1..z2..z3..z4}} \label{fig2} \end{figure} Есть много других способов нарисовать путь через те же самые пять точек. %%There are many other ways to draw a curved path through the same five %%points. Для получения гладкой замкнутой кривой соедините \verb|z4| с началом добавлением \verb|..cycle|\index{cycle?\texttt{cycle}} к команде \verb|draw| как показано на рис.~\ref{fig3}a. %%To make a smooth closed curve, connect \verb|z4| back to the %%beginning by appending \verb|..cycle|\index{cycle?\texttt{cycle}} to the %%\verb|draw| statement as shown in Figure~\ref{fig3}a. Также возможно в одной команде \verb|draw| смешивать кривые и прямые линии как показано на рис.~\ref{fig3}b. %%It is also %%possible in a single \verb|draw| statement to mix curves and straight %%lines as shown in Figure~\ref{fig3}b. Просто используйте \verb|--| там, где вы хотите прямые линии, и \verb|..| там, где вы хотите кривые. %%Just use \verb|--| where you want %%straight lines and \verb|..| where you want curves. Таким образом, %%Thus $$ \hbox{\verb|draw z0..z1..z2..z3--z4--cycle|} $$ произведет кривую через точки 0,~1, 2 и~3, затем ломаную линию из точки~3 в точку~4 и обратно в точку~0. %%produces a curve through points 0,~1, 2, and~3, then a polygonal line from %%point~3 to point~4 and back to point~0. Результат будет точно таким же как после двух команд рисования %%The result is essentially the same %%as having two draw statements \begin{eqnarray*} \hbox{\verb|draw z0..z1..z2..z3|}\\ \noalign{\hbox{и}} %%\noalign{\hbox{and}} \hbox{\verb|draw z3--z4--z0|} \end{eqnarray*} \begin{figure}[htp] $$ {\includegraphics{manfig-ru-104} \atop (a)} \qquad {\includegraphics{manfig-ru-204} \atop (b)} $$ \caption[Замкнутая кривая через пять точек] {(a)~Результат {\tt draw z0..\linebreak[0]z1..\linebreak[0]% z2..\linebreak[0]z3..\linebreak[0]z4..\linebreak[0]cycle}; (b)~Результат {\tt draw z0..\linebreak[0]z1..\linebreak[0]% z2..\linebreak[0]z3--\linebreak[0]z4--\linebreak[0]cycle}.} %%\caption[Closed curves through five points] %% {(a)~The result of {\tt draw z0..\linebreak[0]z1..\linebreak[0]% %% z2..\linebreak[0]z3..\linebreak[0]z4..\linebreak[0]cycle}; %% (b)~the result of {\tt draw z0..\linebreak[0]z1..\linebreak[0]% %% z2..\linebreak[0]z3--\linebreak[0]z4--\linebreak[0]cycle}.} \label{fig3} \end{figure} \subsection{Кубические кривые Безье} %%\subsection{B\'ezier Cubic Curves} Когда MetaPost просят нарисовать гладкую кривую через последовательность точек, он конструирует кусочную кубическую кривую с непрерывным уклоном и с приблизительно непрерывной кривизной\index{кривизна}. %%When MetaPost is asked to draw a smooth curve through a sequence of %%points, it constructs a piecewise cubic curve with continuous slope and %%approximately continuous curvature\index{curvature}. Это значит, что спецификация пути такая как %%This means that a %%path specification such as $$ \hbox{\verb|z0..z1..z2..z3..z4..z5|} $$ дает в результате кривую, что может быть определена параметрически\index{параметризация} как $(X(t),Y(t))$ для $0\leqslant t\leqslant5$, где $X(t)$ и $Y(t)$ --- кусочные кубические функции. %%results in a curve that can be defined parametrically\index{parameterization} %%as $(X(t),Y(t))$ for %%$0\le t\le5$, where $X(t)$ and $Y(t)$ are piecewise cubic functions. Таким образом существуют различные пары кубических функций для каждого ограниченного целыми числами интервала для $t$. %%That is, %%there is a different pair of cubic functions for each integer-bounded %%$t$-interval. Если ${\tt z0}=(x_0,y_0)$, ${\tt z1}=(x_1,y_1)$, ${\tt z2}=(x_2,y_2)$, \ldots, то MetaPost выбирает контрольные\index{управляющие точки} точки Безье %%If ${\tt z0}=(x_0,y_0)$, ${\tt z1}=(x_1,y_1)$, %%${\tt z2}=(x_2,y_2)$, \ldots, MetaPost selects %%B\'ezier control\index{control points} points $(x_0^+,y_0^+)$, $(x_1^-,y_1^-)$, $(x_1^+,y_1^+)$, \ldots, где %%where \begin{eqnarray*} X(t+i) &=& (1-t)^3x_i + 3t(1-t)^2x_i^+ + 3t^2(1-t)x_{i+1}^- + t^3x_{i+1},\\ Y(t+i) &=& (1-t)^3y_i + 3t(1-t)^2y_i^+ + 3t^2(1-t)y_{i+1}^- + t^3y_{i+1} \end{eqnarray*} для %%for $0\le t\le1$. Точные правила для выбора контрольных точек Безье приведены в \cite{ho:splin} и в {\sl \MF book\/}~\cite{kn:c}. %%The precise rules for choosing the B\'ezier control points %%are described in \cite{ho:splin} and in {\sl The \MF book\/}~\cite{kn:c}. Для того, чтобы путь имел непрерывный уклон в $(x_i,y_i)$ входящее и исходящее направления в $(X(i),Y(i))$ должны соответствовать. %%In order for the path to have a continuous slope at $(x_i,y_i)$, the incoming %%and outgoing directions at $(X(i),Y(i))$ must match. Таким образом, вектора %%Thus the vectors $$ (x_i-x_i^-,\,y_i-y_i^-) \qquad \hbox{и} %%\hbox{and} \qquad (x_i^+-x_i,\,y_i^+-y_i) $$ должны иметь одинаковое направление, т.~е. $(x_i,y_i)$ должна быть на отрезке линии между $(x_i^-,y_i^-)$ и $(x_i^+,y_i^+)$. %%must have the same direction; i.e., $(x_i,y_i)$ must be on the line segment %%between $(x_i^-,y_i^-)$ and $(x_i^+,y_i^+)$. Эта ситуация иллюстрируется на рис.~\ref{fig4}, где контрольные точки Безье, выбираемые MetaPost, соединены пунктирными линиями. %%This situation is illustrated %%in Figure~\ref{fig4} where the B\'ezier control points selected by MetaPost %%are connected by dashed lines. Для тех, кто знаком с интересными свойствами такой конструкции, MetaPost позволяет специфицировать контрольные точки напрямую в следующем формате: \index{controls?\texttt{controls}} %%For those who are familiar with the interesting %%properties of this construction, MetaPost allows the control points to be %%specified directly in the following format:\index{controls?\texttt{controls}} $$ \begin{verbatim} draw (0,0)..controls (26.8,-1.8) and (51.4,14.6) ..(60,40)..controls (67.1,61.0) and (59.8,84.6) ..(40,90)..controls (25.4,94.0) and (10.5,84.5) ..(10,70)..controls ( 9.6,58.8) and (18.8,49.6) ..(30,50); \end{verbatim} $$ \begin{figure}[htp] $$ \includegraphics{manfig-ru-5} $$ \caption[Кривая и управляющая ломаная] {Результат {\tt draw z0..z1..z2..z3..z4} с автоматически выбираемой управляющей ломаной Безье, иллюстрируемой пунктирными линиями.} %%\caption[A curve and the control polygon] %% {The result of {\tt draw z0..z1..z2..z3..z4} with the %% automatically-selected B\'ezier control polygon illustrated by dashed %% lines.} \label{fig4} \end{figure} \subsection{Спецификация направления, напряжения и изгиба} %%\subsection{Specifying Direction, Tension, and Curl} \label{tenscurl} MetaPost обеспечивает много способов управления поведением пути кривой без действительного указания контрольных точек. %%MetaPost provides many ways of controlling the behavior of a curved path %%without actually specifying the control points. Например, некоторые точки на пути могут быть выбраны как вертикальный или горизонтальный экстремумы. %%For instance, some %%points on the path may be selected as vertical or horizontal extrema. Если \verb|z1| следует быть горизонтальным экстремумом, а \verb|z2| --- вертикальным, то вы можете указать, что $(X(t),Y(t))$ должна идти вверх в \verb|z1| и влево в \verb|z2|: %%If \verb|z1| is to be a horizontal extreme and \verb|z2| is to be a %%vertical extreme, you can specify that $(X(t),Y(t))$ should go upward at %%\verb|z1| and to the left at \verb|z2|: $$ \hbox{\verb|draw z0..z1{up}..z2{left}..z3..z4;|} $$ Картинка-результат, показанная на рис.~\ref{fig5}, имеет желаемые вертикальное и горизонтальное направления в \verb|z1| и \verb|z2|, но она не выглядит такой плавной, как кривая на рис.~\ref{fig2}. %%The resulting shown in Figure~\ref{fig5} has the desired vertical and %%horizontal directions at \verb|z1| and \verb|z2|, but it does not look %%as smooth as the curve in Figure~\ref{fig2}. Это обусловлено большим разрывом в величине кривизны \index{кривизна} в \verb|z1|. %%The reason is the large %%discontinuity in curvature\index{curvature} at \verb|z1|. Если явно не указать направление в \verb|z1|, то MetaPost-интерпретатор выберет направление таким, чтобы кривизна над \verb|z1| была почти такой же как и кривизна под этой точкой. %%If it were %%not for the specified direction at \verb|z1|, the MetaPost interpreter %%would have chosen a direction designed to make the curvature above %%\verb|z1| almost the same as the curvature below that point. \begin{figure}[htp] $$ \includegraphics{manfig-ru-6} $$ \caption[Кривая и управляющая ломаная] {Результат {\tt draw z0..z1\char`\{up\char`\}..z2\char`\{left\char`\}% ..z3..z4}.} %%\caption[A curve and the control polygon] %% {The result of {\tt draw z0..z1\char`\{up\char`\}..z2\char`\{left\char`\}% %% ..z3..z4}.} \label{fig5} \end{figure} Как может выбор направлений в данных точках на кривой определять будет ли кривизна непрерывной? %%How can the choice of directions at given points on a curve determine whether %%the curvature will be continuous? Ответ в том, что кривые, используемые в MetaPost, пришли из семейства, где путь определяется своими концами и направлениями там. %%The reason is that curves used in MetaPost %%come from a family where a path is determined by its endpoints and the %%directions there. Рисунки \ref{fig6} и~\ref{fig7} дают хорошую идею о том, на что похоже это семейство кривых. %%Figures \ref{fig6} and~\ref{fig7} give a good idea of what %%this family of curves is like. \begin{figure}[htp] $$ \mathcenter{\includegraphics{manfig-ru-7}} \quad \begin{verbatim} beginfig(7) for a=0 upto 9: draw (0,0){dir 45}..{dir -10a}(6cm,0); endfor endfig; \end{verbatim} $$ \caption{Семейство кривых и инструкции MetaPost для его генерации} %%\caption{A curve family and the MetaPost instructions for generating it} \label{fig6} \end{figure} \begin{figure}[htp] $$ \mathcenter{\includegraphics{manfig-ru-8}} \quad \begin{verbatim} beginfig(8) for a=0 upto 7: draw (0,0){dir 45}..{dir 10a}(6cm,0); endfor endfig; \end{verbatim} $$ \caption{Другое семейство кривых с соответствующими инструкциями MetaPost} %%\caption{Another curve family with the corresponding MetaPost instructions} \label{fig7} \end{figure} Рисунки \ref{fig6} и~\ref{fig7} иллюстрируют новые возможности MetaPost. %%Figures \ref{fig6} and~\ref{fig7} illustrate a few new MetaPost %%features. Первая --- это оператор {\tt dir}\index{dir?\texttt{dir}}\label{Ddirop}, который по углу в градусах генерирует единичный вектор в этом направлении. %%The first is the {\tt %%dir}\index{dir?\texttt{dir}}\label{Ddirop} operator that takes an angle %%in degrees and generates a unit vector in that direction. Таким образом, \verb|dir 0| эквивалентен {\tt right}\index{right?\texttt{right}}\label{Dright} и \verb|dir 90| эквивалентен {\tt up}\index{up?\texttt{up}}\label{Dup}. %%Thus \verb|dir 0| is equivalent to {\tt %%right}\index{right?\texttt{right}}\label{Dright} and \verb|dir 90| is %%equivalent to {\tt up}\index{up?\texttt{up}}\label{Dup}. Есть также готовые вектора направлений {\tt left}\index{left?\texttt{left}}\label{Dleft} и {\tt down}\index{down?\texttt{down}}\label{Ddown} для {\tt dir 180} и {\tt dir 270}. %%There are also predefined direction vectors {\tt %%left}\index{left?\texttt{left}}\label{Dleft} and {\tt %%down}\index{down?\texttt{down}}\label{Ddown} for {\tt dir 180} and {\tt %%dir 270}. Вектора направлений, заданные в \verb|{}|, могут быть любой длины и они могут как входить в точку, так и выходить из нее. %%The direction %%vectors given in \verb|{}| can be of any length, and they can come before a %%point as well as after one. Возможно даже в спецификации пути иметь оба направления для одной точки, до и после. %%It is even possible for a path specification %%to have directions given before and after a point. Например, участок спецификации пути %%For example a path specification containing $$ \hbox{\verb|..{dir 60}(10,0){up}..|} $$ произведет кривую с углом в $(10,0)$. %%produces a curve with a corner at $(10,0)$. Заметьте, что некоторые кривые на рис.~\ref{fig6} имеют точки перегиба\index{перегибы}. %%Note that some of the curves in Figure~\ref{fig6} have points of %%inflection\index{inflections}. Это необходимо при создании гладкой кривой в ситуации подобной рис.~\ref{fig3}a, но это вероятно нежелательно при работе с вертикальными и горизонтальными точками экстремума как показано на рис.~\ref{fig8}a. %%This is necessary in order to produce %%smooth curves in situations like Figure~\ref{fig3}a, but it is probably %%not desirable when dealing with vertical and horizontal extreme points %%as in Figure~\ref{fig8}a. Если \verb|z1| нужно сделать наивысшей точкой на кривой, то это можно получить, используя \verb|...|\index{...?\texttt{...}} вместо \verb|..| в спецификации пути как показано на рис.~\ref{fig8}b. %%If \verb|z1| is supposed to be the topmost %%point on the curve, this can be achieved by using %%\verb|...|\index{...?\texttt{...}} instead of \verb|..| in the path %%specification as shown in Figure~\ref{fig8}b. Значение \verb|...| --- это ``выбрать свободный от перегибов путь между этими точками, если направления в концовых точках дают такую возможность''. %%The meaning of \verb|...| %%is ``choose an inflection-free path between these points unless the %%endpoint directions make this impossible.'' На рис.~\ref{fig6} возможно избавиться от перегибов, а на рис.~\ref{fig7} нет. %%(It would be possible to %%avoid inflections in Figure~\ref{fig6}, but not in Figure~\ref{fig7}). \begin{figure}[htp] $$ {\mathcenter{\includegraphics{manfig-ru-109}} \atop \hbox{\verb|draw z0{up}..z1{right}..z2{down}|}} \quad {\mathcenter{\includegraphics{manfig-ru-209}} \atop \hbox{\verb|draw z0{up}...z1{right}...z2{down}|}} $$ \caption{Две команды {\tt draw} и кривая-результат.} %%\caption{Two {\tt draw} statements and the resulting curves.} \label{fig8} \end{figure} Другой способ управлять неподходящим путем в увеличении параметра "напряжение"\index{напряжение}. %%Another way to control a misbehaving path is to increase the %%``tension''\index{tension} parameter. Использование \verb|..| в спецификации пути устанавливает параметр напряжения в типовое значение 1. %%Using \verb|..| in a path %%specification sets the tension parameter to the default value~1. Если это делает некоторую часть пути слишком дикой, то мы можем выборочно увеличить напряжение. %%If this makes some part of a path a little too wild, we can selectively %%increase the tension. Если рис.~\ref{fig9}a рассматривается как ``слишком дикий'', то команда {\tt draw} в следующей форме увеличит напряжение между {\tt z1} и {\tt z2}: %%If Figure~\ref{fig9}a is considered ``too wild,'' %%a {\tt draw} statement of the following form increases the tension %%between {\tt z1} and {\tt z2}: $$ \hbox{\verb|draw z0..z1..tension 1.3..z2..z3|} $$ Это произведет рис.~\ref{fig9}b. %%This produces Figure~\ref{fig9}b. Для асимметричного эффекта подобного рис.~\ref{fig9}c, команда \verb|draw| получает вид %%For an asymmetrical effect like %%Figure~\ref{fig9}c, the \verb|draw| statement becomes $$ \hbox{\verb|draw z0..z1..tension 1.5 and 1..z2..z3|} $$ Параметр напряжения может быть меньшим единицы, но он должен быть не менее $3\over4$. %%The tension parameter can be less than one, but it must be at least $3\over4$. \begin{figure}[htp] $$ {\mathcenter{\includegraphics{manfig-ru-110}} \atop (a)} \quad {\mathcenter{\includegraphics{manfig-ru-210}} \atop (b)} \quad {\mathcenter{\includegraphics{manfig-ru-310}} \atop (c)} $$ \caption[Эффект изменения параметра напряжения] {Результаты {\tt draw z0..z1..tension} $\alpha$ {\tt и} $\beta$ {\tt ..z2..z3} для разных $\alpha$ и $\beta$: %%\caption[Effects of changing the tension parameter] %% {Results of {\tt draw z0..z1..tension} $\alpha$ {\tt and} $\beta$ %% {\tt ..z2..z3} for various $\alpha$ and $\beta$: (a)~$\alpha=\beta=1$; (b)~$\alpha=\beta=1.3$; (c)~$\alpha=1.5$, $\beta=1$.} \label{fig9} \end{figure} Пути MetaPost имеют также параметр, называемый ``изгиб''\index{curl?\texttt{curl}}, который влияет на концы путей. %%MetaPost paths also have a parameter called %%``curl''\index{curl?\texttt{curl}} that affects the ends of a path. При отсутствии спецификаций направления первый и последний отрезки нециклического пути --- это приблизительно дуги окружности, как в случае $c=1$ на рис.~\ref{fig10}. %%In %%the absence of any direction specifications, the first and last segments %%of a non-cyclic path are approximately circular arcs as in the $c=1$ %%case of Figure~\ref{fig10}. Для использования другого значения для параметра изгиба укажите \verb|{curl c}| для некоторого значения $c$. %%To use a different value for the curl %%parameter, specify \verb|{curl c}| for some other value of $c$. Таким образом, %%Thus $$ \hbox{\verb|draw z0{curl c}..z1..{curl c}z2|} $$ установит параметр изгиба для \verb|z0| и \verb|z2|. %%sets the curl parameter for \verb|z0| and \verb|z2|. Маленькие значения параметра изгиба уменьшают кривизну\index{кривизна} в указанных концовых точках пути, а большие значения увеличивают кривизну как показано на рис.~\ref{fig10}. %%Small values of %%the curl parameter reduce the curvature\index{curvature} at the %%indicated path endpoints, while large values increase the curvature as %%shown in Figure~\ref{fig10}. В частности, значение изгиба ноль делает кривизну нулевой. %%In particular, a curl value of zero makes %%the curvature approach zero. \begin{figure}[htp] $$ {\mathcenter{\includegraphics{manfig-ru-111}} \atop c=0} \qquad {\mathcenter{\includegraphics{manfig-ru-211}} \atop c=1} \qquad {\mathcenter{\includegraphics{manfig-ru-311}} \atop c=2} \qquad {\mathcenter{\includegraphics{manfig-ru-411}} \atop c=\infty} $$ \caption[Эффект изменения параметра изгиба] {Результаты {\tt draw z0\char`\{curl c\char`\}..z1..% \char`\{curl c\char`\}z2} для разных значений параметра изгиба~$c$.} %%\caption[Effects of changing the curl parameter] %% {Results of {\tt draw z0\char`\{curl c\char`\}..z1..% %% \char`\{curl c\char`\}z2} for various values %% of the curl parameter~$c$.} \label{fig10} \end{figure} \subsection{Полный синтаксис пути} %%\subsection{Summary of Path Syntax} Есть еще несколько других свойств синтаксиса пути MetaPost, но они относительно неважны. %%There are a few other features of MetaPost path syntax, but they are %%relatively unimportant. Из-за того, что \MF\ использует такой же синтаксис пути, заинтересованным читателям стоит посмотреть \cite[раздел 14]{kn:c}. %%Since \MF\ uses the same path syntax, %%interested readers can refer to \cite[chapter 14]{kn:c}. Сводка синтаксиса пути на рис.~\ref{sypath} включает все, обсуждаемое до сих пор, включая конструкции \verb|--| и \verb|...|, которые \cite{kn:c} показывает как макросы, а не примитивы. %%The summary of %%path syntax in Figure~\ref{sypath} includes everything discussed so far %%including the \verb|--| and \verb|...| constructions which \cite{kn:c} %%shows to be macros rather than primitives. Несколько комментариев по семантике приведены здесь: если непустой $\descr{указатель направления}$ стоит перед $\descr{узлом пути}$, но не после, или наоборот, то указанное направление (или величина изгиба) прилагается как к входящим, так и к выходящим отрезкам пути. %%A few comments on the %%semantics are in order here: If there is a non-empty $\descr{direction %%specifier}$ before a $\descr{path knot}$ but not after it, or vice %%versa, the specified direction (or curl amount) applies to both the %%incoming and outgoing path segments. Похожее соглашение применяется, когда спецификатор $\descr{управления}$ дает только одну $\descr{первичную пару}$. %%A similar arrangement applies when %%a $\descr{controls}$ specification gives only one $\descr{pair %%primary}$. Таким образом, %%Thus $$ \hbox{\verb|..controls (30,20)..|} $$ эквивалентно %%is equivalent to $$ \hbox{\verb|...controls (30,20) and (30,20)..|} $$ \begin{figure}[htp] \begin{ctabbing} $\descr{выражение-путь} \rightarrow \descr{подвыражение-путь}$\\ \qquad \= ${}\mid \descr{подвыражение-путь} \descr{указатель направления}$\\ \> ${}\mid \descr{подвыражение-путь} \descr{соединитель пути}$ \verb|cycle|\\ $\descr{подвыражение-путь} \rightarrow \descr{узел пути}$\\ \> ${}\mid \descr{выражение-путь} \descr{соединитель пути} \descr{узел пути}$\\ $\descr{соединитель пути} \rightarrow \hbox{\verb|--|}$\\ \> ${}\mid \descr{указатель направления} \descr{базовый соединитель пути} \descr{указатель направления}$\\ $\descr{указатель направления} \rightarrow \descr{пусто}$\\ \> ${}\mid {}$\verb|{curl| $\descr{числовое выражение}$\verb|}|\\ \> ${}\mid {}$\verb|{|$\descr{выражение-пара}$\verb|}|\\ \> ${}\mid {}$\verb|{|$\descr{числовое выражение}$\verb|,|% $\descr{числовое выражение}$\verb|}|\\ $\descr{базовый соединитель пути} \rightarrow \hbox{\verb|..|} \mid \hbox{\verb|...|} \mid \hbox{\verb|..|}\descr{напряжение}\hbox{\verb|..|} \mid \hbox{\verb|..|}\descr{управление}\hbox{\verb|..|}$\\ $\descr{напряжение} \rightarrow \hbox{\verb|tension|}\descr{числовая первичность}$\\ \> ${}\mid \hbox{\verb|tension|}\descr{числовая первичность} \hbox{\verb|and|}\descr{числовая первичность}$\\ $\descr{управление} \rightarrow \hbox{\verb|controls|}\descr{первичная пара}$\\ \> ${}\mid \hbox{\verb|controls|}\descr{первичная пара} \hbox{\verb|and|}\descr{первичная пара}$ %%$\descr{path expression} \rightarrow %% \descr{path subexpression}$\\ %%\qquad \= ${}\mid \descr{path subexpression} \descr{direction specifier}$\\ %%\> ${}\mid \descr{path subexpression} \descr{path join}$ \verb|cycle|\\ %%$\descr{path subexpression} \rightarrow %% \descr{path knot}$\\ %%\> ${}\mid \descr{path expression} \descr{path join} \descr{path knot}$\\ %%$\descr{path join} \rightarrow %% \hbox{\verb|--|}$\\ %%\> ${}\mid \descr{direction specifier} \descr{basic path join} %% \descr{direction specifier}$\\ %%$\descr{direction specifier} \rightarrow %% \descr{empty}$\\ %%\> ${}\mid {}$\verb|{curl| $\descr{numeric expression}$\verb|}|\\ %%\> ${}\mid {}$\verb|{|$\descr{pair expression}$\verb|}|\\ %%\> ${}\mid {}$\verb|{|$\descr{numeric expression}$\verb|,|% %% $\descr{numeric expression}$\verb|}|\\ %%$\descr{basic path join} \rightarrow %% \hbox{\verb|..|} %% \mid \hbox{\verb|...|} %% \mid \hbox{\verb|..|}\descr{tension}\hbox{\verb|..|} %% \mid \hbox{\verb|..|}\descr{controls}\hbox{\verb|..|}$\\ %%$\descr{tension} \rightarrow %% \hbox{\verb|tension|}\descr{numeric primary}$\\ %%\> ${}\mid \hbox{\verb|tension|}\descr{numeric primary} %% \hbox{\verb|and|}\descr{numeric primary}$\\ %%$\descr{controls} \rightarrow %% \hbox{\verb|controls|}\descr{pair primary}$\\ %%\> ${}\mid \hbox{\verb|controls|}\descr{pair primary} %% \hbox{\verb|and|}\descr{pair primary}$ \end{ctabbing} \caption{Синтаксис конструкции пути} %%\caption{The syntax for path construction} \label{sypath} \end{figure} Пара координат, подобная \verb|(30,20)| или переменной \verb|z|, представляющей координатную пару, --- это то, что на рис.~\ref{sypath} зовется $\descr{первичной парой}$. %%A pair of coordinates like \verb|(30,20)| or a \verb|z| variable that %%represents a coordinate pair is what Figure~\ref{sypath} calls a %%$\descr{pair primary}$. Похожим является $\descr{узел пути}$ за исключением того, что он может приобретать другие формы, такие как выражение пути в скобках. %%A $\descr{path knot}$ is similar except that it %%can take on other forms such as a path expression in parentheses. Первичности и выражения различных типов будут обсуждаться в полном объеме в разделе~\ref{exprs}. %%Primaries and expressions of various types will be discussed in full %%generality in Section~\ref{exprs}. \section{Линейные уравнения} %%\section{Linear Equations} \label{lin.eq} Важным свойством, взятым из \MF, является возможность решать линейные уравнения, вследствие этого программы могут писаться в частично декларативной манере. %%An important feature taken from \MF\ is the ability to solve linear %%equations so that programs can be written in a partially declarative fashion. Например, MetaPost-интерпретатор может считать %%For example, the MetaPost interpreter can read $$ \hbox{\verb|a+b=3; 2a=b+3;|} $$ и вывести, что $a=2$ и $b=1$. %%and deduce that $a=2$ and $b=1$. Эти же выражения могут быть записаны слегка более компактно путем соединения их вместе несколькими знаками равенства: %%The same equations can be written %%slightly more compactly by stringing them together with multiple equal %%signs: $$ \hbox{\verb|a+b = 2a-b = 3;|} $$ Каким бы способом вы не задавали уравнения, вы можете затем дать команду\index{show?\texttt{show}} %%Whichever way you give the equations, you can then give the %%command\index{show?\texttt{show}} $$ \hbox{\tt show a,b;} $$ для просмотра значений {\tt a} и {\tt b}. %%to see the values of {\tt a} and {\tt b}. MetaPost ответит, напечатав %%MetaPost responds by typing $$\begin{verbatim} >> 2 >> 1 \end{verbatim} $$ Заметьте, что {\tt =}\index{=?\texttt{=}} не является оператором присваивания; он просто объявляет, что левая часть равна правой. %%Note that {\tt =}\index{=?\texttt{=}} is not an assignment operator; it %%simply declares that the left-hand side equals the right-hand side. Таким образом, {\tt a=a+1} приведет к сообщению об ошибке, жалующемуся на ``противоречивое уравнение\index{Inconsistent equation?\texttt{Inconsistent equation}}''. %%Thus {\tt a=a+1} produces an error message complaining about an %%``inconsistent equation\index{Inconsistent equation?\texttt{Inconsistent %%equation}}.'' Способ увеличения значения {\tt a} --- в использовании оператора присваивания\index{присваивание} {\tt :=}\index{:=?\texttt{:=}} как в примере: %%The way to increase the value of {\tt a} is to use the %%assignment\index{assignment} operator {\tt :=}\index{:=?\texttt{:=}} as %%follows: $$ \hbox{\tt a:=a+1;} $$ Другими словами, {\tt :=} для изменения существующих значений, а {\tt =} для задания линейных уравнений для решения. %%In other words, {\tt :=} is for changing existing values while {\tt =} is for %%giving linear equations to solve. Нет ограничений на смешивание уравнений и операций присваивания, например, %%There is no restriction against mixing equations and assignment %%operations as in the following example: $$ \hbox{\tt a = 2; b = a; a := 3; c = a;} $$ После первых двух уравнений, устанавливающих {\tt a} и~{\tt b} равными 2, операция присваивания изменит {\tt a} на~3 без влияния на {\tt b}. %%After the first two equations set {\tt a} and~{\tt b} equal to 2, the %%assignment operation changes {\tt a} to~3 without affecting {\tt b}. Окончательное значение {\tt c} --- 3, т.~к. оно приравняется новому значению {\tt a}. %%The final value of {\tt c} is 3 since it is equated to the new value of %%{\tt a}. В общем, операция присваивания интерпретируется сначала вычислением нового значения и затем уничтожением старого значения из всех существующих уравнений перед собственно присваиванием. %%In general, an assignment operation is interpreted by first %%computing the new value, then eliminating the old value from all %%existing equations before actually assigning the new value. \subsection{Уравнения и координатные пары} %%\subsection{Equations and Coordinate Pairs} MetaPost может также решать линейные уравнения, содержащие координатные пары. %%MetaPost can also solve linear equations involving coordinate pairs. Мы уже видели много тривиальных примеров этого в форме уравнений, подобных %%We have %%already seen many trivial examples of this in the form of equations like $$ \hbox{\verb|z1=(0,.2in)|} $$ Каждая сторона уравнения должна быть сформирована сложением или вычитанием координатных пар и умножением или делением их на известные числовые количества. %%Each side of the equation must be formed by adding or subtracting %%coordinate pairs and multiplying or dividing them by known numeric %%quantities. Другие способы именования пар значений переменных будут обсуждаться позже, а пока рассмотрим именование вида ${\tt z}\descr{число}$\index{z convention?{\tt z}-соглашение}, которое весьма удобно, потому что оно --- сокращение для $$ \hbox{\tt (x}\descr{число} \hbox{\tt, y}\descr{число}\hbox{\tt)} $$ %%Other ways of naming pair-valued variables will be %%discussed later, but the ${\tt z}\descr{number}$\index{z convention?{\tt %%z} convention} is convenient because it is an abbreviation for %%$$ \hbox{\tt (x}\descr{number} \hbox{\tt, y}\descr{number}\hbox{\tt)} $$ Это делает возможным давать значения переменным \verb|z| заданием уравнений для их координат. %%This makes it possible to give values to \verb|z| variables by giving %%equations involving their coordinates. Например, точки {\tt z1}, {\tt z2}, {\tt z3}, и~{\tt z6} на рис.~\ref{fig12} были инициализированы следующими уравнениями: %%For instance, points {\tt z1}, %%{\tt z2}, {\tt z3}, and~{\tt z6} in Figure~\ref{fig12} were initialized %%via the following equations: \begin{eqnarray*} &&\hbox{\verb|z1=-z2=(.2in,0);|} \\ &&\hbox{\verb|x3=-x6=.3in;|} \\ &&\hbox{\verb|x3+y3=x6+y6=1.1in;|} \end{eqnarray*} В точности те же самые точки могли быть получены прямой установкой их значений: %%Exactly the same points could be obtained by setting their values directly: $$ \begin{verbatim} z1=(.2in,0); z2=(-.2in,0); z3=(.3in,.8in); z6=(-.3in,1.4in); \end{verbatim} $$ После чтения уравнений MetaPost-интерпретатор знает значения {\tt z1}, {\tt z2}, {\tt z3} и~{\tt z6}. %%After reading the equations, the MetaPost interpreter knows the values %%of {\tt z1}, {\tt z2}, {\tt z3}, and~{\tt z6}. Следующий шаг в конструировании рис.~\ref{fig12} --- это определение точек {\tt z4} и {\tt z5}, одинаково удаленных от {\tt z3} и {\tt z6} и лежащих на одной линии с ними. %%The next step in the %%construction of Figure~\ref{fig12} is to define points {\tt z4} and {\tt %%z5} equally spaced along the line from {\tt z3} to {\tt z6}. Потому как эта операция появляется часто, MetaPost имеет для нее специальный синтаксис. %%Since this %%operation comes up often, MetaPost has a special syntax for it. Усредняющая конструкция\index{усреднение}\index{[]?\texttt{[]}!усреднение} %%This %%mediation construction\index{mediation}\index{[]?\texttt{[]}!mediation} $$ \hbox{\verb|z4=1/3[z3,z6]|} $$ означает, что {\tt z4} прошла $1\over3$ пути от $z3$ до $z6$, т.~е. %%means that {\tt z4} is $1\over3$ of the way from $z3$ to $z6$; i.e., $$ {\tt z4}={\tt z3}+{1\over3}({\tt z6}-{\tt z3}). $$ Схожая конструкция %%Similarly $$ \hbox{\verb|z5=2/3[z3,z6]|} $$ устанавливает {\tt z5} на $2\over3$ пути от $z3$ до $z6$. %%makes {\tt z5} $2\over3$ of the way from $z3$ to $z6$. \begin{figure}[htp] $$ \begin{verbatim} beginfig(13); z1=-z2=(.2in,0); x3=-x6=.3in; x3+y3=x6+y6=1.1in; z4=1/3[z3,z6]; z5=2/3[z3,z6]; z20=whatever[z1,z3]=whatever[z2,z4]; z30=whatever[z1,z4]=whatever[z2,z5]; z40=whatever[z1,z5]=whatever[z2,z6]; draw z1--z20--z2--z30--z1--z40--z2; pickup pencircle scaled 1pt; draw z1--z2; draw z3--z6; endfig; \end{verbatim} \quad \mathcenter{\includegraphics{manfig-ru-13}} $$ \caption[Код MetaPost, использующий линейные уравнения, и рисунок] {Команды MetaPost и рисунок-результат. Ярлыки точек добавлены к рисунку для ясности.} %%\caption[MetaPost code and figure using linear equations] %% {MetaPost commands and the resulting figure. Point labels have been %% added to the figure for clarity.} \label{fig12} \end{figure} Усреднение может быть также использовано для того, чтобы сказать, что некоторая точка находится в неизвестной позиции на прямой между двумя известными точками. %%Mediation can also be used to say that some point is at an unknown %%position along the line between two known points. Например, мы можем ввести новую переменную {\tt aa} и записать что-то вроде %%For instance, we %%could a introduce new variable {\tt aa} and write something like $$ \hbox{\verb|z20=aa[z1,z3];|} $$ Это означает, что {\tt z20} --- это неизвестное отношение {\tt aa} пути по прямой между {\tt z1} и {\tt z3}. %%This says that {\tt z20} is some unknown fraction {\tt aa} of the way %%along the line between {\tt z1} and {\tt z3}. Еще одного такого отношения для другой линии достаточно для фиксации значения {\tt z20}. %%Another such equation %%involving a different line is sufficient to fix the value of {\tt z20}. Описание того, что {\tt z20} пересечение прямых {\tt z1}-{\tt z3} и {\tt z2}-{\tt z4} вводит еще одну переменную {\tt ab} и устанавливается %%To say that {\tt z20} is at the intersection of the {\tt z1}-{\tt z3} %%line and the {\tt z2}-{\tt z4} line, introduce another variable {\tt ab} %%and set $$ \hbox{\verb|z20=ab[z2,z4];|} $$ Это позволяет MetaPost найти {\tt x20}, {\tt y20}, {\tt aa} и {\tt ab}. %%This allows MetaPost to solve for {\tt x20}, {\tt y20}, {\tt aa}, and {\tt ab}. Несколько сложновато постоянно думать о новых именах, подобных {\tt aa} и {\tt ab}. %%It is a little painful to keep thinking up new names like {\tt aa} and %%{\tt ab}. Этого можно избежать, используя специальную возможность, называемую {\tt whatever}\index{whatever?\texttt{whatever}}\label{Dwhatev}. %%This can be avoided by using a special feature called {\tt %%whatever}\index{whatever?\texttt{whatever}}\label{Dwhatev}. Этот макрос генерирует новую анонимную переменную каждый раз, когда он появляется. %%This macro %%generates a new anonymous variable each time it appears. Таким образом, команда %%Thus the statement $$ \hbox{\verb|z20=whatever[z1,z3]=whatever[z2,z4]|} $$ устанавливает {\tt z20} как и раньше, но она использует {\tt whatever} для генерации двух {\em различных\/} анонимных переменных вместо {\tt aa} и {\tt ab}. %%sets {\tt z20} as before, except it uses {\tt whatever} to generate two %%{\em different\/} anonymous variables instead of {\tt aa} and {\tt ab}. Рис.~\ref{fig12} показывает как устанавливаются {\tt z20}, {\tt z30} и {\tt z40}. %%This is how Figure~\ref{fig12} sets {\tt z20}, {\tt z30}, and %%{\tt z40}. \subsection{Работа с неизвестными} %%\subsection{Dealing with Unknowns} Уравнения в системе такой, как на рис.~\ref{fig12}, могут быть заданы в любом порядке, но все уравнения должны быть линейными и все переменные должно быть возможным вычислить тогда, когда они понадобятся. %%A system of equations such as those used in Figure~\ref{fig12} can be given in %%any order as long as all the equations are linear and all the variables can %%be determined before they are needed. Это значит, что уравнения %%This means that the equations \begin{eqnarray*} && \hbox{\verb|z1=-z2=(.2in,0);|}\\ && \hbox{\verb|x3=-x6=.3in;|}\\ && \hbox{\verb|x3+y3=x6+y6=1.1in;|}\\ && \hbox{\verb|z4=1/3[z3,z6];|}\\ && \hbox{\verb|z5=2/3[z3,z6];|} \end{eqnarray*} достаточны для определения {\tt z1} и остальных до {\tt z6} и порядок уравнений не важен. %%suffice to determine {\tt z1} through {\tt z6}, no matter what order the %%equations are given in. С другой стороны %%On the other hand $$ \hbox{\verb|z20=whatever[z1,z3]|} $$ будет правильно только в случае, когда известное значение было предварительно указано для разности ${\tt z3}-{\tt z1}$, потому что это уравнение эквивалентно\index{усреднение} %%is legal only when a known value has previously been specified for the difference %%${\tt z3}-{\tt z1}$, because the equation is equivalent %%to\index{mediation} $$ \hbox{\verb|z20 = z1 + whatever*(z3-z1)|} $$ и требования линейности не позволяют умножать неизвестные компоненты ${\tt z3}-{\tt z1}$ на анонимный неизвестный результат {\tt whatever}. %%and the linearity requirement disallows multiplying unknown components %%of ${\tt z3}-{\tt z1}$ by the anonymous unknown result of {\tt %%whatever}. Общее правило в том, что вы не можете умножать два неизвестных количества, делить на неизвестное количество или использовать неизвестное количество в команде {\tt draw}. %%The general rule is that you cannot multiply two unknown %%quantities or divide by an unknown quantity, nor can an unknown quantity %%be used in a {\tt draw} statement. Из-за того, что разрешены только линейные уравнения, MetaPost-интерпретатор может легко решать уравнения и хранить информацию о том, какие величины известны. %%Since only linear equations are %%allowed, the MetaPost interpreter can easily solve the equations and %%keep track of what values are known. Наиболее естественный способ гарантировать, что MetaPost сможет воспринять выражение типа %%The most natural way to ensure that MetaPost can handle an expression like $$ \hbox{\verb|whatever[z1,z3]|} $$ в гарантии, что {\tt z1} и {\tt z3} известны. %%is to ensure that {\tt z1} and {\tt z3} are both known. Однако этого в действительности не требуется, т.~к. MetaPost сможет вывести значение для ${\tt z3}-{\tt z1}$, не зная предварительно {\tt z1} и {\tt z3}. %%However this is not %%actually required since MetaPost may be able to deduce a known value for %%${\tt z3}-{\tt z1}$ before either of {\tt z1} and {\tt z3} are known. Например, MetaPost воспринимает правильными уравнения %%For instance, MetaPost will accept the equations $$ \hbox{\verb|z3=z1+(.1in,.6in); z20=whatever[z1,z3];|} $$ и при этом не будет способен определить любую из компонент {\tt z1}, {\tt z3} или {\tt z20}. %%but it will not be able to determine any of the components of {\tt z1}, %%{\tt z3}, or {\tt z20}. Эти уравнения дают частичную информацию о {\tt z1}, {\tt z3} и {\tt z20}. %%These equations do give partial information about {\tt z1}, {\tt z3}, %%and {\tt z20}. Хороший способ понять это в рассмотрении другого уравнения %%A good way to see this is to give another equation such as $$ \hbox{\verb|x20-x1=(y20-y1)/6;|} $$ Оно произведет сообщение об ошибке ``{\tt ! Redundant equation}''\index{Redundant equation?\texttt{Redundant equation}}\footnote{Избыточное уравнение}. %%This produces the error message ``{\tt ! Redundant %%equation}\index{Redundant equation?\texttt{Redundant equation}}.'' MetaPost считает, что вы пытаетесь сообщать ему что-то новое и поэтому он обычно предупреждает при задании избыточного уравнения. %%MetaPost assumes that you are trying to tell it something new, so it %%will usually warn you when you give a redundant equation. Новое уравнение вида %%If the new equation had been $$ \hbox{\verb|(x20-x1)-(y20-y1)/6=1in;|} $$ произведет сообщение об ошибке\index{Inconsistent equation?\texttt{Inconsistent equation}}\footnote{Противоречивое уравнение (отклонение на 71.99979).} %%the error message would have been\index{Inconsistent %%equation?\texttt{Inconsistent equation}} $$ \hbox{\verb|! Inconsistent equation (off by 71.99979).|} $$ Это сообщение об ошибке иллюстрирует ошибку округления\index{ошибка округления} в механизме MetaPost для решения линейных уравнений. %%This error message illustrates %%roundoff\index{roundoff error} error in MetaPost's linear equation solving %%mechanism. Ошибка округления --- это обычно несерьезная проблема, но она может вызвать затруднение при попытке найти пересечение двух почти параллельных прямых. %%Roundoff error %%is normally not a serious problem. but it is likely to cause trouble if you are %%trying to do something like find the intersection of two lines that are almost %%parallel. \section{Выражения} %%\section{Expressions} \label{exprs} Настало время для более систематического обзора языка MetaPost. %%It is now time for a more systematic view of the MetaPost language. Мы видели числовые количества и координатные пары и то, что их можно соединять для указания пути для команд {\tt draw}. %%We %%have seen that there are numeric quantities and coordinate pairs, and %%that these can be combined to specify paths for {\tt draw} statements. Мы также видели, как переменные могут быть использованы в линейных уравнениях, но не обсуждали всех операций и типов данных, что могут быть использованы в уравнениях. %%We have also seen how variables can be used in linear equations, but we %%have not discussed all the operations and data types that can be used in %%equations. Использование команды \index{show?\texttt{show}}\label{Dshow} $$ {\tt show}\, \descr{выражение} $$ для печати символьного представления значения любого выражения делает возможным эксперименты с выражениями любых типов данных, встречающихся далее. %%It is possible to experiment with expressions involving any of the data types %%mentioned below by using the statement\index{show?\texttt{show}}\label{Dshow} %%$$ {\tt show}\, \descr{expression} $$ %%to ask MetaPost to print a symbolic representation of the value of each %%expression. Известные числовые значения печатаются в отдельных строках, предваряемые ``{\tt >>} ''. %%For known numeric values, each is printed on a new line %%preceded by ``{\tt >>} ''. Другие типы результата расчета печатаются похожим образом, за исключением того, что сложные значения иногда не распечатываются на устройстве вывода. %%Other types of result are printed similarly, %%except that complicated values are sometimes not printed on standard %%output. Последнее производит ссылку на файл-дубликат\index{файлы!дубликат}, которая выглядит примерно так\footnote{картинка (см. файл-дубликат)} %%This produces a reference to the transcript %%file\index{files!transcript} that looks like this: $$ \hbox{\tt >> picture (see the transcript file)} $$ Если вы захотите распечатки на терминале полных результатов команды {\tt show}, то назначьте положительное значение внутренней\index{внутренние переменные} переменной\index{переменные!внутренние} {\tt tracingonline}\index{tracingonline?\texttt{tracingonline}}\label{Dtonline}. %%If you want to the full results of {\tt show} statements to be printed %%on your terminal, assign a positive value to the internal\index{internal %%variables} variable\index{variables!internal} {\tt %%tracingonline}\index{tracingonline?\texttt{tracingonline}}\label{Dtonline}. \subsection{Типы данных} %%\subsection{Data Types} MetaPost в действительности имеет десять типов данных\index{типы}: числовой, для пар, для путей, трансформации, цвета (rgb-цвета), cmyk-цвета, строковый, логический, для картинок и тип пера. %%MetaPost actually has ten basic data types\index{types}: numeric, %%pair, path, transform, (rgb)color, cmykcolor, string, boolean, picture, and %%pen. Давайте рассматривать их по-одному, начиная с числового типа. %%Let us consider these one at a time beginning with the numeric %%type. Числовые (numeric)\index{числовой тип} количества представляются в MetaPost с фиксированной десятичной точкой\index{арифметика} как целые, умноженные на $1\over65536$. %%Numeric\index{numeric type} quantities in MetaPost are represented in fixed %%point arithmetic\index{arithmetic} as %%integer multiples of $1\over65536$. Они должны обычно иметь модуль, меньший 4096, но промежуточные результаты могут быть в восемь раз больше. %%They must normally have absolute values %%less than 4096 but intermediate results can be eight times larger. Это не должно быть проблемой для расстояний или значений координат, т.~к. 4096 PostScript-пунктов составляют более 1.4 метра. %%This should not be a problem for distances or coordinate values since 4096 %%PostScript points is more than 1.4~meters. Если вам нужно работать с числами размера 4096 и более, то установка внутренней переменной {\tt warningcheck}\index{warningcheck?\texttt{warningcheck}}\label{Dwarncheck} в ноль подавит предупреждающие сообщения о больших числовых количествах. %%If you need to work with numbers %%of magnitude 4096 or more, setting the internal variable %%{\tt warningcheck}\index{warningcheck}\label{Dwarncheck} to zero %%suppresses the warning messages about large numeric quantities. Тип pair (пары) \index{тип-пара} представляется как пара числовых количеств. %%The pair\index{pair type} type is represented as a pair of numeric %%quantities. Мы видели, что пары используются для задания координат в команде {\tt draw}. %%We have seen that pairs are used to give coordinates in %%{\tt draw} statements. Пары можно складывать, вычитать, использовать в выражениях усреднения, умножать и делить на числа. %%Pairs can be added, subtracted, used in %%mediation expressions, or multiplied or divided by numerics. Тип путей (path)\index{тип-путь} уже обсуждался в контексте команды {\tt draw}, но это обсуждение обошло стороной то, что пути важные отдельные объекты, которые можно сохранять и изменять. %%Paths\index{path type} have already been discussed in the context of {\tt draw} %%statements, but %%that discussion did not mention that paths are first-class objects that can be %%stored and manipulated. Путь представляет прямую линию или кривую, определяемые параметрически. %%A path represents a straight or curved line that is %%defined parametrically. Другой тип данных представляет произвольную аффинную трансформацию (transform)\index{тип-трансформация}. %%Another data type represents an arbitrary affine %%transformation\index{transform type}. {\em Трансформация} может быть любой комбинацией вращений, масштабирований, наклонов и сдвигов. %%A {\em transform\/} can be any %%combination of rotating, scaling, slanting, and shifting. Если ${\tt p}=(p_x,p_y)$ --- это пара и {\tt T} --- это трансформация,\index{transformed?\texttt{transformed}} то $$ \hbox{\tt p transformed T} $$ %%If ${\tt %%p}=(p_x,p_y)$ is a pair and {\tt T} is a %%transform,\index{transformed?\texttt{transformed}} %%$$ \hbox{\tt p transformed T} $$ --- это пара вида %%is a pair of the form $$ (t_x+t_{xx}p_x+t_{xy}p_y, t_y+t_{yx}p_x+t_{yy}p_y), $$ где 6 числовых количеств $(t_x,t_y,t_{xx},t_{xy},t_{yx},t_{yy})$ определяют {\tt T}. %%where the six numeric quantities $(t_x,t_y,t_{xx},t_{xy},t_{yx},t_{yy})$ %%determine {\tt T}. Трансформации могут быть применимы к путям, рисункам, перьям и трансформациям. %%Transforms can also be applied to paths, pictures, pens, %%and transforms. Тип цвета (color)\index{тип-цвет} подобен типу пары, но он имеет три компоненты вместо двух и каждая компонента обычно находится в диапазоне от 0 до 1. %%The color\index{color type} type is like the pair type, except %%that it has three components instead of two and each component is %%normally between 0 and 1. Подобно парам, цвета могут складываться, вычитаться, использоваться в выражения усреднения, умножаться и делиться на числа. %%Like pairs, colors can be added, %%subtracted, used in mediation expressions, or multiplied or divided %%by numerics. Цвета могут задаваться при помощи констант \ttindex{black}\label{Dblack}, \ttindex{white}\label{Dwhite}, \ttindex{red}\label{Dred}, \ttindex{green}\label{Dgreen}, \ttindex{blue}\label{Dblue} или явно заданными красной, зеленой и синей компонентами. %%Colors can be specified in terms of the predefined %%constants \ttindex{black}\label{Dblack}, \ttindex{white}\label{Dwhite}, %%\ttindex{red}\label{Dred}, \ttindex{green}\label{Dgreen}, %%\ttindex{blue}\label{Dblue}, or the red, green, and %%blue components can be given explicitly. Черный --- это {\tt (0,0,0)} и белый --- это {\tt (1,1,1)}. %%Black is {\tt (0,0,0)} and %%white is {\tt (1,1,1)}. Уровень серого, такой как {\tt (.4,.4,.4)}, можно также задать как {\tt 0.4white}. %%A level of gray such as {\tt (.4,.4,.4)} can also be %%specified as {\tt 0.4white}. Хотя цветовой переменной может быть любая упорядоченная тройка, при добавлении объекта к картинке MetaPost преобразует ее цвета обрезкой каждой цветовой компоненты до диапазона от 0 до 1. %%Although color typed variables may be %%any ordered triplet, when adding an object to a picture, MetaPost will %%convert its color by clipping each component between 0 and 1. Например, MetaPost будет выводить цвет (1,2,3) как (1,1,1). %%For %%example, MetaPost will output the color (1,2,3) as (1,1,1). MetaPost решает линейные уравнения с цветами таким же образом как и с парами. %%MetaPost solves linear equations involving %%colors the same way it does for pairs. Тип `rgbcolor' (rgb-цвет) --- это синоним типа `color' (цвет). %%The type `rgbcolor' is an alias of. %%type `color'. Тип cmykcolor\index{тип-cmyk-цвет} (cmyk-цвета) подобен типу color, но имеет четыре компоненты вместо трех. %%The cmykcolor\index{cmykcolor type} type is similar to the color %%type except that it has four components instead of three. Этот тип используется для задания цветов их зеленоголубой (cyan), пурпурнокрасной (magenta), желтой и черной компонентами. %%This type is used to %%specify colors by their cyan, magenta, yellow, and black components explicitly. Из-за того, что cmyk-цвет использует краски вместо световых лучей, белый цвет будет выражаться как {\tt (0,0,0,0)} и черный как {\tt (0,0,0,1)}. %%Because CMYK colors deal with pigments instead of light rays, the color %%black would be expressed as {\tt (1,1,1,1)} and white as {\tt (0,0,0,0)}. Теоретически цвета {\tt ($c$,$m$,$y$,1)} и {\tt (1,1,1,$k$)} должны давать черный для любых значений $c$, $m$, $y$ и~$k$. %%In theory, the colors %%{\tt ($c$,$m$,$y$,1)} and {\tt (1,1,1,$k$)} should result in black for %%any values of $c$, $m$, $y$ and~$k$, too. На практике этого избегают, т.~к. это тратит цветные чернила и может приводить к неудовлетворительным результатам. %%But in practice, this is %%avoided since it is a waste of colored ink and can lead to %%unsatisfactory results. Строки (string)\index{строковый тип} представляют последовательность символов. %%A string\index{string type} represents a sequence of characters. Строковые константы\index{строковые константы} задаются в двойных кавычках \hbox{\verb|"подобно этой"|}. %%String constants\index{string constants} are given %%in double quotes \hbox{\verb|"like this"|}. Строковые константы не могут содержать двойных кавычек или переходов на новую строку, но есть способ конструировать строки, содержащие любую последовательность восьмибитных знаков. %%String constants cannot contain %%double quotes or newlines, but there is a way to construct a string containing %%any sequence of eight-bit characters. \label{Dscantokens} Преобразование строк в другие типы, обычно числовые, возможно примитивом {\tt scantokens}\index{scantokens?\texttt{scantokens}}: \begin{center}\texttt{n := scantokens(}\textit{строка}\texttt{);}\end{center} %%Conversion from strings to other types, notably numeric, can be accomplished by %%the {\tt scantokens}\index{scantokens?\texttt{scantokens}} primitive: %%\begin{center}\texttt{n := scantokens(}\textit{str}\texttt{);}\end{center} Более абстрактно, \texttt{scantokens} разбирает строку на последовательность знаков, также как MetaPost считывал бы их при вводе. %%More generally, \texttt{scantokens} parses a string into a token %%sequence, as if MetaPost had read it as input. Логический\index{логический тип} тип (boolean) имеет константы {\tt true}\index{true?\texttt{true}}\label{Dtrue} и {\tt false}\index{false?\texttt{false}}\label{Dfalse} и операторы {\tt and}\index{and?\texttt{and}}\label{Dand}, {\tt or}\index{or?\texttt{or}}\label{Dor}, {\tt not}\index{not?\texttt{not}}\label{Dnot}. %%The boolean\index{boolean type} type has the constants {\tt %%true}\index{true?\texttt{true}}\label{Dtrue} and {\tt %%false}\index{false}\label{Dfalse} and the operators {\tt %%and}\index{and?\texttt{and}}\label{Dand}, {\tt %%or}\index{or?\texttt{or}}\label{Dor}, {\tt %%not}\index{not?\texttt{not}}\label{Dnot}. Отношения \verb|=| и \verb|<>|\index{<>?\texttt{<>}}\label{Dcmpar} проверяют объекты любых типов на равенство и неравенство\index{неравенство}. %%The relations \verb|=| and %%\verb|<>|\index{<>?\texttt{<>}}\label{Dcmpar} test objects of any type %%for equality and inequality\index{inequality}. Отношения сравнения \index{сравнение} \verb|<|\index{|\index{>?\texttt{>}} и \verb|>=|\index{>=?\texttt{>=}} определяются словарно для строк и обычным способом для чисел. %%Comparison\index{comparison} relations \verb|<|\index{|\index{>?\texttt{>}}, and %%\verb|>=|\index{>=?\texttt{>=}} are defined lexicographically for %%strings and in the obvious way for numerics. Отношения порядка определены также и для логических величин, пар, цветов и трансформаций, но правила их сравнения не стоит обсуждать здесь. %%Ordering relations are %%also defined for booleans, pairs, colors, and transforms, but the %%comparison rules are not worth discussing here. Тип данных picture\index{тип-рисунок} (рисунок) --- это в точности то, что подразумевается его именем. %%The picture\index{picture type} data type is just what the name implies. Все, что можно нарисовать в MetaPost, можно сохранить в переменной-картинке. %%Anything that can be drawn in MetaPost can be stored in a picture %%variable. Фактически команда {\tt draw}\index{draw?\texttt{draw}} сохраняет свои результаты в особой переменной-картинке, называемой {\tt currentpicture}\index{currentpicture?\texttt{currentpicture}}. %%In fact, the {\tt draw}\index{draw?\texttt{draw}} statement %%actually stores its results in a special picture variable called {\tt %%currentpicture}\index{currentpicture?\texttt{currentpicture}}. Картинки могут быть добавлены к другим картинкам и их можно трансформировать. %%Pictures %%can be added to other pictures and operated on by transforms. Наконец, тип данных, называемый pen\index{тип-перо} (перо). %%Finally, there is a data type called a pen\index{pen type}. Главная функция перьев в MetaPost в определении толщины линии, но их также можно использовать для достижения каллиграфических эффектов. %%The main %%function of pens in MetaPost is to determine line thickness, but they %%can also be used to achieve calligraphic effects. Команда\index{pickup?\texttt{pickup}}\label{Dpickup} $$ {\tt pickup\ }\descr{выражение-перо} $$ обусловит использование заданного пера в последующих командах {\tt draw}. %%The statement\index{pickup?\texttt{pickup}}\label{Dpickup} %%$$ {\tt pickup\ }\descr{pen expression} $$ %%causes the given pen to be used in subsequent {\tt draw} statements. Обычно выражение-перо имеет форму $$ {\tt pencircle\ scaled\ }\descr{числовая первичность}. $$ %%Normally, the pen expression is of the form %%$$ {\tt pencircle\ scaled\ }\descr{numeric primary}. $$ Оно определяет круговое перо, производящее линии постоянной толщины. %%This defines a circular pen that produces lines of constant thickness. Если желательны каллиграфические эффекты, то выражение-перо может быть приспособлено для задания эллиптического или многоугольного пера. %%If calligraphic effects are desired, the pen expression can be adjusted to give %%an elliptical pen or a polygonal pen. \subsection{Операторы} %%\subsection{Operators} Есть много разных способов сделать выражения десяти базовых типов, но большинство операций можно сопоставить сравнительно простому синтаксису с четырьмя уровнями приоритета как показано на рис.~\ref{syexpr}. %%There are many different ways to make expressions of the ten basic %%types, but most of the operations fit into a fairly simple syntax with %%four levels of precedence as shown in Figure~\ref{syexpr}. Есть первичности\index{первичность?\tdescr{первичность}}, вторичности\index{вторичность?\tdescr{вторичность}}, третичности\index{третичность?\tdescr{третичность}} и выражения\index{выражение?\tdescr{выражение}} каждого из базовых типов, поэтому синтаксические правила могут уточняться для работы с такими сущностями как \tdescr{числовая первичность}, \tdescr{логическая третичность} и т.~д. %%There are %%primaries\index{primary?\tdescr{primary}}, %%secondaries\index{secondary?\tdescr{secondary}}, %%tertiaries\index{tertiary?\tdescr{tertiary}}, and %%expressions\index{expression?\tdescr{expression}} of each of the basic %%types, so the syntax rules could be specialized to deal with items such %%as \tdescr{numeric primary}, \tdescr{boolean tertiary}, etc. Это позволяет типу результата операции зависеть от выбора оператора и типов операндов. %%This %%allows the result type for an operation to depend on the choice of %%operator and the types of its operands. Например, отношение {\tt <} --- это \tdescr{третичная бинарность}, которую можно применить к \tdescr{числовому выражению} и к \tdescr{числовой третичности} для получения \tdescr{логического выражения}. %%For example, the {\tt <} %%relation is a \tdescr{tertiary binary} that can be applied to a %%\tdescr{numeric expression} and a \tdescr{numeric tertiary} to give a %%\tdescr{boolean expression}. Этот же оператор может допускать другие типы операндов такие как \tdescr{строковое выражение} и \tdescr{строковая третичность}, но результатом в случае несовпадения типов операндов будет сообщение об ошибке. %%The same operator can accept other operand %%types such as \tdescr{string expression} and \tdescr{string tertiary}, %%but an error message results if the operand types do not match. \begin{figure}[htp] \begin{ctabbing} $\tt \descr{первичность} \rightarrow \descr{переменная}$\\ %%$\tt \descr{primary} \rightarrow \descr{variable}$\\ $\tt \qquad \;|\; \hbox{\tt (}\descr{выражение}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; \hbox{\tt (}\descr{expression}\hbox{\tt )}$\\ $\tt \qquad \;|\; \descr{оператор 0-уровня}$\\ %%$\tt \qquad \;|\; \descr{nullary op}$\\ $\tt \qquad \;|\; \descr{of-оператор} \descr{выражение} of \descr{первичность}$\\ %%$\tt \qquad \;|\; \descr{of operator} \descr{expression} %% of \descr{primary}$\\ $\tt \qquad \;|\; \descr{унарный оператор} \descr{первичность}$\\ %%$\tt \qquad \;|\; \descr{unary op} \descr{primary}$\\ $\tt \descr{вторичность} \rightarrow \descr{первичность}$\\ %%$\tt \descr{secondary} \rightarrow \descr{primary}$\\ $\tt \qquad \;|\; \descr{вторичность} \descr{первичный бин. оп-р} \descr{первичность}$\\ %%$\tt \qquad \;|\; \descr{secondary} \descr{primary binop} \descr{primary}$\\ $\tt \descr{третичность} \rightarrow \descr{вторичность}$\\ %%$\tt \descr{tertiary} \rightarrow \descr{secondary}$\\ $\tt \qquad \;|\; \descr{третичность} \descr{вторичный бин. оп-р} \descr{вторичность}$\\ %%$\tt \qquad \;|\; \descr{tertiary} \descr{secondary binop} %% \descr{secondary}$\\ $\tt \descr{выражение} \rightarrow \descr{третичность}$\\ %%$\tt \descr{expression} \rightarrow \descr{tertiary}$\\ $\tt \qquad \;|\; \descr{выражение} \descr{третичный бин. оп-р} \descr{третичность}$ %%$\tt \qquad \;|\; \descr{expression} \descr{tertiary binop} %% \descr{tertiary}$ \end{ctabbing} \caption{Общие синтаксические правила для выражений} %%\caption{The overall syntax rules for expressions} \index{унарный op?\tdescr{унарный оператор}} \index{оператор 0?\tdescr{оператор 0-уровня}} \index{первичный binop?\tdescr{первичный бинарный оператор}} \index{вторичный binop?\tdescr{вторичный бинарный оператор}} \index{третичный binop?\tdescr{третичный бинарный оператор}} %%\index{unary op?\tdescr{unary op}} \index{nullary op?\tdescr{nullary op}} %%\index{primary binop?\tdescr{primary binop}} %%\index{secondary binop?\tdescr{secondary binop}} %%\index{tertiary binop?\tdescr{tertiary binop}} \label{syexpr} \end{figure} Операторы умножения и деления, {\tt *}\label{Dmldiv} и~{\tt /}, --- примеры того, что на рис.~\ref{syexpr} зовется \tdescr{первичным бинарным оператором}. %%The multiplication and division operators {\tt *}\label{Dmldiv} and~{\tt %%/} are examples of what Figure~\ref{syexpr} calls a \tdescr{primary %%binop}. Каждый из них может допускать два числовых операнда или один числовой операнд и один типа пара или цвет. %%Each can accept two numeric operands or one numeric operand and %%one operand of type pair or color. Оператор возведения в степень \verb|**|\index{**?\texttt{**}}\index{степень}\label{Dpow} --- это \tdescr{первичный бинарный оператор}, который требует два числовых операнда. %%The exponentiation operator %%\verb|**|\index{**?\texttt{**}}\index{exponentiation}\label{Dpow} is a %%\tdescr{primary binop} that requires two numeric operands. Размещение его на том же уровне приоритета, что и умножение и деление, имеет неприятное последствие в том, что \verb|3*a**2| значит $(3a)^2$, а не $3(a^2)$\index{нерегулярности разбора}. %%Placing this %%at the same level of precedence as multiplication and division has the %%unfortunate consequence that \verb|3*a**2| means $(3a)^2$, not %%$3(a^2)$\index{parsing irregularities}. Из-за того, что унарный минус\label{Dneg} относится к первичному уровню, он также приводит к неудобочитаемости типа \verb|-a**2|, означающей $(-a)^2$. %%Since unary %%negation\label{Dneg} applies at the primary level, it also turns out %%that \verb|-a**2| means $(-a)^2$. К счастью, вычитание имеет меньший приоритет и \verb|a-b**2| означает $a-(b^2)$ вместо $(a-b)^2$ %%Fortunately, subtraction has lower %%precedence so that \verb|a-b**2| does mean $a-(b^2)$ instead of %%$(a-b)^2$. Другим \tdescr{первичным бинарным оператором} является оператор {\tt dotprod}\index{dotprod?\texttt{dotprod}}\label{Ddprod}, вычисляющий скалярное произведение двух пар. %%Another \tdescr{primary binop} is the {\tt %%dotprod}\index{dotprod?\texttt{dotprod}}\label{Ddprod} operator that %%computes the vector dot product of two pairs. Например, {\tt z1 dotprod z2} эквивалентно {\tt x1*x2 + y1*y2}. %%For example, {\tt z1 %%dotprod z2} is equivalent to {\tt x1*y1 + x2*y2}. Аддитивные операторы {\tt -} и {\tt +}\label{Dadd} --- \tdescr{вторичные бинарные операторы}, применимые к числам, парам или цветам и производящие результаты того же типа. %%The additive operators {\tt +} and {\tt -}\label{Dadd} are %%\tdescr{secondary binops} that operate on numerics, pairs, or colors and %%produce results of the same type. Другие операторы, что попадают в эту категорию --- это ``Пифагорово сложение'' \verb|++|\index{++?\texttt{++}}\label{Dpyadd} и ``Пифагорово вычитание'' \verb|+-+|\index{+-+?\texttt{+-+}}\label{Dpysub}: \verb|a++b| значит $\sqrt{a^2+b^2}$ и \verb|a+-+b| значит $\sqrt{a^2-b^2}$. %%Other operators that fall in this %%category are ``Pythagorean addition'' %%\verb|++|\index{++?\texttt{++}}\label{Dpyadd} and ``Pythagorean %%subtraction'' \verb|+-+|\index{+-+?\texttt{+-+}}\label{Dpysub}: %%\verb|a++b| means $\sqrt{a^2+b^2}$ and \verb|a+-+b| means %%$\sqrt{a^2-b^2}$. Есть еще слишком много других операторов для перечисления здесь, но одни из самых важных --- это логические операторы {\tt and}\index{and?\texttt{and}} и {\tt or}\index{or?\texttt{or}}. %%There are too many other operators to list here, but %%some of the most important are the boolean operators {\tt %%and}\index{and?\texttt{and}} and {\tt or}\index{or?\texttt{or}}. Оператор {\tt and} --- это \tdescr{первичный бинарный оператор} и оператор {\tt or} --- это \tdescr{вторичный бинарный оператор}. %%The %%{\tt and} operator is a \tdescr{primary binop} and the {\tt or} operator %%is a \tdescr{secondary binop}. Базовые операции со строками --- это склейка\index{склейка}, выделение подстроки и вычисление длины строки. %%e basic operations on strings are concatenation\index{concatenation}, %%substring construction and calculating the length of a string. Склейка реализуется \tdescr{третичным бинарным оператором} \verb|&|\index{&?\texttt{\&}}\label{Damp}, например, %%The \tdescr{tertiary binop} \verb|&|\index{&?\texttt{\&}}\label{Damp} %%implements concatenation; e.g., $$ \hbox{\verb|"abc" & "de"|} $$ производит строку \verb|"abcde"|. %%produces the string \verb|"abcde"|. Оператор {\tt length}\index{length?\texttt{length}}\label{DlengthString} возвращает число символов в строке, если аргументом является \tdescr{строковая первичность}, например, %%The {\tt %%length}\index{length?\texttt{length}}\label{DlengthString} operator %%returns the number of characters in a string if the argument is a %%\tdescr{string primary}; e.g., $$ \hbox{\verb|length "abcde"|} $$ возвращает \verb|5|. %%returns \verb|5|. Другое применение оператора {\tt length} обсуждается на стр.\ \pageref{Dlength}. %%Another application of the {\tt length} operator is %%discussed on p.\ \pageref{Dlength}. Для выделения подстроки \tdescr{of-оператор} {\tt substring}\index{substring of?\texttt{substring of}}\label{Dsubstr} используется таким образом: $$ {\tt substring}\, \descr{выражение-пара} \,{\tt of}\, \descr{строковая первичность} $$ %%For substring construction, the %%\tdescr{of operator} {\tt substring}\index{substring %%of?\texttt{substring of}}\label{Dsubstr} is used like this: %%$$ {\tt substring}\, \descr{pair expression} \,{\tt of}\, \descr{string primary} $$ Часть строки для выделение определяется \tdescr{выражением-парой}. %%The \tdescr{pair expression} determines what part of the string to %%select. Позиции в строке нумеруются\index{индексация} так, что целые позиции попадают {\em между\/} символами. %%For this purpose, the string is indexed\index{indexing} so that %%integer positions fall {\em between\/} characters. Представим строку, написанную на кусочке бумаге в клетку так, что первый символ займет $x$-координаты между нулем и единицей, а следующий символ покроет координаты в диапазоне $1\leqslant x\leqslant2$, и т.~д. %%Pretend the string %%is written on a piece of graph paper so that the first character %%occupies $x$~coordinates between zero and one and the next character %%covers the range $1\le x\le2$, etc. Поэтому строку \verb|"abcde"| следует представлять в виде %%Thus the string \verb|"abcde"| %%should be thought of like this $$ \includegraphics{manfig-ru-14} $$ и {\tt substring (2,4) of {\qq}abcde{\qq}} будет {\tt {\qq}cd{\qq}}. %%and {\tt substring (2,4) of {\qq}abcde{\qq}} is {\tt {\qq}cd{\qq}}. Это выглядит несколько усложнено, но имеет целью избежать надоедающих ошибок ``на единицу''. %%This takes a little %%getting used to but it tends to avoid annoying ``off by one'' errors. Некоторые операторы не берут аргументов вообще. %%Some operators take no arguments at all. Пример того, что на рис.~\ref{syexpr} зовется \tdescr{оператором 0-уровня}, --- это {\tt nullpicture}\index{nullpicture?\texttt{nullpicture}}\label{Dnlpic}, который возвращает совершенно пустую картинку. %%An example of what %%Figure~\ref{syexpr} calls a \tdescr{nullary op} is {\tt %%nullpicture}\index{nullpicture?\texttt{nullpicture}}\label{Dnlpic} which %%returns a completely blank picture. Базовый синтаксис на рис.~\ref{syexpr} покрывает только те аспекты синтаксиса выражений, которые являются независимыми от типа. %%The basic syntax in Figure~\ref{syexpr} only covers aspects of the %%expression syntax that are relatively type-independent. Например, непростой синтаксис пути на рис.~\ref{sypath}, дает альтернативные правила для конструирования \tdescr{выражения-пути}. %%For instance, %%the complicated path syntax given in Figure~\ref{sypath} gives %%alternative rules for constructing a \tdescr{path expression}. Дополнительное правило\index{узел пути?\tdescr{узел пути}} $$ \descr{узел пути} \rightarrow \descr{третичная пара} \;|\; \descr{третичный путь} $$ объясняет значение \tdescr{узла пути} на рис.~\ref{sypath}. %%An %%additional rule\index{path knot?\tdescr{path knot}} %%$$ \descr{path knot} \rightarrow \descr{pair tertiary} \;|\; \descr{path tertiary} %%$$ %%explains the meaning of \tdescr{path knot} in Figure~\ref{sypath}. Таким образом, выражение-путь %%This means %%that the path expression $$ \hbox{\verb|z1+(1,1){right}..z2|} $$ не нуждается в скобках вокруг {\tt z1+(1,1)}. %%does not need parentheses around {\tt z1+(1,1)}. \subsection{Дроби, усреднения и унарные операторы} %%\subsection{Fractions, Mediation, and Unary Operators} Выражения усреднения\index{усреднение} отсутствуют в синтаксисе базового выражения на рис.~\ref{syexpr}. %%Mediation\index{mediation} expressions do not appear in the basic expression %%syntax of Figure~\ref{syexpr}. Выражения усреднения разбираются на \tdescr{первичном} уровне, так что общее правило для их конструирования следующее $$ \descr{первичность} \rightarrow \descr{числовой атом} \hbox{\tt [} \descr{выражение} \hbox{\tt ,} \descr{выражение} \hbox{\tt ]}, $$ где каждое \tdescr{выражение} может быть типа число, пара или цвет. %%Mediation expressions are parsed at the %%\tdescr{primary} level, so the general rule for constructing them is %%$$ \descr{primary} \rightarrow %% \descr{numeric atom} \hbox{\tt [} \descr{expression} %% \hbox{\tt ,} \descr{expression} \hbox{\tt ]} %%$$ %%where each \tdescr{expression} can be of type numeric, pair, or color. \tdescr{Числовой атом}\index{числовой атом?\tdescr{числовой атом}} в выражении усреднения имеет очень простой тип \tdescr{числовой первичности}, как показано на рис.~\ref{synprim}. %%The \tdescr{numeric atom}\index{numeric atom?\tdescr{numeric atom}} in a %%mediation expression is an extra simple type of \tdescr{numeric primary} %%as shown in Figure~\ref{synprim}. Значением всего этого является то, что первый параметр в выражении усреднения требует заключения в скобки, если он в точности не переменная, не положительное число или не положительная дробь. %%The meaning of all this is that the %%initial parameter in a mediation expression needs to be parenthesized %%when it is not just a variable, a positive number, or a positive %%fraction. Например,\index{нерегулярности разбора} $$ \hbox{\tt -1[a,b]} \quad {\rm и}\quad \hbox{\tt (-1)[a,b]} $$ очень различны: первое --- это $-b$, т.~к. оно эквивалентно {\tt -(1[a,b])}; второе --- это $a-(b-a)$ или $2a-b$. %%For example,\index{parsing irregularities} %%$$ \hbox{\tt -1[a,b]} \quad {\rm and}\quad \hbox{\tt (-1)[a,b]} $$ %%are very different: the former is $-b$ since it is equivalent to %%{\tt -(1[a,b])}; the latter is $a-(b-a)$ or $2a-b$. \begin{figure}[htp] \begin{ctabbing} $\tt \descr{числовая первичность} \rightarrow \descr{числовой атом}$\\ %%$\tt \descr{numeric primary} \rightarrow \descr{numeric atom}$\\ $\tt \qquad \;|\; \descr{числовой атом}\hbox{\tt [} \descr{числовое выражение}\hbox{\tt ,}\descr{числовое выражение}\hbox{\tt ]}$\\ %%$\tt \qquad \;|\; \descr{numeric atom}\hbox{\tt [} %% \descr{numeric expression}\hbox{\tt ,}\descr{numeric expression}\hbox{\tt ]}$\\ $\tt \qquad \;|\; \descr{of-оператор} \descr{выражение} of \descr{первичность}$\\ %%$\tt \qquad \;|\; \descr{of operator} \descr{expression} of \descr{primary}$\\ $\tt \qquad \;|\; \descr{унарный оператор} \descr{первичность}$\\ %%$\tt \qquad \;|\; \descr{unary op} \descr{primary}$\\ $\tt \descr{числовой атом} \rightarrow \descr{числовая переменная}$\\ %%$\tt \descr{numeric atom} \rightarrow \descr{numeric variable}$\\ $\tt \qquad \;|\; \descr{число или дробь}$\\ %%$\tt \qquad \;|\; \descr{number or fraction}$\\ $\tt \qquad \;|\; \hbox{\tt (}\descr{числовое выражение}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; \hbox{\tt (}\descr{numeric expression}\hbox{\tt )}$\\ $\tt \qquad \;|\; \descr{числовой оператор 0-уровня}$\\ %%$\tt \qquad \;|\; \descr{numeric nullary op}$\\ $\tt \descr{число или дробь} \rightarrow \descr{число} \hbox{\tt /}\descr{число}$\\ %%$\tt \descr{number or fraction} \rightarrow \descr{number} %% \hbox{\tt /}\descr{number}$\\ $\tt \qquad \;|\; \descr{число, за которым нет `$\hbox{\tt /}\descr{числа}$'}$ %%$\tt \qquad \;|\; \descr{number not followed by %% `$\hbox{\tt /}\descr{number}$'}$ \end{ctabbing} \caption{Синтаксические правила для числовых первичностей} %%\caption{Syntax rules for numeric primaries} \label{synprim} \end{figure} Заметным свойством синтаксических правил на рис.~\ref{synprim} является то, что оператор {\tt /}\index{дроби} связывает более крепко, когда его операнды являются числами. %%A noteworthy feature of the syntax rules in Figure~\ref{synprim} is that %%the {\tt /}\index{fractions} operator binds most tightly when its %%operands are numbers. Таким образом, {\tt 2/3} --- это \tdescr{числовой атом}\index{числовой атом?\tdescr{числовой атом}}\index{нерегулярности разбора}, а {\tt (1+1)/3} --- это только \tdescr{числовая вторичность}. %%Thus {\tt 2/3} is a \tdescr{numeric %%atom}\index{numeric atom?\tdescr{numeric atom}}\index{parsing %%irregularities} while {\tt (1+1)/3} is only a \tdescr{numeric %%secondary}. Применение \tdescr{унарного оператора}, такого как {\tt sqrt}\index{sqrt?\texttt{sqrt}}\label{Dsqrt}, делает разницу очевидной: $$ \hbox{\tt sqrt 2/3} $$ значит $\sqrt{2\over3}$, а $$ \hbox{\tt sqrt(1+1)/3} $$ значит $\sqrt 2/3$. %%Applying a \tdescr{primary binop} such as {\tt %%sqrt}\index{sqrt?\texttt{sqrt}}\label{Dsqrt} makes the difference clear: %%$$ \hbox{\tt sqrt 2/3} $$ %%means $\sqrt{2\over3}$ while %%$$ \hbox{\tt sqrt(1+1)/3} $$ %%means $\sqrt 2/3$. Операторы, такие как {\tt sqrt}, могут быть записаны в стандартной функциональной нотации, но часто нет нужды брать аргумент в скобки. %%Operators such as {\tt sqrt} can be written in %%standard functional notation, but it is often unnecessary to %%parenthesize the argument. Это верно для любой функции, что разбирается как \tdescr{унарная операция}. %%This applies to any function that is parsed %%as a \tdescr{primary binop}. Например, и {\tt abs(x)}\index{abs?\texttt{abs}}\label{Dabs}, и {\tt abs x} вычисляют модуль {\tt x}. %%For instance {\tt %%abs(x)}\index{abs?\texttt{abs}}\label{Dabs} and {\tt abs x} both compute %%the absolute value of {\tt x}. Это же верно для функций {\tt round}\index{round?\texttt{round}}\label{Dround}, {\tt floor}\index{floor?\texttt{floor}}\label{Dfloor}, {\tt ceiling}\index{ceiling?\texttt{ceiling}}\label{Dceil}, {\tt sind}\index{sind?\texttt{sind}}\label{Dsind} и {\tt cosd}\index{cosd?\texttt{cosd}}\label{Dcosd}. %%The same holds for the {\tt %%round}\index{round?\texttt{round}}\label{Dround}, {\tt %%floor}\index{floor?\texttt{floor}}\label{Dfloor}, {\tt %%ceiling}\index{ceiling?\texttt{ceiling}}\label{Dceil}, {\tt %%sind}\index{sind?\texttt{sind}}\label{Dsind}, and {\tt %%cosd}\index{cosd?\texttt{cosd}}\label{Dcosd} functions. Две последние из них вычисляют тригонометрические функции от угла в градусах. %%The last two of %%these compute trigonometric functions of angles in degrees. Не все унарные операторы берут числовые аргументы и возвращают числовые результаты. %%Not all unary operators take numeric arguments and return numeric %%results. Например, оператор {\tt abs}\index{abs?\texttt{abs}} можно применять к паре для вычисления длины вектора. %%For instance, the {\tt abs}\index{abs?\texttt{abs}} operator %%can be applied to a pair to compute the Euclidean length of a vector. Применение оператора {\tt unitvector}\index{unitvector?\texttt{unitvector}}\label{Duvec} к паре производит опять пару, задающую вектор с тем же направлением и длиной~1. %%Applying the {\tt %%unitvector}\index{unitvector?\texttt{unitvector}}\label{Duvec} operator %%to a pair produces the same pair rescaled so that its Euclidean length %%is~1. Оператор {\tt decimal}\index{decimal?\texttt{decimal}}\label{Ddecop} берет число и возвращает его строковое представление. %%The {\tt decimal}\index{decimal?\texttt{decimal}}\label{Ddecop} %%operator takes a number and returns the string representation. Оператор {\tt angle}\index{angle?\texttt{angle}}\label{Dangle} берет пару и вычисляет арктангенс отношения ее компонент, т.~е. {\tt angle} --- это оператор, обратный {\tt dir}, что обсуждается в разделе~\ref{tenscurl}. %%The {\tt angle}\index{angle?\texttt{angle}}\label{Dangle} operator takes a pair %%and computes the two-argument arctangent; i.e., {\tt angle} is the %%inverse of the {\tt dir} operator that was discussed in %%Section~\ref{tenscurl}. Есть также оператор {\tt cycle}\index{cycle?\texttt{cycle}}\label{Dcycop}, что берет \tdescr{первичный путь} и возвращает логический результат, показывающий является ли этот путь замкнутой кривой. %%There is also an operator {\tt %%cycle}\index{cycle?\texttt{cycle}}\label{Dcycop} that takes a %%\tdescr{path primary} and returns a boolean result indicating whether %%the path is a closed curve. Существует целый класс других операторов для классификации выражений с логическим результатом. %%There is a whole class of other operators that classify expressions and %%return boolean results. Имя типа, такое как {\tt pair}\index{pair?\texttt{pair}}, может применяться к любому типу \tdescr{первичности} и возвращать логический результат, показывающий является ли аргумент парой\label{Dpairop}. %%A type name such as {\tt %%pair}\index{pair?\texttt{pair}} can operate on any type of %%\tdescr{primary} and return a boolean result indicating whether the %%argument is a {\tt pair}\label{Dpairop}. Аналогично, каждое имя из следующих далее можно использовать как унарный оператор: {\tt numeric}\index{numeric?\texttt{numeric}}\label{Dnumop}, {\tt boolean}\index{boolean?\texttt{boolean}}\label{Dboolop}, {\tt cmykcolor}\index{cmykcolor?\texttt{cmykcolor}}\label{Dccolrop}, {\tt color}\index{color?\texttt{color}}\label{Dcolrop}, {\tt string}\index{string?\texttt{string}}\label{Dstrgop}, {\tt transform}\index{transform?\texttt{transform}}\label{Dtrnfop}, {\tt path}\index{path?\texttt{path}}\label{Dpathop}, {\tt pen}\index{pen?\texttt{pen}}\label{Dpenop}, {\tt picture}\index{picture?\texttt{picture}}\label{Dpictop} и {\tt rgbcolor}\index{rgbcolor?\texttt{rgbcolor}}\label{Drcolrop}. %%Similarly, each of the %%following can be used as a unary operator: %%{\tt numeric}\index{numeric?\texttt{numeric}}\label{Dnumop}, %%{\tt boolean}\index{boolean?\texttt{boolean}}\label{Dboolop}, %%{\tt cmykcolor}\index{cmykcolor?\texttt{cmykcolor}}\label{Dccolrop}, %%{\tt color}\index{color?\texttt{color}}\label{Dcolrop}, %%{\tt string}\index{string?\texttt{string}}\label{Dstrgop}, %%{\tt transform}\index{transform?\texttt{transform}}\label{Dtrnfop}, %%{\tt path}\index{path?\texttt{path}}\label{Dpathop}, %%{\tt pen}\index{pen?\texttt{pen}}\label{Dpenop}, %%{\tt picture}\index{picture?\texttt{picture}}\label{Dpictop}, and %%{\tt rgbcolor}\index{rgbcolor?\texttt{rgbcolor}}\label{Drcolrop}. Кроме проверки типа \tdescr{первичности}, вы можете использовать операторы {\tt known}\index{known?\texttt{known}}\label{Dknown} и {\tt unknown}\index{unknown?\texttt{unknown}}\label{Dunknwn} для проверки, имеет ли она конкретное значение. %%Besides just %%testing the type of a \tdescr{primary}, you can use the {\tt %%known}\index{known?\texttt{known}}\label{Dknown} and {\tt %%unknown}\index{unknown?\texttt{unknown}}\label{Dunknwn} operators to %%test if it has a completely known value. Даже числа могут вести себя как оператор в некоторых контекстах. %%Even a number can behave like an operator in some contexts. Это ссылка на трюк, что позволяет {\tt 3x}\index{умножение, неявное} и {\tt 3cm} как альтернативы для {\tt 3*x} и {\tt 3*cm}. %%This refers %%to the trick that allows {\tt 3x}\index{multiplication, implicit} and %%{\tt 3cm} as alternatives to {\tt 3*x} and {\tt 3*cm}. Правило в том, что \tdescr{число или дробь}, за которыми нет {\tt +}, {\tt -} или другого \tdescr{числа или дроби}, может служить как \tdescr{первичный бинарный оператор}. %%The rule is that %%a \tdescr{number or fraction} that is not followed by {\tt +}, {\tt -}, %%or another \tdescr{number or fraction} can serve as a \tdescr{primary %%binop}. Таким образом, {\tt 2/3x}\index{нерегулярности разбора} --- это две трети от {\tt x}, но {\tt (2)/3x} --- это $2\over3x$, а {\tt 3 3} --- это ошибка. %%Thus {\tt 2/3x}\index{parsing irregularities} is two thirds of %%{\tt x} but {\tt (2)/3x} is $2\over3x$ and {\tt 3 3} is illegal. Есть также операторы для извлечения числовых полей из пар, цветов, cmyk-цветов и даже трансформаций. %%There are also operators for extracting numeric subfields from pairs, %%colors, cmykcolors, and even transforms. Если {\tt p} --- это \tdescr{первичная пара}, то {\tt xpart p}\index{xpart?\texttt{xpart}}\label{Dxprt} и {\tt ypart p}\index{ypart?\texttt{ypart}}\label{Dyprt} извлекают ее компоненты так, что $$ \hbox{\tt (xpart p, ypart p)} $$ эквивалентно {\tt p}, даже если {\tt p} --- неизвестная пара, используемая в линейном уравнении. %%If {\tt p} is a \tdescr{pair %%primary}, {\tt xpart p}\index{xpart?\texttt{xpart}}\label{Dxprt} and %%{\tt ypart p}\index{ypart?\texttt{ypart}}\label{Dyprt} extract its components so that %%$$ \hbox{\tt (xpart p, ypart p)} $$ is equivalent to~{\tt p} even if %%{\tt p} is an unknown pair that is being used in a linear equation. Аналогично, цвет {\tt c} эквивалентен\index{redpart?\texttt{redpart}}% \index{greenpart?\texttt{greenpart}}% \index{bluepart?\texttt{bluepart}}\label{Drgbprt} $$ \hbox{\tt (redpart c, greenpart c, bluepart c)}. $$ %%Similarly, a color {\tt c} is equivalent %%to\index{redpart?\texttt{redpart}}% %%\index{greenpart?\texttt{greenpart}}% %%\index{bluepart?\texttt{bluepart}}\label{Drgbprt} %%$$ \hbox{\tt (redpart c, greenpart c, bluepart c)} $$. Для cmyk-цвета {\tt c} его эквивалент\index{cyanpart?\texttt{cyanpart}}% \index{magentapart?\texttt{magentapart}}% \index{yellowpart?\texttt{yellowpart}}% \index{blackpart?\texttt{blackpart}}\label{Dcmykprt} $$ \hbox{\tt (cyanpart c, magentapart c, yellowpart c, blackpart c)}, $$ а для оттенка серого {\tt c} есть только один компонент \index{greypart?\texttt{greypart}}\label{Dgreyprt}% $$ \hbox{\tt greypart c}. $$ %%For a cmykcolor {\tt c}, the parts are:\index{cyanpart?\texttt{cyanpart}}% %%\index{magentapart?\texttt{magentapart}}% %%\index{yellowpart?\texttt{yellowpart}}% %%\index{blackpart?\texttt{blackpart}}\label{Dcmykprt} %%$$ \hbox{\tt (cyanpart c, magentapart c, yellowpart c, blackpart c)} $$ %%and for a greyscale color {\tt c}, there is only one component% %%\index{greypart?\texttt{greypart}}\label{Dgreyprt}% %%$$ \hbox{\tt greypart c}. $$ Все операторы компонент цвета обсуждаются более подробно в разделе~\ref{piccomp}. %%All color component operators are discussed in more detail in %%section~\ref{piccomp}. Спецификаторы частей трансформаций обсуждаются в разделе~\ref{transsec}. %%The part specifiers for transforms are discussed %%in section~\ref{transsec}. \section{Переменные} %%\section{Variables} \label{vars} MetaPost позволяет составные имена переменных, такие как {\tt z.a}, {\tt x2r}, {\tt y2r} и {\tt z2r}, где {\tt z2r} означает {\tt (x2r,y2r)}, а {\tt z.a} --- {\tt (x.a,y.a)}. %%MetaPost allows compound variable names such as {x.a}, {\tt x2r}, {\tt y2r}, %%and {\tt z2r}, where {\tt z2r} means {\tt (x2r,y2r)} and {\tt z.a} means %%{\tt (x.a,y.a)}. Фактически существует широкий класс суффиксов, например, {\tt z}\tdescr{суффикс}\index{суффикс?\tdescr{суффикс}}, означающий $$ (x\descr{суффикс},\, y\descr{суффикс}). $$ %%In fact there is a broad class of suffixes such that %%{\tt z}\tdescr{suffix}\index{suffix?\tdescr{suffix}} means %%$$ (x\descr{suffix},\, y\descr{suffix}). $$ Из-за того, что \tdescr{суффикс} составляется из знаков, будет наилучшим начать с нескольких слов о знаках. %%Since a \tdescr{suffix} is composed of tokens, it is best to begin with a few %%comments about tokens. \subsection{Знаки} %%\subsection{Tokens} Входной файл MetaPost рассматривается как последовательность чисел, строковых констант и символьных знаков\index{знаки}\index{знаки!символические}. %%A MetaPost input file is treated as a sequence of numbers, string %%constants, and symbolic tokens\index{tokens}\index{tokens!symbolic}. Число состоит из последовательности цифр и может содержать десятичную точку. %%A %%number consists of a sequence of digits possibly containing a decimal %%point. Технически знак минус вначале отрицательного числа --- это отдельный знак. %%Technically, the minus sign in front of a negative number is a %%separate token. Из-за того, что MetaPost использует арифметику\index{арифметика} с фиксированной точкой, он не понимает экспоненциальной нотации, такой как {\tt 6.02E23}. %%Since MetaPost uses fixed point %%arithmetic\index{arithmetic}, it does not understand exponential %%notation such as {\tt 6.02E23}. MetaPost будет интерпретировать это как число 6.02, за которым следует символьный знак {\tt E}, за которым идет число~23. %%MetaPost would interpret this as the %%number 6.02, followed by the symbolic token {\tt E}, followed by the %%number~23. Все между парой двойных кавычек, {\tt \qq}, является строковой константой\index{строковые константы}. %%Anything between a pair of double quotes {\tt \qq} is a %%string constant\index{string constants}. Строковой константе нельзя начинаться на одной строке и заканчиваться на другой. %%It is %%illegal for a string constant to start on one line and end on a later line. Строковая константа не может также содержать двойных кавычек, {\tt \qq}, и чего-нибудь еще, отличного от печатных символов ASCII. %%Nor can a string constant contain double quotes {\tt \qq} or anything other than %%printable ASCII characters. Все в строке ввода, отличное от чисел и символьных констант, разбивается на символьные знаки\index{знаки!символические}. %%Everything in a line of input other than numbers and string constants is broken %%into symbolic tokens\index{tokens!symbolic}. Символьный знак --- это последовательность одного или более схожих символов, где символы ``схожи'', если они встречаются на одной строке таблицы~\ref{classes}. %%A symbolic token is a sequence of %%one or more similar characters, where characters are ``similar'' if they occur %%on the same row of Table~\ref{classes}. \begin{table} $$\begin{tabular}{c} \verb|ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz|\\ {\tt :<=>|}\\ \verb|#&@$|\\ \verb|/*\|\\ {\tt +-}\\ {\tt !?}\\ {\tt '`}\\ \verb|^~|\\ \verb|{}|\\ {\tt [}\\ {\tt ]}\\ \end{tabular} $$ \caption{Классы символов для разбиения на знаки} %%\caption{Character classes for tokenization} \label{classes} \end{table} Таким образом, \verb|A_alpha| и {\tt +-+} --- это отдельные символические знаки, {\tt !=} интерпретируется как два знака, а {\tt x34} --- это символический знак, за которым следует число. %%Thus \verb|A_alpha| and {\tt +-+} are symbolic tokens but {\tt !=} is %%interpreted as two tokens and {\tt x34} is a symbolic token followed by %%a number. Вследствие того, что квадратные скобки приведены на отдельных строках, символическими знаками, включающими их, являются только {\tt [}, {\tt [[}, {\tt [[[}, ... и {\tt ]}, {\tt ]]}, ... %%Since the brackets {\tt [} and {\tt ]} are listed on lines by %%themselves, the only symbolic tokens involving them are {\tt [}, {\tt %%[[}, {\tt [[[}, etc.\ and {\tt ]}, {\tt ]]}, etc. Некоторые символы не приведены в таблице~\ref{classes}, потому что они требуют специального обращения. %%Some characters are not listed in Table~\ref{classes} because they need %%special treatment. Четыре символа {\tt ,;()} являются ``одиночками'': запятая, точка с запятой или скобка --- это отдельный знак, даже если одинаковые из них идут подряд. %%The four characters {\tt ,;()} are ``loners'': each %%comma, semicolon, or parenthesis is a separate token %%even when they occur consecutively. Таким образом, {\tt (())} --- это четыре знака, а не один или два. %%Thus {\tt (())} is four tokens, not %%one or two. Знак процента является весьма специальным, потому что он вводит комментарии\index{комментарии}. %%The percent sign is very special because it introduces %%comments\index{comments}. Знак процента и все после него до конца строки игнорируется. %%The percent sign and everything after it up %%to the end of the line are ignored. Другим специальным символом является точка. %%Another special character is the period. Две и более точек вместе формируют символьный знак, но отдельная точка игнорируется, а точка, перед которой или за которой идут цифры, является частью числа. %%Two or more periods %%together form a symbolic token, but a single period is ignored, and a period %%preceded or followed by digits is part of a number Таким образом, {\tt ..} и {\tt ...} --- это символьные знаки, а {\tt a.b} --- это просто два знака {\tt a} и {\tt b}. %%Thus {\tt ..} %%and {\tt ...} are symbolic tokens while {\tt a.b} is just two tokens {\tt a} %%and {\tt b}. Принято использовать точку таким образом для разделения знаков, когда имя переменной имеет длину более одного знака. %%It conventional to use periods to separate tokens in this fashion %%when naming a variable that is more than one token long. \subsection{Декларации переменных} %%\subsection{Variable Declarations} \label{vardecl} Имя переменной --- это либо символьный знак, либо последовательность символьных знаков. %%A variable name is a symbolic token or a sequence of symbolic tokens. Большинство символьных знаков являются правильными именами переменных, но что угодно с предопределенным значением подобно {\tt draw}, {\tt +} или {\tt ..} недопустимо, например, имена переменных не могут быть макросами или примитивами MetaPost. %%Most symbolic tokens are legitimate variable names, but anything with a %%predefined meaning like {\tt draw}, {\tt +}, or {\tt ..} is disallowed; %%i.e., variable names cannot be macros or MetaPost primitives. Это второстепенное ограничение допускает широкий класс имен переменных: {\tt alpha}, \verb|==>|, \verb|@&#$&| и \verb|~~| --- все они легитимные имена переменных. %%This %%minor restriction allows an amazingly broad class of variable names: %%{\tt alpha}, \verb|==>|, \verb|@&#$&|, and \verb|~~| are all legitimate %%variable names. Символьные знаки без специального значения называются этикетками ({\em tags}\index{этикетки}). %%Such symbolic tokens without special meanings are %%called {\em tags}\index{tags}. Имя переменной может быть последовательностью этикеток, подобной {\tt f.bot} или {\tt f.top}. %%A variable name can be a sequence of tags like {\tt f.bot} or {\tt %%f.top}. Эта идея служит для создания некоторых возможностей записей Паскаля или структур Си. %%The idea is to provide some of the functionality of Pascal %%records or C structures. Также возможно симулировать массивы использованием имен переменных, содержащих числа и символьные знаки. %%It is also possible to simulate arrays by %%using variable names that contain numbers as well as symbolic tokens. Например, имя переменной {\tt x2r} состоит из этикетки {\tt x}, числа 2 и этикетки~{\tt r}. %%For example, the variable name {\tt x2r} consists of the tag {\tt x}, %%the number 2, and the tag~{\tt r}. Могут быть также переменные, именованные {\tt x3r} и даже {\tt x3.14r}. %%There can also be variables named {\tt x3r} and even {\tt x3.14r}. Эти переменные можно рассматривать как массив\index{массивы} через конструкции, подобные {\tt x[i]r}, где {\tt i} имеет подходящее числовое значение. %%These variables can be treated as an %%array\index{arrays} via constructions like {\tt x[i]r}, where {\tt i} %%has an appropriate numeric value. Суммарный обзор синтаксиса для имен переменных показан на рис.~\ref{syvar}. %%The overall syntax for variable names is shown in Figure~\ref{syvar}. \begin{figure}[htp] \begin{ctabbing} $\tt \descr{переменная} \rightarrow \descr{этикетка}\descr{суффикс}$\\ %%$\tt \descr{variable} \rightarrow \descr{tag}\descr{suffix}$\\ $\tt \descr{суффикс} \rightarrow \descr{пусто} \;|\; \descr{суффикс}\descr{индекс} \;|\; \descr{суффикс}\descr{этикетка}$\\ %%$\tt \descr{suffix} \rightarrow \descr{empty} \;|\; %% \descr{suffix}\descr{subscript} \;|\; \descr{suffix}\descr{tag}$\\ $\tt \descr{индекс} \rightarrow \descr{число} \;|\; \hbox{\tt [}\descr{числовое выражение}\hbox{\tt ]}$ %%$\tt \descr{subscript} \rightarrow \descr{number} \;|\; %% \hbox{\tt [}\descr{numeric expression}\hbox{\tt ]}$ \end{ctabbing} \caption{Синтаксис имен переменных.} %%\caption{The syntax for variable names.} \index{суффикс?\tdescr{суффикс}}\index{индекс?\tdescr{индекс}} %%\index{suffix?\tdescr{suffix}}\index{subscript?\tdescr{subscript}} \label{syvar} \end{figure} Переменные, подобные {\tt x2} и {\tt y2}, обычно имеют числовое значение, поэтому мы можем использовать факт, что {\tt z}\tdescr{суффикс} --- это сокращение для\index{z convention?{\tt z}-соглашение}\label{Dzconv} $$ (x\descr{суффикс},\, y\descr{суффикс}), $$ для генерации пар-значений, когда нужно. %%Variables like {\tt x2} and {\tt y2} take on numeric values by default, so we %%can use the fact that {\tt z}\tdescr{suffix} is an abbreviation for\index{z %%convention?{\tt z} convention}\label{Dzconv} %%$$ (x\descr{suffix},\, y\descr{suffix}) $$ %%to generate pair-valued variables when needed. С другой стороны, макрос {\tt beginfig}\index{beginfig?\texttt{beginfig}} уничтожает все существующие до его исполнения переменные, начинающиеся с этикеток {\tt x} или {\tt y}, так что блоки {\tt beginfig} \ldots\ {\tt endfig} не взаимодействуют друг с другом при использовании такой схемы именования. %%It turns out that the %%{\tt beginfig}\index{beginfig?\texttt{beginfig}} macro wipes out %%pre-existing values variables that begin with the tags {\tt x} or {\tt %%y} so that {\tt beginfig} \ldots\ {\tt endfig} blocks do not interfere %%with each other when this naming scheme is used. Другими словами, переменные, начинающиеся с {\tt x}, {\tt y}, {\tt z}, локальны\index{переменные!локальные}\index{локальность} в той картинке, где они используются. %%In other words, %%variables that start with {\tt x}, {\tt y}, {\tt z} are %%local\index{variables!local}\index{locality} to the figure they are used %%in. Общий механизм для создания локальных переменных будет обсуждаться в разделе~\ref{grsec}. %%General mechanisms for making variables local will be discussed in %%Section~\ref{grsec}. Объявления типа\index{декларации}\index{декларации типа} делает возможным использование почти любой схемы именования при удалении всех предшествующих значений, что могут вызвать взаимодействие. %%Type declarations\index{declarations}\index{type declarations} %%make it possible to use almost any naming scheme while still %%wiping out any previous value that might cause interference. Например, декларация $$ \hbox{\tt pair pp, a.b;} $$ делает {\tt pp} и {\tt a.b} неизвестными парами. %%For example, the declaration %%$$ \hbox{\tt pair pp, a.b;} $$ %%makes {\tt pp} and {\tt a.b} unknown pairs. Такая декларация не является строго локальной, т.~к. {\tt pp} и {\tt a.b} не восстанавливают автоматически свои предшествующие значения в конце текущего рисунка. %%Such a declaration is not %%strictly local since {\tt pp} and {\tt a.b} are not automatically %%restored to their previous values at the end of the current figure. Они опять становятся неизвестными парами при повторении этой декларации. %%Of %%course, they are restored to unknown pairs if the declaration is %%repeated. Декларации работают одинаковым образом для любого другого из оставшихся девяти типов: числового, путевого, трансформационного, цветового, cmyk-цветового, строкового, логического, рисуночного и перьевого. %%Declarations work the same way for any of the other eight types: %%numeric, path, transform, color, string, boolean, picture, and pen. Единственное ограничение в том, что вы не можете задать точный числовой индекс в декларации переменной. %%The %%only restriction is that you cannot give explicit numeric subscripts in %%a variable declaration. Не пишите ошибочных деклараций типа $$ \hbox{\tt numeric q1, q2, q3;} $$ используйте обобщенный символ индекса\index{индекс!обобщенный} {\tt []}\index{массивы}\index{[]?\texttt{[]}!массив} вместо чисел для объявления всего массива: $$ \hbox{\tt numeric q[];} $$ %%Do not give the illegal declaration %%$$ \hbox{\tt numeric q1, q2, q3;} $$ %%use the generic subscript\index{subscript!generic} symbol %%{\tt []}\index{arrays}\index{[]?\texttt{[]}!array} %%instead, to declare the whole array: %%$$ \hbox{\tt numeric q[];} $$ Вы можете также определить ``многоразмерные'' массивы\index{массивы!многомерные}. %%You can also declare ``multidimensional'' arrays\index{arrays!multidimensional}. После декларации $$ \hbox{\tt path p[]q[], pq[][];} $$ {\tt p2q3} и {\tt pq1.4 5} --- это два пути. %%After the declaration %%$$ \hbox{\tt path p[]q[], pq[][];} $$ %%{\tt p2q3} and {\tt pq1.4 5} are both paths. Внутренние\index{внутренние переменные}\index{переменные!внутренние} переменные, подобные {\tt tracingonline}, не могут быть объявлены нормальным образом. %%Internal\index{internal variables}\index{variables!internal} variables %%like {\tt tracingonline} cannot be declared in the normal fashion. Все внутренние переменные, обсуждаемые в этом руководстве имеют значения изначально и никак не могут быть декларированы снова, но есть способ объявить, что новая переменная должна вести себя подобно внутренней. %%All %%the internal variables discussed in this manual are predefined and do %%not have to be declared at all, but there is a way to declare that a %%variable should behave like a newly-created internal variable. Это декларация {\tt newinternal}\index{newinternal?\texttt{newinternal}}\label{Dnewint}, за которой следует список символических знаков. %%The %%declaration is {\tt %%newinternal}\index{newinternal?\texttt{newinternal}}\label{Dnewint} %%followed by a list of symbolic tokens. Например, $$ \hbox{\tt newinternal a, b, c;} $$ обусловит поведение {\tt a}, {\tt b} и {\tt c}, как и у внутренних переменных. %%For example, %%$$ \hbox{\tt newinternal a, b, c;} $$ %%causes {\tt a}, {\tt b}, and {\tt c} to behave like internal variables. Такие переменные всегда имеют известные числовые значения и эти значения могут быть изменены только использованием оператора присваивания\index{присваивание} {\tt:=}\index{:=?\texttt{:=}}. %%Such variables always have known numeric values, and these values can %%only be changed by using the assignment\index{assignment} operator %%{\tt:=}\index{:=?\texttt{:=}}. Внутренние переменные инициализируются нулем и, кроме того, макропакет Plain\index{макросы Plain} дает некоторым из них ненулевые значения. %%Internal variables are initially zero %%except that the Plain\index{Plain macros} macro package gives some of %%them nonzero initial values. (Макросы Plain обычно загружаются автоматически в начале работы как описано в разделе~\ref{intro}.) %%(The Plain macros are normally preloaded %%automatically as explained in Section~\ref{intro}.) \section{Интеграция текста и графики} %%\section{Integrating Text and Graphics} \label{text} MetaPost имеет несколько возможностей для включения меток и прочего текста\index{текст и графика} в генерируемые им рисунки. %%MetaPost has a number of features for including labels and other %%text\index{text and graphics} in the figures it generates. Простейший способ сделать это в использовании команды {\tt label}\index{label?\texttt{label}}\label{Dlabel}\index{label suffix?\tdescr{суффикс метки}} $$ {\tt label}\descr{суффикс метки} \hbox{\tt (} \descr{выражение-строка или картинка} \hbox{\tt,}\, \descr{выражение-пара} \hbox{\tt );} $$ %%The simplest %%way to do this is to use the {\tt %%label}\index{label?\texttt{label}}\label{Dlabel} statement\index{label %%suffix?\tdescr{label suffix}} %%$$ {\tt label}\descr{label suffix} \hbox{\tt (} %% \descr{string or picture expression} \hbox{\tt,}\, \descr{pair expression} %% \hbox{\tt );} %%$$ \tdescr{Выражение-строка или картинка} задает метку, а \tdescr{выражение-пара} позицию для нее. %%The \tdescr{string or picture expression} gives the label and the %%\tdescr{pair expression} says where to put it. \tdescr{Суффикс метки} может быть \tdescr{пустым}, что будет означать центрировать метку на заданных координатах. %%The \tdescr{label %%suffix} can be \tdescr{empty} in which case the label is just centered %%on the given coordinates. Если вы размечаете некоторые участки диаграммы, то вам вероятно понадобится слегка сместить метку, чтобы избежать накладки. %%If you are labeling some feature of a diagram %%you probably want to offset the label slightly to avoid overlapping. Это иллюстрируется на рис.~\ref{fig16}, где метка {\tt \qq{a}\qq} размещается над серединой указываемой линии, а метка {\tt \qq{b}\qq} --- слева от середины своей линии. %%This is illustrated in Figure~\ref{fig16} where the {\tt \qq{a}\qq} label is %%placed above the midpoint of the line it refers to and the {\tt \qq{b}\qq} %%label is to the left of the midpoint of its line. Это достигается использованием {\tt label.top}\index{top?\texttt{top}} для метки {\tt \qq{a}\qq} и {\tt label.lft}\index{lft?\texttt{lft}} для метки {\tt \qq{b}\qq}, как показано на рисунке. %%This is achieved by %%using {\tt label.top}\index{top?\texttt{top}} for the {\tt \qq{a}\qq} label %%and {\tt label.lft}\index{lft?\texttt{lft}} for the {\tt \qq{b}\qq} label as %%shown in the figure. \tdescr{Суффикс метки} указывает позицию метки относительно заданных координат. %%The \tdescr{label suffix} specifies the position %%of the label relative to the specified coordinates. Полное множество возможностей --- это\index{rt?\texttt{rt}}\index{bot?\texttt{bot}}% \index{ulft?\texttt{ulft}}\index{urt?\texttt{urt}}\index{llft?\texttt{llft}}\index{lrt?\texttt{lrt}} $$ {\tt \descr{суффикс метки} \rightarrow \descr{пусто} \;|\; lft \;|\; rt \;|\; top \;|\; bot \;|\; ulft \;|\;urt \;|\; llft \;|\; lrt}, $$ где {\tt lft} и {\tt rt} означают влево и вправо, а {\tt llft}, {\tt ulft} и т.~п. значат вниз и влево, вверх и влево и т.~п. %%The complete set of %%possibilities is\index{rt?\texttt{rt}}\index{bot?\texttt{bot}}% %%\index{ulft?\texttt{ulft}}\index{urt?\texttt{urt}}\index{llft?\texttt{llft}}\index{lrt?\t%%exttt{lrt}} %%$$ \tt \descr{label suffix} \rightarrow %% \descr{empty} \;|\; lft \;|\; rt \;|\; top \;|\; bot \;|\; %% ulft \;|\;urt \;|\; llft \;|\; lrt %%$$ %%where {\tt lft} and {\tt rt} mean left and right and {\tt llft}, {\tt %%ulft}, etc.\ mean lower left, upper left, etc. Действительное расстояние, на которое будет смещена метка в заданном направлении, определяется внутренней переменной \index{внутренние переменные}\index{переменные!внутренние} {\tt labeloffset}\index{labeloffset?\texttt{labeloffset}}\label{Dlaboff}. %%The actual amount by %%which the label is offset in whatever direction is determined by the %%internal variable\index{internal variables}\index{variables!internal} %%{\tt %%labeloffset}\index{labeloffset?\texttt{labeloffset}}\label{Dlaboff}. \begin{figure}[htp] $$ \begin{verbatim} beginfig(17); a=.7in; b=.5in; z0=(0,0); z1=-z3=(a,0); z2=-z4=(0,b); draw z1..z2..z3..z4..cycle; draw z1--z0--z2; label.top("a", .5[z0,z1]); label.lft("b", .5[z0,z2]); dotlabel.bot("(0,0)", z0); endfig; \end{verbatim} \qquad \mathcenter{\includegraphics{manfig-ru-17}} $$ \caption{Код MetaPost и результат вывода} %%\caption{MetaPost code and the resulting output} \label{fig16} \end{figure} Рис.\ref{fig16} также иллюстрирует команду {\tt dotlabel}\index{dotlabel?\texttt{dotlabel}}\label{Ddotlab}. %%Figure~\ref{fig16} also illustrates the %%{\tt dotlabel}\index{dotlabel?\texttt{dotlabel}}\label{Ddotlab} %%statement. Она в точности такая же как команда {\tt label}, за которой следует команда рисования точки в заданных координатах. %%This is effectively %%like a {\tt label} statement followed by a statement drawing a dot at %%the indicated coordinates. Например, $$ \hbox{\tt dotlabel.bot(\qq(0,0)\qq, z0)} $$ помещает точку в {\tt z0} и затем размещает метку ``(0,0)'' точно под точкой. %%For example %%$$ \hbox{\tt dotlabel.bot("(0,0)", z0)} $$ %%places a dot at {\tt z0} and then puts the label ``(0,0)'' just below the dot. Другой альтернативой является макрос {\tt thelabel}\index{thelabel?\texttt{thelabel}}\label{Dthelab}. %%Another alternative is the macro %%{\tt thelabel}\index{thelabel?\texttt{thelabel}}\label{Dthelab}. Он имеет такой же синтаксис, что и команды {\tt label} и {\tt dotlabel}, но он возвращает результат как \tdescr{первичный рисунок} вместо его действительного изображения. %%This has %%the same syntax as the {\tt label} and {\tt dotlabel} statements except that it %%returns the label as a \tdescr{picture primary} instead of actually drawing it. Таким образом, $$ \hbox{\tt label.bot(\qq(0,0)\qq, z0)} $$ эквивалентно $$ \hbox{\tt draw thelabel.bot(\qq(0,0)\qq, z0)} $$ %%Thus %%$$ \hbox{\tt label.bot("(0,0)", z0)} $$ %%is equivalent to %%$$ \hbox{\tt draw thelabel.bot("(0,0)", z0)} $$ Для простых случаев размеченных рисунков, вам может обычно быть достаточно {\tt label} и {\tt dotlabel}. %%For simple applications of labeled figures, you can normally get by with %%just {\tt label} and {\tt dotlabel}. Дополнительно вы можете использовать короткую форму команды {\tt dotlabel}, что сэкономит много времени, когда вы имеете много точек {\tt z0}, {\tt z1}, {\tt z.a}, {\tt z.b}, и т.~п. и хотите использовать суффиксы {\tt z} как метки. %%In fact, you may be able to use a %%short form of the {\tt dotlabel} statement that saves a lot of typing %%when you have many points {\tt z0}, {\tt z1}, {\tt z.a}, {\tt z.b}, %%etc.\ and you want to use the {\tt z} suffixes as labels. Команда \index{dotlabels?\texttt{dotlabels}}\label{Ddotlbs} $$ \hbox{\tt dotlabels.rt(0, 1, a);} $$ эквивалентна $$ \hbox{\tt dotlabel.rt(\qq0\qq,z0); dotlabel.rt(\qq1\qq,z1); dotlabel.rt({\qq}a{\qq},z.a);} $$ %%The statement\index{dotlabels?\texttt{dotlabels}}\label{Ddotlbs} %%$$ \hbox{\tt dotlabels.rt(0, 1, a);} $$ %%is equivalent to %%$$ \hbox{\tt dotlabel.rt("0",z0); dotlabel.rt("1",z1); dotlabel.rt("a",z.a);} $$ Таким образом, аргумент {\tt dotlabels} --- это список суффиксов для переменных {\tt z}, а \tdescr{суффикс метки}, задаваемый с {\tt dotlabels}, используется для позиционирования всех меток. %%Thus the argument to {\tt dotlabels} is a list of suffixes for which {\tt z} %%variables are known, and the \tdescr{label suffix} given with {\tt dotlabels} %%is used to position all the labels. Есть еще команда {\tt labels}\index{labels?\texttt{labels}}\label{Dlabels}, аналогичная {\tt dotlabels}, но ее использование не рекомендуется, т.~к. она создает проблемы совместимости с \MF\index{metafont?\MF}. %%There is also a {\tt %%labels}\index{labels?\texttt{labels}}\label{Dlabels} statement that is %%analogous to {\tt dotlabels} but its use is discouraged because it %%presents compatibility problems with \MF\index{metafont?\MF}. Некоторые версии стандартного макропакета Plain\index{макросы Plain} определяют {\tt labels} как синоним {\tt dotlabels}. %%Some %%versions of the preloaded Plain\index{Plain macros} macro package define %%{\tt labels} to be synonymous with {\tt dotlabels}. Для команд разметки, таких как {\tt label} и {\tt dotlabel}, использующих строковые выражения для текста меток, строки печатаются в стандартном шрифте, определяемом строковой переменной {\tt defaultfont}\index{defaultfont?\texttt{defaultfont}}\label{Ddffont}. %%For labeling statements such as {\tt label} and {\tt dotlabel} that use %%a string expression for the label text, the string gets typeset in a %%default font as determined by the string variable {\tt %%defaultfont}\index{defaultfont?\texttt{defaultfont}}\label{Ddffont}. Начальное значение {\tt defaultfont} --- это обычно {\tt \qq{cmr10}\qq}, но оно может быть изменено на другое имя шрифта присваиванием, например, $$ \hbox{\tt defaultfont:=\qq{ptmr8r}\qq}, $$ \ttt{ptmr8r} --- это типичный способ сослаться на шрифт Times-Roman в \TeX. %%The initial value of {\tt defaultfont} is likely to be {\tt \qq{cmr10}\qq}, %%but it can be changed to a different font name by giving an assignment %%such as %%$$ \hbox{\tt defaultfont:=\qq{ptmr8r}\qq} $$ %%\ttt{ptmr8r} is a typical way to refer to the Times-Roman font in \TeX. %%The discussion of font names on p.\ \pageref{fontname} explains further. Есть еще числовое количество, называемое {\tt defaultscale}\index{defaultscale?\texttt{defaultscale}}\label{Ddfscale}, определяющее размер шрифта. %%There is also a numeric quantity called %%{\tt defaultscale}\index{defaultscale?\texttt{defaultscale}}\label{Ddfscale} %%that determines the type size. Пока {\tt default\-scale} равно 1, вы получаете ``нормальный размер'', который обычно равен 10 пунктам, но это можно изменить. %%When {\tt default\-scale} is 1, you get the ``normal size'' which is %%usually 10 point, but this can also be changed. Например, $$ \hbox{\tt defaultscale := 1.2} $$ делает метки на двадцать процентов больше. %%For instance %%$$ \hbox{\tt defaultscale := 1.2} $$ %%makes labels come out twenty percent larger. Если вам неизвестен нормальный размер и вы хотите быть уверенными в конкретном размере шрифта, скажем 12 пунктов, вы можете использовать оператор {\tt fontsize}\index{fontsize?\texttt{fontsize}}\label{Dfntsiz} для определения нормального размера, например, $$ \hbox{\tt defaultscale := 12pt/fontsize defaultfont;} $$ %%If you do not know the %%normal size and you want to be sure the text comes out at some specific %%size, say 12 points, you can use the {\tt %%fontsize}\index{fontsize?\texttt{fontsize}}\label{Dfntsiz} operator to %%determine the normal size: e.g., %%$$ \hbox{\tt defaultscale := 12pt/fontsize defaultfont;} $$ \label{fontname} Когда вы меняете {\tt defaultfont}, то имя нового шрифта должно быть чем-то, что \TeX\ сможет понять, т.~к. MetaPost получает информацию о высоте и ширине чтением {\tt tfm}\index{tfm file?{\tt tfm}-файл}\index{файлы!tfm?{\tt tfm}}-файла. %%When you change {\tt defaultfont}, the new font name should be something %%that \TeX\ would understand since MetaPost gets height and width %%information by reading a {\tt tfm}\index{tfm file?{\tt tfm} %%file}\index{files!tfm?{\tt tfm}} file. (Это объясняется в {\sl The \TeX book\/} \cite{kn:a}.) %%(This is explained in {\sl The \TeX book\/} \cite{kn:a}.) Должно быть возможно использовать встроенные шрифты PostScript\index{PostScript!шрифты}, но их имена зависят от системы. %%It should be possible to use built-in %%PostScript\index{PostScript!fonts} fonts, but the names for %%them are system-dependent. Некоторые типичные имена шрифтов --- это {\tt ptmr8r} для Times-Roman\index{Times-Roman}, \ttt{pplr8r} для Palatino\index{Palatino} и \ttt{phvr} для Helvetica\index{Helvetica}. %%Some typical ones are {\tt ptmr8r} for %%Times-Roman\index{Times-Roman}, \ttt{pplr8r} for Palatino\index{Palatino}, %%and \ttt{phvr} for Helvetica\index{Helvetica}. Документ Fontname, доступный в \url{http://tug.org/fontname}, содержит много информации об именах шрифтов и \TeX. %%The Fontname document, %%available at \url{http://tug.org/fontname}, has much more information %%about font names and \TeX. \TeX\index{TeX?\TeX!шрифты}-шрифт, такой как {\tt cmr10}, является немного опасным, потому что он не имеет символа пробел и некоторых других символов ASCII. %%A \TeX\index{TeX?\TeX!fonts} font such %%as {\tt cmr10} is a little dangerous because it does not have a space %%character or certain ASCII symbols. MetaPost не использует информацию о лигатурах\index{лигатуры} и кернингах\index{кернинг}, что содержится в шрифтах \TeX. %%MetaPost does not use the ligatures\index{ligatures} and %%kerning\index{kerning} information that comes with a \TeX\ font. Более того, сам MetaPost не может интерпретировать виртуальные шрифты. %%Further, MetaPost itself does not interpret virtual fonts. \subsection{Набор ваших меток} %%\subsection{Typesetting Your Labels} \label{Dbtex} \index{метки, набор} %%\index{labels, typesetting} \TeX\index{TeX?\TeX} может быть использован для форматирования сложных меток. %%\TeX\index{TeX?\TeX} may be used to format complex labels. Если вы напишите \index{btex?\texttt{btex}}\index{etex?\texttt{etex}} $$ {\tt btex}\, \descr{команды печати}\, {\tt etex} $$ во входном файле MetaPost, то \tdescr{команды печати} будут обработаны \TeX\ и транслированы в выражение-картинку, точнее в \tdescr{первичный рисунок}, что сможет использоваться в команде {\tt label} или {\tt dotlabel}. %%If you say\index{btex?\texttt{btex}}\index{etex?\texttt{etex}} %%$$ {\tt btex}\, \descr{typesetting commands}\, {\tt etex} $$ %%in a MetaPost input file, the \tdescr{typesetting commands} get processed by %%\TeX\ and translated into a picture expression %%(actually a \tdescr{picture primary}) that can be used in a {\tt label} %%or {\tt dotlabel} statement. Пробелы после {\tt btex} или перед {\tt etex} игнорируются. %%Any spaces after {\tt btex} or before {\tt etex} are ignored. Например, команда $$ \hbox{\verb|label.lrt(btex $\sqrt x$ etex, (3,sqrt 3)*u)|} $$ на рис.~\ref{fig17} поместит метку $\sqrt x$ снизу и вправо от точки {\tt (3,sqrt 3)*u}. %%For instance, the statement %%$$ \hbox{\verb|label.lrt(btex $\sqrt x$ etex, (3,sqrt 3)*u)|} $$ %%in Figure~\ref{fig17} places the label $\sqrt x$ at the lower right of the %%point {\tt (3,sqrt 3)*u}. \begin{figure}[htp] $$ \begin{verbatim} beginfig(18); numeric u; u = 1cm; draw (0,2u)--(0,0)--(4u,0); pickup pencircle scaled 1pt; draw (0,0){up} for i=1 upto 8: ..(i/2,sqrt(i/2))*u endfor; label.lrt(btex $\sqrt x$ etex, (3,sqrt 3)*u); label.bot(btex $x$ etex, (2u,0)); label.lft(btex $y$ etex, (0,u)); endfig; \end{verbatim} \qquad \mathcenter{\includegraphics{manfig-ru-18}} $$ \caption{Произвольный \TeX\ в качестве метки} %%\caption{Arbitrary \TeX\ as labels} \label{fig17} \end{figure} Рис.~\ref{fig18} иллюстрирует некоторые более сложные вещи, что можно сделать с метками. %%Figure~\ref{fig18} illustrates some of the more complicated things that can %%be done with labels. Вследствие того, что результатом {\tt btex} \ldots {\tt etex} является картинка, им можно оперировать как картинкой. %%Since the result of {\tt btex} \ldots {\tt etex} is %%a picture, it can be operated on like a picture. В частности, к картинкам возможно применять трансформации. %%In particular, it is possible %%to apply transformations to pictures. Мы пока не обсуждали синтаксис для этого, но \tdescr{рисунок-вторичность} может быть \index{вращаемый текст}\index{rotated?\texttt{rotated}} $$ \descr{рисунок-вторичность}\, {\tt rotated}\, \descr{числовая первичность} $$ %%We have not discussed the syntax for %%this yet, but a \tdescr{picture secondary} %%can be\index{rotated text}\index{rotated?\texttt{rotated}} %%$$ \descr{picture secondary}\, {\tt rotated}\, \descr{numeric primary} $$ Это используется на рис.~\ref{fig18} для вращения метки ``$y$ axis'' так, что она располагается по-вертикали. %%This is used in Figure~\ref{fig18} to rotate the label ``$y$ axis'' so that %%it runs vertically. \begin{figure}[htp] $$ \begin{verbatim} beginfig(19); numeric ux, uy; 120ux=1.2in; 4uy=2.4in; draw (0,4uy)--(0,0)--(120ux,0); pickup pencircle scaled 1pt; draw (0,uy){right} for ix=1 upto 8: ..(15ix*ux, uy*2/(1+cosd 15ix)) endfor; label.bot(btex $x$ axis etex, (60ux,0)); label.lft(btex $y$ axis etex rotated 90, (0,2uy)); label.lft( btex $\displaystyle y={2\over1+\cos x}$ etex, (120ux, 4uy)); endfig; \end{verbatim} \qquad \mathcenter{\includegraphics{manfig-ru-19}} $$ \caption{Математические метки \TeX\ и метки, вращаемые MetaPost} %%\caption{\TeX\ labels with display math, and rotated by MetaPost} \label{fig18} \end{figure} Другой сложностью на рис.~\ref{fig18} является использование уравнения $$y={2\over 1+\cos x}$$ как метки. %%Another complication in Figure~\ref{fig18} is the use of the displayed equation %%$$y={2\over 1+\cos x}$$ %%as a label. Будет более естественно закодировать эту метку как $$ \hbox{\verb|$$y={2\over 1+\cos x}$$|}, $$ но это не сработает, потому что \TeX\ набирает метки в ``горизонтальном режиме''. %%It would be more natural to code this as %%$$ \hbox{\verb|$$y={2\over 1+\cos x}$$|} $$ %%but this would not work because %%\TeX\ typesets the labels in ``horizontal mode.'' Для печати \emph{переменного} текста, как метки, используйте полезное средство \texttt{TEX}, описанное на стр.\ \pageref{dTEX}. %%For a way to typeset \emph{variable} text as labels, see the %%\texttt{TEX} utility routine described on p.\ \pageref{dTEX}. Далее о том, как \TeX-текст транслируется в форму, понятную MetaPost: процессор MetaPost пропускает блок {\tt btex}\index{btex?\texttt{btex}} \ldots\ {\tt etex}\index{etex?\texttt{etex}}, полагаясь на препроцессор, который должен перевести этот блок в команды низкого уровня MetaPost. %%Here is how \TeX\ material gets translated into a form MetaPost %%understands: The MetaPost processor skips over {\tt %%btex}\index{btex?\texttt{btex}} \ldots\ {\tt %%etex}\index{etex?\texttt{etex}} blocks and depends on a preprocessor to %%translate them into low level MetaPost commands. Если {\tt fig.mp} --- это главный файл, то транслированный \TeX-текст помещается в файл с именем {\tt fig.mpx}\index{файлы!mpx?{\tt mpx}}. %%If the main file is %%{\tt fig.mp}, the translated \TeX\ material is placed in a file named %%{\tt fig.mpx}\index{files!mpx?{\tt mpx}}. Это обычно делается незаметно для пользователя, но вызывает ошибку, если один из блоков {\tt btex} $\ldots$ {\tt etex} содержит ошибочную команду \TeX\index{TeX?\TeX!ошибки}. %%This is normally done %%silently without any user intervention but it could fail if one of the %%{\tt btex} $\ldots$ {\tt etex} blocks contains an erroneous %%\TeX\index{TeX?\TeX!errors} command. После ошибки, ошибочный текст \TeX\ сохраняется в файле {\tt mpxerr.tex}\index{mpxerr.tex?\texttt{mpxerr.tex}} и сообщения об ошибках появляются в {\tt mpxerr.log}\index{mpxerr.log?\texttt{mpxerr.log}}. %%Then the erroneous \TeX\ input is %%saved in the file {\tt mpxerr.tex}\index{mpxerr.tex?\texttt{mpxerr.tex}} %%and the error messages appear in {\tt %%mpxerr.log}\index{mpxerr.log?\texttt{mpxerr.log}}. Препроцессор для меток \TeX\ {\it понимает\/} виртуальные шрифты, т.~е. вы можете использовать команды вашего обычного \TeX\ для переключения шрифтов внутри метки. %%The preprocessor for \TeX\ labels {\it does\/} understand virtual %%fonts, so you can use your normal \TeX\ font switching commands inside %%the label. \label{Dverbatimtex} Определения макросов \TeX\ или любые другие вспомогательные команды \TeX\ могут заключаться в блок {\tt verbatimtex}\index{verbatimtex?\texttt{verbatimtex}} \ldots\ {\tt etex}\index{etex?\texttt{etex}}. %%\TeX\ macro definitions or any other auxiliary \TeX\ commands can be %%enclosed in a {\tt verbatimtex}\index{verbatimtex?\texttt{verbatimtex}} %%\ldots\ {\tt etex}\index{etex?\texttt{etex}} block. Разница между {\tt btex} и {\tt verbatimtex} в том, что первый генерирует выражение-рисунок, а второй только добавляет данные для обработки \TeX. %%The difference %%between {\tt btex} and {\tt verbatimtex} is that the former generates a %%picture expression while the latter only adds material for \TeX\ to %%process. Например, если вы хотите, используя \TeX, напечатать метки, используя макросы из {\tt mymac.tex}, то ваш входной файл для MetaPost будет выглядеть подобно чему-то такому: %%For instance, if you want \TeX\ to typeset labels using macros %%defined in {\tt mymac.tex}, your MetaPost input file would look %%something like this: \begin{eqnarray*} && \verb|verbatimtex \input mymac etex|\\ && \verb|beginfig(1);|\\ && \qquad \dots\\ && \verb|label(btex|\, \descr{\TeX-текст, использующий \hbox{\tt mymac.tex}}\, \verb|etex, | \descr{некоторые координаты} \hbox{\tt );}\\ %%&& \verb|label(btex|\, \descr{\TeX\ material using \hbox{\tt mymac.tex}}\, %% \verb|etex, | \descr{some coordinates} \hbox{\tt );}\\ && \qquad \dots \end{eqnarray*} \label{Dtroffmode} Для Unix\footnote{Unix --- это зарегистрированная торговая марка Unix Systems Laboratories.}\index{Unix} и других основанных на Web2C систем опция MetaPost {\tt -troff} скажет препроцессору, что блоки {\tt btex} $\ldots$ {\tt etex} и {\tt verbatimtex} $\ldots$ {\tt etex} представлены в troff\index{troff} вместо \TeX. %%On Unix\footnote{Unix is a registered trademark of Unix Systems %%Laboratories.}\index{Unix\regmark} and other Web2C-based systems, the %%option {\tt -troff} to MetaPost tells the preprocessor that {\tt btex} %%$\ldots$ {\tt etex} and {\tt verbatimtex} $\ldots$ {\tt etex} blocks %%are in troff\index{troff} instead of \TeX. Когда используется эта опция, MetaPost устанавливает внутреннюю переменную \ttindex{troffmode} в~1\index{prologues?\texttt{prologues}}. %%When using this option, %%MetaPost sets the internal variable %%\ttindex{troffmode} to~1\index{prologues?\texttt{prologues}}. \label{Dprologues} Установка \ttt{prologues} может быть полезна также и с \TeX, а не только для troff. %%Setting \ttt{prologues} can be useful with \TeX, too, not just troff. Далее приводятся некоторые разъяснения: %%Here is some explanation: \begin{itemize} \item Когда \ttt{prologues} равно 0, что устанавливается по-умолчанию, выходные файлы MetaPost не содержат используемых шрифтов. %%\item When \ttt{prologues} is 0, which is the default, the MetaPost %%output files do not have embedded fonts. Шрифты в результате-выводе будут вероятно Courier\index{Courier} или Times-Roman\index{Times-Roman}. %%Fonts in the resulting %%output will probably render as Courier\index{Courier} or %%Times-Roman\index{Times-Roman}. \item Когда \ttt{prologues} равно 1, вывод MetaPost объявляется ``структурированным PostScript''\index{PostScript!структурный} (EPSF\index{EPSF}), но это не вполне верно. %%\item When \ttt{prologues} is 1, the MetaPost output claims to be %%``structured PostScript''\index{PostScript!structured} (EPSF\index{EPSF}), %%but it is not completely conformant. Этот вариант поддерживается для обратной совместимости со старыми troff-документами, но его использование как устаревшего не рекомендуется. %%This variant is kept for backward %%compatibility with old (troff) documents, but its use is deprecated. Из исторических соображений, MetaPost устанавливает \ttt{prologues} в~1, когда опция {\tt -troff} приводится в командной строке. %%For historical reasons, MetaPost sets \ttt{prologues} to~1 when the {\tt %%-troff} option is given on the command line. \item Когда \ttt{prologues} равно 2, вывод MetaPost --- это EPSF, в котором предполагается, что текст набран PostScript\index{PostScript!шрифты}-шрифтами, предоставляемыми ``средой'', такой как просмотрщик документа или встроенное приложение, использующие этот вывод. %%\item When \ttt{prologues} is 2, the MetaPost output is EPSF and assumes %%that the text comes from PostScript\index{PostScript!fonts} fonts %%provided by the ``environment'', such as the document viewer or %%embedded application using the output. MetaPost будет пытаться установить кодировку шрифта правильно, основываясь на командах \ttt{fontmapfile} и \ttt{fontmapline}. %%MetaPost will attempt to %%set up the font encodings correctly, based on \ttt{fontmapfile} and %%\ttt{fontmapline} commands. \item Когда \ttt{prologues} равно 3, вывод MetaPost будет EPSF, содержащий шрифты PostScript (или подмножества шрифтов), используемые на основе команд \ttt{fontmapfile} и \ttt{fontmapline}. %%\item When \ttt{prologues} is 3, the MetaPost output will be EPSF but %%will contain the PostScript font(s) (or a subset) used based on the %%\ttt{fontmapfile} and \ttt{fontmapline} commands. Это значение полезно для генерации самодостаточной PostScript-графики. %%This value is useful %%for generating stand-alone PostScript graphics. \end{itemize} Стоит отметить, что стандартное значение \ttt{prologues:=0} достаточно для графики, включаемой в документы \TeX. %%It is worth noting that the default value \ttt{prologues:=0} is sufficient %%for graphics included in \TeX-based documents. Переменная \ttt{prologues} также не нужна при обработке MetaPost-файлов через утилиту \ttindex{mptopdf} (из дистрибутива \ConTeXt), потому что PDF-файлы естественно самодостаточны. %%Also, the \ttt{prologues} variable is irrelevant %%when processing MetaPost files through the \ttindex{mptopdf} utility %%(part of the \ConTeXt\ distribution), because PDF files are, by nature, %%stand-alone. Более того, значение \ttt{prologues} не имеет эффекта на шрифты \MF\ в ваших MetaPost-файлах, т.~е. MetaPost никогда не встраивает такие шрифты в свой вывод. %%Moreover, the value of \ttt{prologues} has no effect on %%\MF\ fonts in your MetaPost files, i.\,e., MetaPost never embeds such %%fonts. Только драйверы вывода, например, \ttt{dvips} или pdf\LaTeX, могут встроить такие шрифты. %%Only output drivers, e.\,g., \ttt{dvips} or pdf\LaTeX\ will %%handle those. Детали того, как включать рисунки PostScript в документ, сделанный в \TeX\ или troff, системо-зависимы. %%The details on how to include PostScript figures in a paper %%done in \TeX\ or troff are system-dependent. Они могут обычно быть найдены в страницах руководства (man pages) или в другой сетевой документации, но посмотрите сначала в раздел~\ref{Dteximport} этого руководства для кратких инструкций, которые во многих случаях окажутся достаточными. %%They can generally be found %%in manual pages and other on-line documentation, but have a look at %%section~\ref{Dteximport} of this manual for some brief instructions that %%in many cases should work. Руководство для широко используемой программы Dvips находится в файле \ttt{dvips.texi}, включенном в большинство стандартных дистрибутивов и доступном в сети в \url{http://tug.org/texinfohtml/dvips.html} и в других местах, а также в других форматах. %%The manual for the %%widely-used Dvips processor is in a file \ttt{dvips.texi}, included in %%most distributions, and is available online at %%\url{http://tug.org/texinfohtml/dvips.html}, among many other places and %%formats. \label{Dmakempx} В системах, основанных на Web2C, препроцессор называется \ttindex{makempx} --- он вызывает программу \ttindex{mpto}; документация по Web2C описывает их более подробно. %%On Web2C-based systems, the preprocessor is named \ttindex{makempx}, %%which calls another utility \ttindex{mpto}; the Web2C documentation %%describes them in more detail. Однако, упомянем здесь одно свойство: если переменная среды \ttindex{MPTEXPRE} содержит имя существующего файла, то {\tt makempx} будет помещать его в начало при выводе. %%We'll mention one feature here, though: %%if the environment variable \ttindex{MPTEXPRE} is set to the name of an %%existing file, {\tt makempx} will prepend it to the output. Вы можете это использовать, например, для включения преамбул \LaTeX. %%You can use %%this to include \LaTeX\ preambles, for instance. Макрос \ttt{TEX}, описанный на стр.~\pageref{dTEX}, обеспечивает другой способ такого включения. %%The \ttt{TEX} %%macro described on p.\ \pageref{dTEX} provides another way to handle this. \subsection{Файлы-карты шрифтов} %%\subsection{Font map files} \label{Sfontmapfile}\label{Sfontmapline} Если \ttt{prologues} установлено в~2, то любые используемые в выводе шрифты автоматически перекодируются согласно таблице, указанной в отдельной записи шрифтового файла-карты и включаемой в файл вывода. %%If \ttt{prologues} is set to~2, any used fonts in the output file are %%automatically re-encoded, and the encoding vector file specified in %%the fontmap entry will be embedded in the output file. Если \ttt{prologues} установлено в~3, то MetaPost будет также пытаться включить используемые PostScript\index{PostScript!шрифты} шрифты или их подмножества. %%If \ttt{prologues} is set to~3, MetaPost will also attempt to include %%(a subset of) the used PostScript\index{PostScript!fonts} fonts. Чтобы это работало, нужно получение информации из шрифтового файла-карты. %For this to work, it needs to acquire font map information. Код, основанный на шрифтовой библиотеке, используется pdf\TeX. %%The code is based on the font library used by pdf\TeX. Следуя за pdf\TeX, обнаруживаем два новых связанных с темой примитива: \ttindex{fontmapfile} и \ttindex{fontmapline}. %%Following in %%the footsteps of pdf\TeX, there are two new associated primitives: %%\ttindex{fontmapfile} and \ttindex{fontmapline}. Далее следует простой пример, указывающий файл-карту для шрифтов Latin Modern в кодировке YandY (\LaTeX\ LY1): %%Here is a simple %%example, specifying the map file for Latin Modern fonts in YandY %%(\LaTeX\ LY1) encoding: \begin{center}\begin{tabular}{l} \verb|prologues:=2;|\\ \verb|fontmapfile "texnansi-lm.map";|\\ \verb|beginfig(1);|\\ \verb| draw "Hell|{\tt\'o, vil\'a}\verb|g" infont "texnansi-lmr10";|\\ %%\verb| draw "HellС, vilАg" infont "texnansi-lmr10";|\\ \verb|endfig;| \end{tabular}\end{center} Используя \ttt{fontmapline}, можно указать информацию о шрифте внутри рисунка: %%Using \ttt{fontmapline}, you can specify font mapping information %%inside the figure: \begin{center}\begin{tabular}{l} \verb|prologues:=2;|\\ \verb|fontmapline "pplbo8r URWPalladioL-Bold "&ditto&|\\ \verb| ".167 SlantFont"&ditto&" <8r.enc > (4.9813,6.8078)|'', а $$ \hbox{\verb|truecorners:=1; show urcorner btex $\bullet$\rlap{ A} etex|} $$ производит ``\verb|>> (15.7742,6.8078)|''. %%To get the true bounding box of such a %%picture, assign a positive value to the internal variable\index{internal %%variables}\index{variables!internal} {\tt %%truecorners}\index{truecorners?\texttt{truecorners}}\label{Dtruecorn}:\footnote{The %%{\tt setbounds} and {\tt truecorners} features are only found in %%MetaPost version 0.30 and higher.} i.e., %%$$ \hbox{\verb|show urcorner btex $\bullet$\rlap{ A} etex|} $$ %%produces ``\verb|>> (4.9813,6.8078)|'' while %%$$ \hbox{\verb|truecorners:=1; show urcorner btex $\bullet$\rlap{ A} etex|} $$ %%produces ``\verb|>> (15.7742,6.8078)|.'' \section{Продвинутая графика} %%\section{Advanced Graphics} \label{adv.gr} Все примеры предыдущих разделов были простым рисованием линий с добавлением меток. %%All the examples in the previous sections have been simple line drawings %%with labels added. Этот раздел описывает затенение и средства для генерации не столь простых линий. %%This section describes shading and tools for %%generating not-so-simple line drawings. Затенение делается командой {\tt fill}\index{fill?\texttt{fill}}\label{Dfill}. %%Shading is done with the {\tt %%fill}\index{fill?\texttt{fill}}\label{Dfill} statement. В своей простейшей форме команда {\tt fill} требует \tdescr{выражение-путь}, задающее границу региона для заполнения. %%In its simplest %%form, the {\tt fill} statement requires a \tdescr{path expression} that %%gives the boundary of the region to be filled. В синтаксисе $$ {\tt fill}\, \descr{выражение-путь} $$ аргумент должен быть циклическим путем, т.~е. путем, который описывается замкнутой кривой через {\tt ..cycle} или {\tt -{}-cycle}. %%In the syntax %%$$ {\tt fill}\, \descr{path expression} $$ %%the argument should be a cyclic path, i.e., a path that describes a %%closed curve via the {\tt ..cycle} or {\tt --cycle} notation. Например, команда {\tt fill} на рис.~\ref{fig20} строит замкнутый путь продолжением приблизительно полукругового пути~{\tt p}. %%For %%example, the {\tt fill} statement in Figure~\ref{fig20} builds a closed %%path by extending the roughly semicircular path~{\tt p}. Этот путь имеет ориентацию против часовой стрелки, но это не имеет значение, потому что команда {\tt fill} использует правило ``ненулевого вертящегося числа''\index{вертящееся число} (non-zero winding number) PostScript\index{PostScript}~\cite{ad:red2}. %%This path has %%a counter-clockwise orientation, but that does not matter because the %%{\tt fill} statement uses PostScript's\index{PostScript} non-zero %%winding\index{winding number} number rule~\cite{ad:red2}. \begin{figure}[htp] $$ \begin{verbatim} beginfig(21); path p; p = (-1cm,0)..(0,-1cm)..(1cm,0); fill p{up}..(0,0){-1,-2}..{up}cycle; draw p..(0,1cm)..cycle; endfig; \end{verbatim} \qquad \mathcenter{\includegraphics{manfig-ru-21}} $$ \caption{MetaPost код и соответствующий вывод.} %%\caption{MetaPost code and the corresponding output.} \label{fig20} \end{figure} Общая команда\index{withcolor?\texttt{withcolor}}\label{Dwithcolor} {\tt fill} $$ {\tt fill}\, \descr{выражение-путь}\, {\tt withcolor}\, \descr{выражение-цвет} $$ указывает уровень серого или (если у вас есть цветной принтер) некоторый цвет радуги. %%The general {\tt fill} statement\index{withcolor?\texttt{withcolor}}\label{Dwithcolor} %%$$ {\tt fill}\, \descr{path expression}\, %% {\tt withcolor}\, \descr{color expression} %%$$ %%specifies a shade of gray or (if you have a color printer) some %%rainbow color. $\descr{Выражение-цвет}$ может иметь пять возможных значений, переводимых к четырем возможным цветовым моделям: %%The $\descr{color expression}$ can have five possible %%values, mapping to four possible color models: $$ \begin{tabular}{ll} Действительный ввод & Переводимое значение\\\hline %%Actual input & Remapped meaning\\\hline {\tt withcolor} $\descr{rgb-цвет} c$ & withrgbcolor\index{withrgbcolor?\texttt{withrgbcolor}}\label{Dwithrgbcolor} $c$\\ %%{\tt withcolor} $\descr{rgbcolor} c$ & %%withrgbcolor\index{withrgbcolor?\texttt{withrgbcolor}}\label{Dwithrgbcolor} $c$\\ {\tt withcolor} $\descr{cmyk-цвет} c$ & withcmykcolor\index{withrgbcolor?\texttt{withcmykcolor}}\label{Dwithcmykcolor} $c$\\ %%{\tt withcolor} $\descr{cmykcolor} c$ & %%withcmykcolor\index{withrgbcolor?\texttt{withcmykcolor}}\label{Dwithcmykcolor} $c$\\ {\tt withcolor} $\descr{число} c$ & withgreyscale\index{withrgbcolor?\texttt{withgreyscale}}\label{Dwithgreyscale} $c$\\ %%{\tt withcolor} $\descr{numeric} c$ & %%withgreyscale\index{withrgbcolor?\texttt{withgreyscale}}\label{Dwithgreyscale} $c$\\ {\tt withcolor} $\descr{ложь}$ & withoutcolor\index{withrgbcolor?\texttt{withoutcolor}}\label{Dwithoutcolor} \\ %%{\tt withcolor} $\descr{false}$ & %%withoutcolor\index{withrgbcolor?\texttt{withoutcolor}}\label{Dwithoutcolor} \\ {\tt withcolor} $\descr{истина}$ & $\descr{текущая типовая модель цвета}$\\ %%{\tt withcolor} $\descr{true}$ & $\descr{current default color model}$\\ \end{tabular} $$ Для указанных моделей цвета есть также $$ {\tt fill}\, \descr{выражение-путь}\, {\tt withrgbcolor}\, \descr{выражение-rgb-цвет} $$ $$ {\tt fill}\, \descr{выражение-путь}\, {\tt withcmykcolor}\, \descr{выражение-cmyk-цвет} $$ $$ {\tt fill}\, \descr{выражение-путь}\, {\tt withgreyscale}\, \descr{число} $$ $$ {\tt fill}\, \descr{выражение-путь}\, {\tt withoutcolor} $$ %%For the specific color models, there are also: %%$$ {\tt fill}\, \descr{path expression}\, %% {\tt withrgbcolor}\, \descr{rgbcolor expression} %%$$ %%$$ {\tt fill}\, \descr{path expression}\, %% {\tt withcmykcolor}\, \descr{cmykcolor expression} %%$$ %%$$ {\tt fill}\, \descr{path expression}\, %% {\tt withgreyscale}\, \descr{numeric} %%$$ %%$$ {\tt fill}\, \descr{path expression}\, %% {\tt withoutcolor} %%$$ Объект-изображение не может иметь более одной цветовой модели, последнее указание \ttt{withcolor}, \ttt{withrgbcolor}, \ttt{withcmykcolor}, \ttt{withgreyscale} или \ttt{withoutcolor} устанавливает модель цвета для любого отдельного объекта. %%An image object cannot have more then one color model, the last %%\ttt{withcolor}, \ttt{withrgbcolor}, \ttt{withcmykcolor}, %%\ttt{withgreyscale} or \ttt{withoutcolor} specification sets the color %%model for any particular object. Модель \ttt{withoutcolor} требует небольших разъяснений: выбор этой модели означает, что MetaPost не будет писать команду выбора цвета в выходной файл PostScript для этого объекта. %%The model \ttt{withoutcolor} needs a bit more explanation: selecting %%this model means that MetaPost will not write a color selection %%statement to the PostScript output file for this object. `Текущая типовая' модель цвета может быть установлена использованием внутренней переменной \ttindex{defaultcolormodel}. %%The `current default' color model can be set up using the internal %%variable \ttindex{defaultcolormodel}. Таблица~\ref{dfltcmod} перечисляет ее допустимые значения. \begin{table} \centering \begin{tabular}{|c|l|} \hline Значение & Модель цвета\\\hline 1 & нет модели\\ 3 & оттенки серого\\ 5 & rgb (по-умолчанию)\\ 7 & cmyk\\ \hline \end{tabular} \caption{Поддерживаемые модели цвета.} \label{dfltcmod} \end{table} %%\begin{table} %%\centering %%\begin{tabular}{|с|l|} %%\hline %%Value & Color model\\\hline %%1 & no model\\ %%3 & greyscale\\ %%5 & rgb (default)\\ %%7 & cmyk\\ %%\hline %%\end{tabular} %%\caption{Supported color models.} %%\label{dfltcmod} %%\end{table} Рис.~\ref{fig21} иллюстрирует несколько применений команды {\tt fill} для заполнения областей оттенками серого. %%Figure~\ref{fig21} illustrates several applications of the fill command %%to fill areas with shades of gray. Пути включают пересечения кругов {\tt a} и {\tt b} и путь {\tt ab}, охватывающий область внутри обоих кругов. %%The paths involved are intersecting %%circles {\tt a} and {\tt b} and a path {\tt ab} that bounds the region %%inside both circles. Круги {\tt a} и {\tt b} происходят от предопределенного пути {\tt fullcircle}\index{fullcircle?\texttt{fullcircle}}\label{Dfcirc}, приблизительно соответствующего кругу с единичным диаметром и с центром в начале координат. %%Circles {\tt a} and {\tt b} are derived from a %%predefined path {\tt %%fullcircle}\index{fullcircle?\texttt{fullcircle}}\label{Dfcirc} that %%approximates a circle of unit diameter centered on the origin. Есть также предопределенный путь {\tt halfcircle}\index{halfcircle?\texttt{halfcircle}}\label{Dhcirc} --- половина {\tt fullcircle} над осью $x$. %%There is also a predefined path {\tt %%halfcircle}\index{halfcircle?\texttt{halfcircle}}\label{Dhcirc} that is %%the part of {\tt fullcircle} above the $x$ axis. Путь~{\tt ab} затем инициализируется, используя предопределенный макрос {\tt buildcycle}, который будет обсуждаться вскоре. %%Path~{\tt ab} is then %%initialized using a predefined macro {\tt buildcycle} that will be %%discussed shortly. \begin{figure}[htp] $$ \begin{verbatim} beginfig(22); path a, b, aa, ab; a = fullcircle scaled 2cm; b = a shifted (0,1cm); aa = halfcircle scaled 2cm; ab = buildcycle(aa, b); picture pa, pb; pa = thelabel(btex $A$ etex, (0,-.5cm)); pb = thelabel(btex $B$ etex, (0,1.5cm)); fill a withcolor .7white; fill b withcolor .7white; fill ab withcolor .4white; unfill bbox pa; draw pa; unfill bbox pb; draw pb; label.lft(btex $U$ etex, (-1cm,.5cm)); draw bbox currentpicture; endfig; \end{verbatim} \qquad \mathcenter{\includegraphics{manfig-ru-22}} $$ \caption{MetaPost код и соответствующий вывод.} %%\caption{MetaPost code and the corresponding output.} \index{fullcircle?\texttt{fullcircle}}\index{halfcircle?\texttt{halfcircle}}\index{buildcycle?\texttt{buildcycle}} \label{fig21} \end{figure} Заполнение круга {\tt a} светлым серым цветом {\tt .7white} и затем такое же заполнение круга {\tt b} дважды заполняет область, где круги пересекаются. %%Filling circle {\tt a} with the light gray color {\tt .7white} and then %%doing the same with circle {\tt b} doubly fills the region where the %%disks overlap. Есть правило, что каждая команда {\tt fill} присваивает данный цвет всем точкам покрываемого региона, уничтожая все, что там было, включая линии, текст и заполненные области. %%The rule is that each {\tt fill} statement assigns the %%given color to all points in the region covered, wiping out whatever was %%there previously including lines and text as well as filled regions. Таким образом, важно задавать команды {\tt fill} в правильном порядке. %%Thus it is important to give {\tt fill} commands in the right order. В примере выше перекрываемая область получает одинаковый цвет дважды, оставаясь светлосерой после первых двух команд {\tt fill}. %%In the above example, the overlap region gets the same color twice, leaving %%it light gray after the first two {\tt fill} statements. Третья команда {\tt fill} присваивает более темный цвет {\tt .4white} перекрываемой области. %%The third fill %%statement assigns the darker color {\tt .4white} to the overlap region. После этого круги и их пересечение получают свои окончательные цвета, но в них нет вырезок для меток. %%At this point the circles and the overlap region have their final colors %%but there are no cutouts for the labels. Вырезки получаются командами {\tt unfill}\index{unfill?\texttt{unfill}}\label{Dunfill}, которые быстро уничтожают\index{стирание} области, охватывающии {\tt bbox pa}\index{bbox?\texttt{bbox}} и {\tt bbox pb}. %%The cutouts are achieved by %%the {\tt unfill}\index{unfill?\texttt{unfill}}\label{Dunfill} statements %%that effectively erase\index{erasing} the regions bounded by {\tt bbox %%pa}\index{bbox?\texttt{bbox}} and {\tt bbox pb}. Более точно, {\tt unfill} --- это сокращение заполнения с {\tt withcolor background}, где {\tt background} обычно равен {\tt white}, что подходит при печати на белой бумаге. %%More precisely, {\tt %%unfill} is shorthand for filling {\tt withcolor background}, where {\tt %%background} is normally equal to {\tt white} as is appropriate for %%printing on white paper. Если необходимо, то вы можете присвоить новый цвет {\tt background}\index{background?\texttt{background}}\label{Dbground}. %%If necessary, you can assign a new color value to {\tt %%background}\index{background?\texttt{background}}\label{Dbground}. Метки должны быть помещены в картинки {\tt pa} и {\tt pb} для возможности измерения их охватывающих рамок до их рисования. %%The labels need to be stored in pictures {\tt pa} and {\tt pb} to allow %%for measuring their bounding box before actually drawing them. Макрос {\tt thelabel}\index{thelabel?\texttt{thelabel}} создает такие картинки и сдвигает их в позиции, где они готовы для рисования. %%The macro {\tt thelabel}\index{thelabel?\texttt{thelabel}} creates such %%pictures and shifts them into position so that they are ready to draw. Использование итоговых картинок в команде {\tt draw} в форме\index{draw?\texttt{draw}} $$ {\tt draw}\, \descr{выражение-рисунок} $$ добавляет их к текущей картинке {\tt currentpicture}\index{currentpicture?\texttt{currentpicture}} так, что они перезаписывают часть того, что уже нарисовано. %%Using the resulting pictures in {\tt draw} statements of the %%form\index{draw?\texttt{draw}} %%$$ {\tt draw}\, \descr{picture expression} $$ %%adds them to {\tt currentpicture}\index{currentpicture?\texttt{currentpicture}} %%so that they overwrite a portion of what has %%already been drawn. На рис.~\ref{fig21} перезаписываются сами белые прямоугольники, созданные {\tt unfill}. %%In Figure~\ref{fig21} just the white rectangles produced by %%{\tt unfill} get overwritten. \subsection{Построение циклов} %%\subsection{Building Cycles} \label{buildcy} Команда {\tt buildcycle}\index{buildcycle?\texttt{buildcycle}} конструирует пути для использования с макросами {\tt fill} или {\tt unfill}. %%The {\tt buildcycle}\index{buildcycle?\texttt{buildcycle}} command %%constructs paths for use with the {\tt fill} or {\tt unfill} macros. Когда задаются два или более путей, таких как {\tt aa} и {\tt b}, макрос {\tt buildcycle} пытается соединить их части вместе, формируя циклический путь. %%When given two or more paths such as {\tt aa} and {\tt b}, the {\tt %%buildcycle} macro tries to piece them together so as to form a cyclic %%path. В рассмотренном случае путь {\tt aa} является полукругом, начинающимся справа от пересечения с путем {\tt b}, затем проходящим через {\tt b} и заканчивающимся снаружи круга слева, как показано на рис.~\ref{fig22}a. %%In this case path {\tt aa} is a semicircle that starts just to %%the right of the intersection with path {\tt b}, then passes through %%{\tt b} and ends just outside the circle on the left as shown in %%Figure~\ref{fig22}a. Рис.~\ref{fig22}b показывает как {\tt buildcycle} формирует замкнутый цикл из кусков путей {\tt aa} и {\tt b}. %%Figure~\ref{fig22}b shows how {\tt buildcycle} forms a closed cycle from %%the pieces of paths {\tt aa} and {\tt b}. Макрос {\tt buildcycle} находит два пересечения\index{пересечения}, помеченные 1 и 2 на рис.~\ref{fig22}b. %%The {\tt buildcycle} macro %%detects the two intersections\index{intersections} labeled 1 and 2 in %%Figure~\ref{fig22}b. Затем он конструирует циклический путь, показанный выделенным на рисунке, двигаясь вдоль пути {\tt aa} от пересечения~1 к пересечению~2 и затем против часовой стрелки по пути {\tt b} обратно к пересечению~1. %%Then it constructs the cyclic path shown in bold %%in the figure by going forward along path {\tt aa} from intersection~1 %%to intersection~2 and then forward around the counter-clockwise path %%{\tt b} back to intersection~1. Кажется очевидным, что {\tt buildcycle(a,b)} будет производить такой же результат, но основания для этого несколько путанные. %%It turns out that {\tt buildcycle(a,b)} %%would have produced the same result, but the reasoning behind this is a %%little confusing. \begin{figure}[htp] $$ {\includegraphics{manfig-ru-123} \atop (a)} \qquad {\includegraphics{manfig-ru-223} \atop (b)} $$ \caption[Демонстрация построения цикла] {(a)~Полукруговой путь~{\tt aa} с пунктирной линией, отмечающей путь {\tt b}; (b)~пути~{\tt aa} и {\tt b} с частями, выделяемыми {\tt buildcycle} и показанными жирными линиями.} %%\caption[A demonstration of cycle building] %% {(a)~The semicircular path~{\tt aa} %% with a dashed line marking path {\tt b}; (b)~paths~{\tt aa} and {\tt b} %% with the portions selected by {\tt buildcycle} shown by heavy lines.} \label{fig22} \end{figure} Проще всего использовать макрос {\tt buildcycle} в ситуациях, подобных рис.~\ref{fig23}, где есть более двух аргументов-путей и каждая пара последовательных путей имеет уникальное пересечение. %%It is a easier to use the {\tt buildcycle} macro in situations like %%Figure~\ref{fig23} where there are more than two path arguments and each %%pair of consecutive paths has a unique intersection. Например, прямая~{\tt q0.5} и кривая~{\tt p2} пересекаются только в точке~$P$; кривая {\tt p2} и прямая ~{\tt q1.5} --- только в точке~$Q$. %%For instance, the %%line~{\tt q0.5} and the curve~{\tt p2} intersect only at point~$P$; and %%the curve {\tt p2} and the line~{\tt q1.5} intersect only at point~$Q$. Фактически каждая из точек $P$, $Q$, $R$, $S$ является уникальным пересечением и результат\index{buildcycle?\texttt{buildcycle}} команды $$ \hbox{\tt buildcycle(q0.5, p2, q1.5, p4)} $$ берет {\tt q0.5} от $S$ до~$P$, затем {\tt p2} от $P$ до~$Q$, затем {\tt q1.5} от $Q$ до~$R$ и, наконец, {\tt p4} от $R$ обратно до~$S$. %%In fact, each of the points $P$, $Q$, $R$, $S$ is a unique intersection, %%and the result of\index{buildcycle?\texttt{buildcycle}} %%$$ \hbox{\tt buildcycle(q0.5, p2, q1.5, p4)} $$ %%takes {\tt q0.5} from $S$ to~$P$, then {\tt p2} from $P$ to~$Q$, then %%{\tt q1.5} from $Q$ to~$R$, and finally {\tt p4} from $R$ back to~$S$. Исследование кода MetaPost для рис.~\ref{fig23} открывает, что вы должны идти назад вдоль {\tt p2} на переходе от $P$ до~$Q$. %%An examination of the MetaPost code for Figure~\ref{fig23} reveals that %%you have to go backwards along {\tt p2} in order to get from $P$ to~$Q$. Все работает вполне совершенно до тех пор, пока точки пересечения\index{пересечение} определяются уникально, но может обусловить неожиданные результаты, когда пары путей пересекаются более одного раза. %%This works perfectly well as long as the %%intersection\index{intersection} points are uniquely defined but it can %%cause unexpected results when pairs of paths intersect more than once. \begin{figure}[htp] $$ \begin{verbatim} beginfig(24); h=2in; w=2.7in; path p[], q[], pp; for i=2 upto 4: ii:=i**2; p[i] = (w/ii,h){1,-ii}...(w/i,h/i)...(w,h/ii){ii,-1}; endfor q0.5 = (0,0)--(w,0.5h); q1.5 = (0,0)--(w/1.5,h); pp = buildcycle(q0.5, p2, q1.5, p4); fill pp withcolor .7white; z0=center pp; picture lab; lab=thelabel(btex $f>0$ etex, z0); unfill bbox lab; draw lab; draw q0.5; draw p2; draw q1.5; draw p4; dotlabel.top(btex $P$ etex, p2 intersectionpoint q0.5); dotlabel.rt(btex $Q$ etex, p2 intersectionpoint q1.5); dotlabel.lft(btex $R$ etex, p4 intersectionpoint q1.5); dotlabel.bot(btex $S$ etex, p4 intersectionpoint q0.5); endfig; \end{verbatim} \atop \mathcenter{\includegraphics{manfig-ru-24}} $$ \caption{MetaPost-код и соответствующий вывод.} %%\caption{MetaPost code and the corresponding output.} \label{fig23} \end{figure} Общее правило для макроса {\tt buildcycle}: $$ \hbox{\tt buildcycle(}p_1\hbox{\tt,}\, p_2\hbox{\tt,}\, p_3\hbox{\tt,}\, \ldots \hbox{\tt,} p_k \hbox{\tt )} $$ выбирает пересечение между каждым $p_i$ и $p_{i+1}$ так, чтобы это было как можно дальше на $p_i$ и как можно ближе на $p_{i+1}$\footnote{Первым находится пересечение между $p_k$ и $p_1$, затем $p_1$ и $p_2$, $\ldots$ (прим. перев.)}. %%The general rule for the {\tt buildcycle} macro is that %%$$ \hbox{\tt buildcycle(}p_1\hbox{\tt,}\, p_2\hbox{\tt,}\, %% p_3\hbox{\tt,}\, \ldots \hbox{\tt,} p_k \hbox{\tt )} %%$$ %%chooses the intersection between each $p_i$ and $p_{i+1}$ to be as late %%as possible on $p_i$ and as early as possible on $p_{i+1}$. Нет простого правила для разрешения конфликтов между этими двумя целями, так что вам следует избегать случаев, когда одна точка пересечения случается дальше на $p_i$ и другая точка пересечения\index{пересечение} случается ближе на $p_{i+1}$. %%There is no %%simple rule for resolving conflicts between these two goals, so you %%should avoid cases where one intersection point occurs later on $p_i$ %%and another intersection\index{intersection} point occurs earlier on %%$p_{i+1}$. Установка на самые дальние пересечения для $p_i$ и самые ближние для $p_{i+1}$ ведет к устранения неясности предпочтением идущих впереди подпутей. %%The preference for intersections as late as possible on $p_i$ and as %%early as possible on $p_{i+1}$ leads to ambiguity resolution in favor of %%forward-going subpaths. Для циклических путей, как путь~{\tt b} на рис.~\ref{fig22}, ``близко'' и ``далеко'' относительны по отношению к начальной/конечной точке, которая расположена там, куда вы попадаете обратно, сказав ``{\tt ..cycle}''. %%For cyclic paths such as path~{\tt b} in %%Figure~\ref{fig22} ``early'' and ``late'' are relative to a start/finish %%point which is where you get back to when you say ``{\tt ..cycle}''. Для пути~{\tt b} эта точка устанавливается на самую правую точку на круге. %%For the path~{\tt b}, this turns out to be the rightmost point on the %%circle. Более прямой путь для работы с путевыми пересечениями в использовании \tdescr{вторичного бинарного оператора}\index{вторичный binop?\tdescr{вторичный бинарный оператор}} {\tt intersection\-point}\index{intersectionpoint?\texttt{intersectionpoint}}\label{Disecpt}, находящего точки $P$, $Q$, $R$ и~$S$ на рис.~\ref{fig23}. %%A more direct way to deal with path intersections is via the %%\tdescr{secondary binop}\index{secondary binop?\tdescr{secondary binop}} %%{\tt %%intersection\-point}\index{intersectionpoint?\texttt{intersectionpoint}}\label{Disecpt} %%that finds the points $P$, $Q$, $R$, and~$S$ in Figure~\ref{fig23}. Этот макрос находит точку, где два данных пути пересекаются. %%This macro finds a point where two given paths intersect. Если существует более одной точки пересечения, то он выбирает одну; если точек пересечения нет, то макрос генерирует сообщение об ошибке. %%If there is %%more than one intersection point, it just chooses one; if there is no %%intersection, the macro generates an error message. \subsection{Параметрическая работа с путями} %%\subsection{Dealing with Paths Parametrically} Макрос {\tt intersectionpoint}\index{intersectionpoint?\texttt{intersectionpoint}} основан на примитивной операции с именем {\tt intersectiontimes}\index{intersectiontimes?\texttt{intersectiontimes}}\label{Disectt}. %%The {\tt %%intersectionpoint}\index{intersectionpoint?\texttt{intersectionpoint}} %%macro is based on a primitive operation called {\tt %%intersectiontimes}\index{intersectiontimes?\texttt{intersectiontimes}}\label{Disectt}. Этот \tdescr{вторичный бинарный оператор} --- один из нескольких операторов, работающих с путями параметрически. %%This \tdescr{secondary binop} is one of several operations that deal %%with paths parametrically. Он находит пересечение между двумя путями, заданием параметра ``время'' на каждом из путей. %%It locates an intersection between two paths %%by giving the ``time'' parameter on each path. Это ссылка на схему параметризации из раздела~\ref{curves}, определяющего пути как кусочные кубические кривые $\bigl(X(t),Y(t)\bigr)$, где диапазон $t$ от нуля до числа отрезков кривой. %%This refers to the %%parameterization scheme from Section~\ref{curves} that described paths %%as piecewise cubic curves $\bigl(X(t),Y(t)\bigr)$ where $t$ ranges from %%zero to the number of curve segments. Другими словами, путь задается, как проходящий через последовательность точек, где $t=0$ в первой точке, $t=1$ в следующей, $t=2$ в следующей и т.~д. %%In other words, when a path is %%specified as passing through a sequence of points, where $t=0$ at the %%first point, then $t=1$ at the next, and $t=2$ at the next, etc. Результатом $$ \hbox{\tt a intersectiontimes b} $$ будет $(-1,-1)$, если пересечения нет; в противном случае, вы получите пару $(t_a,t_b)$, где $t_a$ --- это время на пути {\tt a}, когда он пересекает путь~{\tt b}, и $t_b$ --- это соответствующее время на пути~{\tt b}. %%The result of %%$$ \hbox{\tt a intersectiontimes b} $$ %%is $(-1,-1)$ if there is no intersection; otherwise you get %%a pair $(t_a,t_b)$, where $t_a$ is a time on path {\tt a} when it intersects %%path~{\tt b}, and $t_b$ is the corresponding time on path~{\tt b}. Например, предположим, что путь~{\tt a} обозначен тонкой линией на рис.~\ref{fig24} и путь~{\tt b} обозначен более толстой линией. %%For example, suppose path~{\tt a} is denoted by the thin line in %%Figure~\ref{fig24} and path~{\tt b} is denoted by the thicker line. Если метки показывают значения времени на путях, то пара значений времени, вычисленная в $$ \hbox{\tt a intersectiontimes b} $$ должна быть одной из $$ (0.25,1.77),\ (0.75,1.40) {\rm или}\ (2.58,0.24) $$ и какая из трех будет выбрана зависит от интерпретатора MetaPost. %%If %%the labels indicate time values on the paths, the pair of time values %%computed by %%$$ \hbox{\tt a intersectiontimes b} $$ %%must be one of %%$$ (0.25,1.77),\ (0.75,1.40), {\rm or}\ (2.58,0.24), $$ %%depending on which of the three intersection points is chosen by the %%MetaPost interpreter. Точное правило выбора из многих точек пересечения несколько сложноватое, но в данном примере вы получите $(0.25,1.77)$. %%The exact rules for choosing among multiple %%intersection points are a little complicated, but it turns out that you %%get the time values $(0.25,1.77)$ in this example. Меньшие значения времени предпочтительнее больших, так что $(t_a,t_b)$ предпочтительнее, чем $(t'_a,t'_b)$ пока $t_a> 0 >> 0 >> 1 >> 0.3, \end{verbatim} $$ потому что в модели оттенков серого черный --- это {\tt 0}, а в модели cmyk-цветов черный --- это {\tt (0,0,0,1)}. %%since in grey scale color model black is {\tt 0} and in CMYK color model %%black is {\tt (0, 0, 0, 1)}. Для подошедшей модели rgb-цвета был возвращен верный цветовой компонент. %%For the matching RGB color model the true %%color component is returned. Когда {\tt clipped p} или {\tt bounded p} --- истинно, то {\tt pathpart p} дает путь вырезки или {\tt setbounds}, а другие операторы извлечения частей не имеют смысла. %%When {\tt clipped p} or {\tt bounded p} is true, {\tt pathpart p} gives the %%clipping or {\tt setbounds} path and the other part extraction operators are %%not meaningful. Такие не имеющие смысла получения частей не генерируют ошибок. %%Such non-meaningful part extractions do not generate %%errors. Они вместо этого возвращают (компоненты) нулевые значения или черный цвет: пустой путь {\tt (0,0)} для {\tt pathpart}, {\tt nullpen}\index{nullpen?\texttt{nullpen}}\label{Dnlpen} для {\tt penpart}, пустой рисунок для {\tt dashpart}, пустую строку для {\tt textpart} или {\tt fontpart}, 0 для {\tt colormodel}, {\tt greypart}, {\tt redpart}, {\tt greenpart}, {\tt bluepart}, {\tt cyanpart}, {\tt magentapart}, {\tt yellowpart}, один для {\tt blackpart} и черный в текущей типовой модели цвета для {\tt colorpart}. %%Instead, they return null values or black color (components): %%the trivial path {\tt (0,0)} for {\tt pathpart}, %%{\tt nullpen}\index{nullpen?\texttt{nullpen}}\label{Dnlpen} for {\tt penpart}, %%an empty picture for {\tt dashpart}, %%the null string for {\tt textpart} or {\tt fontpart}, %%zero for {\tt colormodel}, %%{\tt greypart}, %%{\tt redpart}, {\tt greenpart}, {\tt bluepart}, %%{\tt cyanpart}, {\tt magentapart}, {\tt yellowpart}, %%one for {\tt blackpart}, and %%black in the current default color model for {\tt colorpart}. Подведем итог дискуссии о несоответствующих операторах выделения частей. %%To summarize the discussion of mismatching part operators: \begin{enumerate} \item Вопрос о бессмысленных частях компоненты рисунка, таких как {\tt redpart} для пути вырезки, {\tt textpart} для изображения пером или {\tt pathpart} для текста, спокойно принимается и ответом на него будет либо нулевое значение, либо черный цвет (компонент). %%\item Asking for non-meaningful parts of an item---such as the {\tt %% redpart} of a clipping path, the {\tt textpart} of a stroked item, %% or the {\tt pathpart} of a textual item---is silently accepted and %% returns a null value or a black color (component). \item Применение оператора цветовой части в неправильной модели цвета к цветному компоненту возвращает черный компонент. Более того, это иниициирует ошибку. %%\item Applying a color part operator of the wrong color model to a %% coloured item returns a black color component. Additionally, this %% triggers an error. \end{enumerate} \index{setbounds?\texttt{setbounds}|)} \index{stroked?\texttt{stroked}|)} \index{filled?\texttt{filled}|)} \index{textual?\texttt{textual}|)} \index{clipped?\texttt{clipped}|)} \index{bounded?\texttt{bounded}|)} \index{pathpart?\texttt{pathpart}|)} \index{penpart?\texttt{penpart}|)} \index{dashpart?\texttt{dashpart}|)} \index{colormodel?\texttt{colormodel}|)} \index{colorpart?\texttt{colorpart}|)} \index{redpart?\texttt{redpart}|)} \index{greenpart?\texttt{greenpart}|)} \index{bluepart?\texttt{bluepart}|)} \index{cyanpart?\texttt{cyanpart}|)} \index{magentapart?\texttt{magentapart}|)} \index{yellowpart?\texttt{yellowpart}|)} \index{blackpart?\texttt{blackpart}|)} \index{greypart?\texttt{greypart}|)} \section{Макросы} %%\section{Macros} \label{macros} Уже упоминалось, что MetaPost имеет множество автоматически включаемых макросов, называемое макропакет Plain\index{макросы Plain}, и некоторые команды, рассмотренные в предшествующих разделах, определены как макросы и не являются встроенными в MetaPost. %%As alluded to earlier, MetaPost has a set of automatically included %%macros called the Plain macro package\index{Plain macros}, and some of %%the commands discussed in previous sections are defined as macros %%instead of being built into MetaPost. Цель этого раздела объяснить, как писать такие макросы. %%The purpose of this section is to %%explain how to write such macros. Макросы без аргументов очень просты. %%Macros with no arguments are very simple. Определение макроса\index{текст замены?\tdescr{текст замены}}% \index{def?\texttt{def}}\index{enddef?\texttt{enddef}} $$ {\tt def}\, \descr{символический знак}\, \hbox{\tt =}\, \descr{текст замены}\, {\tt enddef} $$ делает \tdescr{символический знак} сокращением для \tdescr{текста замены}, где \tdescr{текст замены} может быть, в сущности, любой последовательностью знаков. %%A macro definition\index{replacement text?\tdescr{replacement text}}% %%\index{def?\texttt{def}}\index{enddef?\texttt{enddef}} %%$$ {\tt def}\, \descr{symbolic token}\, \hbox{\tt =}\, %% \descr{replacement text}\, {\tt enddef} %%$$ %%makes the \tdescr{symbolic token} an abbreviation for the %%\tdescr{replacement text}, where the \tdescr{replacement text} can be %%virtually any sequence of tokens. Например, макропакет Plain мог бы определить команду {\tt fill} примерно так\index{fill?\texttt{fill}}: $$ \hbox{\tt def fill = addto currentpicture contour enddef} $$ %%For example, the Plain macro package %%could almost define the {\tt fill} statement like %%this\index{fill?\texttt{fill}}: %%$$ \hbox{\tt def fill = addto currentpicture contour enddef} $$ Макросы с аргументами похожи, за исключением того, что они имеют формальные параметры, которые говорят, как использовать аргументы в \tdescr{тексте замены}. %%Macros with arguments are similar, except they have formal parameters %%hat tell how to use the arguments in the \tdescr{replacement text}. Например, макрос {\tt rotatedaround}\index{rotatedaround?\texttt{rotatedaround}} определяется примерно так: $$\begin{verbatim} def rotatedaround(expr z, d) = shifted -z rotated d shifted z enddef; \end{verbatim} $$ %%For example, the {\tt %%rotatedaround}\index{rotatedaround?\texttt{rotatedaround}} macro is %%defined like this: %%$$\begin{verbatim} %%def rotatedaround(expr z, d) = %% shifted -z rotated d shifted z enddef; %%\end{verbatim} %%$$ Слово {\tt expr}\index{expr?\texttt{expr}} в этом определении значит, что формальные параметры {\tt z} и {\tt d} могут быть произвольными выражениями. %%The {\tt expr}\index{expr?\texttt{expr}} in this definition means that %%formal parameters {\tt z} and {\tt d} can be arbitrary expressions. Этим параметрам следует соответствовать выражениям-парам, но MetaPost не проверяет этого сразу. %%(They should be pair expressions but the MetaPost interpreter does not %%immediately check for that.) Из-за того, что MetaPost --- это интерпретируемый язык, макросы с аргументами очень похожи на подпрограммы\index{подпрограммы}. %%Since MetaPost is an interpreted language, macros with arguments are a %%lot like subroutines\index{subroutines}. Макросы MetaPost часто используются подобно подпрограммам, поэтому язык включает в себя программные концепции для такого использования. %%MetaPost macros are often used %%like subroutines, so the language includes programming concepts to %%support this. Эти концепции включают локальные переменные, циклы и условные команды. %%These concepts include local variables, loops, and %%conditional statements. \subsection{Группировка} %%\subsection{Grouping} \label{grsec} Группировка в MetaPost весьма важна для функций\index{функции} и локальных\index{переменные!локальные}\index{локальность} переменных. %%Grouping in MetaPost is essential for functions\index{functions} and %%local\index{variables!local}\index{locality} variables. Базовая идея в том, что группа --- это последовательность команд, возможно завершающаяся выражением, с обеспечением того, что некоторые символьные знаки\index{знаки!символические} могут восстановить свои старые значения в конце группы. %%The basic idea %%is that a group is a sequence of statements possibly followed by an %%expression with the provision that certain symbolic %%tokens\index{tokens!symbolic} can have their old meanings restored at %%the end of the group. Если группа заканчивается выражением, то группа ведет себя подобно вызову функции, что возвращает это выражение. %%If the group ends with an expression, the group %%behaves like a function call that returns that expression. В противном случае, группа --- это просто составная команда\index{блок}. %%Otherwise, %%the group is just a compound statement\index{compound statement}. Синтаксис для группы\index{begingroup?\texttt{begingroup}}\index{endgroup?\texttt{endgroup}} --- $$ {\tt begingroup}\, \descr{список команд}\, {\tt endgroup} $$ или $$ {\tt begingroup}\, \descr{список команд}\, \descr{выражение}\, {\tt endgroup}, $$ где \tdescr{список команд} --- это последовательность команд, за каждой из которых следует точка с запятой. %%The syntax for a group %%is\index{begingroup?\texttt{begingroup}}\index{endgroup?\texttt{endgroup}} %%$$ {\tt begingroup}\, \descr{statement list}\, {\tt endgroup} $$ %%or %%$$ {\tt begingroup}\, \descr{statement list}\, \descr{expression}\, {\tt %%endgroup} %%$$ %%where a \tdescr{statement list} is a sequence of statements each %%followed by a semicolon. Группа с \tdescr{выражением} после \tdescr{списка команд} ведет себя как \tdescr{первичность} из рис.~\ref{syexpr} или подобно \tdescr{числовому атому} из рис.~\ref{synprim}. %%A group with an \tdescr{expression} after the %%\tdescr{statement list} behaves like a \tdescr{primary} in %%Figure~\ref{syexpr} or like a \tdescr{numeric atom} in %%Figure~\ref{synprim}. Из-за того, что \tdescr{текст замены} для макроса {\tt beginfig}\index{beginfig?\texttt{beginfig}} начинается с {\tt begingroup}, а \tdescr{текст замены} для {\tt endfig}\index{endfig?\texttt{endfig}} заканчивается на {\tt endgroup}, каждая картинка входного файла MetaPost ведет себя как группа. %%Since the \tdescr{replacement text} for the {\tt %%beginfig}\index{beginfig?\texttt{beginfig}} macro starts with {\tt %%begingroup} and the \tdescr{replacement text} for {\tt %%endfig}\index{endfig?\texttt{endfig}} ends with {\tt endgroup}, each %%figure in a MetaPost input file behaves like a group. Это позволяет картинкам иметь локальные переменные. %%This is what allows figures can have local variables. Мы уже видели в разделе~\ref{vardecl}, что имена переменных, начинающиеся с {\tt x} или {\tt y} являются локальными в том смысле, что они считаются неизвестными в начале каждой картинки и их значения забываются в конце каждой картинки. %%We have already seen in %%Section~\ref{vardecl} that variable names beginning with {\tt x} or {\tt %%y} are local in the sense that they have unknown values at the beginning %%of each figure and these values are forgotten at the end of each figure. Следующий пример иллюстрирует как работает локальность. %%The following example illustrates how locality works: \begin{eqnarray*} && \hbox{\tt x23 = 3.1;}\\ && \hbox{\tt beginfig(17);}\\ && \qquad \vdots\\ && \hbox{\tt y3a=1; x23=2;}\\ && \qquad \vdots\\ && \hbox{\tt endfig;}\\ && \hbox{\tt show x23, y3a;} \end{eqnarray*} Результат команды {\tt show}\index{show?\texttt{show}} %%The result of the {\tt show}\index{show?\texttt{show}} command is $$\begin{verbatim} >> 3.1 >> y3a \end{verbatim} $$ показывает, что {\tt x23} возвращается к своему прежнему значению {\tt 3.1}, а {\tt y3a} совершенно неизвестно, как оно и было в {\tt beginfig(17)}. %%indicating that {\tt x23} has returned to its former value of {\tt 3.1} and %%{\tt y3a} is completely unknown as it was at {\tt beginfig(17)}. Локальность переменных {\tt x} и {\tt y} достигается командой\index{save?\texttt{save}}\label{Dsave} $$ \hbox{\tt save x,y} $$ в \tdescr{тексте замены} для {\tt beginfig}\index{beginfig?\texttt{beginfig}}. %%The locality of {\tt x} and {\tt y} variables is achieved by the %%statement\index{save?\texttt{save}}\label{Dsave} %%$$ \hbox{\tt save x,y} $$ %%in the \tdescr{replacement text} for {\tt %%beginfig}\index{beginfig?\texttt{beginfig}}. В общем, переменные делаются локальными командой $$ {\tt save}\, \descr{список символических знаков}, $$ где \tdescr{список символических знаков} --- это разделенный запятыми список знаков:\index{знаки!символические} \begin{ctabbing} $\tt \descr{список символических знаков} \rightarrow \descr{символический знак}$\\ $\tt \qquad \;|\; \descr{символический знак}\hbox{\tt ,} \descr{список символических знаков}$ \end{ctabbing} %%In general, variables are made local by the statement %%$$ {\tt save}\, \descr{symbolic token list} $$ %%where \tdescr{symbolic token list} is a comma-separated list of %%tokens:\index{tokens!symbolic} %%\begin{ctabbing} %%$\tt \descr{symbolic token list} \rightarrow \descr{symbolic token}$\\ %% $\tt \qquad \;|\; \descr{symbolic token}\hbox{\tt ,} %% \descr{symbolic token list}$ %%\end{ctabbing} Все переменные, чьи имена начинаются с одного из указанных символических знаков, становятся неизвестными числами, а их прежние значения сохраняются для восстановления в конце текущей группы. %%All variables whose names begin with one of the specified symbolic %%tokens become unknown numerics and their present values are saved for %%restoration at the end of the current group. Если команда {\tt save} используется вне группы, то значения по-просту невосстановимо уничтожаются. %%If the {\tt save} %%statement is used outside of a group, the original values are simply %%discarded. Главная цель команды {\tt save} позволить макросам использовать переменные без взаимодействия с существующими переменными или переменными в нескольких вызовах одного и того же макроса. %%The main purpose of the {\tt save} statement is to allow macros to use %%variables without interfering with existing variables or variables in %%other calls to the same macro. Например, предопределенный макрос {\tt whatever}\index{whatever?\texttt{whatever}} имеет такой \tdescr{текст замены} $$ \hbox{\tt begingroup save ?; ? endgroup} $$ %%For example, the predefined macro {\tt %%whatever}\index{whatever?\texttt{whatever}} has the \tdescr{replacement text} %%$$ \hbox{\tt begingroup save ?; ? endgroup} $$ Он возвращает неизвестное числовое количество, но оно не зовется больше знаком вопроса, потому что это имя было локальным в группе. %%This returns an unknown numeric quantity, but it is no longer called %%question mark since that name was local to the group. Спрашивая имя через {\tt show\index{show?\texttt{show}} whatever}, получаем\index{CAPSULE?\texttt{CAPSULE}} $$ \hbox{\tt >> \%CAPSULE}{\it nnnn}, $$ где {\it nnnn} --- это идентификационный номер, выбираемый, когда {\tt save} организует исчезновение имени знак вопроса. %%Asking the name via {\tt show\index{show?\texttt{show}} whatever} %%yields\index{CAPSULE?\texttt{CAPSULE}} %%$$ \hbox{\tt >> \%CAPSULE}{\it nnnn} $$ %%where {\it nnnn} is an identification number that is chosen when {\tt save} %%makes the name question mark disappear. Вопреки универсальности, {\tt save} не может использоваться для локального изменения любой внутренней переменной\index{внутренние переменные}\index{переменные!внутренние} MetaPost. %%In spite of the versatility of {\tt save}, it cannot be used to make %%local changes to any of MetaPost's internal variables\index{internal %%variables}\index{variables!internal}. Команда, такая как $$ \hbox{\tt save linecap}, $$ приведет MetaPost к временному забыванию специального значения этой переменной и сделает ее обычной неизвестной числовой величиной. %%A statement such as\index{linecap?\texttt{linecap}} %%$$ \hbox{\tt save linecap} $$ %%would cause MetaPost to temporarily forget the special meaning of this %%variable and just make it an unknown numeric. Если вы хотите нарисовать одну пунктирную линию с {\tt linecap:=butt} и затем вернуться назад к прежнему значению, то вы можете использовать команду {\tt interim}\index{interim?\texttt{interim}}\label{Dinterm} как в следующем примере: \begin{eqnarray*} && \hbox{\tt begingroup interim linecap:=butt;}\\ && {\tt draw}\, \descr{выражение-путь}\, \hbox{\tt dashed evenly; endgroup} \end{eqnarray*} %%If you want to draw one %%dashed line with {\tt linecap:=butt} and then go back to the previous %%value, you can use the {\tt %%interim}\index{interim?\texttt{interim}}\label{Dinterm} statement as %%follows: %%\begin{eqnarray*} %%&& \hbox{\tt begingroup interim linecap:=butt;}\\ %%&& {\tt draw}\, \descr{path expression}\, \hbox{\tt dashed evenly; endgroup} %%\end{eqnarray*} Это сохранит значение внутренней переменной\index{внутренние переменные}\index{переменные!внутренние} {\tt linecap}, временно даст ей новое значение и это не приведет к забыванию того, что {\tt linecap} --- внутренняя переменная. %%This saves the value of the %%internal variable\index{internal variables}\index{variables!internal} %%{\tt linecap} and temporarily %%gives it a new value without forgetting that {\tt linecap} is an internal %%variable. Общий синтаксис: $$ {\tt interim}\, \descr{внутренняя переменная} \mathrel{\hbox{\tt:=}} \descr{числовое выражение} $$ %%The general syntax is %%$$ {\tt interim}\, \descr{internal variable} \mathrel{\hbox{\tt:=}} %% \descr{numeric expression} %%$$ \subsection{Параметризованные макросы} %%\subsection{Parameterized Macros} Базовая идея макросов с параметрами в достижении большей гибкости передачей добавочной информации в макрос. %%The basic idea behind parameterized macros is to achieve greater flexibility by %%allowing auxiliary information to be passed to a macro. Мы уже видели, что определения макросов могут иметь формальные параметры для выражений, задаваемых при вызове макроса. %%We have already seen %%that macro definitions can have formal parameters that represent expressions %%to be given when the macro is called. Например, определение $$ \hbox{\tt def rotatedaround(expr z, d) = } \descr{текст замены}\, {\tt enddef} $$ позволяет MetaPost-интерпретатору понимать вызовы макроса в форме $$\tt rotatedaround\hbox{\tt (} \descr{выражение}\hbox{\tt ,} \descr{выражение}\hbox{\tt )} $$ %%For instance a definition such as %%$$ \hbox{\tt def rotatedaround(expr z, d) = } \descr{replacement text}\, %% {\tt enddef} %%$$ %%allows the MetaPost interpreter to understand macro calls of the form %%$$\tt rotatedaround\hbox{\tt (} %% \descr{expression}\hbox{\tt ,} \descr{expression}\hbox{\tt )} %%$$ Ключевое слово {\tt expr}\index{expr?\texttt{expr}}\index{параметр!expr} в определении макроса значит, что параметры могут быть выражениями любого типа. %%The keyword {\tt expr}\index{expr?\texttt{expr}}\index{parameter!expr} %%in the macro definition means that the parameters can be expressions of %%any type. Когда определение указывает {\tt (expr z, d)}, то формальные параметры {\tt z} и {\tt d} ведут себя подобно переменным подходящего типа. %%When the definition specifies {\tt (expr z, d)}, the formal %%parameters {\tt z} and {\tt d} behave like variables of the appropriate %%types. Внутри \tdescr{текста замены} они могут быть использованы в выражениях, как обычные переменные, но они не могут повторно декларироваться или получать новые значения. %%Within the \tdescr{replacement text}, they can be used in %%expressions just like variables, but they cannot be redeclared or %%assigned to. Нет ограничений на неизвестные или частично известные аргументы. %%There is no restriction against unknown or partially known %%arguments. Поэтому определение\index{midpoint?\texttt{midpoint}} $$ \hbox{\tt def midpoint(expr a, b) = (.5[a,b]) enddef} $$ прекрасно работает для неизвестных {\tt a} и {\tt b}. %%Thus the definition\index{midpoint?\texttt{midpoint}} %%$$ \hbox{\tt def midpoint(expr a, b) = (.5[a,b]) enddef} $$ %%works perfectly well when {\tt a} and {\tt b} are unknown. Уравнение, такое как $$ \hbox{\tt midpoint(z1,z2) = (1,1)}, $$ может быть использовано для определения {\tt z1} и {\tt z2}. %%An equation such as %%$$ \hbox{\tt midpoint(z1,z2) = (1,1)} $$ %%could be used to help determine {\tt z1} and {\tt z2}. Заметьте, что определение выше для {\tt midpoint} работает для чисел, пар или цветов --- нужно только совпадение типов обоих параметров. %%Notice that the above definition for {\tt midpoint} works for numerics, %%pairs, or colors as long as both parameters have the same type. Если зачем-то нужен макрос {\tt middlepoint}\index{middlepoint?\texttt{middlepoint}}, работающий только для пути или рисунка, то будет необходимо выполнять проверку {\tt if}\index{if?\texttt{if}} типа аргумента. %%If for some reason we want a {\tt %%middlepoint}\index{middlepoint?\texttt{middlepoint}} macro that works %%for a single path or picture, it would be necessary to do an {\tt %%if}\index{if?\texttt{if}} test on the argument type. Есть унарный оператор\index{path?\texttt{path}} $$ {\tt path}\, \descr{первичность}, $$ возвращающий логический результат, показывающий является ли его аргумент путем. %%This uses the fact %%there is a unary operator\index{path?\texttt{path}} %%$$ {\tt path}\, \descr{primary} $$ %%that returns a boolean result indicating whether its argument is a path. Из-за того, что проверка {\tt if} имеет базовый синтаксис\index{else?\texttt{else}}\index{fi?\texttt{fi}} $$ {\tt if}\, \descr{логическое выражение}\hbox{\tt:}\, \descr{сбалансированные знаки}\, \hbox{\tt else:}\, \descr{сбалансированные знаки}\, {\tt fi}, $$ где \tdescr{сбалансированные знаки}\index{сбалансированные знаки?\tdescr{сбалансированные знаки}} могут быть чем-угодно, сбалансированным относительно {\tt if} и {\tt fi}, полный макрос {\tt middlepoint}\index{middlepoint?\texttt{middlepoint}} с проверкой типа может выглядеть так: $$\begin{verbatim} def middlepoint(expr a) = if path a: (point .5*length a of a) else: .5(llcorner a + urcorner a) fi enddef; \end{verbatim} $$ %%Since the basic {\tt if} test has the %%syntax\index{else?\texttt{else}}\index{fi?\texttt{fi}} %%$$ {\tt if}\, \descr{boolean expression}\hbox{\tt:}\, \descr{balanced tokens}\, %% \hbox{\tt else:}\, \descr{balanced tokens}\, {\tt fi} %%$$ %%where the \tdescr{balanced tokens}\index{balanced %%tokens?\tdescr{balanced tokens}} can be anything that is balanced with %%respect to {\tt if} and {\tt fi}, the complete {\tt %%middlepoint}\index{middlepoint?\texttt{middlepoint}} macro with type test %%looks like this: %%$$\begin{verbatim} %%def middlepoint(expr a) = if path a: (point .5*length a of a) %% else: .5(llcorner a + urcorner a) fi enddef; %%\end{verbatim} %%$$ Полный синтаксис проверки {\tt if} показан на рис.~\ref{syif}. %%The complete syntax for {\tt if} tests is shown in Figure~\ref{syif}. Позволяются многократные проверки {\tt if}, например, $$ \hbox{\tt if $e_1$: \ldots\ else: if $e_2$: \ldots\ else: \ldots\ fi fi},$$ которые можно сократить до\index{elseif?\texttt{elseif}} $$ \hbox{\tt if $e_1$: \ldots\ elseif $e_2$: \ldots\ else: \ldots\ fi}, $$ где $e_1$ и $e_2$ представляют логические выражения. %%It allows multiple {\tt if} tests like %%$$ \hbox{\tt if $e_1$: \ldots\ else: if $e_2$: \ldots\ else: \ldots\ fi fi} $$ %%to be shortened to\index{elseif?\texttt{elseif}} %%$$ \hbox{\tt if $e_1$: \ldots\ elseif $e_2$: \ldots\ else: \ldots\ fi} $$ %%where $e_1$ and $e_2$ represent boolean expressions. Обратите внимание, что проверки {\tt if} не являются командами и \tdescr{сбалансированные знаки} в синтаксических правилах могут не быть полными выражениями или командами. %%Note that {\tt if} tests are not statements and the \tdescr{balanced %%tokens} in the syntax rules can be any sequence of balanced tokens even %%if they do not form a complete expression or statement. Поэтому можно, пожертвовав наглядностью, убрать два знака в определении {\tt middlepoint}: $$\begin{verbatim} def middlepoint(expr a) = if path a: (point .5*length a of else: .5(llcorner a + urcorner fi a) enddef; \end{verbatim} $$ %%Thus we could %%have saved two tokens at the expense of clarity by defining {\tt %%middlepoint} like this: %%$$\begin{verbatim} %%def middlepoint(expr a) = if path a: (point .5*length a of %% else: .5(llcorner a + urcorner fi a) enddef; %%\end{verbatim} %%$$ \begin{figure}[htp] \begin{ctabbing} $\tt \descr{проверка if} \rightarrow if \descr{логическое выражение} \hbox{\tt :} \descr{сбалансированные знаки} \descr{альтернативы} fi$\\ %%$\tt \descr{if test} \rightarrow if \descr{boolean expression} \hbox{\tt :} %% \descr{balanced tokens} \descr{alternatives} fi$\\ $\tt \descr{альтернативы} \rightarrow \descr{пусто}$\\ %%$\tt \descr{alternatives} \rightarrow \descr{empty}$\\ $\tt \qquad \;|\; else\hbox{\tt :} \descr{сбалансированные знаки}$\\ %%$\tt \qquad \;|\; else\hbox{\tt :} \descr{balanced tokens}$\\ $\tt \qquad \;|\; elseif \descr{логическое выражение} \hbox{\tt :} \descr{сбалансированные знаки} \descr{альтернативы}$ %%$\tt \qquad \;|\; elseif \descr{boolean expression} \hbox{\tt :} %% \descr{balanced tokens} \descr{alternatives}$ \end{ctabbing} \caption{Синтаксис проверки {\tt if}.} %%\caption{The syntax for {\tt if} tests.} \label{syif} \end{figure} Настоящее назначение макросов и проверок {\tt if} в автоматизации решения повторяющихся задач, а также в возможности решать подзадачи по-отдельности. %%The real purpose of macros and {\tt if} tests is to automate repetitive %%tasks and allow important subtasks to be solved separately. Например, рис.~\ref{fig42} использует макросы \verb|draw_marked|, \verb|mark_angle| и \verb|mark_rt_angle| для отметки линий и углов, появляющихся на рисунке. %%For example, Figure~\ref{fig42} uses macros \verb|draw_marked|, %%\verb|mark_angle|, and \verb|mark_rt_angle| to mark lines and angles %%that appear in the figure. \begin{figure}[htp] $$\begin{verbatim} beginfig(42); pair a,b,c,d; b=(0,0); c=(1.5in,0); a=(0,.6in); d-c = (a-b) rotated 25; dotlabel.lft("a",a); dotlabel.lft("b",b); dotlabel.bot("c",c); dotlabel.llft("d",d); z0=.5[a,d]; z1=.5[b,c]; (z.p-z0) dotprod (d-a) = 0; (z.p-z1) dotprod (c-b) = 0; draw a--d; draw b--c; draw z0--z.p--z1; draw_marked(a--b, 1); draw_marked(c--d, 1); draw_marked(a--z.p, 2); draw_marked(d--z.p, 2); draw_marked(b--z.p, 3); draw_marked(c--z.p, 3); mark_angle(z.p, b, a, 1); mark_angle(z.p, c, d, 1); mark_angle(z.p, c, b, 2); mark_angle(c, b, z.p, 2); mark_rt_angle(z.p, z0, a); mark_rt_angle(z.p, z1, b); endfig; \end{verbatim} \quad \mathcenter{\includegraphics{manfig-ru-42}} $$ \caption{Код MetaPost и соответствующий рисунок} %%\caption{MetaPost code and the corresponding figure} \label{fig42} \end{figure} Задача макроса \verb|draw_marked|\index{draw_marked?\texttt{draw\_marked}} --- нарисовать путь с заданным числом пересекающих отметок посередине. %%The task of the %%\verb|draw_marked|\index{draw_marked?\texttt{draw\_marked}} macro is to %%draw a path with a given number of cross marks near its midpoint. Стоит начать с подзадачи рисования одной пересекающей путь {\tt p} перпендикулярно отметки в некоторое время {\tt t}. %%A convenient starting place is the subproblem of drawing a single cross %%mark perpendicular to a path {\tt p} at some time {\tt t}. Макрос \verb|draw_mark|\index{draw_mark?\texttt{draw\_mark}} на рис.~\ref{drawmarked} решает эту подзадачу нахождением сначала вектора {\tt dm}, перпендикулярного {\tt p} в~{\tt t}. %%The \verb|draw_mark|\index{draw_mark?\texttt{draw\_mark}} macro in %%Figure~\ref{drawmarked} does this by first finding a vector {\tt dm} %%perpendicular to~{\tt p} at~{\tt t}. Для упрощения позиционирования пересекающей отметки определение макроса \verb|draw_marked| берет длину дуги\index{длина дуги} {\tt a} вдоль {\tt p} и оператором {\tt arctime}\index{arctime of?\texttt{arctime of}} вычисляет~{\tt t} %%To simplify positioning the cross %%mark, the \verb|draw_marked| macro is defined to take an arc %%length\index{arc length} {\tt a} along {\tt p} and use the {\tt %%arctime}\index{arctime} operator to compute~{\tt t} С решением подзадачи рисования одной отметки, макросу \verb|draw_marked| останется только нарисовать путь и вызвать \verb|draw_mark| с соответствующей длиной дуги. %%With the subproblem of drawing a single mark out of the way, the %%\verb|draw_marked| macro only needs to draw the path and call %%\verb|draw_mark| with the appropriate arc length values. Макрос \verb|draw_marked| на рис.~\ref{drawmarked} использует арифметическую прогрессию из {\tt n} значений {\tt a}, центр которых помещается в {\tt .5*arclength~p}\index{arclength?\texttt{arclength}}. %%The \verb|draw_marked| macro in Figure~\ref{drawmarked} uses {\tt n} %%equally-spaced {\tt a} values centered on {\tt %%.5*arclength~p}\index{arclength?\texttt{arclength}}. \begin{figure}[htp] $$\begin{verbatim} marksize=4pt; def draw_mark(expr p, a) = begingroup save t, dm; pair dm; t = arctime a of p; dm = marksize*unitvector direction t of p rotated 90; draw (-.5dm.. .5dm) shifted point t of p; endgroup enddef; def draw_marked(expr p, n) = begingroup save amid; amid = .5*arclength p; for i=-(n-1)/2 upto (n-1)/2: draw_mark(p, amid+.6marksize*i); endfor draw p; endgroup enddef; \end{verbatim} $$ \caption{Макросы для рисования пути {\tt p} с {\tt n} пересекающими отметками.} %%\caption{Macros for drawing a path {\tt p} with {\tt n} cross marks.} \label{drawmarked} \end{figure} Из-за того, что \verb|draw_marked| работает для кривых, он может быть использован для рисования дуг, генерируемых макросом \verb|mark_angle|\index{mark_angle?\texttt{mark\_angle}}. %%Since \verb|draw_marked| works for curved lines, it can be used to draw %%the arcs that the %%\verb|mark_angle|\index{mark_angle?\texttt{mark\_angle}} macro %%generates. С заданными точками {\tt a}, {\tt b} и {\tt c}, определяющими направленный против часовой стрелки угол в {\tt b}, \verb|mark_angle| должен сгенерировать маленькую дугу от отрезка {\tt ba} до отрезка {\tt bc}. %%Given points {\tt a}, {\tt b}, and {\tt c} that define a %%counter-clockwise angle at {\tt b}, the \verb|mark_angle| needs to %%generate a small arc from segment {\tt ba} to segment {\tt bc}. Определение макроса на рис.~\ref{markangle} делает это созданием дуги {\tt p} с единичным радиусом и затем вычислением масштабирующего множителя {\tt s}, который делает ее достаточно большой на вид. %%The %%macro definition in Figure~\ref{markangle} does this by creating an arc %%{\tt p} of radius one and then computing a scale factor {\tt s} that %%makes it big enough to see clearly. Макрос \verb|mark_rt_angle|\index{mark_rt_angle?\texttt{mark\_rt\_angle}} намного проще. %%The \verb|mark_rt_angle|\index{mark_rt_angle?\texttt{mark\_rt\_angle}} %%macro is much simpler. Он берет общий прямой угол и использует оператор {\tt zscaled}\index{zscaled?\texttt{zscaled}} для необходимых вращения и масштабирования. %%It takes a generic right-angle corner and uses %%the {\tt zscaled}\index{zscaled?\texttt{zscaled}} operator to rotate it %%and scale it as necessary. \begin{figure}[htp] $$\begin{verbatim} angle_radius=8pt; def mark_angle(expr a, b, c, n) = begingroup save s, p; path p; p = unitvector(a-b){(a-b)rotated 90}..unitvector(c-b); s = .9marksize/length(point 1 of p - point 0 of p); if s> 2|.'' %%Thus %%$$ \hbox{\tt show hide(numeric a,b; a+b=3; a-b=1) a;} $$ %%prints ``\verb|>> 2|.'' Если бы {\tt hide} не был предопределен, то его можно было определить примерно так: %%If the {\tt hide} macro were not predefined, it could be defined like this: $$\begin{verbatim} def ignore(expr a) = enddef; def hide(text t) = ignore(begingroup t; 0 endgroup) enddef; \end{verbatim} $$ Команды, представленные параметром-текстом {\tt t}, будут считаться как часть группы, формирующей аргумент для {\tt ignore}. %%The statements represented by the text parameter {\tt t} would be %%evaluated as part of the group that forms the argument to {\tt ignore}. Из-за того, что {\tt ignore} имеет пустой \tdescr{текст замены}, раскрытие {\tt hide} не произведет совершенно ничего. %%Since {\tt ignore} has an empty \tdescr{replacement text}, expansion of %%the {\tt hide} macro ultimately produces nothing. Другой пример предопределенного макроса с текстовым параметром --- это {\tt dashpattern}\index{dashpattern?\texttt{dashpattern}}. %%Another example of a predefined macro with a text parameter is {\tt %%dashpattern}\index{dashpattern?\texttt{dashpattern}}. Определение {\tt dashpattern} начинает $$\begin{verbatim} def dashpattern(text t) = begingroup save on, off; \end{verbatim} $$ и затем оно определяет {\tt on} и {\tt off} макросами, создающими требуемую картинку при появлении текстового параметра {\tt t} в тексте замены. %%The definition of {\tt dashpattern} starts %%$$\begin{verbatim} %%def dashpattern(text t) = %% begingroup save on, off; %%\end{verbatim} %%$$ %%then it defines {\tt on} and {\tt off} to be macros that create the desired %%picture when the text parameter~{\tt t} appears in the replacement text. Текстовые параметры очень общие, но их общность иногда допустима. %%Text parameters are very general, but their generality sometimes gets in %%the way. Если же вы хотите в точности передавать имя переменной в макрос, то лучше объявить ее как параметр-суффикс\index{параметр!suffix}. %%If you just want to pass a variable name to a macro, it is %%better to declare it as a suffix parameter\index{parameter!suffix}. Например, \index{incr?\texttt{incr}} $$ \hbox{\verb|def incr(suffix $) = begingroup $:=$+1; $ endgroup enddef;|} $$ определяет макрос, что будет получать любую числовую переменную, добавлять один к ней и возвращать новое значение. %%For example,\index{incr?\texttt{incr}} %%$$ \hbox{\verb|def incr(suffix $) = begingroup $:=$+1; $ endgroup enddef;|} $$ %%defines a macro that will take any numeric variable, add one to it, and return %%the new value. Из-за того, что имена переменных могут состоять из более одного знака, $$ \hbox{\tt incr(a3b)} $$ вполне допустимо, если {\tt a3b} --- числовая переменная. %%Since variable names can be more than one token long, %%$$ \hbox{\tt incr(a3b)} $$ %%is perfectly acceptable if {\tt a3b} is a numeric variable. Параметры-суффиксы являются несколько более общими, чем имена переменных, потому что определения на рис.~\ref{syvar} допускает \tdescr{суффикс}\index{суффикс?\tdescr{суффикс}}, начинающийся с \tdescr{индекса}\index{индекс?\tdescr{индекс}}. %%Suffix parameters are slightly more general than variable names because the %%definition in Figure~\ref{syvar} allows a %%\tdescr{suffix}\index{suffix?\tdescr{suffix}} to start with a %%\tdescr{subscript}\index{subscript?\tdescr{subscript}}. Рис.~\ref{fig45} показывает как параметры suffix и expr могут быть использованы вместе. %%Figure~\ref{fig45} shows how suffix and expr parameters can be used %%together. Макрос {\tt getmid}\index{getmid?\texttt{getmid}} берет переменную-путь и создает массивы точек и направления, чьи имена получаются присоединением {\tt mid}, {\tt off} и {\tt dir} к переменной-пути. %%The {\tt getmid}\index{getmid?\texttt{getmid}} macro takes a %%path variable and creates arrays of points and directions whose names %%are obtained by appending {\tt mid}, {\tt off}, and {\tt dir} to the %%path variable. Макрос {\tt joinup}\index{joinup?\texttt{joinup}} берет массив точек и направлений и создает путь длины {\tt n}, проходящий через каждую {\tt pt[i]} с направлением {\tt d[i]} или $-\hbox{\tt d[i]}$. %%The {\tt joinup}\index{joinup?\texttt{joinup}} macro %%takes arrays of points and directions and creates a path of length {\tt %%n} that passes through each {\tt pt[i]} with direction {\tt d[i]} or %%$-\hbox{\tt d[i]}$. \begin{figure}[htp] $$\begin{verbatim} def getmid(suffix p) = pair p.mid[], p.off[], p.dir[]; for i=0 upto 36: p.dir[i] = dir(5*i); p.mid[i]+p.off[i] = directionpoint p.dir[i] of p; p.mid[i]-p.off[i] = directionpoint -p.dir[i] of p; endfor enddef; def joinup(suffix pt, d)(expr n) = begingroup save res, g; path res; res = pt[0]{d[0]}; for i=1 upto n: g:= if (pt[i]-pt[i-1]) dotprod d[i] <0: - fi 1; res := res{g*d[i-1]}...{g*d[i]}pt[i]; endfor res endgroup enddef; beginfig(45) path p, q; p = ((5,2)...(3,4)...(1,3)...(-2,-3)...(0,-5)...(3,-4) ...(5,-3)...cycle) scaled .3cm shifted (0,5cm); getmid(p); draw p; draw joinup(p.mid, p.dir, 36)..cycle; q = joinup(p.off, p.dir, 36); draw q..(q rotated 180)..cycle; drawoptions(dashed evenly); for i=0 upto 3: draw p.mid[9i]-p.off[9i]..p.mid[9i]+p.off[9i]; draw -p.off[9i]..p.off[9i]; endfor endfig; \end{verbatim} \quad \mathcenter{\includegraphics{manfig-ru-45}} $$ \caption{Код MetaPost и соответствующий рисунок} %%\caption{MetaPost code and the corresponding figure} \label{fig45} \end{figure} Начинающееся с $$ \hbox{\tt def joinup(suffix pt, d)(expr n) =} $$ определение может восприниматься так, что вызов макроса {\tt joinup} может иметь два набора скобок как в $$ \hbox{\tt joinup(p.mid, p.dir)(36)} $$ вместо $$ \hbox{\tt joinup(p.mid, p.dir, 36)} $$ %%A definition that starts %%$$ \hbox{\tt def joinup(suffix pt, d)(expr n) =} $$ %%might suggest that calls to the {\tt joinup} macro should have two sets of %%parentheses as in %%$$ \hbox{\tt joinup(p.mid, p.dir)(36)} $$ %%instead of %%$$ \hbox{\tt joinup(p.mid, p.dir, 36)} $$ Обе формы являются допустимыми. %%In fact, both forms are acceptable. Параметры в вызове макроса могут разделяться запятыми или парами {\tt )(}. %%Parameters in a macro call can be %%separated by commas or by {\tt )(} pairs. Есть только одно ограничение --- за текстовым параметром\index{параметр!text} должна идти правая скобка. %%The only restriction is that %%a text parameter\index{parameter!text} must be followed by a right %%parenthesis. Например, макрос {\tt foo} с одним параметром text и другим expr может быть вызван $$ \hbox{\tt foo(a,b)(c),} $$ в этом случае текстовый параметр --- это ``{\tt a,b}'', а параметр-выражение --- {\tt c}, но $$ \hbox{\tt foo(a,b,c)} $$ устанавливает параметр-текст в ``{\tt a,b,c}'' и оставляет интерпретатор MetaPost продолжать искать параметр-выражение. %%For instance, a macro {\tt foo} with one text parameter %%and one expr parameter can be called %%$$ \hbox{\tt foo(a,b)(c)} $$ %%in which case the text parameter is ``{\tt a,b}'' and the expr parameter is %{\tt c}, but %%$$ \hbox{\tt foo(a,b,c)} $$ %%sets the text parameter to ``{\tt a,b,c}'' and leaves the MetaPost interpreter %%still looking for the expr parameter. \subsection{Макросы vardef} %%\subsection{Vardef Macros} Определение макроса может начинаться с {\tt vardef}\index{vardef?\texttt{vardef}} вместо {\tt def}. %%A macro definition can begin with {\tt %%vardef}\index{vardef?\texttt{vardef}} instead of {\tt def}. Макрос, определенный таким образом, называется vardef-макросом. %%Macros defined in this way are called vardef macros. Они особенно хорошо подходят к приложениям, где макросы используются как функции или процедуры. %%They are particularly %%well-suited to applications where macros are being used like functions %%or subroutines. Главная идея в том, что vardef-макрос подобен переменной типа ``макрос''. %%The main idea is that a vardef macro is like a variable %%of type ``macro.'' Вместо {\tt def} \tdescr{символический знак} vardef-макрос начинает $$ {\tt vardef}\, \descr{обобщенная переменная}, $$ где \tdescr{обобщенная переменная}\index{обобщенная переменная?\tdescr{обобщенная переменная}} -- это имя переменной с числовыми индексами, замененными на символ обобщенного индекса\index{индекс!обобщенный} --- {\tt []}\index{[]?\texttt{[]}!vardef macro?\texttt{vardef}-макрос}. %%Instead of {\tt def} \tdescr{symbolic token}, a vardef macro begins %%$$ {\tt vardef}\, \descr{generic variable} $$ %%where a \tdescr{generic variable}\index{generic variable?\tdescr{generic %%variable}} is a variable name with numeric subscripts replaced by the %%generic subscript\index{subscript!generic} symbol {\tt %%[]}\index{[]?\texttt{[]}!vardef macro?\texttt{vardef} macro}. Другими словами, имя после {\tt vardef} обязано иметь в точности такой же синтаксис как и имя в декларации переменной. %%In other words, the name following {\tt %%vardef} obeys exactly the same syntax as the name given in a variable %%declaration. Оно --- последовательность этикеток и символов обобщенного индекса, начинающаяся с этикетки, где этикетка\index{этикетки} --- это символический знак, не являющийся макросом или примитивным оператором, как объяснялось в разделе~\ref{vardecl}. %%It is a sequence of tags and generic subscript symbols %%starting with a tag, where a tag\index{tags} is a symbolic token that is %%not a macro or a primitive operator as explained in %%Section~\ref{vardecl}. В простейшем случае имя vardef-макроса состоит из одной этикетки. %%The simplest case is when the name of a vardef macro consists of a %%single tag. В таких обстоятельствах {\tt def} и {\tt vardef} обеспечивают почти одинаковую функциональность. %%Under such circumstances, {\tt def} and {\tt vardef} %%provide roughly the same functionality. Наиболее очевидная разница в том, что {\tt begingroup}\index{begingroup?\texttt{begingroup}} и {\tt endgroup}\index{endgroup?\texttt{endgroup}} автоматически вставляются соответственно в начало и конец \tdescr{текста замены} каждого vardef-макроса. %%The most obvious difference is %%that {\tt begingroup}\index{begingroup?\texttt{begingroup}} and {\tt %%endgroup}\index{endgroup?\texttt{endgroup}} are automatically inserted %%at the beginning and end of the \tdescr{replacement text} of every %%vardef macro. Это делает \tdescr{текст замены} группой и поэтому vardef-макрос ведет себя подобно процедуре или функции. %%This makes the \tdescr{replacement text} a group so that %%a vardef macro behaves like a subroutine or a function call. Другое свойство vardef-макросов заключается в разрешении имен из многих этикеток и имен, содержащих обобщенные индексы. %%Another property of vardef macros is that they allow multi-token macro %%names and macro names involving generic subscripts. Когда имя vardef-макроса имеет обобщенные индексы, то числовые значения для них должны быть заданы при вызове этого макроса. %%When a vardef macro %%name has generic subscripts, numeric values have to be given when the %%macro is called. После определения макроса $$ \hbox{\tt vardef a[]b(expr p) =}\, \descr{текст замены}\, \hbox{\tt enddef;} $$ {\tt a2b((1,2))} и {\tt a3b((1,2)..(3,4))} --- это вызовы макроса. %%After a macro definition %%$$ \hbox{\tt vardef a[]b(expr p) =}\, \descr{replacement text}\, %% \hbox{\tt enddef;} %%$$ %%{\tt a2b((1,2))} and {\tt a3b((1,2)..(3,4))} are macro calls. Но как может \tdescr{текст замены} сказать о разнице между {\tt a2b} и {\tt a3b}? %%But how %%can the \tdescr{replacement text} tell the difference between {\tt a2b} %%and {\tt a3b}? Два неявных параметра-суффикса\index{параметр!suffix} автоматически предоставляются для этой цели. %%Two implicit suffix parameters\index{parameter!suffix} %%are automatically provided for this purpose. Каждый vardef-макрос имеет параметры-суффиксы \verb|#@|\index{#@?\texttt{\#@}} и \verb|@|\index{@?\texttt{@}}, где \verb|@| --- это последний знак в имени вызова макроса, а \verb|#@| --- это все предшествующее последнему знаку. %%Every vardef macro has %%suffix parameters \verb|#@|\index{#@?\texttt{\#@}} and %%\verb|@|\index{@?\texttt{@}}, where \verb|@| is the last token in the %%name from the macro call and \verb|#@| is everything preceding the last %%token. Поэтому \verb|#@| равно {\tt a2}, когда данное имя --- {\tt a2b}, и {\tt a3}, когда данное имя --- {\tt a3b}. %%Thus \verb|#@| is {\tt a2} when the name is given as {\tt a2b} %%and {\tt a3} when the name is given as {\tt a3b}. Предположим, например, что макрос {\tt a[]b} сдвигает свой аргумент на величину, зависящую от имени вызова этого макроса. %%Suppose, for example, that the {\tt a[]b} macro is to take its argument %%and shift it by an amount that depends on the macro name. Такой макрос можно определить примерно так: $$ \hbox{\verb|vardef a[]b(expr p) = p shifted (#@,b) enddef;|} $$ %%The macro could be defined like this: %%$$ \hbox{\verb|vardef a[]b(expr p) = p shifted (#@,b) enddef;|} $$ Тогда {\tt a2b((1,2))} означает {\tt (1,2) shifted (a2,b)} и {\tt a3b((1,2)..(3,4))} означает $$ \hbox{\tt ((1,2)..(3,4)) shifted (a3,b)}. $$ %%Then {\tt a2b((1,2))} means {\tt (1,2) shifted (a2,b)} %%and {\tt a3b((1,2)..(3,4))} means %%$$ \hbox{\tt ((1,2)..(3,4)) shifted (a3,b)}. $$ Если макрос был {\tt a.b[]}, то \verb|#@| всегда будет {\tt a.b}, а параметр \verb|@| будет давать числовой индекс. %%If the macro had been {\tt a.b[]}, \verb|#@| would always be {\tt a.b} %%and the \verb|@| parameter would give the numeric subscript. Таким образом, {\tt a@} будет ссылаться на элемент массива {\tt a[]}. %%Then {\tt a@} would refer to an element of the array {\tt a[]}. Заметьте, что \verb|@| --- это параметр-суффикс, а не параметр-выражение, поэтому выражение, подобное {\tt @+1}, ошибочно. %%Note that %%\verb|@| is a suffix parameter, not an expr parameter, so an expression %%like {\tt @+1} would be illegal. Единственный способ получить числовые значения индексов параметра-суффикса\index{параметр!suffix} в извлечении их из строки, возвращаемой оператором {\tt str}\index{str?\texttt{str}}\label{Dstr}. %%The only way to get at the numeric %%values of subscripts in a suffix parameter\index{parameter!suffix} is by %%extracting them from the string returned by the {\tt %%str}\index{str?\texttt{str}}\label{Dstr} operator. Этот оператор по суффиксу возвращает его строковое представление. %%This operator takes %%a suffix and returns a string representation of a suffix. Поэтому {\tt str @} будет \verb|"3"| для {\tt a.b3} и \verb|"3.14"| для {\tt a.b3.14} или {\tt a.b[3.14]}. %%Thus {\tt str %%@} would be \verb|"3"| in {\tt a.b3} and \verb|"3.14"| in {\tt a.b3.14} %%or {\tt a.b[3.14]}. Из-за того, что синтаксис для \tdescr{суффикса}\index{суффикс?\tdescr{суффикс}} на рис.~\ref{syvar} требует заключать отрицательные индексы в квадратные скобки, {\tt str @} возвращает {\tt \qq{[-3]}\qq} для {\tt a.b[-3]}. %%Since the syntax for a %%\tdescr{suffix}\index{suffix?\tdescr{suffix}} in Figure~\ref{syvar} %%requires negative subscripts to be in brackets, {\tt str @} returns {\tt %%\qq{[-3]}\qq} in {\tt a.b[-3]}. Оператор {\tt str}, как правило, используется только при крайней необходимости. %%The {\tt str} operator is generally for emergency use only. Лучше использовать параметры-суффиксы только как имена переменных или суффиксы. %%It is %%better to use suffix parameters only as variable names or suffixes. Наилучший пример vardef-макроса, использующего суффиксы, --- это макрос, определяющий соглашение по {\tt z}\index{z convention?{\tt z}-соглашение}. %%The %%best example of a vardef macro involving suffixes is the {\tt z} macro %%that defines the {\tt z} convention\index{z convention?{\tt z} %%convention}. Определение использует специальный знак \verb|@#|\index{@#?\texttt{@\#}}, который ссылается на суффикс после имени макроса: $$ \hbox{\verb|vardef z@#=(x@#,y@#) enddef;|} $$ %%The definition involves a special token %%\verb|@#|\index{@#?\texttt{@\#}} that refers to the suffix following the %%macro name: %%$$ \hbox{\verb|vardef z@#=(x@#,y@#) enddef;|} $$ Оно означает, что любое имя переменной, чей первый знак {\tt z}, эквивалентно паре переменных, чьи имена получаются заменой {\tt z} на {\tt x} и~{\tt y}. %%This means that any variable name whose first token is {\tt z} is %%equivalent to a pair of variables whose names are obtained by replacing %%{\tt z} with {\tt x} and~{\tt y}. Например, {\tt z.a1} вызывает макрос {\tt z} с параметром-суффиксом \verb|@#|, установленным в {\tt a1}. %%For instance, {\tt z.a1} calls the %%{\tt z} macro with the suffix parameter \verb|@#| set to {\tt a1}. В общем, $$ {\tt vardef}\, \descr{обобщенная переменная} \hbox{\verb|@#|} $$ является альтернативой {\tt vardef} \tdescr{обобщенная переменная}, приводящей интерпретатор MetaPost к выделению суффикса, следующего за именем, заданным в вызове макроса, и делающей его доступным как параметр-суффикс \verb|@#|. %%In general, %%$$ {\tt vardef}\, \descr{generic variable} \hbox{\verb|@#|} $$ %%is an alternative to {\tt vardef} \tdescr{generic variable} that causes the %%MetaPost interpreter %%to look for a suffix following the name given in the macro call and makes this %%available as the \verb|@#| suffix parameter. Суммируем особые свойства vardef-макросов: они допускают как широкий класс имен для макросов, так и имена макросов, за которыми следует специальный параметр-суффикс. %%To summarize the special features of vardef macros, they allow a broad %%class of macro names as well as macro names followed by a special suffix %%parameter. Более того, {\tt begingroup} и {\tt endgroup} автоматически добавляются к \tdescr{тексту замены} vardef-макроса. %%Furthermore, {\tt begingroup} and {\tt endgroup} are %%automatically added to the \tdescr{replacement text} of a vardef macro. Таким образом, использование {\tt vardef} вместо {\tt def} для определения макроса {\tt joinup}\index{joinup?\texttt{joinup}} на рис.~\ref{fig45} позволит избежать нужды явно включать {\tt begingroup} и {\tt endgroup} в определение макроса. %%Thus using {\tt vardef} instead of {\tt def} to define the {\tt %%joinup}\index{joinup?\texttt{joinup}} macro in Figure~\ref{fig45} would %%have avoided the need to include {\tt begingroup} and {\tt endgroup} %%explicitly in the macro definition. Фактически, большинство определений макросов в предыдущих примерах могут использовать {\tt vardef} вместо {\tt def}. %%In fact, most of the macro definitions given in previous examples could %%equally well use {\tt vardef} instead of {\tt def}. Обычно не имеет большого значения, который из них использовать, но есть хорошее общее правило: используйте {\tt vardef}, если вы собираетесь использовать макрос как функцию или процедуру. %%It usually does not %%matter very much which you use, but a good general rule is to use {\tt %%vardef} if you intend the macro to be used like a function or a %%subroutine. Следующее сравнение должно помочь при решении, когда использовать {\tt vardef}. %%The following comparison should help in deciding when to %%use {\tt vardef}. \begin{itemize} \item Vardef-макрос автоматически окружен {\tt begingroup} и {\tt endgroup}. %%\item Vardef macros are automatically surrounded by {\tt begingroup} %%and {\tt endgroup}. \item Имя vardef-макроса может быть более одного знака длиной и оно может содержать индексы. %%\item The name of a vardef macro can be more than one token long and it can %%contain subscripts. \item Vardef-макрос может иметь доступ к суффиксу, следующему за именем макроса при его вызове. %%\item A vardef macro can have access to the suffix that follows the macro name %%when the macro is called. \item Когда символический знак используется в имени vardef-макроса, он остается этикеткой\index{этикетки} и может по-прежнему использоваться в именах других переменных. %%\item When a symbolic token is used in the name of a vardef macro it remains %%a tag\index{tags} and can still be used in other variable names. Поэтому {\tt p5dir} --- это правильное имя переменной, несмотря на то, что {\tt dir} --- это vardef-макрос, но обычный макрос, такой как {\tt ...}\index{...?\texttt{...}}, не может быть использован в имени переменной. %%Thus %%{\tt p5dir} is a legal variable name even though {\tt dir} is a vardef %%macro, but an ordinary macro such as {\tt ...}\index{...?\texttt{...}} %%cannot be used in a variable name. Это к лучшему, потому как {\tt z5...z6} естественно считать выражением-путем, а не составным именем переменной. %%(This is fortunate since {\tt %%z5...z6} is supposed to be a path expression, not an elaborate variable %%name). \end{itemize} \subsection{Определение унарных и бинарных макросов} %%\subsection{Defining Unary and Binary Macros} Уже не раз упоминалось, что некоторые обсуждаемые до сих пор операторы и команды на самом деле являются предопределенными макросами. %%It has been mentioned several times that some of the operators and %%commands discussed so far are actually predefined macros. Это касается унарных операторов {\tt round}\index{round?\texttt{round}} и {\tt unitvector}\index{unitvector?\texttt{unitvector}}, команд {\tt fill}\index{fill?\texttt{fill}} и {\tt draw}\index{draw?\texttt{draw}}, бинарных операторов {\tt dotprod}\index{dotprod?\texttt{dotprod}} и {\tt intersectionpoint}\index{intersectionpoint?\texttt{intersectionpoint}}. %%These include %%unary operators such as {\tt round}\index{round?\texttt{round}} and {\tt %%unitvector}\index{unitvector?\texttt{unitvector}}, statements such as %%{\tt fill}\index{fill?\texttt{fill}} and {\tt %%draw}\index{draw?\texttt{draw}}, and binary operators such as {\tt %%dotprod}\index{dotprod?\texttt{dotprod}} and {\tt %%intersectionpoint}\index{intersectionpoint?\texttt{intersectionpoint}}. Главная разница между этими макросами и теми, определения которых мы уже знаем, в том, как определять синтаксис их аргументов. %%The main difference between these macros and the ones we already know %%how to define is their argument syntax. Макросы {\tt round} и {\tt unitvector} --- это примеры того, что на рис.~\ref{syexpr} зовется \tdescr{унарным оператором}. %%The {\tt round} and {\tt unitvector} macros are examples of what %%Figure~\ref{syexpr} calls \tdescr{unary op}. За ними следует выражение-первичность. %%That is, they are followed by a primary expression. Для указания аргумента макроса такого типа определение макроса должно выглядеть подобно этому: $$ \hbox{\tt vardef round primary u =}\, \descr{текст замены}\, \hbox{\tt enddef;} $$ %%To specify a macro argument of this type, the %%macro definition should look like this: %%$$ \hbox{\tt vardef round primary u =}\, \descr{replacement text}\, %% \hbox{\tt enddef;} %%$$ Параметр {\tt u} --- это {\tt expr}-параметр\index{параметр!expr} и он может быть использован в точности также как параметр-выражение, определяемый обычным синтаксисом, $$ \hbox{\tt (expr u)} $$ %%The {\tt u} parameter is an expr parameter\index{parameter!expr} and it can be %%used exactly like the expr parameter defined using the ordinary %%$$ \hbox{\tt (expr u)} $$ %%syntax. Как предполагает пример с {\tt round}, макрос может определяться с параметром \tdescr{вторичностью}\index{вторичность?\tdescr{вторичность}}, \tdescr{третичностью}\index{третичность?\tdescr{третичность}} или \tdescr{выражением}\index{выражение?\tdescr{выражение}}. %%As the {\tt round} example suggests, a macro can be defined to take a %%\tdescr{secondary}\index{secondary?\tdescr{secondary}}, %%\tdescr{tertiary}\index{tertiary?\tdescr{tertiary}}, or an %%\tdescr{expression}\index{expression?\tdescr{expression}} parameter. Например, предопределенное определение макроса {\tt fill} примерно такое\index{fill?\texttt{fill}} $$ \hbox{\tt def fill expr c = addto currentpicture contour c enddef;} $$ %%For example, the predefined definition of the {\tt fill} macro is %%roughly\index{fill?\texttt{fill}} %%$$ \hbox{\tt def fill expr c = addto currentpicture contour c enddef;} $$ Возможно даже определить макрос в роли \tdescr{of-оператора}\index{of operator?\tdescr{of-оператор}} из рис.~\ref{syexpr}. %%It is even possible to define a macro to play the role of \tdescr{of %%operator}\index{of operator?\tdescr{of operator}} in %%Figure~\ref{syexpr}. Например, макрос {\tt direction of}\index{direction of?\texttt{direction of}} имеет определение такой формы: $$ \hbox{\tt vardef direction expr t of p =}\, \descr{текст замены}\, \hbox{\tt enddef;} $$ %%For example, the {\tt direction %%of}\index{direction of?\texttt{direction of}} macro has a definition of %%this form: %%$$ \hbox{\tt vardef direction expr t of p =}\, \descr{replacement text}\, %% \hbox{\tt enddef;} %%$$ Макросы можно также определять с поведением, подобным бинарным операторам. %%Macros can also be defined to behave like binary operators. Например, определение макроса {\tt dotprod} имеет форму\index{dotprod?\texttt{dotprod}}\index{primarydef?\texttt{primarydef}} $$ \hbox{\tt primarydef w dotprod z =}\, \descr{текст замены}\, \hbox{\tt enddef;} $$ %%For instance, the %%definition of the {\tt dotprod} macro has the %%form\index{dotprod?\texttt{dotprod}}\index{primarydef?\texttt{primarydef}} %%$$ \hbox{\tt primarydef w dotprod z =}\, \descr{replacement text}\, %% \hbox{\tt enddef;} %%$$ Эта форма делает {\tt dotprod} \tdescr{первичным бинарным оператором}\index{первичный binop?\tdescr{первичный бинарный оператор}}. %%This makes {\tt dotprod} a \tdescr{primary binop}\index{primary %%binop?\tdescr{primary binop}}. Похожим образом {\tt secondarydef}\index{secondarydef?\texttt{secondarydef}} и {\tt tertiarydef}\index{tertiarydef?\texttt{tertiarydef}} вводят определения \tdescr{вторичного бинарного оператора}\index{вторичный binop?\tdescr{вторичный бинарный оператор}} и \tdescr{третичного бинарного оператора}\index{третичный binop?\tdescr{третичный бинарный оператор}}. %%Similarly, {\tt %%secondarydef}\index{secondarydef?\texttt{secondarydef}} and {\tt %%tertiarydef}\index{tertiarydef?\texttt{tertiarydef}} introduce %%\tdescr{secondary binop}\index{secondary binop?\tdescr{secondary binop}} %%and \tdescr{tertiary binop}\index{tertiary binop?\tdescr{tertiary %%binop}} definitions. Все они определяют обычные макросы, а не vardef-макросы, например, ``{\tt primaryvardef}'' не существует. %%These all define ordinary macros, not vardef %%macros; e.g., there is no ``{\tt primaryvardef}.'' Таким образом, определения макросов могут вводиться с {\tt def}, {\tt vardef}, {\tt primarydef}, {\tt secondarydef} или {\tt tertiarydef}. %%Thus macro definitions can be introduced by {\tt def}, {\tt vardef}, %%{\tt primarydef}, {\tt secondarydef}, or {\tt tertiarydef}. \tdescr{Текст замены}\index{текст замены?\tdescr{текст замены}} --- это любой список знаков, сбалансированный относительно пар {\tt def}-{\tt enddef}, где все пять определяющих макрос знаков рассматриваются подобными {\tt def} в соответствии {\tt def}-{\tt enddef}. %%A \tdescr{replacement text}\index{replacement text?\tdescr{replacement %%text}} is any list of tokens that is balanced with respect to {\tt %%def}-{\tt enddef} pairs where all five macro definition tokens are %%treated like {\tt def} for the purpose of {\tt def}-{\tt enddef} %%matching. Весь синтаксис для определений макросов приводится на рис.~\ref{symacro}. %%The rest of the syntax for macro definitions is summarized in %%Figure~\ref{symacro}. В этом синтаксисе есть несколько сюрпризов. %%The syntax contains a few surprises. Параметры макроса могут иметь \tdescr{отделенную часть} и \tdescr{неотделенную часть}. %%The macro %%parameters can have a \tdescr{delimited part} and an \tdescr{undelimited %%part}. Обычно одна из них \tdescr{пусто}, но возможно иметь обе части непустыми: $$ \hbox{\tt def foo(text a) expr b =}\, \descr{текст замены}\, \hbox{\tt enddef;} $$ %%Normally, one of these is \tdescr{empty}, but it is possible to %%have both parts nonempty: %%$$ \hbox{\tt def foo(text a) expr b =}\, \descr{replacement text}\, %% \hbox{\tt enddef;} %%$$ Это определяет макрос {\tt foo} с текстовым параметром в скобках, за которым идет выражение. %%This defines a macro {\tt foo} to take a text parameter in parentheses followed %%by an expression. \begin{figure}[htp] \begin{ctabbing} $\tt \descr{определение макроса} \rightarrow \descr{заголовок макроса} \hbox{\tt =} \descr{текст замены}\, enddef$\\ %%$\tt \descr{macro definition} \rightarrow %% \descr{macro heading} \hbox{\tt =} \descr{replacement text}\, enddef$\\ $\tt \descr{заголовок макроса} \rightarrow def\, \descr{символический знак} \descr{отделенная часть} \descr{неотделенная часть}$\\ %%$\tt \descr{macro heading} \rightarrow def\, \descr{symbolic token} %% \descr{delimited part} \descr{undelimited part}$\\ $\tt \qquad \;|\; vardef\, \descr{обобщенная переменная} \descr{отделенная часть} \descr{неотделенная часть}$\\ %%$\tt \qquad \;|\; vardef\, \descr{generic variable} \descr{delimited part} %% \descr{undelimited part}$\\ $\tt \qquad \;|\; vardef\, \descr{обобщенная переменная} \hbox{\tt @\#} \descr{отделенная часть} \descr{неотделенная часть}$\\ %%$\tt \qquad \;|\; vardef\, \descr{generic variable} \hbox{\tt @\#} %% \descr{delimited part} \descr{undelimited part}$\\ $\tt \qquad \;|\; \descr{определение бинарности} \descr{параметр} \descr{символический знак} \descr{параметр}$\\ %%$\tt \qquad \;|\; \descr{binary def} \descr{parameter} %% \descr{symbolic token} \descr{parameter}$\\ $\tt \descr{отделенная часть} \rightarrow \descr{пусто}$\\ %%$\tt \descr{delimited part} \rightarrow \descr{empty}$\\ $\tt \qquad \;|\; \descr{отделенная часть} \hbox{\tt (}\descr{тип параметра} \descr{знаки параметра}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; \descr{delimited part} %% \hbox{\tt (}\descr{parameter type} \descr{parameter tokens}\hbox{\tt )}$\\ $\tt \descr{тип параметра} \rightarrow expr \;|\; suffix \;|\; text$\\ %%$\tt \descr{parameter type} \rightarrow expr \;|\; suffix \;|\; text$\\ $\tt \descr{знаки параметра} \rightarrow \descr{параметр} \;|\; \descr{знаки параметра}\hbox{\tt ,} \descr{параметр}$\\ %%$\tt \descr{parameter tokens} \rightarrow \descr{parameter} \;|\; %% \descr{parameter tokens}\hbox{\tt ,} \descr{parameter}$\\ $\tt \descr{параметр} \rightarrow \descr{символический знак}$\\ %%$\tt \descr{parameter} \rightarrow \descr{symbolic token}$\\ $\tt \descr{неотделенная часть} \rightarrow \descr{пусто}$\\ %%$\tt \descr{undelimited part} \rightarrow \descr{empty}$\\ $\tt \qquad \;|\; \descr{тип параметра} \descr{параметр}$\\ %%$\tt \qquad \;|\; \descr{parameter type} \descr{parameter}$\\ $\tt \qquad \;|\; \descr{приоритет} \descr{параметр}$\\ %%$\tt \qquad \;|\; \descr{precedence level} \descr{parameter}$\\ $\tt \qquad \;|\; expr\, \descr{параметр}\, of\, \descr{параметр}$\\ %%$\tt \qquad \;|\; expr\, \descr{parameter}\, of\, \descr{parameter}$\\ $\tt \descr{приоритет} \rightarrow primary \;|\; secondary \;|\; tertiary$\\ %%$\tt \descr{precedence level} \rightarrow primary \;|\; secondary \;|\; %% tertiary$\\ $\tt \descr{определение бинарности} \rightarrow primarydef \;|\; secondarydef \;|\; tertiatydef$ %%$\tt \descr{binary def} \rightarrow primarydef \;|\; secondarydef \;|\; %% tertiatydef$ \end{ctabbing} \caption{Синтаксис определений макросов} %%\caption{The syntax for macro definitions} \label{symacro} \end{figure} Синтаксис также позволяет \tdescr{неотделенной части} указывать тип аргумента {\tt suffix}\index{suffix?\texttt{suffix}} или {\tt text}\index{text?\texttt{text}}. %%The syntax also allows the \tdescr{undelimited part} to specify an %%argument type of {\tt suffix}\index{suffix?\texttt{suffix}} or {\tt %%text}\index{text?\texttt{text}}. Пример макроса с неотделенным параметром-суффиксом\index{параметр!suffix} --- это предопределенный макрос {\tt incr}\index{incr?\texttt{incr}}\label{Dincr}, который в действительности определяется примерно так: $$ \hbox{\verb|vardef incr suffix $ = $:=$+1; $ enddef;|} $$ %%An example of a macro with an %%undelimited suffix parameter\index{parameter!suffix} is the predefined %%macro {\tt incr}\index{incr?\texttt{incr}}\label{Dincr} that is actually %%defined like this: %%$$ \hbox{\verb|vardef incr suffix $ = $:=$+1; $ enddef;|} $$ Это делает {\tt incr} функцией, что берет переменную, увеличивает ее и возвращает новое значение. %%This makes {\tt incr} a function that takes a variable, increments it, %%and returns the new value. Неотделенные параметры-суффиксы могут быть в скобках, поэтому и {\tt incr a}, и {\tt incr(a)} правильны, если {\tt a} --- это числовая переменная. %%Undelimited suffix parameters may be %%parenthesized, so {\tt incr a} and {\tt incr(a)} are both legal if {\tt %%a} is a numeric variable. Есть также похожий предопределенный макрос {\tt decr}\index{decr?\texttt{decr}}, вычитающий~1. %%There is also a similar predefined macro {\tt %%decr}\index{decr?\texttt{decr}} that subtracts~1. Неотделенные текстовые параметры\index{параметр!text} распространяются до конца команды. %%Undelimited text parameters\index{parameter!text} run to the end of a %%statement. Более точно, неотделенный текстовый параметр --- это список знаков, следующих за вызовом макроса до первого ``{\tt ;}\index{точка с запятой}'' или ``{\tt endgroup}\index{endgroup?\texttt{endgroup}}'' или ``{\tt end}\index{end?\texttt{end}}'', с тем уточнением, что аргумент, содержащий ``{\tt begingroup}'' будет всегда включать соответствующий ``{\tt endgroup}''. %%More precisely, an undelimited text parameter is the list of %%tokens following the macro call up to the first ``{\tt %%;}\index{semicolon}'' or ``{\tt %%endgroup}\index{endgroup?\texttt{endgroup}}'' or ``{\tt %%end}\index{end?\texttt{end}}'' except that an argument containing ``{\tt %%begingroup}'' will always include the matching ``{\tt endgroup}.'' Пример неотделенного текстового параметра --- в предопределенном макросе {\tt cutdraw}\index{cutdraw?\texttt{cutdraw}}\label{Dctdraw}, чье определение выглядит примерно так\index{linecap?\texttt{linecap}}\index{butt?\texttt{butt}}\index{interim?\texttt{interim}} $$\begin{verbatim} def cutdraw text t = begingroup interim linecap:=butt; draw t; endgroup enddef; \end{verbatim} $$ %%An example of an undelimited text parameter comes from the predefined macro %%{\tt cutdraw}\index{cutdraw?\texttt{cutdraw}}\label{Dctdraw} whose %%definition is %%roughly\index{linecap?\texttt{linecap}}\index{butt?\texttt{butt}}\index{interim?\texttt{interim}} %%$$\begin{verbatim} %%def cutdraw text t = %% begingroup interim linecap:=butt; draw t; endgroup enddef; %%\end{verbatim} %%$$ Это делает {\tt cutdraw} синонимом {\tt draw}, но с другим значением {\tt linecap}. %%This makes {\tt cutdraw} synonymous with {\tt draw} except for the {\tt %%linecap} value. Это макрос предоставляется в основном для совместимости с \MF\index{metafont?\MF}. %%(This macro is provided mainly for compatibility with %%\MF\index{metafont?\MF}.) \section{Циклы} %%\section{Loops} Многочисленные примеры в предыдущих разделах использовали простую форму цикла {\tt for}\index{циклы}\index{for?\texttt{for}}\index{endfor?\texttt{endfor}}, $$ {\tt for}\, \descr{символический знак}\, \hbox{\tt =}\, \descr{выражение}\, {\tt upto}\, \descr{выражение}:\ \descr{тело цикла}\, {\tt endfor} $$ %%Numerous examples in previous sections have used simple {\tt for} loops of the %%form\index{loops}\index{for?\texttt{for}}\index{endfor?\texttt{endfor}} %%$$ {\tt for}\, \descr{symbolic token}\, \hbox{\tt =}\, %% \descr{expression}\, {\tt upto}\, \descr{expression}:\ %% \descr{loop text}\, {\tt endfor} %%$$ Конструировать цикл с уменьшением также просто --- нужно лишь заменить {\tt upto} на {\tt downto}\index{downto?\texttt{downto}}\label{Ddwnto} и сделать второе \tdescr{выражение} меньшим первого. %%It is equally simple to construct a loop that counts downward: just %%replace {\tt upto} by {\tt %%downto}\index{downto?\texttt{downto}}\label{Ddwnto} make the second %%\tdescr{expression} smaller than the first. Этот раздел описывает более сложные ситуации: прогрессии; циклы, где параметр цикла ведет себя как суффикс; способы выхода из цикла. %%This section covers more %%complicated types of progressions, loops where the loop counter behaves %%like a suffix parameter, and ways of exiting from a loop. Начнем с представления общего факта того, что {\tt upto}\index{upto?\texttt{upto}} --- это предопределенный макрос, равный\index{step?\texttt{step}}\index{until?\texttt{until}} $$ \hbox{\tt step 1 until}, $$ и {\tt downto}\index{downto?\texttt{downto}} --- макрос, равный {\tt step -1 until}. %%The first generalization is suggested by the fact that {\tt %%upto}\index{upto?\texttt{upto}} is a predefined macro %%for\index{step?\texttt{step}}\index{until?\texttt{until}} %%$$ \hbox{\tt step 1 until} $$ %%and {\tt downto}\index{downto?\texttt{downto}} is a macro for {\tt step %%-1 until}. Цикл, начинающийся с $$ \hbox{\tt for i=a step b until c}, $$ перебирает последовательность {\tt i} из значений {\tt a}, ${\tt a}+{\tt b}$, ${\tt a}+2{\tt b}$, \ldots, останавливаясь до того как {\tt i} пройдет за {\tt c}, т.~е. цикл перебирает значения {\tt i}, где ${\tt i}\leqslant {\tt c}$ при ${\tt b}>0$ и ${\tt i}\geqslant {\tt c}$ при ${\tt b}<0$. %%A loop begining %%$$ \hbox{\tt for i=a step b until c} $$ %%scans a sequence of {\tt i} values {\tt a}, ${\tt a}+{\tt b}$, ${\tt %%a}+2{\tt b}$, \ldots, stopping before {\tt i} passes {\tt c}; i.e., the %%loop scans {\tt i} values where ${\tt i}\le {\tt c}$ if ${\tt b}>0$ and %%${\tt i}\ge {\tt c}$ if ${\tt b}<0$. Для ${\tt b}=0$ цикл никогда не закончится даже при ${\tt a}={\tt c}$. %%For ${\tt b}=0$ the loop never %%terminates, even if ${\tt a}={\tt c}$. Лучше всего использовать такой цикл только тогда, когда шаг цикла --- это целое\index{арифметика} или число, представимое точно в виде дроби, кратной $1\over65536$. %%It is best to use this feature only when the step size is an integer or %%some number that can be represented exactly in fixed point %%arithmetic\index{arithmetic} as a multiple of $1\over65536$. В противном случае будет накапливаться ошибка и параметр цикла может не достичь ожидаемого конечного значения. %%Otherwise, %%error will accumulate and the loop index might not reach the expected %%termination value. Например, $$ \hbox{\tt for i=0 step .1 until 1: show i; endfor} $$ покажет десять значений {\tt i}, последнее из которых будет 0.90005. %%For instance, %%$$ \hbox{\tt for i=0 step .1 until 1: show i; endfor} $$ %%shows ten {\tt i} values the last of which is 0.90005. Стандартный способ избежать проблемы, связанной с нецелым размером шага, в итерации по целым значениям и умножению их при использовании на масштабирующий множитель, как это было сделано на рисунках \ref{fig1} и~\ref{fig40}. %%The standard way of avoid the problems associated with non-integer step %%sizes is to iterate over integer values and then multiply by a scale %%factor when using the loop index as was done in Figures \ref{fig1} %%and~\ref{fig40}. Есть альтернатива --- можно указывать значения для перебора явно. %%Alternatively, the values to iterate over can be given explicitly. Любая последовательность из нуля и более выражений, разделенных запятыми, может использоваться на месте {\tt a step b upto c}. %%Any %%sequence of zero or more expressions separated by commas can be used in %%place of {\tt a step b upto c}. Причем, все выражения не обязаны иметь одинаковый тип или известные значения. %%In fact, the expressions need not all %%be the same type and they need not have known values. Таким образом, $$ \hbox{\tt for t=3.14, 2.78, (a,2a), "hello": show t; endfor} $$ покажет четыре значения из списка. %%Thus %%$$ \hbox{\tt for t=3.14, 2.78, (a,2a), "hello": show t; endfor} $$ %%shows the four values listed. Заметьте, что тело цикла в примере выше --- это команда, за которой следует точка с запятой. %%Note that the loop body in the above example is a statement followed by a %%semicolon. Для тела цикла естественно содержать одну или более команду, хотя это и не обязательно. %%It is common for the body of a loop to be one or more statements, %%but this need not be the case. Цикл подобен определению макроса, за которым следует вызов этого макроса. %%A loop is like a macro definition followed by %%calls to the macro. Тело цикла может быть практически любой последовательностью знаков, имеющих смысл в совокупности. %%The loop body can be virtually any sequence of tokens as %%long as they make sense together. Поэтому (нелепая) команда $$ \hbox{\tt draw for p=(3,1),(6,2),(7,5),(4,6),(1,3): p-{}- endfor cycle;} $$ эквивалента $$ \hbox{\tt draw (3,1)-{}-(6,2)-{}-(7,5)-{}-(4,6)-{}-(1,3)-{}-cycle;} $$ %%Thus, the (ridiculous) statement %%$$ \hbox{\tt draw for p=(3,1),(6,2),(7,5),(4,6),(1,3): p-- endfor cycle;} $$ %%is equivalent to %%$$ \hbox{\tt draw (3,1)--(6,2)--(7,5)--(4,6)--(1,3)--cycle;} $$ См. рис~\ref{fig17} с более реалистическим подходящим примером. %%(See Figure~\ref{fig17} for a more realistic example of this.) Если цикл подобен определению макроса, то параметр цикла подобен {\tt expr}-параметру\index{параметр!expr}. %%If a loop is like a macro definition, the loop index is like an expr %%parameter\index{parameter!expr}. Он может представлять любое значение, но он не является переменной и его нельзя менять командой присваивания\index{присваивание}. %%It can represent any value, but it is %%not a variable and it cannot be changed by an assignment %%statement\index{assignment}. Последнее можно отменить использованием цикла {\tt forsuffixes}\index{forsuffixes?\texttt{forsuffixes}}. %%In order to do that, you need a {\tt %%forsuffixes}\index{forsuffixes?\texttt{forsuffixes}} loop. Цикл {\tt forsuffixes} во многом похож на цикл {\tt for}, но в нем параметр цикла ведет себя как параметр-суффикс\index{параметр!suffix}. %%A {\tt %%forsuffixes} loop is a lot like a {\tt for} loop, except the loop index %%behaves like a suffix parameter\index{parameter!suffix}. Используется синтаксис $$ {\tt forsuffixes}\, \descr{символический знак}\, \hbox{\tt =}\, \descr{список суффиксов}:\ \descr{тело цикла}\, {\tt endfor}, $$ где \tdescr{список суффиксов} --- это разделенный запятыми список. %%The syntax is %%$$ {\tt forsuffixes}\, \descr{symbolic token}\, \hbox{\tt =}\, %% \descr{suffix list}:\ \descr{loop text}\, {\tt endfor} %%$$ %%where a \tdescr{suffix list} is a comma-separated list of suffixes. Если некоторые суффиксы \tdescr{пусты}, то \tdescr{тело цикла} выполняется с параметром цикла, установленным в пустой суффикс. %%If some of the suffixes are \tdescr{empty}, the \tdescr{loop text} gets %%executed with the loop index parameter set to the empty suffix. Хороший пример для цикла {\tt forsuffixes} --- это определение макроса {\tt dotlabels}\index{dotlabels?\texttt{dotlabels}}\index{str?\texttt{str}}: $$\begin{verbatim} vardef dotlabels@#(text t) = forsuffixes $=t: dotlabel@#(str$,z$); endfor enddef; \end{verbatim} $$ %%A good example of a {\tt forsuffixes} loop is the definition of the {\tt %%dotlabels}\index{dotlabels?\texttt{dotlabels}} %%macro\index{str?\texttt{str}}: %%$$\begin{verbatim} %%vardef dotlabels@#(text t) = %% forsuffixes $=t: dotlabel@#(str$,z$); endfor enddef; %%\end{verbatim} %%$$ Он объясняет, почему параметр {\tt dotlabels} должен быть разделенный запятыми список суффиксов. %%This should make it clear why the parameter to {\tt dotlabels} has to be a %%comma-separated list of suffixes. Большинство макросов с разделенными запятыми списками переменной длины используют их в циклах {\tt for} или {\tt forsuffixes} именно таким образом, т.~е. для перебора значений. %%Most macros that accept variable-length %%comma-separated lists %%use them in {\tt for} or {\tt forsuffixes} loops in this fashion as values to %%iterate over. Когда нет значений для перебора, вы можете использовать цикл {\tt forever}\index{forever?\texttt{forever}}, $$ {\tt forever}\hbox{\tt :}\, \descr{тело цикла}\, {\tt endfor} $$ %%When there are no values to iterate over, you can use a %%{\tt forever}\index{forever?\texttt{forever}} loop: %%$$ {\tt forever}\hbox{\tt :}\, \descr{loop text}\, {\tt endfor} $$ Для завершения такого цикла, когда логическое условие станет истинным, используйте пункт выхода\index{exitif?\texttt{exitif}}: $$ {\tt exitif}\, \descr{логическое выражение} \hbox{\tt ;} $$ %%To terminate such a loop when a boolean condition becomes true, use an exit %%clause\index{exitif?\texttt{exitif}}: %%$$ {\tt exitif}\, \descr{boolean expression} \hbox{\tt ;} $$ Когда интерпретатор MetaPost встречает пункт выхода, он вычисляет \tdescr{логическое выражение} и выходит из текущего цикла, если оно истинно. %%When the MetaPost interpreter encounters an exit clause, it evaluates %%the \tdescr{boolean expression} and exits the current loop if the %%expression is true. Если более удобно выйти из цикла, когда выражение станет ложным, то используйте предопределенный макрос {\tt exitunless}\index{exitunless?\texttt{exitunless}}. %%If it is more convenient to exit the loop when an %%expression becomes false, use the predefined macro {\tt %%exitunless}\index{exitunless?\texttt{exitunless}}. Поэтому вариант MetaPost для цикла {\bf while} --- это $$ \hbox{\tt forever: exitunless}\, \descr{логическое выражение} \hbox{\tt ;}\, \descr{тело цикла}\, {\tt endfor} $$ %%Thus MetaPost's version of a {\bf while} loop is %%$$ \hbox{\tt forever: exitunless}\, \descr{boolean expression} \hbox{\tt ;}\, %% \descr{loop text}\, {\tt endfor} %%$$ Пункт выхода может помещаться как непосредственно перед {\tt endfor}, так и в любом другом месте \tdescr{тела цикла}. %%The exit clause could equally well come just before {\tt endfor} or anywhere %%in the \tdescr{loop text}. Любой цикл {\tt for}, {\tt forever} или {\tt forsuffixes} может практически содержать любое количество пунктов выхода. %%In fact any {\tt for}, {\tt forever}, or %%{\tt forsuffixes} loop can contain any number of exit clauses. Сводка синтаксиса цикла, показанная на рис.~\ref{syloop}, не упоминает явно пункты выхода, потому что \tdescr{тело цикла} может быть в действительности любой последовательностью знаков. %%The summary of loop syntax shown in Figure~\ref{syloop} does not mention %%exit clauses explicitly because a \tdescr{loop text} can be virtually %%any sequence of tokens. Единственное ограничение в том, что \tdescr{тело цикла} должно быть сбалансировано относительно {\tt for} и {\tt endfor}. %%The only restriction is that a \tdescr{loop %%text} must be balanced with respect to {\tt for} and {\tt endfor}. Конечно, в этом балансе {\tt forsuffixes} и {\tt forever} рассматриваются как {\tt for}. %%Of course this balancing process treats {\tt forsuffixes} and {\tt forever} %%just like {\tt for}. \begin{figure}[htp] \begin{ctabbing} $\tt \descr{цикл} \rightarrow \descr{заголовок цикла}\hbox{\tt :}\, \descr{тело цикла} endfor$\\ %%$\tt \descr{loop} \rightarrow \descr{loop header}\hbox{\tt :}\, %% \descr{loop text} endfor$\\ $\tt \descr{заголовок цикла} \rightarrow for\, \descr{символический знак}\, \hbox{\tt =}\, \descr{прогрессия}$\\ %%$\tt \descr{loop header} \rightarrow for\, \descr{symbolic token}\, %% \hbox{\tt =}\, \descr{progression}$\\ $\tt \qquad \;|\; for\, \descr{символический знак}\, \hbox{\tt =}\, \descr{список for}$\\ %%$\tt \qquad \;|\; for\, \descr{symbolic token}\, \hbox{\tt =}\, %% \descr{for list}$\\ $\tt \qquad \;|\; forsuffixes\, \descr{символический знак}\, \hbox{\tt =}\, \descr{список суффиксов}$\\ %%$\tt \qquad \;|\; forsuffixes\, \descr{symbolic token}\, \hbox{\tt =}\, %% \descr{suffix list}$\\ $\tt \qquad \;|\; forever$\\ %%$\tt \qquad \;|\; forever$\\ $\tt \descr{прогрессия} \rightarrow \descr{числовое выражение}\, upto\, \descr{числовое выражение}$\\ %%$\tt \descr{progression} \rightarrow \descr{numeric expression}\, upto\, %% \descr{numeric expression}$\\ $\tt \qquad \;|\; \descr{числовое выражение}\, downto\, \descr{числовое выражение}$\\ %%$\tt \qquad \;|\; \descr{numeric expression}\, downto\, %% \descr{numeric expression}$\\ $\tt \qquad \;|\; \descr{числовое выражение}\, step\, \descr{числовое выражение}\, until\, \descr{числовое выражение} $\\ %%$\tt \qquad \;|\; \descr{numeric expression}\, step\, %% \descr{numeric expression}\, until\, \descr{numeric expression} $\\ $\tt \descr{список for} \rightarrow \descr{выражение} \;|\; \descr{список for}\hbox{\tt ,}\, \descr{выражение}$\\ %%$\tt \descr{for list} \rightarrow \descr{expression} %% \;|\; \descr{for list}\hbox{\tt ,}\, \descr{expression}$\\ $\tt \descr{список суффиксов} \rightarrow \descr{суффикс} \;|\; \descr{список суффиксов}\hbox{\tt ,}\, \descr{суффикс}$ %%$\tt \descr{suffix list} \rightarrow \descr{suffix} %% \;|\; \descr{suffix list}\hbox{\tt ,}\, \descr{suffix}$ \end{ctabbing} \caption{Синтаксис для циклов} %%\caption{The syntax for loops} \label{syloop} \end{figure} \section{Изготовление рамок} %%\section{Making Boxes} \label{boxessec} Этот раздел описывает дополнительные макросы, не включенные в Plain MetaPost, что предоставляют удобства делать то, в чем хорош {\it pic} \cite{ke:pic}. %%This section describes auxiliary macros not included in Plain MetaPost %%that make it convenient to do things that {\it pic} is good at %%\cite{ke:pic}. А то, что следует далее --- это описание, как использовать макросы, содержащиеся в файле {\tt boxes.mp}\index{boxes.mp?\texttt{boxes.mp}}. %%What follows is a description of how to use the macros %%contained in the file {\tt boxes.mp}\index{boxes.mp?\texttt{boxes.mp}}. Этот файл размещается в специальном каталоге для макросов MetaPost и обеспечивающего программного обеспечения\footnote{Имя этого каталога подобно чему-то типа \texttt{/usr/lib/mp/lib}, но зависит от системы.} и должен стать доступным через команду MetaPost {\tt input boxes} до любых рисунков, использующих макросы для создания рамок. %%This file is included in a special directory reserved for MetaPost %%macros and support software\footnote{The name of this directory is %%likely to be something like \texttt{/usr/lib/mp/lib}, but this is system %%dependent.} and can be accessed by giving the MetaPost command {\tt %%input boxes} before any figures that use the box making macros. Синтаксис команды {\tt input}\index{input?\texttt{input}} --- $$ {\tt input}\, \descr{имя файла}, $$ где окончание ``{\tt .mp}'' может опускаться в имени файла. %%The %%syntax for the {\tt input} command is \index{input?\texttt{input}} %$$ {\tt input}\, \descr{file name} $$ %%where a final ``{\tt .mp}'' can be omitted from the file name. Команда {\tt input} смотрит сначала в текущем каталоге, а затем в специальном каталоге для макросов. %%The {\tt input} %%command looks first in the current directory and then in the special macro %%directory. Пользователи, заинтересовавшиеся в написании макросов, возможно захотят посмотреть на файл {\tt boxes.mp} в этом каталоге. %%Users interested in writing macros may want to look at the %%{\tt boxes.mp} file in this directory. С времени появления пакета \texttt{boxes} в MetaPost-сообществе были разработаны несколько альтернативных пакетов разных видов для рисования рамок. %%Since the advent of the \texttt{boxes} package several alternative %%packages for drawing boxes of all kinds have been developed by the %%MetaPost community. Наиболее известные из них --- это %%The most widely known ones are \texttt{MetaObj}\index{MetaObj?\texttt{MetaObj}}, \texttt{MetaUML}\index{MetaUML?\texttt{MetaUML}}, \texttt{expressg}\index{expressg?\texttt{expressg}} и %%\texttt{expressg}\index{expressg?\texttt{expressg}}, and \texttt{blockdraw\_mp}\index{blockdraw\_mp?\texttt{blockdraw\_mp}}. Если вы собираетесь создавать много структурных рисунков, диаграмм и т.~п., то эти пакеты тоже могут стать для вас интересным ресурсом. %%If you intend to create lots of structural drawings, flow charts, %%\emph{etc.}, those packages might be an interesting ressource, too. \subsection{Прямоугольные рамки} %%\subsection{Rectangular Boxes} Главная идея создающих рамки макросов в том, что можно сказать\index{boxit?\texttt{boxit}}\label{Dboxit} $$ {\tt boxit.} \descr{суффикс} \hbox{\tt(} \descr{выражение-картинка} \hbox{\tt),} $$ где \tdescr{суффикс} не начинается с индекса\footnote{Некоторые ранние версии делающих рамки макросов не позволяли никаких индексов в суффиксе {\tt boxit}.}. %%The main idea of the box-making macros is that one should %%say\index{boxit?\texttt{boxit}}\label{Dboxit} %%$$ {\tt boxit.} \descr{suffix} %% \hbox{\tt(} \descr{picture expression} \hbox{\tt)} %%$$ %%where the \tdescr{suffix} does not start with a subscript.\footnote{Some early %%versions of the box making macros did not allow any subscripts in the %%{\tt boxit} suffix.} Эта конструкция создает переменные-пары \tdescr{суффикс}{\tt.c}, \tdescr{суффикс}{\tt.n}, \tdescr{суффикс}{\tt.e}, \ldots, что могут затем использоваться при размещении рисунка перед его рисованием отдельной командой\index{drawboxed?\texttt{drawboxed}}\label{Ddrbxed}, например, $$ \hbox{\tt drawboxed(} \descr{список суффиксов} \hbox{\tt )} $$ %%This creates pair variables \tdescr{suffix}{\tt.c}, %%\tdescr{suffix}{\tt.n}, \tdescr{suffix}{\tt.e}, \ldots\ that can then be %%used for positioning the picture before drawing it with a separate command such %%as\index{drawboxed?\texttt{drawboxed}}\label{Ddrbxed} %%$$ \hbox{\tt drawboxed(} \descr{suffix list} \hbox{\tt )} $$ Аргумент {\tt drawboxed} должен быть разделенным запятыми списком имен рамок, где имя рамки\index{имя рамки} --- это \tdescr{суффикс}, с которым вызывается {\tt boxit}. %%The argument to {\tt drawboxed} should be a comma-separated list of box names, %%where a box name\index{box name} is a \tdescr{suffix} with which {\tt boxit} %%has been called. Для команды {\tt boxit.bb(pic)} имя рамки --- это {\tt bb}, а содержимое рамки --- это рисунок {\tt pic}. %%For the command {\tt boxit.bb(pic)}, the box name is {\tt bb} and the %%contents of the box is the picture {\tt pic}. В этом случае, {\tt bb.c} --- это позиция помещения центра картинки {\tt pic}, а {\tt bb.sw}, {\tt bb.se}, {\tt bb.ne} и {\tt bb.nw} --- это углы прямоугольного пути, что будет окружать картинку-результат. %%In this case, {\tt bb.c} %%the position where the center of picture {\tt pic} is to be placed, and %%{\tt bb.sw}, {\tt bb.se}, {\tt bb.ne}, and {\tt bb.nw} are the corners %%of a rectangular path that will surround the resulting picture. Переменные {\tt bb.dx} и {\tt bb.dy} дают промежутки между сдвинутой версией {\tt pic} и окружающим прямоугольником, а {\tt bb.off} --- это расстояние, на которое {\tt pic} сдвигается для достижения всего этого. %%Variables {\tt bb.dx} and {\tt bb.dy} give the spacing between the %%shifted version of {\tt pic} and the surrounding rectangle, and {\tt %%bb.off} is the amount by which {\tt pic} has to be shifted to achieve %%all this. Когда макрос {\tt boxit} вызывается с именем рамки~$b$, то это дает линейные уравнения, что заставляют $b${\tt.sw}, $b${\tt.se}, $b${\tt.ne} и $b${\tt.nw} быть углами прямоугольника вдоль осей $x$ и $y$, содержащим внутри картинку, показанную серым прямоугольником на рис.~\ref{fig48}. %%When the {\tt boxit} macro is called with box name~$b$, it gives linear %%equations that force $b${\tt.sw}, $b${\tt.se}, $b${\tt.ne}, and %%$b${\tt.nw} to be the corners of a rectangle aligned on the $x$ and $y$ %%axes with the box contents centered inside as indicated by the gray %%rectangle in Figure~\ref{fig48}. Значения $b${\tt.dx}, $b${\tt.dy} и $b${\tt.c} остаются неуказанными, так что пользователь может задать уравнения для размещения рамок. %%The values of $b${\tt.dx}, %%$b${\tt.dy}, and $b${\tt.c} are left unspecified so that the user can %%give equations for positioning the boxes. Если такие уравнения не задаются, то макросы типа {\tt drawboxed} могут это обнаруживать и задавать стандартные значения. %%If no such equations are %%given, macros such as {\tt drawboxed} can detect this and give default %%values. Стандартные значения для переменных {\tt dx} и {\tt dy} управляются внутренними переменными\index{внутренние переменные}\index{переменные!внутренние} {\tt defaultdx}\index{defaultdx?\texttt{defaultdx}}\label{Ddefaultdx} и {\tt defaultdy}\index{defaultdy?\texttt{defaultdy}}\label{Ddefaultdy}. %%The default values for {\tt dx} and {\tt dy} variables are %%controlled by the internal variables\index{internal %%variables}\index{variables!internal} {\tt %%defaultdx}\index{defaultdx?\texttt{defaultdx}}\label{Ddefaultdx} and %%{\tt defaultdy}\index{defaultdy?\texttt{defaultdy}}\label{Ddefaultdy}. \begin{figure}[htp] $$ \includegraphics{manfig-ru-48} $$ \caption[Как {\tt boxit}-рисунок соотносится с ассоциированным переменными] {Отношения между рисунком, заданным для {\tt boxit}, и связанными с этим переменными. Рисунок изображен серым прямоугольником.} %%\caption[How a {\tt boxit} picture relates to the associated variables] %% {The relationship between the picture given to {\tt boxit} and the %% associated variables. The picture is indicated by a gray rectangle.} \label{fig48} \end{figure} Если $b$ представляет имя рамки, то {\tt drawboxed($b$)} рисует прямоугольную границу содержимого~$b$, а затем и само содержимое. %%If $b$ represents a box name, {\tt drawboxed($b$)} draws the rectangular %%boundary of box~$b$ and then the contents of the box. Этот охватывающий прямоугольник может быть использован отдельно как {\tt bpath~$b$} или, в общем случае,\index{bpath?\texttt{bpath}}\label{Dbpath} $$ {\tt bpath}\, \descr{имя рамки} $$ %%This bounding %%rectangle can be accessed separately as {\tt bpath~$b$}, or in %%general\index{bpath?\texttt{bpath}}\label{Dbpath} %%$$ {\tt bpath}\, \descr{box name} $$ Это полезно в комбинации с операторами типа {\tt cutbefore}\index{cutbefore?\texttt{cutbefore}} и {\tt cutafter}\index{cutafter?\texttt{cutafter}} для контроля за путями, входящими в рамку. %%It is useful in combination with operators like %%{\tt cutbefore}\index{cutbefore?\texttt{cutbefore}} and {\tt %%cutafter}\index{cutafter?\texttt{cutafter}} %%in order to control paths that enter the box. Например, если $a$ и $b$ --- это имена рамок и $p$ --- это путь из $a${\tt.c} в $b${\tt.c},\index{drawarrow?\texttt{drawarrow}} то $$ \hbox{\tt drawarrow $p$ cutbefore bpath $a$ cutafter bpath $b$} $$ рисует стрелку от края рамки $a$ до края рамки $b$. %%For example, if $a$ and $b$ are box names and $p$ is a path from $a${\tt.c} %%to $b${\tt.c},\index{drawarrow?\texttt{drawarrow}} %%$$ \hbox{\tt drawarrow $p$ cutbefore bpath $a$ cutafter bpath $b$} $$ %%draws an arrow from the edge of box $a$ to the edge of box $b$. Рис.~\ref{fig49} показывает практический пример включения нескольких стрелок, нарисованных с {\tt cutafter bpath} \tdescr{имя рамки}. %%Figure~\ref{fig49} shows a practical example including some arrows drawn %%with {\tt cutafter bpath} \tdescr{box name}. Поучительно сравнить рис.~\ref{fig49} с похожей картинкой в руководстве по {\it pic} \cite{ke:pic}. %%It is instructive to %%compare Figure~\ref{fig49} to the similar figure in the pic manual %%\cite{ke:pic}. Рисунок использует макрос\index{boxjoin?\texttt{boxjoin}}\label{Dbxjoin} $$ \hbox{\tt boxjoin(} \descr{текст уравнений} \hbox{\tt )} $$ для управления отношениями между последовательными рамками. %%The figure uses a %%macro\index{boxjoin?\texttt{boxjoin}}\label{Dbxjoin} %%$$ \hbox{\tt boxjoin(} \descr{equation text} \hbox{\tt )} $$ %%to control the relationship between consecutive boxes. В \tdescr{тексте уравнений} {\tt a} и {\tt b} представляют имена рамок, заданные в последовательных вызовах {\tt boxit}, а \tdescr{текст уравнений} дает уравнения для контроля за относительными размерами и позициями рамок. %%Within the %%\tdescr{equation text}, {\tt a} and {\tt b} represent the box names given in %%consecutive calls to {\tt boxit} and the \tdescr{equation text} gives equations %%to control the relative sizes and positions of the boxes. \begin{figure}[htp] $$\hbox{$\begin{verbatim} input boxes beginfig(49); boxjoin(a.se=b.sw; a.ne=b.nw); boxit.a(btex\strut$\cdots$ etex); boxit.ni(btex\strut$n_i$ etex); boxit.di(btex\strut$d_i$ etex); boxit.ni1(btex\strut$n_{i+1}$ etex); boxit.di1(btex\strut$d_{i+1}$ etex); boxit.aa(btex\strut$\cdots$ etex); boxit.nk(btex\strut$n_k$ etex); boxit.dk(btex\strut$d_k$ etex); drawboxed(di,a,ni,ni1,di1,aa,nk,dk); label.lft("ndtable:", a.w); interim defaultdy:=7bp; boxjoin(a.sw=b.nw; a.se=b.ne); boxit.ba(); boxit.bb(); boxit.bc(); boxit.bd(btex $\vdots$ etex); boxit.be(); boxit.bf(); bd.dx=8bp; ba.ne=a.sw-(15bp,10bp); drawboxed(ba,bb,bc,bd,be,bf); label.lft("hashtab:",ba.w); vardef ndblock suffix $ = boxjoin(a.sw=b.nw; a.se=b.ne); forsuffixes $$=$1,$2,$3: boxit$$(); ($$dx,$$dy)=(5.5bp,4bp); endfor; enddef; ndblock nda; ndblock ndb; ndblock ndc; nda1.c-bb.c = ndb1.c-nda3.c = (whatever,0); xpart ndb3.se = xpart ndc1.ne = xpart di.c; ndc1.c - be.c = (whatever,0); drawboxed(nda1,nda2,nda3, ndb1,ndb2,ndb3, ndc1,ndc2,ndc3); drawarrow bb.c -- nda1.w; drawarrow be.c -- ndc1.w; drawarrow nda3.c -- ndb1.w; drawarrow nda1.c{right}..{curl0}ni.c cutafter bpath ni; drawarrow nda2.c{right}..{curl0}di.c cutafter bpath di; drawarrow ndc1.c{right}..{curl0}ni1.c cutafter bpath ni1; drawarrow ndc2.c{right}..{curl0}di1.c cutafter bpath di1; drawarrow ndb1.c{right}..nk.c cutafter bpath nk; drawarrow ndb2.c{right}..dk.c cutafter bpath dk; x.ptr=xpart aa.c; y.ptr=ypart ndc1.ne; drawarrow subpath (0,.7) of (z.ptr..{left}ndc3.c) dashed evenly; label.rt(btex \strut ndblock etex, z.ptr); endfig; \end{verbatim} $} \atop \vcenter{\vskip8pt\hbox{\includegraphics{manfig-ru-49}}} $$ \caption{Код MetaPost и соответствующий рисунок} %%\caption{MetaPost code and the corresponding figure} \label{fig49} \end{figure} Например, вторая строка ввода для приведенного рисунка содержит $$ \hbox{\tt boxjoin(a.se=b.sw; a.ne=b.nw)} $$ %%For example, the second line of input for the above figure contains %%$$ \hbox{\tt boxjoin(a.se=b.sw; a.ne=b.nw)} $$ Это размещает рамки горизонтально в ряд, благодаря заданию дополнительных уравнений, вызываемых всякий раз, когда некоторая рамка {\tt b} следует за некоторой рамкой {\tt a}. %%This causes boxes to line up horizontally by giving additional equations that %%are invoked each time some box {\tt a} is followed by some other box~{\tt b}. %%These equations are first invoked on the next line when box~{\tt a} is followed %%by box~{\tt ni}. Этим достигается $$ \hbox{\tt a.se=ni.sw; a.ne=ni.nw} $$ %%This yields %%$$ \hbox{\tt a.se=ni.sw; a.ne=ni.nw} $$ Следующая пара рамок --- это ~{\tt ni} и~{\tt di}. %%The next pair of boxes is box~{\tt ni} and box~{\tt di}. На этот раз неявно генерируемые уравнения --- $$ \hbox{\tt ni.se=di.sw; ni.ne=di.nw} $$ %%This time the implicitly generated equations are %%$$ \hbox{\tt ni.se=di.sw; ni.ne=di.nw} $$ Этот процесс продолжается до тех пор, пока новый {\tt boxjoin}\index{boxjoin?\texttt{boxjoin}} не будет задан. %%This process continues until a new {\tt %%boxjoin}\index{boxjoin?\texttt{boxjoin}} is given. В нашем случае новой декларацией будет $$ \hbox{\tt boxjoin(a.sw=b.nw; a.se=b.ne)} $$ --- она соединяет рамки друг под другом. %%In this case the new declaration is %%$$ \hbox{\tt boxjoin(a.sw=b.nw; a.se=b.ne)} $$ %%which causes boxes to be stacked below each other. После вызова {\tt boxit} для первых восьми рамок от {\tt a} до {\tt dk}, высоты рамок принуждаются к взаимному соответствию, но широты остаются неизвестными. %%After calling {\tt boxit} for the first eight boxes {\tt a} through {\tt %%dk}, the box heights are constrained to match but the widths are still %%unknown. Таким образом, макрос {\tt drawboxed}\index{drawboxed?\texttt{drawboxed}} нуждается в присваивании типовых значений переменным \tdescr{имя рамки}{\tt.dx} и \tdescr{имя рамки}{\tt.dy}. %%Thus the {\tt drawboxed}\index{drawboxed?\texttt{drawboxed}} %%macro needs to assign default values to the \tdescr{box name}{\tt.dx} %%and \tdescr{box name}{\tt.dy} variables. Первым делом {\tt di.dx} и {\tt di.dy} получают значения по-умолчанию, так что все рамки принуждаются быть достаточно большими для вмещения содержимого~{\tt di}. %%First, {\tt di.dx} and {\tt %%di.dy} get default values so that all the boxes are forced to be large %%enough to contain the contents of box~{\tt di}. Макрос, который в действительности присваивает типовые значения переменным {\tt dx} и {\tt dy}, зовется {\tt fixsize}\index{fixsize?\texttt{fixsize}}\label{Dfixsiz}. %%The macro that actually assigns default values to {\tt dx} and {\tt dy} %%variables is called {\tt %%fixsize}\index{fixsize?\texttt{fixsize}}\label{Dfixsiz}. Он берет список имен рамок и рассматривает их по-одному за раз, гарантируя, что каждая рамка будет иметь заданные размер и форму. %%It takes a %%list of box names and considers them one at a time, making sure that %%each box has a fixed size and shape. Затем макрос с именем {\tt fixpos}\index{fixpos?\texttt{fixpos}}\label{Dfixpos} берет этот же самый список имен рамок и присваивает типовые значения переменным \tdescr{имя рамки}{\tt.off}, как необходимо для фиксации позиции каждой рамки. %%A macro called {\tt %%fixpos}\index{fixpos?\texttt{fixpos}}\label{Dfixpos} then takes this %%same list of box names and assigns default values to the \tdescr{box %%name}{\tt.off} variables as needed to fix the position of each box. Использование {\tt fixsize} для фиксации размеров каждой рамки до присваивания позиции любой из них может обычно сократить число требуемых позиций по-умолчанию до одной. %%By using {\tt fixsize} to fix the dimensions of each box before assigning %%default positions to any of them, the number of needing default %%positions can usually be cut to at most one. Из-за того, что охватывающий путь для рамки не может быть вычислен до тех пор, пока размер, форма и позиция рамки неопределены, макрос {\tt bpath}\index{bpath?\texttt{bpath}} применяет {\tt fixsize} и {\tt fixpos} к своим аргументам. %%Since the bounding path for a box cannot be computed until the size, %%shape, and position of the box is determined, the {\tt %%bpath}\index{bpath?\texttt{bpath}} macro applies {\tt fixsize} and {\tt %%fixpos} to its argument. Другие макросы, что делают также, включают\index{pic?\texttt{pic}}\label{Dpic} $$ {\tt pic}\, \descr{имя рамки}, $$ где \tdescr{имя рамки} --- это суффикс, возможно, в скобках. %%Other macros that do this %%include\index{pic?\texttt{pic}}\label{Dpic} %%$$ {\tt pic}\, \descr{box name} $$ %%where the \tdescr{box name} is a suffix, possibly in parentheses. Он возвращает содержание именованной рамки как картинки, позиционированной так, что $$ {\tt draw\ pic} \descr{имя рамки} $$ изображает содержимое рамки без охватывающего прямоугольника. %%This returns %%the contents of the named box as a picture positioned so that %%$$ {\tt draw\ pic} \descr{box name} $$ %%draws the box contents without the bounding rectangle. Эта операция может также быть усовершенствована макросом {\tt drawunboxed}\index{drawunboxed?\texttt{drawunboxed}}\label{Ddrunbx}, берущим разделенный запятыми список имен рамок. %%This operation can also be accomplished by the {\tt %%drawunboxed}\index{drawunboxed?\texttt{drawunboxed}}\label{Ddrunbx} %%macro that takes a comma-separated list of box names. Есть еще макрос {\tt drawboxes}\index{drawboxes?\texttt{drawboxes}}\label{Ddrbxes}, рисующий только охватывающие прямоугольники. %%There is also a %%{\tt drawboxes}\index{drawboxes?\texttt{drawboxes}}\label{Ddrbxes} macro %%that draws just the bounding rectangles. Другой способ нарисовать пустые прямоугольники --- это просто\label{Deboxit} $$ {\tt boxit} \descr{имя рамки} \hbox{\tt ()} $$ без рисунка-аргумента, как это делалось несколько раз на рис.~\ref{fig49}. %%Another way to draw empty rectangles is by just saying\label{Deboxit} %%$$ {\tt boxit} \descr{box name} \hbox{\tt ()} $$ %%with no picture argument as is done several times in Figure~\ref{fig49}. Это похоже на вызов {\tt boxit} с пустым аргументом. %%This is like calling {\tt boxit} with an empty picture. Кроме того, аргумент может быть строковым\label{Dsboxit} выражением вместо выражения-рисунка и в этом случае строка изображается шрифтом по-умолчанию. %%Alternatively the argument can be a string\label{Dsboxit} expression %%instead of a picture %%expression in which case the string is typeset in the default font. \subsection{Круглые и овальные рамки} %%\subsection{Circular and Oval Boxes} Круговые и овальные рамки во многом похожи на прямоугольные, отличаясь только формой охватывающего пути. %%Circular and oval boxes are a lot like rectangular boxes except for the shape %%of the bounding path. Такие рамки устанавливаются макросом {\tt circleit}\index{circleit?\texttt{circleit}}\label{Dcircit}: $$ {\tt circleit} \descr{имя рамки} \hbox{\tt(} \descr{содержание рамки} \hbox{\tt)}, $$ где \tdescr{имя рамки} --- это суффикс, а \tdescr{содержание рамки} --- это либо выражение-картинка, либо строковое выражение, либо \tdescr{пусто}. %%Such boxes are set up by the %%{\tt circleit}\index{circleit?\texttt{circleit}}\label{Dcircit} macro: %%$$ {\tt circleit} \descr{box name} %% \hbox{\tt(} \descr{box contents} \hbox{\tt)} %%$$ %%where \tdescr{box name} is a suffix and \tdescr{box contents} is either a %%picture expression, a string expression, or \tdescr{empty}. Макрос {\tt circleit} определяет переменные-пары также, как {\tt boxit}, но без угловых точек \tdescr{имя рамки}{\tt.ne}, \tdescr{имя рамки}{\tt.sw} и т.~д. %%The {\tt circleit} macro defines pair variables just as {\tt boxit} does, except %%that there are no corner points \tdescr{box name}{\tt.ne}, %%\tdescr{box name}{\tt.sw}, etc. Вызов $$ \hbox{\tt circleit.a(}\ldots \hbox{\tt )} $$ задает отношения между точками {\tt a.c}, {\tt a.s}, {\tt a.e}, {\tt a.n}, {\tt a.w} и расстояния {\tt a.dx} и {\tt a.dy}. %%A call to %%$$ \hbox{\tt circleit.a(}\ldots \hbox{\tt )} $$ %%gives relationships among points {\tt a.c}, {\tt a.s}, {\tt a.e}, {\tt %%a.n}, {\tt a.w} and distances {\tt a.dx} and {\tt a.dy}. Вместе с {\tt a.c} и {\tt a.off} эти переменные определяют, как картинка центрируется в овале, что можно увидеть на рис.~\ref{fig50}. %%Together with %%{\tt a.c} and {\tt a.off}, these variables describe how the picture is %%centered in an oval as can be seen from the Figure~\ref{fig50}. \begin{figure}[htp] $$ \includegraphics{manfig-ru-50} $$ \caption[Как {\tt circleit}-рисунок соотносится с ассоциированными переменными] {Отношения между заданным {\tt circleit} рисунком и связанными с этим переменными. Рисунок изображен серым прямоугольником.} %%\caption[How a {\tt circleit} picture relates to the associated variables] %% {The relationship between the picture given to {\tt circleit} and the %% associated variables. The picture is indicated by a gray rectangle.} \label{fig50} \end{figure} Макросы {\tt drawboxed}\index{drawboxed?\texttt{drawboxed}}, {\tt drawunboxed}\index{drawunboxed?\texttt{drawunboxed}}, {\tt drawboxes}\index{drawboxes?\texttt{drawboxes}}, {\tt pic}\index{pic?\texttt{pic}} и {\tt bpath}\index{bpath?\texttt{bpath}} работают для рамок {\tt circleit} также как и для рамок {\tt boxit}. %%The {\tt drawboxed}\index{drawboxed?\texttt{drawboxed}}, {\tt %%drawunboxed}\index{drawunboxed?\texttt{drawunboxed}}, {\tt %%drawboxes}\index{drawboxes?\texttt{drawboxes}}, {\tt %%pic}\index{pic?\texttt{pic}}, and {\tt %%bpath}\index{bpath?\texttt{bpath}} macros work for {\tt circleit} boxes %%just as they do for {\tt boxit} boxes. Типовой охватывающий путь для рамки {\tt circleit} достаточно велик для окружения содержимого рамки с маленькими предохраняющими отступами, управляемыми внутренней переменной\index{внутренние переменные}\index{переменные!внутренние} {\tt circmargin}\label{Dcmargin}. %%By default, the boundary path %%for a {\tt circleit} box is a circle large enough to surround the box %%contents with a small safety margin controlled by the internal %%variable\index{internal variables}\index{variables!internal} {\tt %%circmargin}\label{Dcmargin}. Рис.~\ref{fig51} предоставляет базовый пример использования {\tt bpath} с рамками {\tt circleit}. %%Figure~\ref{fig51} gives a basic example %%of the use of {\tt bpath} with {\tt circleit} boxes. \begin{figure}[htbp] $$\begin{verbatim} vardef drawshadowed(text t) = fixsize(t); forsuffixes s=t: fill bpath.s shifted (1pt,-1pt); unfill bpath.s; drawboxed(s); endfor enddef; beginfig(51) circleit.a(btex Box 1 etex); circleit.b(btex Box 2 etex); b.n = a.s - (0,20pt); drawshadowed(a,b); drawarrow a.s -- b.n; endfig; \end{verbatim} \qquad \mathcenter{\includegraphics{manfig-ru-51}} $$ \caption[Код MetaPost и рисунок-результат.] {Код MetaPost и рисунок-результат. Заметьте, что макрос {\tt drawshadowed}, используемый здесь, не входит в макропакет {\tt boxes.mp}.} %%\caption[MetaPost code and the resulting figure.] {MetaPost code and %% the resulting figure. Note that the {\tt drawshadowed} macro %% used here is not part of the {\tt boxes.mp} macro package.} \label{fig51} \index{drawshadowed?\texttt{drawshadowed}} \end{figure} Полный пример рамок {\tt circleit} приводится на рис.~\ref{fig52}. %%A full example of {\tt circleit} boxes appears in Figure~\ref{fig52}. Пути овальной границы вокруг ``Start'' и ``Stop'' соответствуют уравнениям $$ \hbox{\tt aa.dx=aa.dy;} \quad \hbox{\rm и}\quad \hbox{\tt ee.dx=ee.dy} $$ после $$ \hbox{\verb|circleit.ee(btex\strut Stop etex)|} \quad\hbox{\rm и}\quad \hbox{\verb|circleit.ee(btex\strut Stop etex)|}. $$ %%The oval boundary paths around ``Start'' and ``Stop'' are due to the equations %%$$ \hbox{\tt aa.dx=aa.dy;} \quad {\rm and}\quad \hbox{\tt ee.dx=ee.dy} $$ %%after %%$$ \hbox{\verb|circleit.ee(btex\strut Stop etex)|} %% \quad{\rm and}\quad %% \hbox{\verb|circleit.ee(btex\strut Stop etex)|}. %%$$ Общее правило в том, что {\tt bpath.}$c$ выходит круглым, если все $c${\tt.dx}, $c${\tt.dy} и $c\hbox{\tt.dx}-c\hbox{\tt.dy}$ неизвестны. %%The general rule is that {\tt bpath.}$c$ comes out circular if %%$c${\tt.dx}, $c${\tt.dy}, and $c\hbox{\tt.dx}-c\hbox{\tt.dy}$ are all %%unknown. Иначе макросы выбирают достаточно большой овал для вмещения данной картинки с предохраняющими отступами {\tt circmargin}\index{circmargin?\texttt{circmargin}}. %%Otherwise, the macros select an oval big enough to contain the %%given picture with the safety margin {\tt %%circmargin}\index{circmargin?\texttt{circmargin}}. \begin{figure}[htp] $$\hbox{$\begin{verbatim} vardef cuta(suffix a,b) expr p = drawarrow p cutbefore bpath.a cutafter bpath.b; point .5*length p of p enddef; vardef self@# expr p = cuta(@#,@#) @#.c{curl0}..@#.c+p..{curl0}@#.c enddef; beginfig(52); verbatimtex \def\stk#1#2{$\displaystyle{\matrix{#1\cr#2\cr}}$} etex circleit.aa(btex\strut Start etex); aa.dx=aa.dy; circleit.bb(btex \stk B{(a|b)^*a} etex); circleit.cc(btex \stk C{b^*} etex); circleit.dd(btex \stk D{(a|b)^*ab} etex); circleit.ee(btex\strut Stop etex); ee.dx=ee.dy; numeric hsep; bb.c-aa.c = dd.c-bb.c = ee.c-dd.c = (hsep,0); cc.c-bb.c = (0,.8hsep); xpart(ee.e - aa.w) = 3.8in; drawboxed(aa,bb,cc,dd,ee); label.ulft(btex$b$etex, cuta(aa,cc) aa.c{dir50}..cc.c); label.top(btex$b$etex, self.cc(0,30pt)); label.rt(btex$a$etex, cuta(cc,bb) cc.c..bb.c); label.top(btex$a$etex, cuta(aa,bb) aa.c..bb.c); label.llft(btex$a$etex, self.bb(-20pt,-35pt)); label.top(btex$b$etex, cuta(bb,dd) bb.c..dd.c); label.top(btex$b$etex, cuta(dd,ee) dd.c..ee.c); label.lrt(btex$a$etex, cuta(dd,bb) dd.c..{dir140}bb.c); label.bot(btex$a$etex, cuta(ee,bb) ee.c..tension1.3 ..{dir115}bb.c); label.urt(btex$b$etex, cuta(ee,cc) ee.c{(cc.c-ee.c)rotated-15}..cc.c); endfig; \end{verbatim} $} \atop \vcenter{\vskip8pt\hbox{\includegraphics{manfig-ru-52}}} $$ \caption{Код MetaPost и соответствующий рисунок} %%\caption{MetaPost code and the corresponding figure} \label{fig52} \end{figure} \section{Файловые чтение и запись} %%\section{Reading and Writing Files} Доступ к файлам --- это одно из новых свойств, введенное в версию~0.60 языка MetaPost. %%File access was one of the new language features introduced in version~0.60 %%of the MetaPost language. Новый оператор $$ {\tt readfrom}\ \descr{имя файла} $$\index{readfrom?\texttt{readfrom}}\label{Dreadfrom}% возвращает очередную строку из именованного входного файла\index{файлы!чтение}. %%A new operator %%$$ {\tt readfrom}\ \descr{file name} $$\index{readfrom?\texttt{readfrom}}\label{Dreadfrom}% %%returns a string giving the next line of input from the named %%file\index{files!reading}. \tdescr{Имя файла} может быть любым первичным выражением типа строка. %%The \tdescr{file name} can be any primary expression of type string. Если файл закончился или не может читаться, то результат чтения --- это строка из одного нулевого символа. %%If the file has ended or cannot be read, the %%result is a string consisting of a single null character. Макропакет {\tt plain} вводит имя {\tt EOF}\index{EOF?\texttt{EOF}}\label{Deof} для такой строки. %%The preloaded {\tt plain} macro package introduces the name %%{\tt EOF}\index{EOF?\texttt{EOF}}\label{Deof} for this string. После возвращения {\tt EOF} от {\tt readfrom}, следующие чтения этого же файла приведут к его повторному чтению сначала. %%After %%{\tt readfrom} has returned {\tt EOF}, additional reads from the same file %%cause the file to be reread from the start. Все файлы, открытые \ttt{readfrom}, что еще не считаны полностью, закрываются\index{файлы!закрытие} автоматически, когда программа заканчивает выполнение, хотя существует команда $${\tt closefrom}\ \descr{имя файла}$$% \index{closefrom?\texttt{closefrom}}\label{Dclosefrom}% для явного закрытия файлов, открытых {\tt readfrom}. %%All files opened by \ttt{readfrom} that have not completely been read %%yet are closed\index{files!closing} automatically when the program %%terminates, but there exists a command %%$${\tt closefrom}\ \descr{file name}$$% %%\index{closefrom?\texttt{closefrom}}\label{Dclosefrom}% %%to close files opened by {\tt readfrom} explicitly. Разумно явно закрывать файлы, которые не нужно считывать полностью, т.~е. до получения {\tt EOF}, потому что в противном случае такие файлы продолжат использовать внутренние ресурсы и возможно обусловят ошибку \ttt{capacity exceeded!}\footnote{емкость превышена!} %%It is wise to %%manually close files you do not need to read completely (i.e. until {\tt %% EOF} is returned) because otherwise such files will continue to use %%internal resources and perhaps cause a \ttt{capacity exceeded!} error. Противоположностью {\tt readfrom} является команда $$ {\tt write}\ \descr{строковое выражение}\ {\tt to}\ \descr{имя файла} $$% \index{write to?\texttt{write to}}\label{Dwrite}% %%The opposite of {\tt readfrom} is the command %%$$ {\tt write}\ \descr{string expression}\ {\tt to}\ \descr{file name} $$% %%\index{write to?\texttt{write to}}\label{Dwrite}% Она пишет\index{файлы!запись} строку текста в указанный файл вывода, открывая сначала файл, если это нужно. %%This writes\index{files!writing} a line of text to the specified output file, %%opening the file first if necessary. Все такие файлы закрываются\index{файлы!закрытие} автоматически, когда программа завершается. %%All such files are %%closed\index{files!closing} automatically when the program terminates. Они могут быть также закрыты явно использованием {\tt EOF}\index{EOF?\texttt{EOF}} как \tdescr{строкового выражения}. %%They %%can also be closed explicitly by using {\tt EOF}\index{EOF?\texttt{EOF}} %%as the \tdescr{string expression}. Единственный способ узнать была ли команда {\tt write} успешной в закрытии файла и использовании {\tt readfrom} для его просмотра. %%The only way to tell if a {\tt write} %%command has succeeded is to close the file and use {\tt readfrom} to look %%at it. \section{Полезные средства} %%\section{Utility Routines} \index{полезные средства} %%\index{utility routines} \index{mplib?\texttt{mplib}} \index{metapost/base?\texttt{metapost/base}} Этот раздел описывает некоторые полезные средства, включенные в каталог \texttt{mplib} иерархии разработки исходников. %%This section describes some of the utility routines included in the %%\texttt{mplib} directory of the development source hierarchy. Будущие версии этой документации должны содержать больше информации, пока же, пожалуйста, читайте файлы исходников --- большинство из них имеют объяснительные комментарии в начале. %%Future %%versions of this documentation may include more; meanwhile, please read %%the source files, most have explanatory comments at the top. Исходники также включают в дистрибутивы как MetaPost, так и в б\'ольшие \TeX, как правило, в каталог \texttt{texmf/metapost/base}. %%They are %%also included in the MetaPost and larger \TeX\ distributions, typically %%in a \texttt{texmf/metapost/base} directory. \subsection{\texttt{TEX.mp}} \label{dTEX} \index{TEX.mp?\texttt{TEX.mp}} \index{метки с переменным текстом} %%\index{labels, with variable text} \index{строковые выражения, как метки} %%\index{string expressions, as labels} \texttt{TEX.mp} предоставляет способ печатать текст строковых выражений MetaPost. %%\texttt{TEX.mp} provides a way to typeset the text of a MetaPost string %%expression. Предположим, например, что вам нужны метки в форме $n_0$, $n_1$, \ldots, $n_{10}$ по оси $x$. %%Suppose, for example, you need labels of the form $n_0$, %%$n_1$, \ldots, $n_{10}$ across the $x$ axis. Вы можете сделать их с (относительным) удобством с \texttt{TEX.mp}: %%You can do this (relatively) conveniently with \texttt{TEX.mp}, as follows: $$\begin{verbatim} input TEX; beginfig(100) last := 10; for i := 0 upto last: label(TEX("$n_{" & decimal(i) & "}$"), (5mm*i,0)); endfor ... endfig; \end{verbatim} $$ В отличии от этого, базовая команда \texttt{btex} (см. стр.\ \pageref{Dbtex}) печатает текст буквально. %%In contrast, the basic \texttt{btex} command (see p.\ \pageref{Dbtex}) %%typesets verbatim text. Получается, что \texttt{btex~s~etex} печатает литеральный символ `s', а \texttt{TEX(s)} печатает значение текстовой переменной MetaPost~$s$. %%That is, \texttt{btex~s~etex} typesets the %%literal character `s'; \texttt{TEX(s)} typesets the value of the %%MetaPost text variable~$s$. \index{LaTeX?\LaTeX!набор меток с} В версию 0.9 \texttt{TEX.mp} добавлены два дополнительных средства, позволяющие использовать \LaTeX\ для печати меток: \texttt{TEXPRE} и \texttt{TEXPOST}. %%\index{LaTeX?\LaTeX!typesetting labels with} In version 0.9, %%\texttt{TEX.mp} acquired two additional routines to facilitate using %%\LaTeX\ to typeset labels: \texttt{TEXPRE} and \texttt{TEXPOST}. Их значения запоминаются и включаются соответственно перед и после каждого вызова \texttt{TEX}. %%Their %%values are remembered, and included before and after (respectively) each %%call to \texttt{TEX}. Без них каждый вызов \texttt{TEX} печатает совершенно независимо. %%Otherwise, each \texttt{TEX} call is effectively %%typeset independently. Вызовы \texttt{TEX} также не взаимодействуют с использованием {\tt verbatimtex}\index{verbatimtex?\texttt{verbatimtex}} (стр.\ \pageref{Dverbatimtex}). %%\texttt{TEX} calls also do not interfere with %%uses of {\tt verbatimtex}\index{verbatimtex?\texttt{verbatimtex}} (p.\ \pageref{Dverbatimtex}). Вот тот же самый пример, что и выше, но с использованием команд \LaTeX\ \verb|\(| и \verb|\)|: %%Here's the same example as above, using the \LaTeX\ commands \verb|\(| %%and \verb|\)|: $$\begin{verbatim} input TEX; TEXPRE("%&latex" & char(10) & "\documentclass{article}\begin{document}"); TEXPOST("\end{document}"); beginfig(100) last := 10; for i := 0 upto last: label(TEX("\( n_{" & decimal(i) & "} \)"), (5mm*i,0)); endfor ... endfig; \end{verbatim} $$ Объяснения: %%Explanation: \begin{itemize} \item \texttt{\%\&latex} приводит к вызову \LaTeX\ вместо \TeX\ (см. также ниже). %%The \texttt{\%\&latex} causes \LaTeX\ to be invoked instead of \TeX. %%(See below, also.) Основанные на Web2C и MiKTeX дистрибутивы \TeX, как минимум, понимают \texttt{\%\&} спецификацию; см., например, документацию Web2C для деталей, \url{http://tug.org/web2c}. %%Web2C- and MiKTeX-based \TeX\ implementations, at %%least, understand this \texttt{\%\&} specification; see, e.g., the Web2C %%documentation for details, \url{http://tug.org/web2c}. (Информация о том, как делать это же в других системах будет весьма приветствоваться.) %%(Information on %%how to do the same with other systems would be most welcome.) \item \texttt{char(10)} помещает маркер новой строки (десятичный код символа ASCII --- 10) в вывод. %%The \texttt{char(10)} puts a newline (ASCII character code 10, decimal) %%in the output. \item \verb|\documentclass...| --- обычный способ начать документ \LaTeX. %%The \verb|\documentclass...| is the usual way to start a \LaTeX\ %%document. \item Из-за поведения \texttt{mpto} \verb|TEXPOST("\end{document}")| не является строго необходимым, но надежнее его включать. %%The \verb|TEXPOST("\end{document}")| is not strictly necessary, due to %%the behavior of \texttt{mpto}, but it is safer to include it. \end{itemize} К сожалению, инструкции \TeX\ \verb|\special| исчезают в этом процессе. %%Unfortunately, \TeX\ \verb|\special| instructions vanish in this %%process. Поэтому нельзя использовать пакеты, подобные \texttt{xcolor} и \texttt{hyperref}. %%So it is not possible to use packages such as \texttt{xcolor} %%and \texttt{hyperref}. В случае, если вы любопытны, то средства \texttt{TEX.mp} реализуются очень просто: они пишут команды \texttt{btex} во временный файл и затем используют \texttt{scantokens} (стр.\ \pageref{Dscantokens}) для его обработки. %%In case you're curious, these routines are implemented very simply: they %%write \texttt{btex} commands to a temporary file and then use %%\texttt{scantokens} (p.\ \pageref{Dscantokens}) to process it. Механизм \texttt{makempx} (стр.\ \pageref{Dmakempx}) выполняет всю работу по использованию \TeX. %%The %%\texttt{makempx} mechanism (p.\ \pageref{Dmakempx}) does all the work of %%running \TeX. Магические \verb|%&| в первой строке --- это не единственный путь указать на вызов программы, отличной от (plain) \TeX. %%The \verb|%&| magic on the first line is not the only way to specify %%invoking a different program than (plain) \TeX. Здесь проявляется преимущество максимума гибкости: разные конструкции \texttt{TEX} могут использовать разные процессоры \TeX. %%It has the advantage of %%maximum flexibility: different \texttt{TEX} constructs can use different %%\TeX\ processors. Возможны не менее двух других способов: %%But at least two other methods are possible: \begin{itemize} \item Установка переменный среды \texttt{TEX} в \texttt{latex} или в какой-угодно процессор, желаемый для вызова. %%Set the environment variable \texttt{TEX} to \texttt{latex}---or %%whatever processor you want to invoke. (Для работы с фрагментами \ConTeXt\ нужно вызывать \ttt{texexec}.) %%(To handle \ConTeXt\ fragments, %%\ttt{texexec} could be used.) Этот способ удобен, когда пишется сценарий или идет работа над проектом, всегда требующим \texttt{latex}. %%This might be convenient when writing a %%script, or working on a project that always requires \texttt{latex}. \item Вызов MetaPost с опцией командной строки \ttt{-tex=latex} (или другим процессором, конечно). %%Invoke MetaPost with the command-line option \ttt{-tex=latex} (or %%whatever processor, of course). Это может быть полезно в Makefile или при единственном исполнении. %%This might be useful from a Makefile, %%or just a one-off run. \end{itemize} \subsection{\texttt{mproof.tex}} \index{mproof.tex?\texttt{mproof.tex}} \texttt{mproof.tex} --- это средство (plain) \TeX, а не MetaPost. %%\texttt{mproof.tex} is a (plain) \TeX\ routine, not MetaPost at all. Оно печатает гранки вывода MetaPost. %%It writes a proof sheet for MetaPost output. Вызывайте его примерно так: %%Call it like this: $$\hbox{\tt tex mproof {\sl имя-выходного-файла-MetaPost}}$$ %%$$\hbox{\tt tex mproof {\sl MetaPost-output-filename}}$$ Затем работайте с результирующим файлом \texttt{dvi} обычным образом. %%Then process the resulting \texttt{dvi} file as usual. \section{Отладка} %%\section{Debugging} MetaPost унаследовал многие возможности \MF\index{metafont?\MF} для интерактивной отладки, значительная часть которых может лишь вкратце быть упомянута здесь. %%MetaPost inherits from \MF\index{metafont?\MF} numerous facilities for %%interactive debugging, most of which can only be mentioned briefly here. Больше информации по сообщениям об ошибках, отладке, генерации трассирующей информации можно найти в {\sl The\ \MF book} \cite{kn:c}. %%Further information on error messages, debugging, and generating tracing %%information can be found in {\sl The\ \MF book} \cite{kn:c}. Предположим, что ваш входной файл содержит в строке 17 $$ \hbox{\tt draw z1-{}-z2;} $$ без предварительного определения значений {\tt z1} и {\tt z2}. %%Suppose your input file says %%$$ \hbox{\tt draw z1--z2;} $$ %%on line 17 without first giving known values to {\tt z1} and {\tt z2}. Рис.~\ref{errmsg} показывает то, что интерпретатор MetaPost печатает на вашем терминале, когда находит ошибку. %%Figure~\ref{errmsg} shows what the MetaPost interpreter prints on your %%terminal when it finds the error. Собственно сообщение об ошибке --- это строка, начинающаяся с ``{\tt !}'', следующие шесть строк дают контекст, точно показывающий, что читалось с ввода, когда была обнаружена ошибка, а ``{\tt ?}'' на последней строке --- это приглашение для вашего ответа. %%The actual error message is the line %%beginning with ``{\tt !}''; the next six lines give the context that %%shows exactly what input was being read when the error was found; and %%the ``{\tt ?}'' on last line is a prompt for your response. Из-за того, что сообщение об ошибке говорит о неопределенной координате $x$, это значение печатается в первой строке после `{\tt >{}>}''. %%Since the %%error message talks about an undefined $x$~coordinate, this value is %%printed on the first line after the ``{\tt >>}''. В этом случае координата $x$ пары {\tt z1} --- это неизвестная переменная {\tt x1}, поэтому интерпретатор печатает имя переменной {\tt x1} точно также, как если бы в этом месте было сказано\index{show?\texttt{show}} ``{\tt show x1}''. %%In this case the %%$x$~coordinate of {\tt z1} is just the unknown variable {\tt x1}, so the %%interpreter prints the variable name {\tt x1} just as it would if it %%were told to\index{show?\texttt{show}} ``{\tt show x1}'' at this point. \begin{figure}[htp] $$\begin{verbatim} >> x1 ! Undefined x coordinate has been replaced by 0. { --->{ curl1}..{curl1} l.17 draw z1-- z2; ? \end{verbatim} $$ \caption{Пример сообщения об ошибке.} %%\caption{An example of an error message.} \label{errmsg} \end{figure} Листинг контекста может показаться слегка путаным в первый раз, но он по-просту выдает несколько строк текста, показывая, как много из каждой строки было уже считано. %%The context listing may seem a little confusing at first, but it really just %%gives a few lines of text showing how much of each line has been read so far. Каждая строка ввода печатается в две строки, подобные следующим: %%Each line of input is printed on two lines like this: \begin{eqnarray*} \descr{дескриптор}\ \hbox{Уже считанный текст} \\ && \hbox{Текст для считывания} %%\descr{descriptor}\ \hbox{Text read so far} \\ %% && \hbox{Text yet to be read} \end{eqnarray*} \tdescr{Дескриптор} идентифицирует исходник. %%The \tdescr{descriptor} identifies the input source. Это либо номер строки типа ``{\tt l.17}'' для строки 17 текущего файла, либо имя макроса перед ``{\tt ->}'', либо объясняющая фраза в угловых скобках. %%It is either a %%line number like ``{\tt l.17}'' for line 17 of the current file; or it %%can be a macro name followed by ``{\tt ->}''; or it is a descriptive %%phrase in angle brackets. Таким образом, значение листинга контекста на рис.~\ref{errmsg}: интерпретатор только что считал строку 17 входного файла до ``{\tt -{}-}'', раскрытие макроса {\tt -{}-} как раз началось и начальный ``\verb|{|'' возвращен назад, позволяя ввод пользователя до разбора этого знака. %%Thus, the meaning of the context listing in %%Figure~\ref{errmsg} is that the interpreter has just read line 17 of the %%input file up to ``{\tt --},'' the expansion of the {\tt --} macro has %%just started, and the initial ``\verb|{|'' has been reinserted to allow %%for user input before scanning this token. Среди возможных ответов на приглашение {\tt ?} есть такие: %%Among the possible responses to a {\tt ?} prompt are the following: \begin{description} \item[x] прекращает исполнение --- вы можете исправить ваш входной файл и перезапустить MetaPost. %%\item[x] terminates the run so that you can fix your input file and start over. \item[h] печатает подсказку, за которой идет другое {\tt ?}-приглашение. %%\item[h] prints a help message followed by another {\tt ?} prompt. \item[\tdescr{return}] приводит интерпретатор к продолжению работы так хорошо, как он сможет. %%\item[\tdescr{return}] causes the interpreter to proceed as best it can. \item[?] печатает список возможных опций, за которыми следует {\tt ?}-приглашение. %%\item[?] prints a listing of the options available, followed by another %% {\tt ?} prompt. \end{description} Сообщения об ошибках и ответы на команды {\tt show} также печатаются и в файл-дубликат\index{файлы!дубликат}, чье имя получается из имени главного входного файла изменением ``{\tt .mp}'' на ``{\tt .log}''. %%Error messages and responses to {\tt show} commands are also written %%into the transcript\index{files!transcript} file whose name is obtained %%from the name of the main input file by changing ``{\tt .mp}'' to ``{\tt %%.log}''. Когда внутренняя переменная\index{внутренние переменные}\index{переменные!внутренние} {\tt tracingonline}\index{tracingonline?\texttt{tracingonline}} имеет исходное значение ноль, то некоторые команды {\tt show} печатают свои результаты во всех деталях только в файл-дубликат. %%When the internal variable\index{internal %%variables}\index{variables!internal} {\tt %%tracingonline}\index{tracingonline?\texttt{tracingonline}} is at its %%default value of zero, some {\tt show} commands print their results in %%full detail only in the transcript file. Только один тип команды {\tt show}\index{show?\texttt{show}} обсуждался до сих пор: {\tt show} с разделенным запятыми списком выражений печатает символьное представление этих выражений. %%Only one type of {\tt show}\index{show?\texttt{show}} command has been %%discussed so far: {\tt show} followed by a comma-separated list of %%expressions prints symbolic representations of the expressions. Команда {\tt showtoken}\index{showtoken?\texttt{showtoken}}\label{Dshtok} может быть использована для показа параметров и текста замены макроса. %%The {\tt showtoken}\index{showtoken?\texttt{showtoken}}\label{Dshtok} %%command can be used to show the %%parameters and replacement text of a macro. Она берет разделенный запятыми список знаков и идентифицирует каждый из них. %%It takes a comma-separated list of tokens and identifies each one. Если знак --- это примитив, например, ``\verb|showtoken +|'', то он по-просту идентифицируется собой: $$ \hbox{\verb|> +=+|} $$ %%If the token is a primitive as in %%``\verb|showtoken +|'' it is just identified as being itself: %%$$ \hbox{\verb|> +=+|} $$ Применение {\tt showtoken} к переменной или {\tt vardef}-макросу приведет к $$ \hbox{\tt > } \descr{знак}\hbox{\tt =variable} $$ %%Applying {\tt showtoken} to a variable or a {\tt vardef} macro yields %%$$ \hbox{\tt > } \descr{token}\hbox{\tt =variable} $$ Для получения дополнительной информации о переменной используйте {\tt showvariable}\index{showvariable?\texttt{showvariable}}\label{Dshvar} вместо {\tt showtoken}. %%To get more information about a variable, use %%{\tt showvariable}\index{showvariable?\texttt{showvariable}}\label{Dshvar} %%instead of {\tt showtoken}. Аргумент к {\tt showvariable} --- это разделенный запятыми список символических знаков, а ее результат --- это описание всех переменных, чьи имена начинаются с одного из знаков из списка. %%The %%argument to {\tt showvariable} is a comma-separated list of symbolic tokens %%and the result is a description of all the variables whose names begin with %%one of the listed tokens. Это работает даже для vardef-макросов. %%This even works for {\tt vardef} macros. Например, {\tt showvariable z} печатает $$ \hbox{\verb|z@#=macro:->begingroup(x(SUFFIX2),y(SUFFIX2))endgroup|} $$ %%For example, {\tt showvariable z} yields %%$$ \hbox{\verb|z@#=macro:->begingroup(x(SUFFIX2),y(SUFFIX2))endgroup|} $$ Есть еще команда {\tt showdependencies}\index{showdependencies?\texttt{showdependencies}}\label{Dshdep}, не имеющая аргументов и печатающая список всех {\em зависимых} переменных и то, как линейные уравнения заданные ранее делают их зависимыми с другими переменными. %%There is also a {\tt %%showdependencies}\index{showdependencies?\texttt{showdependencies}}\label{Dshdep} %%command that takes no arguments and prints a list of all {\em dependent} %%variables and how the linear equations given so far make them depend on %%other variables. Таким образом, после $$ \hbox{\tt z2-z1=(5,10); z1+z2=(a,b);} $$ {\tt showdependencies} напечатает то, что показано на рис.~\ref{shdep}. %%Thus after %%$$ \hbox{\tt z2-z1=(5,10); z1+z2=(a,b);} $$ %%{\tt showdependencies} prints what is shown in Figure~\ref{shdep}. Это может быть полезным при ответе на вопрос типа ``Что значит, что `{\tt !\ Undefined x coordinate}?'\footnote{Координата x --- неопределена} --- я думаю, что приведенные ранее уравнения определяют {\tt x1}.'' %%This could %%be useful in answering a question like ``What does it mean %%`{\tt !\ Undefined x coordinate}?' %%I thought the equations given so far would determine {\tt x1}.'' \begin{figure}[htp] $$\begin{verbatim} x2=0.5a+2.5 y2=0.5b+5 x1=0.5a-2.5 y1=0.5b-5 \end{verbatim} $$ \caption{Результат {\tt z2-z1=(5,10); z1+z2=(a,b); showdependencies;}} %%\caption{The result of {\tt z2-z1=(5,10); z1+z2=(a,b); showdependencies;}} \label{shdep} \end{figure} Если все это не приводит к успеху, то есть еще предопределенный макрос {\tt tracingall}\index{tracingall?\texttt{tracingall}}\label{Dtall}, приводящий интерпретатор к печати детального отчета обо всем, что он делает. %%When all else fails, the predefined macro {\tt %%tracingall}\index{tracingall?\texttt{tracingall}}\label{Dtall} causes %%the interpreter to print a detailed listing of everything it is doing. Вследствие того, что трассирующая информация часто имеет весьма большой размер, возможно будет лучше использовать макрос {\tt loggingall}\index{loggingall?\texttt{loggingall}}\label{Dlogall}, производящий ту же самую информацию, но только для записи в файл-дубликат\index{файлы!дубликат}. %%Since the tracing information is often quite voluminous, it may be %%better to use the {\tt %%loggingall}\index{loggingall?\texttt{loggingall}}\label{Dlogall} macro %%that produces the same information but only writes it in the %%transcript\index{files!transcript} file. Есть еще макрос {\tt tracingnone}\index{tracingnone?\texttt{tracingnone}}\label{Dtnone}, отключающий все распечатки по трассировке. %%There is also a {\tt %%tracingnone}\index{tracingnone?\texttt{tracingnone}}\label{Dtnone} macro %%that turns off all the tracing output. Вывод трассировки контролируется множеством внутренних переменных\index{внутренние переменные}\index{переменные!внутренние}, приводимых далее. %%Tracing output is controlled by the set of internal %%variables\index{internal variables}\index{variables!internal} summarized %%below. Когда любой из этих переменных задают положительное значение, то этим устанавливается соответствующая форма трассировки. %%When any one of these variables is given a positive value, the %%corresponding form of tracing is turned on. Здесь приведено множество переменных трассировки и то, что случается, когда каждая из них становится положительной. %%Here is the set of tracing %%variables and what happens when each of them is positive: \begin{description} \item[{\tt tracingcapsules}]\index{tracingcapsules?\texttt{tracingcapsules}}\label{Dtcapsules}% показывает значения временных количеств (капсул), когда они становятся известными. %%\item[{\tt tracingcapsules}]\index{tracingcapsules?\texttt{tracingcapsules}}\label{Dtcapsules}% %%shows the values of temporary quantities (capsules) when they become known. % \item[{\tt tracingchoices}]\index{tracingchoices?\texttt{tracingchoices}}\label{Dtchoices}% показывает контрольные точки Безье\index{управляющие точки} на каждом пути, где они выбираются. % %%\item[{\tt tracingchoices}]\index{tracingchoices?\texttt{tracingchoices}}\label{Dtchoices}% %%shows the B\'ezier control\index{control points} points of each new path %%when they are chosen. % \item[{\tt tracingcommands}]\index{tracingcommands?\texttt{tracingcommands}}\label{Dtcommands}% показывает команды перед их выполнением. Установка в ${}>1$ также покажет проверки {\tt if}\index{if?\texttt{if}} и циклы до их раскрытия; установка в ${}>2$ покажет алгебраические операции до их выполнения. %%\item[{\tt tracingcommands}]\index{tracingcommands?\texttt{tracingcommands}}\label{Dtcommands}% %%shows the commands before they are performed. A setting ${}>1$ also shows %%{\tt if}\index{if?\texttt{if}} tests and loops before they are expanded; %%a setting ${}>2$ shows algebraic operations before they are performed. % \item[{\tt tracingequations}]\index{tracingequations?\texttt{tracingequations}}\label{Dtequations}% показывает каждую переменную, когда она становится известной. %%\item[{\tt %%tracingequations}]\index{tracingequations?\texttt{tracingequations}}\label{Dtequations}% %%shows each variable when it becomes known. % \item[{\tt tracinglostchars}]\index{tracinglostchars?\texttt{tracinglostchars}}\label{Dtlostchars}% предупреждает о символах, отсутствующих в картинке, из-за их отсутствия в шрифте, используемом для печати меток. %%\item[{\tt tracinglostchars}]\index{tracinglostchars?\texttt{tracinglostchars}}\label{Dtlostchars}% %%warns about characters omitted from a picture because they are not in the font %%being used to typeset labels. % \item[{\tt tracingmacros}]\index{tracingmacros?\texttt{tracingmacros}}\label{Dtmacros}% печатает макросы до их раскрытия. %%\item[{\tt tracingmacros}]\index{tracingmacros?\texttt{tracingmacros}}\label{Dtmacros}% %%shows macros before they are expanded. % \item[{\tt tracingoutput}]\index{tracingoutput?\texttt{tracingoutput}}\label{Dtoutput}% печатает картинки при их отправке в PostScript-файлы. %%\item[{\tt tracingoutput}]\index{tracingoutput?\texttt{tracingoutput}}\label{Dtoutput}% %%shows pictures as they are being shipped out as PostScript files. % \item[{\tt tracingrestores}]\index{tracingrestores?\texttt{tracingrestores}}\label{Dtrestores}% показывает символы и внутренние переменные при их восстановлении в конце группы. %%\item[{\tt tracingrestores}]\index{tracingrestores?\texttt{tracingrestores}}\label{Dtrestores}% %%shows symbols and internal variables as they are being restored at the end %%of a group. % \item[{\tt tracingspecs}]\index{tracingspecs?\texttt{tracingspecs}}\label{Dtspecs}% показывает выделения, генерируемые при рисовании многоугольным пером\index{перья!многоугольные}. %%\item[{\tt tracingspecs}]\index{tracingspecs?\texttt{tracingspecs}}\label{Dtspecs}% %%shows the outlines generated when drawing with a %%polygonal pen\index{pens!polygonal}. % \item[{\tt tracingstats}]\index{tracingstats?\texttt{tracingstats}}\label{Dtstats} в конце работы печатает в файл-дубликат о том, как много ограниченных ресурсов интерпретатора MetaPost было использовано. %%\item[{\tt tracingstats}]\index{tracingstats?\texttt{tracingstats}}\label{Dtstats} %%shows in the transcript file at the end of the job how many of the %%MetaPost interpreter's limited resources were used. \end{description} \section*{Признательность} %%\section*{Acknowledgement} Я рад поблагодарить Дональда Кнута за возможность проделать эту работу --- за развитие \MF\ и помещения его в открытый доступ. %%I would like to thank Don Knuth for making this work possible by %%developing \MF\ and placing it in the public domain. Я также в долгу перед ним за полезные предложения, особенно в связи с обработкой включаемого материала \TeX. %%I am also indebted %%to him for helpful suggestions, particularly with regard to the %%treatment of included \TeX\ material. \appendix \section{Справочное руководство} %%\section{Reference Manual} \let\svtopfrac=\topfraction % prepare to restore values at end of this appendix \let\svtxtfrac=\textfraction % grouping would fail because \setcounter is global \newcounter{svtopnum} \newcounter{svtotnum} \setcounter{svtopnum}{\value{topnumber}} \setcounter{svtotnum}{\value{totalnumber}} \renewcommand\topfraction{1.0} % set values to allow *lots* of figures and tables \renewcommand\textfraction{0.0} \setcounter{topnumber}{10} \setcounter{totalnumber}{10} Таблицы \ref{ivartab}--\ref{pseudotab} суммируют встроенные возможности Plain MetaPost и возможности, определенные в файле с макросами {\tt boxes.mp}\index{boxes.mp?\texttt{boxes.mp}}. %%Tables \ref{ivartab}--\ref{pseudotab} summarize the built-in features of %%Plain MetaPost and the features defined in the {\tt %%boxes.mp}\index{boxes.mp?\texttt{boxes.mp}} macro file. Как объяснялось в разделе ~\ref{boxessec}, файл с макросами {\tt boxes.mp} не включается автоматически и макросы из него недоступны до тех пор, пока вы не запросите их командой\index{input?\texttt{input}} $$ \hbox{\tt input boxes} $$ %%As explained in %%Section~\ref{boxessec}, the {\tt boxes.mp} macro file is not %%automatically preloaded and the macros defined there are not accessible %%until you ask for them via the command\index{input?\texttt{input}} %%$$ \hbox{\tt input boxes} $$ Возможности, зависящие от {\tt boxes.mp} отмечены символами \bx. %%Features that depend on {\tt boxes.mp} are marked by \bx\ symbols. Возможности из макропакета Plain\index{макросы Plain} отмечены символами \pl, а примитивы MetaPost приводятся без \bx\ или \pl. %%Features from the Plain\index{Plain macros} macro package are marked by %%\pl\ symbols, and MetaPost primitives are not marked by \bx\ or \pl. Разница между примитивами и макросами из plain может игнорироваться случайным пользователем, но важно помнить, что возможности с меткой \bx\ могут быть использованы только после чтения файла {\tt boxes.mp}\index{boxes.mp?\texttt{boxes.mp}} с макросами. %%The distinction between primitives and plain macros can be ignored by %%the casual user, but it is important to remember that features marked by %%a \bx\ can only be used after reading in the {\tt %%boxes.mp}\index{boxes.mp?\texttt{boxes.mp}} macro file. Таблицы в этом приложении приводят имя каждой возможности, номер страницы, где она объясняется, и краткое описание. %%The tables in this appendix give the name of each feature, the page %%number where it is explained, and a short description. Небольшое число свойств нигде не объяснялось и они не имеют номеров страниц. %%A few features %%are not explained elsewhere and have no page number listed. Эти возможности существуют, в основном, для совместимости с \MF\index{metafont?\MF} и предполагаются самообъясняющими. %%These %%features exist primarily for compatibility with \MF\index{metafont?\MF} %%and are intended to be self-explanatory. Некоторые определенные возможности \MF\ полностью отсутствуют из-за ограниченного интереса к ним пользователей MetaPost и/или из-за требуемых длинных объяснений. %%Certain other features from %%\MF\ are omitted entirely because they are of limited interest to the %%MetaPost users and/or would require long explanations. Все они документированы в {\sl The \MF book} \cite{kn:c} как объяснено в приложении~\ref{MPvsMF}. %%All of these are %%documented in {\sl The \MF book} \cite{kn:c} as explained in %%Appendix~\ref{MPvsMF}. Таблица~\ref{ivartab} перечисляет внутренние переменные с числовыми значениями. %%Table~\ref{ivartab} lists internal variables that take on numeric values. Таблица~\ref{pvartab} перечисляет предопределенные переменные других типов. %%Table~\ref{pvartab} lists predefined variables of other types. Таблица~\ref{consttab} перечисляет предопределенные константы. %%Table~\ref{consttab} lists predefined constants. Некоторые из них реализованы как переменные, чьи значения предполагается не менять. %%Some of these are implemented %%as variables whose values are intended to be left unchanged. Таблица~\ref{optab} приводит операторы MetaPost и перечисляет возможные типы для аргументов и результата каждого из них. %%Table~\ref{optab} summarizes MetaPost operators and lists %%the possible argument and result types for each one. Пункт ``--'' для левого аргумента задает унарный оператор, а ``--'' для обоих задает оператор без аргументов. %%A ``--'' entry for %%the left argument indicates a unary operator; ``--'' entries for both %%arguments indicate a nullary operator. Операторы с параметрами-суффиксами не приводятся в этой таблице, потому что они обрабатываются как ``похожие на функции макросы''. %%Operators that take suffix %%parameters are not listed in this table because they are treated as %%``function-like macros''. Две последние таблицы --- это таблица~\ref{cmdtab} для команд и таблица~\ref{pseudotab} для макросов, ведущих себя как функции или процедуры. %%The last two tables are Table~\ref{cmdtab} for commands and %%Table~\ref{pseudotab} macros that behave like functions or procedures. Такие макросы берут списки аргументов в скобках и/или параметры-суффиксы и возвращают либо значение приведенного в таблице типа, либо ничего. %%Such macros take parenthesized argument lists and/or suffix parameters, %%returning either a value whose type is listed in the table, or nothing. Последний случай для макросов, ведущих себя как процедуры. %%The latter case is for macros that behave like procedures. Их возвращаемые значения приводится как ``--''. %%Their return values are listed as ``--''. Картинки в этом приложении представляют синтаксис языка MetaPost, начиная с выражений на рисунках \ref{syexpr1}--\ref{sypseudo}. %%The figures in this appendix present the syntax of the MetaPost language %%starting with expressions in Figures \ref{syexpr1}--\ref{sypseudo}. Хотя правила иногда указывают типы для выражений, первичностей, вторичностей и третичностей, но отдельный синтаксис для \tdescr{числового выражения}, \tdescr{выражения-пары} и т.~п. не приводится. %%Although the productions sometimes specify types for expressions, primaries, %%secondaries, and tertiaries, no attempt is made to give separate syntaxes %%for \tdescr{numeric expression}, \tdescr{pair expression}, etc. Своей простоте правила на рис.~\ref{sytypexpr} обязаны этим отсутствием информации о типах. %%The simplicity of the productions in Figure~\ref{sytypexpr} is due to this %%lack of type information. Информация о типах может быть найдена в таблицах \ref{ivartab}--\ref{pseudotab}. %%Type information can be found in Tables \ref{ivartab}--\ref{pseudotab}. Рисунки \ref{syprog} и \ref{sycmds} содержат синтаксис программ MetaPost, включая команды и их обобщения. %%Figures \ref{syprog} and \ref{sycmds} give the syntax for MetaPost programs, %%including statements and commands. Они не упоминают циклов\index{циклы} и проверок {\tt if}\index{if?\texttt{if}}, потому что эти конструкции не ведут себя как команды. %%They do not mention loops\index{loops} %%and {\tt if}\index{if?\texttt{if}} %%tests because these constructions do not behave like statements. Синтаксис на рисунках \ref{syexpr1}--\ref{sycondloop} применим к результатам раскрытия всех условных конструкций и циклов. %%The syntax %%given in Figures \ref{syexpr1}--\ref{sycondloop} applies to the result of %%expanding all conditionals and loops. Условные конструкции и циклы имеют синтаксис, но они работают практически с произвольными последовательностями знаков. %%Conditionals and loops do have a %%syntax, but they deal with almost arbitrary sequences of tokens. Рис.~\ref{sycondloop} определяет условные конструкции через \tdescr{сбалансированные знаки}, а циклы через \tdescr{тело цикла}, где \tdescr{сбалансированные знаки} --- это любая последовательность знаков, сбалансированная относительно {\tt if} и {\tt fi}, а \tdescr{тело цикла} --- это последовательность знаков, сбалансированная относительно {\tt for}, {\tt forsuffixes}, {\tt forever} и {\tt endfor}. %%Figure~\ref{sycondloop} specifies conditionals in terms of %%\tdescr{balanced tokens} and loops in terms of \tdescr{loop text}, where %%\tdescr{balanced tokens} is any sequence of tokens balanced with respect %%to {\tt if} and {\tt fi}, and \tdescr{loop text} is a sequence of tokens %%balanced with respect to {\tt for}, {\tt forsuffixes}, {\tt forever}, %%and {\tt endfor}. \begin{table}[htp] \caption{Внутренние переменные с числовыми значениями} %%\caption{Internal variables with numeric values} $$\begin{tabular}{|l|r|l|} \hline \multicolumn1{|c}{Имя}& \multicolumn1{|c}{Стр.}& \multicolumn1{|c|}{Описание}\\ %%\multicolumn1{|c}{Name}& \multicolumn1{|c}{Page}& \multicolumn1{|c|}{Explanation}\\ \hline \hline \pl\tt ahangle& \pageref{Dahangle}& угол для наконечника стрелки в градусах (стандартно 45)\\\hline %% angle for arrowheads in degrees (default: 45)\\\hline \pl\tt ahlength& \pageref{Dahlength}& размер наконечника стрелки (стд. 4{\tt bp})\\\hline %% size of arrowheads (default: 4{\tt bp})\\\hline \pl\tt bboxmargin& \pageref{Dbbmargin}& особый промежуток, допускаемый {\tt bbox} (стд. 2{\tt bp})\\\hline %% extra space allowed by {\tt bbox} (default 2{\tt bp})\\\hline \tt charcode& \pageref{Dcharcode}& номер текущей картинки\\\hline %% the number of the current figure\\\hline \bx\tt circmargin& \pageref{Dcmargin}& пустота вокруг содержимого круговой или овальной рамки\\\hline %% clearance around contents of a circular or oval box\\\hline \tt day& --& текущий день месяца\\\hline %% the current day of the month\\\hline \tt defaultcolormodel& --& начальная цветовая модель (стд. 5, rgb)\\\hline %% the initial color model (default: 5, rgb)\\\hline \bx\tt defaultdx& \pageref{Ddefaultdx}& обычный гориз. отступ вокруг содержимого рамки (стд. 3{\tt bp})\\\hline %% usual horizontal space around box contents (default 3{\tt bp})\\\hline \bx\tt defaultdy& \pageref{Ddefaultdy}& обычный верт. отступ вокруг содержимого рамки (стд. 3{\tt bp})\\\hline %% usual vertical space around box contents (default 3{\tt bp})\\\hline \pl\tt defaultpen& \pageref{Ddefaultpen}& число, используемое {\tt pickup} для выбора стд. пера\\\hline %% numeric index used by {\tt pickup} to select default pen\\\hline \pl\tt defaultscale& \pageref{Ddfscale}& масштабирующий множитель шрифта для строк-меток (стд. 1)\\\hline %% font scale factor for label strings (default 1)\\\hline \pl\tt labeloffset& \pageref{Dlaboff}& расстояние отступа для меток (стд. 3{\tt bp})\\\hline %% offset distance for labels (default 3{\tt bp})\\\hline \tt linecap& \pageref{Dlinecap}& 0 для butt, 1 для round, 2 для square\\\hline %% 0 for butt, 1 for round, 2 for square\\\hline \tt linejoin& \pageref{Dlinejoin}& 0 для mitered, 1 для round, 2 для beveled\\\hline %% 0 for mitered, 1 for round, 2 for beveled\\\hline \tt miterlimit& \pageref{Dmiterlim}& контролирует длину острия как в PostScript\\\hline %% controls miter length as in PostScript\\\hline \tt month& --& текущий месяц (например, 3 $\equiv$ Март)\\\hline %% the current month (e.g, 3 $\equiv$ March)\\\hline \tt mpprocset& --& \vtop{\hbox{установите в~1, если хотите включить словарь сокращений}\hbox{PostScript в вывод}}\\\hline %% \vtop{\hbox{set this to~1 if you want to include a PostScript %%dictionary}\hbox{of abbreviations in the output}}\\\hline \tt pausing& --& ${}>0$ --- показывать строки на терминале до их чтения\\\hline %% ${}>0$ to display lines on the terminal before they are read\\\hline \tt prologues& \pageref{Dprologues}& ${}>0$ --- выводить PostScript с встроенными шрифтами\\\hline %% ${}>0$ to output conforming PostScript using built-in fonts\\\hline \tt restoreclipcolor& --& восстановление состояния графики после вырезки (стд. 1)\\\hline %% restore the graphics state after clip operations (default: 1)\\\hline \tt showstopping& --& ${}>0$ --- останавливать после каждой команды {\tt show}\\\hline %% ${}>0$ to stop after each {\tt show} command\\\hline \tt time& --& число минут после полуночи в начале этой работы\\\hline %% the number of minutes past midnight when this job started\\\hline \tt tracingcapsules& \pageref{Dtcapsules}& ${}>0$ --- показывать и капсулы\\\hline %% ${}>0$ to show capsules too\\\hline \tt tracingchoices& \pageref{Dtchoices}& ${}>0$ --- показывать контрольные точки для путей\\\hline %% ${}>0$ to show the control points chosen for paths\\\hline \tt tracingcommands& \pageref{Dtcommands}& ${}>0$ --- показывать команды при их выполнении\\\hline %% ${}>0$ to show commands and operations as they are performed\\\hline \tt tracingequations& \pageref{Dtequations}& ${}>0$ --- показывать каждую ставшую известной переменную\\\hline %% ${}>0$ to show each variable when it becomes known\\\hline \tt tracinglostchars& \pageref{Dtlostchars}& ${}>0$ --- показывать символы не из {\tt infont}\\\hline %% ${}>0$ to show characters that aren't {\tt infont}\\\hline \tt tracingmacros& \pageref{Dtmacros}& ${}>0$ --- показывать макросы до их раскрытия\\\hline %% ${}>0$ to show macros before they are expanded\\\hline \tt tracingonline& \pageref{Dtonline}& ${}>0$ --- показывать длинные диагностики на терминале\\\hline %% ${}>0$ to show long diagnostics on the terminal\\\hline \tt tracingoutput& \pageref{Dtoutput}& ${}>0$ --- показывать цифровые края при выводе\\\hline %% ${}>0$ to show digitized edges as they are output\\\hline \tt tracingrestores& \pageref{Dtrestores}& ${}>0$ --- показывать переменные при их восстановлении\\\hline %% ${}>0$ to show when a variable or internal is restored\\\hline \tt tracingspecs& \pageref{Dtspecs}& ${}>0$ --- показывать деления пути (исп-ся многоугольное перо)\\\hline %% ${}>0$ to show path subdivision when using a polygonal a pen\\\hline \tt tracingstats& \pageref{Dtstats}& ${}>0$ --- показывать использование памяти в конце работы\\\hline %% ${}>0$ to show memory usage at end of job\\\hline \tt tracingtitles& --& ${}>0$ --- показывать заголовки при их появлении\\\hline %% ${}>0$ to show titles online when they appear\\\hline \tt troffmode& \pageref{Dtroffmode}& будет~1, если есть опция {\tt -troff} или {\tt -T}\\\hline %% set to~1 if a {\tt -troff} or {\tt -T} option was given\\\hline \tt truecorners& \pageref{Dtruecorn}& ${}>0$ --- делать {\tt llcorner} и т.~д., игнорировать {\tt setbounds}\\\hline %% ${}>0$ to make {\tt llcorner} etc. ignore {\tt setbounds}\\\hline \tt warningcheck& \pageref{Dwarncheck}& сообщение об ошибке при большом значении переменной\\\hline %% controls error message when variable value is large\\\hline \tt year& --& текущий год (например, 1992)\\\hline %% the current year (e.g., 1992)\\\hline \end{tabular} $$ \label{ivartab}% \index{day?\texttt{day}}\index{month?\texttt{month}}\index{pausing?\texttt{pausing}}\index{showstopping?\texttt{showstopping}}% \index{time?\texttt{time}}\index{tracingtitles?\texttt{tracingtitles}}\index{year?\texttt{year}} \end{table} \begin{table}[htp] \caption{Другие предопределенные переменные} %%\caption{Other Predefined Variables} $$\begin{tabular}{|l|l|r|l|} \hline \multicolumn1{|c}{Имя}& \multicolumn1{|c}{Тип}& \multicolumn1{|c}{Стр.}& \multicolumn1{|c|}{Объяснение}\\ %%\multicolumn1{|c}{Name}& \multicolumn1{|c}{Type}& \multicolumn1{|c}{Page}& %% \multicolumn1{|c|}{Explanation}\\ \hline \hline \pl\tt background& color& \pageref{Dbground}& Цвет для {\tt unfill} и {\tt undraw} (обычно белый)\\\hline %% Color for {\tt unfill} and {\tt undraw} (usually white)\\\hline \pl\tt currentpen& pen& \pageref{Dcurpen}& Текущее перо (для команды {\tt draw})\\\hline %% Last pen picked up (for use by the {\tt draw} command)\\\hline \pl\tt currentpicture& picture& \pageref{Dcurpic}& Результат команд {\tt draw} и {\tt fill}\\\hline %% Accumulate results of {\tt draw} and {\tt fill} commands\\\hline \pl\tt cuttings& path& \pageref{Dcuttings}& Подпуть, отрезанный последней {\tt cutbefore} или {\tt cutafter}\\\hline %% subpath cut off by last {\tt cutbefore} or {\tt cutafter}\\\hline \pl\tt defaultfont& string& \pageref{Ddffont}& Шрифт для команд печати строк\\\hline %% Font used by label commands for typesetting strings\\\hline \pl\tt extra\_beginfig& string& \pageref{Dxbfig}& Дополнительные команды для {\tt beginfig}\\\hline %% Commands for {\tt beginfig} to scan\\\hline \pl\tt extra\_endfig& string& \pageref{Dxefig}& Дополнительные команды для {\tt endfig}\\\hline %% Commands for {\tt endfig} to scan\\\hline \end{tabular} $$ \label{pvartab} \end{table} \begin{table}[htp] \caption{Предопределенные константы} %%\caption{Predefined Constants} $$\begin{tabular}{|l|l|r|l|} \hline \multicolumn1{|c}{Имя}& \multicolumn1{|c}{Тип}& \multicolumn1{|c}{Стр.}& \multicolumn1{|c|}{Объяснение}\\ %%\multicolumn1{|c}{Name}& \multicolumn1{|c}{Type}& \multicolumn1{|c}{Page}& %% \multicolumn1{|c|}{Explanation}\\ \hline \hline \pl\tt beveled& numeric& \pageref{Dbvled}& Значение {\tt linejoin} для срезанных соединений [2]\\\hline %%\pl\tt beveled& numeric& \pageref{Dbvled}& %% {\tt linejoin} value for beveled joins [2]\\\hline \pl\tt black& color& \pageref{Dblack}& Эквивалентно {\tt (0,0,0)}\\\hline %%\pl\tt black& color& \pageref{Dblack}& %% Equivalent to {\tt (0,0,0)}\\\hline \pl\tt blue& color& \pageref{Dblue}& Эквивалентно {\tt (0,0,1)}\\\hline %%\pl\tt blue& color& \pageref{Dblue}& %% Equivalent to {\tt (0,0,1)}\\\hline \pl\tt bp& numeric& \pageref{Dbp}& Один пункт PostScript в {\tt bp}-единицах [1]\\\hline %%\pl\tt bp& numeric& \pageref{Dbp}& %% One PostScript point in {\tt bp} units [1]\\\hline \pl\tt butt& numeric& \pageref{Dbutt}& Значение {\tt linecap} для butt-конца [0]\\\hline %%\pl\tt butt& numeric& \pageref{Dbutt}& %% {\tt linecap} value for butt end caps [0]\\\hline \pl\tt cc& numeric& --& Одна единица цицеро в {\tt bp}-единицах [12.79213]\\\hline %%\pl\tt cc& numeric& --& %% One cicero in {\tt bp} units [12.79213]\\\hline \pl\tt cm& numeric& \pageref{Dcm}& Один сантиметр в {\tt bp}-единицах [28.34645]\\\hline %%\pl\tt cm& numeric& \pageref{Dcm}& %% One centimeter in {\tt bp} units [28.34645]\\\hline \pl\tt dd& numeric& --& Один дидот в {\tt bp}-единицах [1.06601]\\\hline %%\pl\tt dd& numeric& --& %% One didot point in {\tt bp} units [1.06601]\\\hline \pl\tt ditto& string& --& Строка {\tt \qq} длины 1\\\hline %%\pl\tt ditto& string& --& %% The {\tt \qq} character as a string of length 1\\\hline \pl\tt down& pair& \pageref{Ddown}& Вектор вниз $(0,-1)$\\\hline %%\pl\tt down& pair& \pageref{Ddown}& %% Downward direction vector $(0,-1)$\\\hline \pl\tt epsilon& numeric& --& Наименьшее положительное число MetaPost [$1\over65536$]\\\hline %%\pl\tt epsilon& numeric& --& %% Smallest positive MetaPost number [$1\over65536$]\\\hline \pl\tt evenly& picture& \pageref{Devenly}& Образец пунктира из тире и равных промежутков\\\hline %%\pl\tt evenly& picture& \pageref{Devenly}& %% Dash pattern for equal length dashes\\\hline \pl\tt EOF& string& \pageref{Deof}& Одиночный нулевой символ\\\hline %%\pl\tt EOF& string& \pageref{Deof}& %% Single null character\\\hline \tt false& boolean& \pageref{Dfalse}& Логическое значение {\it false\/}\\\hline %%\tt false& boolean& \pageref{Dfalse}& %% The boolean value {\it false\/}\\\hline \pl\tt fullcircle& path& \pageref{Dfcirc}& Окружность диаметра 1 с центром в $(0,0)$\\\hline %%\pl\tt fullcircle& path& \pageref{Dfcirc}& %% Circle of diameter 1 centered on $(0,0)$\\\hline \pl\tt green& color& \pageref{Dgreen}& Эквивалентно {\tt (0,1,0)}\\\hline %%\pl\tt green& color& \pageref{Dgreen}& %% Equivalent to {\tt (0,1,0)}\\\hline \pl\tt halfcircle& path& \pageref{Dhcirc}& Верхняя полуокружность диаметра 1\\\hline %%\pl\tt halfcircle& path& \pageref{Dhcirc}& %% Upper half of a circle of diameter 1\\\hline \pl\tt identity& transform& \pageref{Dident}& Тождественная трансформация\\\hline %%\pl\tt identity& transform& \pageref{Dident}& %% Identity transformation\\\hline \pl\tt in& numeric& \pageref{Din}& Один дюйм в {\tt bp}-единицах [72]\\\hline %%\pl\tt in& numeric& \pageref{Din}& %% One inch in {\tt bp} units [72]\\\hline \pl\tt infinity& numeric& \pageref{Dinf}& Наибольшее положительное значение [4095.99998]\\\hline %%\pl\tt infinity& numeric& \pageref{Dinf}& %% Large positive value [4095.99998]\\\hline \pl\tt left& pair& \pageref{Dleft}& Направление влево $(-1,0)$\\\hline %%\pl\tt left& pair& \pageref{Dleft}& %% Leftward direction $(-1,0)$\\\hline \pl\tt mitered& numeric& \pageref{Dmitred}& Значение {\tt linejoin} для ``острых'' соединений [0]\\\hline %%\pl\tt mitered& numeric& \pageref{Dmitred}& %% {\tt linejoin} value for mitered joins [0]\\\hline \pl\tt mm& numeric& \pageref{Dmm}& Один миллиметр в {\tt bp}-единицах [2.83464]\\\hline %%\pl\tt mm& numeric& \pageref{Dmm}& %% One millimeter in {\tt bp} units [2.83464]\\\hline \tt mpversion& string& \pageref{Dmpversion}& Номер версии MetaPost\\\hline %%\tt mpversion& string& \pageref{Dmpversion}& %% MetaPost version number\\\hline \tt nullpen& pen& \pageref{Dnlpen}& Пустое перо\\\hline %%\tt nullpen& pen& \pageref{Dnlpen}& %% Empty pen\\\hline \tt nullpicture& picture& \pageref{Dnlpic}& Пустая картинка\\\hline %%\tt nullpicture& picture& \pageref{Dnlpic}& %% Empty picture\\\hline \pl\tt origin& pair& --& Пара $(0,0)$\\\hline %%\pl\tt origin& pair& --& %% The pair $(0,0)$\\\hline \pl\tt pc& numeric& --& Одна пика в {\tt bp}-единицах [11.95517]\\\hline %%\pl\tt pc& numeric& --& %% One pica in {\tt bp} units [11.95517]\\\hline \tt pencircle& pen& \pageref{Dpncirc}& Круговое перо диаметра 1\\\hline %%\tt pencircle& pen& \pageref{Dpncirc}& %% Circular pen of diameter 1\\\hline \pl\tt pensquare& pen& \pageref{Dpnsqr}& Квадратное перо высоты и ширины 1\\\hline %%\pl\tt pensquare& pen& \pageref{Dpnsqr}& %% square pen of height 1 and width 1\\\hline \pl\tt pt& numeric& \pageref{Dpt}& Один принтерный пункт в {\tt bp}-единицах [0.99626]\\\hline %%\pl\tt pt& numeric& \pageref{Dpt}& %% One printer's point in {\tt bp} units [0.99626]\\\hline \pl\tt quartercircle& path& --& Первый квадрант окружности диаметра 1\\\hline %%\pl\tt quartercircle& path& --& %% First quadrant of a circle of diameter 1\\\hline \pl\tt red& color& \pageref{Dred}& Эквивалентно {\tt (1,0,0)}\\\hline %%\pl\tt red& color& \pageref{Dred}& %% Equivalent to {\tt (1,0,0)}\\\hline \pl\tt right& pair& \pageref{Dright}& Направление вправо $(1,0)$\\\hline %%\pl\tt right& pair& \pageref{Dright}& %% Rightward direction $(1,0)$\\\hline \pl\tt rounded& numeric& \pageref{Drnded}& Значение для {\tt linecap} и {\tt linejoin} для круглых\\ \tt & & & соединений и концов [1]\\\hline %%\pl\tt rounded& numeric& \pageref{Drnded}& %% {\tt linecap} and {\tt linejoin} value for round joins\\ %%\tt & & & %% and end caps [1]\\\hline \pl\tt squared& numeric& \pageref{Dsqred}& Значение {\tt linecap} для квадратных концов [2]\\\hline %%\pl\tt squared& numeric& \pageref{Dsqred}& %% {\tt linecap} value for square end caps [2]\\\hline \tt true& boolean& \pageref{Dtrue}& Логическая величина {\tt true}\\\hline %%\tt true& boolean& \pageref{Dtrue}& %% The boolean value {\tt true}\\\hline \pl\tt unitsquare& path& --& Путь {\tt (0,0)-{}-(1,0)-{}-(1,1)-{}-(0,1)-{}-cycle}\\\hline %%\pl\tt unitsquare& path& --& %% The path {\tt (0,0)--(1,0)--(1,1)--(0,1)--cycle}\\\hline \pl\tt up& pair& \pageref{Dup}& Направление вверх $(0,1)$\\\hline %%\pl\tt up& pair& \pageref{Dup}& %% Upward direction $(0,1)$\\\hline \pl\tt white& color& \pageref{Dwhite}& Эквивалентно {\tt (1,1,1)}\\\hline %%\pl\tt white& color& \pageref{Dwhite}& %% Equivalent to {\tt (1,1,1)}\\\hline \pl\tt withdots& picture& \pageref{Dwdots}& Образец пунктира из точек\\\hline %%\pl\tt withdots& picture& \pageref{Dwdots}& %% Dash pattern that produces dotted lines\\\hline \end{tabular} $$ \label{consttab}% \index{cc?\texttt{cc}}\index{dd?\texttt{dd}}\index{ditto?\texttt{ditto}}\index{epsilon?\texttt{epsilon}}% \index{origin?\texttt{origin}}\index{pc?\texttt{pc}}\index{quartercircle?\texttt{quartercircle}}% \index{unitsquare?\texttt{unitsquare}} \end{table} \clearpage \LTXtable{\textwidth}{mpman-optab-ru} \begin{table}[htp] \caption{Команды} %%\caption{Commands} $$\begin{tabular}{|l|r|l|} \hline \multicolumn1{|c}{Имя}& \multicolumn1{|c}{Стр.}& \multicolumn1{|c|}{Объяснение}\\ %%\multicolumn1{|c}{Name}& \multicolumn1{|c}{Page}& \multicolumn1{|c|}{Explanation}\\ \hline \hline \tt \verb|addto|& \pageref{sydraw}& Низкоуровневая команда для рисования и заполнения\\\hline %% Low-level command for drawing and filling\\\hline \tt \verb|clip|& \pageref{Dclip}& Применяет путь вырезки к картинке\\\hline %% Applies a clipping path to a picture\\\hline \tt \verb|closefrom|& \pageref{Dclosefrom}& Закрывает файл, открытый {\tt readfrom}\\\hline %% Close a file opened by {\tt readfrom}\\\hline \pl\tt \verb|cutdraw|& \pageref{Dctdraw}& Рисовать с butt-концом\\\hline %% Draw with butt end caps\\\hline \tt \verb|dashed|& \pageref{Ddashed}& Применять образец пунктира в команде рисования\\\hline %% Apply dash pattern to drawing command\\\hline \pl\tt \verb|draw|& \pageref{curves}& Рисовать линию или картинку\\\hline %% Draw a line or a picture\\\hline \pl\tt \verb|drawarrow|& \pageref{Ddrwarr}& Рисовать линию со стрелкой на конце\\\hline %% Draw a line with an arrowhead at the end\\\hline \pl\tt \verb|drawdblarrow|& \pageref{Ddrwdar}& Рисовать линию со стрелками в обоих концах\\\hline %% Draw a line with arrowheads at both ends\\\hline \tt \verb|filenametemplate|& \pageref{Dfilenametemplate}& Установить шаблон имени выходного файла\\\hline %% Set output file name pattern\\\hline \pl\tt \verb|fill|& \pageref{Dfill}& Заполнить циклический путь\\\hline %% Fill inside a cyclic path\\\hline \pl\tt \verb|filldraw|& \pageref{Dfildrw}& Рисовать циклический путь и заполнить его внутри\\\hline %% Draw a cyclic path and fill inside it\\\hline \tt \verb|interim|& \pageref{Dinterm}& Сделать локальное изменение внутренней переменной\\\hline %% Make a local change to an internal variable\\\hline \tt \verb|let|& --& Назначить символическому знаку значение другого знака\\\hline %% Assign one symbolic token the meaning of another\\\hline \pl\tt \verb|loggingall|& \pageref{Dlogall}& Включить трассировку (только для файла-журнала)\\\hline %% Turn on all tracing (log file only)\\\hline \tt \verb|newinternal|& \pageref{Dnewint}& Объявить новые внутренние переменные\\\hline %% Declare new internal variables\\\hline \pl\tt \verb|pickup|& \pageref{Dpickup}& Указать новое перо для рисования линии\\\hline %% Specify new pen for line drawing\\\hline \tt \verb|save|& \pageref{Dsave}& Делает переменные локальными\\\hline %% Make variables local\\\hline \tt \verb|setbounds|& \pageref{Dsetbnd}& Устанавливает охватывающую рамку для картинки\\\hline %% Make a picture lie about its bounding box\\\hline \tt \verb|shipout|& \pageref{Dship}& Низкоуровневая команда печати рисунка\\\hline %% Low-level command to output a figure\\\hline \tt \verb|show|& \pageref{Dshow}& Печать выражений в символической форме\\\hline %% print out expressions symbolically\\\hline \tt \verb|showdependencies|& \pageref{Dshdep}& Печать всех нерешенных уравнений\\\hline %% print out all unsolved equations\\\hline \tt \verb|showtoken|& \pageref{Dshtok}& Печать информации по знаку\\\hline %% print an explanation of what a token is\\\hline \tt \verb|showvariable|& \pageref{Dshvar}& Печать переменных в символьной форме\\\hline %% print variables symbolically\\\hline \tt \verb|special|& \pageref{Dspecl}& Печать строки прямо в PostScript-файл вывода\\\hline %% print a string directly in the PostScript output file\\\hline \pl\tt \verb|tracingall|& \pageref{Dtall}& Включить трассировку\\\hline %% Turn on all tracing\\\hline \pl\tt \verb|tracingnone|& \pageref{Dtnone}& Отключить трассировку\\\hline %% Turn off all tracing\\\hline \pl\tt \verb|undraw|& \pageref{Dundraw}& Стереть линию или рисунок\\\hline %% Erase a line or a picture\\\hline \pl\tt \verb|unfill|& \pageref{Dunfill}& Стереть внутри замкнутого пути\\\hline %% Erase inside a cyclic path\\\hline \pl\tt \verb|unfilldraw|& \pageref{Dunfdrw}& Стереть циклический путь и все внутри него\\\hline %% Erase a cyclic path and its inside\\\hline \tt \verb|withcmykcolor|& \pageref{Dwithcmykcolor}& Используй CMYK-цвет в команде рисования\\\hline % Apply CMYK color to drawing command\\\hline \tt \verb|withcolor|& \pageref{Dwithcolor}& Используй обычный цвет в команде рисования\\\hline % Apply generic color specification to drawing command\\\hline \tt \verb|withgreyscale|& \pageref{Dwithgreyscale}& Используй оттенок серого в команде рисования\\\hline % Apply greyscale color to drawing command\\\hline \tt \verb|withoutcolor|& \pageref{Dwithoutcolor}& Не используй спецификации цвета в команде рисования\\\hline % Don't apply any color specification to drawing command\\\hline \tt \verb|withpen|& \pageref{sec.pens}& Используй перо в команде рисования\\\hline % Apply pen to drawing operation\\\hline \tt \verb|withpostscript|& \pageref{Dwithpost}& Конец кода PostScript\\\hline % End raw PostScript code\\\hline \tt \verb|withprescript|& \pageref{Dwithpre}& Начало кода PostScript\\\hline % Begin raw PostScript code\\\hline \tt \verb|withrgbcolor|& \pageref{Dwithrgbcolor}& Используй RGB-цвет в команде рисования\\\hline % Apply RGB color to drawing command\\\hline \tt \verb|write to|& \pageref{Dwrite}& Писать строку в файл\\\hline %% Write string to file\\\hline \end{tabular} $$ \index{let?\texttt{let}}% \label{cmdtab} \end{table} \begin{table}[htp] \caption{Макросы, похожие на функции} %%\caption{Function-Like Macros} $$\begin{tabular}{|l|l|l|r|p{5.7cm}|} %%$$\begin{tabular}{|l|l|l|r|l|} \hline \multicolumn1{|c}{Имя}& \multicolumn1{|c}{Аргументы}& \multicolumn1{|c}{Резу-т}& \multicolumn1{|c}{С.}& \multicolumn1{|c|}{Объяснение}\\ %%\multicolumn1{|c}{Name}& \multicolumn1{|c}{Arguments}& %% \multicolumn1{|c}{Result}& \multicolumn1{|c}{Page}& %% \multicolumn1{|c|}{Explanation}\\ \hline \hline \bx\tt \verb|boxit|& \small суффикс, картинка& --& \pageref{Dboxit}& %%\bx\tt \verb|boxit|& suffix, picture& --& \pageref{Dboxit}& \small Задает рамку, содержащую картинку\\\hline %% Define a box containing the picture\\\hline \bx\tt \verb|boxit|& \small суффикс, строка& --& \pageref{Dsboxit}& %%\bx\tt \verb|boxit|& suffix, string& --& \pageref{Dsboxit}& \small Определяет рамку, содержащую текст\\\hline %% Define a box containing text\\\hline \bx\tt \verb|boxit|& \small суффикс, \tdescr{пусто}& --& \pageref{Deboxit}& %%\bx\tt \verb|boxit|& suffix, \tdescr{empty}& --& \pageref{Deboxit}& \small Определяет пустую рамку\\\hline %% Define an empty box\\\hline \bx\tt \verb|boxjoin|& \small уравнения& --& \pageref{Dbxjoin}& %%\bx\tt \verb|boxjoin|& equations& --& \pageref{Dbxjoin}& \small Задает уравнения для соединяемых рамок\\\hline %% Give equations for connecting boxes\\\hline \bx\tt \verb|bpath|& \small суффикс& path& \pageref{Dbpath}& %%\bx\tt \verb|bpath|& suffix& path& \pageref{Dbpath}& \small Охватывающий круг или прямоугольник\\\hline %% A box's bounding circle or rectangle\\\hline \pl\tt \verb|buildcycle|& \small список путей& path& \pageref{buildcy}& %%\pl\tt \verb|buildcycle|& list of paths& path& \pageref{buildcy}& \small Строить замкнутый путь\\\hline %% Build a cyclic path\\\hline \bx\tt \verb|circleit|& \small суффикс, картинка& --& \pageref{Dcircit}& %%\bx\tt \verb|circleit|& suffix, picture& --& \pageref{Dcircit}& \small Поместить картинку в круговую рамку\\\hline %% Put picture in a circular box\\\hline \bx\tt \verb|circleit|& \small суффикс, картинка& --& \pageref{Dcircit}& %%\bx\tt \verb|circleit|& suffix, picture& \small Поместить строку в круговую рамку\\\hline %% Put a string in a circular box\\\hline \bx\tt \verb|circleit|& \small суффикс, \tdescr{пусто}& --& \pageref{Dcircit}& %%\bx\tt \verb|circleit|& suffix, \tdescr{empty}& --& \pageref{Dcircit}& \small Определить пустую круговую рамку\\\hline %% Define an empty circular box\\\hline \pl\tt \verb|dashpattern|& \small расстояния вкл./выкл.& picture& \pageref{Ddshpat}& %%\pl\tt \verb|dashpattern|& on/off distances& picture& \pageref{Ddshpat}& \small Создать образец пунктирных линий\\\hline %% Create a pattern for dashed lines\\\hline \pl\tt \verb|decr|& \small числовая переменная& numeric& \pageref{Dincr}& %%\pl\tt \verb|decr|& numeric variable& numeric& \pageref{Dincr}& \small Уменьшить и возвратить новое значение\\\hline %% Decrement and return new value\\\hline \pl\tt \verb|dotlabel|& \small суффикс, картинка, пара& --& \pageref{Ddotlab}& %%\pl\tt \verb|dotlabel|& suffix, picture, pair& --& \pageref{Ddotlab}& \small Нарисовать точку и рядом картинку\\\hline %% Mark point and draw picture nearby\\\hline \pl\tt \verb|dotlabel|& \small суффикс, строка, пара& --& \pageref{Ddotlab}& %%\pl\tt \verb|dotlabel|& suffix, string, pair& --& \pageref{Ddotlab}& \small Отметить точку и поместить рядом текст\\\hline %% Mark point and place text nearby\\\hline \pl\tt \verb|dotlabels|& \small суффикс, номера точек& --& \pageref{Ddotlbs}& %%\pl\tt \verb|dotlabels|& suffix, point numbers& --& \pageref{Ddotlbs}& \small Отметить точки {\tt z} их номерами\\\hline %% Mark {\tt z} points with their numbers\\\hline \bx\tt \verb|drawboxed|& \small список суффиксов& --& \pageref{Ddrbxed}& %%\bx\tt \verb|drawboxed|& list of suffixes& --& \pageref{Ddrbxed}& \small Нарисовать именованные рамки и их содержимое\\\hline %% Draw the named boxes and their\\ %%& & & & %% contents\\\hline \bx\tt \verb|drawboxes|& \small список суффиксов& --& \pageref{Ddrbxes}& %%\bx\tt \verb|drawboxes|& list of suffixes& --& \pageref{Ddrbxes}& \small Нарисовать именованные рамки\\\hline %% Draw the named boxes\\\hline \pl\tt \verb|drawdot|& \small пара& --& \pageref{Ddrawdot}& %%\pl\tt \verb|drawdot|& pair& --& \pageref{Ddrawdot}& \small Поставить точку в данном месте\\\hline %% Draw a dot at the given point\\\hline \pl\tt \verb|drawoptions|& \small опции рисования& --& \pageref{Ddropts}& %%\pl\tt \verb|drawoptions|& drawing options& --& \pageref{Ddropts}& \small Установить опции для команд рисования\\\hline %% Set options for drawing commands\\\hline \bx\tt \verb|drawunboxed|& \small список суффиксов& --& \pageref{Ddrunbx}& %%\bx\tt \verb|drawunboxed|& list of suffixes& --& \pageref{Ddrunbx}& \small Рисовать содержимое именованных рамок\\\hline %% Draw contents of named boxes\\\hline \bx\tt \verb|fixpos|& \small список суффиксов& --& \pageref{Dfixpos}& %%\bx\tt \verb|fixpos|& list of suffixes& --& \pageref{Dfixpos}& \small Найти размер и позицию именованных рамок\\\hline %% Solve for the size and position of the\\ %%& & & & %% named boxes\\\hline \bx\tt \verb|fixsize|& \small список суффиксов& --& \pageref{Dfixsiz}& %%\bx\tt \verb|fixsize|& list of suffixes& --& \pageref{Dfixsiz}& \small Найти размер именованных рамок\\\hline %% Solve for size of named boxes\\\hline \pl\tt \verb|image|& \small строка& picture& \pageref{Dimage}& %%\pl\tt \verb|image|& string& picture& \pageref{Dimage}& \small Возвращает рисунок из текста\\\hline %% Return picture from text\\\hline \pl\tt \verb|incr|& \small числовая переменная& numeric& \pageref{Dincr}& %%\pl\tt \verb|incr|& numeric variable& numeric& \pageref{Dincr}& \small Увеличить и возвратить новое значение\\\hline %% Increment and return new value\\\hline \pl\tt \verb|label|& \small суффикс, картинка, пара& --& \pageref{Dlabel}& %%\pl\tt \verb|label|& suffix, picture, pair& --& \pageref{Dlabel}& \small Изобразить рис. возле заданной точки\\\hline %% Draw picture near given point\\\hline \pl\tt \verb|label|& \small суффикс, строка, пара& --& \pageref{Dlabel}& %%\pl\tt \verb|label|& suffix, string, pair& --& \pageref{Dlabel}& \small Поместить текст возле заданной точки\\\hline %% Place text near given point\\\hline \pl\tt \verb|labels|& \small суффикс, номера точек& --& \pageref{Dlabels}& %%\pl\tt \verb|labels|& suffix, point numbers& --& \pageref{Dlabels}& \small Нарисовать числа пар {\tt z}, без точек\\\hline %% Draw {\tt z} point numbers; no dots\\\hline \pl\tt \verb|max|& \small список чисел& numeric& --& %%\pl\tt \verb|max|& list of numerics& numeric& --& \small Найти максимум\\\hline %% Find the maximum\\\hline \pl\tt \verb|max|& \small список строк& string& --& %%\pl\tt \verb|max|& list of strings& string& --& \small Найти словарно последнюю строку\\\hline %% Find the lexicographically last string\\\hline \pl\tt \verb|min|& \small список чисел& numeric& --& %%\pl\tt \verb|min|& list of numerics& numeric& --& \small Найти минимум\\\hline %% Find the minimum\\\hline \pl\tt \verb|min|& \small список строк& string& --& %%\pl\tt \verb|min|& list of strings& string& --& \small Найти словарно первую строку\\\hline %% Find the lexicographically first string\\\hline \bx\tt \verb|pic|& \small суффикс& picture& \pageref{Dpic}& %%\bx\tt \verb|pic|& suffix& picture& \pageref{Dpic}& \small Содержимое рамки, сдвинутое в позицию\\\hline %% Box contents shifted into position\\\hline \pl\tt \verb|thelabel|& \small суффикс, картинка, пара& picture& \pageref{Dthelab}& %%\pl\tt \verb|thelabel|& suffix, picture, pair& picture& \pageref{Dthelab}& \small Картинка, \small сдвинутая как для метки точки\\\hline %% Picture shifted as if to label a point\\\hline \pl\tt \verb|thelabel|& \small суффикс, строка, пара& picture& \pageref{Dthelab}& %%\pl\tt \verb|thelabel|& suffix, string, pair& picture& \pageref{Dthelab}& \small Текст, размещенный как для метки точки\\\hline %% text positioned as if to label a point\\\hline \pl\tt \verb|z|& \small суффикс& pair& \pageref{Dzconv}& %%\pl\tt \verb|z|& suffix& pair& \pageref{Dzconv}& \small Пара ${\tt x}\descr{суффикс},{\tt y}\descr{суффикс})$\\\hline %% The pair ${\tt x}\descr{suffix},{\tt y}\descr{suffix})$\\\hline \end{tabular} $$ \index{min?\texttt{min}}\index{max?\texttt{max}}% \label{pseudotab} \end{table} \clearpage \begin{figure}[htp] \begin{ctabbing} $\tt \descr{атом} \rightarrow \descr{переменная} \;|\; \descr{аргумент}$\\ %%$\tt \descr{atom} \rightarrow \descr{variable} \;|\; \descr{argument}$\\ $\tt \qquad \;|\; \descr{число или дробь}$\\ %%$\tt \qquad \;|\; \descr{number or fraction}$\\ $\tt \qquad \;|\; \descr{внутренняя переменная}$\\ %%$\tt \qquad \;|\; \descr{internal variable}$\\ $\tt \qquad \;|\; \hbox{\tt (}\descr{выражение}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; \hbox{\tt (}\descr{expression}\hbox{\tt )}$\\ $\tt \qquad \;|\; begingroup \descr{список команд} \descr{выражение} endgroup$\\ %%$\tt \qquad \;|\; begingroup \descr{statement list} \descr{expression} endgroup$\\ $\tt \qquad \;|\; \descr{оператор 0-уровня}$\\ %%$\tt \qquad \;|\; \descr{nullary op}$\\ $\tt \qquad \;|\; btex \descr{команды печати} etex$\\ %%$\tt \qquad \;|\; btex \descr{typesetting commands} etex$\\ $\tt \qquad \;|\; \descr{псевдофункция}$\\ %%$\tt \qquad \;|\; \descr{pseudo function}$\\ $\tt \descr{первичность} \rightarrow \descr{атом}$\\ %%$\tt \descr{primary} \rightarrow \descr{atom}$\\ $\tt \qquad \;|\; \hbox{\tt (}\descr{числовое выражение}\hbox{\tt ,} \descr{числовое выражение}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; \hbox{\tt (}\descr{numeric expression}\hbox{\tt ,} \descr{numeric expression}\hbox{\tt )}$\\ $\tt \qquad \;|\; \hbox{\tt (}\descr{числовое выражение}\hbox{\tt ,} \descr{числовое выражение}\hbox{\tt ,} \descr{числовое выражение}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; \hbox{\tt (}\descr{numeric expression}\hbox{\tt ,} \descr{numeric expression}\hbox{\tt ,} \descr{numeric expression}\hbox{\tt )}$\\ $\tt \qquad \;|\; \descr{of-оператор} \descr{выражение} of \descr{первичность}$\\ %%$\tt \qquad \;|\; \descr{of operator} \descr{expression} of \descr{primary}$\\ $\tt \qquad \;|\; \descr{унарный оператор} \descr{первичность}$\\ %%$\tt \qquad \;|\; \descr{unary op} \descr{primary}$\\ $\tt \qquad \;|\; str \descr{суффикс}$\\ %%$\tt \qquad \;|\; str \descr{suffix}$\\ $\tt \qquad \;|\; z \descr{суффикс}$\\ %%$\tt \qquad \;|\; z \descr{suffix}$\\ $\tt \qquad \;|\; \descr{числовой атом}\hbox{\tt [}\descr{выражение}\hbox{\tt ,}\descr{выражение}\hbox{\tt ]}$\\ %%$\tt \qquad \;|\; \descr{numeric atom}\hbox{\tt [}\descr{expression}\hbox{\tt ,}\descr{expression}\hbox{\tt ]}$\\ $\tt \qquad \;|\; \descr{операция скалярного умножения} \descr{первичность}$\\ %%$\tt \qquad \;|\; \descr{scalar multiplication op} \descr{primary}$\\ $\tt \descr{вторичность} \rightarrow \descr{первичность}$\\ %%$\tt \descr{secondary} \rightarrow \descr{primary}$\\ $\tt \qquad \;|\; \descr{вторичность} \descr{первичный бинарный оператор} \descr{первичность}$\\ %%$\tt \qquad \;|\; \descr{secondary} \descr{primary binop} \descr{primary}$\\ $\tt \qquad \;|\; \descr{вторичность} \descr{трансформация}$\\ %%$\tt \qquad \;|\; \descr{secondary} \descr{transformer}$\\ $\tt \descr{третичность} \rightarrow \descr{вторичность}$\\ %%$\tt \descr{tertiary} \rightarrow \descr{secondary}$\\ $\tt \qquad \;|\; \descr{третичность} \descr{вторичный бинарный оператор} \descr{вторичность}$\\ %%$\tt \qquad \;|\; \descr{tertiary} \descr{secondary binop} \descr{secondary}$\\ $\tt \descr{подвыражение} \rightarrow \descr{третичность}$\\ %%$\tt \descr{subexpression} \rightarrow \descr{tertiary}$\\ $\tt \qquad \;|\; \descr{выражение-путь} \descr{соединение путей} \descr{узел пути}$\\ %%$\tt \qquad \;|\; \descr{path expression} \descr{path join} \descr{path knot}$\\ $\tt \descr{выражение} \rightarrow \descr{подвыражение}$\\ %%$\tt \descr{expression} \rightarrow \descr{subexpression}$\\ $\tt \qquad \;|\; \descr{выражение} \descr{третичный бинарный оператор} \descr{третичность}$\\ %%$\tt \qquad \;|\; \descr{expression} \descr{tertiary binop} \descr{tertiary}$\\ $\tt \qquad \;|\; \descr{подвыражение пути} \descr{указатель направления}$\\ %%$\tt \qquad \;|\; \descr{path subexpression} \descr{direction specifier}$\\ $\tt \qquad \;|\; \descr{подвыражение пути} \descr{соединение путей} cycle$\\ %%$\tt \qquad \;|\; \descr{path subexpression} \descr{path join} cycle$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{узел пути} \rightarrow \descr{третичность}$\\ %%$\tt \descr{path knot} \rightarrow \descr{tertiary}$\\ $\tt \descr{соединение путей} \rightarrow -{}-$\\ %%$\tt \descr{path join} \rightarrow --$\\ $\tt \qquad \;|\; \descr{указатель направления} \descr{базовое соединение путей} \descr{указатель направления}$\\ %%$\tt \qquad \;|\; \descr{direction specifier} \descr{basic path join} \descr{direction specifier}$\\ $\tt \descr{указатель направления} \rightarrow \descr{пусто}$\\ %%$\tt \descr{direction specifier} \rightarrow \descr{empty}$\\ $\tt \qquad \;|\; \{{curl \descr{числовое выражение}\}}$\\ %%$\tt \qquad \;|\; \char`\{curl \descr{numeric expression}\char`\}$\\ $\tt \qquad \;|\; \{{\descr{выражение-пара}\}}$\\ %%$\tt \qquad \;|\; \char`\{\descr{pair expression}\char`\}$\\ $\tt \qquad \;|\; \{{\descr{числовое выражение}\hbox{\tt ,}\descr{числовое выражение}\}}$\\ %%$\tt \qquad \;|\; \char`\{\descr{numeric expression}\hbox{\tt ,}\descr{numeric expression}\char`\}$\\ $\tt \descr{базовое соединение путей} \rightarrow \hbox{\tt ..} \;|\; \hbox{\tt ...} \;|\; \hbox{\tt ..}\descr{напряжение}\hbox{\tt ..} \;|\; \hbox{\tt ..}\descr{управление}\hbox{\tt ..}$\\ %%$\tt \descr{basic path join} \rightarrow \hbox{\tt ..} \;|\; \hbox{\tt ...} \;|\; \hbox{\tt ..}\descr{tension}\hbox{\tt ..} \;|\; \hbox{\tt ..}\descr{controls}\hbox{\tt ..}$\\ $\tt \descr{напряжение} \rightarrow tension \descr{числовая первичность}$\\ %%$\tt \descr{tension} \rightarrow tension \descr{numeric primary}$\\ $\tt \qquad \;|\; tension \descr{числовая первичность} and \descr{числовая первичность}$\\ %%$\tt \qquad \;|\; tension \descr{numeric primary} and \descr{numeric primary}$\\ $\tt \descr{управление} \rightarrow controls \descr{первичность-пара}$\\ %%$\tt \descr{controls} \rightarrow controls \descr{pair primary}$\\ $\tt \qquad \;|\; controls \descr{первичность-пара} and \descr{первичность-пара}$\\ %%$\tt \qquad \;|\; controls \descr{pair primary} and \descr{pair primary}$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{аргумент} \rightarrow \descr{символически знак}$\\ %%$\tt \descr{argument} \rightarrow \descr{symbolic token}$\\ $\tt \descr{число или дробь} \rightarrow \descr{число}\hbox{\tt /}\descr{число}$\\ %%$\tt \descr{number or fraction} \rightarrow \descr{number}\hbox{\tt /}\descr{number}$\\ $\tt \qquad \;|\; \descr{число, за которым нет `\hbox{\tt /}\tdescr{число}'}$\\ %%$\tt \qquad \;|\; \descr{number not followed by `\hbox{\tt /}\tdescr{number}'}$\\ $\tt \descr{операция скалярного умножения} \rightarrow + \;|\; -$\\ %%$\tt \descr{scalar multiplication op} \rightarrow + \;|\; -$\\ $\tt \qquad \;|\; \descr{`\tdescr{число или дробь}', за которым нет `\tdescr{операции сложения}\tdescr{число}'}$ %%$\tt \qquad \;|\; \descr{`\tdescr{number or fraction}' not followed by `\tdescr{add op}\tdescr{number}'}$ \end{ctabbing} \caption{Часть 1 синтаксиса выражений} %%\caption{Part 1 of the syntax for expressions} \index{выражение?\tdescr{выражение}}\index{оператор 0?\tdescr{оператор 0-уровня}}\index{of operator?\tdescr{of-оператор}}% \index{узел пути?\tdescr{узел пути}}\index{первичность?\tdescr{первичность}}\index{первичный binop?\tdescr{первичный бинарный оператор}}% \index{вторичность?\tdescr{вторичность}}\index{вторичный binop?\tdescr{вторичный бинарный оператор}}\index{суффикс?\tdescr{суффикс}}% \index{третичность?\tdescr{третичность}}\index{третичный binop?\tdescr{третичный бинарный оператор}}\index{унарный op?\tdescr{унарный оператор}}% %%\index{expression?\tdescr{expression}}\index{nullary op?\tdescr{nullary op}}\index{of operator?\tdescr{of operator}}% %%\index{path knot?\tdescr{path knot}}\index{primary?\tdescr{primary}}\index{primary binop?\tdescr{primary binop}}% %%\index{secondary?\tdescr{secondary}}\index{secondary binop?\tdescr{secondary binop}}\index{suffix?\tdescr{suffix}}% %%\index{tertiary?\tdescr{tertiary}}\index{tertiary binop?\tdescr{tertiary binop}}\index{unary op?\tdescr{unary op}}% \label{syexpr1} \end{figure} \begin{figure}[htp] \begin{ctabbing} $\tt \descr{трансформация} \rightarrow rotated \descr{числовая первичность}$\\ %%$\tt \descr{transformer} \rightarrow rotated \descr{numeric primary}$\\ $\tt \qquad \;|\; scaled \descr{числовая первичность}$\\ %%$\tt \qquad \;|\; scaled \descr{numeric primary}$\\ $\tt \qquad \;|\; shifted \descr{первичность-пара}$\\ %%$\tt \qquad \;|\; shifted \descr{pair primary}$\\ $\tt \qquad \;|\; slanted \descr{числовая первичность}$\\ %%$\tt \qquad \;|\; slanted \descr{numeric primary}$\\ $\tt \qquad \;|\; transformed \descr{трансформация-первичность}$\\ %%$\tt \qquad \;|\; transformed \descr{transform primary}$\\ $\tt \qquad \;|\; xscaled \descr{числовая первичность}$\\ %%$\tt \qquad \;|\; xscaled \descr{numeric primary}$\\ $\tt \qquad \;|\; yscaled \descr{числовая первичность}$\\ %%$\tt \qquad \;|\; yscaled \descr{numeric primary}$\\ $\tt \qquad \;|\; zscaled \descr{первичность-пара}$\\ %%$\tt \qquad \;|\; zscaled \descr{pair primary}$\\ $\tt \qquad \;|\; reflectedabout\hbox{\tt (}\descr{выражение-пара}\hbox{\tt ,} \descr{выражение-пара}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; reflectedabout\hbox{\tt (}\descr{pair expression}\hbox{\tt ,} \descr{pair expression}\hbox{\tt )}$\\ $\tt \qquad \;|\; rotatedaround\hbox{\tt (}\descr{выражение-пара}\hbox{\tt ,} \descr{выражение-пара}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; rotatedaround\hbox{\tt (}\descr{pair expression}\hbox{\tt ,} \descr{numeric expression}\hbox{\tt )}$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{оператор 0-уровня} \rightarrow false \;|\; normaldeviate \;|\; nullpen \;|\; nullpicture \;|\; pencircle$\\ %%$\tt \descr{nullary op} \rightarrow false \;|\; normaldeviate \;|\; nullpen \;|\; nullpicture \;|\; pencircle$\\ $\tt \qquad \;|\; true \;|\; whatever$\\ $\tt \descr{унарный оператор} \rightarrow \descr{тип}$\\ %%$\tt \descr{unary op} \rightarrow \descr{type}$\\ $\tt \qquad \;|\; abs \;|\; angle \;|\; arclength \;|\; ASCII \;|\; bbox \;|\; blackpart \;|\; bluepart \;|\; bot \;|\; bounded$\\ $\tt \qquad \;|\; ceiling \;|\; center \;|\; char \;|\; clipped \;|\; colormodel \;|\; cosd \;|\; cyanpart \;|\; cycle$\\ $\tt \qquad \;|\; dashpart \;|\; decimal \;|\; dir \;|\; floor \;|\; filled \;|\; fontpart \;|\; fontsize$\\ $\tt \qquad \;|\; greenpart \;|\; greypart \;|\; hex \;|\; inverse \;|\; known \;|\; length \;|\; lft \;|\; llcorner$\\ $\tt \qquad \;|\; lrcorner\;|\; magentapart \;|\; makepath \;|\; makepen \;|\; mexp \;|\; mlog \;|\; not \;|\; oct \;|\; odd$\\ $\tt \qquad \;|\; pathpart \;|\; penpart \;|\; readfrom \;|\; redpart \;|\; reverse \;|\; round \;|\; rt \;|\; sind \;|\; sqrt$\\ $\tt \qquad \;|\; stroked \;|\; textpart \;|\; textual \;|\; top \;|\; ulcorner$\\ $\tt \qquad \;|\; uniformdeviate \;|\; unitvector \;|\; unknown \;|\; urcorner \;|\; xpart \;|\; xxpart$\\ $\tt \qquad \;|\; xypart \;|\; yellowpart \;|\; ypart \;|\; yxpart \;|\; yypart$\\ $\tt \descr{тип} \rightarrow boolean \;|\; cmykcolor \;|\; color \;|\; numeric \;|\; pair$\\ %%$\tt \descr{type} \rightarrow boolean \;|\; cmykcolor \;|\; color \;|\; numeric \;|\; pair$\\ $\tt \qquad \;|\; path \;|\; pen \;|\; picture \;|\; rgbcolor \;|\; string \;|\; transform$\\ $\tt \descr{первичный бинарный оператор} \rightarrow \hbox{\tt *} \;|\; \hbox{\tt /} \;|\; \hbox{\tt **} \;|\; and$\\ %%$\tt \descr{primary binop} \rightarrow \hbox{\tt *} \;|\; \hbox{\tt /} \;|\; \hbox{\tt **} \;|\; and$\\ $\tt \qquad \;|\; dotprod \;|\; div \;|\; infont \;|\; mod$\\ $\tt \descr{вторичный бинарный оператор} \rightarrow + \;|\; - \;|\; ++ \;|\; +-+ \;|\; or$\\ %%$\tt \descr{secondary binop} \rightarrow + \;|\; - \;|\; ++ \;|\; +-+ \;|\; or$\\ $\tt \qquad \;|\; intersectionpoint \;|\; intersectiontimes$\\ $\tt \descr{третичный бинарный оператор} \rightarrow \hbox{\tt \&} \;|\; \hbox{\verb|<|} \;|\; \hbox{\verb|<=|} \;|\; \hbox{\verb|<>|} \;|\; \hbox{\tt =} \;|\; \hbox{\verb|>|} \;|\; \hbox{\verb|>=|}$\\ %%$\tt \descr{tertiary binop} \rightarrow \hbox{\tt \&} \;|\; \hbox{\verb|<|} \;|\; \hbox{\verb|<=|} \;|\; \hbox{\verb|<>|} \;|\; \hbox{\tt =} \;|\; \hbox{\verb|>|} \;|\; \hbox{\verb|>=|}$\\ $\tt \qquad \;|\; cutafter \;|\; cutbefore$\\ $\tt \descr{of-оператор} \rightarrow arctime \;|\; direction \;|\; directiontime \;|\; directionpoint$\\ %%$\tt \descr{of operator} \rightarrow arctime \;|\; direction \;|\; directiontime \;|\; directionpoint$\\ $\tt \qquad \;|\; penoffset \;|\; point \;|\; postcontrol \;|\; precontrol \;|\; subpath$\\ $\tt \qquad \;|\; substring$\\ $\tt $\\ $\tt \descr{переменная} \rightarrow \descr{этикетка}\descr{суффикс}$\\ %%$\tt \descr{variable} \rightarrow \descr{tag}\descr{suffix}$\\ $\tt \descr{суффикс} \rightarrow \descr{пусто} \;|\; \descr{суффикс}\descr{индекс} \;|\; \descr{суффикс}\descr{этикетка}$\\ %%$\tt \descr{suffix} \rightarrow \descr{empty} \;|\; \descr{suffix}\descr{subscript} \;|\; \descr{suffix}\descr{tag}$\\ $\tt \qquad \;|\; \descr{параметр-суффикс}$\\ %%$\tt \qquad \;|\; \descr{suffix parameter}$\\ $\tt \descr{индекс} \rightarrow \descr{число} \;|\; \hbox{\tt [}\descr{числовое выражение}\hbox{\tt ]}$\\ %%$\tt \descr{subscript} \rightarrow \descr{number} \;|\; \hbox{\tt [}\descr{numeric expression}\hbox{\tt ]}$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{внутренняя переменная} \rightarrow ahangle \;|\; ahlength \;|\; bboxmargin$\\ %%$\tt \descr{internal variable} \rightarrow ahangle \;|\; ahlength \;|\; bboxmargin$\\ $\tt \qquad \;|\; charcode \;|\; day \;|\; defaultcolormodel \;|\; defaultpen \;|\; defaultscale$\\ $\tt \qquad \;|\; labeloffset \;|\; linecap \;|\; linejoin \;|\; miterlimit \;|\; month$\\ $\tt \qquad \;|\; pausing \;|\; prologues \;|\; showstopping \;|\; time \;|\; tracingoutput$\\ $\tt \qquad \;|\; tracingcapsules \;|\; tracingchoices \;|\; tracingcommands$\\ $\tt \qquad \;|\; tracingequations \;|\; tracinglostchars \;|\; tracingmacros$\\ $\tt \qquad \;|\; tracingonline \;|\; tracingrestores \;|\; tracingspecs$\\ $\tt \qquad \;|\; tracingstats \;|\; tracingtitles \;|\; truecorners$\\ $\tt \qquad \;|\; warningcheck \;|\; year$\\ $\tt \qquad \;|\; \descr{символический знак, определенный {\tt newinternal}}$ %%$\tt \qquad \;|\; \descr{symbolic token defined by {\tt newinternal}}$ \end{ctabbing} \caption{Часть 2 синтаксиса выражений} %%\caption{Part 2 of the syntax for expressions} \index{оператор 0?\tdescr{оператор 0-уровня}}\index{of operator?\tdescr{of-оператор}}\index{первичный binop?\tdescr{первичный бинарный оператор}}% \index{вторичный binop?\tdescr{вторичный бинарный оператор}}\index{индекс?\tdescr{индекс}}\index{суффикс?\tdescr{суффикс}}% \index{третичный binop?\tdescr{третичный бинарный оператор}}\index{унарный op?\tdescr{унарный оператор}}% %%\index{nullary op?\tdescr{nullary op}}\index{of operator?\tdescr{of operator}}\index{primary binop?\tdescr{primary binop}}% %%\index{secondary binop?\tdescr{secondary binop}}\index{subscript?\tdescr{subscript}}\index{suffix?\tdescr{suffix}}% %%\index{tertiary binop?\tdescr{tertiary binop}}\index{unary op?\tdescr{unary op}}% \label{syexpr2} \end{figure} \begin{figure}[htp] \begin{ctabbing} $\tt \descr{псевдофункция} \rightarrow min\hbox{\tt (}\descr{список выражений}\hbox{\tt )}$\\ %%$\tt \descr{pseudo function} \rightarrow min\hbox{\tt (}\descr{expression list}\hbox{\tt )}$\\ $\tt \qquad \;|\; max\hbox{\tt (}\descr{список выражений}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; max\hbox{\tt (}\descr{expression list}\hbox{\tt )}$\\ $\tt \qquad \;|\; incr\hbox{\tt (}\descr{числовая переменная}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; incr\hbox{\tt (}\descr{numeric variable}\hbox{\tt )}$\\ $\tt \qquad \;|\; decr\hbox{\tt (}\descr{числовая переменная}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; decr\hbox{\tt (}\descr{numeric variable}\hbox{\tt )}$\\ $\tt \qquad \;|\; dashpattern\hbox{\tt (}\descr{список on\hbox{\tt /}off}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; dashpattern\hbox{\tt (}\descr{on\hbox{\tt /}off list}\hbox{\tt )}$\\ $\tt \qquad \;|\; interpath\hbox{\tt (}\descr{числовое выражение}\hbox{\tt ,} \descr{выражение-путь}\hbox{\tt ,} \descr{выражение-путь}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; interpath\hbox{\tt (}\descr{numeric expression}\hbox{\tt ,} \descr{path expression}\hbox{\tt ,} \descr{path expression}\hbox{\tt )}$\\ $\tt \qquad \;|\; buildcycle\hbox{\tt (}\descr{список выражений-путей}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; buildcycle\hbox{\tt (}\descr{path expression list}\hbox{\tt )}$\\ $\tt \qquad \;|\; thelabel\descr{суффикс метки}\hbox{\tt (}\descr{выражение}\hbox{\tt ,} \descr{выражение-пара}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; thelabel\descr{label suffix}\hbox{\tt (}\descr{expression}\hbox{\tt ,} \descr{pair expression}\hbox{\tt )}$\\ $\tt \descr{список выражений-путей} \rightarrow \descr{выражение-путь}$\\ %%$\tt \descr{path expression list} \rightarrow \descr{path expression}$\\ $\tt \qquad \;|\; \descr{список выражений-путей}\hbox{\tt ,} \descr{выражение-путь}$\\ %%$\tt \qquad \;|\; \descr{path expression list}\hbox{\tt ,} \descr{path expression}$\\ $\tt \descr{список on\hbox{\tt /}off} \rightarrow \descr{список on\hbox{\tt /}off}\descr{пункт on\hbox{\tt /}off} \;|\; \descr{пункт on\hbox{\tt /}off}$\\ %%$\tt \descr{on\hbox{\tt /}off list} \rightarrow \descr{on\hbox{\tt /}off list}\descr{on\hbox{\tt /}off clause} \;|\; \descr{on\hbox{\tt /}off clause}$\\ $\tt \descr{пункт on\hbox{\tt /}off} \rightarrow on \descr{числовая третичность} \;|\; off \descr{числовая третичность}$ %%$\tt \descr{on\hbox{\tt /}off clause} \rightarrow on \descr{numeric tertiary} \;|\; off \descr{numeric tertiary}$ \end{ctabbing} \caption{Синтаксис макросов, похожих на функции} %%\caption{The syntax for function-like macros} \index{label suffix?\tdescr{суффикс метки}}% %%\index{label suffix?\tdescr{label suffix}}% \label{sypseudo} \end{figure} \begin{figure}[htp] \begin{ctabbing} $\tt \descr{логическое выражение} \rightarrow \descr{выражение}$\\ %%$\tt \descr{boolean expression} \rightarrow \descr{expression}$\\ $\tt \descr{выражение-cmyk-цвет } \rightarrow \descr{выражение}$\\ %%$\tt \descr{cmykcolor expression} \rightarrow \descr{expression}$\\ $\tt \descr{выражение-цвет} \rightarrow \descr{выражение}$\\ %%$\tt \descr{color expression} \rightarrow \descr{expression}$\\ $\tt \descr{числовой атом} \rightarrow \descr{атом}$\\ %%$\tt \descr{numeric atom} \rightarrow \descr{atom}$\\ $\tt \descr{числовое выражение} \rightarrow \descr{выражение}$\\ %%$\tt \descr{numeric expression} \rightarrow \descr{expression}$\\ $\tt \descr{числовая первичность} \rightarrow \descr{первичность}$\\ %%$\tt \descr{numeric primary} \rightarrow \descr{primary}$\\ $\tt \descr{числовая третичность} \rightarrow \descr{третичность}$\\ %%$\tt \descr{numeric tertiary} \rightarrow \descr{tertiary}$\\ $\tt \descr{числовая переменная} \rightarrow \descr{переменная} \;|\; \descr{внутренняя переменная}$\\ %%$\tt \descr{numeric variable} \rightarrow \descr{variable} \;|\; \descr{internal variable}$\\ $\tt \descr{выражение-пара} \rightarrow \descr{выражение}$\\ %%$\tt \descr{pair expression} \rightarrow \descr{expression}$\\ $\tt \descr{пара-первичность} \rightarrow \descr{первичность}$\\ %%$\tt \descr{pair primary} \rightarrow \descr{primary}$\\ $\tt \descr{выражение-путь} \rightarrow \descr{выражение}$\\ %%$\tt \descr{path expression} \rightarrow \descr{expression}$\\ $\tt \descr{подвыражение-путь} \rightarrow \descr{подвыражение}$\\ %%$\tt \descr{path subexpression} \rightarrow \descr{subexpression}$\\ $\tt \descr{выражение-перо} \rightarrow \descr{выражение}$\\ %%$\tt \descr{pen expression} \rightarrow \descr{expression}$\\ $\tt \descr{выражение-картинка} \rightarrow \descr{выражение}$\\ %%$\tt \descr{picture expression} \rightarrow \descr{expression}$\\ $\tt \descr{переменная-картинка} \rightarrow \descr{переменная}$\\ %%$\tt \descr{picture variable} \rightarrow \descr{variable}$\\ $\tt \descr{выражение-rgb-цвет} \rightarrow \descr{выражение}$\\ %%$\tt \descr{rgbcolor expression} \rightarrow \descr{expression}$\\ $\tt \descr{строковое выражение} \rightarrow \descr{выражение}$\\ %%$\tt \descr{string expression} \rightarrow \descr{expression}$\\ $\tt \descr{параметр-суффикс} \rightarrow \descr{параметр}$\\ %%$\tt \descr{suffix parameter} \rightarrow \descr{parameter}$\\ $\tt \descr{трансформация-первичность} \rightarrow \descr{первичность}$ %%$\tt \descr{transform primary} \rightarrow \descr{primary}$ \end{ctabbing} \caption{Различные правила, нужные для завершения НФБН} %%\caption{Miscellaneous productions needed to complete the BNF} \label{sytypexpr} \end{figure} \begin{figure}[htp] \begin{ctabbing} $\tt \descr{программа} \rightarrow \descr{список метакоманд} end$\\ %%$\tt \descr{program} \rightarrow \descr{statement list} end$\\ $\tt \descr{список метакоманд} \rightarrow \descr{пусто} \;|\; \descr{список метакоманд} \hbox{\tt ;} \descr{метакоманда}$\\ %%$\tt \descr{statement list} \rightarrow \descr{empty} \;|\; \descr{statement list} \hbox{\tt ;} \descr{statement}$\\ $\tt \descr{метакоманда} \rightarrow \descr{пусто}$\\ %%$\tt \descr{statement} \rightarrow \descr{empty}$\\ $\tt \qquad \;|\; \descr{уравнение} \;|\; \descr{присваивание}$\\ %%$\tt \qquad \;|\; \descr{equation} \;|\; \descr{assignment}$\\ $\tt \qquad \;|\; \descr{декларация} \;|\; \descr{определение макроса}$\\ %%$\tt \qquad \;|\; \descr{declaration} \;|\; \descr{macro definition}$\\ $\tt \qquad \;|\; \descr{блок} \;|\; \descr{псевдопроцедура}$\\ %%$\tt \qquad \;|\; \descr{compound} \;|\; \descr{pseudo procedure}$\\ $\tt \qquad \;|\; \descr{команда}$\\ %%$\tt \qquad \;|\; \descr{command}$\\ $\tt \descr{блок} \rightarrow begingroup \descr{список метакоманд} endgroup$\\ %%$\tt \descr{compound} \rightarrow begingroup \descr{statement list} endgroup$\\ $\tt \qquad \;|\; beginfig\hbox{\tt (}\descr{числовое выражение}\hbox{\tt );} \descr{список метакоманд}\hbox{\tt ;} endfig$\\ %%$\tt \qquad \;|\; beginfig\hbox{\tt (}\descr{numeric expression}\hbox{\tt );} \descr{statement list}\hbox{\tt ;} endfig$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{уравнение} \rightarrow \descr{выражение} \hbox{\tt =} \descr{правая часть}$\\ %%$\tt \descr{equation} \rightarrow \descr{expression} \hbox{\tt =} \descr{right-hand side}$\\ $\tt \descr{присваивание} \rightarrow \descr{переменная} \hbox{\tt :=} \descr{правая часть}$\\ %%$\tt \descr{assignment} \rightarrow \descr{variable} \hbox{\tt :=} \descr{right-hand side}$\\ $\tt \qquad \;|\; \descr{внутренняя переменная} \hbox{\tt :=} \descr{правая часть}$\\ %%$\tt \qquad \;|\; \descr{internal variable} \hbox{\tt :=} \descr{right-hand side}$\\ $\tt \descr{правая часть} \rightarrow \descr{выражение} \;|\; \descr{уравнение} \;|\; \descr{присваивание}$\\ %%$\tt \descr{right-hand side} \rightarrow \descr{expression} \;|\; \descr{equation} \;|\; \descr{assignment}$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{декларация} \rightarrow \descr{тип} \descr{список декларации}$\\ %%$\tt \descr{declaration} \rightarrow \descr{type} \descr{declaration list}$\\ $\tt \descr{список декларации} \rightarrow \descr{обобщение переменной}$\\ %%$\tt \descr{declaration list} \rightarrow \descr{generic variable}$\\ $\tt \qquad \;|\; \descr{список декларации}\hbox{\tt ,} \descr{обобщение переменной}$\\ %%$\tt \qquad \;|\; \descr{declaration list}\hbox{\tt ,} \descr{generic variable}$\\ $\tt \descr{обобщение переменной} \rightarrow \descr{символический знак} \descr{обобщение суффикса}$\\ %%$\tt \descr{generic variable} \rightarrow \descr{symbolic token} \descr{generic suffix}$\\ $\tt \descr{обобщение суффикса} \rightarrow \descr{пусто} \;|\; \descr{обобщение суффикса} \descr{этикетка}$\\ %%$\tt \descr{generic suffix} \rightarrow \descr{empty} \;|\; \descr{generic suffix} \descr{tag}$\\ $\tt \qquad \;|\; \descr{обобщение суффикса} \hbox{\tt []}$\\ %%$\tt \qquad \;|\; \descr{generic suffix} \hbox{\tt []}$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{определение макроса} \rightarrow \descr{заголовок макроса} \hbox{\tt =} \descr{текст замены} enddef$\\ %%$\tt \descr{macro definition} \rightarrow \descr{macro heading} \hbox{\tt =} \descr{replacement text} enddef$\\ $\tt \descr{заголовок макроса} \rightarrow def \descr{символический знак} \descr{отделенная часть} \descr{неотделенная часть}$\\ %%$\tt \descr{macro heading} \rightarrow def \descr{symbolic token} \descr{delimited part} \descr{undelimited part}$\\ $\tt \qquad \;|\; vardef \descr{обобщение переменной} \descr{отделенная часть} \descr{неотделенная часть}$\\ %%$\tt \qquad \;|\; vardef \descr{generic variable} \descr{delimited part} \descr{undelimited part}$\\ $\tt \qquad \;|\; vardef \descr{обобщение переменной} \hbox{\verb|@#|} \descr{отделенная часть} \descr{неотделенная часть}$\\ %%$\tt \qquad \;|\; vardef \descr{generic variable} \hbox{\verb|@#|} \descr{delimited part} \descr{undelimited part}$\\ $\tt \qquad \;|\; \descr{определение бинарности} \descr{параметр} \descr{символический знак} \descr{параметр}$\\ %%$\tt \qquad \;|\; \descr{binary def} \descr{parameter} \descr{symbolic token} \descr{parameter}$\\ $\tt \descr{отделенная часть} \rightarrow \descr{пусто}$\\ %%$\tt \descr{delimited part} \rightarrow \descr{empty}$\\ $\tt \qquad \;|\; \descr{отделенная часть}\hbox{\tt (}\descr{тип параметра} \descr{параметры-знаки}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; \descr{delimited part}\hbox{\tt (}\descr{parameter type} \descr{parameter tokens}\hbox{\tt )}$\\ $\tt \descr{тип параметра} \rightarrow expr \;|\; suffix \;|\; text$\\ %%$\tt \descr{parameter type} \rightarrow expr \;|\; suffix \;|\; text$\\ $\tt \descr{параметры-знаки} \rightarrow \descr{параметр} \;|\; \descr{параметры-знаки}\hbox{\tt ,} \descr{параметр}$\\ %%$\tt \descr{parameter tokens} \rightarrow \descr{parameter} \;|\; \descr{parameter tokens}\hbox{\tt ,} \descr{parameter}$\\ $\tt \descr{параметр} \rightarrow \descr{символический знак}$\\ %%$\tt \descr{parameter} \rightarrow \descr{symbolic token}$\\ $\tt \descr{неотделенная часть} \rightarrow \descr{пусто}$\\ %%$\tt \descr{undelimited part} \rightarrow \descr{empty}$\\ $\tt \qquad \;|\; \descr{тип параметра} \descr{параметр}$\\ %%$\tt \qquad \;|\; \descr{parameter type} \descr{parameter}$\\ $\tt \qquad \;|\; \descr{уровень приоритета} \descr{параметр}$\\ %%$\tt \qquad \;|\; \descr{precedence level} \descr{parameter}$\\ $\tt \qquad \;|\; expr \descr{параметр} of \descr{параметр}$\\ %%$\tt \qquad \;|\; expr \descr{parameter} of \descr{parameter}$\\ $\tt \descr{уровень приоритета} \rightarrow primary \;|\; secondary \;|\; tertiary$\\ %%$\tt \descr{precedence level} \rightarrow primary \;|\; secondary \;|\; tertiary$\\ $\tt \descr{определение бинарности} \rightarrow primarydef \;|\; secondarydef \;|\; tertiarydef$\\ %%$\tt \descr{binary def} \rightarrow primarydef \;|\; secondarydef \;|\; tertiarydef$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{псевдопроцедура} \rightarrow drawoptions\hbox{\tt (}\descr{список опций}\hbox{\tt )}$\\ %%$\tt \descr{pseudo procedure} \rightarrow drawoptions\hbox{\tt (}\descr{option list}\hbox{\tt )}$\\ $\tt \qquad \;|\; label\descr{суффикс метки}\hbox{\tt (}\descr{выражение}\hbox{\tt ,} \descr{выражение-пара}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; label\descr{label suffix}\hbox{\tt (}\descr{expression}\hbox{\tt ,} \descr{pair expression}\hbox{\tt )}$\\ $\tt \qquad \;|\; dotlabel\descr{суффикс метки}\hbox{\tt (}\descr{выражение}\hbox{\tt ,} \descr{выражение-пара}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; dotlabel\descr{label suffix}\hbox{\tt (}\descr{expression}\hbox{\tt ,} \descr{pair expression}\hbox{\tt )}$\\ $\tt \qquad \;|\; labels\descr{суффикс метки}\hbox{\tt (}\descr{список номеров точек}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; labels\descr{label suffix}\hbox{\tt (}\descr{point number list}\hbox{\tt )}$\\ $\tt \qquad \;|\; dotlabels\descr{суффикс метки}\hbox{\tt (}\descr{список номеров точек}\hbox{\tt )}$\\ %%$\tt \qquad \;|\; dotlabels\descr{label suffix}\hbox{\tt (}\descr{point number list}\hbox{\tt )}$\\ $\tt \descr{список номеров точек} \rightarrow \descr{суффикс} \;|\; \descr{список номеров точек}\hbox{\tt ,} \descr{суффикс}$\\ %%$\tt \descr{point number list} \rightarrow \descr{suffix} \;|\; \descr{point number list}\hbox{\tt ,} \descr{suffix}$\\ $\tt \descr{суффикс метки} \rightarrow \descr{пусто} \;|\; lft \;|\; rt \;|\; top \;|\; bot \;|\; ulft \;|\; urt \;|\; llft \;|\; lrt$ %%$\tt \descr{label suffix} \rightarrow \descr{empty} \;|\; lft \;|\; rt \;|\; top \;|\; bot \;|\; ulft \;|\; urt \;|\; llft \;|\; lrt$ \end{ctabbing} \caption{Полный синтаксис программ MetaPost} %%\caption{Overall syntax for MetaPost programs} \index{обобщенная переменная?\tdescr{обобщенная переменная}}\index{label suffix?\tdescr{суффикс метки}}\index{текст замены?\tdescr{текст замены}}% %%\index{suffix?\tdescr{суффикс}}% %%\index{generic variable?\tdescr{generic variable}}\index{label suffix?\tdescr{label suffix}}\index{replacement text?\tdescr{replacement text}}% %%\index{suffix?\tdescr{suffix}}% \label{syprog} \end{figure} \begin{figure}[htp] \begin{ctabbing} $\tt \descr{команда} \rightarrow clip \descr{переменная-картинка} to \descr{выражение-путь}$\\ %%$\tt \descr{command} \rightarrow clip \descr{picture variable} to \descr{path expression}$\\ $\tt \qquad \;|\; interim \descr{внутренняя переменная} \hbox{\tt :=} \descr{правая часть}$\\ %%$\tt \qquad \;|\; interim \descr{internal variable} \hbox{\tt :=} \descr{right-hand side}$\\ $\tt \qquad \;|\; let \descr{символический знак} \hbox{\tt =} \descr{символический знак}$\\ %%$\tt \qquad \;|\; let \descr{symbolic token} \hbox{\tt =} \descr{symbolic token}$\\ $\tt \qquad \;|\; newinternal \descr{список символических знаков}$\\ %%$\tt \qquad \;|\; newinternal \descr{symbolic token list}$\\ $\tt \qquad \;|\; pickup \descr{выражение}$\\ %%$\tt \qquad \;|\; pickup \descr{expression}$\\ $\tt \qquad \;|\; randomseed \hbox{\tt :=} \descr{числовое выражение}$\\ %%$\tt \qquad \;|\; randomseed \hbox{\tt :=} \descr{numeric expression}$\\ $\tt \qquad \;|\; save \descr{список символических знаков}$\\ %%$\tt \qquad \;|\; save \descr{symbolic token list}$\\ $\tt \qquad \;|\; setbounds \descr{переменная-картинка} to \descr{выражение-путь}$\\ %%$\tt \qquad \;|\; setbounds \descr{picture variable} to \descr{path expression}$\\ $\tt \qquad \;|\; shipout \descr{выражение-картинка}$\\ %%$\tt \qquad \;|\; shipout \descr{picture expression}$\\ $\tt \qquad \;|\; special \descr{строковое выражение}$\\ %%$\tt \qquad \;|\; special \descr{string expression}$\\ $\tt \qquad \;|\; write \descr{строковое выражение} to \descr{строковое выражение}$\\ %%$\tt \qquad \;|\; write \descr{string expression} to \descr{string expression}$\\ $\tt \qquad \;|\; \descr{команда addto}$\\ %%$\tt \qquad \;|\; \descr{addto command}$\\ $\tt \qquad \;|\; \descr{команда рисования}$\\ %%$\tt \qquad \;|\; \descr{drawing command}$\\ $\tt \qquad \;|\; \descr{команда метрики шрифта}$\\ %%$\tt \qquad \;|\; \descr{font metric command}$\\ $\tt \qquad \;|\; \descr{команда-сообщение}$\\ %%$\tt \qquad \;|\; \descr{message command}$\\ $\tt \qquad \;|\; \descr{команда show}$\\ %%$\tt \qquad \;|\; \descr{show command}$\\ $\tt \qquad \;|\; \descr{команда трассировки}$\\ %%$\tt \qquad \;|\; \descr{tracing command}$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{команда show} \rightarrow show \descr{список выражений}$\\ %%$\tt \descr{show command} \rightarrow show \descr{expression list}$\\ $\tt \qquad \;|\; showvariable \descr{список символических знаков}$\\ %%$\tt \qquad \;|\; showvariable \descr{symbolic token list}$\\ $\tt \qquad \;|\; showtoken \descr{список символических знаков}$\\ %%$\tt \qquad \;|\; showtoken \descr{symbolic token list}$\\ $\tt \qquad \;|\; showdependencies$\\ %%$\tt \qquad \;|\; showdependencies$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{список символических знаков} \rightarrow \descr{символический знак}$\\ %%$\tt \descr{symbolic token list} \rightarrow \descr{symbolic token}$\\ $\tt \qquad \;|\; \descr{символический знак}\hbox{\tt ,} \descr{список символических знаков}$\\ %%$\tt \qquad \;|\; \descr{symbolic token}\hbox{\tt ,} \descr{symbolic token list}$\\ $\tt \descr{список выражений} \rightarrow \descr{выражение} \;|\; \descr{список выражений}\hbox{\tt ,} \descr{выражение}$\\ %%$\tt \descr{expression list} \rightarrow \descr{expression} \;|\; \descr{expression list}\hbox{\tt ,} \descr{expression}$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{команда addto} \rightarrow$\\ %%$\tt \descr{addto command} \rightarrow$\\ $\tt \qquad addto \descr{переменная-картинка} also \descr{выражение-картинка} \descr{список опций}$\\ %%$\tt \qquad addto \descr{picture variable} also \descr{picture expression} \descr{option list}$\\ $\tt \qquad \;|\; addto \descr{переменная-картинка} contour \descr{выражение-путь} \descr{список опций}$\\ %%$\tt \qquad \;|\; addto \descr{picture variable} contour \descr{path expression} \descr{option list}$\\ $\tt \qquad \;|\; addto \descr{переменная-картинка} doublepath \descr{выражение-путь} \descr{список опций}$\\ %%$\tt \qquad \;|\; addto \descr{picture variable} doublepath \descr{path expression} \descr{option list}$\\ $\tt \descr{список опций} \rightarrow \descr{пусто} \;|\; \descr{опция рисования} \descr{список опций}$\\ %%$\tt \descr{option list} \rightarrow \descr{empty} \;|\; \descr{drawing option} \descr{option list}$\\ $\tt \descr{опция рисования} \rightarrow withcolor \descr{выражение-цвет}$\\ %%$\tt \descr{drawing option} \rightarrow withcolor \descr{color expression}$\\ $\tt \qquad \;|\; withrgbcolor \descr{выражение-rgb-цвет} \;|\; withcmykcolor \descr{выражение-cmyk-цвет}$\\ %%$\tt \qquad \;|\; withrgbcolor \descr{rgbcolor expression} \;|\; withcmykcolor \descr{cmykcolor expression}$\\ $\tt \qquad \;|\; withgreyscale \descr{числовое выражение} \;|\; withoutcolor$\\ %%$\tt \qquad \;|\; withgreyscale \descr{numeric expression} \;|\; withoutcolor$\\ $\tt \qquad \;|\; withprescript \descr{строковое выражение} \;|\; withpostscript \descr{строковое выражение}$\\ %%$\tt \qquad \;|\; withprescript \descr{string expression} \;|\; withpostscript \descr{string expression}$\\ $\tt \qquad \;|\; withpen \descr{выражение-перо} \;|\; dashed \descr{выражение-картинка}$\\ %%$\tt \qquad \;|\; withpen \descr{pen expression} \;|\; dashed \descr{picture expression}$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{команда рисования} \rightarrow draw \descr{выражение-картинка} \descr{список опций}$\\ %%$\tt \descr{drawing command} \rightarrow draw \descr{picture expression} \descr{option list}$\\ $\tt \qquad \;|\; \descr{тип заполнения} \descr{выражение-путь} \descr{список опций}$\\ %%$\tt \qquad \;|\; \descr{fill type} \descr{path expression} \descr{option list}$\\ $\tt \descr{тип заполнения} \rightarrow fill \;|\; draw \;|\; filldraw \;|\; unfill \;|\; undraw \;|\; unfilldraw$\\ %%$\tt \descr{fill type} \rightarrow fill \;|\; draw \;|\; filldraw \;|\; unfill \;|\; undraw \;|\; unfilldraw$\\ $\tt \qquad \;|\; drawarrow \;|\; drawdblarrow \;|\; cutdraw$\\ %%$\tt \qquad \;|\; drawarrow \;|\; drawdblarrow \;|\; cutdraw$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{команда-сообщение} \rightarrow errhelp \descr{строковое выражение}$\\ %%$\tt \descr{message command} \rightarrow errhelp \descr{string expression}$\\ $\tt \qquad \;|\; errmessage \descr{строковое выражение}$\\ %%$\tt \qquad \;|\; errmessage \descr{string expression}$\\ $\tt \qquad \;|\; filenametemplate \descr{строковое выражение}$\\ %%$\tt \qquad \;|\; filenametemplate \descr{string expression}$\\ $\tt \qquad \;|\; message \descr{строковое выражение}$\\ %%$\tt \qquad \;|\; message \descr{string expression}$\\ $\tt $\\ %%$\tt $\\ $\tt \descr{команда трассировки} \rightarrow tracingall \;|\; loggingall \;|\; tracingnone$ %%$\tt \descr{tracing command} \rightarrow tracingall \;|\; loggingall \;|\; tracingnone$ \end{ctabbing} \caption{Синтаксис команд} %%\caption{The syntax for commands} \index{список опций?\tdescr{список опций}}\index{переменная-картинка?\tdescr{переменная-картинка}}% %%\index{option list?\tdescr{option list}}\index{picture variable?\tdescr{picture variable}}% \label{sycmds} % is this really true? in practice, in real implementations? %\bigskip %By the way, the default for \ttindex{randomseed} is, in effect, %$\textsl{day} + \textsl{time}*\epsilon$. Unfortunately, \textsl{time} %is in minutes. \end{figure} \begin{figure}[htp] \begin{ctabbing} $\tt \descr{проверка if} \rightarrow if \descr{логическое выражение} \hbox{\tt :} \descr{сбалансированные знаки} \descr{альтернативы} fi$\\ %%$\tt \descr{if test} \rightarrow if \descr{boolean expression} \hbox{\tt :} \descr{balanced tokens} \descr{alternatives} fi$\\ $\tt \descr{альтернативы} \rightarrow \descr{пусто}$\\ %%$\tt \descr{alternatives} \rightarrow \descr{empty}$\\ $\tt \qquad \;|\; else\hbox{\tt :} \descr{сбалансированные знаки}$\\ %%$\tt \qquad \;|\; else\hbox{\tt :} \descr{balanced tokens}$\\ $\tt \qquad \;|\; elseif \descr{логическое выражение} \hbox{\tt :} \descr{сбалансированные знаки} \descr{альтернативы}$\\ %%$\tt \qquad \;|\; elseif \descr{boolean expression} \hbox{\tt :} \descr{balanced tokens} \descr{alternatives}$\\ $\tt $\\ $\tt \descr{цикл} \rightarrow \descr{заголовок цикла}\hbox{\tt :} \descr{тело цикла} endfor$\\ %%$\tt \descr{loop} \rightarrow \descr{loop header}\hbox{\tt :} \descr{loop text} endfor$\\ $\tt \descr{заголовок цикла} \rightarrow for \descr{символический знак} \hbox{\tt =} \descr{прогрессия}$\\ %%$\tt \descr{loop header} \rightarrow for \descr{symbolic token} \hbox{\tt =} \descr{progression}$\\ $\tt \qquad \;|\; for \descr{символический знак} \hbox{\tt =} \descr{список for}$\\ %%$\tt \qquad \;|\; for \descr{symbolic token} \hbox{\tt =} \descr{for list}$\\ $\tt \qquad \;|\; for \descr{символический знак} \hbox{\tt within} \descr{выражение-картинка}$\\ %%$\tt \qquad \;|\; for \descr{symbolic token} \hbox{\tt within} \descr{picture expression}$\\ $\tt \qquad \;|\; forsuffixes \descr{символический знак} \hbox{\tt =} \descr{список суффиксов}$\\ %%$\tt \qquad \;|\; forsuffixes \descr{symbolic token} \hbox{\tt =} \descr{suffix list}$\\ $\tt \qquad \;|\; forever$\\ %%$\tt \qquad \;|\; forever$\\ $\tt \descr{прогрессия} \rightarrow \descr{числовое выражение} upto \descr{числовое выражение}$\\ %%$\tt \descr{progression} \rightarrow \descr{numeric expression} upto \descr{numeric expression}$\\ $\tt \qquad \;|\; \descr{числовое выражение} downto \descr{числовое выражение}$\\ %%$\tt \qquad \;|\; \descr{numeric expression} downto \descr{numeric expression}$\\ $\tt \qquad \;|\; \descr{числовое выражение} step \descr{числовое выражение} until \descr{числовое выражение} $\\ %%$\tt \qquad \;|\; \descr{numeric expression} step \descr{numeric expression} until \descr{numeric expression} $\\ $\tt \descr{список for} \rightarrow \descr{выражение} \;|\; \descr{список for}\hbox{\tt ,} \descr{выражение}$\\ %%$\tt \descr{for list} \rightarrow \descr{expression} \;|\; \descr{for list}\hbox{\tt ,} \descr{expression}$\\ $\tt \descr{список суффиксов} \rightarrow \descr{суффикс} \;|\; \descr{список суффиксов}\hbox{\tt ,} \descr{суффикс}$ %%$\tt \descr{suffix list} \rightarrow \descr{suffix} \;|\; \descr{suffix list}\hbox{\tt ,} \descr{suffix}$ \end{ctabbing} \caption{Синтаксис для условий и циклов} %%\caption{The syntax for conditionals and loops} \index{сбалансированные знаки?\tdescr{сбалансированные знаки}}\index{суффикс?\tdescr{суффикс}}% %%\index{balanced tokens?\tdescr{balanced tokens}}\index{suffix?\tdescr{suffix}}% \label{sycondloop} \end{figure} \clearpage \let\topfraction=\svtopfrac % restore values from the start of this appendix \let\textfraction=\svtxtfrac \setcounter{topnumber}{\value{svtopnum}} \setcounter{totalnumber}{\value{svtotnum}} \section{MetaPost и \MF} %%\section{MetaPost Versus \MF} \label{MPvsMF} Из-за того, что языки \MF\index{metafont?\MF} и MetaPost имеют так много общего, пользователи-эксперты \MF\ возможно захотят пропустить большую часть объяснений из этого документа и сконцентрироваться на уникальных концепциях MetaPost. %%Since the \MF\index{metafont?\MF} and MetaPost languages have so much in %%common, expert users of \MF\ will want to skip most of the explanations %%in this document and concentrate on concepts that are unique to %%MetaPost. Сравнения в этом приложение приводятся для помощи экспертам, хорошо знакомым с {\sl The\ \MF book}, а также другим пользователям, что хотят получить пользу из более детальных объяснений работы Кнута \cite{kn:c}. %%The comparisons in this appendix are intended to help experts %%that are familiar with {\sl The\ \MF book} as well as other users that %%want to benefit from Knuth's more detailed explanations \cite{kn:c}. Вследствие того, что \MF\ предназначен для изготовления шрифтов \TeX, он имеет ряд примитивов для генерации {\tt tfm}\index{tfm file?{\tt tfm}-файл}\index{файлы!tfm?{\tt tfm}}-файлов, нужных \TeX\ для измерения символов, информации об отступах, лигатурах\index{лигатуры} и кернинге\index{кернинг}. %%Since \MF\ is intended for making \TeX\ fonts, it has a number of %%primitives for generating the {\tt tfm}\index{tfm file?{\tt tfm} %%file}\index{files!tfm?{\tt tfm}} files that \TeX\ needs for character %%dimensions, spacing information, ligatures\index{ligatures} and %%kerning\index{kerning}. MetaPost может также использоваться для генерации шрифтов и он также имеет примитивы \MF\ для создания {\tt tfm}-файлов. %%MetaPost can also be used for generating fonts, %%and it also has \MF's primitives for making {\tt tfm} files. Они перечисляются в таблице~\ref{tfmprim}. %%These are listed in Table~\ref{tfmprim}. Их объяснения могут быть найдены в документации \MF\ \cite{kn:c,kn:mf3}. %%Explanations can be found in the \MF\ %%documentation \cite{kn:c,kn:mf3}. \begin{table}[htp] $$\begin{tabular}{|l|l|} \hline команды& {\tt charlist}, {\tt extensible}, %%commands& {\tt charlist}, {\tt extensible}, {\tt fontdimen}, {\tt headerbyte} \\ & {\tt kern}, {\tt ligtable} \\ \hline операторы лигатурных& \verb!::!, \verb!=:!, \verb!=:|!, \verb!=:|>!, %%ligtable operators& \verb!::!, \verb!=:!, \verb!=:|!, \verb!=:|>!, \verb!|=:!, \verb!|=:>!, \\ таблиц& \verb!|=:|!, \verb!|=:|>!, \verb!|=:|>>!, %% & \verb!|=:|!, \verb!|=:|>!, \verb!|=:|>>!, \verb!||:! \\ \hline внутренние переменные\index{внутренние переменные}\index{переменные!внутренние}& %%internal variables\index{internal variables}\index{variables!internal}& {\tt boundarychar}, {\tt chardp}, {\tt charext}, {\tt charht}, \\ & {\tt charic}, {\tt charwd}, {\tt designsize}, {\tt fontmaking} \\ \hline другие операторы& {\tt charexists} \\ \hline %%other operators& {\tt charexists} \\ \hline \end{tabular} $$ \caption{Примитивы MetaPost для создания {\tt tfm}-файлов.} %%\caption{MetaPost primitives for making {\tt tfm} files.} \label{tfmprim} \end{table} Даже хотя MetaPost имеет примитивы для генерации шрифтов, многие такие примитивы и внутренние переменные, которые входят в Plain \MF\index{metafont?\MF}, не определены в Plain MetaPost\index{макросы Plain}. %%Even though MetaPost has the primitives for generating fonts, many of %%the font-making primitives and internal variables that are part of Plain %%\MF\index{metafont?\MF} are not defined in Plain MetaPost\index{Plain %%macros}. Вместо этого имеется отдельный макропакет {\tt mfplain}\index{mfplain?\texttt{mfplain}}, определяющий макросы, требуемые для возможности обработать через MetaPost шрифты Computer Modern Кнута, --- они показаны в таблице~\ref{mfponly} \cite{kn:e}. %%Instead, there is a separate macro package called {\tt %%mfplain}\index{mfplain?\texttt{mfplain}} that defines the macros %%required to allow MetaPost to process Knuth's Computer Modern fonts as %%shown in Table~\ref{mfponly} \cite{kn:e}. Для загрузки этих макросов поставьте ``\verb|&mfplain|'' перед именем входного файла. %%To load these macros, put %%``\verb|&mfplain|'' before the name of the input file. Это может быть сделано по приглашению {\tt **} после вызова интерпретатора MetaPost без аргументов или в командной строке, например\footnote{Синтаксис командной строки зависит от системы. Кавычки нужны в большинстве систем Unix для защиты специальных символов, подобных {\tt\&}.}, %%This can be done %%at the {\tt **} prompt after invoking the MetaPost interpreter with no %%arguments, or on a command line that looks something like %%this:\footnote{Command line syntax is system dependent. Quotes are %%needed on most Unix systems to protect special characters like %%{\tt\&}.} $$ \hbox{\verb|mpost '&mfplain' cmr10|} $$ %%$$ \hbox{\verb|mpost '&mfplain' cmr10|} $$ Командой, аналогичной \MF-команде %%The analog of a \MF\ command line like $$ \hbox{\verb|mf '\mode=lowres; mag=1.2; input cmr10'|,} $$ %%$$ \hbox{\verb|mf '\mode=lowres; mag=1.2; input cmr10'|} $$ будет %%is $$ \hbox{\verb|mpost '&mfplain \mode=lowres; mag=1.2; input cmr10'|} $$ %%$$ \hbox{\verb|mpost '&mfplain \mode=lowres; mag=1.2; input cmr10'|} $$ Результат --- это множество файлов PostScript\index{PostScript}, по одному на каждый символ шрифта. %%The result is a set of PostScript\index{PostScript} files, one for each %%character in the font. Потребуется некоторое редактирование для их соединения в загружаемый PostScript Type 3 шрифт~\cite{ad:red2}.. %%Some editing would be required in order to %%merge them into a downloadable Type~3 PostScript font~\cite{ad:red2}. \begin{table}[htp] $$ \renewcommand{\FancyVerbFormatLine}[1]{\hbox{#1}\strut} \begin{tabular}{|l|} \hline \multicolumn 1{|c|} {Определены в пакете {\tt mfplain}} \\ \hline %%{Defined in the {\tt mfplain} package} \\ \hline \begin{verbatim} beginchar font_identifier blacker font_normal_shrink capsule_def font_normal_space change_width font_normal_stretch define_blacker_pixels font_quad define_corrected_pixels font_size define_good_x_pixels font_slant define_good_y_pixels font_x_height define_horizontal_corrected_pixels italcorr define_pixels labelfont define_whole_blacker_pixels makebox define_whole_pixels makegrid define_whole_vertical_blacker_pixels maketicks define_whole_vertical_pixels mode_def endchar mode_setup extra_beginchar o_correction extra_endchar proofrule extra_setup proofrulethickness font_coding_scheme rulepen font_extra_space smode \end{verbatim} \\ \hline \multicolumn 1{|c|} {Определены как пустые операции в пакете {\tt mfplain}}\\ \hline %%{Defined as no-ops in the {\tt mfplain} package}\\ \hline \begin{verbatim} cullit proofoffset currenttransform screenchars gfcorners screenrule grayfont screenstrokes hround showit imagerules slantfont lowres_fix titlefont nodisplays unitpixel notransforms vround openit \end{verbatim} \\ \hline \end{tabular} \renewcommand{\FancyVerbFormatLine}[1]{#1} $$ \caption{Макросы и внутренние переменные, определенные только в пакете {\tt mfplain}.} %%\caption{Macros and internal variables defined only in the {\tt mfplain} %%package.} \label{mfponly} \end{table} Другим ограничением пакета {\tt mfplain} является то, что определенные переменные из Plain \MF\index{metafont?\MF} не могут получить разумных определений в MetaPost. %%Another limitation of the {\tt mfplain} package is that certain internal %%variables from Plain \MF\index{metafont?\MF} cannot be given reasonable %%MetaPost definitions. Среди них {\tt displaying}, {\tt currentwindow}, \verb|screen_rows| и \verb|screen_cols|, которые зависят от способности \MF\ изображать рисунки на экране компьютера. %%These include {\tt displaying}, {\tt %%currentwindow}, \verb|screen_rows|, and \verb|screen_cols| which depend %%on \MF's ability to display images on the computer screen. Кроме того, \verb|pixels_per_inch| является неуместным из-за того, что MetaPost использует фиксированные единицы пунктов PostScript\index{PostScript!пункт}\index{пункт!PostScript}. %%In addition, %%\verb|pixels_per_inch| is irrelevant since MetaPost uses fixed units of %%PostScript\index{PostScript!point}\index{point!PostScript} points. Основания того, что некоторые макросы и внутренние переменные\index{внутренние переменные}\index{переменные!внутренние} ничего не значат в MetaPost в том, что примитивные команды \MF\ {\tt cull}, {\tt display}, {\tt openwindow}, {\tt numspecial} и {\tt totalweight} не реализованы в MetaPost. %%The reason why some macros and internal variables\index{internal %%variables}\index{variables!internal} are not meaningful in MetaPost is %%that \MF\ primitive commands {\tt cull}, {\tt display}, {\tt %%openwindow}, {\tt numspecial} and {\tt totalweight} are not implemented %%in MetaPost. Также не реализованы ряд внутренних переменных и \tdescr{опция рисования} {\tt withweight}. %%Also not implemented are a number of internal variables as %%well as the \tdescr{drawing option} {\tt withweight}. Далее следует полный список внутренних переменных, чьи примитивные \MF-значения не имеют смысла в MetaPost: %%Here is a %%complete listing of the internal variables whose primitive meanings in %%\MF\ do not make sense in MetaPost: $$\begin{verbatim} autorounding fillin proofing tracingpens xoffset chardx granularity smoothing turningcheck yoffset chardy hppp tracingedges vppp \end{verbatim} $$ Есть еще примитив \MF, имеющий несколько иное значение в MetaPost. %%There is also one \MF\ primitive that has a slightly different meaning in %%MetaPost. Оба языка допускают команду в форме\index{special?\texttt{special}}\label{Dspecl} $$ {\tt special}\, \descr{строковое выражение} \hbox{\tt; }, $$ но \MF\ копирует строку в свой выходной файл ``обобщенного шрифта'', тогда как MetaPost интерпретирует строку как последовательность команд PostScript\index{PostScript}, которые помещаются в начало следующего выходного файла %%Both languages allow statements of the %%form\index{special?\texttt{special}}\label{Dspecl} %%$$ {\tt special}\, \descr{string expression} \hbox{\tt;} $$ %%but \MF\ copies the string into its ``generic font'' output file, while %%MetaPost interprets the string as a sequence of PostScript\index{PostScript} %%commands that are to be placed at the beginning of the next output file. В этом рассмотрении стоит заметить, что линейки в материале \TeX, включаемом через {\tt btex..etex}, в MetaPost округляются до правильного числа пикселов, согласно правилам преобразования PostScript\index{PostScript!правила преобразования}~\cite{ad:red2}. %%In this regard, it is worth mentioning that rules in \TeX\ material %%included via {\tt btex..etex} in MetaPost are rounded to the correct %%number of pixels according to PostScript\index{PostScript!conversion rules} %%conversion rules~\cite{ad:red2}. В \MF линейки напрямую не генерируются, а просто включаются в special-команды и интерпретируются позже другими программами, такими как {\tt gftodvi}\index{gftodvi?\ttt{gftodvi}}, поэтому здесь нет никаких преобразований. %%In \MF, rules are not generated %%directly, but simply included in specials and interpreted later by %%other programs, such as {\tt gftodvi}\index{gftodvi?\ttt{gftodvi}}, %%so there is no special conversion. Все другие различия между \MF\ и MetaPost --- это возможности, которые можно найти только в MetaPost. %%All the other differences between \MF\ and MetaPost are features found %%only in MetaPost. Они перечислены в таблице~\ref{mponly}. %%These are listed in Table~\ref{mponly}. Единственными командами, которые не обсуждались в предыдущих разделах и которые есть в этой таблице, являются \verb|extra_beginfig|\index{extra_beginfig?\texttt{extra\_beginfig}}\label{Dxbfig}, \verb|extra_endfig|\index{extra_endfig?\texttt{extra\_endfig}}\label{Dxefig} и {\tt mpxbreak}. %%The only %%commands listed in this table that the preceding sections do not discuss %%are %%\verb|extra_beginfig|\index{extra_beginfig?\texttt{extra\_beginfig}}\label{Dxbfig}, %%\verb|extra_endfig|\index{extra_endfig?\texttt{extra\_endfig}}\label{Dxefig}, %%and {\tt mpxbreak}. Первые две --- это строки, содержащие дополнительные команды для обработки в соответственно {\tt beginfig}\index{beginfig?\texttt{beginfig}} и {\tt endfig}\index{endfig?\texttt{endfig}}, --- они подобны \verb|extra_beginchar| и \verb|extra_endchar|, обрабатываемым в {\tt beginchar} и {\tt endchar}. %%The first two are strings that contain extra %%commands to be processed by {\tt %%beginfig}\index{beginfig?\texttt{beginfig}} and {\tt %%endfig}\index{endfig?\texttt{endfig}} just as \verb|extra_beginchar| and %%\verb|extra_endchar| are processed by {\tt beginchar} and {\tt endchar}. Файл {\tt boxes.mp}\index{boxes.mp?\texttt{boxes.mp}} использует эти возможности. %%(The file {\tt boxes.mp}\index{boxes.mp?\texttt{boxes.mp}} uses these %%features). Другой новой возможностью, приведенной в таблице~\ref{mponly}, является {\tt mpxbreak}\index{mpxbreak?\texttt{mpxbreak}}. %%The other new feature listed in Table~\ref{mponly} not listed in the %%index is {\tt mpxbreak}\index{mpxbreak?\texttt{mpxbreak}}. Она используется для разделения блоков транслированных команд \TeX\index{TeX?\TeX} или troff\index{troff} в {\tt mpx}\index{файлы!mpx?{\tt mpx}}-файлах. %%This is used %%to separate blocks of translated \TeX\index{TeX?\TeX} or %%troff\index{troff} commands in {\tt mpx}\index{files!mpx?{\tt mpx}} %%files. Она не должна затрагивать пользователей, т.к. {\tt mpx}-файлы генерируются автоматически. %%It should be of no concern to users since {\tt mpx} files are %%generated automatically. \begin{table} \centering \begin{tabular}{|c|}\hline Примитивы MetaPost, отсутствующие в \MF\\\hline %%MetaPost primitives not found in \MF\\\hline \begin{minipage}[b]{.75\linewidth}\ttfamily \begin{multicols}{3} blackpart\\ bluepart\\ bounded\\ btex\\ clip\\ clipped\\ closefrom\\ cmykcolor\\ color\\ colormodel\\ cyanpart\\ dashed\\ dashpart\\ defaultcolormodel\\ etex\\ filenametemplate\\ filled\\ fontmapfile\\ fontmapline\\ fontpart\\ fontsize\\ for within\\ greenpart\\ greypart\\ infont\\ linecap\\ linejoin\\ llcorner\\ lrcorner\\ magentapart\\ miterlimit\\ mpprocset\\ mpxbreak\\ pathpart\\ penpart\\ prologues\\ readfrom\\ redpart\\ restoreclipcolor\\ rgbcolor\\ setbounds\\ stroked\\ textpart\\ textual\\ tracinglostchars\\ troffmode\\ truecorners\\ ulcorner\\ urcorner\\ verbatimtex\\ withcmykcolor\\ withcolor\\ withgreyscale\\ withoutcolor\\ withpostscript\\ withprescript\\ withrgbcolor\\ write to\\ yellowpart \end{multicols} \end{minipage}\\\hline Переменные и макросы, определенные только в Plain MetaPost\\\hline %%Variables and Macros defined only in Plain MetaPost\\\hline \begin{minipage}[b]{.75\linewidth}\ttfamily \begin{multicols}{3} ahangle\\ ahlength\\ background\\ bbox\\ bboxmargin\\ beginfig\\ beveled\\ black\\ blue\\ buildcycle\\ butt\\ center\\ cutafter\\ cutbefore\\ cuttings\\ dashpattern\\ defaultfont\\ defaultpen\\ defaultscale\\ dotlabel\\ dotlabels\\ drawarrow\\ drawdblarrow\\ drawoptions\\ endfig\\ EOF\\ evenly\\ extra\_beginfig\\ extra\_endfig\\ green\\ image\\ label\\ labeloffset\\ mitered\\ red\\ rounded\\ squared\\ thelabel\\ white \end{multicols} \end{minipage}\\\hline \end{tabular} \caption{Макросы и внутренние переменные, определенные только в MetaPost, --- их нет в \MF.} %%\caption{Macros and internal variables defined in MetaPost but not \MF.} \label{mponly} \end{table} \bibliographystyle{plain} \bibliography{mpman-ru} \printindex \end{document} % Copyright 1990 - 1995 by AT&T Bell Laboratories. % Updated 2006 by Taco Hoekwater, Karl Berry, and others. % Permission to use, copy, modify, and distribute this software % and its documentation for any purpose and without fee is hereby % granted, provided that the above copyright notice appear in all % copies and that both that the copyright notice and this % permission notice and warranty disclaimer appear in supporting % documentation, and that the names of AT&T Bell Laboratories or % any of its entities not be used in advertising or publicity % pertaining to distribution of the software without specific, % written prior permission. % AT&T disclaims all warranties with regard to this software, % including all implied warranties of merchantability and fitness. % In no event shall AT&T be liable for any special, indirect or % consequential damages or any damages whatsoever resulting from % loss of use, data or profits, whether in an action of contract, % negligence or other tortious action, arising out of or in % connection with the use or performance of this software. % In addition, John Hobby, the original author of MetaPost and this % manual, makes the following requests: % - I request that it remain clear that I am the author of % "A User's Manual for MetaPost" and "Drawing Graphs with MetaPost". % - I request to be consulted before significant changes are made.