创建一个可以根据参数在 center、flushleft、flushright 之间切换的新环境

创建一个可以根据参数在 center、flushleft、flushright 之间切换的新环境

我想要创建一个环境,该环境提供centerleft或 ,right创建一个centerflushleftflushright环境。

我当前的代码如下:

\newenvironment{withalignment}[1]{%
    \ifthenelse{\equal{#1}{center}}{\begin{center}}{%
        \ifthenelse{\equal{#1}{left}}{\begin{flushleft}}{%
            \ifthenelse{\equal{#1}{right}}{\begin{flushright}}{}%
        }%
    }%
}{%
    \ifthenelse{\equal{#1}{center}}{\end{center}}{%
        \ifthenelse{\equal{#1}{left}}{\end{flushleft}}{%
            \ifthenelse{\equal{#1}{right}}{\end{flushright}}{}%
        }%
    }%
}%

但:

  1. 似乎不起作用
  2. 递归\ifthenelse相当丑陋,如果有更好的解决方案,那就太好了

如何让它优雅地发挥作用?

答案1

这里是expl3;您可以使用lc或者r此外leftcenterright

\documentclass{article}
\usepackage{lipsum} % for mock text

\ExplSyntaxOn

\NewDocumentEnvironment{withalignment}{m}
 {
  \begin{\vincent_alignment:n { #1 }}
 }
 {
  \end{\vincent_alignment:n { #1 }}
 }

\cs_new:Nn \vincent_alignment:n
 {
  \str_case:nn { #1 }
   {
    {c}{center}
    {center}{center}
    {l}{flushleft}
    {left}{flushleft}
    {r}{flushright}
    {right}{flushright}
   }
 }
\ExplSyntaxOff

\begin{document}

\section{Long arguments}

\begin{withalignment}{left}
\lipsum[1][1-4]
\end{withalignment}

\begin{withalignment}{center}
\lipsum[1][1-4]
\end{withalignment}

\begin{withalignment}{right}
\lipsum[1][1-4]
\end{withalignment}

\section{Short arguments}

\begin{withalignment}{l}
\lipsum[1][1-4]
\end{withalignment}

\begin{withalignment}{c}
\lipsum[1][1-4]
\end{withalignment}

\begin{withalignment}{r}
\lipsum[1][1-4]
\end{withalignment}

\end{document}

在此处输入图片描述

使用错误管理:

\documentclass{article}
\usepackage{lipsum} % for mock text

\ExplSyntaxOn

\NewDocumentEnvironment{withalignment}{m}
 {
  \cs_if_exist:cTF { \vincent_alignment:n { #1 } }
   {% the environment exists
    \begin{\vincent_alignment:n { #1 }}
   }
   {
    \msg_error:nnn { vincent/alignment } { bad-argument } { #1 }
   }
 }
 {
  \cs_if_exist:cT { \vincent_alignment:n { #1 } }
   {
    \end{\vincent_alignment:n { #1 }}
   }
 }

\msg_new:nnnn { vincent/alignment } { bad-argument }
 {
  Wrong~argument~'#1'~to~'withalignment'
 }
 {
  The~allowed~arguments~are~l,~c,~r,~left,~center,~right
 }

\cs_new:Nn \vincent_alignment:n
 {
  \str_case:nn { #1 }
   {
    {c}{center}
    {center}{center}
    {l}{flushleft}
    {left}{flushleft}
    {r}{flushright}
    {right}{flushright}
   }
 }

\ExplSyntaxOff

\begin{document}

\begin{withalignment}{xyzzz}
\end{withalignment}

\section{Long arguments}

\begin{withalignment}{left}
\lipsum[1][1-4]
\end{withalignment}

\begin{withalignment}{center}
\lipsum[1][1-4]
\end{withalignment}

\begin{withalignment}{right}
\lipsum[1][1-4]
\end{withalignment}

\section{Short arguments}

\begin{withalignment}{l}
\lipsum[1][1-4]
\end{withalignment}

\begin{withalignment}{c}
\lipsum[1][1-4]
\end{withalignment}

\begin{withalignment}{r}
\lipsum[1][1-4]
\end{withalignment}

\end{document}

错误的参数会导致 TeX 问题

! Package vincent/alignment Error: Wrong argument 'xyzzz' to 'withalignment'

For immediate help type H <return>.
 ...

l.48 \begin{withalignment}{xyzzz}

? h

The allowed arguments are l, c, r, left, center, right

答案2

尽管所有的 s 都还不够优雅\if,但它确实有效。

\documentclass{article}
\newcommand*{\alignment}{}
\newenvironment{withalignment}[1]{%
    \renewcommand*{\alignment}{#1}
    \if\alignment c
        \begin{center}%
    \else\if\alignment l
        \begin{flushleft}%
    \else\if\alignment r
        \begin{flushright}%
    \fi\fi\fi%
}{%
    \if\alignment c
        \end{center}%
    \else\if\alignment l
        \end{flushleft}%
    \else\if\alignment r
        \end{flushright}%
    \fi\fi\fi%
}
\begin{document}
This is text outside of \texttt{withalignment}.

\begin{withalignment}{c}
This is text in \texttt{withalignment} with parameter \texttt{c}.
\end{withalignment}

\begin{withalignment}{l}
This is text in \texttt{withalignment} with parameter \texttt{l}.
\end{withalignment}

\begin{withalignment}{r}
This is text in \texttt{withalignment} with parameter \texttt{r}.
\end{withalignment}
\end{document}

相关内容