summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/third/gnuplot
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2008-12-04 01:54:15 +0000
committerKarl Berry <karl@freefriends.org>2008-12-04 01:54:15 +0000
commit63a8575f80c1b973beff974090dcd2570fd8e325 (patch)
tree819a9002f6f77bf18409adb92f6133eccdd40fd6 /Master/texmf-dist/tex/context/third/gnuplot
parent45fc4db67b07e91238eba1f833fa950e333ca22a (diff)
new context package context-gnuplot (3dec08)
git-svn-id: svn://tug.org/texlive/trunk@11513 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/third/gnuplot')
-rwxr-xr-xMaster/texmf-dist/tex/context/third/gnuplot/t-gnuplot.tex925
1 files changed, 925 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/third/gnuplot/t-gnuplot.tex b/Master/texmf-dist/tex/context/third/gnuplot/t-gnuplot.tex
new file mode 100755
index 00000000000..aff8d0fc2ff
--- /dev/null
+++ b/Master/texmf-dist/tex/context/third/gnuplot/t-gnuplot.tex
@@ -0,0 +1,925 @@
+%D \module
+%D [ file=t-gnuplot,
+%D version=2007.02.07,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\GNUPLOT\ Inclusion,
+%D author={Hans Hagen, Taco Hoekwater, Mojca Miklavec, (Aditya Mahajan)},
+%D date=\currentdate,
+%D copyright=\PRAGMA]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module is used for creating gnuplot graphs on-the-fly and including them
+%D into documents.
+%D
+%D Known Bugs:
+%D
+%D \startitemize
+%D \item spurious space \& page
+%D \stopitemize
+%D
+%D TODO (Optimisations):
+%D
+%D \startitemize
+%D \item optimize the number of gnuplot runs (if possible, gnuplot should be run only once)
+%D \item optimize the number of times for loading/converting an already used graphic
+%D \item pstopdf is a bit slow
+%D \stopitemize
+%D
+%D TODO (Handle things that may go wrong):
+%D - gnuplot executable doesn't exist
+%D - context terminal isn't available or some other failure in gnuplot script (no file created)
+%D - write18 disabled (you may call gnuplot later - create a script)
+%D
+%D TODO (Missing functionality):
+%D
+%D - a lot ...
+
+\writestatus{loading}{Gnuplot module}
+
+\startmodule[gnuplot]
+
+\unprotect
+
+\def\c!terminal {terminal}
+\def\c!options {options}
+\def\c!pointset {pointset}
+
+%D MPextensions
+%D
+%D XXX
+%D if possible, they should be specific to \type{\startGNUPLOTgraphic},
+%D so unvisible to \type{MPcode}
+%D (probably something like \type+\appendtoks ... to\everyGNUPLOTgraphic+)
+\startMPextensions
+ % load metapost macros (only once)
+ input mp-gnuplot.mp ;
+ % number of points defined with \setupGNUPLOTterminal[pointset=...]
+ %gp_num_points_with_tex := \gp:num:pointswithtex;
+ gp_num_points_with_tex := 3;
+ % main color should be set equal to the current text color
+ gp_color_foreground := \MPcolor{currentcolor};
+ gp_color_lt[-2] := gp_color_foreground;
+ % TODO: is there any chance to make this local to gnuplot?
+ % linejoin & linecap
+ linejoin := \@@GNUPLOT@term@context@linejoin;
+% linecap := \gp:term:context:linecap;
+ % dashes or solid? (true/false)
+ gp_use_dashed := \@@GNUPLOT@term@context@is@dashed;
+ % dashlength scale
+% gp_scale_dashlength := \gp:term:context:dashlength;
+ % linewidth scale
+ gp_scale_linewidth := \@@GNUPLOT@term@context@linewidth;
+
+ gp_scale_text := \@@GNUPLOT@term@context@textscale;
+
+ % linejoin := \gp:term:context:linejoin;
+ % linecap := \gp:term:context:linecap;
+ % % dashes or solid? (true/false)
+ % gp_use_dashed := \gp:term:context:dashed;
+ % % dashlength scale
+ % gp_scale_dashlength := \gp:term:context:dashlength;
+ % % linewidth scale
+ % gp_scale_linewidth := \gp:term:context:linewidth;
+
+\stopMPextensions
+
+%D (hopefully) temporary solution for handling the color in expressions like
+%D \type+draw \sometxt{...} withcolor red+
+\chardef\TeXtextcolormode\zerocount
+
+%D We have to make sure that runtime MP graphics are enabled,
+%D otherwise sizes of labels created by \type+\sometxt{}+ would be wrong
+%D if user didn't enable that option in \type{cont-usr.tex}.
+%D (Taco says it might be a bug, but let's not worry too much about it.
+%D If it will be resolved, we may delete this.)
+\runMPgraphicstrue
+
+%D We need a \type{\strut} in front of labels for better vertical centering.
+%D This might still fail for Zapfino and alike where \type{\strut} might be smaller
+%D than the actual font height.
+%D
+%D TODO (optional improvement): instead of placing \type{\strut} in front,
+%D create a \type{\hbox} and adjust it's dimensions to \type{\strut}'s height and depth.
+
+%D Aditya, thanks a lot for requesting it!
+%D Hans, thanks a lot for implementing this!
+\definetextext[gp]{\strut}
+%D TODO (feature request):
+%D \starttyping
+%D \sometxt[gp][ss,20pt]{abc}
+%D \stoptyping
+%D should become equivalent to
+%D \starttyping
+%D \sometxt{\switchtobodyfont[ss,20pt]\strut abc}
+%D \stoptyping
+%D
+%D Or, even more drastic perhaps, I would love to implement
+%D \starttyping
+%D \sometxt[gp][iwona,bold,c]{abc}
+%D \stoptyping
+%D meaning: iwona, bold typeface, size \quote{c}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%D The following patch has been written by Aditya and seems to work OK,
+%D however it would be more clean to have this functionality in the core.
+%D Redefining low-level macros might be a bit dangerous, esp. since
+%D they tend to change over time.
+%D
+%D TODO: remind Hans to implement it in core ;)
+%D and remove this patch from the module
+
+\long\def\redofiltersometxt[#1]%
+{\doifnextcharelse[{\reredofiltersometxt[#1]}{\redodofiltersometxt[#1]}}
+
+\long\def\redodofiltersometxt[#1]#2%
+ {\increment\txtcounter
+ \TeXtext[#1]\txtcounter{#2}%
+ \filtersometxt}
+
+\long\def\reredofiltersometxt[#1][#2]#3%
+ {\increment\txtcounter
+ \TeXtext[#1]\txtcounter{\switchtobodyfont[#2]\strut#3}%
+ \filtersometxt}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+%D For the old method of \type{put_text("some text")} using textext:
+%D not used/supported any more, but still here for testing purposes
+%D (to be removed in the future)
+\forceMPTEXcheck{put_text}
+%\runMPTEXgraphicstrue
+
+\newcounter\GNUPLOTnumber
+
+%D \macros
+%D {startGNUPLOTinclusions, resetGNUPLOTinclusions}
+%D
+%D For those who want to have two or more graphs with similar options,
+%D these options may be included inside \type{\startMPinclusions ... \stopMPinclusions}
+%D and will be place on the top of the created \GNUPLOT\ script.
+%D
+%D \starttyping
+%D \startMPinclusions
+%D set xlabel '$x$'
+%D set ylabel '$y$'
+%D set format y "%.1f"
+%D \stopMPinclusions
+%D
+%D \startGNUPLOTscript{sin}
+%D plot sin(x)
+%D \stopGNUPLOTscript
+%D \startGNUPLOTscript{cos}
+%D plot cos(x)
+%D \stopGNUPLOTscript
+%D \stoptyping
+
+%D The code is not 100\% robust. Different characters and/or expansions may cause problems.
+%D \type{\%} takes care for not ignoring what comes after \type{%}.
+%D That might be only start of the game.
+\long\def\startGNUPLOTinclusions
+ {\bgroup
+ \obeylines
+ \catcode`\%=\@@letter
+ \catcode`\|=\@@letter
+ \dostartGNUPLOTinclusions}
+
+\long\def\dostartGNUPLOTinclusions#1\stopGNUPLOTinclusions
+ {\gdef\GNUPLOTinclusions{#1}%
+ \egroup}
+
+\def\resetGNUPLOTinclusions{\let\GNUPLOTinclusions\empty}
+
+\resetGNUPLOTinclusions
+
+%D On the other hand, one can probably achieve the same effect
+%D when drawing two plots inside the same script, like that:
+%D
+%D \starttyping
+%D \startGNUPLOTscript{sin and cos}
+%D set xlabel '$x$'
+%D set ylabel '$y$'
+%D set format y "%.1f"
+%D plot sin(x)
+%D plot cos(x)
+%D \stopGNUPLOTscript
+%D \stoptyping
+%D
+%D and then recall the graphics using \type{\useGNUPLOTgraphic[sin and cos][1]}.
+
+%D \macros
+%D {startGNUPLOTscript}
+%D
+%D \starttyping
+%D \startGNUPLOTscript{some name}
+%D plot sin(x)
+%D \stopGNUPLOTscript
+%D \stoptyping
+
+%\long\def\startGNUPLOTscript#1%
+% {\bgroup
+% \obeylines
+% \catcode`\%=\@@letter
+% \dostartGNUPLOTscript{#1}}
+
+\def\startGNUPLOTscript
+ {\bgroup\dosingleempty\dostartGNUPLOTscript}
+
+\def\redostartGNUPLOTscript#1
+ {\obeylines
+ \catcode`\%=\@@letter
+ \catcode`\|=\@@letter
+ \catcode`\$=\@@letter
+ \dodostartGNUPLOTscript{#1}%
+%\dostartGNUPLOTscript[#2]
+}
+
+\def\dostartGNUPLOTscript[#1]%
+ {\iffirstargument
+ \obeylines
+ \catcode`\%=\@@letter
+ \catcode`\|=\@@letter
+ \catcode`\$=\@@letter
+ \dodostartGNUPLOTscript{#1}%
+ \else
+ \redostartGNUPLOTscript
+ \fi
+}
+
+% FIXME:
+% Math labels still don't work properly
+% plot x t '$\frac{2}{\sqrt{\pi}}e^{-x^2}$'
+% will fail for example.
+%
+% Taco suggested to put \detokenize in front of the argument,
+% but then I run into problems with newlines.
+% I've lost too many nerves with ^^M already.
+% This item should be somewhere on top of priority list,
+% but I'm no TeXacker.
+%
+\long\def\dodostartGNUPLOTscript#1#2\stopGNUPLOTscript
+ {\doglobal\increment\GNUPLOTnumber
+ \letgvalue{gps:n:#1}\GNUPLOTnumber
+ \setgvalue{gps:d:\GNUPLOTnumber}{#2}%
+% \setgvalue{gps:d:\GNUPLOTnumber}{\detokenize{#2}}%
+ \egroup}
+
+\long\def\dodostartGNUPLOTscript#1#2\stopGNUPLOTscript
+ {\doglobal\increment\GNUPLOTnumber
+ \letgvalue{gps:n:#1}\GNUPLOTnumber
+ \setgvalue{gps:d:\GNUPLOTnumber}{#2}%
+% \setgvalue{gps:d:\GNUPLOTnumber}{\detokenize{#2}}%
+ \egroup}
+
+
+\newtoks\everyGNUPLOTscript
+
+%D We need to preserve newline characters (\TeX\ doesn't distinguish them from spaces).
+%D Finding the proper solution has costed quite some nerves: most solutions resulted in \type{^M}.
+
+\appendtoks
+ \obeylines
+ \def\obeyedline{\outputnewlinechar}%
+\to \everyGNUPLOTscript
+
+%D Content of GNUPLOTscript has to be handled literally:
+%D backslash (\letterbackslash) and percent (\%) may not interfere with \TeX.
+
+\appendtoks
+ \let\%\letterpercent
+ \def\ {\letterbackslash\outputnewlinechar}%
+ \catcode`\$=\@@letter
+\to \everyGNUPLOTscript
+
+% When are the graphics processed/read?
+%
+% - \gps:n:{name} (gnuplot script:name:{name}) holds the number of gnuplot script;
+% - that number was defined if we created the plot using \startGNUPLOTscript{name}
+% - and most probably undefined if we only issued \processGNUPLOTfile[name][filename]
+% => if, at the time of issuing \processGNUPLOTfile[name][filename], \gps:n:{name} is not defined,
+% it should be defined at that time
+% - \gpe:{name}:{terminal} (gnuplot graphic executed:{name}:{terminal})
+% is defined if we executed the command for that specific name and for that terminal
+% (once it will probably be 0 for a failed run and 1 for a successful one)
+
+% \useGNUPLOTgraphic[name] has three different ways of working:
+% - it can be called after \processGNUPLOTfile[name][filename]
+% which defined MP graphics that are now used
+% - it can be called for the first time under the current terminal
+% in that case it compiles the graphic and includes it
+% - it can be called for the second, third, ... time
+% in which case it only includes files without compiling it
+
+%D \macros
+%D {useGNUPLOTgraphic}
+
+% 5 ways of calling it:
+% - \useGNUPLOTgraphic{name}
+% - \useGNUPLOTgraphic[name]
+% - \useGNUPLOTgraphic[name][1,2,5]
+% - \useGNUPLOTgraphic[name][width=.8\textwidth]
+% - \useGNUPLOTgraphic[name][1,2,5][width=.8\textwidth]
+
+% this code takes care of reading arguments
+\def\useGNUPLOTgraphic
+ {\dotripleempty\douseGNUPLOTgraphic}
+
+\def\douseGNUPLOTgraphic[#1][#2][#3]%
+ {\doifelse{#3}{}{%
+ % < 3 arguments
+ \doifelse{#2}{}%
+ % 1 argument
+ % as in \useGNUPLOTgraphic[name]
+ {\dodouseGNUPLOTgraphic[#1][][]}%
+ % % as in \useGNUPLOTgraphic{name}
+ % {\redouseGNUPLOTgraphic[][][]}%
+ % 2 arguments
+ {\doifassignmentelse{#2}%
+ % as in \useGNUPLOTgraphic[name][width=.8\textwidth]
+ {\dodouseGNUPLOTgraphic[#1][][#2]}%
+ % as in \useGNUPLOTgraphic[name][1,2,5]
+ {\dodouseGNUPLOTgraphic[#1][#2][]}%
+ }%
+ }%
+ % as in \useGNUPLOTgraphic[name][1,2,5][width=.8\textwidth]
+ {\dodouseGNUPLOTgraphic[#1][#2][#3]}%
+ }
+
+\def\redouseGNUPLOTgraphic[#1][#2][#3]#4%
+ {\dodouseGNUPLOTgraphic[#4][][]}
+
+% and this code actually does something with it
+
+%D \doifundefined {string} {...}
+%D \doifdefined {string} {...}
+%D \doifundefinedelse {string} {then ...} {else ...}
+%D \doifdefinedelse {string} {then ...} {else ...}
+
+% \doifGNUPLOTscriptdefined{name}{...}
+
+% if gnuplot script with {name} and current terminal has already been processed
+% \doifGNUPLOTscriptprocessed{name}{...}
+
+% \letGNUPLOTscriptprocessed[optional terminal]{name} signals that the gnuplot script named {name}
+% has already been processed with the current terminal
+% TODO: currently it is always defined to be one as soon as one tries to process it,
+% even if en error is produced; in future it would be helpful if it would be set to zero
+% if it was unsuccessfully executed;
+% that is needed, since scripts are processed only when one first asks for including the graphic
+\def\letGNUPLOTscriptprocessed
+ {\dosingleempty\doletGNUPLOTscriptprocessed}
+%\def\doletGNUPLOTscriptprocessed[#1]#2%
+%{\letgvalue{gpe:#1:\@@GNUPLOTterminal}\plusone}
+\def\doletGNUPLOTscriptprocessed[#1]#2%
+ {\iffirstargument
+ % terminal has been specified
+ \letgvalue{gpe:#2:#1}\plusone
+ \else
+ % no terminal specified - use the current one
+ \letgvalue{gpe:#2:\@@GNUPLOTterminal}\plusone
+ \fi}
+
+% Although that should preferably not happen, one might come to an idea of defining
+% a gnuplot script with the same name as already defined.
+% In that case the old script cannot be referenced any more, but we can still try
+% to do out best to make it work anyway. We have to do two things:
+% - claim that script with that name hasn't been defined yet, so that processing will happen again
+% (TODO: do it in a more elegant way for all known terminals)
+% - undefine any metapost graphics (TODO: I have no idea yet how it can be done)
+%
+% \resetGNUPLOTscriptprocessed{name}
+\def\resetGNUPLOTscriptprocessed#1%
+ {\bgroup
+ % claim that the script with {name} (#1) hasn't been processed with {terminal} (##1) yet
+ \def\undefineGNUPLOTscriptforterminal##1{\letbeundefined{gpe:#1:##1}}%
+ % TODO: the list of available terminals should be generated automatically
+ \processcommalist[context,postscript,ps,eps,pdf,metapost,mp,png]\undefineGNUPLOTscriptforterminal
+ \resetGNUPLOTgraphics{#1}%
+ \egroup}
+
+% \resetGNUPLOTgraphics{name} undefines any gnuplot graphic defined with \startGNUPLOTgraphic[name][number]
+\def\resetGNUPLOTgraphics#1%
+ {\doloop
+ {\doifMPgraphicelse{gpg:#1:\recurselevel}%
+ % TODO: be aware - @@MPG is low-level ConTeXt variable which might change without notice,
+ % it would be better to call this \undefineMPgraphic{gpg:#1:\recurselevel} or something similar
+ {\letbeundefined{@@MPGgpg:#1:\recurselevel}}%
+ {\exitloop}}%
+ }%
+
+% TODO: this can probably be done in a better way
+\def\doifGNUPLOTscriptprocessed#1#2%
+ {\doifdefined {gpe:#1:\@@GNUPLOTterminal}{#2}}
+\def\doifGNUPLOTscriptprocessedelse#1#2#3%
+ {\doifdefinedelse {gpe:#1:\@@GNUPLOTterminal}{#2}{#3}}
+\def\doifGNUPLOTscriptnotprocessed#1#2%
+ {\doifundefined {gpe:#1:\@@GNUPLOTterminal}{#2}}
+\def\doifGNUPLOTscriptnotprocessedelse#1#2#3%
+ {\doifundefinedelse{gpe:#1:\@@GNUPLOTterminal}{#2}{#3}}
+
+
+% private
+% \writeandprocessGNUPLOTscript{name}
+\def\writeandprocessGNUPLOTscript#1%
+ % TODO: if gps:n:#1 (holding the script content) is not defined,
+ % error or warning should be issued
+ %
+ % only process the script if it has been defined and not processed before for the current terminal
+ {\doifdefined{gps:n:#1}{\doifGNUPLOTscriptnotprocessed{#1}{%
+ % \gpe:{name}:{terminal} is defined
+ %\setgvalue{gpe:#1:\@@GNUPLOTterminal}{#2}
+ \letGNUPLOTscriptprocessed{#1}
+ % call to gnuplot and processing/converting the graphics is only needed in the first ConTeXt run
+ \doifmode{*\v!first}{% (perhaps also: if files haven't changed)
+ \bgroup
+ % catcodes trickery & alike
+ \the\everyGNUPLOTscript
+ % open file for writing
+ \immediate\openout\scratchwrite=\GNUPLOTfile.plt
+ % TODO: terminal-specific options (default or provided by the user)
+ \immediate\write\scratchwrite{\letterhash\space Do not modify this file - all changes will be overwritten}%
+ \immediate\write\scratchwrite{\letterhash\space Change \jobname.tex instead.}%
+ \immediate\write\scratchwrite{set terminal \@@GNUPLOToutput\space\@@GNUPLOToptions}%
+ % add common inclusions in scripts for multiple similar plots
+ \doifnotempty
+ {\GNUPLOTinclusions}{\immediate\write\scratchwrite{\GNUPLOTinclusions}}%
+ \immediate\write\scratchwrite{set output "\@@GNUPLOTresult"}%
+ % write main contents of the script, like "plot sin(x)"
+ \immediate\write\scratchwrite{\getvalue{gps:d:\GNUPLOTnumber}}%
+ \immediate\closeout\scratchwrite
+ \egroup
+ % TODO:
+ % - check the state of write18 and warn the user if it's disabled,
+ % otherwise just everyone will start complaining that the module doens't work
+ % - check if execution was successful; possible pitfalls:
+ % - gnuplot doesn't exist as a binary
+ % - gnuplot doesn't support context terminal
+ % or some other error in script which results in empty output file
+ %
+ % run gnuplot & execute the script that has just been written
+ \executesystemcommand{texmfstart --ifchanged=\GNUPLOTfile.plt\space
+ --direct \@@GNUPLOTprogram\space\GNUPLOTfile.plt}%
+ \convertGNUPLOTgraphic
+ }%
+ % for ConTeXt terminal only - read the result
+ \doif{\@@GNUPLOTterminal}{context}{\processGNUPLOTfile[#1][\@@GNUPLOTresult]}%
+ }}}
+
+% \dodouseGNUPLOTgraphic[name][numbers][options]
+\def\dodouseGNUPLOTgraphic[#1][#2][#3]%
+ {\bgroup
+ \doifdefined{gps:n:#1}
+ {\edef\GNUPLOTnumber{\getvalue{gps:n:#1}}%
+ \edef\GNUPLOTfile {\bufferprefix gnuplot-\GNUPLOTnumber}%
+ \writeandprocessGNUPLOTscript{#1}%
+ % "ctxtools --purge" should delete the gnuplot script and other intermediate files
+ % (but it seems that they are deleted automatically already; preferred or not?)
+% \registertempfile{\GNUPLOTfile.plt}
+% \registertempfile{\@@GNUPLOTresult}
+% \registertempfile{\@@GNUPLOTfinalresult}
+ \doifelse{\@@GNUPLOTterminal}{context}%
+ % for ConTeXt terminal only
+ {\doifelse{#2}{}%
+ % if no explicit figure number was specified, include all the figures
+ {\doloop
+ {\doifMPgraphicelse{gpg:#1:\recurselevel}%
+ {\scale[#3]{\reuseMPgraphic{gpg:#1:\recurselevel}}}%
+ {\exitloop}}}%
+ % if numbers were specified, include the figures specified in the list only
+ {\begingroup
+ \def\useGNUPLOTgraphicN##1{\doifMPgraphicelse
+ {gpg:#1:##1}%
+ {\scale[#3]{\reuseMPgraphic{gpg:#1:##1}}}%
+ % if graphic doesn't exist: draw a dummy frame instead and warn the user
+ {\scale[#3]{\framed[frame=on,width=5in,height=3in,align={middle,lohi}]{GNUPLOT graphic #1, Nr. ##1 doesn't exist}}}}%
+ \processcommalist[#2]\useGNUPLOTgraphicN
+ \endgroup
+ }%
+ }%
+ % for all the other terminals
+ % TODO: add more safety switches (if pages don't exist for example)
+ {\doifelse{#2}{}%
+ % if no explicite figure number was specified, include all the pages
+ % TODO: properly handle METAPOST & PNG (only works for (E)PS & PDF) !!!
+ {\getfiguredimensions[\@@GNUPLOTresult]%
+ \dorecurse{\noffigurepages}{\externalfigure[\@@GNUPLOTfinalresult][page=\recurselevel,#3]}}%
+ % if numbers were specified, include the pages specified in the list only
+ {\begingroup
+ \def\useGNUPLOTgraphicN##1{\externalfigure[\@@GNUPLOTfinalresult][page=##1,#3]}%
+ \processcommalist[#2]\useGNUPLOTgraphicN
+ \endgroup
+ }%
+ }%
+ }%
+ \egroup}
+
+%D \macros
+%D {setupGNUPLOT}
+
+\def\setupGNUPLOT
+% {\dodoubleempty\getparameters[@@GNUPLOT]}
+ {\dosingleargument\dosetupGNUPLOT}
+
+\def\dosetupGNUPLOT[#1]%
+ {\getparameters[@@GNUPLOT][#1]%
+ % define all the necessary points according to the option "pointset"
+ %
+ % XXX: no idea why this is needed, but otherwise it complains that @@GNUPLOTpointset is undefined
+ \edef\currentGNUPLOTpointset{\@@GNUPLOTpointset}%
+ \startTeXtexts
+ \doloop{\doifelseconversionnumber{\@@GNUPLOTpointset}{\recurselevel}%
+ % +500 is a hack (hopefully the plot doesn't contain more than 500 labels)
+ % otherwise the points would be overwritten by labels with another \TeXtext:
+ % it might need a fix in ConTeXt core
+ {\TeXtext{\numexpr\recurselevel+500\relax}{{\convertnumber{\currentGNUPLOTpointset}{\recurselevel}}}}%
+ {\exitloop}}%
+ \stopTeXtexts
+ % \gp:num:pointswithtex is passed to metapost, so that it knows
+ % how many points are defined and chooses the proper point
+ % form a set of the defined ones
+ %
+ % for safety reasons define \gp:num:pointswithtex to be equal to 1 (it can only increase later), otherwise:
+ % - (something mod 0) won't work
+ % - if conversion is not defined, the number will retain its old value (not desirable)
+ \edef\gp:num:pointswithtex{1}%
+ \doloop{\doifelseconversionnumber{\@@GNUPLOTpointset}{\recurselevel}%
+ {\edef\gp:num:pointswithtex{\recurselevel}}%
+ {\exitloop}}%
+ % TODO:
+ % - issue a warning if user wants to use points with TeX,
+ % but pointset= is undefined (if the first point doesn't exist)
+ % - no idea what happens if conversion is infinite,
+ % so try to stop at some reasonable value (100?)
+ % - current implementation redefines the points even if only terminal type
+ % has been set to some other value (which is a stupid approach, but I
+ % wanted to have a working version first and will consider efficiency later)
+ % - it may be that the old points remain defined if conversion changes
+ % (perhaps they should be undefined again?)
+ }
+
+% Hans has written this piece of code, but:
+% - "start" and "/MIN" caused problems
+% - pgnuplot is not much more "portable" than gnuplot
+% best thing to do is to create a "gnuplot.bat" somewhere in PATH
+%
+%\def\processGNUPLOTscript
+% {\doifelse\operatingsystem{mswin}
+% {\executesystemcommand{start /MIN pgnuplot \GNUPLOTfile.plt}} % start is needed else gp fails
+% {\executesystemcommand{gnuplot \GNUPLOTfile.plt}}}
+%\def\processGNUPLOTscript
+% {\executesystemcommand{gnuplot \GNUPLOTfile.plt}}
+
+% TODO: check if write18 is enabled; if not, issue a command and warn the user that running the module might be pointless or that he/she has to run gnuplot on the produced files manually
+\def\convertGNUPLOTgraphic
+ {\doifsomething\@@GNUPLOThandle{\executesystemcommand{\@@GNUPLOThandle}}}
+
+%D \macros
+%D {processGNUPLOTfile}
+
+%D It's needed to input a file resulting from a gnuplot run (with ConTeXt terminal).
+%D It reads the file and "saves" the metapost graphics defined in that file,
+%D so that they can be used with \usegnuplotgraphic (low level: \reuseMPgraphic) later
+%D
+% \processGNUPLOTfile[NAME][filename]
+\def\processGNUPLOTfile
+ {\dodoubleargument\doprocessGNUPLOTfile}
+
+\def\doprocessGNUPLOTfile[#1][#2]%
+ {% we first define two commands: \startGNUPLOTgraphic & \stopGNUPLOTgraphic to read the files in;
+ % files that gnuplot creates in non-standalone mode look approximately like this:
+ %
+ % \startGNUPLOTgraphic[1]
+ % ... metapost commands to draw the graph ...
+ % \stopGNUPLOTgraphic
+ % \startGNUPLOTgraphic[2]
+ % ... metapost commands to draw the graph ...
+ % \stopGNUPLOTgraphic
+ % ...
+ %
+ % while reading the file in, metapost graphics named "gpg:{name}:{number}" are defined
+ %
+ % (we might need some additional arguments later on, but for now the figure number should suffice)
+ \def\startGNUPLOTgraphic
+ {\obeyMPlines % <- no longer a problem
+ \def\obeyedline{}% <- thanks to this
+ \dosingleargument\dostartGNUPLOTgraphic}%
+ \long\def\dostartGNUPLOTgraphic[##1]##2\stopGNUPLOTgraphic
+ {\startreusableMPgraphic{gpg:#1:##1}##2\stopreusableMPgraphic}%
+ %
+ % if gps:n:{name} (which is a number) is not defined,
+ % then we first have to increase the \GNUPLOTnumber counter and associate this name with the new number
+
+ % , then we should now also define
+ % gpe:{number}:context which should signal later on that the graphic
+% \doifdefined{gps:n:#1}
+ % input the file
+ % TODO: error / warning if the files doesn't exist
+ \readlocfile{#2}{}{}% the third argument should be: if file not found
+ % this file is known
+ % TODO \letgvalue{gpf:#1}\plusone
+ }
+
+%D \macros
+%D {startGNUPLOTpage}
+%D
+%D Used for standalone \GNUPLOT\ figures & written out by gnuplot in standalone mode.
+%D
+%D Instead of having to \type{\useGNUPLOTgraphic}, a figure is inserted directly using
+%D \type{\startMPpage ... }\type{\stopMPpage}.
+%D
+%D A high-level command is provided if some more advance features will
+%D be needed in the future and to be able to ensure backward compatibility.
+
+%D We need to preserve line breaks, otherwise metapost runs into troubles for longer input.
+\def\startGNUPLOTpage
+ {\obeyMPlines\dostartGNUPLOTpage}
+
+\long\def\dostartGNUPLOTpage#1\stopGNUPLOTpage
+ {\startMPpage#1\stopMPpage}
+
+
+% TODO: currently, the following definitions are used,
+% but the ones below would be preferred
+
+\def\defineGNUPLOThandle#1#2#3#4#5#6% name; output; suffix; conversion-method; gnuplot's result; final result
+ {\setvalue{@@GNUPLOT-#1}{{#2}{#3}{#4}{#5}{#6}}}
+
+\def\@@GNUPLOToutput{\filterfromvalue{@@GNUPLOT-\@@GNUPLOTterminal}51}
+\def\@@GNUPLOTsuffix{\filterfromvalue{@@GNUPLOT-\@@GNUPLOTterminal}52}
+\def\@@GNUPLOThandle{\filterfromvalue{@@GNUPLOT-\@@GNUPLOTterminal}53}
+\def\@@GNUPLOTresult{\filterfromvalue{@@GNUPLOT-\@@GNUPLOTterminal}54}
+\def\@@GNUPLOTfinalresult{\filterfromvalue{@@GNUPLOT-\@@GNUPLOTterminal}55}
+
+% name "set term" suffix conversion (system command) gnuplot's result final result
+% (suffix is probably not needed any more since full names were introduced)
+\defineGNUPLOThandle
+ {postscript}{postscript color}{ps}{texmfstart pstopdf --method=raw \GNUPLOTfile-ps.ps}
+ {\GNUPLOTfile-ps.ps}{\GNUPLOTfile-ps.pdf}
+\defineGNUPLOThandle
+ {ps}{postscript color}{ps}{texmfstart pstopdf -dAutoRotatePages=/PageByPage --method=raw \GNUPLOTfile-ps.ps}
+ {\GNUPLOTfile-ps.ps}{\GNUPLOTfile-ps.pdf}
+\defineGNUPLOThandle
+ {eps}{postscript color eps}{ps}{texmfstart pstopdf -dEPSCrop \GNUPLOTfile-eps.eps}
+ {\GNUPLOTfile-eps.eps}{\GNUPLOTfile-eps.pdf}
+\defineGNUPLOThandle
+ {pdf}{pdf}{pdf}{}
+ {\GNUPLOTfile-pdf.pdf}{\GNUPLOTfile-pdf.pdf}
+\defineGNUPLOThandle
+ {metapost}{mp}{mp}{texmfstart mptopdf \GNUPLOTfile-mp.mp}
+ {\GNUPLOTfile-mp.mp}{\GNUPLOTfile-mp-0.pdf}
+\defineGNUPLOThandle
+ {mp}{mp}{mp}{texmfstart mptopdf \GNUPLOTfile-mp.mp}
+ {\GNUPLOTfile-mp.mp}{\GNUPLOTfile-mp-0.pdf}
+\defineGNUPLOThandle
+ {png}{png}{png}{}
+ {\GNUPLOTfile-png.png}{\GNUPLOTfile-png.png}
+\defineGNUPLOThandle
+ {context}{context textscale \@@GNUPLOT@term@context@textscale}{tex}{}
+ {\GNUPLOTfile-ctx.tex}{\GNUPLOTfile-ctx.tex}
+% \doifnotempty{\@@GNUPLOT@term@context@textscale}{textscale \@@GNUPLOT@term@context@textscale}
+
+\def\defineGNUPLOTterminal
+ {\dodoubleargument\dodefineGNUPLOTterminal}
+
+\def\dodefineGNUPLOTterminal[#1][#2]%
+ {\doifassignmentelse{#2}%
+ % define a proper terminal
+ {}% TODO
+ % only define a synonym for that terminal
+ {}% TODO
+ }
+
+%D {\sl terminal}: argument to be passed to gnuplot in the form of "set term {\sl terminal}"
+%D {\sl defaultoptions}: options to be passed to gnuplot after terminal name:
+%D set term {\sl teminal} {\sl defaultoptions}
+%D not to be touched by users
+%D {\sl suffix}: filename suffix
+%D {\sl result}: the file to which gnuplot should output the result
+%D set output {\sl result}
+%D {\sl convertwith}: command for conversion from gnuplot-generated file to a file that can be read by \CONTEXT; may be empty
+%D {\sl finalresult}: file resulting after the conversion to be read by \CONTEXT
+
+%D \POSTSCRIPT\ terminal
+\defineGNUPLOTterminal
+ [postscript]
+ [terminal=postscript,
+ defaultoptions=color, % TODO: only if \setupcolors[state=start]
+ suffix=ps,
+ result=\GNUPLOTfile-ps.ps,
+ % TODO: -dAutoRotatePages=/PageByPage or remove that option from the default ones
+ convertwith={texmfstart pstopdf --method=raw \GNUPLOTfile-ps.ps},
+ finalresult=\GNUPLOTfile-ps.pdf,
+ ]
+%D Define \type{ps} as a synonym for \type{postscript} terminal
+\defineGNUPLOTterminal
+ [ps]
+ [postscript]
+
+%D \EPS\ terminal:
+%D - same terminal as for \POSTSCRIPT, but slightly different handling
+\defineGNUPLOTterminal
+ [eps]
+ [terminal=postscript,
+ defaultoptions=eps color,
+ suffix=eps,
+ result=\GNUPLOTfile-eps.eps,
+ % TODO: -dEPSCrop
+ convertwith={texmfstart pstopdf -dEPSCrop \GNUPLOTfile-eps.eps},
+ finalresult=\GNUPLOTfile-eps.pdf,
+ ]
+
+%D \PDF\ terminal
+\defineGNUPLOTterminal
+ [pdf]
+ [terminal=pdf,
+ defaultoptions=,
+ suffix=pdf,
+ result=\GNUPLOTfile-pdf.pdf,
+ convertwith=,
+ finalresult=\GNUPLOTfile-pdf.pdf,
+ ]
+
+%D \METAPOST\ terminal:
+%D - deprecated: use the \CONTEXT\ terminal instead,
+%D which was built starting from the \METAPOST\ one,
+%D but improved in many aspects
+\defineGNUPLOTterminal
+ [mp]
+ [terminal=mp,
+ defaultoptions=,
+ suffix=mp,
+ result=\GNUPLOTfile-mp.mp,
+ convertwith={texmfstart mptopdf \GNUPLOTfile-mp.mp},
+ % TODO: support for multiple graphics
+ % one would need a switch in mptopdf, so that a single pdf would be created instead of multiple ones
+ finalresult=\GNUPLOTfile-mp-0.pdf,
+ ]
+
+\defineGNUPLOTterminal
+ [metapost]
+ [mp]
+
+%D png terminal:
+%D - bitmap
+%D - no conversion needed
+%D - new version pretty advanced
+\defineGNUPLOTterminal
+ [png]
+ [terminal=png,
+ defaultoptions=,
+ suffix=png,
+ result=\GNUPLOTfile-png.png,
+ convertwith=,
+ finalresult=\GNUPLOTfile-png.png,
+ ]
+
+%D \CONTEXT\ terminal (native)
+\defineGNUPLOTterminal
+ [context]
+ [terminal=context,
+ defaultoptions=,
+ suffix=tex,
+ result=\GNUPLOTfile-ctx.tex,
+ convertwith=,
+ finalresult=\GNUPLOTfile-ctx.tex,
+ ]
+
+\def\setupGNUPLOTterminal
+ {\dodoubleargument\dosetupGNUPLOTterminal}
+
+\def\dosetupGNUPLOTterminal[#1][#2]%
+ {% TODO
+ \getparameters[@@GNUPLOT@term@#1@][#2]
+ % TODO: width & height
+ % linejoin, linecap - I have to improve this !!!
+ % \edef\gp:term:context:linejoin{\@@GNUPLOT@term@context@linejoin}
+ % \edef\gp:term:context:linecap{\@@GNUPLOT@term@context@linecap}
+ % dashed or solid lines?
+ \doifsamestringelse{\@@GNUPLOT@term@context@dashed}{yes}% yes or no
+ {\edef\@@GNUPLOT@term@context@is@dashed{true}}%
+ {\edef\@@GNUPLOT@term@context@is@dashed{false}}%
+ % {\edef\gp:term:context:dashed{true}}%
+ % {\edef\gp:term:context:dashed{false}}%
+ % % dashlength scale
+ % \edef\gp:term:context:dashlength{\@@GNUPLOT@term@context@dashlength}
+ % % linewidth scale
+ % \edef\gp:term:context:linewidth{\@@GNUPLOT@term@context@linewidth}
+ }
+
+\setupGNUPLOTterminal
+ [context]
+ [width=default, % *default* (5in) | <dimension>
+ height=default, % *default* (3in) | <dimension>
+ linejoin=rounded, % mitered | *rounded* | beveled
+ linecap=butt, % *butt* | rounded (in gnuplot: round) | squared
+ dashed=yes, % *yes* | no
+ dashlength=1, % scaling factor for dash lengths
+ linewidth=1, % scaling factor for line widths (1.0 means 0.4bp)
+ textscale=1, % scaling factor for text labels
+ points=metapost] % *metapost* | tex (Should points be drawn with MetaPost or TeX?)
+
+% TODO: better scaling
+\defineconversion
+ [gnuplot:pointset]
+ [{\scale[scale=800]{\mathematics{+}}},
+ {\scale[scale=800]{\mathematics{\times}}},
+ \mathematics{\ast},
+ {\scale[scale=700]{\mathematics{\square}}},
+ {\scale[scale=700]{\mathematics{\blacksquare}}},
+ \mathematics{\circ},
+ \mathematics{\bullet},
+ {\scale[scale=900]{\mathematics{\triangleup}}},
+ {\scale[scale=900]{\mathematics{\blacktriangle}}},
+ {\scale[scale=900]{\mathematics{\triangledown}}},
+ {\scale[scale=900]{\mathematics{\blacktriangledown}}},
+ {\scale[scale=800]{\mathematics{\lozenge}}},
+ {\scale[scale=800]{\mathematics{\blacklozenge}}}%,
+% {\rotate[rotation=45]{\mathematics{\square}}},
+% {\rotate[rotation=45]{\mathematics{\blacksquare}}},
+ ]
+
+%\defineGNUPLOTcolor[red] [r=1]
+%\defineGNUPLOTcolor[green] [g=1]
+%\defineGNUPLOTcolor[blue] [b=1]
+%\defineGNUPLOTcolor[magenta][r=1,b=1]
+%\defineGNUPLOTcolor[cyan] [g=1,b=1]
+%\defineGNUPLOTcolor[yellow] [r=1,g=1]
+%\defineGNUPLOTcolor[black] [s=0]
+%\defineGNUPLOTcolor[orange] [r=1,g=.3,b=0]
+%\defineGNUPLOTcolor[gray50] [s=.5]
+
+%\defineGNUPLOTcolors
+% [default] % from PostScript
+% [red,green,blue,magenta,cyan,yellow,black,orange,gray50]
+
+% TODO: testset is here only temporary & for testing
+\setupGNUPLOT[program=gnuplot,\c!terminal=context,\c!options=,\c!pointset=gnuplot:pointset] % colors=postscript
+
+%D Some additional typescripts which enable us using font "Arial" and "Helvetica"
+
+%D Pretend the font to be serif as well, so that no "ss" switch is needed
+\starttypescript [serif] [helvetica] [name]
+ \definefontsynonym [Serif] [Helvetica]
+ \definefontsynonym [SerifBold] [Helvetica-Bold]
+ \definefontsynonym [SerifItalic] [Helvetica-Oblique]
+ \definefontsynonym [SerifSlanted] [Helvetica-Oblique]
+ \definefontsynonym [SerifBoldItalic] [Helvetica-BoldOblique]
+ \definefontsynonym [SerifBoldSlanted] [Helvetica-BoldOblique]
+ \definefontsynonym [SerifCaps] [Helvetica]
+\stoptypescript
+
+\starttypescript [gnuplot] [texnansi,ec]
+ \definetypeface [Helvetica] [rm] [serif] [helvetica] [default] [encoding=\typescripttwo]
+ \definetypeface [Helvetica] [ss] [sans] [helvetica] [default] [encoding=\typescripttwo]
+ \definetypeface [Arial] [rm] [serif] [helvetica] [default] [encoding=\typescripttwo]
+ \definetypeface [Arial] [ss] [sans] [helvetica] [default] [encoding=\typescripttwo]
+\stoptypescript
+
+% TODO: fix for XeTeX
+\usetypescript[gnuplot][ec]
+
+\stopmodule
+
+\protect \doifnotmode{demo}{\endinput}
+
+
+\starttext
+
+\startGNUPLOTscript[exp]
+set key bottom
+set format x "%.1f"
+set format y "%.1f"
+set style fill solid 0.25 noborder
+plot [0:3] 2/sqrt(pi)*exp(-x**2) t '$\frac{2}{\sqrt{\pi}}e^{-x^2}$' with filledcurves x1 lt 3, erf(x) lc 3 lw 2
+\stopGNUPLOTscript
+
+\useGNUPLOTgraphic[exp][width=.7\textwidth]
+
+
+\startGNUPLOTinclusions
+ set title "trigonometry"
+\stopGNUPLOTinclusions
+
+\startGNUPLOTscript[sin]
+ plot sin(x)
+\stopGNUPLOTscript
+
+\startGNUPLOTscript[cos]
+ plot cos(x)
+\stopGNUPLOTscript
+
+\useGNUPLOTgraphic[sin] \endgraf
+\useGNUPLOTgraphic[cos] \endgraf
+\useGNUPLOTgraphic[cos] \endgraf
+
+\setupGNUPLOT[terminal=ps] \useGNUPLOTgraphic[sin][object=no,height=2cm] \blank
+%setupGNUPLOT[terminal=pdf] \useGNUPLOTgraphic[sin][object=no,height=2cm] \blank
+%setupGNUPLOT[terminal=png] \useGNUPLOTgraphic[sin][object=no,height=2cm] \blank
+\setupGNUPLOT[terminal=mp] \useGNUPLOTgraphic[sin][object=no,height=2cm,options=color] \blank
+
+\stoptext
+