# substring with calculated end position

I have a string and I would like to use only the first part of the string up to a specific position. So I wrote the \stringpart command using strinstrings' functions.

The position of the searched word (--) where I want to split is found without issues. But when I want to use that position in the \substring command it gives me errors.

Example:

\documentclass{article}
\usepackage{stringstrings}

\newcommand\stringpart[1]{
input: #1\\
string end is at position\ \whereisword{#1}{--}\\% this works
\substring{#1}{1}{\whereisword[q]{#1}{--}}\\% this gives errors
}

\begin{document}
\stringpart{this -- that}
\end{document}


Errors:

! Use of \\isnextbyte doesn't match its definition.
\kernel@ifnextchar ...rved@d =#1\def \reserved@a {
#2}\def \reserved@b {#3}\f...
l.11 \stringpart{this -- that}
! Use of \\whereisword doesn't match its definition.
\kernel@ifnextchar ...d@d =#1\def \reserved@a {#2}
\def \reserved@b {#3}\futu...
l.11 \stringpart{this -- that}
! Undefined control sequence.
<argument> \equal
{\@@teststring }{\endofstring }
l.11 \stringpart{this -- that}
! Argument of \@tempc has an extra }.
<inserted text>
\par
l.11 \stringpart{this -- that}
[... and more errors]


If you don't need the place where the splitting takes place, you can use expl3 features:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\stringpart}{O{1}mO{--}}
{
\seq_set_split:Nnn \l_mayr_string_seq { #3 } { #2 }
\seq_item:Nn \l_mayr_string_seq { #1 }
}
\seq_new:N \l_mayr_string_seq
\ExplSyntaxOff

\begin{document}

X\stringpart{this -- that}X

X\stringpart[2]{this -- that}X

X\stringpart{this;that}[;]X

X\stringpart[2]{this;that}[;]X

\end{document}


stringstrings isn't the best package (I can say that, since I wrote it). In this case, though, the \substring macro wants to see an actual value, not a macro as its end-location argument. I should rewrite that piece of code to make it more forgiving. In the meantime, one needs to expand \theresult, which contains the intermediate calculation of the \whereisword.

\documentclass{article}
\usepackage{stringstrings}

\newcommand\stringpart[1]{
input: #1\\
string end is at position\ \whereisword{#1}{--}\\% this works
\whereisword[q]{#1}{--}% REDUNDANT, UNLESS ABOVE LINE IS REMOVED
\def\tmp{\substring{#1}{1}}%
\expandafter\tmp\expandafter{\theresult}\\% this gives errors
}

\begin{document}
\stringpart{this -- that}
\end{document}


If one wanted to be able to operate with expandable arguments in slots #3 and #4 of \substring, one can use this formulated \Substring macro. Note though, that while \theresult expands to a number, \whereisword is not an expandable argument (it only produces an expandable output in \theresult).

In the MWE below, I actually pass \the\numexpr\theresult-1\relax as argument #4 to \Substring to show that it can handle something more complex, as long as it is expandable.

\documentclass{article}
\usepackage{stringstrings}
\newcommand\Substring[4][v]{%
\edef\tmpA{#3}%
\edef\tmpB{#4}%
\def\tmpC{\substring[#1]{#2}}
\def\tmpD{\expandafter\tmpC\expandafter{\tmpA}}%
\expandafter\tmpD\expandafter{\tmpB}%
}

\newcommand\stringpart[1]{
input: #1\\
string end is at position\ \whereisword{#1}{--}\\% this works