grph-inc.mkiv /size: 36 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=grph-inc, % moved from core-fig
3%D        version=2006.08.26, % overhaul of 1997.03.31
4%D          title=\CONTEXT\ Graphic Macros,
5%D       subtitle=Figure Inclusion,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14% \enabledirectives[graphics.conversion.eps.cleanup.ai]
15
16% \setupexternalfigures[directory=dirfile://./test/**]
17% \externalfigure[crappname(2).eps][frame=on]
18
19% todo: messages
20
21\writestatus{loading}{ConTeXt Graphic Macros / Figure Inclusion}
22
23\registerctxluafile{grph-img}{}
24\registerctxluafile{grph-inc}{}
25
26\registerctxluafile{grph-con}{}
27\registerctxluafile{grph-fil}{}
28\registerctxluafile{grph-mem}{}
29\registerctxluafile{grph-u3d}{} % this will become a module
30\registerctxluafile{grph-swf}{} % this will become a module
31
32\unprotect
33
34%D Including graphics is complicated by the fact that  we need to locate them first,
35%D optionally manipulate them and scale then next. Lookups are to be done as efficient
36%D as possible and inclusion of the data might happens only once. In \MKIV\ much of this
37%D is delegated to the \LUA\ end. There is not so much less code as in \MKII\ but it's
38%D more powerful, flexible, pluggable and some of the extended functionality has been
39%D moved from modules to the core. The overall functionality is rather stable and has
40%D not changed much over the years.
41
42\ifdefined\dotagfigure \else \let\dotagfigure\relax \fi
43
44\installcorenamespace{externalfigure}
45\installcorenamespace{externalfigureinstance}
46\installcorenamespace{externalfigurecollection}
47
48\installframedcommandhandler \??externalfigure {externalfigure} \??externalfigure
49
50\let\setupexternalfigures\setupexternalfigure
51
52\setupexternalfigures[% we really need the defaults
53   \c!method         =,
54   \c!label          =,
55   \c!size           =,
56   \c!conversion     =,
57   \c!resolution     =,
58   \c!prefix         =,
59   \c!cache          =,
60   \c!page           =\zerocount,
61   \c!file           =,
62   \c!display        =,
63   \c!mask           =,
64   \c!preset         =\v!yes,
65   \c!split          =,
66   \c!color          =,
67   \c!arguments      =,
68   \c!symbol         =\v!no,
69   \c!controls       =\v!no,
70   \c!resources      =,
71   \c!preview        =\v!no,
72   \c!repeat         =\v!no,
73   \c!foregroundcolor=,
74   \c!interaction    =\v!none,
75   \c!hfactor        =,
76   \c!wfactor        =,
77   \c!factor         =,
78   \c!maxwidth       =\externalfigureparameter\c!width,
79   \c!maxheight      =\externalfigureparameter\c!height,
80   \c!xscale         =,
81   \c!yscale         =,
82   \c!scale          =,
83   \c!sx             =\externalfigureparameter\c!s,
84   \c!sy             =\externalfigureparameter\c!s,
85   \c!s              =1,
86   \c!width          =,
87   \c!height         =,
88   \c!lines          =,
89   \c!grid           =,
90   \c!bodyfont       =\bodyfontsize,
91   \c!object         =\v!yes,
92   \c!corner         =\v!rectangular,
93   \c!frame          =\v!off,
94   \c!option         =,
95   \c!reset          =\v!no,
96   \c!directory      =,
97   \c!radius         =.5\bodyfontsize,
98   \c!background     =,
99   \c!splitcolor     =\s!white,
100   \c!order          =,
101   \c!equalwidth     =,
102   \c!equalheight    =,
103   \c!location       ={\v!local,\v!global},
104   \c!frames         =\v!off,
105   \c!ymax           =24,
106   \c!xmax           =,
107   \c!align          =\v!none, % New, for Tacos extremely large graphics.
108   \c!crossreference =\v!no,
109   \c!transform      =\v!auto,
110   \c!userpassword   =,
111   \c!ownerpassword  =,
112   \c!compact        =,
113   \c!cmyk           =,
114   \c!crop           =\v!yes,
115  ]
116
117%D Defining figures.
118
119\newcount\c_grph_include_nesting
120
121\newtoks \everyexternalfigureresets % for the moment still public
122\newtoks \everyexternalfigurechecks % for the moment still public
123
124% \useexternalfigure[alpha][cow]
125% \useexternalfigure[beta] [cow]       [width=1cm]
126% \useexternalfigure[gamma][cow][alpha]
127% \useexternalfigure[delta][cow][alpha][width=2cm]
128%
129% full width : \externalfigure[cow]               \par
130% 3cm width  : \externalfigure[cow]  [width=3cm]  \par
131% full width : \externalfigure[alpha]             \par
132% 1cm width  : \externalfigure[beta]              \par
133% full width : \externalfigure[gamma]             \par
134% 2cm width  : \externalfigure[delta]             \par
135% 4cm width  : \externalfigure[beta] [width=4cm]  \par
136% 5cm width  : \externalfigure[gamma][width=5cm]  \par
137%
138% \defineexternalfigure[a][width=10cm]
139% \defineexternalfigure[b][width=5cm]
140% \externalfigure[cow][a]
141% \externalfigure[cow][b][height=8cm]
142%
143% \useexternalfigure[x][cow][width=10cm,height=1cm]
144% \externalfigure[x]
145% \externalfigure[x][width=3cm]
146%
147% [label] [filename]
148% [label] [filename] [parent]
149% [label] [filename] [parent] [settings]
150% [label] [filename]          [settings]
151%
152% new: more convenient/efficient than
153%
154%   \use..[a][a][setting] \externalfigure[b][a]
155%
156% is equivalent to:
157%
158%   \def..[a][setting]    \externalfigure[b][a]
159%
160% see x-res modules for usage:
161%
162% \defineexternalfigure[name][settings]
163
164%D Defining is persistent, i.e.\ when you redefine an instance, the already set
165%D parameters need to be set again or otherwise the old values will be used.
166%D
167%D New: \type {method=auto}: strips suffix and uses \quote {order} which is handy in
168%D some of four workflows where sources are used for web and print and where the web
169%D tools need a suffix (like gif) which we don't want as we want a high quality
170%D format.
171
172\newconditional\c_grph_include_trace_inheritance
173
174\installtextracker
175  {graphics.inheritance}
176  {\settrue \c_grph_include_trace_inheritance}
177  {\setfalse\c_grph_include_trace_inheritance}
178
179\installcorenamespace{externalfiguredefinition}
180
181% \unexpanded\def\defineexternalfigure
182%   {\dodoubleargument\grph_include_define}
183%
184% \def\grph_include_define[#1][#2]%
185%   {\setvalue{\??externalfiguredefinition#1}{\setupcurrentexternalfigure[#2]}}
186
187\let\defineexternalfigures\defineexternalfigure
188
189\unexpanded\def\useexternalfigure
190  {\doquadrupleempty\grph_include_use}
191
192% label file parent settings
193% label file settings
194% label file parent
195
196% \def\grph_include_use[#1][#2][#3][#4]%
197%   {\doifelsenothing{#1}
198%      {\doifsomething{#2}
199%         {\doifelseassignment{#3}
200%            {\grph_include_use_indeed{#2}{#2}{#3}{#4}}
201%            {\grph_include_use_indeed{#2}{#2}\empty{#4}}}}
202%      {\doifelsenothing{#2}
203%         {\doifelseassignment{#3}
204%            {\grph_include_use_indeed{#1}{#1}\empty{#3}}
205%            {\grph_include_use_indeed{#1}{#1}{#3}{#4}}}
206%         {\doifelseassignment{#3}
207%            {\grph_include_use_indeed{#1}{#2}\empty{#3}}
208%            {\grph_include_use_indeed{#1}{#2}{#3}{#4}}}}}
209
210\def\grph_include_use[#1][#2][#3][#4]%
211  {\doifelsenothing{#1}
212     {\doifsomething{#2}
213        {\ifcondition\validassignment{#3}%
214           \grph_include_use_indeed{#2}{#2}{#3}{#4}%
215         \else
216           \grph_include_use_indeed{#2}{#2}\empty{#4}%
217         \fi}}%
218     {\doifelsenothing{#2}
219        {\ifcondition\validassignment{#3}%
220           \grph_include_use_indeed{#1}{#1}\empty{#3}%
221         \else
222           \grph_include_use_indeed{#1}{#1}{#3}{#4}%
223         \fi}
224        {\ifcondition\validassignment{#3}%
225           \grph_include_use_indeed{#1}{#2}\empty{#3}
226         \else
227           \grph_include_use_indeed{#1}{#2}{#3}{#4}%
228         \fi}}}
229
230\def\grph_include_use_indeed#1#2#3#4%
231  {\dodoglobal\setvalue{\??externalfigureinstance#1}{\grph_include_setup{#2}{#3}{#4}}%
232   \grph_include_analyze_collection[#2][#4]}
233
234% inclusion
235
236\unexpanded\def\externalfigure
237  {\dotripleempty\grph_include_figure}
238
239\def\grph_include_figure[#1][#2][#3]%
240% {\docheckassignment{#2}%
241%  \ifassignment
242  {\ifcondition\validassignment{#2}%
243     \grph_include_place[#1][][#2]%
244   \else
245     \grph_include_place[#1][#2][#3]%
246   \fi}
247
248% todo: chain them
249
250\def\grph_include_setup#1#2#3% name parent settings
251  {\edef\m_grph_include_name  {#1}%
252   \edef\m_grph_include_parent{#2}%
253   \ifx\m_grph_include_name\empty \else
254     \let\p_grph_include_name\m_grph_include_name
255   \fi
256   \ifx\m_grph_include_parent\empty \else
257     \grph_include_inherit_from_parent\m_grph_include_parent
258   \fi
259   \setupcurrentexternalfigure[#3]}
260
261% \def\grph_include_inherit_from_parent#1%
262%   {\ifcsname\??externalfiguredefinition#1\endcsname
263%      \ifconditional\c_grph_include_trace_inheritance\c_grph_include_trace_inheritance\writestatus\m!figures{inheriting from definition: #1}\fi
264%      \csname\??externalfiguredefinition#1\endcsname
265%    \fi
266%    \ifcsname\??externalfigureinstance#1\endcsname
267%      \ifconditional\c_grph_include_trace_inheritance\c_grph_include_trace_inheritance\writestatus\m!figures{inheriting from instance: #1}\fi
268%      \csname\??externalfigureinstance#1\endcsname
269%    \fi}
270
271\def\grph_include_inherit_from_parent#1%
272  {%\ifcsname\??externalfiguredefinition#1\endcsname
273   %  \ifconditional\c_grph_include_trace_inheritance\writestatus\m!figures{inheriting from definition: #1}\fi
274   %  \csname\??externalfiguredefinition#1\endcsname
275   %\fi
276   \ifcsname\??externalfigure#1:\s!parent\endcsname
277     \let\currentexternalfigure#1%
278   \fi
279   \ifcsname\??externalfigureinstance#1\endcsname
280     \ifconditional\c_grph_include_trace_inheritance\writestatus\m!figures{inheriting from instance: #1}\fi
281     \csname\??externalfigureinstance#1\endcsname
282   \fi}
283
284\newtoks\t_grph_include_local_settings
285
286\appendtoks
287   \let\textunderscore\letterunderscore % {\string _} % space needed as _ is now letter in unprotected mode (probably no longer needed)
288   %
289   \dontcomplain
290   \restorecatcodes
291   \forgetall
292\to \t_grph_include_local_settings
293
294\def\grph_include_place_inherit
295  {\ifconditional\c_grph_include_trace_inheritance
296     \writestatus\m!figures{label: \p_grph_include_label, name: \p_grph_include_name, parent: \p_grph_include_parent}%
297   \fi
298   \ifx\p_grph_include_parent\empty
299     % nothing to be done
300   \else\ifx\p_grph_include_parent\p_grph_include_label
301     % redundant
302   \else
303     \grph_include_inherit_from_parent\p_grph_include_parent
304   \fi\fi
305   \ifx\p_grph_include_label\empty
306     % nothing to be done
307   \else
308     \grph_include_inherit_from_parent\p_grph_include_label
309   \fi}
310
311\def\grph_include_place[#1][#2][#3]% [label][file][settings] | [file][settings] | [file][parent][settings]
312  {\bgroup
313   \advance\c_grph_include_nesting\plusone
314   \edef\currentexternalfigure{\the\c_grph_include_nesting}%
315   \checkexternalfigureparent % each inherits from the root
316   %
317   \the\everyexternalfigureresets
318   %
319   \edef\p_grph_include_label{#1}%
320   \let\p_grph_include_name\p_grph_include_label
321 % \docheckassignment{#2}%
322 % \ifassignment
323   \ifcondition\validassignment{#2}%
324     % [label] [settings]
325     \let\p_grph_include_parent\p_grph_include_label
326     \grph_include_place_inherit
327     \setupcurrentexternalfigure[#2]%
328   \else
329     % [label] [parent] [settings]
330     \edef\p_grph_include_parent{#2}%
331     \ifx\p_grph_include_parent\empty
332        \let\p_grph_include_parent\p_grph_include_label
333     \fi
334     \grph_include_place_inherit
335     \setupcurrentexternalfigure[#3]%
336   \fi
337   %
338   \the\everyexternalfigurechecks
339   %
340   \the\t_grph_include_local_settings
341   %
342   \edef\p_width    {\externalfigureparameter\c!width}%
343   \edef\p_height   {\externalfigureparameter\c!height}%
344   \edef\p_label    {\externalfigureparameter\c!label}%
345   \edef\p_reference{\externalfigureparameter\c!reference}%
346   %
347   \dostarttagged\t!image\empty
348   \clf_figure_push {
349        name         {\p_grph_include_name}%
350        label        {\ifx\p_label\empty\p_grph_include_label\else\p_label\fi}%
351        page         {\externalfigureparameter\c!page}%
352        file         {\externalfigureparameter\c!file}%
353        size         {\externalfigureparameter\c!size}%
354        object       {\externalfigureparameter\c!object}%
355        prefix       {\externalfigureparameter\c!prefix}%
356        cache        {\externalfigureparameter\c!cache}%
357        format       {\externalfigureparameter\c!method}%
358        preset       {\externalfigureparameter\c!prefix}%
359        controls     {\externalfigureparameter\c!controls}%
360        resources    {\externalfigureparameter\c!resources}%
361        preview      {\externalfigureparameter\c!preview}%
362        display      {\externalfigureparameter\c!display}%
363        mask         {\externalfigureparameter\c!mask}%
364        conversion   {\externalfigureparameter\c!conversion}%
365        resolution   {\externalfigureparameter\c!resolution}%
366        color        {\externalfigureparameter\c!color}% unprocessed raw key
367        cmyk         {\externalfigureparameter\c!cmyk}% kind of special
368        arguments    {\externalfigureparameter\c!arguments}% used for converters
369        repeat       {\externalfigureparameter\c!repeat}%
370        transform    {\externalfigureparameter\c!transform}%
371        compact      {\externalfigureparameter\c!compact}% experiment, share fonts
372        userpassword {\externalfigureparameter\c!userpassword}%
373        ownerpassword{\externalfigureparameter\c!ownerpassword}%
374        crop         {\externalfigureparameter\c!crop}%
375    \ifx\p_width\empty \else
376        width  \dimexpr\p_width\relax
377    \fi
378    \ifx\p_height\empty \else
379        height \dimexpr\p_height\relax
380    \fi
381   }%\relax
382   \clf_figure_identify
383   \relax
384   \ifconditional\c_grph_include_test_only
385      \ifcase\figurestatus \else
386        \clf_figure_check
387        \clf_figure_dummy
388        \clf_figure_scale
389        \clf_figure_done
390      \fi
391      \grph_include_set_mode
392   \else
393      \ifcase\figurestatus
394        \clf_figure_dummy
395        \clf_figure_scale
396      \else
397        \clf_figure_check
398        \clf_figure_include
399        \clf_figure_scale
400      \fi
401      \clf_figure_done
402      \grph_include_set_mode
403      \grph_include_finalize
404   \fi
405   \clf_figure_pop
406   \dotagfigure
407   %
408   \scratchcounter\zerocount
409   \edef\p_crossreference{\externalfigureparameter\c!crossreference}%
410   \iflocation\iftrialtypesetting\else
411     \ifx\p_crossreference\empty
412        % nothing
413     \else\ifx\p_crossreference\v!no
414        % nothing
415     \else\ifx\p_crossreference\v!yes
416       \ifcondition\validassignment{#2}%
417         \scratchcounter\clf_figure_register_page{#1}{}{#2}\relax
418       \else
419         \scratchcounter\clf_figure_register_page{#1}{#2}{#3}\relax
420       \fi
421     \else
422       \scratchcounter-\p_crossreference % passed by repeater
423     \fi\fi\fi
424   \fi\fi
425   \naturalvpack
426     attr \imageattribute \plustwo
427   \ifnum\scratchcounter>\zerocount
428     {\strc_references_cross_forward {ex:\number \scratchcounter}{\box\foundexternalfigure}}%
429   \else\ifnum\scratchcounter<\zerocount
430     {\strc_references_cross_backward{ex:\number-\scratchcounter}{\box\foundexternalfigure}}%
431   \else
432     {\box\foundexternalfigure}%
433   \fi\fi
434   %
435   \dostoptagged
436   \egroup}
437
438%D Next we provide a cross referenced scale-up mechanism:
439
440\def\strc_references_cross_forward#1#2%
441  {\begingroup
442   \strc_references_set_simple_internal_reference{cross:b:#1}%
443   \naturalhpack
444      attr \destinationattribute\number\lastdestinationattribute
445      {\naturalhpack{\strc_references_flush_destination_nodes\directgotodumbbox{#2}[cross:f:#1]}}%
446   \endgroup}
447
448\def\strc_references_cross_backward#1#2%
449  {\begingroup
450   \strc_references_set_simple_internal_reference{cross:f:#1}%
451   \naturalhpack
452      attr \destinationattribute\number\lastdestinationattribute
453      {\naturalhpack{\strc_references_flush_destination_nodes\directgotodumbbox{#2}[cross:b:#1]}}%
454   \endgroup}
455
456\let\doexternalfigurerepeat\gobblefourarguments % called from lua end
457
458\unexpanded\def\placeregisteredexternalfigures
459  {\dosingleempty\grph_include_place_registered}
460
461\unexpanded\def\grph_include_place_registered[#1]%
462  {\page
463   \begingroup
464   \unexpanded\def\doexternalfigurerepeat{\grph_include_place_registered_indeed{#1}}%
465   \dorecurse\clf_figure_nof_registered_pages
466    {\page
467     \clf_figure_flush_registered_pages\recurselevel
468     \page}%
469   \endgroup
470   \page}
471
472\unexpanded\def\grph_include_place_registered_indeed#1#2#3#4#5% called from lua end
473  {\grph_include_place[#2][#3][#4,%
474     \c!hfactor=,\c!wfactor=,\c!factor=,%
475     \c!maxwidth=,\c!maxheight=,%
476     \c!xscale=,\c!yscale=,\c!scale=,%
477     \c!sx=,\c!sy=,\c!s=,%
478     \c!width=,\c!height=,%
479     \c!crossreference=#5,%
480     #1]}
481
482%D Scaling:
483
484\let\dowithfigure\relax % name might change (into a proper hook)
485
486\unexpanded\def\doscalefigure % used at lua end
487  {\global\setbox\foundexternalfigure\vpack{\scale[\v!figure]{\dowithfigure{\box\foundexternalfigure}}}}
488
489\definescale % some day we will inherit
490  [\v!figure]
491  [\c!hfactor    =\externalfigureparameter\c!hfactor,
492   \c!wfactor    =\externalfigureparameter\c!wfactor,
493   \c!factor     =\externalfigureparameter\c!factor,
494   \c!maxwidth   =\externalfigureparameter\c!maxwidth ,
495   \c!maxheight  =\externalfigureparameter\c!maxheight,
496   \c!equalwidth =\externalfigureparameter\c!equalwidth ,
497   \c!equalheight=\externalfigureparameter\c!equalheight,
498   \c!xscale     =\externalfigureparameter\c!xscale,
499   \c!yscale     =\externalfigureparameter\c!yscale,
500   \c!scale      =\externalfigureparameter\c!scale,
501   \c!sx         =\externalfigureparameter\c!sx,
502   \c!sy         =\externalfigureparameter\c!sy,
503   \c!s          =\externalfigureparameter\c!s,
504   \c!width      =\externalfigureparameter\c!width,
505   \c!height     =\externalfigureparameter\c!height,
506   \c!lines      =\externalfigureparameter\c!lines]
507
508%D You can register additional suffixes with the following command:
509%D
510%D \starttyping
511%D \definegraphictypesynonym[jbig] [jb2]
512%D \definegraphictypesynonym[jbig2][jb2]
513%D \definegraphictypesynonym[jbg]  [jb2]
514%D \stoptyping
515
516\unexpanded\def\definegraphictypesynonym
517  {\dodoubleargument\grph_include_set_type_synonym}
518
519\def\grph_include_set_type_synonym[#1][#2]%
520  {\clf_registerfiguresuffix{#1}{#2}}
521
522%D Additional paths can be installed with the regular setup command. The next
523%D macro picks up the list.
524
525\unexpanded\def\setfigurepathlist
526  {\clf_setfigurepaths{\externalfigureparameter\c!location}{\externalfigureparameter\c!directory}}
527
528%D Variables:
529
530\newbox \foundexternalfigure
531\newtoks\externalfigurepostprocessors
532
533\def\defaultfigurewidth  {8\lineheight}
534\def\defaultfigureheight {6\lineheight}
535
536\def\figurestatus        {\numexpr\clf_figurestatus{status}{0}\relax} % number: 0 = not found
537\def\figurewidth         {\clf_figurestatus{width}{0}sp}
538\def\figureheight        {\clf_figurestatus{height}{0}sp}
539\def\figurexscale        {\clf_figurestatus{xscale}{1}}
540\def\figureyscale        {\clf_figurestatus{yscale}{1}}
541
542\def\figuresize          {\clf_figurerequest{size}{}}
543\def\figurelabel         {\clf_figurerequest{label}{}}
544\def\figurefileoriginal  {\clf_figurerequest{name}{}}
545\def\figurefilepage      {\clf_figurerequest{page}{1}}
546\def\figurefileoptions   {\clf_figurerequest{options}{}}
547\def\figurefileconversion{\clf_figurerequest{conversion}{}}
548\def\figurefileresolution{\clf_figurerequest{resolution}{}}
549\def\figurefilecolor     {\clf_figurerequest{color}{}}
550\def\figurefilearguments {\clf_figurerequest{arguments}{}}
551\def\figurefilecache     {\clf_figurerequest{cache}{}}
552\def\figurefileprefix    {\clf_figurerequest{prefix}{}}
553
554\def\figurenaturalwidth  {\clf_figureused{width}{\number\dimexpr\defaultfigurewidth\relax}sp}
555\def\figurenaturalheight {\clf_figureused{height}{\number\dimexpr\defaultfigureheight\relax}sp}
556\def\figurexresolution   {\clf_figureused{xresolution}{0}}
557\def\figureyresolution   {\clf_figureused{yresolution}{0}}
558\def\figureorientation   {\clf_figureused{orientation}{1}}
559\def\figurerotation      {\clf_figureused{rotation}{0}}
560\def\figurexsize         {\clf_figureused{xsize}{0}}
561\def\figureysize         {\clf_figureused{ysize}{0}}
562\def\figurecolordepth    {\clf_figureused{colordepth}{0}}
563\def\figuredepth         {\clf_figureused{depth}{0}}
564
565\def\figurefullname      {\clf_figureused{fullname}{}}
566\def\noffigurepages      {\clf_figureused{pages}{0}}
567
568% \def\figurefilepath      {\clf_figurefilepath} % public in lua
569% \def\figurefilename      {\clf_figurefilename} % public in lua
570% \def\figurefiletype      {\clf_figurefiletype} % public in lua
571
572\let\naturalfigurewidth  \figurenaturalwidth
573\let\naturalfigureheight \figurenaturalheight
574
575\let\figurescalewidth    \figurewidth
576\let\figurescaleheight   \figureheight
577\let\figurescalexscale   \figurexscale
578\let\figurescaleyscale   \figureyscale
579
580%D Abuse:
581%D
582%D \starttyping
583%D \externalfigure[rubish.pdf] \ifcase\figurestatus\relax \ctxlua{os.exit(999)} \fi
584%D \stoptyping
585
586%D Calculating:
587
588% \enabletrackers[figures.conversion]
589% \externalfigure[demo.svg]
590% \externalfigure[demo.svg][conversion=png]
591
592%D The following registers are used (if only to be downward compatible).
593
594\newconditional\c_grph_include_skip
595\newconditional\c_grph_include_test_only
596\newconditional\c_grph_include_level      \setfalse\c_grph_include_level  % true=background false=normal
597\newconditional\c_grph_include_flush      \settrue \c_grph_include_flush  % true=place      false=ignore
598
599\newsystemmode\v!figure
600
601\def\grph_include_set_mode
602  {\ifcase\figurestatus
603     \globalresetsystemmode\v!figure % todo, also: \v!resource
604   \else
605     \globalsetsystemmode  \v!figure % todo, also: \v!resource
606   \fi}
607
608\appendtoks
609    \clf_setfigurepaths
610      {\externalfigureparameter\c!location}%
611      {\externalfigureparameter\c!directory}%
612    \clf_figure_reset
613      \foundexternalfigure
614      \defaultfigurewidth
615      \defaultfigureheight
616    \relax
617\to \everyexternalfigureresets
618
619\appendtoks
620    \edef\p_option{\externalfigureparameter\c!option}%
621    \ifx\p_option\v!frame
622      \setfalse\c_grph_include_skip
623      \letexternalfigureparameter\c!frame\v!on
624    \else\ifx\p_option\v!empty
625      \settrue\c_grph_include_skip
626      \letexternalfigureparameter\c!frame\v!off
627    \else
628      \setfalse\c_grph_include_skip
629    \fi\fi
630    % fake color in gray bitmaps, assumes that
631    % a transparent color is used
632    \edef\p_foregroundcolor{\externalfigureparameter\c!foregroundcolor}%
633    \ifx\p_foregroundcolor\empty \else
634        \setexternalfigureparameter\c!background{\v!foreground,\v!color}%
635        \letexternalfigureparameter\c!backgroundcolor\p_foregroundcolor
636    \fi
637\to \everyexternalfigurechecks
638
639%D Internal graphics are handled at the \TEX\ end:
640
641\def\grph_include_process_tex#1%
642  {\framed
643     [\c!strut=\v!no,\c!align=\v!normal,\c!frame=\v!off,
644      \c!offset=\v!overlay,\c!width=\v!fit,\c!height=\v!fit]
645     {\blank[\v!disable]#1\endgraf\removelastskip}} % disable should stay here!
646
647% used al lua end:
648
649\unexpanded\def\docheckfigurebuffer  #1{\global\setbox\foundexternalfigure\vpack{\grph_include_process_tex{\getbuffer[#1]}}}
650\unexpanded\def\docheckfiguretex     #1{\global\setbox\foundexternalfigure\vpack{\grph_include_process_tex{\input{#1}}}}
651\unexpanded\def\docheckfigurecld     #1{\global\setbox\foundexternalfigure\vbox {\cldprocessfile{#1}}}
652\unexpanded\def\docheckfiguremps     #1{\global\setbox\foundexternalfigure\vpack{\convertMPtoPDF{#1}11}}
653\unexpanded\def\docheckfiguremprun #1#2{\global\setbox\foundexternalfigure\vpack{\useMPrun{#1}{#2}}}
654
655% \unexpanded\def\relocateexternalfigure % easier here than in lua
656%   {\global\setbox\foundexternalfigure\vpack to \ht\foundexternalfigure\bgroup
657%      \vss
658%      \ht\foundexternalfigure\zeropoint
659%      \hpack to \wd\foundexternalfigure\bgroup
660%         \box\foundexternalfigure
661%         \hss
662%      \egroup
663%    \egroup}
664
665\unexpanded\def\relocateexternalfigure
666  {\global\setbox\foundexternalfigure\vpack to \ht\foundexternalfigure\bgroup
667     %
668     % The \vss can (!) introduce 1 sp excess visible in xform which in itself
669     % is not that important but some don't like these cosmetic side effects, for
670     % instance we can get:
671     %
672     % vss   : \vbox(845.1575+0.0)x597.23125, glue set 845.15747fil, direction TLT
673     % vskip : \vbox(845.1575+0.0)x597.23125, direction TLT
674     %
675     % or
676     %
677     % 1 0 0 1 0 0.00003 cm
678     % 1 0 0 1 0 0       cm
679     %
680     % This is a known property of using glue and can even depend on the architecture
681     % (float implementation). Anyway, let's for now use a skip. Of course this can
682     % shift the issue elsewhere, as vss is used a lot elsewhere.
683     %
684   % \vss
685     \vkern\ht\foundexternalfigure
686     %
687     \ht\foundexternalfigure\zeropoint
688     \dp\foundexternalfigure\zeropoint
689     \hpack to \wd\foundexternalfigure\bgroup
690        \box\foundexternalfigure
691        \hss
692     \egroup
693   \egroup}
694
695\unexpanded\def\startfoundexternalfigure#1#2% ht wd
696  {\global\setbox\foundexternalfigure\vbox to #2\bgroup\vss\hbox to #1\bgroup}
697
698\unexpanded\def\stopfoundexternalfigure
699  {\hss\egroup\egroup}
700
701\unexpanded\def\emptyfoundexternalfigure % sort of obsolete
702  {\startfoundexternalfigure\defaultfigurewidth\defaultfigureheight
703   \stopfoundexternalfigure}
704
705% \doifmodeelse{*\v!last}
706%   {\settrue \c_grph_include_flush}
707%   {\setfalse\c_grph_include_flush}%
708
709\def\grph_include_finalize
710  {\global\setbox\foundexternalfigure\vbox
711     {\ifcase\figurestatus
712        \letexternalfigureparameter\c!frame\v!on
713      \fi
714      \ifconditional\c_grph_include_flush
715        \ifconditional\c_grph_include_level % probably background
716          \ifconditional\c_grph_include_skip
717            % nothing
718            \fakebox\foundexternalfigure
719          \else\ifcase\figurestatus
720            % nothing
721          \else
722            \the\externalfigurepostprocessors
723            \box\foundexternalfigure
724          \fi\fi
725        \else
726          \iftrialtypesetting \else \feedbackexternalfigure \fi
727          \settrue\c_grph_include_level
728          \ifconditional\c_grph_include_skip
729            \ifcase\figurestatus
730              \grph_include_replacement\figurelabel\figurefileoriginal{unknown}%
731            \else
732              \grph_include_replacement\figurelabel\figurefullname{skipped}%
733            \fi
734          \else\ifcase\figurestatus
735            \grph_include_replacement\figurelabel\figurefileoriginal{unknown}%
736          \else
737            \the\externalfigurepostprocessors
738            \edef\p_reset{\externalfigureparameter\c!reset}%
739            \ifx\p_reset\v!yes
740              \wd\foundexternalfigure\figurewidth
741              \ht\foundexternalfigure\figureheight
742              \dp\foundexternalfigure\zeropoint
743              \box\foundexternalfigure
744            \else
745              \letexternalfigureparameter\c!offset\v!overlay
746              \letexternalfigureparameter\c!width \figurewidth
747              \letexternalfigureparameter\c!height\figureheight
748              \inheritedexternalfigureframed{\box\foundexternalfigure}%
749            \fi
750          \fi\fi
751        \fi
752      \else
753        % maybe also \the\externalfigurepostprocessors
754        \iftrialtypesetting \else \feedbackexternalfigure \fi
755      \fi}}
756
757\let\feedbackexternalfigure\relax % hook
758
759\unexpanded\def\getfiguredimensions
760  {\dodoubleempty\grph_include_get_dimensions}
761
762\def\grph_include_get_dimensions[#1][#2]%
763  {\startnointerference
764     \settrue\c_grph_include_test_only
765     \externalfigure[#1][#2,\c!display=,\c!mask=,\c!object=\v!no]%
766   \stopnointerference}
767
768\unexpanded\def\doifelsefigure#1%
769  {\getfiguredimensions[#1]% so data is available !
770   \ifcase\figurestatus
771     \expandafter\secondoftwoarguments
772   \else
773     \expandafter\firstoftwoarguments
774   \fi}
775
776\let\doiffigureelse\doifelsefigure
777
778% No placement, handy for preprocessing:
779
780\unexpanded\def\registerexternalfigure
781  {\dotripleempty\grph_include_register}
782
783\def\grph_include_register[#1][#2][#3]%
784  {\startnointerference
785     \c_grph_include_test_only
786     \setfalse\c_grph_include_flush % == test ?
787     \externalfigure[#1][#2][#3]% or
788     \externalfigure[#1][#2,\c!display=,\c!mask=,\c!object=\v!no]%
789   \stopnointerference}
790
791% Helpers will be replaced when xforms are accessible at the lua end but then
792% we need to do the object offset there too.
793
794\unexpanded\def\dosetfigureobject#1#2%
795  {\setobject{#1}{#2}\vpack{\box\foundexternalfigure}}
796
797\unexpanded\def\doboxfigureobject#1#2%
798  {\global\setbox\foundexternalfigure\vpack{\getobject{#1}{#2}}} % probably one vbox too many
799
800% Figure bases
801
802\unexpanded\def\usefigurebase[#1]%
803  {\clf_usefigurebase{#1}}
804
805\appendtoks
806   \setfigurepathlist  % the path may be used elsewhere too (as in x-res-04)
807\to \everysetupexternalfigure
808
809\appendtoks
810    \clf_setfigurelookuporder{\externalfigureparameter\c!order}%
811\to \everysetupexternalfigure
812
813\definecolor[missingfigurecolor][s=.8]
814
815\def\grph_include_replacement#1#2#3%
816  {\bgroup
817   \letexternalfigureparameter\c!width\figurewidth
818   \letexternalfigureparameter\c!height\figureheight
819   \letexternalfigureparameter\c!background\v!color
820   \setexternalfigureparameter\c!backgroundcolor{missingfigurecolor}%
821   \setexternalfigureparameter\c!align{\v!middle,\v!lohi}% we default to \v!none
822   \inheritedexternalfigureframed
823     {\tt\tfxx \nohyphens
824      name:  \expanded{\verbatimstring{#1}}\\%
825      file:  \expanded{\verbatimstring{#2}}\\%
826      state: \expanded{\verbatimstring{#3}}}%
827   \egroup}
828
829% maybe setuphandler
830
831\newconditional\c_grph_include_in_collection
832
833\newdimen\d_grph_include_collection_minwidth
834\newdimen\d_grph_include_collection_maxwidth
835\newdimen\d_grph_include_collection_minheight
836\newdimen\d_grph_include_collection_maxheight
837
838\def\grph_include_analyze_collection[#1][#2]%
839  {\ifconditional\c_grph_include_in_collection
840      \setfalse\c_grph_include_in_collection
841      \getfiguredimensions[#1][#2]%
842      \settrue\c_grph_include_in_collection
843      \scratchdimen\naturalfigurewidth
844      \ifdim\scratchdimen>\d_grph_include_collection_maxwidth  \d_grph_include_collection_maxwidth \scratchdimen \fi
845      \ifdim\scratchdimen<\d_grph_include_collection_minwidth  \d_grph_include_collection_minwidth \scratchdimen \fi
846      \scratchdimen\naturalfigureheight
847      \ifdim\scratchdimen>\d_grph_include_collection_maxheight \d_grph_include_collection_maxheight\scratchdimen \fi
848      \ifdim\scratchdimen<\d_grph_include_collection_minheight \d_grph_include_collection_minheight\scratchdimen \fi
849   \fi}
850
851\unexpanded\def\startexternalfigurecollection[#1]%
852  {\begingroup
853   \def\currentexternalfigurecollection{#1}%
854   \settrue\c_grph_include_in_collection
855   \d_grph_include_collection_minwidth \maxdimen
856   \d_grph_include_collection_maxwidth \zeropoint
857   \d_grph_include_collection_minheight\maxdimen
858   \d_grph_include_collection_maxheight\zeropoint}
859
860\unexpanded\def\stopexternalfigurecollection
861  {\setxvalue{\??externalfigurecollection\currentexternalfigurecollection:\c!minwidth }{\the\d_grph_include_collection_minwidth }%
862   \setxvalue{\??externalfigurecollection\currentexternalfigurecollection:\c!maxwidth }{\the\d_grph_include_collection_maxwidth }%
863   \setxvalue{\??externalfigurecollection\currentexternalfigurecollection:\c!minheight}{\the\d_grph_include_collection_minheight}%
864   \setxvalue{\??externalfigurecollection\currentexternalfigurecollection:\c!maxheight}{\the\d_grph_include_collection_maxheight}%
865   \endgroup}
866
867\def\externalfigurecollectionparameter#1#2%
868  {\csname
869     \ifcsname\??externalfigurecollection#1:#2\endcsname
870       \??externalfigurecollection#1:#2%
871     \else
872       \s!empty
873     \fi
874   \endcsname}
875
876\def\externalfigurecollectionminwidth #1{\externalfigurecollectionparameter{#1}\c!minwidth }
877\def\externalfigurecollectionmaxwidth #1{\externalfigurecollectionparameter{#1}\c!maxwidth }
878\def\externalfigurecollectionminheight#1{\externalfigurecollectionparameter{#1}\c!minheight}
879\def\externalfigurecollectionmaxheight#1{\externalfigurecollectionparameter{#1}\c!maxheight}
880
881\let\efcparameter\externalfigurecollectionparameter % still needed ?
882\let\efcminwidth \externalfigurecollectionminwidth  % still needed ?
883\let\efcmaxwidth \externalfigurecollectionmaxwidth  % still needed ?
884\let\efcminheight\externalfigurecollectionminheight % still needed ?
885\let\efcmaxheight\externalfigurecollectionmaxheight % still needed ?
886
887% \startexternalfigurecollection[name]
888%     \useexternalfigure[cow] [cow.pdf]
889%     \useexternalfigure[mill][mill.png]
890% \stopexternalfigurecollection
891% \starttext
892% \bTABLE
893%     \bTR
894%         \bTD \externalfigure[cow] [height=\externalfigurecollectionmaxheight{name}] \eTD
895%         \bTD \externalfigure[mill][height=\externalfigurecollectionmaxheight{name}] \eTD
896%     \eTR
897% \eTABLE
898% \stoptext
899
900\unexpanded\def\overlayfigure#1%
901  {\externalfigure[#1][\c!width=\d_overlay_width,\c!height=\d_overlay_height]}
902
903% Bonus:
904
905\useexternalfigure
906  [\v!buffer]
907  [\jobname.buffer]
908  [\c!object=\v!no]
909
910% Another two:
911
912\defineexternalfigure
913  [\v!inline]
914  [\c!height=\lineheight]
915
916\definemeasure
917  [\v!combination]
918  [(\textwidth
919    -\effectiveleftskip
920    -\effectiverightskip
921    -\numexpr\combinationparameter\c!nx-\plusone\relax\dimexpr\combinationparameter\c!distance\relax
922   )/\combinationparameter\c!nx]
923
924\defineexternalfigure
925  [\v!combination]
926  [\c!width=\measure{\v!combination}]
927
928% \startcombination[nx=2,ny=1]
929%     {\externalfigure[dummy][combination]} {}
930%     {\externalfigure[dummy][combination]} {}
931% \stopcombination
932
933% \startcombination[nx=2,ny=1]
934%     {\externalfigure[dummy][width=\measure{combination}]} {}
935%     {\externalfigure[dummy][width=\measure{combination}]} {}
936% \stopcombination
937
938% \startcombination[nx=2,ny=2]
939%     {\externalfigure[dummy][combination]} {}
940%     {\externalfigure[dummy][combination]} {}
941%     {\externalfigure[dummy][combination]} {}
942%     {\externalfigure[dummy][combination]} {}
943% \stopcombination
944
945% \startcombination[nx=3,ny=1]
946%     {\externalfigure[dummy][combination]} {}
947%     {\externalfigure[dummy][combination]} {}
948%     {\externalfigure[dummy][combination]} {}
949% \stopcombination
950
951% \startcombination[nx=4,ny=1]
952%     {\externalfigure[dummy][combination]} {}
953%     {\externalfigure[dummy][combination]} {}
954%     {\externalfigure[dummy][combination]} {}
955%     {\externalfigure[dummy][combination]} {}
956% \stopcombination
957
958\unexpanded\def\inlinefigure[#1]{\dontleavehmode\sbox{\externalfigure[#1][\v!inline]}}
959
960%D Needs to be done global:
961
962\definelayer[epdfcontent]
963
964\protect \endinput
965
966%D Moved here because this already old code is nowhere documents (so I need to check
967%D it:
968%
969% \starttyping
970% \starttext
971%
972% \startluaparameterset [u3d:myset:controls:1]
973%     view = {
974%         name = 'default',
975%         bg = {1,1,1},
976%         mag = 100,
977%         coo = {0,0,0},
978%         c2c = {0,0,1},
979%         rot = {40,0,60},
980%         roo = 6,
981%         lights = 'CAD'
982%     },
983%     js = 'cloudq.js'
984% \stopluaparameterset
985%
986% \startluaparameterset [u3d:myset:controls:2]
987%     views = {
988%         {
989%             name = 'AnglePositioning',
990%             bg = {1,1,1},
991%             azimuth = 45,
992%             altitude = 45,
993%             roo = 50,
994%             aac = 2.5,
995%             lights = 'Artwork'
996%         },
997%         {
998%             name = 'RotationPositioning',
999%             bg = {1,1,1},
1000%             rot = {0,45,45},
1001%             roo = 50,
1002%             aac = 2.5,
1003%             lights = 'Artwork'
1004%         },
1005%         {
1006%             name = 'VectorPositioning',
1007%             bg = {1,0,0},
1008%             c2c = {1,1,math.sqrt(2)},
1009%             roo = 50,
1010%             aac = 2.5,
1011%             lights = 'CAD'
1012%         },
1013%         {
1014%             name = 'PositionPositioning',
1015%             bg = {1,0,0},
1016%             pos = {1+25,1+25,1+50/math.sqrt(2)},
1017%             aac = 2.5,
1018%             lights = 'CAD'
1019%         },
1020%         {
1021%             name = 'ortho',
1022%             bg = {1,1,1},
1023%             mag = 300,
1024%             lights = 'CAD',
1025%             crossection = {}
1026%         }
1027%     },
1028%     view = {
1029%         name = 'default',
1030%         bg = {1,1,1},
1031%         c2c = {-1,-1,0},
1032%         roo = 50,
1033%         aac = 2.5,
1034%         roll = 45,
1035%         lights = 'CAD',
1036%         crossection = {
1037%             normal = {-1,-1,-1},
1038%             transparent = true
1039%         },
1040%         nodes = {
1041%             {
1042%                 name = 'xlabel',
1043%                 visible = false
1044%             },
1045%             {
1046%                 name = 'ylabel',
1047%                 opacity = 0.5
1048%             },
1049%             {
1050%                 name = 'zlabel',
1051%                 rendermode = 'Wireframe'
1052%             }
1053%         }
1054%     }
1055% \stopluaparameterset
1056%
1057% \useexternalfigure
1058%   [cloudq]
1059%   [cloudq.u3d]
1060%   [width=0.7\textwidth,
1061%    height=.7\textwidth,
1062%    display=u3d:myset:display:1,
1063%    controls=u3d:myset:controls:1]
1064%
1065% \useexternalfigure
1066%   [axes]
1067%   [axes.u3d]
1068%   [width=0.7\textwidth,
1069%    height=.7\textwidth,
1070%    controls=u3d:myset:controls:1]
1071%
1072% \startluaparameterset[u3d:myset:display:2]
1073%     toolbar = true,
1074%     preview = 'cloudq.png'
1075% \stopluaparameterset
1076% \startluaparameterset[u3d:myset:display:3]
1077%     toolbar = true,
1078%     tree = false,
1079%     preview = 'axes.png'
1080% \stopluaparameterset
1081% \startluaparameterset[u3d:myset:display:4]
1082%     toolbar = true,
1083%     tree = false,
1084%     view = {
1085%         name = 'view',
1086%         bg = {0.1,0.1,0.1},
1087%         c2c = {-1,-1,0},
1088%         roo = 50,
1089%         aac = 2.5,
1090%         roll = 45,
1091%         lights = 'Red'
1092%     }
1093% \stopluaparameterset
1094% \startluaparameterset[u3d:myset:display:5]
1095%     toolbar = true,
1096%     tree = false,
1097%     view = 'ortho'
1098% \stopluaparameterset
1099%
1100% \placefigure[here]{none}{\externalfigure[cloudq][frame=on,display=u3d:myset:display:2]}
1101% \placefigure[here]{none}{\externalfigure[axes]  [frame=on,display=u3d:myset:display:3]}
1102% \placefigure[here]{none}{\externalfigure[axes]  [frame=on,display=u3d:myset:display:4]}
1103% \placefigure[here]{none}{\externalfigure[axes]  [frame=on,display=u3d:myset:display:5,width=0.5\textwidth,height=.5\textwidth]}
1104%
1105% \stoptext
1106