2

I have a problem where I seem to be unable to replace a string that is the output of a command.

In my document I call the \outerfunction with an argument that is actually a list of key/value pairs. (This is something I cannot change because the command as it is is used throughout the entire document)

In the \outerfunction the values list items are stripped off and the keys separated by a separation code (-SEPARATOR-) and enclosed in parentheses.

The problem is that I want to get rid of the last separation code before the closing parenthesis. I tried the \replace function as provided in this post, I also tried the \StrSubstitute function from the xstring package without success.

When I insert the source string hard-coded into any of these functions the replacement works. I fail to understand the difference or to find a way to a solution. Can someone help me on this please?

Example:

\documentclass{article}
\usepackage{stringstrings}
\usepackage{xstring}
\usepackage{xparse}

\def\replace#1#2#3{%
 \def\tmp##1#2{##1#3\tmp}%
   \tmp#1\stopreplace#2\stopreplace}
\def\stopreplace#1\stopreplace{}

\newcommand{\processlist}[1]
{%
    \noexpandarg%
  \ifx\listfinish#1\empty%
    %\else\texttt{\stringpart{#1}--}\expandafter\processlist%
    \else\texttt{#1-SEPARATOR-}\expandafter\processlist%
    \fi%
}

\newcommand\outerfunction[2][\relax]
{%
    arg1: #1\\
    arg2: #2\\
    \def\listfinish{#1}%
    \long\def\listact{}%
    \replace{(\processlist#2\listfinish)}{-SEPARATOR-)}{)}\\%this does nothing
    \StrSubstitute{(\processlist#2\listfinish)}{-SEPARATOR-)}{)}\\%this does nothing

    %using the text from the output for the StrSubstitute command works
    \StrSubstitute{(key1 - value1-SEPARATOR-key2 - value2-SEPARATOR-key3 - value3-SEPARATOR-)}{-SEPARATOR-)}{)}
}

\begin{document}

\outerfunction
    {
        {key1 - value1}
        {key2 - value2}
        {key3 - value3}
    }

\end{document}
2
  • So you'd like the macro to output (key1)-SEPARATOR-(key2)-SEPARATOR-(key3)? Otherwise, please be more specific on what you expect.
    – egreg
    Commented Aug 4, 2017 at 9:24
  • Yes, that is correct, I must have missed to specify that... Commented Aug 4, 2017 at 9:46

1 Answer 1

1

Here's an implementation with xparse, where you select whether to output the result or to save it in a macro.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\outerfunction}{O{}mo}
 {
  \seq_clear:N \l__mayr_output_seq
  \keys_set:nn { mayr/outerfunction }
   {
    % set the defaults
    inner-sep = --,
    outer-sep = -SEPARATOR-,
    left      = (,
    right     = ),
    #1
   }
  \IfNoValueTF{#3}
   {
    \mayr_outerfunction:n { #2 }
   }
   {
    \mayr_outerfunction_save:Nn #3 { #2 }
   }
 }

\seq_new:N \l__mayr_output_seq
\seq_new:N \l__mayr_temp_seq

\cs_generate_variant:Nn \seq_set_split:Nnn { NV }
\cs_generate_variant:Nn \seq_use:Nn { NV }

\keys_define:nn { mayr/outerfunction }
 {
  inner-sep .tl_set:N  = \l__mayr_inner_separator_tl,
  outer-sep .tl_set:N  = \l__mayr_outer_separator_tl,
  left      .tl_set:N  = \l__mayr_left_tl,
  right     .tl_set:N  = \l__mayr_right_tl,
 }

\cs_new_protected:Nn \mayr_outerfunction:n
 {
  \tl_map_inline:nn { #1 } { \__mayr_innerfunction:n { ##1 } }
  \seq_use:NV \l__mayr_output_seq \l__mayr_outer_separator_tl
 }

\cs_new_protected:Nn \mayr_outerfunction_save:Nn
 {
  \tl_map_inline:nn { #2 } { \__mayr_innerfunction:n { ##1 } }
  \tl_set:Nx #1 { \seq_use:NV \l__mayr_output_seq \l__mayr_outer_separator_tl }
 }

\cs_new_protected:Nn \__mayr_innerfunction:n
 {
  \seq_set_split:NVn \l__mayr_temp_seq \l__mayr_inner_separator_tl { #1 }
  \seq_put_right:Nx \l__mayr_output_seq
   {
    \exp_not:V \l__mayr_left_tl
    \seq_item:Nn \l__mayr_temp_seq { 1 }
    \exp_not:V \l__mayr_right_tl
   }
 }


\ExplSyntaxOff

\begin{document}

\outerfunction
  {
   {key1 -- value1}
   {key2 -- value2}
   {key3 -- value3}
  }

\outerfunction[inner-sep={=},outer-sep=---,left={[},right={]}]
  {
   {key1 = value1}
   {key2 = value2}
   {key3 = value3}
  }[\saved]

\texttt{\meaning\saved}

\end{document}

You should recognize \__mayr_innerfunction:n as my proposal for your earlier question.

enter image description here

1
  • This solved my problem in an instant! -- Thank you so much for your help! Commented Aug 4, 2017 at 10:32

You must log in to answer this question.

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