Good day!
I'd like to construct some strings (actually, names of TIKZ nodes /
coordinates, but my problem is independent of TIKZ). As they should be
constructed in a consistent way, I'd like to use a macro (\getposname)
for this task. In this macro, I'd like to use something like local
variables. Unfortunately, it is not obvious to me, how to achieve
this. The following minimized example shows the problem:
----------------------------
\documentclass{article}
\begin{document}
\def\getposname{%
\def\dummy{foo}% comment this line to get \coordinate to work
bar% (actually something more involved using \dummy, where
% \getposname takes 2 parameters and \dummy contains
#1 ...)
}
\edef\myvar{\getposname} % fails with:
%! Undefined control sequence.
%\getposname ->\def \dummy
% {foo}bar
%l.11 \edef\myvar{\getposname
% } % fails with:
%?
\getposname % works always, shows bar (as expected)
\end{document}
----------------------------
Why would the macro fail in the first case and succeed in the other?
Is there a way to get the first call to work?
TIA
|
|
0
|
|
|
|
Reply
|
carsten.scholtes (3)
|
3/28/2011 3:17:48 PM |
|
le 28/03/2011 17:17 selon c.scholtes:
> Good day!
>
> I'd like to construct some strings (actually, names of TIKZ nodes /
> coordinates, but my problem is independent of TIKZ). As they should be
> constructed in a consistent way, I'd like to use a macro (\getposname)
> for this task. In this macro, I'd like to use something like local
> variables. Unfortunately, it is not obvious to me, how to achieve
> this. The following minimized example shows the problem:
>
> ----------------------------
> \documentclass{article}
> \begin{document}
>
> \def\getposname{%
> \def\dummy{foo}% comment this line to get \coordinate to work
> bar% (actually something more involved using \dummy, where
> % \getposname takes 2 parameters and \dummy contains
> #1 ...)
> }
>
> \edef\myvar{\getposname} % fails with:
> %! Undefined control sequence.
> %\getposname ->\def \dummy
> % {foo}bar
> %l.11 \edef\myvar{\getposname
> % } % fails with:
> %?
>
> \getposname % works always, shows bar (as expected)
>
> \end{document}
> ----------------------------
>
> Why would the macro fail in the first case and succeed in the other?
>
> Is there a way to get the first call to work?
>
> TIA
don't you want something rather like this:
\documentclass{minimal}
\begin{document}
\def\getposname{\edef\dummy{\foo}%
\dummy}
\def\foo{foo}
\getposname
\def\foo{bar}
\getposname
\def\foo{blob}
\getposname
\end{document}
regards,
Jean-Francois
|
|
0
|
|
|
|
Reply
|
Jean
|
3/28/2011 3:40:42 PM
|
|
c.scholtes wrote:
> I'd like to use something like local
> variables.
"variable" is a concept of e.g., procedural or object oriented
programming languages like pascal, c or c++ or whatever
while (La)TeX is a macro-language.
There are integer-parameters, registers, macros, primitives,
expansion and assignments in (La)TeX.
> Unfortunately, it is not obvious to me, how to achieve
> this. The following minimized example shows the problem:
>
> ----------------------------
> \documentclass{article}
> \begin{document}
>
> \def\getposname{%
> \def\dummy{foo}% comment this line to get \coordinate to work
> bar% (actually something more involved using \dummy, where
> % \getposname takes 2 parameters and \dummy contains
> #1 ...)
> }
>
> \edef\myvar{\getposname} % fails with:
> %! Undefined control sequence.
> %\getposname ->\def \dummy
> % {foo}bar
> %l.11 \edef\myvar{\getposname
> % } % fails with:
> %?
>
> \getposname % works always, shows bar (as expected)
>
> \end{document}
> ----------------------------
>
> Why would the macro fail in the first case and succeed in the other?
The first case is about trying to use \getposname within \edef.
The crucial point is that \edef does perform macro-expansion,
but does not perform assignments that might possibly be contained
in its' definition-text (e.g., does not execute \def or \let or \edef).
In case a token is undefined while attempting to expand it, an
error-message will be raised.
With
\edef\myvar{\getposname}
, \getposname will be expanded to
\def\dummy{foo}bar .
In further \edef-evaluation, \def will be left untouched as it is
defined and not expandable and an attempt of expanding
\dummy will take place while \dummy is still undefined
due to the \def-assignment not being carried out, which
implies raising an error-message about \dummy being
undefined.
See, \def or \let are not expandable macros but they are
unexpandable primitives which can reach TeX's "stomach".
[If you are interested in the "anatomy" of TeX, have a look at
section 11 of David Salomon, An introduction to TeX, part 1,
NTG course june 1992
(http://www.tex.ac.uk/tex-archive/usergrps/ntg/maps/maps08/maps08_i.ps.gz ) ]
> Is there a way to get the first call to work?
You can't perform an assignment from within an \edef or \xdef
as those are assignments themselves, but you can try
LaTeX' \DeclareRobustCommand or \protect-mechanism
with \protected@edef instead of \edef in order to delay the
assignment:
\documentclass{article}
\DeclareRobustCommand*\dummydefiner{\def\dummy}
\begin{document}
\def\getposname{\dummydefiner{foo}bar}
\makeatletter
\protected@edef\myvar{\getposname}
\makeatother
% now the \def\dummy/\dummydefiner-assignment is not
% carried out at the time of defining \myvar but is attempted to be
% carried out whenever \myvar gets expanded in non-expansion-
% contexts - that is outside things like \edef, \xdef or \csname..
\show\myvar
\myvar
\getposname % works always, shows bar (as expected)
\end{document}
Ulrich
|
|
0
|
|
|
|
Reply
|
Ulrich
|
3/28/2011 5:17:27 PM
|
|
Dear Jean Francois,
Thank you for your quick answer. Unfortunately, your proposition
does not appear to be applicable to my problem:
I will have to use the result of \getposname in an "expanding"
context (as a coordinate name in TIKZ, as in e.g.
"\draw (\getposname) -- (0,0);"). In this situation,
the \edef contained in the value of the macro
still leads to the error explained by Ulrich.o
Best regards
Carsten
|
|
0
|
|
|
|
Reply
|
carsten.scholtes (3)
|
3/30/2011 10:37:42 AM
|
|
Dear Ulrich,
Thank you very much for your elaborate and enlightening answer.
I can now understand why my code fails in the way it does.
I was not aware of the selective expansion
in the template part of an \edef.
The link you provided was also very informative.
(Among many other things, it pointed me to the very
helpful \tracingmacros...)
Trying to apply your solution to my problem, I still had
difficulties: I want to use the value of \dummy
for constructing the result of \getposname (not simply "bar").
When I try to do so, \dummy appears to be undefined...
Additionally, the result is to be used as
the name of a TIKZ coordinate / node and this use
appears to be in an expanding context similar to \edef.
I don't really understand what \protect is supposed to achieve
but I'm afraid, the result would still not be accepted.
In the meantime, I found some ugly workaround (involving
much verbosity and code replication) for my current needs.
Having spent already way too much time on this,
that'll have to do, for now.
Again, thank you very much for your inspiring input.
Best regards
Carsten
|
|
0
|
|
|
|
Reply
|
carsten.scholtes (3)
|
3/30/2011 10:39:19 AM
|
|
|
4 Replies
382 Views
(page loaded in 0.092 seconds)
Similiar Articles: local variables - comp.text.texGood day! I'd like to construct some strings (actually, names of TIKZ nodes / coordinates, but my problem is independent of TIKZ). As they should ... /bin/sh: Local variables in a function ? - comp.unix.solaris ...Hi there, I'm writing a shellscript which consists of a function which gets called somewhere in the main loop. In order to keep things as tidy as pos... Local array variables in functions - comp.lang.awkHow to rename fields in structure variable - comp.soft-sys.matlab ..... for code symbols such as fields, local variables ... ... of variables, you can return a struct ... MASM_LOCAL variable - comp.lang.asm.x86Hi All, How to declare LOCAL variable inside a PROCEDURE And that variable can assign to specific register during declaration time. Some thing ... how to ask GCC to automatically initialize local variables - comp ...Hi, all How can I ask GCC to automatically initialize local variables? I think some compilers do that and some not, which will lead to portability pr... Evaluate character macro variable - comp.soft-sys.sas... just wants to evaluate which hand wins at the end ... Poker-Eval's fish program (in heavily macro'ed C) runs ... global variable, and then read it into a > local variable ... stack layout x86 - comp.lang.asm.x86The stack layout of an x86 is: instruction pointer: arguments to function(if any): local variables ? is this correct? ... Remote Execution of Local Code - comp.soft-sys.matlab... local Matlab editor window which would execute on the remote machine, again with the output being displayed locally, and where I would have local access to the variables ... Global Variable vs Struct Variable Question - comp.lang.asm.x86 ...It is preferable to use global functions outside > of struct or class while global functions can still access local variable > inside struct or class. > My test ... How to use Setcc?? - comp.lang.asm.x86Do C/C++ compiler have access to eflag register directly? I will not want to use inline __asm that uses setcc to set 1 or 0 into local variable? ... Local variable - Wikipedia, the free encyclopediaIn computer science, a local variable is a variable that is given local scope. Such a variable is accessible only from the function or block in which it is declared. Local VariablesWhat makes a variable local? local variables. A variable declared as local is one that is visible only within the block of code in which it appears. 7/23/2012 5:18:03 PM
|