\marginparsep
仅增加偶数页的有效性的最有效方法是什么?
我一直在研究缩进列表、章节标题等,这导致了边注问题:我需要增加\marginparsep
偶数页的有效页数以允许缩进。由于这是一个长度,我不能简单地包含一个宏,例如 KOMA 的\ifthispageodd
。
如果可能的话,我想要一个可以与标准\marginpar
以及marginnote
类似的软件包兼容的解决方案。
更新:
Werner 的以下回答几乎解决了该问题,但有一个错误与 修复的错误密切相关mparhack
。此 MWE 演示了该问题:
\documentclass[twoside]{scrbook}
\usepackage{etoolbox}
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\usepackage{everyshi}% http://ctan.org/pkg/everyshi
\usepackage{xifthen}% http://ctan.org/pkg/xifthen
\usepackage{mparhack}
\begin{document}
\EveryShipout{%
\ifthenelse{\isodd{\value{page}}}%
{\global\marginparsep=22pt}% Next page is even
{\global\marginparsep=11pt}% Next page is odd
}
\lipsum[1]
\marginpar[This is a paragraph in the left margin]{This is a paragraph in the right margin}
\lipsum[2]
\begin{itemize}
\def\do#1{\item This is a line #1 and should have a note with the same
number:\marginpar{Note #1 and a bit.}}
\docsvlist{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
\end{itemize}
\lipsum[3-5]
\marginpar[This is a paragraph in the left margin]{This is a paragraph in the right margin}
\lipsum[6-8]
\marginpar[This is a paragraph in the left margin]{This is a paragraph in the right margin}
\lipsum[9-10]
\end{document}
第二页顶部的第 17 条注释没有得到正确的调整。如果mparhack
不使用该软件包,则此注释也会出现在页面的错误一侧,因此完整的解决方案可能涉及以某种方式应用类似的补丁。有没有简单的方法可以做到这一点?
答案1
我认为在 shipout 时访问页码已经足够强大了。为此,请使用everyshi
包裹。以下是一次小型试运行:
\documentclass[twoside]{scrartcl}
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\usepackage{everyshi}% http://ctan.org/pkg/everyshi
\usepackage{xifthen}% http://ctan.org/pkg/xifthen
\begin{document}
\EveryShipout{%
\ifthenelse{\isodd{\value{page}}}%
{\global\marginparsep=22pt}% Next page is even
{\global\marginparsep=11pt}% Next page is odd
}
\lipsum[1]
\marginpar[This is a paragraph in the left margin]{This is a paragraph in the right margin}
\lipsum[2-5]
\marginpar[This is a paragraph in the left margin]{This is a paragraph in the right margin}
\lipsum[6-8]
\end{document}
关键是\global
在 内进行更改\EveryShipout
,因为它是分组的。您可以对 进行类似的修改\marginparwidth
。
答案2
解决这个问题的关键是mparhack
包,如果没有这个包,问题更新中带圆圈的边距 par 就会出现在页面的错误一侧。mparhack
包重新定义了\@addmarginpar
命令,使其具有:
\renewcommand\@addmarginpar{%
...
\c@page=\mph@pg@new % At this point, \c@page is correct
...
\mph@orig@addmarginpar % This typesets the note using \marginparsep
...
}
可以直接\patchcmd
从包中使用,在实际设置边距之前etoolbox
插入我的\marginparsep
更改。这样就无需使用。\mph@orig@addmarginpar
everyshi
可以将类似的补丁应用于 来\@mn@@@marginnote
解决 的问题marginnote
,\kern\marginparsep
用条件语句替换。这有点棘手,因为有几个地方需要更改,所以我们使用递归应用补丁的技巧,直到 失败\patchcmd
(之后没有剩余的补丁)。
原则上,人们可能能够\marginparsep
用适当的条件在任何地方替换,但正确确定页面奇偶校验似乎并非易事,并且必须在每种情况下进行独立测试:\ifodd\c@page
对于\marginpar
和\ifodd\@mn@currpage
对于\marginnote
。
这是一个有点混乱的黑客攻击,但我还没有找到更简单的解决方案:
\documentclass[twoside]{scrbook}
\usepackage{etoolbox}
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\usepackage{marginnote}
\usepackage{mparhack}
\newlength\marginparsepodd
\newlength\marginparsepeven
\marginparsepodd=11pt
\marginparsepeven=22pt
\makeatletter
% First we patch \@addmarginpar
% The \patchcmd command does a search and replace.
\patchcmd{\@addmarginpar} % In this command
{\mph@orig@addmarginpar} % ... replace this...
{\if@twoside\ifodd\c@page\relax % ... with this
\marginparsep=\marginparsepodd % Page is odd
\else
\marginparsep=\marginparsepeven % Page is even
\fi
\else
\marginparsep=\marginparsepodd
\fi
\mph@orig@addmarginpar}
{} % success
{\message{Error! Couldn't hook into command % failure
`\string\@addmarginpar'}}
% Now we patch \@mn@@@marginnote
{%% Group to keep patching commands local
%
% Here we use a little trick to repeatedly patch the \@mn@@@marginnote
% command, replacing all instances of \kern\marginparsep with a
% conditional. We call \patch recursively each time on success, and stop
% when the patch fails (because all instances have been replaced). If the
% patch fails the first time, we show an error message.
\def\patcherr{%
\message{Error! Couldn't hook into command `\string\@mn@@@marginnote'}}
\def\patchok{%
\let\patcherr\relax % Only display error if first patch fails
\patch % Now patch again.
}
\def\patch{
\patchcmd{\@mn@@@marginnote} % In this command
{\kern\marginparsep} % ... replace this...
{\ifx\@mn@currpage\relax\else % ... with this
\if@twoside\ifodd\@mn@currpage\relax
\kern\marginparsepodd
\else
\kern\marginparsepeven
\fi
\else
\kern\marginparsepodd
\fi
\fi}
{\message{Patched!}\patchok} % success (recurse)
{\patcherr} % fail
}
\message{Patching `\string\@mn@@@marginnote`!}
\patch
\global\let\@mn@@@marginnote\@mn@@@marginnote % Make patch global
}
\makeatother
\begin{document}
\lipsum[1]
\marginpar[This is a paragraph in the left margin]{This is a paragraph in the right margin}
\lipsum[2]
\begin{itemize}
\def\do#1{\item This is a line #1 and should have a note with the same
number:\marginpar{Note #1 and a bit.}}
\docsvlist{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
\end{itemize}
\lipsum[3-4]
\marginpar[This is a paragraph in the left margin]{This is a paragraph in the right margin}
\lipsum[5]
\end{document}