首次使用 \ref 时自动生成边注

首次使用 \ref 时自动生成边注

我希望在第一次引用某个图形时生成一个边注,例如显示“图 1”。我希望在第一次引用表格或公式时也能发生这种情况。我希望这在多列环境中也能正常工作。

“showlabels” 包与我的需求很接近;但是,它显示的是真正的标签名称,而不是分配给它的编号,也不是“Fig.”或“Eq.”之类的文本。此外,“outer”选项似乎不起作用。

以下(不是那么简单)的 MWE 显示了我所在的位置:

\documentclass{article}

\usepackage[nolabel,outer]{showlabels}
\usepackage{color}
\renewcommand{\showlabelfont}{\small\slshape\color{red}}
\showlabels{ref}

\usepackage{lipsum}
\usepackage{multicol}


\author{John Doe}
\title{Automatic marginal notes for the first use of a label}

\begin{document}
  \maketitle

  \begin{multicols}{2}

  See Figure~\ref{fig:figure}. \lipsum[1] 

  A new reference to Figure~\ref{fig:figure} is not 
referenced in the marginal note.

  Let's do the same with an equation.
  \begin{equation}
    \label{eq:1}f(x) = x^2
  \end{equation}

  Refering to Equation~\ref{eq:1} for the first time, there should be a marginal note, as is visible here, but it shoudl begin with  ``Eq.'', not ``Fig.''.

  Refering to Table~\ref{tab:1} for the first time. Here, there is no visible marginal note at all...

  \end{multicols}

% lets put a table and a figure
  \begin{table}
    \caption{Table title}
    \label{tab:1}
    \begin{tabular}{cc}
      x & y \\ \hline 
      3 & 3 \\
      4 & 4 \\ \hline
    \end{tabular}
  \end{table}

  \begin{figure}
    \centering\rule{150pt}{10pt}
    \caption{A figure}\label{fig:figure}
  \end{figure}

\end{document}

结果如下

MWE 结果

我们看到,第一次引用图 1 的页边距错误;第二次引用也放在了边注中,这不是我想要的(只有第一次引用才应该放在边注中)。第一次引用公式时显示的是“{fig:figure}”,而不是“图 1”。表格的页边距显示的是“{tab:1}”,而不是“Tab。”

任何帮助均感激不尽。

答案1

我对你问题中的一些细节有点困惑,因此以下是我对你问题的目标的理解:

(1)将格式化的参考文献(即参考文献类型和编号)作为注释显示在引用行相应的相应页边距中。

(2)仅对第一次进行了引用(即,\ref{fig:figure}您的 MWE 中的第二个应该不是在页边空白处做个注释)。

(3)若参考文献在第一栏,则该注释应出现在左边距中;若参考文献在第二栏,则该注释应出现在右边距中。

首先,我建议使用提供上下文感知引用的cleveref包和命令(即,如果传递的标签与图形计数器相对应,它将自动将“图形”添加到参考文献中。\cref

就这样,我适应了Yiannis Lazarides 回答这个问题它利用zref包保存标签的 x 位置,从而允许使用该包区分两列multicol。我还添加了geometry包来测试边注的对齐。

为了确保边注只用于 的第一个引用labelkey\cref重新定义了 以检查命令是否\marginnote@labelkey已定义。如果已定义,则标签已制作成边注。如果没有,则制作边注并定义命令。这还确保 是labelkey唯一的,以便找到与 相关联的位置(使用zref标签)。marginnote:labelkey

结果如下:

\usepackage[left=1.5in,right=1in]{geometry}

\usepackage{cleveref}
\crefname{equation}{Equation}{Equations}
\crefname{figure}{Figure}{Figures}
\crefname{table}{Table}{Tables}

\usepackage{zref-savepos}
%Adapted from Yiannis Lazarides' answer at https://tex.stackexchange.com/a/50295/89497
\def\putmarginpar#1#2{%
    \zsavepos{margnote:#1}%
    \ifnum20432158>\number\zposx{margnote:#1}%
        \hbox to 0pt{\hskip\dimexpr-\zposx{margnote:#1}sp \relax\makebox[\dimexpr 1in+\hoffset+\oddsidemargin-\marginparsep]{\hfill #2}}%\hskip\dimexpr-\zposx{#1}sp +0.5cm \relax#2}%
    \else
        \hbox to 0pt{\hskip\dimexpr-\zposx{margnote:#1}sp+1in+\hoffset+\oddsidemargin+\textwidth+\marginparsep\relax\makebox[\dimexpr\paperwidth-\textwidth-1in-\hoffset-\oddsidemargin-\marginparsep]{#2\hfill}}%\hskip4cm #2}%
    \fi%
    }
\makeatletter
%Redefine \cref so that it will make a margin note if the passed label is referenced for the first time.
\let\oldcref=\cref
\def\cref#1{%
    \oldcref{#1}%
    %check if the label has already been referenced.
    \ifcsname marginnote@#1\endcsname
        %already exists...therefore not the first citation
    \else
        \expandafter\gdef\csname marginnote@#1\endcsname{}%first citation
        \putmarginpar{#1}{\mbox{\color{red}\oldcref{#1}}}%add note to margin
    \fi
    }
\makeatother

如果将其添加到您的 MWE 的 pramble 中(并将调用更改\ref\cref并删除showlabels):

\documentclass{article}

%\usepackage[nolabel,right]{showlabels}
\usepackage{color}
%\renewcommand{\showlabelfont}{\small\slshape\color{red}}
%\showlabels{ref}

\usepackage{lipsum}
\usepackage{multicol}

\usepackage[left=1.5in,right=1in]{geometry}

\usepackage{cleveref}
\crefname{equation}{Equation}{Equations}
\crefname{figure}{Figure}{Figures}
\crefname{table}{Table}{Tables}

\usepackage{zref-savepos}
%Adapted from Yiannis Lazarides' answer at https://tex.stackexchange.com/a/50295/89497
\def\putmarginpar#1#2{%
    \zsavepos{margnote:#1}%
    \ifnum20432158>\number\zposx{margnote:#1}%
        \hbox to 0pt{\hskip\dimexpr-\zposx{margnote:#1}sp \relax\makebox[\dimexpr 1in+\hoffset+\oddsidemargin-\marginparsep]{\hfill #2}}%\hskip\dimexpr-\zposx{#1}sp +0.5cm \relax#2}%
    \else
        \hbox to 0pt{\hskip\dimexpr-\zposx{margnote:#1}sp+1in+\hoffset+\oddsidemargin+\textwidth+\marginparsep\relax\makebox[\dimexpr\paperwidth-\textwidth-1in-\hoffset-\oddsidemargin-\marginparsep]{#2\hfill}}%\hskip4cm #2}%
    \fi%
    }
\makeatletter
%Redefine \cref so that it will make a margin note if the passed label is referenced for the first time.
\let\oldcref=\cref
\def\cref#1{%
    \oldcref{#1}%
    %check if the label has already been referenced.
    \ifcsname marginnote@#1\endcsname
        %already exists...therefore not the first citation
    \else
        \expandafter\gdef\csname marginnote@#1\endcsname{}%first citation
        \putmarginpar{#1}{\mbox{\color{red}\oldcref{#1}}}%add note to margin
    \fi
    }
\makeatother

\author{John Doe}
\title{Automatic marginal notes for the first use of a label}

\begin{document}
  \maketitle
  \begin{multicols}{2}

  See \cref{fig:figure}. \lipsum[1] 

  A new reference to \cref{fig:figure} is not 
referenced in the marginal note.

  Let's do the same with an equation.
  \begin{equation}
    \label{eq:1}f(x) = x^2
  \end{equation}

  Refering to \cref{eq:1} for the first time, there should be a marginal note, as is visible here, but it shoudl begin with  ``Eq.'', not ``Fig.''.

  Refering to \cref{tab:1} for the first time. Here, there is no visible marginal note at all...

  \end{multicols}

% lets put a table and a figure
  \begin{table}
    \caption{Table title}
    \label{tab:1}
    \begin{tabular}{cc}
      x & y \\ \hline 
      3 & 3 \\
      4 & 4 \\ \hline
    \end{tabular}
  \end{table}

  \begin{figure}
    \centering\rule{150pt}{10pt}
    \caption{A figure}\label{fig:figure}
  \end{figure}

\end{document}

产量:

例子

编辑:如果您只想\ref在文档中使用(就像在 MWE 中一样),\ref可以重新定义,\cref在注释中使用以提供上下文感知格式。这允许文本内上下文与边注中使用的上下文不同(即您请求的缩写版本)。在您的 MWE 中实现:

\documentclass{article}

%\usepackage[nolabel,right]{showlabels}
\usepackage{color}
%\renewcommand{\showlabelfont}{\small\slshape\color{red}}
%\showlabels{ref}

\usepackage{lipsum}
\usepackage{multicol}

\usepackage[left=1.5in,right=1in]{geometry}

\usepackage{cleveref}
\crefname{equation}{Eq.}{Eqs.}
\crefname{figure}{Fig.}{Figs.}
\crefname{table}{Tab.}{Tabs.}

\usepackage{zref-savepos}
%Adapted from Yiannis Lazarides' answer at https://tex.stackexchange.com/a/50295/89497
\def\putmarginpar#1#2{%
    \zsavepos{margnote:#1}%
    \ifnum20432158>\number\zposx{margnote:#1}%
        \hbox to 0pt{\hskip\dimexpr-\zposx{margnote:#1}sp \relax\makebox[\dimexpr 1in+\hoffset+\oddsidemargin-\marginparsep]{\hfill #2}}%\hskip\dimexpr-\zposx{#1}sp +0.5cm \relax#2}%
    \else
        \hbox to 0pt{\hskip\dimexpr-\zposx{margnote:#1}sp+1in+\hoffset+\oddsidemargin+\textwidth+\marginparsep\relax\makebox[\dimexpr\paperwidth-\textwidth-1in-\hoffset-\oddsidemargin-\marginparsep]{#2\hfill}}%\hskip4cm #2}%
    \fi%
    }
\makeatletter
%Redefine \cref so that it will make a margin note if the passed label is referenced for the first time.
\let\oldref=\ref
\def\ref#1{%
    \oldref{#1}%
    %check if the label has already been referenced.
    \ifcsname marginnote@#1\endcsname
        %already exists...therefore not the first citation
    \else
        \expandafter\gdef\csname marginnote@#1\endcsname{}%first citation
        \putmarginpar{#1}{\mbox{\color{red}\cref{#1}}}%add note to margin
    \fi
    }
\makeatother

\author{John Doe}
\title{Automatic marginal notes for the first use of a label}

\begin{document}
 \maketitle

  \begin{multicols}{2}

  See Figure~\ref{fig:figure}. \lipsum[1] 

  A new reference to Figure~\ref{fig:figure} is not 
referenced in the marginal note.

  Let's do the same with an equation.
  \begin{equation}
    \label{eq:1}f(x) = x^2
  \end{equation}

  Refering to Equation~\ref{eq:1} for the first time, there should be a marginal note, as is visible here, but it shoudl begin with  ``Eq.'', not ``Fig.''.

  Refering to Table~\ref{tab:1} for the first time. Here, there is no visible marginal note at all...

  \end{multicols}

% lets put a table and a figure
  \begin{table}
    \caption{Table title}
    \label{tab:1}
    \begin{tabular}{cc}
      x & y \\ \hline 
      3 & 3 \\
      4 & 4 \\ \hline
    \end{tabular}
  \end{table}

  \begin{figure}
    \centering\rule{150pt}{10pt}
    \caption{A figure}\label{fig:figure}
  \end{figure}

\end{document}

产量:

第二个版本

答案2

我的方法是重新定义\label\ref做他们传统上做的事情额外的事情。

\label补充写入额外行到辅助文件。写入的格式,假设eq:1

\expandafter\gdef\csname Zeq:1Z\endcsname{\margnote{eq:1}}

它将在第二遍执行。这定义了一个宏,当调用它时,它将调用我的\margnote定义。但它什么时候被调用呢?

它由 renewed 调用,现在除了标准参数外,还\ref采用可选参数来定义边注l或 的对齐方式。此 new 将使用辅助文件中定义的机制调用。然后,它会执行正常操作。最后,它重新定义为不再为该标签调用边注。r\ref\margnote\csname Z<label>Z\endcsname\ref\csname Z<label>Z\endcsname

\margnote会判断您是否需要左或右边距注释,并调用 来\decoderef确定与标签类型关联的打印名称,然后是\ref值本身。因此,标签类型必须一致。这里,所有图形标签必须是fig:xx,所有表格必须是tab:xx,所有方程式必须是eq:xx。如果意外省略了冒号,则使用标签[Unknown]。如果使用了冒号但标签类型名称拼写错误(例如,Tab:1不是tab:1),则不会出现标识标签名称。

图形、表格和方程式的边距标签名称存储在\figlabeltablabel和中\eqlabel

\documentclass{article}
\usepackage{xcolor,lipsum,multicol,tabto}
\let\svlabel\label
\let\svref\ref
\def\myspace{ }
\makeatletter
\def\pwr{\protected@write\@auxout}
\newcommand\Xlabel[1]{\xdef\Addaux{%
    {}{\string\expandafter\string\gdef\string\csname\myspace Z#1Z\string\endcsname%
    {\string\margnote{#1}}}}\expandafter\expandafter\expandafter\pwr\Addaux}
\renewcommand\label[1]{\svlabel{#1}\Xlabel{#1}}
\renewcommand\ref[2][r]{\csname Z#2Z\endcsname{#1}\svref{#2}%
  \expandafter\gdef\csname Z#2Z\endcsname{\@gobble}}
\makeatother
\newcommand\margnote[2]{%
  \if r#2\tabto*{\dimexpr\linewidth+10pt\relax}\else\tabto*{-10pt}\fi%
  \csname #2lap\endcsname{\color{red}\decoderef#1::\relax}\tabto*{\TabPrevPos}}
\def\decoderef#1:#2:#3{%
  \ifx:#3 \csname #1label\endcsname~\svref{#1:#2}\else[Unknown] \svref{#1}\fi}
\def\figlabel{Fig.}
\def\eqlabel{Eq.}
\def\tablabel{Tab.} 

\author{John Doe}
\title{Automatic marginal notes for the first use of a label}
\begin{document}
  \maketitle
  \begin{multicols}{2}

  See Figure~\ref[l]{fig:figure}. \lipsum[1] 

  A new reference to Figure~\ref{fig:figure} is not 
referenced in the marginal note.

  Let's do the same with an equation.
  \begin{equation}
    \label{eq:1}f(x) = x^2
  \end{equation}

  Refering to Equation~\ref{eq:1} for the first time, there should be a marginal note, as is visible here, but it shoudl begin with  ``Eq.'', not ``Fig.''.

  Refering to Table~\ref{tab:1} for the first time. Here, there is no visible marginal note at all...Note table~\ref{tab2} has an improperly formed label, 
even though table~\ref{tab:1} is just fine, but doesn't show the 2nd time.
  \end{multicols}
% lets put a table and a figure
  \begin{table}
  \centering
    \caption{Table title}
    \label{tab:1}
    \begin{tabular}{cc}
      x & y \\ \hline 
      3 & 3 \\
      4 & 4 \\ \hline
    \end{tabular}
  \end{table}
  \begin{table}
  \centering
    \caption{Table title}
    \label{tab2}
    \begin{tabular}{cc}
      x & y \\ \hline 
      3 & 3 \\
      4 & 4 \\ \hline
    \end{tabular}
  \end{table}
  \begin{figure}
    \centering\rule{150pt}{10pt}
    \caption{A figure}\label{fig:figure}
  \end{figure}
\end{document}

在此处输入图片描述

相关内容