Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I really hope that I'm asking the correct question. What I'm actually working on if far more convoluted than what's happening in the MWE here. I think I've narrowed down things to real problem.

I have some old code that does what I want perfectly. Now I would like to use that code in a new situation where I iterate several times using the old code before outputting anything.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
%%--------------------------------------------------------------------------------
%% In theory, this first section of code works correctly and gives me the desired 
%% result.                                                                        
%%--------------------------------------------------------------------------------
%% This next macro does some complicated things:                                  
%%                                                                                
%%    testing booleans, setting token lists, \int_compare, \int_case              
%%                                                                                
%% But, regardless, everything it does--I believe--is fully expandable.  That is  
%% it should work whether in an "x" or "f" type argument.                         
\cs_new:Npn  \_format_expression:n #1 { #1 x 2 - }

\seq_new:N \l_collection_of_expressions_seq
\cs_new:Npn \_parse_expressions:n #1
  { \seq_set_split:Nnn \l_collection_of_expressions_seq {,} {#1} }


%% This next function, while fully expandable is not expandable in an "f"     
%% tyep argument.                                                             
\cs_new:Nn \_write_expression:
  {
    \seq_map_inline:Nn \l_collection_of_expressions_seq
      { \_format_expression:n { ##1 } }
  }

\NewDocumentCommand{\trialFunctionA}{ m }
    { \_parse_expressions:n { #1 } 
      \_write_expression:
    }

%%--------------------------------------------------------------------------------
%% Here starts the problematic code                                               
%%--------------------------------------------------------------------------------
%% The start of more complicated things.                                          
\seq_new:N \l_outer_collection_of_expressions_seq
\tl_new:N  \l_numerator_tl
\seq_new:N \l_formatted_expressions_seq   
\seq_new:N \l_denominator_seq

\cs_new:Npn \_parse_outer:nn #1#2
  { 
    \tl_put_right:Nn \l_numerator_tl {#2}
    \_parse_expressions:n {#1}
    %% This is where my problem step seems to be. I need the                  
    %% expansion of \_write_expression: but can't get it.  However,           
    %% since \_write_expression: uses \seq_map_inline, this is not            
    %% expandable in an "f" type argument.  But neither do I want to blast    
    %% this with "x" because I might have some unexpandable stuff in here     
    \seq_put_right:Nn \l_formatted_expressions_seq { 3^{\_write_expression:} }
  }

\cs_new:Npn \parse_outer:n #1
  { 
    \seq_set_split:Nnn \l_outer_collection_of_expressions_seq {,} { #1 }
    \seq_map_inline:Nn \l_outer_collection_of_expressions_seq 
      { \_parse_outer:nn  ##1 } 
    \frac{\l_numerator_tl}{\seq_use:Nn \l_formatted_expressions_seq {\,}}
  }   

\NewDocumentCommand{\trialFunctionB}{ m }
    { \parse_outer:n { #1 } }

%%--------------------------------------------------------------------------------
%% This is here just so I can easily demo the desired final result.               
\def\cheat#1{\_format_expression:n{#1}}

\ExplSyntaxOff
\begin{document}

\[
  \trialFunctionA{1,2,3}
\]

\[
  \frac{ABC}{3^{\cheat{1}\cheat{2}\cheat{3}}\,
             3^{\cheat{a}\cheat{b}\cheat{c}}\,
             3^{\cheat{M}\cheat{N}\cheat{P}}}
\]

\[
  \trialFunctionB{{1,2,3}{A},
                  {a,b,c}{B},
                  {M,N,P}{C}}
\]

\end{document}

enter image description here

The above code does compile, which is better than my actual document. But I don't have the desired results because expansion is happening too late.

Is there some way to get \_write_expression: to expand just far enough, but not too far?

share|improve this question
    
\seq_map_inline:Nn is not fully expandable. –  egreg Aug 24 '13 at 21:32
    
Can you replace \_write_expression: with an appropriate \seq_use as in changing parse expressions to \cs_new:Npn \_parse_expressions:n #1 { \seq_set_split:Nnn \l_collection_of_expressions_seq {,} {#1} \seq_put_right:Nx \l_formatted_expressions_seq { 3^{\seq_use:Nn \l_collection_of_expressions_seq {x2-} x2-}} } and eliminating write expressions. –  Scott H. Aug 24 '13 at 22:05

1 Answer 1

up vote 3 down vote accepted

I would suggest that you blast it with :x anyway and protect fragile content with \exp_not:n.

Also, you made a wrong assumption about \seq_map_inline:Nn. Any _map_inline function has to make a definition in the background, and is thus ineligible for :x expansion. So you need to use \seq_map_function:NN.

The following code should work. I added some fragile content to show that it's protected from expansion until the right time.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new:Npn  \_format_expression:n #1 { \exp_not:n{#1} x 2 - } % CHANGED

\seq_new:N \l_collection_of_expressions_seq
\cs_new:Npn \_parse_expressions:n #1
  { \seq_set_split:Nnn \l_collection_of_expressions_seq {,} {#1} }

\cs_new:Nn \_write_expression:
  {
    \seq_map_function:NN
        \l_collection_of_expressions_seq
        \_format_expression:n  % CHANGED
  }

%%--------------------------------------------------------------------------------
%% Here starts the problematic code                                               
%%--------------------------------------------------------------------------------

\seq_new:N \l_outer_collection_of_expressions_seq
\tl_new:N  \l_numerator_tl
\seq_new:N \l_formatted_expressions_seq   
\seq_new:N \l_denominator_seq

\cs_new:Npn \_parse_outer:nn #1#2
  { 
    \tl_put_right:Nn \l_numerator_tl {\exp_not:n{#2}}  % CHANGED
    \_parse_expressions:n {#1} 
    \seq_put_right:Nx
        \l_formatted_expressions_seq
        { 3^{\_write_expression:} }  % CHANGED
  }

\cs_new:Npn \parse_outer:n #1
  { 
    \seq_set_split:Nnn \l_outer_collection_of_expressions_seq {,} { #1 }
    \seq_map_inline:Nn \l_outer_collection_of_expressions_seq 
      { \_parse_outer:nn  ##1 }
    \frac{\l_numerator_tl}{\seq_use:Nn \l_formatted_expressions_seq {\,}}
  }   

\NewDocumentCommand{\trialFunctionB}{ m }
    { \parse_outer:n { #1 } }


%%% Example don't-want-this-to-expand content
\int_new:N \g_counter_int
\cs_new:Npn \DontExpandPlease {
    \int_gincr:N \g_counter_int
    \int_use:N \g_counter_int
}

\ExplSyntaxOff
\begin{document}

\[
  \trialFunctionB{{\DontExpandPlease,\DontExpandPlease,\DontExpandPlease}{A},
                  {a,b,c}{B},
                  {M,N,P}{C}}
\]

\end{document}
share|improve this answer
    
\seq_map_inline:Nn doesn't survive x expansion, while \seq_map_function:Nn can be used in f expansion. –  egreg Aug 24 '13 at 22:24
    
Yes, of course, silly me. Any _map_inline has to make a definition in the background, and is thus ineligible for :x expansion. (I blame sleep-deprivation. :-)) --- However, your second statement confuses me still. The docs would suggest that \seq_map_function:Nn can not be expanded by :f (it has a hollow star). –  mhelvens Aug 24 '13 at 22:32
    
You're right: it is fully expandable, but not in f arguments. –  egreg Aug 24 '13 at 22:35
    
Nice explanation. I'm still trying to get my actual document to compile correctly. I'm still scratching my head. No error messages now, but my formatting is still getting lost. :( –  A.Ellett Aug 24 '13 at 22:43
    
Well, it's hard to say without seeing your code, but are you perhaps :xing your formatted content again at some point? \exp_not:n will only protect it once. –  mhelvens Aug 24 '13 at 22:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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