Sie sind hier

Optionales Argument von addmargin

In folgendem Minimalbeispiel wird der von align gesetzte Text in der ersten addmargin-Umgebung horizontal falsch gesetzt.

Liegt die Ursache in der Umgebung, oder in \intertext von amsmath?

\documentclass{article}
\usepackage{blindtext}
\usepackage{scrextend}
\usepackage{mathtools}
\usepackage{showframe}
\begin{document}
\begin{addmargin}[3cm]{-3cm}
	\begin{align}
		\intertext{Dies ist Text}
	\end{align}
	\rule{\linewidth}{1pt}
\end{addmargin}
\begin{addmargin}[-2cm]{-3cm}
	\begin{align}
		\intertext{Dies ist Text}
	\end{align}
	\rule{\linewidth}{1pt}
\end{addmargin}
\begin{addmargin}{3cm}
	\begin{align}
		\intertext{Dies ist Text}
	\end{align}
	\rule{\linewidth}{1pt}
\end{addmargin}
\begin{addmargin}{-3cm}
	\begin{align}
		\intertext{Dies ist Text}
	\end{align}
	\rule{\linewidth}{1pt}
\end{addmargin}
\end{document}
scrextend.sty    2015/05/19 v3.18.2106 KOMA-Script package (extend other classe
s with features of KOMA-Script classes)
Bild von Markus Kohm

Wobei die noch bessere Frage ist, warum

\documentclass{article}
\usepackage{blindtext}
\usepackage{scrextend}
\usepackage{mathtools}
\usepackage{showframe}
\begin{document}
\begin{addmargin}[3cm]{-2.999992cm}
	\rule{\linewidth}{1pt}
	\begin{align}
		\intertext{Dies ist Text}
	\end{align}
	\rule{\linewidth}{1pt}
\end{addmargin}
\begin{addmargin}{3cm}
	\rule{\linewidth}{1pt}
	\begin{align}
		\intertext{Dies ist Text}
	\end{align}
	\rule{\linewidth}{1pt}
\end{addmargin}
\end{document}

funktioniert, während

\documentclass{article}
\usepackage{blindtext}
\usepackage{scrextend}
\usepackage{mathtools}
\usepackage{showframe}
\begin{document}
\begin{addmargin}[3cm]{-2.999993cm}
	\rule{\linewidth}{1pt}
	\begin{align}
		\intertext{Dies ist Text}
	\end{align}
	\rule{\linewidth}{1pt}
\end{addmargin}
\begin{addmargin}{3cm}
	\rule{\linewidth}{1pt}
	\begin{align}
		\intertext{Dies ist Text}
	\end{align}
	\rule{\linewidth}{1pt}
\end{addmargin}
\end{document}

nicht funktioniert. Und

\documentclass{article}
\usepackage{blindtext}
\usepackage{scrextend}
\usepackage{mathtools}
\usepackage{showframe}
\begin{document}
\begin{addmargin}[3cm]{-3.000008cm}
	\rule{\linewidth}{1pt}
	\begin{align}
		\intertext{Dies ist Text}
	\end{align}
	\rule{\linewidth}{1pt}
\end{addmargin}
\begin{addmargin}{3cm}
	\rule{\linewidth}{1pt}
	\begin{align}
		\intertext{Dies ist Text}
	\end{align}
	\rule{\linewidth}{1pt}
\end{addmargin}
\end{document}

wieder funktioniert. Es scheint genau dann schief zu gehen, wenn die Umgebung im Endeffekt die Textbreite nicht ändert.

Interessant auch, dass echte Formeln entsprechend der addmargin-Umgebung platziert werden. Es betrifft nur \intertext. Wenn wir uns nun dessen Definition anschauen:

\def\intertext@{%
  \def\intertext##1{%
    \ifvmode\else\\\@empty\fi
    \noalign{%
      \penalty\postdisplaypenalty\vskip\belowdisplayskip
      \vbox{\normalbaselines
        \ifdim\linewidth=\columnwidth
        \else \parshape\@ne \@totalleftmargin \linewidth
        \fi
        \noindent##1\par}%
      \penalty\predisplaypenalty\vskip\abovedisplayskip%
    }%
}}

dann finden wir in der Tat, dass da geprüft wird, ob die aktuelle Zeilenbreite der Spaltenbreite entspricht. In genau diesem Fall wird nicht mit \parshape gearbeitet, wohl weil davon ausgegangen wird, dass in dem Fall die Ränder unverändert sind. Entfernt man diese Optimierung:

\documentclass{article}
\usepackage{blindtext}
\usepackage{scrextend}
\usepackage{mathtools}
\usepackage{showframe}
\makeatletter
\def\intertext@{%
  \def\intertext##1{%
    \ifvmode\else\\\@empty\fi
    \noalign{%
      \penalty\postdisplaypenalty\vskip\belowdisplayskip
      \vbox{\normalbaselines
%        \ifdim\linewidth=\columnwidth
%        \else 
        \parshape\@ne \@totalleftmargin \linewidth
%        \fi
        \noindent##1\par}%
      \penalty\predisplaypenalty\vskip\abovedisplayskip%
    }%
}}
\makeatother
\begin{document}
\noindent\rule{\linewidth}{1pt}
\begin{align}
  a &= b\\
  \intertext{Dies ist Text mit linewidth=\the\linewidth,
    columnwidth=\the\columnwidth}
\end{align}
\rule{\linewidth}{1pt}
\begin{addmargin}[3cm]{-3.000007cm}
  \rule{\linewidth}{1pt}
  \begin{align}
    a &= b\\
    \intertext{Dies ist Text mit linewidth=\the\linewidth,
      columnwidth=\the\columnwidth}
  \end{align}
  \rule{\linewidth}{1pt}
\end{addmargin}
\begin{addmargin}[3cm]{-3.000008cm}
  \rule{\linewidth}{1pt}
  \begin{align}
    a &= b\\
    \intertext{Dies ist Text mit linewidth=\the\linewidth,
      columnwidth=\the\columnwidth}
  \end{align}
  \rule{\linewidth}{1pt}
\end{addmargin}
\end{document}

scheint alles zu funktionieren.
Allerdings heißt es in den Quellen von amsmath:

Frank Mittelbach, Rainer Schöpf, Michael Downes und
David M. Jones schrieben:

We need to do something extra if the outside environment is a list environment. I don't see offhand an elegant way to test "are we inside any list environment'' that is both easy and reliable (for example, checking for zero \@totalleftmargin wouldn't catch the case where \@totalleftmargin is zero but \linewidth is less than \columnwidth), so it seems to me checking \linewidth is the best practical solution.

Daher könnte es sein, dass obige Lösung in manchen Situationen nicht ideal ist. Es erklärt aber auch, wie das Problem entsteht: amsmath nimmt tatsächlich an, dass in Listenumgebungen \linewidth immer von \columnwidth abweicht, was aber keineswegs zwingend ist. Es liegt also an der Implementierung von \intertext bzw. der unzureichenden Erkennung von Listen-Umgebungen darin.

Wow, da hängt ja ein ganzer Rattenschwanz dran. Ein Bug in KOMA-script wäre mir lieber gewesen, den könnte man leichter fixen.

Vielen Dank, dass du dir das angeschaut hast. Ich werde einen Fehlerbericht mit deiner Analyse and Barabara Beeton und das Team von mathtools weiterleiten. Vielleicht haben Joseph oder Lars eine bahnbrechende Idee.

Bild von Markus Kohm

Wenn die Änderung aus meinem Beispiel tatsächlich keine Lösung sein sollte, könnte man eventuell auch wirklich auf \@totalleftmargin>0 und \linewidth!=\columnwidth testen und eine Liste daran erkennen, dass min. eines von beiden zutrifft.

Wobei ich inzwischen stark davon ausgehe, dass mein Patch auch außerhalb von Listen funktioniert, weil die \parshape-Anweisung dann quasi keine Wirkung hat.

Lars Madsen und David Carlisle haben im TeX-Chat bei Stackexchange über die Lösung des Problems diskutiert (Transkript-Link).

Ein Update mit dem Fix zu obigem Problem ist ab demnächst auf CTAN verfügbar.

Comments for "Optionales Argument von addmargin" abonnieren