基于 Enumitem 的描述中标签宽度自动计算环境不能嵌套

基于 Enumitem 的描述中标签宽度自动计算环境不能嵌套

使用边距 埃格尔提出了以下环境来收集description-label 的最大宽度。不幸的是,此代码仅在环境未嵌套时才有效xdesc。如果嵌套(见下文),代码将返回

LaTeX 错误:出现问题 - 也许缺少 \item。

以下是该代码的嵌套版本:

\documentclass[12pt]{article}
\usepackage[a4paper, margin=2cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[shortlabels]{enumitem}
\usepackage[spanish]{babel}

\newlength{\xdescwd}
\usepackage{environ}
\makeatletter
\NewEnviron{xdesc}{%
  \vbox{\hbadness=\@M \global\xdescwd=0pt
    \def\item[##1]{%
      \settowidth\@tempdima{\textbf{##1}:}%
      \ifdim\@tempdima>\xdescwd \global\xdescwd=\@tempdima\fi}
  \BODY}
  \begin{description}[leftmargin=\dimexpr\xdescwd+.5em\relax,
    labelindent=0pt,labelsep=.5em,
    labelwidth=\xdescwd,align=left]\BODY\end{description}}
\makeatother

\begin{document}

En un contexto determinado, las palabras poseen, además de su
significado literal, también una dimensión intencional. Un texto es la
manifestación lingüística de la intención del emisor dirigida a un
receptor. Si consideramos, pues, los actos ilocutivos implicados, un
texto cumplirá funciones diferentes.

La función textual es el efecto de los textos en una situación
comunicativa según los objetivos que queremos alcanzar. Un texto puede
desempeñar las siguientes funciones:

\begin{xdesc}
\item[Representativa:] llamada también asertiva, cuando se afirma o se 
    \begin{xdesc}
    \item[Prescriptiva:] cuando se establecen normas. anuncia algo que se
                      considera verdadero.
    \end{xdesc}     
\item[Informativa:] cuando se presenta algo de manera neutra, sin
     énfasis que pueda denotar emotividad, como por ejemplo un titular
     de una noticia.
\item[Prescriptiva:] cuando se establecen normas. En la legislación, por
     ejemplo, se emplean formas modales deónticas (deber + infinitivo)
\item[Persuasiva:] cuando se trata de convencer al interlocutor
\item[Comisiva:] cuando se promete, jura, ofrece, etc.
\item[Fática:] cuando el emisor se centra en el interlocutor y procura
               mantener el contacto con él, como por ejemplo “Oye…”
\item[Expresiva:] cuando el emisor se alegra, agradece, felicita.
\end{xdesc}

\end{document}     

除此之外,即使是原始代码也会产生环境上方项目文本的奇怪重复xdesc

使用 pdflatex 编译的 egreg 的两遍代码

由于我真的很想在自己的环境中实现 egreg 代码的想法,因此任何形式的帮助都将不胜感激。

[更新 2016/12/04] 这是我关于以下问题的答案的补充埃格尔安德鲁以下:

不幸的是,在进一步的野外测试后,出现了以下问题:egregxdesc破坏了与正常enumerate环境的兼容性。在正常环境中,可能存在没有任何文本的 \items。但在xdesc无文本项目中会消失。(Andrew 的代码也是如此。)我尝试了一些修改,但没有成功。所以我不知道如何防止xdesc吃掉无文本项目。由于我需要枚举的功能,因此欢迎任何帮助。这是一个 MWE:

\documentclass[12pt]{article}
\usepackage[a4paper, margin=2cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[spanish]{babel}
\usepackage{enumitem}

\newlength{\xdescwd}
\usepackage{environ}
\makeatletter%
\NewEnviron{xdesc}{% I only changed "description" to "enumerate"
               % and did some formatting
              \setbox0=\vbox{%
                             \hbadness=\@M \global\xdescwd=0pt
                             \RenewEnviron{xdesc}{}%
                             \def\item[##1]{%
                             \settowidth\@tempdima{##1}%
                             \ifdim\@tempdima>\xdescwd \global\xdescwd=\@tempdima\fi}
                             \BODY%
                             }%
               \begin{enumerate}[leftmargin=\dimexpr\xdescwd+.5em\relax,
                                labelindent=0pt,labelsep=.5em,
                                labelwidth=\xdescwd,align=left]
               \BODY%
               \end{enumerate}%
               }
\makeatother

\begin{document}
\parindent0pt
Here is what \textbf{enumerate} does:

\begin{enumerate}
\item[(DF)] %llamada también asertiva, cuando se afirma o se

        \begin{enumerate}
        \item[(1)] cuando se establecen normas. anuncia algo que se
                    considera verdadero.
        \item[(1a)] cuando se establecen normas. anuncia algo que se
                    considera verdadero.
        \end{enumerate}
\end{enumerate}

Here is what \textbf{xdesc} does:

\begin{xdesc}
\item[(DF)] %llamada también asertiva, cuando se afirma o se

        \begin{xdesc}
        \item[(1)] cuando se establecen normas. anuncia algo que se
                    considera verdadero.
        \item[(1a)] cuando se establecen normas. anuncia algo que se
                    considera verdadero.
        \end{xdesc}
\end{xdesc}
\end{document}

输出如下:

enumerate 和 xdesc 的输出

[2016/12/04 更新结束]

答案1

这似乎有效:

\documentclass[12pt]{article}
\usepackage[a4paper, margin=2cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[spanish]{babel}
\usepackage{enumitem}

\newlength{\xdescwd}
\usepackage{environ}
\makeatletter
\NewEnviron{xdesc}{%
  \setbox0=\vbox{\hbadness=\@M \global\xdescwd=0pt
    \RenewEnviron{xdesc}{}%
    \def\item[##1]{%
      \settowidth\@tempdima{\textbf{##1}:}%
      \ifdim\@tempdima>\xdescwd \global\xdescwd=\@tempdima\fi}
  \BODY}
  \begin{description}[leftmargin=\dimexpr\xdescwd+.5em\relax,
    labelindent=0pt,labelsep=.5em,
    labelwidth=\xdescwd,align=left]\BODY\end{description}}
\makeatother

\begin{document}

En un contexto determinado, las palabras poseen, además de su
significado literal, también una dimensión intencional. Un texto es la
manifestación lingüística de la intención del emisor dirigida a un
receptor. Si consideramos, pues, los actos ilocutivos implicados, un
texto cumplirá funciones diferentes.

La función textual es el efecto de los textos en una situación
comunicativa según los objetivos que queremos alcanzar. Un texto puede
desempeñar las siguientes funciones:

\begin{xdesc}
\item[Representativa:] llamada también asertiva, cuando se afirma o se 
    \begin{xdesc}
    \item[Prescriptiva:] cuando se establecen normas. anuncia algo que se
                      considera verdadero.
    \item[Prescriptivaaaa:] cuando se establecen normas. anuncia algo que se
                      considera verdadero.
    \end{xdesc}    
\item[Informativa:] cuando se presenta algo de manera neutra, sin
     énfasis que pueda denotar emotividad, como por ejemplo un titular
     de una noticia.
\item[Prescriptiva:] cuando se establecen normas. En la legislación, por
     ejemplo, se emplean formas modales deónticas (deber + infinitivo)
\item[Persuasiva:] cuando se trata de convencer al interlocutor
\item[Comisiva:] cuando se promete, jura, ofrece, etc.
\item[Fática:] cuando el emisor se centra en el interlocutor y procura
               mantener el contacto con él, como por ejemplo “Oye…”
\item[Expresiva:] cuando el emisor se alegra, agradece, felicita.
\end{xdesc}

\end{document}

\vbox设置为测量时,xdesc被重新定义为不执行任何操作。

在此处输入图片描述

答案2

这里实际上有两个问题。首先,您需要修复缺失项目错误;其次,我认为您希望每个嵌套级别的最大标签宽度不同,因此您需要跟踪嵌套级别。

\item\setitemwidth我通过第一次设置然后直接\BODY将其重置为原始命令来修复缺少项目错误\item

对于嵌套问题,描述环境用于\@listdepth跟踪此问题,但我们不能使用它,因为我们在进入环境之前计算最宽的标签description,所以我添加了一个计数器xdescdepth来跟踪此问题。然后我将标签宽度存储在中widest<xdescepth>

\documentclass{article}
\usepackage{mathtools}
\usepackage{enumitem}
\usepackage{etoolbox}
\usepackage{environ}

\newdimen\widest
\newcounter{xdescdepth}
\makeatletter
\def\setitemwidth[#1]{% compute maximum width of labels for nesting depth
    \settowidth\@tempdima{\textbf{#1}}%
    \ifdim\@tempdima>\csuse{widest\thexdescdepth}%
       \csdimgdef{widest\thexdescdepth}{\@tempdima}%
    \fi%
}
\let\realitem\item% save the real \item command
\NewEnviron{xdesc}{%
  \addtocounter{xdescdepth}{1}% increment nesting depth
  % initialise label width to 0pt at the start of each nesting level
  \ifcsdef{widest\thexdescdepth}{\relax}%
          {\csdef{widest\thexdescdepth}{0pt}}%
  \let\item\setitemwidth% temporarily override \item
  \setbox0=\vbox{\BODY}% compute label widths without printing anything
  \let\item\realitem% reset \item
  \widest=\dimexpr\csuse{widest\thexdescdepth}\relax%
  \description[
    leftmargin=\dimexpr\widest+0.5em\relax,
    labelindent=0pt,
    labelwidth=\widest
    ]
    \BODY
  \enddescription%
  \addtocounter{xdescdepth}{-1}% decrement nesting depth
}
\makeatother

\begin{document}

  \begin{xdesc}
  \item[Representativa:] llamada también asertiva, cuando se afirma o se
      \begin{xdesc}
      \item[Prescriptiva:] cuando se establecen normas. anuncia algo que se
                        considera verdadero.
      \end{xdesc}
  \item[Informativa:] cuando se presenta algo de manera neutra, sin
       énfasis que pueda denotar emotividad, como por ejemplo un titular
       de una noticia.
  \item[Prescriptiva:] cuando se establecen normas. En la legislación, por
       ejemplo, se emplean formas modales deónticas (deber + infinitivo)
  \item[Persuasiva:] cuando se trata de convencer al interlocutor
  \item[Comisiva:] cuando se promete, jura, ofrece, etc.
      \begin{xdesc}
      \item[Prescrip] cuando se establecen normas. anuncia algo que se
                        considera verdadero.
      \end{xdesc}
  \item[Fática:] cuando el emisor se centra en el interlocutor y procura
                 mantener el contacto con él, como por ejemplo “Oye…”
  \item[Expresiva:] cuando el emisor se alegra, agradece, felicita.
  \end{xdesc}

\end{document}

输出如下:

在此处输入图片描述

相关内容