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? Joey On Fri, Nov 26, 2021 at 11:57 AM Joey McCollum wrote: > Thanks! Invoking string.find(str,"^"..pre) is certainly much easier. This > sort of thing would be a nice general-purpose helper function. Denis Maier > and I should have a "wish list" of desired helpers and features (mostly > related to bibliographies/publication support) ready for you (and Alan) > sometime soon. > > But for now, it looks like I still need to work out errors that arise when > I pass a macro as the "str" input to be searched. I've defined a \loc macro > that accepts an assignment and outputs a formatted string, and later, I > want to check if this macro (after it has been fully expanded) starts with > a certain prefix. A minimal (non-)working example follows: > > ``` > > \starttexdefinition loc [#1] > > \doifassignmentelse{#1} { > > % if an assignment, then parse and format accordingly > > \getparameters[loc][#1] > > % Was a section number specified? > > \doifdefined{locsec} { > > § \locsec\btxcomma > > } > > } { > > % 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 > > \DoIfPrefixElse{§}{\currentbtxloctext}{YES}{NOP} > > \stoptext > ``` > > Lua is throwing an "invalid escape sequence near '"\l'" error, which is > presumably because the macro \loc[sec=31] is not being expanded. How do I > fix this? > > Thanks! > > Joey > > On Fri, Nov 26, 2021 at 3:46 AM Hans Hagen via ntg-context < > ntg-context@ntg.nl> wrote: > >> On 11/26/2021 7:42 AM, Joey McCollum via ntg-context wrote: >> > I wasn't aware of a general-purpose "doifstartswith" macro in ConTeXt >> > (the \doifnextcharelse macro only works one character at a time, and >> the >> > \doifinstring macros may capture substrings that are not prefixes), and >> > I'd like to develop one for something I'm working on. I've been trying >> > to do this in Lua, as that seemed like the most natural approach. >> > Normally, something like this would work fine as a foundation: >> > >> > ``` >> > function isprefix(prefix, str) >> > if string.sub(str, 1, string.len(prefix)) == prefix then >> > return true >> > end >> > return false >> > end >> > ``` >> >> how about >> >> if string.find(str,"^"..prefix) then >> >> in: >> >> \starttext >> >> >> \def\DoIfPrefixElse#1#2{\ctxlua{commands.doifelse(string.find("#2","^".."#1"))}} >> >> \DoIfPrefixElse{pre}{prefix}{YES}{NOP} >> \DoIfPrefixElse{pre}{suffix}{YES}{NOP} >> >> \stoptext >> >> utf strings are just sequences of bytes so matching works >> >> when you want to do more in lua you can decide for >> >> \startluacode >> interfaces.implement { >> name = "DoIfPrefixElse", >> arguments = { "argument", "argument" }, >> actions = function(pre,str) >> commands.doifelse(string.find(str,"^"..pre)) >> end >> } >> \stopluacode >> >> \DoIfPrefixElse{pre}{prefix}{YES}{NOP} >> \DoIfPrefixElse{pre}{suffix}{YES}{NOP} >> >> but in any case: make sure that you don't clash with built in ... >> >> if needed i can make a set of fast(er) ones but someone has to collect a >> list of 'handy helpers' first >> >> 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 >> >> ___________________________________________________________________________________ >> >