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.

1 Answer 1

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}
5
  • 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
    Commented Apr 16, 2021 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. Commented Apr 16, 2021 at 19:55
  • There is another problem: calling \Paragraph without specifying an option would use the value specified in the previous call.
    – egreg
    Commented Apr 16, 2021 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
    Commented Apr 16, 2021 at 20:35
  • Never mind, I've done it!
    – mjc
    Commented Apr 16, 2021 at 21:32

You must log in to answer this question.

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