Changes

Jump to navigation Jump to search
m
added \startTEXpage[pagestate=start] %`pagestate=start` is needed to have incremented page numbering of the pdf
< [[Math]]__TOC__MetaPost is a graphical programming language, [[MetaFun]]based on Donald Knuth's MetaFont. Normally MP graphics are converted to PostScript and used with dvips, but ConTeXt can use it directly with PDF (see the[[Graphics]http://www.pragma-ade.nl/general/sources/mptopdf.pdf MP to PDF]manual).
* John HobbyMetaPost is ConTeXt's page: http://cmnative graphics language.bell[[MetaFun -labs.com/who/hobby/MetaPost.html* Current development: http://foundry.supelec.fr/projects/metapost/ in ConTeXt]] is a MetaPost module by Hans Hagen that adds a lot of extra features; it is a graphical programming languageenabled by default, based on Donald Knuthso one could say that MetaFun is ConTeXt's MetaFont. Normally MP graphics are converted to PostScript and used with dvips, but ConTeXt can use it directly with PDF (see [http://www.pragma-ade.com/general/sources/mptopdf.pdf MPtoPDF])default dialect of MetaPost.
MetaPost is ConTeXt's "native" graphics mode, see [[MetaFun]].  == Documentation & Tutorials ==
* [http://www.tug.org/docs/metapost/mpman.pdf A User's Manual for MetaPost] <!-- http://cm.bell-labs.com/who/hobby/cstr_162.pdf has its pages reversed -->
* [http://remote.science.uva.nl/~heck/Courses/mptut.pdf Learning METAPOST by doing] ([http://maps.aanhet.net/maps/pdf/32_14.pdf this] and [http://maps.aanhet.net/maps/pdf/32_15.pdf this link] are not working)
* [[manual:metafun-s.pdf|MetaFun]]
* [http://tex.loria.fr/prod-graph/zoonekynd/metapost/metapost.html Lots of examples]
* [[Color in MetaPost]] describes how to get color mixtures, TeX colors, and transparent effects in MetaPost graphics.
 
= Using MetaPost in ConTeXt =
 
With {{cmd|startuseMPgraphic}}, you define a piece of graphics code that is processed anew every time the graphic is placed with {{cmd|useMPgraphic}}. Further commands are described at [[MetaFun - MetaPost in ConTeXt]].
 
<context source=yes>
\def\mycolor{.625red}
 
\startuseMPgraphic{name}
fill fullcircle scaled 20pt withcolor \mycolor;
\stopuseMPgraphic
 
red: \useMPgraphic{name}
 
\def\mycolor{.625blue}
blue: \useMPgraphic{name}
</context>
== Different Packages, Extensions & Applications of Metapost ==
* [http://www.ctan.org/tex-archive/graphics/metaplot/ MetaPlot] - graph drawing
* [http://www.ctan.org/tex-archive/graphics/metapost/contrib/macros/metaobj/ MetaObj] - object-oriented drawing, see also the page about [[MetaObj and Labels]]
* [http://stud4.tuwien.ac.at/~e0225855/finomaton/finomaton.html finomaton] - drawing finite state automata
* [http://www-math.univ-poitiers.fr/~phan/statsmac.html statsmac] - metapost macros for statistics graphs
* [http://metauml.sourceforge.net/ MetaUML] - MetaPost library for typesetting UML diagrams
* [http://vigna.dsi.unimi.it/metagraph/ METAGRAPH] - drawing (un)directed graphs
=== 3D support ===
* [http://matagalatlante.org/nobre/featpost/doc/featexamples.html FeatPost]
* [http://www.gnu.org/software/3dldf/LDF.html 3DLDF]
{{todo|needs major review}}
== MetaPost relatives ===== Font Creation ===
* [[MetaType1]], see [http://www.ctan.org/tex-archive/fonts/utilities/metatype1/ CTAN]
=== 3D drawing ===
* [http://asymptote.sourceforge.net/ Asymptote] - inspired by MetaPost & fully generalizes MetaPost path construction algorithms to three-dimensions
=Testing plain MetaPost = Using MP To test whether MetaPost is installed on your system, create a file called {{code|test.mp}}:  beginfig(1) draw fullcircle scaled 3cm ; endfig ; end ; * apply MetaPost on the testfile  mp test.mp or mpost test.mp * that should create a postscript file test.1* open test.1 with a postscript viewer like Ghostview, Okular, … You should see a circle. = Testing MetaPost embedded in ConTeXt = If MetaPost is installed on your system and working correctly, you can   \starttext \startMPcode draw fullcircle scaled 3cm; \stopMPcode \stoptext * for mkii you need to have write18 support enabled and run texexec --pdf test.tex * for mkiv run context test.tex * that should create a pdf file test.pdf* open test.pdf with a pdf viewer like Adobe Acrobat, Okular... You should see a circle. =Text in MetaPost = Text that is typeset using `textext` or `btex … etex` adapts to the body font. However, when `label("Foo", pair)` or `"Foo" infont defaultfont` is used, which is not the recommended way, the text is typeset using the font `MetafunDefault`, which can be changed if desired. Example: <context mode="mkiv" source="yes" text="Gives:">\starttext \startMPcode label("Foo", origin); draw textext("Bar") yshifted -LineHeight; \stopMPcode  \definefontsynonym [MetafunDefault] [Bold*default]  \switchtobodyfont [pagella, 18pt]  \startMPcode label("Foo", origin); draw textext("Foo") yshifted -LineHeight; \stopMPcode\stoptext</context> The first recommended way to typeset text is to use the `textext` macro and change the font using {{cmd |setupMPinstance}}. = Repetition of a Text Element to Fill a Bar Using textext = Imagine you want to create a frame which consists out of one glyph or a combination of different glyphs in order to make a decorative border. For this purpose a series of such elements should be placed on the bar as pictures, evenly spaced. Probably you want to have at the end of the bar a usable graphicdifferent glyph inserted as a picture too. The following code is working but the last picture is not the expected glyph. Such One would expect 14 times the "?" and at the end of the bar a graphic "*": <context mode="mkiv" source="yes" text="Gives:">\starttext \startMPpage picture PicA ; PicA := textext("*"); picture PicB ; PicB := textext("?");  numeric Step ; Step := 2cm div bbwidth(PicB) ;  for i = 1 upto Step : draw PicB shifted (i*5mm,0) ; endfor ; draw PicA ; \stopMPpage\stoptext</context> What you get is 15 "?" but no "*"! In order to get this corrected one needs to calculate the boundingbox of the "?" on beforehand. Hans Hagen provided this solution on 14-10-2014. <context mode="mkiv" source="yes" text="Gives:">\starttext \startMPcalculation path PicX ; PicX := boundingbox textext("?") ; \stopMPcalculation  \startMPpage picture PicA ; PicA := textext("*"); picture PicB ; PicB := textext("?");  numeric Step ; Step := 2cm div bbwidth(PicX) ; % numeric Step ; Step := 2cm div bbwidth(PicB) ;  for i = 1 upto Step : draw PicB shifted (i*5mm,0) ; endfor ; draw PicA ; \stopMPpage\stoptext </context> Now you get 14 "?" and the "*". == A Full Example == <context mode="mkiv" source="yes" text="Gives:">\setupbodyfont [8pt] \defineoverlay[Myframe][\reuseMPgraphic{Frame}] \setuppapersize[A8][A8] \setuplayout [topspace=5mm, backspace=5mm, height=middle, width=middle, header=0pt, footer=0pt] \starttext % ======== Definition of the frame in Metafun ==========\startMPcalculation path PicX ; PicX := boundingbox textext("= : =") ;\stopMPcalculation \startreusableMPgraphic{Frame} numeric u,v,xshift,yshift,picwidth,remnant,nelements;  u := OverlayWidth; v := OverlayHeight; path p,w; p := unitsquare xscaled u yscaled v; w := fullcircle scaled 8pt; picture Edgepic,Linepic[]; color edgedotcolor,linelementcolorA; edgedotcolor := blue; linelementcolorA := red;  Linepic[1] := textext("\rotate[rotation=90]{= : =}"); Linepic[2] := textext("= : ="); Edgepic := textext("o"); %Calculations for the horizontal frame-element placement: % In order to make this work, the width of the line element needs to be calculated anew each on beforehand. % path PicX; PicX := textext(")("); picwidth := bbwidth(PicX); nelements := u div picwidth; remnant := u mod picwidth; xshift := picwidth + remnant/nelements;   Linepic[3] := Linepic[2] shifted (0.5*picwidth,0);  for a = llcorner p, ulcorner p : for i = 1 upto nelements : draw Linepic[3] shifted ((xpart a + (i-1)*xshift),ypart a) withcolor linelementcolorA; endfor; endfor; %Calculations for the vertical frame-element placement: picheight := bbwidth(PicX); nelements := v div picheight; remnant := v mod picheight; yshift := picheight + remnant/nelements; Linepic[4]:= Linepic[1] shifted (0,0.5*picheight); for a = llcorner p, lrcorner p : for i = 1 upto nelements: draw Linepic[4] shifted (xpart a,ypart a + (i-1)*yshift) withcolor linelementcolorA; endfor; endfor;  for i = llcorner p, lrcorner p,ulcorner p,urcorner p : fill w shifted (xpart i,ypart i) withcolor white; draw Edgepic shifted (xpart i,ypart i) withcolor edgedotcolor; endfor; % For frame-element positioning checking:% draw p;%\stopreusableMPgraphic % ========== \startframedtext [width=0.8\textwidth,height=0.8\textheight,frame=off,background=Myframe, align={middle,lohi}] The butterfly counts not months but moments, and has time it enough. \blank {\tfx Rabindranath Tagore}\stopframedtext\stoptext </context>  There is one important remark: The MPcalculation and the drawing itself must be inside \starttext ... \stoptext. = Layer sets as individual pages =The following ConTeXt code example can be usedto create a series of layered Metapost graphics and generate multiple pages with different combinations of these layers. Each page represents a different composition of the defined layers. Use cases are when you need to compose manually your layer sets.  == Base or Invisible Layer ==The code begins by defining a base or invisible layer called "base" using the `\startuseMPgraphic` command. An In this layer, various components are defined, such as paths, colors, and coordinates. These components will be used to draw the images in subsequent layers, but they're not drawn yet, thus this layer is "invisible". == Layer Definitions ==After defining the base layer, several other layers are defined using the `\startuseMPgraphic` command. Each layer is given a unique name, in our example:the names are such as "layerA" "layerW" or "layerM". These layers are created as images using the `picture` environment. Each image consists of drawn elements. In our example, the elements are filled squares with a specific color and a label. == Finishing Layer ==The purpose of the finishing layer in our ConTeXt code is to add the final touches to the drawn layers and to clip the graphic to the same frame. It also includes the addition of page numbering to each page with the help of a Metapost variable, in our case "mypagenumber". We need this method because apparently, it is not possible to use the ConTeXt page numbering on a Metapost page. The finishing layer needs to be applied after drawing all the other layers. == Layer Sets ==The before defined layers can be "set" (selected and combined) manually together, to become a layer set. They are layered on top of each other according to the order of appearance. The last layer is put on top of (and might cover) the previous one. Some subgroups or intermediate results of our "setting" or "putting together" will be reused again during the process. Selected intermediate results will be shown as such on individual pages, like a photo documentation of your setting procedure. Other intermediate results will be reused without ever being shown on an individual page. To be spared from doing such steps over and over again, they are stored, either as layersetpage plus a number, as a mere layerset, or as a layer subset. All of them are defined using the `\startuseMPgraphic` command. Each of them includes a specific set of the previously defined layers (or if you want, also drawn elements, as the "special!" label in layersetpage4). The layersets which are shown as a page are numbered, starting from one. == Drawing the Pages ==Finally, the code uses a loop to draw each layerset page onto its own page using the `\dorecurse` command. The loop iterates from 1 to a manually defined number, and for each iteration, it uses the `\useMPgraphic` command to draw the corresponding layersetpage, to which it is also passing the Metapost variable "mypagenumber". The resulting output is a series of pages, each displaying a different selection and combination of the defined layers.
<texcode>
\startuseMPgraphic{namebase}%Here in the base, we define the components we will use to draw our imagesnumeric u; u = 1cm; numeric framefactor; framefactor = 3.4;path TheFrame ; TheFrame := fullsquare xyscaled (framefactor*u, framefactor*u) ; %Needed to have for every page the same dimensions. Use (sqrt(2)*framefactor*u, framefactor*u) for DIN A Landscape ratio of the dimensions. color stone_color; stone_color = 1/256(199,199,199);color light_teal_color; light_teal_color = 1/256(154,209,189); z1 = (-u,-u) ;z2 = (u,-u) ;z3 = (-u,u) ;z4 = (u,u) ;z5 = (-.5u,0);z6 = (.8u,0); picture layerA;layerA:=image(fill fullsquare scaled u shifted(z1) withcolor stone_color;label("A", z1);); picture layerW;layerW:=image(fill fullsquare scaled u shifted(z2) withcolor stone_color;label("W", z2);); picture layerM;layerM:=image(fill fullsquare scaled u shifted(z3) withcolor blue;label("M", z3) withcolor white;); picture layerC;layerC:=image( fill fullcircle fullsquare scaled 1.5u shifted(z4) withcolor transparent(1, .8, green);label("C", z4);); picture layerY;layerY:=image(fill fullsquare scaled 2u shifted(z5) withcolor light_teal_color;label("Y", z5);); picture layerU;layerU:=image(fill fullsquare rotated 30 scaled 2u shifted(z4) withcolor transparent(1, .5, red);label("U", z4);); picture layerV;layerV:=image(fill fullsquare rotated 10 scaled 1.4u shifted(z6) withcolor transparent(1, .7, yellow);label("V", z6););\stopuseMPgraphic %base \startuseMPgraphic{finishing} %This is needed to clip the graphic to the same frame and to add the page numbering. Both have to happen after drawing the layers. draw TheFrame withpen pencircle scaled 5cm .25u withcolor magenta ;draw textext(decimal(\MPvar{mypagenumber})) scaled .1u withcolor magenta ;setbounds currentpicture to TheFrame ;%scaling the page to your preferred dimension: desiredformat := 150;% In pixels (will be converted by default at 72dpi). The shorter dimension of DIN A4 would be 595 pixels. currentpicture := currentpicture xysized (desiredformat ,desiredformat ); %for square pages. If DIN A Landscape, use (sqrt(2)*desiredformat ,desiredformat)\stopuseMPgraphic %finishing \startuseMPgraphic{Gamma} %This is a layer subset which will be used more than once. I call it a layer subset and not a layer set because it doesn't include another MPgraphic.draw layerU ;draw layerM ;\stopuseMPgraphic %Gamma \startuseMPgraphic{layersetpage1} %Each layersetpage will become a page containing the defined layer set. The number corresponds to the page number. Start with number 1. \includeMPgraphic{base} %base has to be included only in layersetpage1. It will be passed on to the next layersetpages via inclusion. draw layerW ;draw layerA ;\stopuseMPgraphic \startuseMPgraphic{layersetpage2} %There should be no gap in the sequence of the numbers of the layersetpages\includeMPgraphic{layersetpage1} ;draw layerV ;\stopuseMPgraphic \startuseMPgraphic{layersetpage3}\includeMPgraphic{layersetpage2} ;\includeMPgraphic{Gamma} ;\stopuseMPgraphic  \startuseMPgraphic{layersetpre4} %This is a layer set because it includes another MPgraphic. It will be used more than once, but it will not become a page itself. It's only an intermediate step on the way to the next layersetpage. For that reason, it's not named layersetpage. Because it's coming before the layersetpage4, I call it layersetpre4. If I need another intermediate step stored before layersetpre4, I would call it layersetprepre4. But that's only a naming convention for myself.\includeMPgraphic{layersetpage1} ;draw layerY ;\stopuseMPgraphic  \startuseMPgraphic{layersetpage4}\includeMPgraphic{layersetpre4} ;label("special!", (z3+z4)/2) rotated 5 withcolor red;\stopuseMPgraphic   \startuseMPgraphic{layersetpage5}\includeMPgraphic{layersetpage3} ;draw layerC ;\stopuseMPgraphic \startuseMPgraphic{layersetpage6}\includeMPgraphic{layersetpre4} ;draw layerC ;
\stopuseMPgraphic
\useMPgraphic{name}</texcode>starttext
As said, this graphic is calculated \dorecurse{6}{ %This loop starts from 1 until the set number and draws each time it layersetpage onto its own page. Don't set a number which is placed, which can be time consuming. Apart from higher than the time aspect, this also means that the graphic itself is incorporated many timesnumber of your last layersetpage. Therefore, for graphics that don’t change, CONTEXT provides reusable graphics:
%By differentiating finishinglayersetpage#1 from layersetpage#1, we can avoid adding \includeMPgraphic{finishing} to each \startuseMPgraphic{layersetpage<texcodenumber>}. This allows us to apply the scaling of the page to our desiredformat, because the scaling will done only once per \useMPgraphic{}.\startreusableMPgraphicstartuseMPgraphic{namefinishinglayersetpage#1} fill fullcircle scaled 200pt withcolor .625yellow\includeMPgraphic{layersetpage#1} ;\stopreusableMPgraphicincludeMPgraphic{finishing}\stopuseMPgraphic
%uncomment if needed: % \reuseMPgraphicsetupTEXpage[background=color, backgroundcolor=gray] \startTEXpage[pagestate=start] %`pagestate=start` is needed to have incremented page numbering of the pdf \useMPgraphic{finishinglayersetpage#1}{namemypagenumber=#1} \stopTEXpage}\stoptext
</texcode>
[[File:layer_sets.png|400px]]
See also section 3.3 of [[manual:metafun-s.pdf|MetaFun manual]]. == Other Links ==
* Metapost home page: http://tug.org/metapost
* John Hobby's page: http://cm.bell-labs.com/who/hobby/MetaPost.html
* Current development: http://foundry.supelec.fr/projects/metapost/
* http://melusine.eu.org/syracuse/metapost/
[[Category:Graphics]]
[[Category:Metapost]]
12

edits

Navigation menu