Low-level macro help needed
Hello Hans and developers, I have been trying to convert some two- and three-step macros (as shown below) to single-step macros using the LMTX syntax given in the low-level macros manual. I have succeeded in many cases, but failed when the macro follows one particular group of patterns. The group of patterns is similar to this macro to process \MyMacro[optional]{Required}{Required}{Optional} In this the number of arguments can be 2, 3, or 4. A three-step solution might be as follows, which I use for a list of persons: \defineregister[Bindex] \setupregister [Bindex][n=1, balance=no, method=default, % or New follows Newton! compress=no, % yes if not note number+q expansion=yes, pagecommand=\gobbleoneargument ] \starttexdefinition unexpanded Bi \dosingleempty\doBindex \stoptexdefinition \starttexdefinition unexpanded doBindex [#SORTAS]#INDEXED \def\SortAs{#SORTAS}% \def\Indexed{#INDEXED}% \dodoublegroupempty\doBindexFull \stoptexdefinition \starttexdefinition doBindexFull #BD#MORE \doifemptyelse{#MORE} {\Bindex[\SortAs]{\Indexed\ #BD}} {\Bindex[\SortAs]{\Indexed\ #BD\\ #MORE}} \stoptexdefinition with input like: \Bi{Rumble, Walker}{1938|–|}% \Bi{Runia, David Theunis}{1951|–|}{Classicist}% \Bi{Rutherford, Ernest (Baron Rutherford of Nelson)}{1871|–|1937}{Physicist}% \Bi{Saenger, Paul}{1945|–|}% \Bi{Saldarini, Anthony J.}{1941|–|2001}% \Bi{Salter, William M.}{1853|–|1931}% \Bi[Saint-Exupery]{de Saint-Exupéry, Antoine}{1900|–|1944}% \Bi{Santayana, George}{1863|–|1952}% \Bi{Sapir, Edward}{1884|–|1939}{Linguist}% \Bi[Schrodinger]{Schrödinger, Erwin}{1887|–|1961}{Physicist}% \Bi[Spinoza]{de Spinoza, Baruch (Benedict de Spinoza, Bento de Espinosa)}{1632|–|1677}% The best I can get with the newer syntax is a two-step: \starttexdefinition unexpanded Bi \dosingleempty\doBindex \stoptexdefinition \tolerant\def\doBindex [#1]#=#=#=% {\doifemptyelse{#4} {\Bindex[#1]{#2\ #3}}% {\Bindex[#1]{#2\ #3\\ #4}}% } In the low-level macros manual, near the end of chapter 2, it says that some day there may be a use for #?, #!, #<, or #>. If I am not missing something in the manual about how to provide that first optional argument as an empty value, I think I have one. Could [#?] always return a value (perhaps empty)? That would allow something like: \tolerant\def\doBindex [#?]#=#=#=% {\doifemptyelse{#4} {\Bindex[#1]{#2\ #3}}% {\Bindex[#1]{#2\ #3\\ #4}}% } -- Rik
Rik Kabel schrieb am 16.10.2024 um 23:18:
Hello Hans and developers,
I have been trying to convert some two- and three-step macros (as shown below) to single-step macros using the LMTX syntax given in the low-level macros manual. I have succeeded in many cases, but failed when the macro follows one particular group of patterns.
The group of patterns is similar to this macro to process
\MyMacro[optional]{Required}{Required}{Optional}
In this the number of arguments can be 2, 3, or 4.
A three-step solution might be as follows, which I use for a list of persons:
\defineregister[Bindex] \setupregister [Bindex][n=1, balance=no, method=default, % or New follows Newton! compress=no, % yes if not note number+q expansion=yes, pagecommand=\gobbleoneargument ]
\starttexdefinition unexpanded Bi \dosingleempty\doBindex \stoptexdefinition
\starttexdefinition unexpanded doBindex [#SORTAS]#INDEXED \def\SortAs{#SORTAS}% \def\Indexed{#INDEXED}% \dodoublegroupempty\doBindexFull \stoptexdefinition
\starttexdefinition doBindexFull #BD#MORE \doifemptyelse{#MORE} {\Bindex[\SortAs]{\Indexed\ #BD}} {\Bindex[\SortAs]{\Indexed\ #BD\\ #MORE}} \stoptexdefinition
with input like:
\Bi{Rumble, Walker}{1938|–|}% \Bi{Runia, David Theunis}{1951|–|}{Classicist}% \Bi{Rutherford, Ernest (Baron Rutherford of Nelson)}{1871|–|1937}{Physicist}% \Bi{Saenger, Paul}{1945|–|}% \Bi{Saldarini, Anthony J.}{1941|–|2001}% \Bi{Salter, William M.}{1853|–|1931}% \Bi[Saint-Exupery]{de Saint-Exupéry, Antoine}{1900|–|1944}% \Bi{Santayana, George}{1863|–|1952}% \Bi{Sapir, Edward}{1884|–|1939}{Linguist}% \Bi[Schrodinger]{Schrödinger, Erwin}{1887|–|1961}{Physicist}% \Bi[Spinoza]{de Spinoza, Baruch (Benedict de Spinoza, Bento de Espinosa)}{1632|–|1677}%
The best I can get with the newer syntax is a two-step:
\starttexdefinition unexpanded Bi \dosingleempty\doBindex \stoptexdefinition \tolerant\def\doBindex [#1]#=#=#=% {\doifemptyelse{#4} {\Bindex[#1]{#2\ #3}}% {\Bindex[#1]{#2\ #3\\ #4}}% }
In the low-level macros manual, near the end of chapter 2, it says that some day there may be a use for #?, #!, #<, or #>. If I am not missing something in the manual about how to provide that first optional argument as an empty value, I think I have one. Could [#?] always return a value (perhaps empty)? That would allow something like:
\tolerant\def\doBindex [#?]#=#=#=% {\doifemptyelse{#4} {\Bindex[#1]{#2\ #3}}% {\Bindex[#1]{#2\ #3\\ #4}}% }
When you have argument after square brackets you have to use #: to continues scanning for arguments of the command. For the mandatory argument you should just use #2 and keep #= for the optional arguments which are only used when text enclosed in curly braces appears. The #* between the third and fourth argument allows spaces between them. %%%% begin example \tolerant\protected\def\Bi[#1]#:#2#*#=#*#=% {(1=#1)% (2=#2)% (3=#3)% (4=#4)} \starttext [\Bi[one]{two}{three}{four}] [\Bi [one] {two} {three} {four}] [\Bi [one] {two} {three}] [\Bi [one] {two}] [\Bi {two}] [\Bi [one] {two}] \stoptext %%%% end example To check whether a argument is empty or not you can use the \ifparameter command with the parameter to check (i.e. #1) as argument (don't forget the \or) but \doifempty etc. work as well. %%%% begin example \tolerant\protected\def\Bi[#1]#:#2#*#=#*#=% {\ifparameter#1\or First argument is used. \else First argument is missing or empty. \fi} \starttext \Bi {bar} \Bi [] {bar} \Bi [foo] {bar} \stoptext %%%% end example Wolfgang
On 2024-10-16 17:48, Wolfgang Schuster wrote:
Rik Kabel schrieb am 16.10.2024 um 23:18:
<stuff deleted for brevity in replying.>
When you have argument after square brackets you have to use #: to continues scanning for arguments of the command. For the mandatory argument you should just use #2 and keep #= for the optional arguments which are only used when text enclosed in curly braces appears. The #* between the third and fourth argument allows spaces between them.
%%%% begin example \tolerant\protected\def\Bi[#1]#:#2#*#=#*#=% {(1=#1)% (2=#2)% (3=#3)% (4=#4)}
\starttext
[\Bi[one]{two}{three}{four}]
[\Bi [one] {two} {three} {four}]
[\Bi [one] {two} {three}]
[\Bi [one] {two}]
[\Bi {two}]
[\Bi [one] {two}]
\stoptext %%%% end example
To check whether a argument is empty or not you can use the \ifparameter command with the parameter to check (i.e. #1) as argument (don't forget the \or) but \doifempty etc. work as well.
%%%% begin example \tolerant\protected\def\Bi[#1]#:#2#*#=#*#=% {\ifparameter#1\or First argument is used. \else First argument is missing or empty. \fi}
\starttext
\Bi {bar}
\Bi [] {bar}
\Bi [foo] {bar}
\stoptext %%%% end example
Wolfgang ___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror) archive : https://github.com/contextgarden/context wiki : https://wiki.contextgarden.net ___________________________________________________________________________________
Excellent, and thank you for the explanation. I guess #? is still available. (I had tried with #:, but not in combination with [#1] and #= for the last parameter). -- Rik
participants (2)
-
Rik Kabel
-
Wolfgang Schuster