我定义了一个命令,可以让我同时快速引用编号(图形或表格)和页面:
命令
\newcommand{\kplref}[2]{~\ref{#1}, S.~\pageref{#1}{#2}\xspace}
第二个参数用于添加类似“第 6f 页”或“第 6ff 页”的内容,但我希望它是可选的,并且不想每次都强制输入空的 {}。
但是,像这样定义,命令将后面单词的首字母作为其第二个参数(参见示例)。
- 我该如何更改命令定义以避免这种情况?
- 或者是否已经有一个现成的命令可以完全满足我的要求?
结果
示例文档
\documentclass[11pt, parskip=half]{scrbook}
\usepackage{xspace}
\newcommand{\kplref}[2]{~\ref{#1}, S.~\pageref{#1}{#2}\xspace}
\begin{document}
%\tableofcontents
\section{Section1}
\label{sec1}
This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph.
This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph.
\section{Section2}
Now lets refer to section~\kplref{sec1}.
It fails if other text is following and there is no second argument like here:\newline
\kplref{sec1} shows the nonsense of this document.
\end{document}
答案1
您应该将命令定义为
\newcommand{\kplref}[2][]{\ref{#2}, S.~\pageref{#2}#1\xspace}
并使用可选参数,如
\kplref[f]{sec1}
梅威瑟:
\documentclass[11pt, parskip=half]{scrbook}
\usepackage{xspace}
\newcommand{\kplref}[2][]{\ref{#2}, S.~\pageref{#2}#1\xspace}
\begin{document}
%\tableofcontents
\section{Section1}
\label{sec1}
This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph.
This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph. This is a nonsense paragraph.
\section{Section2}
Now lets refer to section~\kplref{sec1}.
It doesn't fail if other text is following and there is no optional argument like here:\newline
\kplref{sec1} shows the nonsense of this document.
This is how to use the optional argument: \kplref[f]{sec1} which shows again the nonsense of this document.
\end{document}
答案2
这并不是对您关于如何设置带有可选参数的宏的问题的直接回答。相反,这是一个建议,希望它能更好地解决您要解决的问题。
如果我理解您的设置正确,您希望有一种方法来引用某些项目(在您的示例中是部分,但其他类型的项目也应该允许)——如果标注与项目本身位于同一页,则仅通过编号引用,如果项目位于其他位置,则通过编号加上某种形式的页码引用。如果这种解释是正确的,您应该研究瓦里雷夫包及其\vref
宏,它自动处理这些任务。
运行下面的示例代码,第一个页面如下所示
而第二页看起来像这样——请注意由宏提供的附加字符串“在上一页” \vref
。
\documentclass[11pt, parskip=half]{scrbook}
\usepackage{varioref} % for \vref macro
\begin{document}
\setcounter{chapter}{1} % just for this example
\section{Thoughts} \label{sec1}
This is a nonsense paragraph.
\section{More thoughts}
Now let's refer to Section~\vref{sec1}.
\newpage % force a page break
Now let's again refer to Section~\vref{sec1}.
\end{document}
附录:如果您另外加载聪明人包(之后varioref
),你可以写Now let's again refer to~\vref{sec1}.
(注意:没有“Section”字符串),你会得到
现在我们再次参考第 1 页的第 1.1 节。
即,您将获得数字页面引用(“在第 1 页”),而不是字符串“在前一页”。
答案3
您可以使用 xargs 包
\documentclass[11pt, parskip=half]{scrbook}
\usepackage{xspace,xargs}
\newcommandx{\kplref}[2][2]{\ref{#1}, S.~\pageref{#1}#2\xspace}% removed ~ from OP
\begin{document}
\section{Section1}
\label{sec1}
This is a nonsense paragraph. This is a nonsense paragraph. This is a
nonsense paragraph. This is a nonsense paragraph. This is a nonsense
paragraph. This is a nonsense paragraph.
This is a nonsense paragraph. This is a nonsense paragraph. This is a
nonsense paragraph. This is a nonsense paragraph. This is a nonsense
paragraph. This is a nonsense paragraph.
\section{Section2}
Now lets refer to section~\kplref{sec1}, or even to
section~\kplref{sec1}[ff] to check also that the following space is not gobbled.
It does not fail if other text is following and there is no second
argument like here:\newline \kplref{sec1} shows the true sense of this
document.
\end{document}
答案4
以下是一些可能性:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\kplref}{m}{%
\unskip~\ref{#1}, S.~\pageref{#1}%
}
\NewDocumentCommand{\kplrefA}{mo}{%
\unskip~\ref{#1}, S.~\pageref{#1}
\IfValueTF{#2}{#2}% <--- this adds the possibility of manipulating the argument
}
\NewDocumentCommand{\kplrefB}{mG{}}{%
\unskip~\ref{#1}, S.~\pageref{#1}%
\IfValueTF{#2}{#2}% <--- this adds the possibility of manipulating the argument
}
\begin{document}
\section{Title}\label{aaa}
Here are usage examples:
\begin{itemize}
\item Example of \verb|\kplref| for \kplref{aaa} and something
\item Example of \verb|\kplref| for \kplref{aaa}ff and something
\item Example of \verb|\kplrefA| for \kplrefA{aaa} and something
\item Example of \verb|\kplrefA| for \kplrefA{aaa}[ff] and something
\item Example of \verb|\kplrefB| for \kplrefB{aaa} and something
\item Example of \verb|\kplrefB| for \kplrefB{aaa}{ff} and something
\end{itemize}
\end{document}
注意,这很简单,只需ff
在单个参数宏后添加即可。这个\unskip
技巧可以让你忘记\kplref
在前一个单词后面写东西。
然而,我倾向于采用不同的方法,即先给出可选参数,然后不tie 被隐式地使用:
\NewDocumentCommand{\kplref}{om}{%
\ref{#2}, S.~\pageref{#2}%
\IfValueT{#1}{#1}% <--- this adds the possibility of manipulating the argument
}
像
\item Example of \verb|\kplref| for~\kplref{aaa} and something
\item Example of \verb|\kplref| for~\kplref[ff]{aaa} and something
我说的“操纵论点的可能性”是什么意思?假设你的缩写ff
需要变成,ff.
因为一些挑剔的文字编辑的要求。使用最后一种方法,但它与相同\kplrefA
,\kplrefB
你只需要将定义更改为
\NewDocumentCommand{\kplref}{om}{%
\ref{#2}, S.~\pageref{#2}%
\IfValueT{#1}{#1.\@}%
}
重新处理文档后,就会出现句号。