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}
  • So you'd like the macro to output (key1)-SEPARATOR-(key2)-SEPARATOR-(key3)? Otherwise, please be more specific on what you expect. – egreg Aug 4 '17 at 9:24
  • Yes, that is correct, I must have missed to specify that... – Reinhard Mayr Aug 4 '17 at 9:46
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

  • This solved my problem in an instant! -- Thank you so much for your help! – Reinhard Mayr Aug 4 '17 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.