关于 zref bundle 的问题(改变脚注规则的行为)

关于 zref bundle 的问题(改变脚注规则的行为)

bidi包中,我们有三个脚注命令\footnote(在 RTL 模式下排版 RTL 脚注,在 LTR 模式下排版 LTR 脚注)、\RTLfootnote(始终排版 RTL 脚注)和\LTRfootnote(始终排版 LTR 脚注)。目前,bidi包有一种复杂的方法来检测页面中的第一个脚注命令是什么,当脚注被拆分时,它会失败。

因此我的问题是,是否有可能(使用zref捆绑包)检测页面中使用的第一个脚注命令是什么,并相应地(如果页面中的第一个脚注是 RTL,则将脚注规则放在右侧,如果页面中的第一个脚注是 LTR,则将脚注规则放在左侧)更改脚注规则的行为。

这是一个看起来可以正常工作的示例:

\documentclass{article}
\usepackage{zref-perpage}
\usepackage{bidi}
\makeatletter
\@definecounter{bidifootnote}

\zmakeperpage{bidifootnote}
\long\def\@RTLfootnotetext#1{\insert\footins{%
    \stepcounter{bidifootnote}\@RTLtrue
    \ifnum\c@bidifootnote=1\if@RTL\global\let\footnoterule\right@footnote\else\global\let\footnoterule\left@footnote\fi\fi
    \reset@font\footnotesize
    \interlinepenalty\interfootnotelinepenalty
    \splittopskip\footnotesep
    \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
    \hsize\columnwidth \@parboxrestore
    \protected@edef\@currentlabel{%
       \csname p@footnote\endcsname\@thefnmark
    }%
    \color@begingroup
      \@makefntext{%
        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
    \color@endgroup}}%


\long\def\@LTRfootnotetext#1{\insert\footins{\stepcounter{bidifootnote}\@RTLfalse%
    \ifnum\c@bidifootnote=1\if@RTL\global\let\footnoterule\right@footnote\else\global\let\footnoterule\left@footnote\fi\fi
    \reset@font\footnotesize
    \interlinepenalty\interfootnotelinepenalty
    \splittopskip\footnotesep
    \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
    \hsize\columnwidth \@parboxrestore
    \protected@edef\@currentlabel{%
       \csname p@footnote\endcsname\@thefnmark
    }%
    \color@begingroup
      \@makefntext{%
        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
    \color@endgroup}}%



\long\def\@footnotetext#1{\insert\footins{%
    \stepcounter{bidifootnote}\if@RTL@footnote\@RTLtrue\else\@RTLfalse\fi
    \ifnum\c@bidifootnote=1\if@RTL\global\let\footnoterule\right@footnote\else\global\let\footnoterule\left@footnote\fi\fi
    \reset@font\footnotesize
    \interlinepenalty\interfootnotelinepenalty
    \splittopskip\footnotesep
    \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
    \hsize\columnwidth \@parboxrestore
    \protected@edef\@currentlabel{%
       \csname p@footnote\endcsname\@thefnmark
    }%
    \color@begingroup
      \@makefntext{%
        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
    \color@endgroup}}%
\makeatother
\begin{document}
\RTLfootnote{This is a test.}\LTRfootnote{This is a test.}
\newpage
\LTRfootnotetext[3]{This is a test.}\RTLfootnote[4]{This is a footnote.}
\end{document}

答案1

以下解决方案使用标签来了解执行脚注命令的页面。第一个执行的脚注(\@LTRfootnotetext\@RTLfootnotetext)全局定义宏,\footdir@<absolute page number>其中L/R表示规则左或右。 \footnoterule检查该宏以打印正确的规则。

\documentclass{article}
\usepackage{zref-abspage}[2010/03/26]
\usepackage{auxhook}
\usepackage{ltxcmds}[2010/11/12]
\usepackage{bidi}

\makeatletter
\newcounter{footdir@label}
\renewcommand*{\thefootdir@label}{footdir@\the\value{footdir@label}}
\newcommand*{\footdir@write}{%
  \stepcounter{footdir@label}%
  \zref@labelbyprops{\thefootdir@label}{abspage}%
}
\newif\iffootdir@debug
\footdir@debugtrue
\newcommand*{\footdir@debug}[1]{%
  \iffootdir@debug
    \typeout{[footdir] #1}%
  \fi
}
\@ifpackagelater{zref-abspage}{2012/10/27}{%
  % this version is not yet released
  \newcommand*{\footdir@LeftRightElse}{%
    \ltx@ifundefined{footdir@\the\value{zabspage}}{%
      \footdir@debug{abspage \the\value{zabspage}: else}%
      \ltx@thirdofthree
    }{%
      \if\csname footdir@\the\value{zabspage}\endcsname L%
        \footdir@debug{abspage \the\value{zabspage}: left}%
        \expandafter\ltx@firstofthree
      \else
        \footdir@debug{abspage \the\value{zabspage}: right}%
        \expandafter\ltx@secondofthree
      \fi
    }%
  }%
}{%
  \providecommand*{\c@zabspage}{\c@abspage}%
  \newcommand*{\footdir@LeftRightElse}{%
    \footdir@write
    \zifrefundefined{\thefootdir@label}{%
      \footdir@debug{abspage ??: else}%  
      \ltx@thirdofthree
    }{%
      \edef\footdir@abspage{%
        \zref@extractdefault{\thefootdir@label}{abspage}{0}%
      }%
      \ltx@ifundefined{footdir@\footdir@abspage}{%
        \footdir@debug{\footdir@abspage: else}%   
        \ltx@thirdofthree
      }{%
        \if\csname footdir@\footdir@abspage\endcsname L%
          \footdir@debug{\footdir@abspage: left}%
          \expandafter\ltx@firstofthree
        \else
          \footdir@debug{\footdir@abspage: right}%
          \expandafter\ltx@secondofthree
        \fi
      }%   
    }%     
  }%       
}          
\newcommand*{\footdir@fntext}[1]{%
  \footdir@write
  \zifrefundefined{\thefootdir@label}{%
  }{%
    \edef\footdir@name{%
      footdir@\zref@extractdefault{\thefootdir@label}{abspage}{0}%
    }%
    \@ifundefined{\footdir@name}{%
      \expandafter\gdef\csname\footdir@name\endcsname{#1}%
    }{}%
  }%
}   
\@ifdefinable{\footdir@ORG@RTLfootnotetext}{%
  \let\footdir@ORG@RTLfootnotetext\@RTLfootnotetext
  \def\@RTLfootnotetext{%
    \footdir@fntext{R}%  
    \footdir@ORG@RTLfootnotetext
  }%
}   
\@ifdefinable{\footdir@ORG@LTRfootnotetext}{%
  \let\footdir@ORG@LTRfootnotetext\@LTRfootnotetext
  \def\@LTRfootnotetext{%
    \footdir@fntext{L}%  
    \footdir@ORG@LTRfootnotetext
  }%
}   
\def\footnoterule{%
  \footdir@LeftRightElse
    \left@footnoterule  
    \right@footnoterule 
    \left@footnoterule  
}
\makeatother

\begin{document}
\RTLfootnote{This is a test.}\LTRfootnote{This is a test.}
\newpage
\LTRfootnotetext[3]{This is a test.}\RTLfootnote[4]{This is a footnote.}
\newpage
\beginR 
\RTLfootnote{This is a test.}\LTRfootnote{This is a test.}
\endR
\newpage
\beginR 
\LTRfootnotetext[3]{This is a test.}\RTLfootnote[4]{This is a footnote.}
\endR
\end{document}

调试输出:

[footdir] abspage 1: right
[1]
[footdir] abspage 2: left
[2]
[footdir] abspage 3: right
[3]
[footdir] abspage 4: left
[4]

脚注扩展,分为两页

\documentclass{article}
\usepackage{lipsum}
\usepackage{zref-abspage}[2010/03/26]
\usepackage{auxhook}
\usepackage{ltxcmds}[2010/11/12]
\usepackage{bidi}

\makeatletter
\newcounter{footdir@label}
\renewcommand*{\thefootdir@label}{footdir@\the\value{footdir@label}}
\newcommand*{\footdir@write}{%
  \stepcounter{footdir@label}%
  \zref@labelbyprops{\thefootdir@label}{abspage}%
}
\newif\iffootdir@debug
\footdir@debugtrue
\newtoks\footdir@toks
\newcommand*{\footdir@debug}[1]{%
  \iffootdir@debug
    \typeout{[footdir] #1}%
  \fi
}
\@ifpackagelater{zref-abspage}{2012/10/27}{%
  \newcommand*{\footdir@LeftRightElse}{%
    \ltx@ifundefined{footdir@\the\value{zabspage}}{%
      \footdir@debug{abspage \the\value{zabspage}: else}%
      \ltx@thirdofthree
    }{%
      \if\csname footdir@\the\value{zabspage}\endcsname L%
        \footdir@debug{abspage \the\value{zabspage}: left}%
        \expandafter\ltx@firstofthree
      \else
        \footdir@debug{abspage \the\value{zabspage}: right}%
        \expandafter\ltx@secondofthree
      \fi
    }%
  }%
}{%
  \providecommand*{\c@zabspage}{\c@abspage}%
  \newcommand*{\footdir@LeftRightElse}{%
    \footdir@write
    \zifrefundefined{\thefootdir@label}{%
      \footdir@debug{abspage ??: else}%  
      \ltx@thirdofthree
    }{%
      \edef\footdir@abspage{%
        \zref@extractdefault{\thefootdir@label}{abspage}{0}%
      }%
      \ltx@ifundefined{footdir@\footdir@abspage}{%
        \footdir@debug{\footdir@abspage: else}%   
        \ltx@thirdofthree
      }{%
        \if\csname footdir@\footdir@abspage\endcsname L%
          \footdir@debug{\footdir@abspage: left}%
          \expandafter\ltx@firstofthree
        \else
          \footdir@debug{\footdir@abspage: right}%
          \expandafter\ltx@secondofthree
        \fi
      }%   
    }%     
  }%       
}          
\newcommand*{\footdir@fntext}[1]{%
  \zifrefundefined{\thefootdir@label}{%
  }{%
    \edef\footdir@name{%
      footdir@\zref@extractdefault{\thefootdir@label}{abspage}{0}%
    }%
    \@ifundefined{\footdir@name}{%
      \expandafter\gdef\csname\footdir@name\endcsname{#1}%
    }{}%
  }%
}   
\newcommand*{\footdir@temp}[3]{%
  \@ifdefinable{#1}{%
    \let#1#2%
    \renewcommand{#2}[1]{%
      \footdir@write
      \footdir@fntext{#3}%
      \stepcounter{footdir@label}%
      \footdir@fntext{#3}%
      \footdir@toks{##1}% 
      \footdir@toks\expandafter{%
        \the\expandafter\footdir@toks
        \expandafter
        \zref@labelbyprops\expandafter{\thefootdir@label}{abspage}%
      }%
      \expandafter#1\expandafter{\the\footdir@toks}%
    }%
  }%  
}     
\footdir@temp\footdir@ORG@RTLfootnotetext\@RTLfootnotetext{R}%
\footdir@temp\footdir@ORG@LTRfootnotetext\@LTRfootnotetext{L}%
\def\footnoterule{%
  \footdir@LeftRightElse
    \left@footnoterule  
    \right@footnoterule 
    \left@footnoterule  
}
\makeatother

\begin{document}
\RTLfootnote{This is a test.}\LTRfootnote{This is a test.}
\newpage
\lipsum[1-4]
\LTRfootnotetext[3]{This is a test.}\RTLfootnote[4]{\lipsum[1-2]}
\newpage
Test with split footnote.
\newpage
\beginR 
\RTLfootnote{This is a test.}\LTRfootnote{This is a test.}
\endR
\newpage
\beginR 
\LTRfootnotetext[3]{This is a test.}\RTLfootnote[4]{This is a footnote.}
\endR
\end{document}

在此示例中,脚注的结尾也有一个标签。如果脚注的结尾位于下一页,则为\footdir@<absolute page number>该页定义 。

不支持的情况是,一个脚注跨过两页以上。这要复杂得多,因为还必须记住最后一个脚注的方向,并且需要找到最后一个脚注所在的页面。

答案2

由于时间不够,这是页面上编号元素的初稿。

\onopSet{<class>}{<id>}

元素的类型在中给出,元素由类内部<class>标识。在文件中写入/构造一个标签。<id>\onopSetzref.aux

\onopGet{<class>}{<id>}

可扩展宏扩展到其页面上类\onopGet元素的序数。<id><class>

\onopUsed{<class>}{<id>}

是可扩展宏的配套宏\onopGet,并将引用标记为已使用,以便如果引用尚不存在,LaTeX 可以打印未定义的引用警告。

\documentclass{article}
\usepackage{zref-abspage}
\usepackage{auxhook}

% Ordinal Number On Page/ OrdNumOnPage / onop

\makeatletter
\providecommand*{\c@zabspage}{\c@abspage}
\newcommand*{\onop@abspage}{\the\value{zabspage}}

\zref@newprop{OrdinalNumberOnPage}[0]{0}
\newcommand*{\onopSet}[2]{%
  \if@filesw
    \protected@write\@auxout{%
      \let\onop@abspage\relax
    }{%
      \protect\onopLabel{#1}{#2}{\onop@abspage}%
    }%
  \fi
}
\AddLineBeginAux{%
  \string\providecommand{\string\onopLabel}[3]{}%
}
\newcommand*{\onopLabel}[3]{%
  \@ifundefined{onop:#1:#3}{%
    \expandafter\xdef\csname onop:#1:#3\endcsname{1}%
    \onop@Clear{#1}{#3}%
  }{%
    \begingroup
      \count@=\csname onop:#1:#3\endcsname\relax
      \advance\count@\@ne
      \expandafter\xdef\csname onop:#1:#3\endcsname{\the\count@}%
    \endgroup
  }%
  \begingroup
  \edef\onop@tmp{\endgroup
    \noexpand\zref@newlabel{onop@#1@#2}{%
      \noexpand\abspage{#3}%
      \noexpand\OrdinalNumberOnPage{\csname onop:#1:#3\endcsname}%
    }%
  }\onop@tmp
}
\let\onop@AtBeginDocument\@empty
\newcommand*{\onop@Clear}[2]{%
  \expandafter
  \g@addto@macro\expandafter\onop@AtBeginDocument\expandafter{%
    \expandafter
    \global\expandafter\let\csname onop:#1:#2\endcsname\@undefined
  }%
}
\AtBeginDocument{%
  \onop@AtBeginDocument
  \let\onop@Clear\@gobbletwo 
}
\newcommand*{\onopUsed}[2]{%
  \zref@refused{onop@#1@#2}%
}
\newcommand*{\onopGet}[2]{%
  \zref@extract{onop@#1@#2}{OrdinalNumberOnPage}%
}
\newcommand*{\onopLabelName}[2]{%
  onop@#1@#2%
}   
\newcommand*{\onopGetAbsPage}[2]{%
  \zref@extract{onop@#1@#2}{abspage}%
}
\makeatother

\begin{document}
\section{Test}
\onopSet{footnote}{a}
\onopSet{footnote}{b}

\onopUsed{footnote}{a}
\onopUsed{footnote}{b}

a: \onopGet{footnote}{a}%
\ifnum\onopGet{footnote}{a}=1 %
  ~(first)%
\fi
,
b: \onopGet{footnote}{b}%   
\ifnum\onopGet{footnote}{b}=1 %
  ~(first)%
\fi
\end{document}

相关内容