Подавить отступ после окружения в LaTeX

Я пытаюсь создать новую среду в моем документе LaTeX, где отступ в следующем абзаце после среды подавлен.

Мне сказали (источник TeXbook и LaTeX), что, установив \everypar в {\setbox0\lastbox}, наборщик TeX выполнит это в начале следующего абзаца и, таким образом, удалит отступ:

\everypar{\setbox0\lastbox}

Вот что я делаю, но безрезультатно (следующий абзац все еще с отступом):

\newenvironment{example}
  {\begin{list}
     {}
     {\setlength\leftmargin{2em}}}
  {\end{list}\everypar{\setbox0\lastbox}}

Я изучил внутреннее устройство LaTeX настолько хорошо, насколько мог. Кажется, что процедура \end в какой-то момент говорит \endgroup и \par, что может быть причиной того, что LaTeX игнорирует мои настройки \everypar. \global тоже не помогает. Я знаю о \noindent, но хочу сделать это автоматически.

Пример фрагмента документа:

This is paragraph text. This is paragraph text, too.

\begin{example}
  \item This is the first item in the list.
  \item This is the second item in the list.
\end{example}

This is more paragraph text. I don't want this indented, please.

Представляются интересующие внутренние процедуры и переключатели \@endpetrue, \@endparenv и другие. Спасибо за вашу помощь.


person glts    schedule 29.04.2010    source источник
comment
AFAIK, источник LaTeX на самом деле предоставляет крючки для решения данной проблемы. Он комментирует: Чтобы подавить отступ абзаца в тексте сразу после среды создания абзаца ... [переопределяет \everypar и \par] Это делается в \@doendpe, который будет расширен, если \@endpetrue - но безрезультатно.   -  person glts    schedule 30.04.2010


Ответы (9)


Я не мог заставить что-либо работать без переопределения \end, но я, конечно, не эксперт.

Следующее довольно хакерское, но работало в моем ограниченном тестировании. Конечно, это будет мешать работе вложенных сред (вы сможете переопределить \begin, чтобы восстановить старый \end, если у вас возникнут проблемы).

\newenvironment{example}{%
  \bgroup
  \let\oldend=\end
  \def\end##1{\oldend{##1}\csname @afterindentfalse\endcsname
                          \csname @afterheading\endcsname}
  \begin{list}{}
    {\setlength\leftmargin{2em}}
  }{%
  \end{list}
  \egroup
}
person Ivan Andrus    schedule 30.04.2010
comment
У меня не работает, извините. Я получаю несколько ошибок LaTeX: невозможно использовать \ spacefactor в вертикальном режиме, а также отсутствуют или лишние фигурные скобки и $ (хотя синтаксис моего документа в порядке). - person glts; 30.04.2010
comment
Ой, я забыл упомянуть, что он должен быть между \ makeatletter и \ makeatother. Я обновил ответ, чтобы отразить это, используя \ csname - person Ivan Andrus; 30.04.2010
comment
Ой, я забыл о \makeatletter на секунду, извините за это. Да, это решение довольно хакерское, и я должен признать, что меня беспокоит то, что я не могу найти более элегантное решение с \@doendpe и друзьями ... В любом случае, ваше решение работает, спасибо! - person glts; 01.05.2010

Разве вы не можете этого избежать, если между вашей средой и следующей строкой не будет пустой строки?

This is paragraph text. This is paragraph text, too.

\begin{example}
  \item This is the first item in the list.
  \item This is the second item in the list.
\end{example}
% (No blank line)
This is more paragraph text. I don't want this indented, please.
person Geoff    schedule 29.04.2010
comment
Конечно я могу. Но поскольку команды \section и т. Д. Могут делать то, что я ищу (без отступов в следующем абзаце, даже если между ними есть пустые строки), я надеюсь, что это можно сделать элегантным и общим способом, если несколько низкий уровень. - person glts; 30.04.2010

У меня работает такая простая вещь:

\makeatletter
\newenvironment{example}{%
  \bgroup
    \list{}{}
}{%
    \endlist
    \@afterindentfalse
    \@afterheading
  \egroup
}
\makeatother

Но это не работает до того, как будет вызван первый \ section (или \ chapter, в случае классов "book" и "report"). Не знаю почему.

person josé    schedule 02.07.2012

Я попробовал ответ Ивана, но у меня это не сработало. Но у меня все заработало! Вот что я сделал:

\makeatletter
\renewenvironment{quotation}{% 
\bgroup%
\let\oldend=\end%
\def\end##1{\oldend{##1}\csname @afterindentfalse\endcsname%
                        \csname @afterheading\endcsname}%
\list{}{\listparindent 1.5em%
\itemindent    \listparindent%
\leftmargin 1.5em%               This controls the size of the indentation
\rightmargin   \leftmargin
\parsep        \z@ \@plus\p@}%      This line reduces inter-paragraph space to normal values.
\item\relax%
}{%
\endlist%%
\egroup%
}
\makeatother

Преимущество этого заключается в том, что он очень красиво набирает ваши цитаты и удаляет отступ в абзаце после цитаты.

person Swift Arrow    schedule 05.09.2011

Вы можете сделать это, не переопределяя \end

\makeatletter
\newenvironment{example}
   {\begin{list}
      {}
      {\setlength\leftmargin{2em}}}
   {\end{list}%
    \def\if@endpe{%
      \@doendpe
      \let\par\@@par
      \iffalse}}
\makeatother

Объяснение

\end изменяется \everypar после раскрытия \endexample. Чтобы еще больше усложнить задачу, он устанавливает \par на восстановление \everypar{}. По-видимому, \@doendpe предназначен для того, чтобы убедиться, что нет отступа, если абзац продолжается после окружения, но для восстановления нормального поведения, если после окружения есть \par (или пустая строка).

Возможно, вы захотите избежать изменения \end, потому что это должно быть изменено в начале среды и, следовательно, может нарушить работу вложенных сред. К счастью, определение \end содержит \expandafter\endgroup\if@endpe. Мы можем использовать \if@endpe как ловушку для внедрения нашего кода во внешнюю область видимости. После \endgroup \if@endpe автоматически восстанавливается.

person Leonard Michlmayr    schedule 16.10.2017

Включите \ @afterindentfalse \ @afterheading в конце вашего определения.

person Community    schedule 09.06.2010

У меня такая же проблема. Я просто использовал это:

\noindent \newenvironment
person user6240730    schedule 22.04.2016

Не стоит связываться со списком токенов \everypar, если вы точно не знаете, что делаете. Использовать

\setlength{\parindent}{0pt}

чтобы избавиться от отступов во всем документе.

person topskip    schedule 29.04.2010
comment
Я бы хотел избавиться от отступов только после некоторого окружения. Поскольку обычный tex, очевидно, может это делать (см. TeXbook, стр. 10), LaTeX тоже должен. - person glts; 30.04.2010

завершение вашего окружения с помощью \ noindent может вам помочь

person Peter Pall    schedule 07.08.2011
comment
Возможно, вы захотите не давать простых ответов на вопросы годичной давности, человек, вероятно, ушел. - person Codeguy007; 15.11.2012
comment
Кроме того, это кажется более подходящим в качестве комментария, а не ответа. - person Eudis Duran; 15.11.2012