MetaPost

Материал из Seo Wiki - Поисковая Оптимизация и Программирование
Перейти к навигацииПерейти к поиску
Файл:MetaPost на Википедии.png
Лого MetaPost на Википедии

MetaPost — интерпретатор языка программирования META, который можно использовать для создания графических иллюстраций. MetaPost был создан Джоном Хобби в то время, когда он был аспирантом у Дональда Кнута. В качестве основы была взята система создания шрифтов METAFONT.

На входе интерпретатору подаётся текст на META, а на выходе получается графический файл в формате PostScript. Язык META, унаследованный от METAFONT, позволяет оперировать геометрическими объектами, такими как: точка, путь, картинка и выполнять над ними различные алгебраические действия, например, сдвиг, вращение и другие линейные преобразования.

Основными отличиями MetaPost от METAFONT кроме выходного формата является наличие поддержки цвета и возможность делать текстовые вставки. Текстовые вставки создаются с помощью LaTeX, таким образом, любая конструкция, которая может быть создана в LaTeX, также может быть вставлена в картинку MetaPost.

Интерпретатор MetaPost (исполняемый файл mpost) вместе со стандартными макро-библиотеками распространяется как открытое программное обеспечение, обычно, в составе дистрибутивов LaTeX.

MetaPost-конвейер

Файл:MetaPost конвейер.png
MetaPost-конвейер

На вход программы mpost подаётся «META-картинка». «META-картинка» — это текстовый файл с расширением .mp (далее для краткости mp-файл) с инструкциями на языке META. В одном mp-файле можно хранить несколько описаний картинок. При компиляции с помощью mpost создаются файлы с тем же именем, что и у исходного файла, но с расширениями в виде чисел, которые указываются в декларации beginfig. Результирующие файлы сразу можно вставлять в LaTeX-тексты с помощью обычного \includegraphics. Для этого достаточно в заголовок tex-файла добавить команду из LaTeX-пакета graphicx: <source lang="latex">\DeclareGraphicsRule{*}{eps}{*}{}</source> От «правильных» eps-файлов они отличаются только тем, что в них не «внедрены» шрифты, поэтому просмотреть их без дополнительной обработки не удастся.

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

Кириллица и MetaPost

Внедрить кириллицу в метки MetaPost можно только с помощью LaTeX. Для этого mp-файл должен иметь примерно следующий заголовок: <source lang="latex"> verbatimtex \documentclass[12pt]{minimal} %простейшая кириллизация \usepackage[koi8-r]{inputenc} \usepackage[english,russian]{babel} \begin{document} etex; </source> Этот заголовок будет использоваться каждый раз, когда MetaPost доходит до текста, находящегося между метками btex и etex. Если для создание метки требуется какой-либо пакет LaTeX, то, соответственно, необходимо добавить этот пакет в заголовок стандартным образом.

Для того, чтобы при создании надписи использовался именно latex, интерпретатор mpost должен запускаться с опцией -tex=latex. Если эта опция отсутствует, то информацию о том, что следует запускать, mpost ищет в переменной окружения TEX. По умолчанию вместо latex запускается tex.

Если в тексте определяется переменная prologues, то она должна быть равна 0. В этом случае все необходимые шрифты «подшиваются» к картинке в момент, когда создаются eps и pdf-файлы.

Структура mp-файла

После заголовка идут описания картинок. Каждая картинка заключается между командами beginfig и endfig. В качестве параметра beginfig указывается порядковый номер картинки. При компиляции этот номер будет добавляться к картинке как расширение. Пример:

Hello World
Hello World

<source lang="latex"> %Математический HelloWorld beginfig(3) ;

for alpha:=90 step -9 until 0:
 label(btex \(f(x)=
 \frac{1}{\sqrt{2\pi}\,\sigma}
   \int\limits_{-\infty}^{\infty}
     e^{-\frac{x^2}{2\sigma^2}}dx\) etex
   scaled (5*(1-alpha/100)) rotated alpha,(0,0))
withcolor(max(1-alpha/45,0)*red+min(alpha/45,2-alpha/45)*green+max(alpha/45-1,0)*blue);
endfor;

endfig ; </source>

Файл должен закончиться командой end. или bye. Эти команды дают понять интерпретатору mpost, что обработка закончена.

Автоматизация

Для автоматизации получения картинок с помощью MetaPost можно использовать следующий Makefile: <source lang="make">

  1. временный файл

tmp_file := tmp_file

  1. программы

LATEX := latex MPOST := mpost -tex=latex DVIPS := dvips MPTOPDF := mptopdf MV := mv all: @echo "run: make mpfile.n.[eps|pdf] - where n is the picture number" %.eps:  % @echo "\documentclass[12pt]{minimal}">$(tmp_file).tex @echo "\usepackage[koi8-r]{inputenc}">>$(tmp_file).tex @echo "\usepackage[english,russian]{babel}">>$(tmp_file).tex @echo "\usepackage{graphicx}">>$(tmp_file).tex @echo "\DeclareGraphicsRule{*}{eps}{*}{}">> $(tmp_file).tex @echo "\nofiles">>$(tmp_file).tex @echo "\begin{document}">> $(tmp_file).tex @echo "\thispagestyle{empty}">> $(tmp_file).tex @echo "\includegraphics{$(basename $@)}">> $(tmp_file).tex @echo "\end{document}">> $(tmp_file).tex @$(LATEX) $(tmp_file) @$(DVIPS) -E -o $@ $(tmp_file) @rm $(tmp_file).* %.pdf:  % @$(MPTOPDF) $< @$(MV) `echo $< | sed -e "s/\.\([0-9]\+\)$$/-\1.pdf/"` $<.pdf clean: @rm -f mpx* *~ *.log *.mpx @rm -f $(tmp_file).*

  1. Зависимости для mpost-картинок.
  2. По одной для каждого числа из beginfig

%.1: %.mp $(MPOST) $<

%.64: %.mp $(MPOST) $< </source> Чтобы на выходе получить готовую eps-картинку с уже «внедрёнными» шрифтами, которую можно вставить уже куда угодно, достаточно выполнить следующую команду: <source lang="bash"> make <имя mp-файла>.<номер картинки>.[eps|pdf] </source> Обычно mp-файлам даются короткие имена.

Как вариант, предлагается shell-скрипт (mp2pdf.sh), который делает практически то же самое. Предполагается использование Linux (или подобной ОС).

Скрипт для каждого beginfig(n)-блока сделает файлы filen.eps и filen.pdf, где file — имя исходного MetaPost-файла, n — номер блока. Для удобства (?) предусмотрено расталкивание полученных файлов по отдельным каталогам. <source lang="bash">

  1. !/bin/sh
  2. Скрипт для превращения MetaPost файла в EPS и PDF рисунки
  1. каталоги для хранения eps- и pdf-файлов

EPS_DIR=./eps PDF_DIR=./pdf TMP_FILE=tmp

if "$@" == ""; then

 echo 
 echo Скрипт обрабатывает mp-файл, создает eps- и pdf-файлы и
 echo перемещает их соответственно в каталоги $EPS_DIR и $PDF_DIR
 echo Использование: ./mp2pdf.sh file.mp
 echo
 exit

fi

if [ ! -d $EPS_DIR ]; then

 echo ======== Создание каталога для eps-файлов 
 mkdir $EPS_DIR

fi if [ ! -d $PDF_DIR ]; then

 echo ======== Создание каталога для pdf-файлов
 mkdir $PDF_DIR

fi

echo ======== Исходный файл: $@

list=`grep beginfig $1 | sed -e 's/beginfig(//' -e 's/);//'` echo ======== Список блоков: $list

echo ======== Запуск mpost... mpost -tex=latex $1

for i in $list # цикл по блокам beginfig() do

epsi=${1%mp}$i
eps=${1%.mp}${i}.eps
pdf=${1%.mp}${i}.pdf
echo Блок ${i}: ' >> ' $epsi ' >> ' $eps ' >> ' $pdf

if [ ! -e $epsi ]; then

 echo
 echo Ошибки при обработке mp-файла!
 echo
 exit

else

 echo ======== MetaPost ===== Ok!

fi

echo ======== Генерация временного LaTeX-файла... echo \\documentclass[12pt]{article} > ${TMP_FILE}.tex echo \\usepackage{mathtext} >> ${TMP_FILE}.tex echo \\usepackage{amsmath} >> ${TMP_FILE}.tex echo \\usepackage[T2A]{fontenc} >> ${TMP_FILE}.tex echo \\usepackage[koi8-r]{inputenc} >> ${TMP_FILE}.tex echo \\usepackage[english,russian]{babel} >> ${TMP_FILE}.tex echo \\usepackage{graphics} >> ${TMP_FILE}.tex echo \\begin{document} >> ${TMP_FILE}.tex echo \\pagestyle{empty} >> ${TMP_FILE}.tex echo \\includegraphics{${epsi}} >> ${TMP_FILE}.tex echo \\end{document} >> ${TMP_FILE}.tex

echo ======== Запуск LaTeX... latex ${TMP_FILE}

if [ ! -e ${TMP_FILE}.dvi ]; then

 echo
 echo ======== Не найден dvi-файл!
 echo
 exit

else

 echo ======== LaTeX ===== Ok!

fi echo ======== Запуск dvips... dvips -E ${TMP_FILE} -o $eps

echo ======== Запуск epstopdf... epstopdf $eps

if -e $pdf; then

mv $eps $EPS_DIR 
mv $pdf $PDF_DIR
echo ======== Перенос $eps и $pdf в нужное место...

fi

echo ======== Зачистка... rm *.log *.mpx ${TMP_FILE}.* *.aux *.dvi *.tex $epsi 2>>/dev/null

done </source> Скрипт надо сделать исполняемым: <source lang="bash"> chmod +x ./mp2pdf.sh </source> Использование: <source lang="bash"> ./mp2pdf.sh file.mp </source> Пример MetaPost-файла для тестирования: <source lang="latex"> %% Шаблон для mp-файлов prologues:=0;

% LaTeX; работает вместе с "mpost -tex=latex file.mp" (см. скрипт выше) verbatimtex \documentclass[12pt]{article} \usepackage{mathtext} \usepackage{amsmath} \usepackage[T2A]{fontenc} \usepackage[koi8-r]{inputenc} \usepackage[english,russian]{babel} \begin{document} etex;

beginfig(1); draw (0,0)--(0,100)--(100,100)--(100,0)--cycle; label(btex Метка: $\alpha_1$ etex, (50,50)); endfig;

end. </source>

Немного о META

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

В MetaPost можно оперировать следующими типами данных:

  • boolean — логический (Истина/Ложь)
  • numeric — обычные числа
  • pen (перо) — то, чем компьютер рисует (в подавляющем большинстве случаев используется круглое перо pencircle)
  • pair (точка) — пара чисел (x, y) в случае декартовых координат или R*dir(α) в случае полярных координат
  • path (путь) — набор точек с описанием типа соединений между ними
  • color (цвет) — тройка чисел (r, g, b) соответствует цветовой модели RGB
  • picture (картинка) — совокупность путей и точек
  • string (строка) — ASCII строка,
  • transform (линейные преобразования) — линейные преобразования, которые можно применять к объектам типа pair, pen, path и picture.

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

Все переменные необходимо объявлять перед использованием. Исключением являются переменные типа numeric. Массивы объявляются и используются следующим образом: <source lang="latex">

pair w[];
w1:=(10,5);
w[2]=w[1];

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

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

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

В языке присутствуют операторы цикла, условных переходов и тому подобное. Отличительной особенностью META является возможность решать линейные уравнения. Например, выражение вида <math>C=1/2[A,B]</math>, означает, что точка C находится ровно посередине между точками А и B.

Программу mpost можно использовать в режиме калькулятора для вычислений на языке META. Это позволяет проверить правильность ваших предположений относительно языка. Пример сеанса представлен ниже: <source lang="text">

baldin@evgueni:~$ mpost
This is MetaPost, Version 0.901 (Web2C 7.5.5)
**\relax
*a:=10;
*b:=8;
*c:=a+-+b;
*show c;
>> 6
*show (3-sqrt 5)/2;
>> 0.38197
*show angle(1,sqrt 3);
>> 60.00008
*show 2**10;
>> 1024.00003
*show infinity;
>> 4095.99998
*show epsilon;
>> 0.00002
*show infinity-infinity;
>> 0
*end
Transcript written on mpout.log.

</source> После вывода приглашения ** следует набрать команду \relax. Далее можно вводить команды MetaPost. Делать это надо аккуратно, так как этот режим не поддерживает «истории команд». В начале не предполагалось, что MetaPost можно использовать и так тоже. С помощью команды show можно вывести результат на экран. Закончить сеанс можно с помощью команды end. Обратите внимание, что на просьбу вывести бесконечность (infinity) MetaPost выдал 4095.99998 — это максимальное значение, которое может принимать переменная типа numeric. Причём в процессе вычисления результат может превышать «бесконечность», но ответ должен быть меньше или равен ей, иначе будет выдана ошибка. Минимальный шаг изменения типа numeric равен epsilon, или, точнее, 1/256/256. При создании рисунка эти ограничения не существенны, так как диапазон изменения чисел вполне велик, чтобы вместить все элементы. Но в любом случае это тоже необходимо учитывать.

Если необходимо вычислить однострочное выражение, то на первоначальное приглашение ** можно ввести expr. В этом случае mpost считает файл expr.mf и на любое действие будет выдаваться ответ: <source lang="text">

baldin@evgueni:~$ mpost
This is MetaPost, Version 0.901 (Web2C 7.5.5)
**expr
(/usr/local/texlive/2005/texmf-dist/metafont/base/expr.mf
gimme an expr: 2(a+3b)-2b
>> 4b+2a
gimme an expr: 1/3[a,b]
>> 0.33333b+0.66667a

</source>

Примеры

Код каждого примера приведён в описании соответствующей картинки.

Аналоги

MetaPost имеет некоторое количество ограничений, доставшихся ему в наследство от METAFONT. Попытка обойти эти ограничения легла в основу создания программного интерпретатора Asymptote. Язык, используемый Asymptote, похож на META, но вследствие перехода от синтаксиса макро-языка к синтаксису C++ гораздо более многословен и сложен. Основное преимущество Asymptote заключается в лучшей поддержке возможностей PostScript.

Functional MetaPost — DSL для графики встроенный в Haskell, который генерирует код MetaPost.[1]

METAGRAF — графический интерфейс над MetaPost. Написан на Java. По возможностям напоминает xfig. Картинки сохраняет в формате MetaPost.[2]

Примечания

Ссылки

Литература

  • Дональд Кнут. Всё про METAFONT = The METAFONTbook. — М.: Вильямс, 2003. — 384 с. — ISBN 5-8459-0442-0
  • М. Гуссенс, С. Ратц, Ф. Миттельбах. Путеводитель по пакетам LaTeX и его графическим расширениям = The LaTeX Graphics Companion. — М.: Мир, 2002. — 621 с. — ISBN 5-03-003388-2

de:MetaPost en:MetaPost es:MetaPost fr:MetaPost it:MetaPost ja:MetaPost pl:MetaPost sv:MetaPost uk:MetaPost zh:MetaPost

Если вам нравится SbUP.com Сайт, вы можете поддержать его - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 и ещё....