summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/metapost/makecirc/latex.mp
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/metapost/makecirc/latex.mp')
-rw-r--r--Master/texmf-dist/metapost/makecirc/latex.mp246
1 files changed, 246 insertions, 0 deletions
diff --git a/Master/texmf-dist/metapost/makecirc/latex.mp b/Master/texmf-dist/metapost/makecirc/latex.mp
new file mode 100644
index 00000000000..f2f1945ef32
--- /dev/null
+++ b/Master/texmf-dist/metapost/makecirc/latex.mp
@@ -0,0 +1,246 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% latex.mp Parametrizable latex labels for metapost
+%% Copyright (c) 2003 JL Diaz
+%% based on an idea taken from Metafun, by Hans Hagen
+%
+% This program may be distributed and/or modified under the conditions
+% of the LaTeX Project Public License, either version 1.2 of this
+% license or (at your option) any later version. The latest version
+% of this license is in http://www.latex-project.org/lppl.txt and
+% version 1.2 or later is part of all distributions of LaTeX version
+% 1999/12/01 or later.
+%
+% This program consists of the file latex.mp
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% For the impatient: Jump to "USAGE"
+%
+% Introduction: The problem
+%
+% Let us suppose that you need to typeset several labels of the form
+% $x_1$, $x_2$, ... $x_{10}$. Since each label is a formula, the
+% construction btex/etex is required to typeset it through TeX (or
+% LaTeX). So, the straighforward solution is:
+%
+% label(btex $x_1$ etex, (1u,0u));
+% label(btex $x_2$ etex, (2u,0u));
+% ...
+% label(btex $x_{10}$ etex, (10u,0u));
+%
+% This repeated structure is inviting us to convert it into a for
+% loop. A naive attempt would be:
+%
+% for i=1 upto 10:
+% label (btex $x_{i}$ etex, (i*u, 0));
+% endfor;
+%
+% Unfortunately the above would produce ten times the same label
+% $x_{i}$, because i is not evaluated in this context as a variable.
+%
+% A second, more clever attempt would be:
+%
+% for i=1 upto 10:
+% label("btex $x_{" & decimal i & "}$ etex", (i*u, 0));
+% endfor;
+%
+% where we are making use of the string concatenation operator (&),
+% and the "decimal" operator, which produces an string whith the
+% decimal representation of its argument. This way, the macro label
+% will receive successively as first argument the strings: "btex
+% $x_{1}$ etex", "btex $x_{2}$ etex", end so on.
+%
+% This solution does not work either, because label is receiving a
+% string, instead of a picture (which is the result of a proper
+% btex/etex construction). When a string is received, label simply
+% outputs that string, without calling TeX (LaTeX) for formatting it.
+%
+% Metapost provides a way of "executing" the code which is stored in
+% a string, it is the scantokens primitive. So, it appears that a
+% modification of the label primitive would be possible, which
+% applies the scantokens primitive on the string which it receives as
+% parameter. Unfortunately this does not work either, because the way
+% in which btex/etex works procludes it use as argument of
+% scantokens.
+%
+% So, apparently, there is not an easy solution to the problem of
+% passing arguments to the etex/btex construct.
+%
+% The solution
+%
+% Since the construct btex/etex can only be used at the "top level"
+% of a source file, and not embedded in any string, the only way to
+% achieve the desired result is to store the string "btex ... etex"
+% in an external temporal file, and input back that file.
+%
+% This solution is implemented in the macro package "TEX.mp" which is
+% part of the standard metapost distribution. Using this package, the
+% problem of printing the ten labels $x_1$ .. $x_{10}$ becomes simple:
+%
+% for i=0 upto 10:
+% label(TEX("$x_{" & decimal i & "}$", (u*i,0));
+% endfor;
+%
+% The macro TEX receives an string as argument, and uses TeX to
+% typeset it. This is achieved, as already explained, by creating a
+% new string which encapsulated the given argument into a btex/etex
+% pair, writing this new string in an external file, and inputting
+% that file back.
+%
+% This approach has two main drawbacks:
+%
+% 1) An external file is created, and processed each time TEX is
+% used. This is very inefficient, and the slowdown is noticeable if
+% TEX is used often.
+%
+% 2) If we want to use latex istead of tex, the TEX macro will not
+% work, because the external file created through this macro does
+% not include the verbatimtex header required to initialize latex.
+%
+% Metafun approach: a clever solution
+%
+% In the excelent macro package Metafun (by Hans Hagens), a nice
+% solution is found to the first problem. Instead of writing the
+% auxiliar file and inputting it again, what is wrote is an auxiliar
+% metapost program which defines a serie of picture variables, each
+% one with the result of a btex/etex pair. In the first run of
+% metapost, this auxiliar file is write-only. In the second run, the
+% file is read at the beginning, so all picture variables get
+% defined. In this second run, each time the TEX macro is called, it
+% checks if the corresponding picture variable is already defined,
+% and in this case it simply returns its value.
+%
+% This approach is much more efficient, since a single externa file
+% is produced and processed, no matter how much the TEX macro is
+% called. The only drawback is that two metapost runs are required.
+%
+% latex.mp: my solution
+%
+% I liked very much the metafun solution, but I did not want to use
+% the whole Metafun package only to obtain this
+% functionality. Moreover, metafun relies in a set of external
+% scripts, which decide to input or not the external file, depending
+% on the existence of that file. I would prefer do not require perl
+% nor any other scripting language. Only metapost.
+%
+% This is why I wrote "latex.mp". It implements the idea in the
+% metafun package, but it does not require any external script in
+% order to check the existence of the auxiliar file.
+%
+% ================================================================
+%
+% USAGE
+%
+% input "latex";
+% initlatex(...);
+% ...
+%
+% latex("string to be formatted by latex");
+% % Returns a picture which can be used in a label
+%
+% The initlatex macro writes a latex header in an auxiliar file. You
+% do not need to call this macro if you use TeX as typesetting engine.
+%
+% On the other hand, if you want to use LaTeX as typesetting engine,
+% you need to call this macro before the first beginfig(). The macro
+% requires a mandatory argument, which is a string with adittional
+% macro commands to be placed before the "\begin{document}". For
+% example:
+%
+% initlatex("\usepackage[latin1]{inputenc}\usepackage{amsmath}");
+%
+% If you do not need any aditional package, you can use "" as
+% argument.
+%
+% You can use the latex macro in any place where a picture is
+% expected, as in the first argument of a label comand. For example:
+%
+% for i=0 upto 10:
+% label(latex("$x_{$ & decimal i & "}$", (u*i,0));
+% endfor;
+%
+% In order to correctly obtain the labels which use the latex macro,
+% you need to process your source file twice through metapost. The
+% first run all labels will show as "[?]", but the second run they
+% will have the correct value.
+%
+% IMPORTANT:
+%
+% If the text passed to the latex macro contains errors, latex will be
+% unable to complete its run. This will make impossible to run mpost
+% on the source, even if the errors are corrected, until you delete
+% the auxiliar file (which has .mpt extension)
+%
+%
+%================================================================
+% Implementation
+%
+numeric NumPic; % Total number of times that latex() macro has been
+ % called
+picture LaTeXPic[]; % Picture array which stores the result of each
+ % latex macro call. This array is filled when the
+ % axiliar file is read.
+string LaTeXsetup; % additional packages and macro definitions for latex
+
+% Initialization
+NumPic:=0;
+LaTeXsetup:="\documentclass{article}";
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Entry point
+%
+% The auxiliar file is read, but only if it exists
+%
+if readfrom(jobname&".mpt") <> EOF:
+ scantokens ("input "&jobname & ".mpt");
+fi;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% initlatex()
+%
+% By calling this function, the user can specify aditional packages and
+% macro definitions to the be used by latex.
+%
+% For example:
+%
+% initlatex("\usepackage[latin1]{inputenc}\usepackage{amsmath}");
+%
+% The global variable LaTeXsetup is also provided, mainly for third
+% party libraries which require to define their own macros. The
+% programmers of these libraries should append their own material to
+% the LaTeXsetup variable, by using the & operator. For example:
+%
+% LaTeXsetup:=LaTeXsetup & "\def\TO{\Longrightarrow}";
+%
+def initlatex primary s =
+ write "verbatimtex" to jobname & ".mpt";
+ write "%&latex" to jobname & ".mpt";
+ write LaTeXsetup to jobname & ".mpt";
+ write s to jobname & ".mpt";
+ write "\begin{document}" to jobname & ".mpt";
+ write "etex" to jobname & ".mpt";
+enddef;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% latex()
+%
+% This macro receives a string, and returns a picture which contains
+% the result of running the string by latex. The result can be used
+% whenever a picture argument is expected, as for example in a label.
+
+vardef latex@#(expr txt) =
+ NumPic := NumPic + 1 ;
+ if string txt :
+ write "% figure " & decimal charcode & " : " & char(10) &
+ "LaTeXPic[" & decimal NumPic & "] := btex " &
+ txt & " etex ;" to jobname & ".mpt" ;
+ if unknown LaTeXPic[NumPic] :
+ thelabel@#("[??]",origin)
+ else :
+ thelabel@#(LaTeXPic[NumPic],origin)
+ fi
+ else :
+ thelabel@#(txt,origin)
+ fi
+enddef ;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% EOF