From 63a8575f80c1b973beff974090dcd2570fd8e325 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 4 Dec 2008 01:54:15 +0000 Subject: new context package context-gnuplot (3dec08) git-svn-id: svn://tug.org/texlive/trunk@11513 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/context/third/gnuplot/t-gnuplot.tex | 925 +++++++++++++++++++++ 1 file changed, 925 insertions(+) create mode 100755 Master/texmf-dist/tex/context/third/gnuplot/t-gnuplot.tex (limited to 'Master/texmf-dist/tex/context') 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) | + height=default, % *default* (3in) | + 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 + -- cgit v1.2.3