I was afraid that might be the problem. I've described some of the intended purpose of this code near the end of the "Checking for a macro in a string without expanding it" thread on the mailing list, but I will get into more detail here. I'm working on a ConTeXt implementation of citation style language (CSL) locators, particularly for the SBL citation rendering (although the code could easily be adapted for use in general or with other bibliographic renderings). This would allow for a consistent, language-sensitive syntax that could be used within citations or in any part of a text and could accommodate changes in bibliographic style without requiring the user to reformat all their page number citations. In SBL style, for instance, volume, part, and page numbers are not prefixed by abbreviations like "vol.", "pt." and "p.", but in other styles, they might be. The locator syntax

```
\loc[vol=33,pt=1,p=86]
```

would be defined in the SBL rendering file to output

```
33.1:86
```

while in some other style, it might be defined to output

```
vol. 33, pt. 1, p. 86
```

To accommodate the use of these macros within citations, I've added "loctext" (locator text) and "altloctext" (alternate locator text) arguments to the set of parameters used by the \cite macro, because in some bibliographic categories, different locators can be specified for different parts of a citation (e.g., one for a passage in an ancient text and another for the book reproducing it), and therefore cannot just be specified in the "righttext" parameter. So now we can do something like

```
\cite[lefttext={See},altloctext={1.3},loctext={8:223},righttext={for further details}][clementinehomilies]
```

to get

See The Clementine Homilies 1.3 (ANF 8:223) for further details.

or 

```
\cite[lefttext={See},loctext={\loc[p=8]},righttext={; but there are also contradictory statements, e.g. \loc[p=12].}][Doe:Title]
```

to get

See Doe, Title, 8; but there are also contradictory statements, e.g. 12.

The main problem is determining when to include a comma before printing the "loctext" and when not to include one. In the first example above, we don't want a comma between ANF and 8:223 (SBL style does not add a comma between a multivolume set abbreviation and a volume number), but in the second example, we do want one between Title and 8. Similarly, we want to remove the comma if the first locator in the loctext is a section marker (§) or paragraph marker (¶). This is why I want to check the beginning of the \currentloctext macro for the presence of a volume number (a number followed by a colon), a section mark, or a paragraph mark.

While storing the locator parameters as btx parameters would allow for another solution to this problem, it would complicate defining the \loc macro in a way that would be suitable outside of citations or for multiple uses in the same citation (notice how a second \loc invocation occurs in the righttext of the second example above). Parsing the output of \loc seemed like the simplest solution, but as you've pointed out, it has its own difficulties. I'm inclined to try one of the TeX-based solutions you describe above to avoid complicating other things, but if my description of the intended use gives you any better ideas, please suggest them!

Thanks again!

Joey

On Sat, Nov 27, 2021 at 1:44 PM Hans Hagen <j.hagen@xs4all.nl> wrote:
On 11/27/2021 6:13 PM, Joey McCollum wrote:
> All right, I think I've solved the expansion problem I described before:
> to ensure that the first input is expanded when it is passed to Lua, I
> have to pass it as [==[#1]==], not "#1". But the updated MWE below still
> does not seem to work, as the \DoIfPrefixElse macro is printing "NOP"
> instead of "YES":
>
> ```
>
> \starttexdefinition loc [#1]
>
> \doifassignmentelse{#1} {
>
> % if an assignment, then parse and format accordingly
>
> \getparameters[loc][#1]
>
> % Was a section number specified?
>
> \doifdefined{locsec} {
>
> § \locsec
>
> }
>
> } {
>
> % otherwise, just print the input as-is
>
> #1
>
> }
>
> \stoptexdefinition
>
>
> \def\DoIfPrefixElse#1#2{\ctxlua{commands.doifelse(string.find([==[#2]==],"^"..[==[#1]==]))}}
>
>
> \def\currentbtxloctext{\loc[sec=31]}
>
>
> \starttext
>
> \currentbtxloctext\blank
>
> \DoIfPrefixElse{§}{\currentbtxloctext}{YES}{NOP}
>
> \stoptext
>
> ```
>
> Indeed, if I add a simple \doifelse equality check, it looks like the
> value I expect is not the same as what the macro produces, even though
> they look identical:
>
> ```
>
> \starttexdefinition loc [#1]
>      \doifassignmentelse{#1} {
>          % if an assignment, then parse and format accordingly
>          \getparameters[loc][#1]
>          % Was a section number specified?
>          \doifdefined{locsec} {
>              § \locsec
>          }
>      } {
>          % otherwise, just print the input as-is
>          #1
>      }
> \stoptexdefinition
>
> \def\DoIfPrefixElse#1#2{\ctxlua{commands.doifelse(string.find([==[#2]==],"^"..[==[#1]==]))}}
>
> \def\currentbtxloctext{\loc[sec=31]}
>
> \starttext
>      § 31\blank%the raw text we expect
>      \currentbtxloctext\blank%the text as produced by the macro
>      \doifelse{\currentbtxloctext}{§ 31}{YES}{NOP}\blank% should output
> YES, but doesn't
>      \DoIfPrefixElse{§}{\currentbtxloctext}{YES}{NOP}\blank% should
> output YES, but doesn't
> \stoptext
>
> ```
>
> What am I missing here?
Expansion hell ... and i fear that you draw yourself into more and more
trouble with this approach (which is why you don't find that kind of
hackery in the core unless we're real desperate) so maybe try to explain
what the real problem is that needs to be solved. Parsing tex is seldom
a solution (at least not in context).

You can add:

     \edef\Whatever{\currentbtxloctext}\meaning\Whatever
     \doifelse{\currentbtxloctext}{§ 31}{YES}{NOP}\blank

and see what comes back. Now, as always in tex, there's of course a
solution because after all it's a programming language too (and at some
point these solutions start looking so complex that one enters guru state)

\starttexdefinition loc [#1]
     \beginlocalcontrol
     \doifassignmentelse{#1} {
         \getparameters[loc][#1]
         \doifdefinedelse{locsec} {
         \endlocalcontrol
             § \locsec
         } {
             \endlocalcontrol
         }
     } {
         \endlocalcontrol
         #1
     }
\stoptexdefinition

a curious mix between a fully expanded result, using protected macros
and hiding what tex does but hard to explain

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