Optimal way to defining of macros in Luacode in ConTeXt
Hello ConTeXist. How best (optimally) in Lua code in ConTeXt define own ConTeXt macros? I was used recently LuaTeX syntax (for example) : tex.sprint(tex.ctxcatcodes,'\\def\\mymacro\{arg of mymacro\}') But someone advised me that I use the better syntax: context('\\def\\Mymacro\{arg of mymacro\}') or context("\\def\\test#1{#1}") etc... Exist other (best or most optimal) way to do? for example something like: context.def.mymacro("first arg", "sec arg:") (which of course does not work ...) Thanx Jaroslav My example: \startluacode function ar2rom(arnum) -- Convert Arabic numbers to Roman. Used for "numbering" column in the TeX macros local romans = {{1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"}, {100, "C"}, {90, "XC"}, {50, "L"}, {40, "XL"}, {10, "X"}, {9, "IX"}, {5, "V"}, {4, "IV"}, {1, "I"} } local romnum='' for _, v in ipairs(romans) do -- create of the Roman numbers val, let = unpack(v) while arnum >= val do arnum = arnum - val romnum=romnum..let end end return romnum end for i = 1, 10 do tex.sprint(tex.ctxcatcodes,'\\def\\macro'..ar2rom(i)..'\{macro '..i..'\}') context('\\def\\Macro'..ar2rom(i)..'\{Macro '..i..'\}') end tex.sprint(tex.ctxcatcodes,'\\def\\mymacro\{arg of mymacro\}') context('\\def\\Mymacro\{arg of Mymacro\}') \stopluacode \starttext \macroI, \MacroI \macroII, \MacroII etc ... \macroIX, \MacroIX \macroX, \MacroX \Mymacro, \mymacro \stoptext
On 12-7-2011 5:30, Jaroslav Hajtmar wrote:
But someone advised me that I use the better syntax: context('\\def\\Mymacro\{arg of mymacro\}') or context("\\def\\test#1{#1}") etc...
whatever you like best context.setvalue{"Mymacro",somevalue) context([[\def\MyMacro#1{#1}]])
Exist other (best or most optimal) way to do? for i = 1, 10 do tex.sprint(tex.ctxcatcodes,'\\def\\macro'..ar2rom(i)..'\{macro '..i..'\}') context('\\def\\Macro'..ar2rom(i)..'\{Macro '..i..'\}') end
for i = 1, 10 do context([[\def\Macro%s{Macro%s}]],ar2rom(i),i) end When more than one argument is given, the context command treats the first argument as format template. By using the context command you can see what happens with \enabletrackers[context.trace] Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | voip: 087 875 68 74 | www.pragma-ade.com | www.pragma-pod.nl -----------------------------------------------------------------
Hello all. It is GREAT! Thanx Hans and Wolfgang too. It is very instructive and inspiring for me... I was looking for something similar for a long time, but I have not found anything (not even in the CLD-MKIV and others ...). Finally, after yours reply to this email find something in the ctx-man.pdf from 1997 year :-). But I have a few questions and comments on this subject: 1. Is there any possibility to do anything similar with counters, dimensions etc? I trying but without success. For example: context.newcount(mycounter) or context.newcounter(mycounter) context.mycounter=5 etc. or it must be realized by classical way: context('\\newcount\\mycounter') context('\\mycounter=10') context('\\advance\\mycounter by5') context('\\the\\mycounter') similary with \newdimen, \newif etc... 2. Any person interested in using context.setvalue{"Mymacro",somevalue) and context([[\def\MyMacro#1{#1}]]) syntaxes I have pointed out that the second syntax only operates when the command is given in a separate LUA file (ie file.lua) (ie not within an environment \startluacode - \stopluacode in classical TEX file!!!). Hans told me once that it is the individual categories of characters (backslash??) (if I remember correctly). First syntax works perfectly in LUA and TeX files too. Here I have a question. Why not comment out this case in TEX file? \startluacode -- context([[\def\macro#1{#1}]]) \stopluacode I get error: ! Undefined control sequence. -- context([[\def \macro #1{#1}]]) \dodostartluacode ...and \directlua \zerocount {#1 }} l.25 \stopluacode ? That category characters again? Comment character -- works differently in TEX file, and otherwise in the LUA file? Ie. comment on the backslash? 3. Wolfgang write about using context command \convertnumber{R}{1400} and the corresponding syntax: context.convertnumber("R",1400) to roman converting. It is great, but I could not figure out how to use in combination with the above syntax (ie use case context.command) or find the appropriate conversion LUA function (I did not use a custom function). Is there any way to do something like that: context([[\def\Macro%s{Macro%s}]],context.convertnumber("R",1400),1400) ??? ie. TEX command is used as a LuaTeX parameter? Thanx Jaroslav Dne 12.7.2011 17:43, Hans Hagen napsal(a):
On 12-7-2011 5:30, Jaroslav Hajtmar wrote:
But someone advised me that I use the better syntax: context('\\def\\Mymacro\{arg of mymacro\}') or context("\\def\\test#1{#1}") etc...
whatever you like best
context.setvalue{"Mymacro",somevalue)
context([[\def\MyMacro#1{#1}]])
Exist other (best or most optimal) way to do? for i = 1, 10 do tex.sprint(tex.ctxcatcodes,'\\def\\macro'..ar2rom(i)..'\{macro '..i..'\}') context('\\def\\Macro'..ar2rom(i)..'\{Macro '..i..'\}') end
for i = 1, 10 do context([[\def\Macro%s{Macro%s}]],ar2rom(i),i) end
When more than one argument is given, the context command treats the first argument as format template.
By using the context command you can see what happens with
\enabletrackers[context.trace]
Hans
----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | voip: 087 875 68 74 | www.pragma-ade.com | www.pragma-pod.nl -----------------------------------------------------------------
On 13-7-2011 10:05, Jaroslav Hajtmar wrote:
Hello all. It is GREAT! Thanx Hans and Wolfgang too. It is very instructive and inspiring for me... I was looking for something similar for a long time, but I have not found anything (not even in the CLD-MKIV and others ...). Finally, after yours reply to this email find something in the ctx-man.pdf from 1997 year :-). But I have a few questions and comments on this subject:
1. Is there any possibility to do anything similar with counters, dimensions etc? I trying but without success. For example: context.newcount(mycounter) or context.newcounter(mycounter) context.mycounter=5 etc.
As currently we cannot define a counter at the tex end (using countdef) it would introduce too much complexitity to mimmick that now. When you do: context.newcount("name") you should realize that this command is effectuated after the lua call, so if you want a counter also at the tex level you should define it at that end, \newcount\name
or it must be realized by classical way: context('\\newcount\\mycounter') context('\\mycounter=10') context('\\advance\\mycounter by5') context('\\the\\mycounter')
tex.count.name = 10 tex.count.name = tex.count.name + 5 if you never need the counter at the tex end, you can of course use a lua number instead.
similary with \newdimen, \newif etc...
at some point we will have helpers for that
2. Any person interested in using context.setvalue{"Mymacro",somevalue) and context([[\def\MyMacro#1{#1}]]) syntaxes I have pointed out that the second syntax only operates when the command is given in a separate LUA file (ie file.lua) (ie not within an environment \startluacode - \stopluacode in classical TEX file!!!). Hans told me once that it is the individual categories of characters (backslash??) (if I remember correctly). First syntax works perfectly in LUA and TeX files too.
indeed, but if you already have the command and it's defined as unexpandable then you can use the [[ ]] method too
Here I have a question. Why not comment out this case in TEX file?
\startluacode -- context([[\def\macro#1{#1}]]) \stopluacode
I get error: ! Undefined control sequence. -- context([[\def \macro #1{#1}]]) \dodostartluacode ...and \directlua \zerocount {#1 }} l.25 \stopluacode ?
That category characters again? Comment character -- works differently in TEX file, and otherwise in the LUA file? Ie. comment on the backslash?
indeed
3. Wolfgang write about using context command
\convertnumber{R}{1400} and the corresponding syntax: context.convertnumber("R",1400) to roman converting. It is great, but I could not figure out how to use in combination with the above syntax (ie use case context.command) or find the appropriate conversion LUA function (I did not use a custom function). Is there any way to do something like that:
context([[\def\Macro%s{Macro%s}]],context.convertnumber("R",1400),1400) ??? ie. TEX command is used as a LuaTeX parameter?
context([[\def\Macro%s{Macro%s}]],converters.romannumeral(1400),1400) Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | voip: 087 875 68 74 | www.pragma-ade.com | www.pragma-pod.nl -----------------------------------------------------------------
Great!!!! Hans, thanx very much for complete an exhaustive answer.. It very help me to solve my module Regards Jaroslav Dne 13.7.2011 11:55, Hans Hagen napsal(a):
On 13-7-2011 10:05, Jaroslav Hajtmar wrote:
Hello all. It is GREAT! Thanx Hans and Wolfgang too. It is very instructive and inspiring for me... I was looking for something similar for a long time, but I have not found anything (not even in the CLD-MKIV and others ...). Finally, after yours reply to this email find something in the ctx-man.pdf from 1997 year :-). But I have a few questions and comments on this subject:
1. Is there any possibility to do anything similar with counters, dimensions etc? I trying but without success. For example: context.newcount(mycounter) or context.newcounter(mycounter) context.mycounter=5 etc.
As currently we cannot define a counter at the tex end (using countdef) it would introduce too much complexitity to mimmick that now.
When you do:
context.newcount("name")
you should realize that this command is effectuated after the lua call, so if you want a counter also at the tex level you should define it at that end,
\newcount\name
or it must be realized by classical way: context('\\newcount\\mycounter') context('\\mycounter=10') context('\\advance\\mycounter by5') context('\\the\\mycounter')
tex.count.name = 10 tex.count.name = tex.count.name + 5
if you never need the counter at the tex end, you can of course use a lua number instead.
similary with \newdimen, \newif etc...
at some point we will have helpers for that
2. Any person interested in using context.setvalue{"Mymacro",somevalue) and context([[\def\MyMacro#1{#1}]]) syntaxes I have pointed out that the second syntax only operates when the command is given in a separate LUA file (ie file.lua) (ie not within an environment \startluacode - \stopluacode in classical TEX file!!!). Hans told me once that it is the individual categories of characters (backslash??) (if I remember correctly). First syntax works perfectly in LUA and TeX files too.
indeed, but if you already have the command and it's defined as unexpandable then you can use the [[ ]] method too
Here I have a question. Why not comment out this case in TEX file?
\startluacode -- context([[\def\macro#1{#1}]]) \stopluacode
I get error: ! Undefined control sequence. -- context([[\def \macro #1{#1}]]) \dodostartluacode ...and \directlua \zerocount {#1 }} l.25 \stopluacode ?
That category characters again? Comment character -- works differently in TEX file, and otherwise in the LUA file? Ie. comment on the backslash?
indeed
3. Wolfgang write about using context command
\convertnumber{R}{1400} and the corresponding syntax: context.convertnumber("R",1400) to roman converting. It is great, but I could not figure out how to use in combination with the above syntax (ie use case context.command) or find the appropriate conversion LUA function (I did not use a custom function). Is there any way to do something like that:
context([[\def\Macro%s{Macro%s}]],context.convertnumber("R",1400),1400) ??? ie. TEX command is used as a LuaTeX parameter?
context([[\def\Macro%s{Macro%s}]],converters.romannumeral(1400),1400)
Hans
----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | voip: 087 875 68 74 | www.pragma-ade.com | www.pragma-pod.nl -----------------------------------------------------------------
Am 13.07.2011 um 12:05 schrieb Jaroslav Hajtmar:
Great!!!! Hans, thanx very much for complete an exhaustive answer.. It very help me to solve my module
A few dozen commands to access values aren’t a perfect solution, there are better ways to access entries from a Lua table. \starttext \startusercode entries = { one = "1", two = "2", three = "Three", five = "More text!" } function getentry(name) local entry = entries[name] or "" global.context(entry) end \stopusercode \define[1]\getentry{\usercode{getentry("#1")}} \starttabulate \NC one \EQ \getentry{one} \NC\NR \NC two \EQ \getentry{two} \NC\NR \NC three \EQ \getentry{three} \NC\NR \NC four \EQ \getentry{four} \NC\NR \NC five \EQ \getentry{five} \NC\NR \stoptabulate \stoptext Wolfgang
Thanx Wolfgang, It looks very interesting... It can be used this method for example for macro definitions? When I will return to the subject of this mail: Can also be used for the council said Hans macros with multiple parameters? For example macros without parameter is no problem: context.setvalue('printline',calling.luafunction(),tex.par) I assume that for a more parameters cannot be used context.setvalue (...) .. But how to use multiple parameters when defining the macro as follows: context([[\\def\\paramcontrol#1#2{%s}]],thirddata.scancsv.paramcontrol('#1', '#2')) etc... I want completely rewrite my entire module into LUA code (this means only lua file without TEX code) Thanx Jaroslav Dne 13.7.2011 14:56, Wolfgang Schuster napsal(a):
Am 13.07.2011 um 12:05 schrieb Jaroslav Hajtmar:
Great!!!! Hans, thanx very much for complete an exhaustive answer.. It very help me to solve my module
A few dozen commands to access values aren’t a perfect solution, there are better ways to access entries from a Lua table.
\starttext
\startusercode
entries = { one = "1", two = "2", three = "Three", five = "More text!" }
function getentry(name) local entry = entries[name] or "" global.context(entry) end
\stopusercode
\define[1]\getentry{\usercode{getentry("#1")}}
\starttabulate \NC one \EQ \getentry{one} \NC\NR \NC two \EQ \getentry{two} \NC\NR \NC three \EQ \getentry{three} \NC\NR \NC four \EQ \getentry{four} \NC\NR \NC five \EQ \getentry{five} \NC\NR \stoptabulate
\stoptext
Am 13.07.2011 um 16:09 schrieb Jaroslav Hajtmar:
Thanx Wolfgang,
It looks very interesting... It can be used this method for example for macro definitions?
It depends what you want to achieve, while you try to create many commands in the form \MacroXXX where each command contains some content i define only one command which takes the content only when requested.
When I will return to the subject of this mail: Can also be used for the council said Hans macros with multiple parameters?
For example macros without parameter is no problem: context.setvalue('printline',calling.luafunction(),tex.par) I assume that for a more parameters cannot be used context.setvalue (...) ..
But how to use multiple parameters when defining the macro as follows: context([[\\def\\paramcontrol#1#2{%s}]],thirddata.scancsv.paramcontrol('#1', '#2'))
Look into cldf-int.lua where you can see a method to create TeX commands without optional arguments from Lua. Wolfgang
Thanx very much Hans and Wolfgang too, I converted ALL my ConTeXt definitions (macros) with fixed numbers of parameters by using yours method - ie: interfaces.definecommand { name = "....", macro = ....., arguments = { { "content", "string" }, { "content", "string" }, }, } It is great and very easy - thanx. Now I want convert rest of definitions (macros) - they have varied numbers of parameters. Is there any similar way to do it? Suffice it to indicate how. Thanx Jaroslav To show what macros I want to convert, I mention these examples: \def\opencsvfile{% \dosingleempty\doopencsvfile% } \def\doopencsvfile[#1]{% \dosinglegroupempty\dodoopencsvfile } \def\dodoopencsvfile#1{% \iffirstargument \ctxlua{thirddata.scancsv.opencsvfile("#1")} \else \ctxlua{thirddata.scancsv.opencsvfile()} \fi } or other macro etc: % \doloopaction % implicit use \lineaction macro % \doloopaction{\action} % use \action macro for all lines % \doloopaction{\action}{4} % use \action macro for first 4 lines % \doloopaction{\action}{2}{5} % use \action macro for lines from 2 to 5 \def\doloopaction{\dotriplegroupempty\doloopAction} \def\doloopAction#1#2#3{% \opencsvfile% \doifsomethingelse{#3}{%3 args. \doloopfromto{#2}{#3}{#1}% if 3 arguments then do #1 macro from #2 line to #3 line }{% \doifsomethingelse{#2}{%2 args. \doloopfromto{1}{#2}{#1}% if 2 arguments then do #1 macro for first #2 lines }% {\doifsomethingelse{#1}{% 1 arg. \doloopfromto{-1}{-1}{#1}% }{% if without arguments then do \lineaction macro for all lines \doloopfromto{-1}{-1}{\lineaction}% }% }% }% }% Dne 13.7.2011 16:33, Wolfgang Schuster napsal(a):
Am 13.07.2011 um 16:09 schrieb Jaroslav Hajtmar:
Thanx Wolfgang,
It looks very interesting... It can be used this method for example for macro definitions?
It depends what you want to achieve, while you try to create many commands in the form \MacroXXX where each command contains some content i define only one command which takes the content only when requested.
When I will return to the subject of this mail: Can also be used for the council said Hans macros with multiple parameters?
For example macros without parameter is no problem: context.setvalue('printline',calling.luafunction(),tex.par) I assume that for a more parameters cannot be used context.setvalue (...) ..
But how to use multiple parameters when defining the macro as follows: context([[\\def\\paramcontrol#1#2{%s}]],thirddata.scancsv.paramcontrol('#1', '#2'))
Look into cldf-int.lua where you can see a method to create TeX commands without optional arguments from Lua.
Wolfgang
On 14-7-2011 5:12, Jaroslav Hajtmar wrote:
To show what macros I want to convert, I mention these examples:
\def\opencsvfile{% \dosingleempty\doopencsvfile% }
\def\doopencsvfile[#1]{% \dosinglegroupempty\dodoopencsvfile }
\def\dodoopencsvfile#1{% \iffirstargument \ctxlua{thirddata.scancsv.opencsvfile("#1")} \else \ctxlua{thirddata.scancsv.opencsvfile()} \fi }
There is no support yet for optional {} (which is to be avoided anyway as [] is meant for optional arguments). Wolgangs example shows the regular optional argument. Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | voip: 087 875 68 74 | www.pragma-ade.com | www.pragma-pod.nl -----------------------------------------------------------------
On 13-7-2011 4:09, Jaroslav Hajtmar wrote:
But how to use multiple parameters when defining the macro as follows: context([[\\def\\paramcontrol#1#2{%s}]],thirddata.scancsv.paramcontrol('#1', '#2'))
interfaces.definecommand { name = "TwoMandate", macro = thirddata.scancsv.paramcontrol, arguments = { { "content", "string" }, { "content", "string" }, }, } ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | voip: 087 875 68 74 | www.pragma-ade.com | www.pragma-pod.nl -----------------------------------------------------------------
Am 12.07.2011 um 17:30 schrieb Jaroslav Hajtmar:
Hello ConTeXist.
How best (optimally) in Lua code in ConTeXt define own ConTeXt macros?
I was used recently LuaTeX syntax (for example) : tex.sprint(tex.ctxcatcodes,'\\def\\mymacro\{arg of mymacro\}')
But someone advised me that I use the better syntax: context('\\def\\Mymacro\{arg of mymacro\}') or context("\\def\\test#1{#1}") etc...
Exist other (best or most optimal) way to do?
You can use “context.setvalue”. To convert numbers in different formats you can use the \convertnumber command. \starttext \startluacode context.setvalue("One","1") context.setvalue("Two","2") \stopluacode \define\Three{3} \One:\Two:\Three \blank \startluacode context.define({2},"\\CMDA","[One:#1,Two:#2]") \stopluacode \define[2]\CMDB{[One:#1,Two:#2]} \CMDA{1}{2} \CMDB{1}{2} \blank \convertnumber{R}{1400} \stoptext Wolfgang
participants (3)
-
Hans Hagen
-
Jaroslav Hajtmar
-
Wolfgang Schuster