1

Motivation

I'm trying to make a customised paragraph command. I'd like it to have several arguments, some optional and some mandatory. An inconvenience with previous versions has been accessing optional arguments by position, like

\Paragraph[][remember to specify default value here][][is this the right one?]{body of text}

To avoid this, I'd like to implement key-value parameters, as in, say, tikz. I'd also like to have default values specified in an optional argument in the definition.

What I have so far

Note

I expect the top line of the finished command to look like this:

\NewDocumentCommand{\Paragraph}{O{before={&}, after={\\}} m}{

I've got this optional syntax to work without the ampersand, or with the ampersand but no second key-value pair, but in the code below it was useful for explanatory purposes to use a second mandatory argument instead of the optional argument.

End of note

I've cannibalised @egreg's answer to this question to produce the following. I have the expl3 guide open, but haven't studied it thorougly.

\documentclass{article}
\usepackage{xparse,amsmath}

\ExplSyntaxOn

% define the keys \keys_define:nn { Paragraph }{ before .tl_set:N = \l__Paragraph_before_tl, after .tl_set:N = \l__Paragraph_after_tl, }

% formatting \NewDocumentCommand{\Paragraph}{m m}{ \keys_set:nn { Paragraph } { #1 } % populate the keys % format the paragraph \Paragraph_before:V \l__Paragraph_before_tl #2 \Paragraph_after:V \l__Paragraph_after_tl }

\cs_new_protected:Nn \Paragraph_before:n{ #1 } \cs_new_protected:Nn \Paragraph_after:n{ #1 } \cs_generate_variant:Nn \Paragraph_before:n {V} \cs_generate_variant:Nn \Paragraph_after:n {V}

\ExplSyntaxOff

\begin{document} \begin{align} & above \ \Paragraph{before={&}}{text 1} \ % before works singly & \Paragraph{after={\}}{text 2} % after works singly & \Paragraph{before=hi~, after={\}}{text 3} % before and after together, without ampersand, works \Paragraph{before={&}, after={~hey}}{text 4} \ % before and after together, with ampersand, doesn't work & below \end{align} \end{document}

Problem

The command is intended for use inside align-type environments. As shown in the notes on the code, ampersand seems to break something.

mjc
  • 745

1 Answers1

1

The issue is that l__Paragraph_after_tl is set with a normal (local) assignment, so the assignment only applies until the current group ends. But TeX ends a group and starts a new one when it sees & in an align, so the value gets lost. You can avoid this by expanding \l__Paragraph_after_tl before executing any user code:

Here for example I added a \__Paragraph_line:VVn which gets the values of before and after as parameters. Since it's arguments get expanded before it's executed, the expansion happens before & is executed and therefore in the right group.

\documentclass{article}
\usepackage{xparse,amsmath}

\ExplSyntaxOn

% define the keys \keys_define:nn { Paragraph }{ before .tl_set:N = \l__Paragraph_before_tl, after .tl_set:N = \l__Paragraph_after_tl, }

% formatting \NewDocumentCommand{\Paragraph}{m m}{ \keys_set:nn { Paragraph } { #1 } % populate the keys % format the paragraph __Paragraph_line:VVn \l__Paragraph_before_tl \l__Paragraph_after_tl { #2 } }

\cs_new_protected:Nn __Paragraph_line:nnn { \Paragraph_before:n { #1 } #3 \Paragraph_after:n { #2 } } \cs_new_protected:Nn \Paragraph_before:n{ #1 } \cs_new_protected:Nn \Paragraph_after:n{ #1 } \cs_generate_variant:Nn __Paragraph_line:nnn {VVn}

\ExplSyntaxOff

\begin{document} \begin{align} & above \ \Paragraph{before={&}}{text 1} \ % before works singly & \Paragraph{after={\}}{text 2} % after works singly & \Paragraph{before=hi~, after={\}}{text 3} % before and after together, without ampersand, works \Paragraph{before={&}, after={~hey}}{text 4} \ % before and after together, with ampersand, doesn't work & below \end{align} \end{document}

  • Maybe you want \Paragraph_after:n in the second call in \__Paragraph_line:nnn. On the other hand I don't see the need for such auxiliary macro. – egreg Apr 16 '21 at 19:45
  • @egreg Thanks, corrected. I don't see the need either, but since it was present in the original code I assumed that there might be some reason for it which has been removed while creating the MWE, so I decided to keep it. – Marcel Krüger Apr 16 '21 at 19:55
  • There is another problem: calling \Paragraph without specifying an option would use the value specified in the previous call. – egreg Apr 16 '21 at 20:12
  • Thanks for this. I'm now trying to figure out how to add additional arguments. Perhaps this belongs in a new question, but my next problem is to add a width key, where \Paragraph puts the body of the text in a \text{body} environment if width is not specified and a \parbox{width}{body} environment if width is specified. A little tinkering with your code makes me feel like my normal pull-it-and-see-what-happens approach may not get me very far here. – mjc Apr 16 '21 at 20:35
  • Never mind, I've done it! – mjc Apr 16 '21 at 21:32