diff options
Diffstat (limited to 'Master/texmf-dist/metapost/makecirc/latex.mp')
-rw-r--r-- | Master/texmf-dist/metapost/makecirc/latex.mp | 246 |
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 |