Expansion help needed, getvariable and TABLE
Listers, I have a problem, and a question on ConTeXt programming efficiency. In the example below, I have a set of variables. When these are reference directly via \getvariable, everything works as expected in simple text and in TABLEs. When I \define a macro to the \getvariable, that works in simple text, but only the value of the last iteration appears in the TABLE. The macro definition is saved and when it is used, that is the value that it has. So, how can I \define (or \def, ...) a macro to the expanded value to avoid this? That is the problem. The question is, Is there is any advantage to be had in doing this? Assume that the value is referenced many (tens of) times. There seems to be an aesthetic value of factoring out the multiple identical instances of the \getvariable syntax and assigning a more semantically informative name, but beyond that, is there any other value? % macros=mkvi engine=luajittex \setvariables [one] [a=1a,b=1b] \setvariables [two] [a=2a,b=2b] \define \Sets {one,two} \starttexdefinition unexpanded doInlineText #SET Direct: \getvariable{#SET}{a} \getvariable{#SET}{b}\par \stoptexdefinition \starttexdefinition unexpanded doTableRow #SET \bTR \bTC\getvariable{#SET}{a}\eTC \bTC\getvariable{#SET}{b}\eTC \eTR \stoptexdefinition \starttexdefinition doInlineTextExp #SET \define\A{\getvariable{#SET}{a}} \define\B{\getvariable{#SET}{b}} Factored: \A\ \B\par \stoptexdefinition \starttexdefinition doTableRowExp #SET \define\A{\getvariable{#SET}{a}} \define\B{\getvariable{#SET}{b}} \bTR \bTC\A\eTC \bTC\B\eTC \eTR \stoptexdefinition \starttext \starttext \expandafter\processcommalist\expandafter[\Sets]\doInlineText \bTABLE[frame=off] \bTABLEhead \bTR[nc=2] \bTH Direct\eTH \eTR \eTABLEhead \bTABLEbody \expandafter\processcommalist\expandafter[\Sets]\doTableRow \eTABLEbody \eTABLE \expandafter\processcommalist\expandafter[\Sets]\doInlineTextExp \bTABLE[frame=off] \bTABLEhead \bTR[nc=2] \bTH Factored\eTH \eTR \eTABLEhead \bTABLEbody \expandafter\processcommalist\expandafter[\Sets]\doTableRowExp \eTABLEbody \eTABLE \stoptext -- Rik
On 2018-01-30 21:10, Rik Kabel wrote:
Listers,
I have a problem, and a question on ConTeXt programming efficiency.
In the example below, I have a set of variables. When these are reference directly via \getvariable, everything works as expected in simple text and in TABLEs. When I \define a macro to the \getvariable, that works in simple text, but only the value of the last iteration appears in the TABLE. The macro definition is saved and when it is used, that is the value that it has.
So, how can I \define (or \def, ...) a macro to the expanded value to avoid this? That is the problem.
The question is, Is there is any advantage to be had in doing this? Assume that the value is referenced many (tens of) times. There seems to be an aesthetic value of factoring out the multiple identical instances of the \getvariable syntax and assigning a more semantically informative name, but beyond that, is there any other value?
Replying to my own query, I see that I just have to localize the definitions by grouping them, as \starttexdefinition doTableRowExp #SET {\define\A{\getvariable{#SET}{a}} \define\B{\getvariable{#SET}{b}} \bTR \bTC\A\eTC \bTC\B\eTC \eTR} \stoptexdefinition Does it matter if I use {}, \bgroup\egroup, or some other mechanism? My style question is still outstanding. -- Rik
Rik Kabel mailto:context@rik.users.panix.com 31. Januar 2018 um 03:10
Listers,
I have a problem, and a question on ConTeXt programming efficiency.
In the example below, I have a set of variables. When these are reference directly via \getvariable, everything works as expected in simple text and in TABLEs. When I \define a macro to the \getvariable, that works in simple text, but only the value of the last iteration appears in the TABLE. The macro definition is saved and when it is used, that is the value that it has.
So, how can I \define (or \def, ...) a macro to the expanded value to avoid this? That is the problem.
The question is, Is there is any advantage to be had in doing this? Assume that the value is referenced many (tens of) times. There seems to be an aesthetic value of factoring out the multiple identical instances of the \getvariable syntax and assigning a more semantically informative name, but beyond that, is there any other value?
Natural tables collect the content of all cells to perform the width and height calculations and you have to expand the content of the cells to get the current value of \getvariable. \starttexdefinition unexpanded doTableRow #SET \bTR \expanded{\bTC\getvariable{#SET}{a}\eTC} \expanded{\bTC\getvariable{#SET}{b}\eTC} \eTR \stoptexdefinition BTW: You can use the \processcommacommand command when you save your lists in a macro (no need for \expandafter). \defineexpandable\Sets{one,two} \processcommacommand[\Sets]\doInlineTextExp Wolfgang
On 2018-01-31 01:04, Wolfgang Schuster wrote:
Rik Kabel mailto:context@rik.users.panix.com 31. Januar 2018 um 03:10
Listers,
I have a problem, and a question on ConTeXt programming efficiency.
In the example below, I have a set of variables. When these are reference directly via \getvariable, everything works as expected in simple text and in TABLEs. When I \define a macro to the \getvariable, that works in simple text, but only the value of the last iteration appears in the TABLE. The macro definition is saved and when it is used, that is the value that it has.
So, how can I \define (or \def, ...) a macro to the expanded value to avoid this? That is the problem.
The question is, Is there is any advantage to be had in doing this? Assume that the value is referenced many (tens of) times. There seems to be an aesthetic value of factoring out the multiple identical instances of the \getvariable syntax and assigning a more semantically informative name, but beyond that, is there any other value?
Natural tables collect the content of all cells to perform the width and height calculations and you have to expand the content of the cells to get the current value of \getvariable.
\starttexdefinition unexpanded doTableRow #SET \bTR \expanded{\bTC\getvariable{#SET}{a}\eTC} \expanded{\bTC\getvariable{#SET}{b}\eTC} \eTR \stoptexdefinition
BTW: You can use the \processcommacommand command when you save your lists in a macro (no need for \expandafter).
\defineexpandable\Sets{one,two}
\processcommacommand[\Sets]\doInlineTextExp
Wolfgang
Thank you for the help and the processcommacommand bit. However, the problem is still there (and I was just wrong in my own follow-up). Below is an updated example with and without the \expanded{\bTC... It does not seem to make a difference here, but perhaps it is needed in some situations. My question is about factoring the \getvariable out of the \bTC rows (in this example) and \defining a simpler macro to hold the value. Should it be done, and if so, how? % macros=mkvi engine=luajittex \setvariables [one] [a=1aaaaaaaa,b=1b,c=1c] \setvariables [two] [a=2a,b=2bbbbbbbbbbbbbbbb,c=2c] \defineexpandable \Sets {one,two} \starttexdefinition unexpanded doInlineText #SET Direct: \getvariable{#SET}{a} \getvariable{#SET}{b}\ \getvariable{#SET}{c}\par \stoptexdefinition \starttexdefinition unexpanded doTableRow #SET \bTR \bTC\getvariable{#SET}{a}\eTC \bTC\getvariable{#SET}{b}\eTC \bTC\getvariable{#SET}{c}\eTC \eTR \stoptexdefinition \starttexdefinition doInlineTextExpA #SET \define\A{\getvariable{#SET}{a}} \define\B{\getvariable{#SET}{b}} \define\C{\getvariable{#SET}{c}} Factored A: \A\ \B\ \C\par \stoptexdefinition \starttexdefinition doTableRowExpA #SET \define\A{\getvariable{#SET}{a}} \define\B{\getvariable{#SET}{b}} \define\C{\getvariable{#SET}{c}} \bTR \bTC\A\eTC \bTC\B\eTC \bTC\C\eTC \eTR \stoptexdefinition \starttexdefinition doInlineTextExpB #SET \define\A{\getvariable{#SET}{a}} \define\B{\getvariable{#SET}{b}} \define\C{\getvariable{#SET}{c}} Factored B: \A\ \B\ \C\par \stoptexdefinition \starttexdefinition doTableRowExpB #SET \define\A{\getvariable{#SET}{a}} \define\B{\getvariable{#SET}{b}} \define\C{\getvariable{#SET}{c}} \bTR \expanded{\bTC\A\eTC} \expanded{\bTC\B\eTC} \expanded{\bTC\C\eTC} \eTR \stoptexdefinition \starttext \processcommacommand[\Sets]\doInlineText \bTABLE[frame=off] \bTABLEhead \bTR[nc=2] \bTH Direct\eTH \eTR \eTABLEhead \bTABLEbody \processcommacommand[\Sets]\doTableRow \eTABLEbody \eTABLE \processcommacommand[\Sets]\doInlineTextExpA \bTABLE[frame=off] \bTABLEhead \bTR[nc=2] \bTH Factored A\eTH \eTR \eTABLEhead \bTABLEbody \processcommacommand[\Sets]\doTableRowExpA \eTABLEbody \eTABLE \processcommacommand[\Sets]\doInlineTextExpB \bTABLE[frame=off] \bTABLEhead \bTR[nc=2] \bTH Factored B\eTH \eTR \eTABLEhead \bTABLEbody \processcommacommand[\Sets]\doTableRowExpB \eTABLEbody \eTABLE \stoptext -- RIk
Rik Kabel schrieb:
\starttexdefinition doTableRowExpB #SET \define\A{\getvariable{#SET}{a}} \define\B{\getvariable{#SET}{b}} \define\C{\getvariable{#SET}{c}} \bTR \expanded{\bTC\A\eTC} \expanded{\bTC\B\eTC} \expanded{\bTC\C\eTC} \eTR \stoptexdefinition
You can’t use \define but it creates non expandable commands (which can be solved when you use \defineexpandable instead) and there is no need for this extra step. \starttexdefinition doTableRowExpB #SET \bTR \expanded{\bTC\getvariable{#SET}{a}\eTC} \expanded{\bTC\getvariable{#SET}{b}\eTC} \expanded{\bTC\getvariable{#SET}{c}\eTC} \eTR \stoptexdefinition Wolfgang
On 2018-01-31 09:54, Wolfgang Schuster wrote:
Rik Kabel schrieb:
\starttexdefinition doTableRowExpB #SET \define\A{\getvariable{#SET}{a}} \define\B{\getvariable{#SET}{b}} \define\C{\getvariable{#SET}{c}} \bTR \expanded{\bTC\A\eTC} \expanded{\bTC\B\eTC} \expanded{\bTC\C\eTC} \eTR \stoptexdefinition
You can’t use \define but it creates non expandable commands (which can be solved when you use \defineexpandable instead) and there is no need for this extra step.
\starttexdefinition doTableRowExpB #SET \bTR \expanded{\bTC\getvariable{#SET}{a}\eTC} \expanded{\bTC\getvariable{#SET}{b}\eTC} \expanded{\bTC\getvariable{#SET}{c}\eTC} \eTR \stoptexdefinition
Wolfgang ___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : http://contextgarden.net ___________________________________________________________________________________
Great. This does the job, and allows assigning more semantically-meaningful names to the elements. \starttexdefinition doTableRowExpB #SET \defineexpandable\A{\getvariable{#SET}{a}} \defineexpandable\B{\getvariable{#SET}{b}} \defineexpandable\C{\getvariable{#SET}{c}} \bTR \expanded{\bTC\A\eTC} \expanded{\bTC\B\eTC} \expanded{\bTC\C\eTC} \eTR \stoptexdefinition I see no performance difference on a much larger test, and I think that the readability is improved (and thus the opportunity for simple mistakes) when the hundreds of \getvariable macros are refactored into a few macro definitions. Thank you once again. -- Rik
On 1/31/2018 4:40 PM, Rik Kabel wrote:
On 2018-01-31 09:54, Wolfgang Schuster wrote:
Rik Kabel schrieb:
\starttexdefinition doTableRowExpB #SET \define\A{\getvariable{#SET}{a}} \define\B{\getvariable{#SET}{b}} \define\C{\getvariable{#SET}{c}} \bTR \expanded{\bTC\A\eTC} \expanded{\bTC\B\eTC} \expanded{\bTC\C\eTC} \eTR \stoptexdefinition
You can’t use \define but it creates non expandable commands (which can be solved when you use \defineexpandable instead) and there is no need for this extra step.
\starttexdefinition doTableRowExpB #SET \bTR \expanded{\bTC\getvariable{#SET}{a}\eTC} \expanded{\bTC\getvariable{#SET}{b}\eTC} \expanded{\bTC\getvariable{#SET}{c}\eTC} \eTR \stoptexdefinition
Wolfgang ___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://context.aanhet.net archive : https://bitbucket.org/phg/context-mirror/commits/ wiki : http://contextgarden.net ___________________________________________________________________________________
Great. This does the job, and allows assigning more semantically-meaningful names to the elements.
\starttexdefinition doTableRowExpB #SET \defineexpandable\A{\getvariable{#SET}{a}} \defineexpandable\B{\getvariable{#SET}{b}} \defineexpandable\C{\getvariable{#SET}{c}} \bTR \expanded{\bTC\A\eTC} \expanded{\bTC\B\eTC} \expanded{\bTC\C\eTC} \eTR \stoptexdefinition
I see no performance difference on a much larger test, and I think that the readability is improved (and thus the opportunity for simple mistakes) when the hundreds of \getvariable macros are refactored into a few macro definitions.
maybe the next can convince you then \starttexdefinition doTableRowExpB #SET \expanded {\bTR \bTC\getvariable{#SET}{a}\eTC \bTC\getvariable{#SET}{b}\eTC \bTC\getvariable{#SET}{c}\eTC \eTR} \stoptexdefinition with \starttexdefinition doTableRowExpB #SET \normalexpanded {\bTR \bTC\getvariable{#SET}{a}\eTC \bTC\getvariable{#SET}{b}\eTC \bTC\getvariable{#SET}{c}\eTC \eTR} \stoptexdefinition being a bit faster Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
participants (3)
-
Hans Hagen
-
Rik Kabel
-
Wolfgang Schuster