Re: [NTG-context] Checking for a macro in a string without expanding it

2021-11-17 Thread Hans Hagen via ntg-context

On 11/17/2021 12:36 PM, Henning Hraban Ramm via ntg-context wrote:




Am 16.11.2021 um 22:18 schrieb Hans Hagen via ntg-context :



it's pretty fast and needs no lua magic, only a twisted mind


May I quote you as “ConTeXt needs a twisted mind”? ;D
How about "Context tries to untwist your tex mind". After all this is 
not really user code is it?


-
  Hans Hagen | PRAGMA ADE
  Ridderstraat 27 | 8061 GH Hasselt | The Netherlands
   tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl
-
___
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
___


Re: [NTG-context] Checking for a macro in a string without expanding it

2021-11-17 Thread Henning Hraban Ramm via ntg-context


> Am 16.11.2021 um 22:18 schrieb Hans Hagen via ntg-context 
> :

> it's pretty fast and needs no lua magic, only a twisted mind

May I quote you as “ConTeXt needs a twisted mind”? ;D

Hraban
___
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
___


Re: [NTG-context] Checking for a macro in a string without expanding it

2021-11-17 Thread Hans Hagen via ntg-context

On 11/16/2021 11:15 PM, Joey McCollum via ntg-context wrote:
I'm not sure if my mind is twisted enough! I can follow how Jairo's 
answer works, and that does what I need it to, but it's not as clear to 
me what the last two TeX-only approaches are doing at a low level.


Perhaps more importantly, I should clarify that for my purposes, the 
\MyOuter macro is the \currentbtxrighttext macro, which is defined in a 
separate module that I'd prefer not to modify. I want to be able to 
detect and parse the parameters of a \loc macro that a user can specify 
in a citation as follows:


```
\cite[lefttext={See}, righttext={\loc[vol=8,p=223] for further 
details}][clementinehomilies]

```

Because the locator parameters may need to be parenthesized or formatted 
differently depending on the category of the bibliography entry, they 
should be typeset separately from the plain part of the righttext. This 
is why I'd like to be able to parse the parameters and then expand the 
\loc macro itself as empty when the righttext is typeset.
in that case: just redefine \loc on the fly depending on where it's used 
and/or use keys


\cite[lefttext={See},volume=8,page=223]

or so .. imo parsing content is not really a good solution and probably 
also not reliable


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
-
___
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
___


Re: [NTG-context] Checking for a macro in a string without expanding it

2021-11-16 Thread Joey McCollum via ntg-context
I'm not sure if my mind is twisted enough! I can follow how Jairo's answer
works, and that does what I need it to, but it's not as clear to me what
the last two TeX-only approaches are doing at a low level.

Perhaps more importantly, I should clarify that for my purposes, the
\MyOuter macro is the \currentbtxrighttext macro, which is defined in a
separate module that I'd prefer not to modify. I want to be able to detect
and parse the parameters of a \loc macro that a user can specify in a
citation as follows:

```
\cite[lefttext={See}, righttext={\loc[vol=8,p=223] for further
details}][clementinehomilies]
```

Because the locator parameters may need to be parenthesized or formatted
differently depending on the category of the bibliography entry, they
should be typeset separately from the plain part of the righttext. This is
why I'd like to be able to parse the parameters and then expand the \loc
macro itself as empty when the righttext is typeset.

Joey

On Tue, Nov 16, 2021 at 4:19 PM Hans Hagen via ntg-context <
ntg-context@ntg.nl> wrote:

> On 11/16/2021 9:09 PM, Jairo A. del Rio via ntg-context wrote:
> > If I understand it correctly, you may need something like this...?
> >
> > % Protection is key
> > \protected\def\inner[#1]{\empty}
> > % \outer is (or was) already defined in \CONTEXT
> > % Please use another name
> > \def\Outer{\inner[123] and \inner[some text] etc.}
> > \startluacode
> > local implement = interfaces.implement
> > local argument = tokens.scanners.argument
> > local function parseinner()
> >local r = {}
> >local str = argument()
> >str = str:gsub("\\inner%s*(%b[])",function(s)r[#r+1] =
> s:sub(2,#s-1)end)
> >context(table.concat(r," ")) -- Change " " by another spacer if needed
> > end
> > implement{name = "parseinner", public = true, actions = parseinner}
> > \stopluacode
> > \starttext
> > \parseinner{\Outer}
> > \stoptext
> >
> > However, this will only work with very simple cases (no nesting, etc.).
> > Hope this helps.
> well, if we start talking weird code ...
>
> \starttext
>
> \tolerant\def\MyInnerOuter#1\MyInner[#2]#3\MyDone\ignorearguments{#2}
>
> \def\MyOuter#1{\MyInnerOuter#1\MyDone\ignorearguments}
>
> whatever: \MyOuter{\MyInner[oeps]}\par
> whatever: \MyOuter{\InnerMy[oeps]}\par
>
> \edef\ItWorksA{\MyOuter{\MyInner[oeps]}}
> \edef\ItWorksB{\MyOuter{\InnerMy[oeps]}}
>
> whatever: \meaningless\ItWorksA\par
> whatever: \meaningless\ItWorksB\par
>
> \stoptext
>
> (1) we're tolerant so no problem when no match
> (2) the ignore hack quits scanning because tex will keep looking
>
> it's pretty fast and needs no lua magic, only a twisted mind
>
> 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
> -
>
> ___
> 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
>
> ___
>
___
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
___


Re: [NTG-context] Checking for a macro in a string without expanding it

2021-11-16 Thread Hans Hagen via ntg-context

On 11/16/2021 9:09 PM, Jairo A. del Rio via ntg-context wrote:

If I understand it correctly, you may need something like this...?

% Protection is key
\protected\def\inner[#1]{\empty}
% \outer is (or was) already defined in \CONTEXT
% Please use another name
\def\Outer{\inner[123] and \inner[some text] etc.}
\startluacode
local implement = interfaces.implement
local argument = tokens.scanners.argument
local function parseinner()
   local r = {}
   local str = argument()
   str = str:gsub("\\inner%s*(%b[])",function(s)r[#r+1] = s:sub(2,#s-1)end)
   context(table.concat(r," ")) -- Change " " by another spacer if needed
end
implement{name = "parseinner", public = true, actions = parseinner}
\stopluacode
\starttext
\parseinner{\Outer}
\stoptext

However, this will only work with very simple cases (no nesting, etc.). 
Hope this helps.

well, if we start talking weird code ...

\starttext

\tolerant\def\MyInnerOuter#1\MyInner[#2]#3\MyDone\ignorearguments{#2}

\def\MyOuter#1{\MyInnerOuter#1\MyDone\ignorearguments}

whatever: \MyOuter{\MyInner[oeps]}\par
whatever: \MyOuter{\InnerMy[oeps]}\par

\edef\ItWorksA{\MyOuter{\MyInner[oeps]}}
\edef\ItWorksB{\MyOuter{\InnerMy[oeps]}}

whatever: \meaningless\ItWorksA\par
whatever: \meaningless\ItWorksB\par

\stoptext

(1) we're tolerant so no problem when no match
(2) the ignore hack quits scanning because tex will keep looking

it's pretty fast and needs no lua magic, only a twisted mind

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
-
___
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
___


Re: [NTG-context] Checking for a macro in a string without expanding it

2021-11-16 Thread Hans Hagen via ntg-context

On 11/16/2021 8:22 PM, Joey McCollum via ntg-context wrote:
As the subject of this question suggests, this is really more of a 
question about expansion control (a topic that is still a bit obscure to 
me). Suppose I have a macro \inner that expects a single argument or an 
assignment of parameters in brackets. For my purposes, I don't want this 
macro to do anything when it is typeset, so I'll just define it as empty:


```
\def\inner[#1]\empty
```

Now suppose I have another macro \outer that invokes this macro with 
some specific input and sets some plain text after it:


```
\def\outer{\inner[123] etc.}
```

What I'd like to do is parse the argument of \inner in \outer. I was 
hoping that a string search in Lua would work, but I'm not having any 
luck. A minimal (non)-working example is included below:


```

\def\inner[#1]\empty

\def\outer{\inner[123] etc.}


\startluacode

local userdata = userdata or {}

function userdata.parseinner(str)

local innerparams = ""

     if string.find(str, "\\inner(%b[])") then

       i, j = string.find(str, "\\inner(%b[])")

       innerparams = string.sub(str, i+1, j-1) -- we just want the 
content inside the brackets


     end

     context(innerparams)

     return

end

\stopluacode

\def\parseinner#1{\ctxlua{userdata.parseinner([==[#1]==])}}


\starttext

Testing:\blank

\parseinner{\outer}

\stoptext

```

My problem is that when I pass \outer to the \parseinner macro, it gets 
fully expanded, so there isn't anything left to match "\\inner%b[]". Is 
there a way to expand \outer when I pass it to the \parseinner macro 
without also expanding the \inner macro inside it? Or is there some 
other preferred way of doing this?


One can always abuse native tex:

\starttext

\def\MyOuter#1%
  {\beginlocalcontrol % hides the next
   \let\Indeed\empty
   \def\MyInner[##1]{\gdef\Indeed{##1}}%
   \setbox\scratchbox\hpack{#1}%
   \endlocalcontrol  % but only if needed
   \Indeed}

whatever: \MyOuter{\MyInner[oeps]}%

\edef\ItWorks{\MyOuter{\MyInner[oeps]}}

whatever: \meaningless\ItWorks

\stoptext



--

-
  Hans Hagen | PRAGMA ADE
  Ridderstraat 27 | 8061 GH Hasselt | The Netherlands
   tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl
-
___
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
___


Re: [NTG-context] Checking for a macro in a string without expanding it

2021-11-16 Thread Jairo A. del Rio via ntg-context
If I understand it correctly, you may need something like this...?

% Protection is key
\protected\def\inner[#1]{\empty}
% \outer is (or was) already defined in \CONTEXT
% Please use another name
\def\Outer{\inner[123] and \inner[some text] etc.}
\startluacode
local implement = interfaces.implement
local argument = tokens.scanners.argument
local function parseinner()
  local r = {}
  local str = argument()
  str = str:gsub("\\inner%s*(%b[])",function(s)r[#r+1] = s:sub(2,#s-1)end)
  context(table.concat(r," ")) -- Change " " by another spacer if needed
end
implement{name = "parseinner", public = true, actions = parseinner}
\stopluacode
\starttext
\parseinner{\Outer}
\stoptext

However, this will only work with very simple cases (no nesting, etc.).
Hope this helps.

Best regards,

Jairo

El mar, 16 de nov. de 2021 a la(s) 14:22, Joey McCollum via ntg-context (
ntg-context@ntg.nl) escribió:

> As the subject of this question suggests, this is really more of a
> question about expansion control (a topic that is still a bit obscure to
> me). Suppose I have a macro \inner that expects a single argument or an
> assignment of parameters in brackets. For my purposes, I don't want this
> macro to do anything when it is typeset, so I'll just define it as empty:
>
> ```
> \def\inner[#1]\empty
> ```
>
> Now suppose I have another macro \outer that invokes this macro with some
> specific input and sets some plain text after it:
>
> ```
> \def\outer{\inner[123] etc.}
> ```
>
> What I'd like to do is parse the argument of \inner in \outer. I was
> hoping that a string search in Lua would work, but I'm not having any luck.
> A minimal (non)-working example is included below:
>
> ```
>
> \def\inner[#1]\empty
>
> \def\outer{\inner[123] etc.}
>
>
> \startluacode
>
> local userdata = userdata or {}
>
> function userdata.parseinner(str)
>
> local innerparams = ""
>
> if string.find(str, "\\inner(%b[])") then
>
>   i, j = string.find(str, "\\inner(%b[])")
>
>   innerparams = string.sub(str, i+1, j-1) -- we just want the content
> inside the brackets
>
> end
>
> context(innerparams)
>
> return
>
> end
>
> \stopluacode
>
> \def\parseinner#1{\ctxlua{userdata.parseinner([==[#1]==])}}
>
>
> \starttext
>
> Testing:\blank
>
> \parseinner{\outer}
>
> \stoptext
> ```
>
> My problem is that when I pass \outer to the \parseinner macro, it gets
> fully expanded, so there isn't anything left to match "\\inner%b[]". Is
> there a way to expand \outer when I pass it to the \parseinner macro
> without also expanding the \inner macro inside it? Or is there some other
> preferred way of doing this?
>
> Joey
>
> ___
> 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
>
> ___
>
___
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
___


[NTG-context] Checking for a macro in a string without expanding it

2021-11-16 Thread Joey McCollum via ntg-context
As the subject of this question suggests, this is really more of a question
about expansion control (a topic that is still a bit obscure to me).
Suppose I have a macro \inner that expects a single argument or an
assignment of parameters in brackets. For my purposes, I don't want this
macro to do anything when it is typeset, so I'll just define it as empty:

```
\def\inner[#1]\empty
```

Now suppose I have another macro \outer that invokes this macro with some
specific input and sets some plain text after it:

```
\def\outer{\inner[123] etc.}
```

What I'd like to do is parse the argument of \inner in \outer. I was hoping
that a string search in Lua would work, but I'm not having any luck. A
minimal (non)-working example is included below:

```

\def\inner[#1]\empty

\def\outer{\inner[123] etc.}


\startluacode

local userdata = userdata or {}

function userdata.parseinner(str)

local innerparams = ""

if string.find(str, "\\inner(%b[])") then

  i, j = string.find(str, "\\inner(%b[])")

  innerparams = string.sub(str, i+1, j-1) -- we just want the content
inside the brackets

end

context(innerparams)

return

end

\stopluacode

\def\parseinner#1{\ctxlua{userdata.parseinner([==[#1]==])}}


\starttext

Testing:\blank

\parseinner{\outer}

\stoptext
```

My problem is that when I pass \outer to the \parseinner macro, it gets
fully expanded, so there isn't anything left to match "\\inner%b[]". Is
there a way to expand \outer when I pass it to the \parseinner macro
without also expanding the \inner macro inside it? Or is there some other
preferred way of doing this?

Joey
___
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
___