14-10-2023
Класс языка: | |
---|---|
Появился в: | |
Автор(ы): | |
Релиз: |
1.212 |
Тестовая версия: |
1.503 |
Типизация данных: | |
Испытал влияние: | |
Повлиял на: | |
Сайт: |
Development website |
MetaPost — интерпретатор языка программирования META, который можно использовать для создания графических иллюстраций. MetaPost был создан Джоном Хобби в то время, когда он был аспирантом у Дональда Кнута. В качестве основы была взята система создания шрифтов METAFONT[1].
На входе интерпретатору подаётся текст на META, а на выходе получается графический файл в формате PostScript[2]. Начиная с версии 1.200 MetaPost поддерживает в качестве выходного формата SVG-графику[3].
Язык META, унаследованный от METAFONT, позволяет оперировать геометрическими объектами, такими как: точка, путь, картинка и выполнять над ними различные алгебраические действия, например, сдвиг, вращение и другие линейные преобразования.
Основными отличиями MetaPost от METAFONT кроме выходного формата является наличие поддержки цвета и возможность делать текстовые вставки. Текстовые вставки создаются с помощью LaTeX, таким образом, любая конструкция, которая может быть создана в LaTeX, также может быть вставлена в картинку MetaPost. Кроме этого изначально автор MetaPost Джон Хобби разработал библиотеку для визуализации двумерных графиков[4].
Интерпретатор MetaPost (исполняемый файл mpost) вместе со стандартными макро-библиотеками распространяется как открытое программное обеспечение, обычно, в составе дистрибутивов LaTeX.
Содержание |
На вход программы mpost подаётся «META-картинка». «META-картинка» — это текстовый файл с расширением .mp (далее для краткости mp-файл) с инструкциями на языке META. В одном mp-файле можно хранить несколько описаний картинок. При компиляции с помощью mpost создаются файлы с тем же именем, что и у исходного файла, но с расширениями в виде чисел, которые указываются в декларации beginfig
. Результирующие файлы сразу можно вставлять в LaTeX-тексты с помощью обычного \includegraphics
. Для этого достаточно в заголовок tex-файла добавить команду из LaTeX-пакета graphicx:
\DeclareGraphicsRule{*}{eps}{*}{}
От «правильных» eps-файлов они отличаются только тем, что в них не «внедрены» шрифты, поэтому просмотреть их без дополнительной обработки не удастся.
Шрифты можно внедрить посредством программ latex и dvips с результатом в виде eps-файла или скрипта mptopdf с результатом в виде pdf-файла. Эти картинки уже можно использовать независимо любой программой, которая поддерживает эти векторные форматы.
Внедрить кириллицу в метки 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-файлы.
После заголовка идут описания картинок. Каждая картинка заключается между командами beginfig
и endfig
. В качестве параметра beginfig
указывается порядковый номер картинки. При компиляции этот номер будет добавляться к картинке как расширение. Пример:
%Математический 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.
В качестве базового языка, инструкции которого подаются на вход программы MetaPost, используется язык META[5].
В MetaPost можно оперировать следующими типами данных:
pencircle
)pair
, pen
, path
и picture
.Имена переменных в META могут состоять из нескольких лексем. Лексемы могут быть либо буквенными, либо числовыми. Например, переменная x1l
состоит из трёх лексем. Её можно переписать более понятным способом x[1].l
, то есть числовая лексема по сути указывает на номер элемента в массиве, а следующая за ней буква уточняет элемент структуры. Возможность опускать «[].» в написании имён переменных упрощает в некоторых случаях восприятие кода (например, — это x-координата границы линии слева по направлению движения для первой точки пути z[]
) и сокращает объём программы. Взамен, если нужны просто переменные без подобных особенностей, то придётся ограничиться только буквенными комбинациями.
Все переменные необходимо объявлять перед использованием. Исключением являются переменные типа numeric
. Массивы объявляются и используются следующим образом:
pair w[]; w:=(10,5); w[2]=w[1];
Взаимодействие переменных, чисел и операторов вполне естественно, но достаточно нетривиально. Описание этого достойно отдельного раздела. В любом случае следует действовать по правилу: если сомневаетесь, то расставляйте скобки в нужных местах.
В 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
Лого MetaPost на Википедии.
Узор из черепашек. Пример использования объекта picture (картинка).
Треугольник Паскаля. Пример вставки текста.
Траектории точек на колесе во время поступательного движения без проскальзывания. Пример использования цикла.
Пример использование линейных преобразований.
Число постов на LOR от номера месяца в году. Пример простого графика.
Фрактальные узоры. Пример рекурсии.
Распределение вещества во вселенной. Пример круговой диаграммы
Код каждого примера приведён в описании соответствующей картинки.
MetaPost имеет некоторое количество ограничений, доставшихся ему в наследство от METAFONT. Попытка обойти эти ограничения легла в основу создания программного интерпретатора Asymptote[6]. Язык, используемый Asymptote, похож на META, но вследствие перехода от синтаксиса макро-языка к синтаксису C++ гораздо более многословен и сложен. Основное преимущество Asymptote заключается в лучшей поддержке возможностей PostScript.
Functional MetaPost — DSL для графики встроенный в Haskell, который генерирует код MetaPost.[7]
METAGRAF — графический интерфейс над MetaPost. Написан на Java. По возможностям напоминает xfig. Картинки сохраняет в формате MetaPost.[8]
Среди программного окружения LaTeX аналогичной MetaPost функциональностью также обладают пакеты PSTricks и PGF/TikZ.
На основе программной базы MetaPost был создан инструмент METATYPE1 для разработки Type1 шрифтов.
Свободная типографика | |
---|---|
Гарнитуры операционных систем | GNU FreeFont • Ghostscript fonts • GNU Unifont • Droid • Roboto • Liberation • Ubuntu |
Другие гарнитуры | Allerta • Asana-Math • Bitstream Vera • Caslon Roman • Chandas • Charis SIL • Computer Modern • DejaVu • Doulos SIL • Fixedsys Excelsior • Gentium • Inconsolata • Junicode • Kochi • Linux Libertine • M+ • Nimbus Mono • Nimbus Roman • Nimbus Sans • PT • Tiresias • Ubuntu-Title • Terminus |
Программное обеспечение | FontForge • FreeType • METAFONT • MetaPost • METATYPE1 • Pango • TeX |
Лицензии | OFL • Ubuntu Font Licence |
Группы и люди | Дональд Кнут • Open Font Library |
Свободные гарнитуры Unicode Список свободных гарнитур • Список свободных гарнитур Unicode |
MetaPost.