0

Thanks for any suggestions on this problem. This is a variation on how to use xstrings to make a test when the xstrings test function is buried deep in code. I have read a dozen examples or more on this site and elsewhere, but none of the suggested solutions worked for me, possibly because of the specific package I am using that calls the xstrings function.

I am happy to replace xstrings with something else, but if possible would like to avoid Latex 3/expl3/whatever, as the document is a long book, I have zero experience with these newer things, and don't know what else would change. That is, I'd find minimal and local solutions to be easiest for me to implement.

I am typesetting Gregorian chant using the gregorio tex package in LuaLaTeX. An MWE follows, but some background is necessary.

Gregorio Tex reads in a plain text file called a .gabc file containing a representation of a score and translates that into tex code to print an actual musical score. A .gabc file contains a header with tags (e.g. name: for the name of the piece), followed by a %%, and then the actual mark-up of the music.

Gregorio Tex provides a command \gresetheadercapture that will capture the value of a particular tag and pass it to a user-defined command as an argument. This allows printing of titles, etc. based on values associated with the score, such as name, musical mode, biblical citation of the text, etc. I have stripped this down as much as possible for this example.

I'm printing a title above each score in a document that uses the chant name (\thelatinname) and chant type (\thechantpart) read from the gabc file using gresetheadercapture.

The problem is that I'd like to vary the title slightly by the type of chant; specifically, if it is of type "Varia", omit the chant part from the title. So I would get titles like

Gradual: Christus factus est

but simply, e.g.,

Improperia

for chants of type "Varia".

The chant type may have spaces in the name, but is always purely alphabetic without other special characters. Varia is the only type that contains the letter V.

To accomplish this, I'm using a test to see if \thechantpart contains the capital letter V using xstrings \IfSubStr. This fails miserably because of problems with what piece of software expands what arguments when, and to what degree, and I am at sea trying to debug or fix this. Obviously, this is complicated as nothing happens until the command \gregorioscore runs, so I am not sure where I stand in terms of my own commands expanding arguments based on what is executed by the package before them.

Practically, no matter what I do, the test is always false.

The xstrings package has several flags for changing how arguments are expanded: \fullexpandarg, \expandarg, \normalexpandarg, and \noexpandarg. None of these change the result in any way, and same goes for their optional flag \exploregroup. All 8 combinations of these commands fail.

Here is the MWE tex file, followed by an MWE.gabc file. The output should not include Varia: in the title, but it does.

% !TEX TS-program = lualatex
% !TEX encoding = UTF-8

\documentclass[12pt,twoside]{book}

\usepackage[autocompile]{gregoriotex}
\usepackage{xstring}

%Set the testing flag to 2 to look for any changes.
\gdef\hasVaria{2} %

%Routine to process the type of chant as \thechantpart.
%  Check if \thechantpart is the string Varia.
%  If so, set \hasVaria to 1 for later use.
\newcommand\mkchantindex[1]{%
\gdef\thechantpart{#1}

 \message{thechantpart macro is !\thechantpart!}
   \message{Test result:}
   \begingroup
     \normalexpandarg
     \exploregroups
       \IfSubStr{\thechantpart}{V}{\message{true}\gdef\hasVaria{1}}{\message{false}\gdef\hasVaria{0}}
    \noexploregroups
    \fullexpandarg
  \message{hasVaria is !\hasVaria!}
  \endgroup
}


%Routine to get the Latin title and typeset the chant title
%  If the hasVaria flag is 1, omit the chant part from the title.
\newcommand\mklatinlabel[1]{%
\gdef\thelatinname{#1}
      \ifnum\hasVaria=1%
          \printtitle{\thelatinname}\nopagebreak%
      \else
         \printtitle{\thechantpart:\ \thelatinname}\nopagebreak%
      \fi
}

\newcommand{\printtitle}[1]{\noindent  #1\par}

%Direct gregorio tex to pass the contents of the named tag to the named subroutine as
% a string
\gresetheadercapture{latin-name}{mklatinlabel}{string}
\gresetheadercapture{office-part}{mkchantindex}{string}  

\begin{document}

\message{First hasVaria = !\hasVaria!\par}

\gregorioscore{MWEchant}

\message{Last hasVaria = !\hasVaria!}

\end{document}

File MWEchant.gabc:

% !TEX root = ./MWE.tex
name:Chant;
office-part:Varia;
latin-name:Improperia;
%%
(c4) This(c) is(d) some(e) chant(d.) (::)

Problems with argument expansion during execution of gresetheadercapture routines Posting...

2
  • note on expl3, as it's preloaded using it is more minimal than using xstring, and as for being new, the syntax has been used with latex since about 1992 or so: a couple of decades before luatex that you are using. Although here I just used \ifx so rather more minimal than either xstring or expl3. Commented Jun 26, 2021 at 18:54
  • Thanks. I should say new to me. I wrote my thesis in plain TeX back in the late 80s/early 90s, but left that world and have only recently returned to using TeX of any kind at all. When I started using Gregorio, I followed the examples of others who used it I think for support of various accented characters for Latin such as é. I'm sure there are other ways, but I'm not really using anything sophisticated in the Lua world at all. Which is to say that I am trying to minimize the gap in what I need to learn!
    – Rob LEduc
    Commented Jun 26, 2021 at 19:04

1 Answer 1

1

You can normalise the catcodes then simply compare with \ifx

\documentclass[12pt,twoside]{book}

\usepackage[autocompile]{gregoriotex}
\usepackage{xstring}

%Set the testing flag to 2 to look for any changes.
\gdef\hasVaria{2} %

%Routine to process the type of chant as \thechantpart.
%  Check if \thechantpart is the string Varia.
%  If so, set \hasVaria to 1 for later use.
\newcommand\mkchantindex[1]{%
  \edef\thechantpart{\detokenize{#1}}}

%Routine to get the Latin title and typeset the chant title
%  If the hasVaria flag is 1, omit the chant part from the title.
\edef\Variapart{\detokenize{Varia}}
\newcommand\mklatinlabel[1]{%
\gdef\thelatinname{#1}
      \ifx\thechantpart\Variapart
\message{VARIA}%
          \printtitle{\thelatinname}\nopagebreak%
      \else
\message{NOT VARIA}%
         \printtitle{\thechantpart:\ \thelatinname}\nopagebreak%
      \fi
}

\newcommand{\printtitle}[1]{\noindent  #1\par}

%Direct gregorio tex to pass the contents of the named tag to the named subroutine as
% a string
\gresetheadercapture{latin-name}{mklatinlabel}{string}
\gresetheadercapture{office-part}{mkchantindex}{string}  

\begin{document}

\message{First hasVaria = !\hasVaria!\par}

\gregorioscore{MWEchant}

\message{Last hasVaria = !\hasVaria!}

\end{document}
1
  • Magnificent! Thanks. I guess I need to break down and find a more modern book on syntax. I can write endless amounts of content, math, etc., but need something that starts on the level of "this is a catcode; this is a token; this is how they are parsed; now here is a slightly trickier example..."
    – Rob LEduc
    Commented Jun 26, 2021 at 19:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .