On 9/19/2014 9:30 AM, Christoph Reller wrote:
> > Hi,
> >
> > \installcommandhandler nicely provides (among others) \define<name> and
> > \setup<name> commands. Thus it is easy to provide a key with
> > \setup<name>[key=value] and to read the value of such a key with
> > \<name>parameter{key}.
> >
> > My question is: How do I read the value of a key defined with
> > \setup...[key=value] on the lua side? If I use
> >    context.<name>parameter("key")
> > then the value of key is printed directly. I want to be able to read
> > that value and use it in lua with something like
> >    myvariable = context.?whatfunction?("key")
> >
> > Here is some example code:
> >
> > \unprotect
> >
> > \startluacode
> >    function myfun(parameters,content)
> >      context("From lua: Parameters: ")
> >      context(parameters)
> >      context.elemparameter("gkey") -- directly prints the parameter
> >      context.par()
> >    end
> > \stopluacode
> >
> > \installnamespace{elem}
> > \installcommandhandler \????elem {elem} \????elem
> > \appendtoks
> >    \setuevalue{\currentelem}{\elem_cmd{\currentelem}}%
> > \to \everydefineelem
> >
> > \unexpanded\def\elem_cmd#environment{%
> >    \edef\currentelem{#environment}%
> >    \dosingleempty\elem_cmd_parameters}
> >
> > \def\elem_cmd_parameters[#parameters]#content{%
> >    \setupcurrentelem[#parameters]
> >    From \TeX\: Parameters: key=\elemparameter{key},
> > gkey=\elemparameter{gkey}\par
> >
> > \ctxlua{myfun(\!!bs#parameters\!!es,\!!bs\normalunexpanded{#content}\!!es)}
> > }
> >
> > \defineelem[base]
> > \setupelem[gkey=gval]
> >
> > \protect
> >
> > \starttext
> >
> > \base[key=val]{Hello}
> >
> > \stoptext
> >
> > Thank you for any feedback,

On Fri, Sep 19, 2014 at 12:00 PM, Hans Hagen wrote:
> something like this ... keep in mind that there is no grouping in lua
> % macros=mkvi
> \unprotect
> \installnamespace{elem}
> \installcommandhandler \????elem {elem} \????elem
> \startluacode
>      userdata.elem = { data = { [""] = { } } }
>      function userdata.elem.define(namespace,parent)
>          print("define",namespace,parent)
>          userdata.elem.data[namespace] = { }
>          if namespace ~= parent then
> table.setmetatableindex(userdata.elem.data[namespace],userdata.elem.data[parent])
>          end
>      end
>      function userdata.elem.setup(namespace,key,gkey)
>          print("setup",namespace,key,gkey)
>          userdata.elem.data[namespace].key = key
>          userdata.elem.data[namespace].gkey = gkey
>      end
>      function userdata.myfun(namespace,one,two)
>          context.par()
>          context("elem: one=%s",userdata.elem.data[namespace][one])
>          context.par()
>          context("elem: two=%s",userdata.elem.data[namespace][two])
>          context.par()
>      end
> \stopluacode
> \appendtoks
>      \setuevalue{\currentelem}{\elem_cmd{\currentelem}}%
>      \ctxlua{userdata.elem.define("\currentelem","\currentelemparent")}%
> \to \everydefineelem
> \appendtoks
> \ctxlua{userdata.elem.setup("\currentelem","\elemparameter{key}","\elemparameter{gkey}")}%
> \to \everysetupelem
> \unexpanded\def\elem_cmd#environment%
>    {\edef\currentelem{#environment}%
>     \dosingleempty\elem_cmd_parameters}
> \def\elem_cmd_parameters[#parameters]#content%
>    {\setupelem[\currentelem][#parameters]
>     From \TeX\: Parameters: key=\elemparameter{key},
> gkey=\elemparameter{gkey}\par
>     \ctxlua{userdata.myfun("\currentelem","key","gkey")}}
> \defineelem[base]
> \setupelem[gkey=gval]
> \protect
> \starttext
> \base[key=val]{Hello}
> \stoptext
> A simpler alternative is:
> % macros=mkvi
> \unprotect
> \installnamespace{elem}
> \installcommandhandler \????elem {elem} \????elem
> \startluacode
>      userdata.elem = { data = {  } }
>      function userdata.elem.sync(key,gkey)
>          userdata.elem.data.key = key
>          userdata.elem.data.gkey = gkey
>      end
>      function userdata.myfun(one,two)
>          context.par()
>          context("elem: one=%s",userdata.elem.data[one])
>          context.par()
>          context("elem: two=%s",userdata.elem.data[two])
>          context.par()
>      end
> \stopluacode
> \appendtoks
>      \setuevalue{\currentelem}{\elem_cmd{\currentelem}}%
> \to \everydefineelem
> \unexpanded\def\elem_cmd#environment%
>    {\edef\currentelem{#environment}%
>     \dosingleempty\elem_cmd_parameters}
> \unexpanded\def\elem_sync
> {\ctxlua{userdata.elem.sync("\elemparameter{key}","\elemparameter{gkey}")}}
> \def\elem_cmd_parameters[#parameters]#content%
>    {\setupcurrentelem[#parameters]
>     \elem_sync
>     From \TeX\: Parameters: key=\elemparameter{key},
> gkey=\elemparameter{gkey}\par
>     \ctxlua{userdata.myfun("key","gkey")}}
> \defineelem[base]
> \setupelem[gkey=gval]
> \protect
> \starttext
> \base[key=val]{Hello}
> \stoptext

Thank you Hans!

Two general questions arise (if your permit):

1. Where are the key-value pairs stored?
In your first solution you handle the key setting by explicitly calling lua on every \setup<name> call.  It seems that all key-value pairs (that are set with \installcommandhandler-generated \setup<name>) are stored on the TeX side and not on the lua side.  Is this correct?

2. Calling \ctxlua from lua.
I was tempted to add another level of indirection to your second (the "synchronize") solution.  I.e: in the lua code (in a separate lua file to avoid the do ... end introduced by \startluacode ... \stopluacode) I have: 

n = ""
v = ""
function getkey(name,value)
   n = name
   v = value
end
function myfun(parameters,content)
   context([[\ctxlua{getkey("gkey","\elemparameter{gkey}")}]])
   context(" name=")
   context(n)
   context(", value=")
   context(v)
end

The above does not work because the value obtained "lags behind", i.e. initially v will be "", on the second call v will have the value of the first \setupelem[gkey=gval], and so on.  I guess this lag is due to the way TeX and lua communicate to each other?

A small question: What do you mean by "there is no grouping in lua"?

Thank you anyway for your valuable input.

Regards, Christoph