奇数页和偶数页的 \marginparsep 不同吗?

奇数页和偶数页的 \marginparsep 不同吗?

\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}

奇数页/偶数页的 marginparsep 值不同

关键是\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@addmarginpareveryshi

可以将类似的补丁应用于 来\@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}

工作解决方案的输出。

相关内容