summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/metafun/metafun-sneaky.tex
blob: a1df9afa3087ec37e0705b9e0db40fae4c1b4fe5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
% language=us runpath=texruns:manuals/metafun

\startcomponent metafun-conventions

\environment metafun-environment

\startchapter[title={Conventions}]

\startsection[title={Suffixes}]

One characteristic of using \METAFUN\ in \CONTEXT\ is that it is basically one
long run. The code snippets become figures that then get converted to \PDF\ and
embedded. If text is involved, each figure is actually processed twice, once to
identify what needs to be typeset, and once with the result(ing metrics).
Normally that gets unnoticed. You can check for the state by consulting the
boolean \type {mfun_trial_run}.

A consequence of the one run cq.\ multiple runs is that you need to be careful with
undefined or special variables. Consider the following:

\starttyping
vardef foo@#(text t) =
  save s ; string s ; s := str @# ;
  if length(s) > 0 :
    textext(s)
  else :
    nullpicture
  fi
enddef ;
\stoptyping

The following works ok in the first run when bar is undefined:

\starttyping
draw foo.bar("a") ;
\stoptyping

But if afterwards we say:

\starttyping
vardef bar(expr x) =
  123
enddef ;
\stoptyping

and expand \type {foo.bar} again we will get an error message because this time
\type {bar} expands. Suffixes are always expanded!

The lesson is: when you get unexpected results or errors, check your variable
definitions. You can use the \type {begingroup} and \type {endgroup} primitives
to protect your variables but then you also need to explicitly use \type {save}
to store their meanings and allocate new ones after that inside the group.

\stopsection

\startsection[title=Templates]

This section is a bit off|-|topic and thereby also qualifies as sneaky. At the
\TEX\ end we have a couple of alternative input methods, like \XML\ and templates.
Just because we want to be consistent, the \METAPOST\ end also offers this.

The first example resembled the \type{btex ... etex} approach:

\startbuffer
\startbuffer[test-a]
  blua for i=0,100,20 do elua
    draw fullcircle scaled (blua p(i) elua * cm)
      withcolor "darkgreen" withpen pencircle scaled 1cm ;
  blua end elua

  blua for i=10,100,20 do elua
    draw fullcircle scaled (blua p(i) elua * cm)
      withcolor "darkred" withpen pencircle scaled 1cm ;
  blua end elua
\stopbuffer

\startMPcode
    draw image (
        loadfile ("mpstemplate://buffer?name=test-a") ;
    ) ysized 3cm ;
\stopMPcode
\stopbuffer

\typebuffer[test-1][option=TEX]

The filename is specified as a \URI\ and the \type {mpstemplate} does the magic
here.

\startlinecorrection[blank] \getbuffer \stoplinecorrection

The second example is like the \type {lmx} files that you can find in the distibution:

\startbuffer
\startbuffer[test-b]
  <?lua for i=0,100,20 do ?>
    draw fullcircle scaled (<?lua p(i) ?> * cm)
      withcolor "darkblue" withpen pencircle scaled 1cm ;
  <?lua end ?>

  <?lua for i=10,100,20 do ?>
    draw fullcircle scaled (<?lua p(i) ?> * cm)
      withcolor "darkyellow" withpen pencircle scaled 1cm ;
  <?lua end ?>
\stopbuffer

\startMPcode
  draw image (
    loadfile ("mpstemplate://buffer?name=test-b") ;
  ) ysized 3cm ;
\stopMPcode
\stopbuffer

\typebuffer[test-b][option=TEX]

The filename is again specified as a \URI:

\startlinecorrection[blank] \getbuffer \stoplinecorrection

\startbuffer
\startMPcode
  picture p[] ; % we can't input nested
  loadfile("mpstemplate://buffer?name=test-a&method=metapost") ;
  p[1] := currentpicture ; currentpicture := nullpicture ;
  loadfile("mpstemplate://buffer?name=test-b&method=xml") ;
  p[2] := currentpicture ; currentpicture := nullpicture ;
  draw p[1] ysized 3cm ;
  draw p[2] ysized 4cm shifted (4cm,0) ;
\stopMPcode
\stopbuffer

\typebuffer[option=TEX]

The combination comes out as:

\startlinecorrection[blank] \getbuffer \stoplinecorrection

Another approach is to load as image, which saves some typing:

\startbuffer
\startMPpage[offset=10pt]
  draw image (loadfile("mpstemplate://buffer?name=test-a&method=metapost"))
    xsized 2cm shifted ( 3cm,0) ;
  draw image (loadfile("mpstemplate://buffer?name=test-b&method=xml"))
    xsized 2cm shifted ( 6cm,0) ;
  draw loadimage ("mpstemplate://buffer?name=test-a&method=metapost")
    xsized 2cm shifted ( 9cm,0) ;
  draw loadimage ("mpstemplate://buffer?name=test-b&method=xml")
    xsized 2cm shifted (12cm,0) ;
\stopMPpage
\stopbuffer

\typebuffer[option=TEX]

The result is predictable:

\startlinecorrection[blank] \getbuffer \stoplinecorrection

Of course there is also a \type {cld} approach possible:

% context.startMPpage { offset = "10pt" }
% context.stopMPpage()

\startbuffer
\startluacode
  context.startMPcode()
    for i=0,100,20 do
      context ( [[draw fullcircle scaled (%s * cm)
        withcolor "darkmagenta" withpen pencircle scaled 1cm ;]], i)
    end
    for i=10,100,20 do
      context ( [[draw fullcircle scaled (%s * cm)
        withcolor "darkcyan" withpen pencircle scaled 1cm ;]], i)
    end
  context.stopMPcode()
\stopluacode
\stopbuffer

\typebuffer[option=TEX]

The commented commands will create a page. This is a convenient way to make
graphics that can be used in other documents (programs). For practical reasons the
example is scaled down:

\startlinecorrection[blank] \scale[height=3cm]{\getbuffer} \stoplinecorrection

All these methods are rather efficient because all happens in memory and without
intermediate runs. It is this kind of features that the tight integration of \TEX,
\METAPOST\ and \LUA\ make possible.

\stopsection

\stopchapter

\stopcomponent