Interested Article - MetaPost

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

На входе интерпретатору подаётся текст на META, а на выходе получается графический файл в формате PostScript . Начиная с версии 1.200 MetaPost поддерживает в качестве выходного формата SVG -графику .

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

Основными отличиями MetaPost от METAFONT кроме выходного формата является наличие поддержки цвета и возможность делать текстовые вставки. Текстовые вставки создаются с помощью TeX , таким образом, любая конструкция, которая может быть создана в TeX, также может быть вставлена в картинку MetaPost. Кроме этого изначально автор MetaPost разработал библиотеку METAOBJ (“metapost Objects”) для визуализации двумерных графиков .

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

MetaPost-конвейер

MetaPost-конвейер

На вход программы mpost подаётся «META-картинка». «META-картинка» — это текстовый файл с расширением .mp (далее для краткости mp-файл) с инструкциями на языке META. В одном mp-файле можно хранить несколько описаний картинок. При компиляции с помощью mpost создаются файлы с тем же именем, что и у исходного файла, но с расширениями в виде чисел, которые указываются в декларации beginfig . Результирующие файлы сразу можно вставлять в LaTeX-тексты с помощью обычного \includegraphics . Для этого достаточно в заголовок tex-файла добавить команду из LaTeX-пакета graphicx:

\DeclareGraphicsRule{*}{eps}{*}{}

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

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

Кириллица и MetaPost

Внедрить кириллицу в метки MetaPost можно только с помощью LaTeX. Для этого mp-файл должен иметь примерно следующий заголовок:

verbatimtex 
\documentclass[12pt]{minimal} 
%простейшая кириллизация
\usepackage[koi8-r]{inputenc}
\usepackage[english,russian]{babel}
\begin{document}
etex;

Этот заголовок будет использоваться каждый раз, когда MetaPost доходит до текста, находящегося между метками btex и etex . Если для создание метки требуется какой-либо пакет LaTeX, то, соответственно, необходимо добавить этот пакет в заголовок стандартным образом.

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

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

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

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

Hello World
Hello World
%Математический 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 ;

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

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

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

#временный файл
tmp_file := tmp_file
#программы
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).* 
#Зависимости для mpost-картинок.
#По одной для каждого числа из beginfig
%.1:%.mp 
	$(MPOST) $<
 %.64:%.mp 
	$(MPOST) $<

Чтобы на выходе получить готовую eps-картинку с уже «внедрёнными» шрифтами, которую можно вставить уже куда угодно, достаточно выполнить следующую команду:

make <имя mp-файла>.<номер картинки>.[eps|pdf]

Обычно mp-файлам даются короткие имена.

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

Скрипт для каждого beginfig(n) -блока сделает файлы filen.eps и filen.pdf , где file — имя исходного MetaPost-файла, n — номер блока. В скрипте предусмотрено размещения полученных файлов в отдельных каталогах. Имена каталогов задаются переменными EPS_DIR и PDF_DIR. Если каталогов с такими именами не существуют, то скрипт автоматически создаёт их.

#!/bin/sh
# Скрипт для превращения MetaPost файла в EPS и PDF рисунки

# каталоги для хранения 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

Скрипт надо сделать исполняемым:

chmod +x ./mp2pdf.sh

Использование:

./mp2pdf.sh file.mp

Пример MetaPost-файла для тестирования:

%% Шаблон для 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.

Язык META

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

В 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 , то есть числовая лексема по сути указывает на номер элемента в массиве, а следующая за ней буква уточняет элемент структуры. Возможность опускать «[].» в написании имён переменных упрощает в некоторых случаях восприятие кода (например, — это x-координата границы линии слева по направлению движения для первой точки пути z[] ) и сокращает объём программы. Взамен, если нужны просто переменные без подобных особенностей, то придётся ограничиться только буквенными комбинациями.

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

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

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

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

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

В языке присутствуют операторы цикла, условных переходов и тому подобное. Отличительной особенностью META является возможность решать системы линейных уравнений. Например, выражение вида , означает, что точка C находится ровно посередине между точками А и B.

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

 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.

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

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

 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

Примеры

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

Известен пример нестандартного применения программы. С 1996 по 1999 год авторы спелеопрограммы Therion написали DSL METAPOST для преобразования 2D-карт в 3D-модели пещер, а все подписи реализовали в формате TEX .

Аналоги

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

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

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

Среди программного окружения LaTeX аналогичной MetaPost функциональностью также обладают пакеты PSTricks и .

На основе программной базы MetaPost был создан инструмент для разработки Type1 шрифтов.

Примечания

  1. Дата обращения: 4 января 2011. Архивировано из 15 мая 2012 года.
  2. от 15 мая 2012 на Wayback Machine MetaPost is a picture-drawing language very much like METAFONT except with PostScript output. The language provides access to all major features of Level 1 PostScript® and it has facilities for integrating graphics with typeset text.
  3. . Дата обращения: 4 января 2011. 5 сентября 2014 года.
  4. Дата обращения: 4 января 2011. Архивировано из 15 мая 2012 года.
  5. . Дата обращения: 31 июля 2022. 31 июля 2022 года.
  6. от 4 сентября 2016 на Wayback Machine // Linux Format 76 (февраль 2006)
  7. . therion.speleo.sk . Дата обращения: 25 ноября 2022. 4 декабря 2022 года.
  8. . Хабр . Дата обращения: 25 ноября 2022. 24 ноября 2022 года.
  9. Дата обращения: 4 января 2011. 17 июля 2011 года.
  10. . Дата обращения: 3 сентября 2006. Архивировано из 13 ноября 2008 года.
  11. . Дата обращения: 3 сентября 2006. 31 августа 2006 года.

Ссылки

  • (англ.) . T E X users group . Дата обращения: 1 января 2011. Архивировано из 8 февраля 2012 года.
  • . (2006). — Цикл статей в журнале Linux Format . Дата обращения: 1 января 2011. Архивировано из 20 марта 2012 года.
  • и участники проекта развития MetaPost. (англ.) . T E X users group (19 октября 2010). Дата обращения: 1 января 2011. Архивировано из 8 февраля 2012 года.
  • и участники проекта развития MetaPost/ Пер. Владимира Лидовского. . CTAN (10 мая 2008). Дата обращения: 5 января 2011. Архивировано из 8 февраля 2012 года.
  • André Heck. (англ.) . MAPS (2005). Дата обращения: 5 января 2011. Архивировано из 8 февраля 2012 года.
  • Vincent Zoonekynd. (фр.) (2003). — Большое количество примеров. Дата обращения: 5 января 2011. Архивировано из 8 февраля 2012 года.
  • Jean-Michel Sarlat. (фр.) (11 декабря 2005). — Фракталы, геометрия, картинки «под Эшера ». Дата обращения: 5 января 2011. Архивировано из 8 февраля 2012 года.
  • Создание векторных картинок в MetaPost

Литература

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



Источник —

Same as MetaPost