
Ich arbeite in einer zweispaltigen Umgebung mit mehreren Spalten und versuche, Zitate mit Wrapfig zu erstellen. Das Problem ist, dass ich möchte, dass diese Zitate am Rand hängen: am linken Rand, wenn ich in der linken Spalte bin, am rechten Rand, wenn ich in der rechten bin.
Gibt es eine Möglichkeit, die aktuelle Spaltennummer zu ermitteln, sodass ich wrapfig mitteilen kann: „Hänge die Zahl links, wenn Spaltennummer = 1, und rechts, wenn Spaltennummer = 2“? Ich habe viel Text dieser Art und es wäre ziemlich mühsam, dies alles von Hand festzulegen.
Ich habe versucht, dies zu verwendenPullquote-Paket, aber bisher habe ich nur eine Menge Mikrotypfehler bekommen (ich verwende XeLaTeX).
Bearbeiten: Eine Art MWE würde so aussehen, das \imaginarycolumnnumberidentifier
ist offensichtlich das, wonach ich suche. Dies ist eindeutig kein „funktionierendes“ Beispiel, und ich habe noch nie versucht, etoolbox zu verwenden, daher könnte es andere Probleme mit diesem Code geben, aber Sie verstehen, was ich meine.
\documentclass{article}
\usepackage{multicol}
\usepackage{wrapfig}
\usepackage{lipsum}
\usepackage{etoolbox}
\newenvironment{pquote}{%
\begin{wrapfigure}[3]{%
\ifnumequal{1}{\imaginarycolumnnumberidentifier}{l}{r}%
}[0.2\columnwith]{0.4\columnwidth}
}{%
\end{wrapfigure}}
\begin{document}
\begin{multicols}{2}
\lipsum[1]
\begin{pquote}
Lorem ipsum!
\end{pquote}
\lipsum[2]
\begin{pquote}
dolor sit amet!
\end{pquote}
\lipsum[3]
\end{multicols}
\end{document}
Ich habe nicht genug Reputation, um ein Bild zu posten, also müssen Sie sich das Ergebnis einfach vorstellen! Vertrauen Sie mir, das erste Zitat ist auf der linken Seite und das zweite Zitat ist auf der rechten Seite. In meiner Vorstellung.
Antwort1
Ich zeige Ihnen, wie Sie dies für twocolumn
Layouts und nicht über das multicol
Paket implementieren. Dadurch werden einige Ihrer Codierungsprobleme behoben.
\documentclass[twocolumn]{article}
\usepackage{wrapfig}
\usepackage{lipsum}
\makeatletter
\newenvironment{pquote}[1][\relax]{%
\ifx#1\relax\def\@mypl{\if@firstcolumn l\else r\fi}%
\else\def\@mypl{#1}\fi%
\wrapfigure[3]{\@mypl}[0.2\columnwidth]{0.4\columnwidth}%
\large\bfseries}{\par\endwrapfigure}
\makeatother
\begin{document}
\lipsum[1]
\begin{pquote}
Lorem ipsum!
\end{pquote}
\lipsum[2-4]
\begin{pquote}
Dolor sit amet!
\end{pquote}
\lipsum[5-8]
\begin{pquote}[r]
Mauris ut est.
\end{pquote}
\lipsum[9]
\end{document}
Ihre allgemeine Methode, pquote
eine Variation von wrapfigure
using festzulegen \begin{wrapfigure}
, funktioniert leider nicht, wie Sie sehen werden, wenn Sie ein einfaches Testdokument mit fester Positionierung erstellen. Dies hat etwas mit der Art und Weise zu tun, wie die Argumente verarbeitet werden. Verwenden Sie stattdessen \wrapfigure
mit den entsprechenden Argumenten und gleichen Sie es mit aus \endwrapfigure
. Darüber hinaus muss das Positionierungsargument direkt in eine der zulässigen Zeichenfolgen erweitert werden, sodass dies über ein Zwischenmakro erfolgen sollte.
Damit twocolumn
haben wir nun den Test \if@firstcolumn
, mit dem die Positionierung bestimmt werden kann. Leider ist er nicht 100% narrensicher, daher bietet meine obige Definition ein optionales Argument, mit dem Sie die Positionierung erzwingen können.
In multicols
ist die Sache etwas komplizierter, und ich sehe keine leicht zugängliche Variable, um dies zu tun. multicol
Setzt das Material im Wesentlichen in eine lange Box und teilt dann für jede Spalte die richtige Menge von oben ab. Es gibt einige interne Variablen, die die Spaltenanzahl zählen, aber sie sind nicht leicht zugänglich. Außerdem multicol
gleicht es die Spalten aus, indem es versucht, das gegebene gesetzte Material in eine Anzahl gleich hoher Boxen aufzuteilen. Wenn sich der Satz dabei ändern soll, ist dies komplizierter. Ein Symptom dafür ist, dass \marginpar
s in nicht zulässig sind multicols
, siehe die Paketdokumentation, während in twocolumn
margin pars (ziemlich) gut funktionieren und die Seiten nach Bedarf wechseln.
ZUSATZals Antwort auf den Kommentar:
Wenn Sie die Platzierung verwenden möchten multicols
und bereit sind, diese anzugeben, ist die Codierung einfacher, Sie müssen jedoch dennoch Folgendes vermeiden \begin{wrapfigure}
:
\documentclass{article}
\usepackage{multicol,ragged2e}
\usepackage{wrapfig}
\usepackage{lipsum}
\makeatletter
\newenvironment{pquote}[2]{%
\wrapfigure[#1]{#2}[0.2\columnwidth]{0.4\columnwidth}%
\large\bfseries\Centering}{\par\endwrapfigure}
\makeatother
\begin{document}
\begin{multicols}{2}
\lipsum[1]
\begin{pquote}{4}{l}
Lorem ipsum!
\end{pquote}
\lipsum[2-4]
\begin{pquote}{6}{r}
Dolor sit amet!
\end{pquote}
\lipsum[5-8]
\begin{pquote}{5}{r}
Mauris ut est.
\end{pquote}
\lipsum[9]
\end{multicols}
\end{document}
Antwort2
Wie Andrew in seiner Antwort bemerkte, ist eine Lösung für mehrere Spalten etwas komplizierter, da die „aktuelle“ Spalte beim Satz überhaupt nicht bekannt ist. Daher ist ein ziemlich komplizierter Ansatz mit mehreren Satzläufen (unter Verwendung der .aux
Datei) erforderlich.
Nachfolgend sehen Sie einen ersten Lösungsentwurf, der es ermöglicht, \docolaction{left}{middle}{right}
bedingten Code abhängig vom Spaltentyp auszuführen. Wenn der Spaltentyp noch nicht bekannt ist, wird die erste Spalte angenommen (als Standard).
\begin{filecontents}{mccolaction.sty}
%
% \begin{macrocode}
\ProvidesPackage{mccolaction}
[2013/05/05 v0.9b column actions for multicolumn formatting (FMi)]
% \end{macrocode}
%
% \begin{macrocode}
\RequirePackage{etoolbox}
\RequirePackage{multicol}[2011/12/20]
% \end{macrocode}
%
% Determining the current column in multicols is difficult because
% (in contrast to the twocolumn mode of standard LaTeX) the
% multicols columns are determined very late in the game and due to
% the balancing routine it is not known where a piece of text is
% going to end up at the time the text is typeset. Only afterwards,
% when everything has be typeset into a single long galley, that
% galley is split into individual columns (at the very end in a
% possibly huge set of trials to balance the column material.
%
% Therefore the approach taken here is to write out a single line
% into the .aux file whenever a column is finally typeset:
%\begin{verbatim}
% \mc@col@status{<number>}
%\end{verbatim}
% The number in the argument denotes the different kind of column: 1
% for left column 2 for any middle column and 3 for the final column.
%
% We only set this up for the LR typesetting case here, something
% similar could be done for the RL version:
% \begin{macrocode}
\patchcmd{\LR@column@boxes}{\box\count@}
{\protected@write\@auxout{}{\string\mc@col@status
{\ifmc@firstcol 1\else 2\fi}}%
\mc@firstcolfalse
\box\count@}
{\typeout{juhu!}}{\typeout{oje!}}%
\patchcmd{\LR@column@boxes}{\box\mult@rightbox}
{\protected@write\@auxout{}{\string\mc@col@status{3}}%
\box\mult@rightbox}%
{\typeout{juhu!}}{\typeout{oje!}}%
\newif\ifmc@firstcol
\mc@firstcoltrue
% \end{macrocode}
%
% Need to reinitiate \verb=\mc@align@columns= as this was let to
% the old definition of \verb=\LR@column@boxes=.
%
% \begin{macrocode}
\LRmulticolcolumns
% Whenever we want to do something that depends on the current
% column we execute \verb=\docolaction=. This command takes one
% optional and three mandatory arguments. The mandatory ones denote
% what to do if this is a ``left'', ``middle'', or ``right'' column
% and the optional one is simply there to say what to do if we don't
% know (default is to use the ``left'' column action in that case).
%
% We use one counter \verb=\mc@col@check@num= to generate us unique
% label names. Each time we execute \verb=\docolaction= we increment
% this counter to get a new name.
% \begin{macrocode}
\newcount\mc@col@check@num
% \end{macrocode}
% The generated ``labels'' are named
% \verb=\mc@col-\the\mc@col@check@num= and they hold as values the
% numbers 1, 2, or 3 denoting the current column type.
% \begin{macrocode}
\newcommand\docolaction[4][1]{%
\global\advance\mc@col@check@num\@ne
\edef\mc@col@type{\expandafter\ifx
\csname mc@col-\the\mc@col@check@num\endcsname\relax
0\else
\csname mc@col-\the\mc@col@check@num\endcsname
\fi}%
% \end{macrocode}
% We prefix with 0 so that an unknown label (that returns
% \verb=\relax=) will result in case 0
% \begin{macrocode}
\ifcase \mc@col@type\relax
% \end{macrocode}
% If column is unknown we use the default action or the action
% denoted by the optional argument (so that arg can take the value
% 1, 2, 3)
% \begin{macrocode}
\ifcase #1\or #2\or#3\or#4\fi % 0 not known use first col as default
\or
% \end{macrocode}
% Otherwise we know (or think we know) that this is a first, middle,
% or last column:
% \begin{macrocode}
#2% % 1 First col
\or
#3% % 2 any middle col
\or
#4% % 3 last col
\else
\ERROR
\fi
% \end{macrocode}
% But how does the column number get associated with our label? We
% do do this by writing another line into the aux file at this point:
% \begin{macrocode}
\edef\next{\write\@auxout
{\string\mc@set@col@status{mc@col-\the\mc@col@check@num}%
{\mc@col@type}}}%
\next
}
% \end{macrocode}
%
% Because of extra data writing to the aux file the aux file will
% now contain something like the following after the document is
% processed the first time:
%\begin{verbatim}
%\relax
%\mc@col@status{1}
%\mc@set@col@status{lcol-1}{0}
%\mc@col@status{2}
%\mc@set@col@status{lcol-2}{0}
%\mc@col@status{3}
%\mc@set@col@status{lcol-3}{0}
%\mc@col@status{1}
%\mc@col@status{2}
%\mc@col@status{3}
%\mc@set@col@status{lcol-4}{0}
%\end{verbatim}
% The \verb=\mc@col@status= line denotes the column type and has been
% writting out just before corresponding the column box was placed
% onto the page.
% The\verb=\mc@set@col@status= lines have been written out as part
% of shipping the column boxes out, e.g.,
% \verb=\mc@set@col@status{lcol-1}{0}= was therefore somewhere within
% the first column as it appears between \verb=\mc@col@status{1}=
% and \verb=\mc@col@status{2}=
% The second argument in that line is the value used in the previous
% run (or zero if there was no previous run. We can use this to
% determine if a rerun is necessary.
%
% Thus with this knowledge we can set things up to get the labels
% working.
%
% When the aux file is read in \verb=\mc@col@status= is used to set
% \verb=\mc@curr@col@status=:
%
% \begin{macrocode}
\def\mc@col@status#1{\gdef\mc@curr@col@status{#1}}
% \end{macrocode}
% And when \verb=\mc@set@col@status= is executed we can simply set
% up the label by associating it with the \verb=\mc@curr@col@status=
% and ignore the second argument:
% \begin{macrocode}
\def\mc@set@col@status#1#2{%
\global\expandafter\let\csname #1\endcsname\mc@curr@col@status}
% \end{macrocode}
%
% The above definition is being used when the \texttt{.aux} file is
% read in at the beginning. At the end we need a different
% definition to test if another typesetting run is needed. There we
% compare the value used in the current run (stored in the second
% argument) with the value used on the next run. If those two values
% differ we set \verb=@tempswa= to false which will trigger the
% ``Label(s) may have changed'' warning.
% \begin{macrocode}
\AtEndDocument{\def\mc@set@col@status#1#2{%
\ifnum #2=\mc@curr@col@status\else
\@tempswatrue
\fi}%
}
% \end{macrocode}
\end{filecontents}
\documentclass{article}
\usepackage{mccolaction}
\usepackage{wrapfig}
\usepackage{lipsum}
% An application of \docolaction. We put the whole wrapfigure into the
% args so that the internal label used is placed after wrapfigure.
\newcommand\pquote[2]{%
\docolaction
{\begin{wrapfigure}[#1]{l}[0.2\columnwidth]{0.4\columnwidth}%
\raggedright\large\bfseries #2\end{wrapfigure}}%
{\begin{wrapfigure}[#1]{l}[0pt]{0.4\columnwidth}%
\raggedright\large\bfseries #2\end{wrapfigure}}%
{\begin{wrapfigure}[#1]{r}[0.2\columnwidth]{0.4\columnwidth}%
\raggedright\large\bfseries #2\end{wrapfigure}}%
\ignorespaces
}
\setlength\columnseprule{.7pt}
\setlength\emergencystretch{2em}
\begin{document}
\begin{multicols}{3}
\lipsum[1]
\pquote{4}{Lorem ipsum!}
\lipsum[2]
\pquote{5}{Dolor sit amet!}
\lipsum[4-5]
\pquote{4}{Mauris ut est.}
\lipsum[6-7]
Only a few words left \ldots
Here the pquote comes in the middle of the paragraph for a change
\pquote{6}{Final test related to the edge}
as we can see. Only a few words left so this drops off the column \ldots
\end{multicols}
\end{document}
Wenn wir diese Datei ausführen, erhalten wir
Auf der zweiten Seite sieht man dann, dass nicht alles perfekt sein wird, was in diesem Fall aber daran liegt, dass ich es bewusst \pquote
zu weit hinten platziert habe.
Wenn wir die Datei so ändern, dass sie 4 Spalten verwendet, erhalten wir am Ende eine Wrapfigure, die sich über mehrere Spalten erstreckt. Dies ist offensichtlich ein Problem, bei dem die beiden Pakete nicht gut genug zusammenarbeiten, um dieses Problem automatisch zu lösen.
Zusammenfassend würde ich sagen, dass es ganz gut funktioniert. In Kombination mit etwas Ähnlichem wrapfigure
wird es an manchen Stellen etwas Hilfe brauchen, aber das ist zu erwarten, da ich wrapfigure
keine Ahnung davon habe, wie mehrere Spalten die Spalten später aufteilen.
Aktualisieren
Ich habe den Code leicht verbessert, so dass er nun auch Änderungen in den Spaltentypen verfolgt. Wenn dadurch die Notwendigkeit eines weiteren LaTeX-Laufs erkannt wird, wird die bekannte Warnung „Label(s) haben sich möglicherweise geändert. Führen Sie den Vorgang erneut aus, um die Querverweise richtig zu machen.“ ausgegeben.
Daher sollte eine Ausgabe wie die folgende nur erfolgen, wenn der Benutzer diese Warnung ignoriert.
Aktualisierung II
Die obige Version mccolaction
wurde gegen die SVN-Version geschrieben, die derzeit nicht auf CTAN verfügbar ist. Als AntwortSpaltenumbruch nur innerhalb der ersten Spalte von MulticolIch habe ein aktualisiertes Paket bereitgestellt, das mit beiden Versionen von funktioniert multicol
.
Aktualisierung III
Die oben beschriebene Funktionalität ist jetzt in Multicol Version 1.8 und höher verfügbar. Sie ist nicht automatisch aktiviert (da sie kostspielig ist) – Sie müssen sie mit der Option anfordern colaction
. Anschließend \docolaction
ist sie für die Verwendung in Ihrem Dokument aktiviert.