如何为带有“扩展”文本的新编号环境创建宏?

如何为带有“扩展”文本的新编号环境创建宏?

我希望在 LATeX 中创建一个新环境,用于排版一首诗(非英语)的某些诗句。我希望每节诗句的文本都占据最长诗句的整个宽度。为了说明这一点,请考虑以下最小工作示例:

\documentclass{article}
\begin{document}
\newlength{\versewd}
\settowidth{\versewd}{adipiscing vitae, felis. Curabitur dictum gravida mauris.}

\begin{tabular}{p{\versewd}l}
    \makebox[\versewd][s]{Lorem ipsum dolor sit amet}     &                \\
    \makebox[\versewd][s]{consectetuer adipiscing elit} & (1) \\
    \makebox[\versewd][s]{Ut purus elit, vestibulum ut, placerat ac}        &                \\
    \makebox[\versewd][s]{adipiscing vitae, felis. Curabitur dictum gravida mauris.}    & (2) \\
\end{tabular}
\end{document}

这将生成如下输出: MWE 的输出

这正是我想要的,但我想创建一个可以做到这一点的环境。我希望代码看起来更简单,类似于:

\documentclass{article}
\begin{document}
\begin{verse}
    \myitem{Lorem ipsum dolor sit amet}{consectetuer adipiscing elit}       
    \myitem{Ut purus elit, vestibulum ut, placerat ac}{adipiscing vitae, felis. Curabitur dictum gravida mauris.}
\end{verse}
\end{document}

我将非常感激任何关于这个方向的指点。我最初搜索了创建新环境,但没有找到任何足够有助于解决这个问题的方法。谢谢!

答案1

以下解决方案的作用是

  1. 吸收整首诗;
  2. 测量每节诗句的自然宽度,跟踪最大宽度;
  3. 将每节诗句打印在一个展开框中。

输入中,诗节之间用空行分隔,诗句之间用 分隔\\。每节末尾添加数字。

\documentclass{article}

\usepackage{xparse,environ}

\ExplSyntaxOn

\NewEnviron{spreadverse}
 {
  \setlength{\parindent}{0pt} % no indent
  \hbadness=\c_ten_thousand   % don't show underfull box messages
  \raman_spreadverse:V \BODY
 }

%% variables
\dim_new:N \l_raman_spreadverse_width_dim
\int_new:N \l_raman_spreadverse_stanza_int
\seq_new:N \l_raman_spreadverse_stanzas_seq
\seq_new:N \l_raman_spreadverse_verses_seq
\seq_new:N \l_raman_spreadverse_printverses_seq
\box_new:N \l_raman_spreadverse_verse_box

\cs_new_protected:Nn \raman_spreadverse:n
 {
  \dim_zero:N \l_raman_spreadverse_width_dim
  \int_zero:N \l_raman_spreadverse_stanza_int
  \seq_set_split:Nnn \l_raman_spreadverse_stanzas_seq { \par } { #1 }
  % measure the verses
  \seq_map_inline:Nn \l_raman_spreadverse_stanzas_seq
   {
    \raman_spreadverse_measure:n { ##1 }
   }
  % typeset the verses
  \seq_map_inline:Nn \l_raman_spreadverse_stanzas_seq
   {
    \raman_spreadverse_print:n { ##1 }
    \int_incr:N \l_raman_spreadverse_stanza_int
    \nolinebreak
    \quad
    ( \int_to_arabic:n {\l_raman_spreadverse_stanza_int} )
    \par
   }
 }
\cs_generate_variant:Nn \raman_spreadverse:n { V }

\cs_new_protected:Nn \raman_spreadverse_measure:n
 {
  \seq_set_split:Nnn \l_raman_spreadverse_verses_seq { \\ } { #1 }
  \seq_map_inline:Nn \l_raman_spreadverse_verses_seq
   {
    \hbox_set:Nn \l_raman_spreadverse_verse_box { ##1 }
    \dim_set:Nn \l_raman_spreadverse_width_dim
     {
      \dim_max:nn
       { \l_raman_spreadverse_width_dim }
       { \box_wd:N \l_raman_spreadverse_verse_box }
     }
   }
 }
\cs_new_protected:Nn \raman_spreadverse_print:n
 {
  \seq_clear:N \l_raman_spreadverse_printverses_seq
  \seq_set_split:Nnn \l_raman_spreadverse_verses_seq { \\ } { #1 }
  \seq_map_inline:Nn \l_raman_spreadverse_verses_seq
   {
    \seq_put_right:Nn \l_raman_spreadverse_printverses_seq
     {
      \makebox[\l_raman_spreadverse_width_dim][s]{##1}
     }
   }
  \seq_use:Nn \l_raman_spreadverse_printverses_seq { \\* }
 }
\ExplSyntaxOff

\begin{document}

\begin{spreadverse}
Lorem ipsum dolor sit amet \\
consectetuer adipiscing elit

Ut purus elit, vestibulum ut, placerat ac \\
adipiscing vitae, felis. Curabitur dictum gravida mauris.
\end{spreadverse}

\end{document}

在此处输入图片描述

这是一个允许使用可选参数的版本,用于使用包含诗句的不同环境(默认center)。

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

\usepackage{lipsum,showframe} % just for the example

\ExplSyntaxOn

\NewEnviron{spreadverse}[1][center]
 {
  \begin{#1}
  \hbadness=\c_ten_thousand
  \raman_spreadverse:V \BODY
  \end{#1}
 }

%% variables
\dim_new:N \l_raman_spreadverse_width_dim
\int_new:N \l_raman_spreadverse_stanza_int
\seq_new:N \l_raman_spreadverse_stanzas_seq
\seq_new:N \l_raman_spreadverse_verses_seq
\seq_new:N \l_raman_spreadverse_printverses_seq
\box_new:N \l_raman_spreadverse_verse_box

\cs_new_protected:Nn \raman_spreadverse:n
 {
  \dim_zero:N \l_raman_spreadverse_width_dim
  \int_zero:N \l_raman_spreadverse_stanza_int
  \seq_set_split:Nnn \l_raman_spreadverse_stanzas_seq { \par } { #1 }
  % measure the verses
  \seq_map_inline:Nn \l_raman_spreadverse_stanzas_seq
   {
    \raman_spreadverse_measure:n { ##1 }
   }
  % typeset the verses
  \seq_map_inline:Nn \l_raman_spreadverse_stanzas_seq
   {
    \raman_spreadverse_print:n { ##1 }
    \int_incr:N \l_raman_spreadverse_stanza_int
    \nolinebreak
    \makebox[0pt][l]
     {
      \quad
      ( \int_to_arabic:n {\l_raman_spreadverse_stanza_int} )
     }
    \par
   }
 }
\cs_generate_variant:Nn \raman_spreadverse:n { V }

\cs_new_protected:Nn \raman_spreadverse_measure:n
 {
  \seq_set_split:Nnn \l_raman_spreadverse_verses_seq { \\ } { #1 }
  \seq_map_inline:Nn \l_raman_spreadverse_verses_seq
   {
    \hbox_set:Nn \l_raman_spreadverse_verse_box { ##1 }
    \dim_set:Nn \l_raman_spreadverse_width_dim
     {
      \dim_max:nn
       { \l_raman_spreadverse_width_dim }
       { \box_wd:N \l_raman_spreadverse_verse_box }
     }
   }
 }
\cs_new_protected:Nn \raman_spreadverse_print:n
 {
  \seq_clear:N \l_raman_spreadverse_printverses_seq
  \seq_set_split:Nnn \l_raman_spreadverse_verses_seq { \\ } { #1 }
  \seq_map_inline:Nn \l_raman_spreadverse_verses_seq
   {
    \seq_put_right:Nn \l_raman_spreadverse_printverses_seq
     {
      \makebox[\l_raman_spreadverse_width_dim][s]{##1}
     }
   }
  \seq_use:Nn \l_raman_spreadverse_printverses_seq { \\* }
 }
\ExplSyntaxOff

\begin{document}

\lipsum[2]

\begin{spreadverse}
Lorem ipsum dolor sit amet \\
consectetuer adipiscing elit

Ut purus elit, vestibulum ut, placerat ac \\
adipiscing vitae, felis. Curabitur dictum gravida mauris.
\end{spreadverse}

\lipsum[2]

\begin{spreadverse}[flushleft]
Lorem ipsum dolor sit amet \\
consectetuer adipiscing elit

Ut purus elit, vestibulum ut, placerat ac \\
adipiscing vitae, felis. Curabitur dictum gravida mauris.
\end{spreadverse}

\lipsum[3]

\end{document}

请注意,在此版本中,数字不参与居中(可以进行修改以便参与)。

在此处输入图片描述

答案2

在此处输入图片描述

\documentclass{article}
\renewenvironment{verse}
{\par\addvspace{10pt}\hsize12cm\parindent0pt
\parfillskip0pt
\emergencystretch\maxdimen
\def\par{\ifhmode\unskip\rlap{\quad\refstepcounter{enumi} (\theenumi)}\fi
\endgraf}%
\def\\{\endgraf}}
{\par\let\par\endgraf\addvspace{10pt}}
\begin{document}


\noindent\rule{12cm}{2pt}

\begin{verse}

    Lorem ipsum dolor sit amet\\
    consectetuer adipiscing elit

    Ut purus elit, vestibulum ut, placerat ac\\
    adipiscing vitae, felis. Curabitur dictum gravida mauris.

\end{verse}
\end{document}

相关内容