% \iffalse meta-comment % % Copyright (C) 2014 by Leo Liu % --------------------------------------------------------------------------- % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Leo Liu. % % This work consists of the files seealso.dtx and seealso.ins % and the derived filebase seealso.sty. % % \fi % % \iffalse %<*driver> \ProvidesFile{seealso.dtx} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{seealso} %<*package> [2014/04/06 v1.0 makeidx's see and seealso with page number support.] % % %<*driver> \documentclass{ltxdoc} \usepackage[a4paper,left=2in,right=1in,top=1in,bottom=1in]{geometry} \newcommand\pkg[1]{\textsf{#1}} \usepackage[UTF8,hyperref]{ctex} \makeatletter \renewcommand\glossary@prologue{% \section*{版本历史} \markboth{版本历史}{版本历史}} \renewcommand\index@prologue{% \section*{Index / 代码索引} \markboth{Index / 代码索引}{Index / 代码索引} 斜体的数字表示对应项说明所在的页码。下划线的数字表示定义所在的代码行号;而直 立体的数字表示对应项使用时所在的行号。} \def\option{\begingroup \catcode`\\12 \MakePrivateLetters \option@} \let\endoption\endtrivlist \long\def\option@#1{\endgroup \topsep\MacroTopsep \trivlist \edef\saved@macroname{\string#1}% \def\makelabel##1{\llap{##1}}% \if@inlabel \let\@tempa\@empty \count@\macro@cnt \loop \ifnum\count@>\z@ \edef\@tempa{\@tempa\hbox{\strut}}\advance\count@\m@ne \repeat \edef\makelabel##1{\llap{\vtop to\baselineskip {\@tempa\hbox{##1}\vss}}}% \advance \macro@cnt \@ne \else \macro@cnt\@ne \fi \edef\@tempa{\noexpand\item[% \noexpand\PrintEnvName {\string#1}]}% \@tempa \global\advance\c@CodelineNo\@ne \SpecialMainOptionIndex{#1}\nobreak \global\advance\c@CodelineNo\m@ne \ignorespaces} \def\SpecialMainOptionIndex#1{\@bsphack \special@index{% #1\actualchar {\string\ttfamily\space#1} (option)% \encapchar main}% \@esphack} \def\SpecialOptionIndex#1{\@bsphack \index{#1\actualchar{\protect\ttfamily#1} (option)\encapchar usage}% \index{options:\levelchar#1\actualchar{\protect\ttfamily#1}\encapchar usage}\@esphack} \def\DescribeOption{\leavevmode\@bsphack\begingroup\MakePrivateLetters \Describe@Option} \def\Describe@Option#1{\endgroup \marginpar{\raggedleft\PrintDescribeEnv{#1}}% \SpecialOptionIndex{#1}\@esphack\ignorespaces} \def\stylemeaning#1{\texttt{% \expandafter\expandafter\expandafter\strip@prefix \expandafter\meaning\csname seealso@#1\endcsname}} \renewcommand\author[2][]{% \ifstrempty{#1}{}{% \hypersetup{pdfauthor=#1}}% \def\@author{#2}} \renewcommand\title[2][]{% \ifstrempty{#1}{}{% \hypersetup{pdftitle=#1}}% \def\@title{#2}} \makeatother \usepackage{seealso} \usepackage{fancyvrb} \fvset{gobble=2} \usepackage{hypdoc} \hypersetup{pdfstartview=FitH} \AtBeginDocument{\MakeShortVerb\|} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{seealso.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % \CheckSum{163} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % % \changes{v0.1}{2014/04/04}{初始版本。} % \changes{v1.0}{2014/04/05}{功能较完备的版本。} % % \DoNotIndex{\newcommand,\newenvironment,\^,\~,\@ifnextchar,\@onlypreamble, % \active, \AtBeginDocument,\begingroup,\catcode, \csdef,\cslet,\cslet,\csuse, % \DeclareBoolOption,\def,\define@key,\do, \docsvlist, \dolistloop,\else, % \emph,\empty,\endgroup,\fi,\forcsvlist, \forlistcsloop, \forlistloop, % \ifcsdef,\ifcsempty, \ifinlistcs,\ifstrempty,\ignorespaces,\lccode,\let, % \listadd, \listcsgadd,\lowercase,\newif, \ProcessKeyvalOptions, % \RequirePackage, \setkeys,\SetupKeyvalOptions,\space,\unless} % % \GetFileInfo{seealso.dtx} % \title[The seealso Package (\fileversion)] % {\hypertarget{English}{The \pkg{seealso} Package (\fileversion)} % \makebox[0pt][l]{\hspace{3cm}\large % \hyperlink{Chinese}{$\Rightarrow$ \textsf{中文版}}}} % \author[Liú Hǎiyáng (Leo Liu) ] % {Liú Hǎiyáng (Leo Liu) \\ \nolinkurl{leoliu.pku@gmail.com}} % \date{\filedate} % % \maketitle % % \section{Introduction} % % When preparing index, the macros |\see| and |\seealso| define by \LaTeXe's % standard package \pkg{makeidx} are handy to use. They are used as special % page format command, to present cross reference of index entry. For example, % if we use % \begin{Verbatim} % \index{math|see{mathematics}} % \end{Verbatim} % to reference the index entry ``mathematics'', we will get % \begin{quote} % math, \emph{see} mathematics % \end{quote} % in the output index. % % However, |\see| and |\seealso| commands in \LaTeXe{} cannot produce page % numbers. Moreover, if we use multiple |\see| or |\seealso|'s for one entry, % there will be multiple reference targets produced. Therefore we may get % this unexpected output: % \begin{quote} % math, \emph{see} mathematics, \emph{see} mathematics, \emph{see} mathematics % \end{quote} % if we have used \verb=\index{math|see{mathematics}}= at 3 different places % in the document. % % The \pkg{seealso} package solve the problem. If we use % \begin{Verbatim} % \usepackage{seealso} % \end{Verbatim} % all cross references of index entry will produce page numbers, and the % reference targets, which we call \emph{see list}, will be merged. The % previous example will produce an output like this: % \begin{quote} % math, \seepage{mathematics}{2}, \seepage{mathematics}{4}, \seepage{mathematics}{5} % \end{quote} % % \section{Reference} % % \subsection{Package Loading} % % The basic usage of the package is to simply load the package % \begin{Verbatim} % \usepackage{seealso} % \end{Verbatim} % then |\see| and |\seealso| commands will be redefined to support page number % output and reference target merging. % % The \pkg{seealso} package should be loaded after \pkg{makeidx}, % \pkg{imakeidx}, etc. Or the redefinition of |\see| and |\seealso| may be % broken. % % \subsection{Package Options} % % \DescribeOption{override} % |override| is a boolean option, with a default value |true|. When it is set % the original |\see| and |\seealso| will be overridden. However, when it is % set to be |false|, say % \begin{Verbatim} % \usepackage[override=false]{seealso} % \end{Verbatim} % then |\see| and |\seealso| will not be overridden, and |\seepage| and % |\seealsopage| should be used for page number output. % % \DescribeOption{activecr} % |activecr| is a boolean option, with a default value |true|. When it is set, % the see list will be output at the end of an index entry line (in a |.ind| % file). If we set |activecr=false|, however, the see list will not be output % automatically, one should use |\SeealsoPrintList| manually at the end of the % index entry instead. Usually |\SeealsoPrintList| is added via |delim_t| % style of Makeindex. % % \subsection{The \cs{see} and \cs{seealso} Commands} % % \DescribeMacro{\seepage} % \DescribeMacro{\seealsopage} % |\seepage| and |\seealsopage| provide the main functions of this package. % They provide the same faculty of cross reference, but output page numbers % and prevent redundancy. For example, suppose that there are % \begin{Verbatim} % \index{foo|seepage{bar}} % \end{Verbatim} % in page 1, 2, and 3, we will have a |.ind| file as below: % \begin{Verbatim} % foo, \seepage{bar}{1}, \seepage{bar}{2}, \seepage{bar}{3} % \end{Verbatim} % And the output of the index will be: % \begin{quote} % foo, \seepage{bar}{1}, \seepage{bar}{2}, \seepage{bar}{3} % \end{quote} % % It is possible to use different references for one index entry. For example % we can use % \begin{Verbatim} % \index{foo|seepage{bar}} % \end{Verbatim} % and % \begin{Verbatim} % \index{foo|seepage{foobaz}} % \end{Verbatim} % several times, the generated |.ind| file may be: % \begin{Verbatim} % foo, \seepage{bar}{1}, \seepage{bar}{2}, \seepage{foobaz}{3} % \end{Verbatim} % And the output of the index will be: % \begin{quote} % foo, \seepage{bar}{1}, \seepage{bar}{2}, \seepage{foobaz}{3} % \end{quote} % % \DescribeMacro{\seenopage} % \DescribeMacro{\seealsonopage} % The macros |\seenopage| and |\seealsonopage| save the original definitions % of |\see| and |\seealso| before loading \pkg{seealso}, which do not produce % page numbers. % % \DescribeMacro{\see} % \DescribeMacro{\seealso} % When option |override| is |true|, which is the default, |\see| and % |\seealso| works just as |\seepage| and |\seealsopage|. % % \DescribeMacro{\SeealsoPrintList} % |\seepage| and |\seealsopage| will collect the see lists, which will be % output at the end of the line under default |activecr| option. However, when % |activecr| is set to be |false|, the see lists won't be output at the end of % source line where |\seepage| and |\seealsopage| are. In the latter case, we % can add |\SeealsoPrintList| manually at the end of line to output the see % lists. Usually we can set |delim_t| variable in the style file of Makeindex, % for example: % \begin{Verbatim} % % example.ist % delim_t "\\SeealsoPrintList" % \end{Verbatim} % Then a |\SeealsoPrintList| will be appended at the end of every non-empty % index entry, and the see lists will be output properly. % % \DescribeMacro{\DeclareSeealsoMacro} % |\DeclareSeealsoMacro| can be used to define a new macro like |\see| and % |\seealso|. The syntax is % \begin{quote} % |\DeclareSeealsoMacro\|\meta{macro}|{|\meta{seelist}|}{|\meta{name}|}| % \end{quote} % where |\|\meta{macro} is the macro name, \meta{seelist} is the new see list, % and \meta{name} is the name of the see list to be output (like |\seename|). % Using |\DeclareSeealsoMacro|, two macros will be defined, the one is % |\|\meta{macro}, the other is |\|\meta{macro}|name|. If there has no % |\|\meta{macro}|name| predefined, it is defined to be \meta{name}, or the % definition remains unchanged. % % For example, |\seepage| and |\seealsopage| are defined like this: % \begin{Verbatim} % \DeclareSeealsoMacro\seepage{see}{see} % \DeclareSeealsoMacro\seealsopage{also}{see also} % \end{Verbatim} % The definitions above also provide the default value of |\seename| and % |\alsoname| to be |see| and |see also|, respectively. % % \subsection{Output Styles} % % \DescribeMacro{\seealsosetup} % The macro |\seealsosetup| is used to configure the output style of see % lists. The syntax is: % \begin{quote} % |\seealsosetup[|\meta{seelists}|]{|\meta{kv-options}|}| % \end{quote} % where \meta{seelists} is a comma separated list, each item of which is a see % list to be setup. \meta{seelists} can also be omitted or set to be empty, % which means we are setting up the default output style of all kind of see % lists. \meta{kv-options} is the options in key-value syntax. % % All possible output styles are summarized in table~\ref{tab:outstyleen}. % \begin{table}[htbp] % \centering % \begin{tabular}{lp{4cm}ll} % \hline % Key & Meaning & Argument & Default Value \\ % \hline % |name| & The name of see list to be output, e.g. |\seename| & none % & (invalid) \\ % |listsep| & The separator before a see list & none % & \stylemeaning{listsep} \\ % |itemsep| & The separator between see list items & none % & \stylemeaning{itemsep} \\ % |nameformat| & Output format of the see list name & |#1| % & \stylemeaning{nameformat} \\ % |itemformat| & Output format of the see list items & |#1| % & \stylemeaning{itemformat} \\ % |pageformat| & Output format of the page numbers & |#1| % & \stylemeaning{pageformat} \\ % \hline % \end{tabular} % \caption{Output styles used by \cs{seealsosetup}}\label{tab:outstyleen} % \end{table} % % For example, if we want to set all page numbers produced by |\seealsopage| % to be italic, we can use: % \begin{Verbatim} % \seealsosetup[also]{pageformat=\textit{#1}} % \end{Verbatim} % % \DescribeMacro{\SeealsoGobble} % |\SeealsoGobble| takes a character \meta{c} as argument. It checks the % following character, gobble it and ignore spaces if it is \meta{c}, or do % nothing if it is not \meta{c}. This macro is useful in |pageformat| style % to prevent outputting the page numbers, like this: % \begin{Verbatim} % \seealsosetup[see,also]{pageformat=\SeealsoGobble{,}, listsep=} % \end{Verbatim} % However, |\see| and |\seealso| will be encapsulated by |\hyperindexformat| % is we use \pkg{hyperref}, then |\SeealsoGobble| will be invalid. % % \section{Known Issues} % % Here are some known problems and their solutions: % \begin{itemize} % \item % Makeindex wraps the output lines with respect to |line_max| variable. The % default value of |line_max| is only 72, therefore the entry line containing % |\see| and |\seealso| may be wrapped. However, |activecr| is |true| by % default, then package \pkg{seealso} will print the see lists at each end of % lines, and in the wrapped lines the see lists are output multiple times, % which is unexpected. % % To solve the problem, it is better to set larger |line_max| in the |.ist| % style file to prevent wrapping. Another approach is to set |activecr=false| % option, and set |delim_t| to be |\SeealsoPrintList| explicitly to output the % see lists. % % \item % Since the output format of page numbers of |\seepage|, |\seealsopage| is the % same as normal page numbers, it may be ambiguous if we use normal |\index| % and \verb=\index{...|seepage}= simultaneously. Usually we should avoid using % different style of |\index| with or without |\seepage| and |\seealsopage|. % If it is impossible, we can set special page number format to identify them, % or we can use |\SeealsoGobble| to disable page numbers. % % \item % When \pkg{hyperref} package is used, the function of avoiding page numbers % via |\SeealsoGobble| is invalid. That is because that |\see| and |\seealso| % will be encapsulated by |\hyperindexformat| in the |.ind| file. To solve the % problem, we can set |hyperindex=false| option of \pkg{hyperref} to disable % hyperlinks in the index, or some special patching of \pkg{hyperref} can be % considered. % \end{itemize} % % % \clearpage % \title{\hypertarget{Chinese}{\pkg{seealso} 宏包 (\fileversion)} % \makebox[0pt][l]{\hspace{3cm}\large % \hyperlink{English}{$\Rightarrow$ \textsf{English Version}}}} % \author{刘海洋 \\ \nolinkurl{leoliu.pku@gmail.com}} % \date{\filedate} % % \maketitle % % \section{简介} % % 在索引生成时,\LaTeXe{} 的标准宏包 \pkg{makeidx} 定义了 |\see| 与 |\seealso| % 两个宏,它们通常是在 |\index| 中作为一种特殊的页码格式使用,表示索引项的引 % 用。例如使用 % \begin{Verbatim} % \index{math|see{mathematics}} % \end{Verbatim} % 会使索引项 math 引用到 mathematics。生成类似 % \begin{quote} % math, \emph{see} mathematics % \end{quote} % 的索引条目。 % % 不过,\LaTeXe{} 的 |\see| 与 |\seealso| 命令并不会为交叉引用的索引项输出页 % 码。更严重的问题是,如果对一个索引项使用了多次交叉引用,则会多次输出相同的目 % 标引用。因此可能出现这样的尴尬效果: % \begin{quote} % math, \emph{see} mathematics, \emph{see} mathematics, \emph{see} mathematics % \end{quote} % 其中可能在三个不同的地方使用了 \verb=\index{math|see{mathematics}}=。 % % \pkg{seealso} 宏包即为解决这种问题而编写。只要使用了 % \begin{Verbatim} % \usepackage{seealso} % \end{Verbatim} % 则交叉引用的索引项会同时显示页码,同时多个交叉引用的目标(我们称为\emph{参见 % 列表})会合并显示。前面的例子就可能会输出: % \begin{quote} % math, \seepage{mathematics}{2}, \seepage{mathematics}{4}, \seepage{mathematics}{5} % \end{quote} % 这样的格式。 % % \section{参考手册} % % \subsection{宏包载入} % % 基本的用法就是直接使用 % \begin{Verbatim} % \usepackage{seealso} % \end{Verbatim} % 这样 |\see| 和 |\seealso| 命令就会被重定义为支持输出页码和合并目标的格式。 % % 注意 \pkg{seealso} 宏包的载入应该晚于 \pkg{makeidx}、\pkg{imakeidx} 等定义 % |\see|、|\seealso| 的宏包,否则其功能将会失效。 % % \subsection{宏包选项} % % \DescribeOption{override} % |override| 是布尔型选项,默认为 |true|。表示覆盖已有的 |\see| 与 |\seealso| % 定义。如果设置 % \begin{Verbatim} % \usepackage[override=false]{seealso} % \end{Verbatim} % 则不对 |\see| 与 |\seealso| 覆盖,要使用 |\seepage| 和 % |\seealsopage| 命令调用相应的功能。 % % \DescribeOption{activecr} % |activecr| 是布尔型选项,默认为 |true|。表示打开在(|.ind| 文件中)索引项行 % 末自动输出所有参见列表的功能。如果设置 |activecr=false|,则必须手工(通常通 % 过设置 Makeindex 的 |delim_t| 格式)在索引项末加上 |\SeealsoPrintList| 输出 % 参见列表。 % % \subsection{\cs{see} 与 \cs{seealso} 命令} % % \DescribeMacro{\seepage} % \DescribeMacro{\seealsopage} % |\seepage| 与 |\seealsopage| 提供了宏包的主要功能,它们与原始的 % |\see|、|\seealso| 命令类似提供索引项的交叉引用功能,但同时会输出页码,并避 % 免重复输出交叉引用。例如,在文档中第 1, 2, 3 页分别多次使用 % \begin{Verbatim} % \index{foo|seepage{bar}} % \end{Verbatim} % 则在 |.ind| 文件中会生成: % \begin{Verbatim} % foo, \seepage{bar}{1}, \seepage{bar}{2}, \seepage{bar}{3} % \end{Verbatim} % 而输出的结果将会是: % \begin{quote} % foo, \seepage{bar}{1}, \seepage{bar}{2}, \seepage{bar}{3} % \end{quote} % % 同一个词可以有不同的参见引用项目,例如在不同的位置几次使用 % \begin{Verbatim} % \index{foo|seepage{bar}} % \end{Verbatim} % 和 % \begin{Verbatim} % \index{foo|seepage{foobaz}} % \end{Verbatim} % 则 |.ind| 文件中可能生成: % \begin{Verbatim} % foo, \seepage{bar}{1}, \seepage{bar}{2}, \seepage{foobaz}{3} % \end{Verbatim} % 于是将得到输出结果 % \begin{quote} % foo, \seepage{bar}{1}, \seepage{bar}{2}, \seepage{foobaz}{3} % \end{quote} % % \DescribeMacro{\seenopage} % \DescribeMacro{\seealsonopage} % |\seenopage| 与 |\seealsonopage| 这两个宏则保存了在调用 \pkg{seealso} 宏包之 % 前,|\see| 与 |\seealso| 的原始定义,它们不会输出页码。 % % \DescribeMacro{\see} % \DescribeMacro{\seealso} % 在默认的 |override| 选项下,|\see| 与 |\seealso| 的功能与 % |\seepage|、|\seealsopage| 相同。 % % \DescribeMacro{\SeealsoPrintList} % |\seepage| 和 |\seealsopage| 会收集参见列表,在默认的 |activecr| 选项为 % |ture| 时会在行末自动输出。但如果 |activecr| 选项设置为 |false|,则 % |\seepage| 与 |\seealsopage| 所在行结束后不会自动输出参见列表。此时,可以手 % 工在此行最后加上 |\SeealsoPrintList| 宏,输出参见列表。通常可以在 Makeindex % 的格式文件中,输出格式选项 |delim_t| 里面加上 |\SeealsoPrintList| 宏,如: % \begin{Verbatim} % % example.ist % delim_t "\\SeealsoPrintList" % \end{Verbatim} % 这样,每个非空索引项输出的最后都会加上 |\SeealsoPrintList|,按需要输出参见列 % 表。 % % \DescribeMacro{\DeclareSeealsoMacro} % |\DeclareSeealsoMacro| 命令用于生成新的类似 |\see| 与 |\seealso| 的宏。其语 % 法为: % \begin{quote} % |\DeclareSeealsoMacro\|\meta{macro}|{|\meta{seelist}|}{|\meta{name}|}| % \end{quote} % 其中 |\|\meta{macro} 是新的宏名称,\meta{seelist} 是新的参见列表 % 名,\meta{name} 是输出参见列表时的名称。使用该命令会生成两个宏,一个是 % |\|\meta{macro},一个是对应的名称 |\|\meta{macro}|name|。 % |\|\meta{macro}|name| 如果事先没有定义,则定义其值为 \meta{name},否则保持不 % 变。 % % 例如,|\seepage| 和 |\seealsopage| 就是这样定义的: % \begin{Verbatim} % \DeclareSeealsoMacro\seepage{see}{see} % \DeclareSeealsoMacro\seealsopage{also}{see also} % \end{Verbatim} % 上述命令同时定义了 |\seename| 的备选值为 |see|,以及 |\alsoname| 的备选值为 % |see also|。 % % \subsection{格式设置} % % \DescribeMacro{\seealsosetup} % |\seealsosetup| 命令用于设置参见列表的输出格式。其语法为: % \begin{quote} % |\seealsosetup[|\meta{seelists}|]{|\meta{kv-options}|}| % \end{quote} % 其中,可选参数 \meta{seelists} 是一个逗号分隔的列表,每一项表示要设置其格式 % 的参见列表,如果不设置 \meta{seelists} 或设为空,则设置默认的输出格式。而选 % 项 \meta{kv-options} 则是输出格式项。 % % 可用的输出格式见表~\ref{tab:outstylezh}。 % \begin{table}[htbp] % \centering % \begin{tabular}{llll} % \hline % 选项 & 意义 & 参数 & 默认值 \\ % \hline % |name| & 输出参见列表的名称 & 无 & (不可用) \\ % |listsep| & 参见列表前的分隔符 & 无 & \stylemeaning{listsep} \\ % |itemsep| & 参见列表项间的分隔符 & 无 & \stylemeaning{itemsep} \\ % |nameformat| & 输出参见名“see also”的格式 & |#1| & \stylemeaning{nameformat} \\ % |itemformat| & 参见列表项的格式 & |#1| & \stylemeaning{itemformat} \\ % |pageformat| & 页码格式 & |#1| & \stylemeaning{pageformat} \\ % \hline % \end{tabular} % \def\tablename{表} % \caption{\cs{seealsosetup} 使用的输出格式}\label{tab:outstylezh} % \end{table} % % 例如,如果要让所有 |\seealsopage| 命令生成的页码以斜体显示,就可以使用 % \begin{Verbatim} % \seealsosetup[also]{pageformat=\textit{#1}} % \end{Verbatim} % % \DescribeMacro{\SeealsoGobble} % |\SeealsoGobble| 宏接受一个字符作为参数,它检查后面是否有此字符,如果是则吞 % 掉此字符及后面的空格,否则什么都不做。在 |pageformat| 选项中使用这个宏可以用 % 来禁止显示参见项的页码,像下面这样: % \begin{Verbatim} % \seealsosetup[see,also]{pageformat=\SeealsoGobble{,}, listsep=} % \end{Verbatim} % 但注意使用 \pkg{hyperref} 时,|\see|、|\seealso| 等命令会被 % |\hyperindexformat| 所包裹,使这种方法会失效。 % % \section{已知问题} % % 以下是一些已知的问题和解决方案: % \begin{itemize} % \item % Makeindex 会按输出选项 |line_max| 对输出的内容进行折行,默认的 |line_max| 只 % 有 72,所以当项目较多时,可能在 |\see| 或 |\seealso| 等命令所在的项目中产生 % 折行。但由于默认情况下(|activecr| 选项打开)\pkg{seealso} 包遇到换行符就会 % 输出参见列表,会造成错误。一种解决方法是将 |line_max| 设置得很大,避免折行; % 另一种解决方法是设置 |activecr=false|,同时在 Makeindex 的格式文件中显式设置 % |delim_t| 为 |\SeealsoPrintList| 来输出参见列表。 % % \item % 由于 |\seepage|, |\seealsopage| 的页码显示形式与普通页码相同,所以可能会造成 % 页码重叠的情况。最好尽量避免交叉引用的项目有多种形式的索引。如果不能避免,为 % 解决此问题,可以设置特别的页码输出格式以示区分,或者借用 |\SeealsoGobble| 设 % 置不输出页码。 % % \item % 在使用 \pkg{hyperref} 功能时,用 |\SeealsoGobble| 禁止显示页码的功能会失效。 % 这是因为 |\see|、|\seealso| 等命令会被 |\hyperindexformat| 包裹。为解决此问 % 题,可以设置 \pkg{hyperref} 的选项 |hyperindex=false| 禁用索引的超链接,或者 % 考虑对 \pkg{hyperref} 做特殊的补丁。 % \end{itemize} % % \StopEventually{} % % \clearpage % \section{Implementation / 代码实现} % % \iffalse %<*package> % \fi % % \subsection{准备工作} % % 引入相关编程工具。 % \begin{macrocode} \RequirePackage{etoolbox} \RequirePackage{kvoptions} \SetupKeyvalOptions{ family=seealso@opt, prefix=seealso@} % \end{macrocode} % % 声明宏包选项。 % % \begin{option}{override} % \changes{v1.0}{2014/04/05}{新增选项。} % 重定义 |\see| 与 |\seealso| 为有页码的形式。默认打开。 % \begin{macrocode} \DeclareBoolOption[true]{override} % \end{macrocode} % \end{option} % % \begin{option}{activecr} % \changes{v1.0}{2014/04/05}{新增选项。} % 使用换行符作为输出 |\see| 等命令的指令。默认打开。 % \begin{macrocode} \DeclareBoolOption[true]{activecr} % \end{macrocode} % \end{option} % % 执行选项。 % \begin{macrocode} \ProcessKeyvalOptions* % \end{macrocode} % % \begin{macro}{\seealso@charlet} % 参数 |#1| 是一个字符或 |\| 加字符的形式,|\seealso@charlet| 将此字符看做活动 % 字符的宏,使用 |\let| 与后面的内容赋值,但本身不改变字符的 catcode。 % \begin{macrocode} \def\seealso@charlet#1{% \begingroup\lccode`\~=`#1\lowercase{\endgroup\let~}} % \end{macrocode} % \end{macro} % % \subsection{参见列表及其实现} % % \begin{macro}{\seealso@macrolist} % 列表记录所有独立的类似 |\seepage| 的宏。默认只有 |see| 和 |also| 两组,对应 % 命令 |\seepage| 和 |\seealsopage|。 % \begin{macrocode} \let\seealso@macrolist\empty % \end{macrocode} % \end{macro} % % \begin{macro}{\seealso@clearlists} % 清空参见列表,如 |\seealso@see@list|、|\seealso@also@list|。 % \begin{macrocode} \def\seealso@clearlists{% \def\do##1{\cslet{seealso@##1@list}\empty}% \dolistloop\seealso@macrolist} \AtBeginDocument{\seealso@clearlists} % \end{macrocode} % \end{macro} % % \begin{macro}{\SeealsoPrintList} % 输出参见列表,如 |\seealso@see@list|、|\seealso@also@list|。 % \begin{macrocode} \newcommand\SeealsoPrintList{% \forlistloop\seealso@printlist\seealso@macrolist \seealso@clearlists} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifseealso@firstitem} % 测试是否是在输出参见列表的第一项。 % \begin{macrocode} \newif\ifseealso@firstitem % \end{macrocode} % \end{macro} % % \begin{macro}{\seealso@printlist} % 输出参见列表 |#1|。如果列表为空则无操作。 % \begin{macrocode} \def\seealso@printlist#1{% \ifcsempty{seealso@#1@list} {} {\csuse{seealso@#1@listsep}% \csuse{seealso@#1@nameformat}{\csuse{#1name}}% \seealso@firstitemtrue \forlistcsloop{\seealso@listitem{#1}}{seealso@#1@list}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\seealso@listitem} % 输出参见列表的一项。如果不是第一项,同时输出分隔符。 % \begin{macrocode} \def\seealso@listitem#1#2{% \ifseealso@firstitem \seealso@firstitemfalse \else \csuse{seealso@#1@itemsep}% \fi \csuse{seealso@#1@itemformat}{#2}} % \end{macrocode} % \end{macro} % % \begin{macro}{\DeclareSeealsoMacro} % \changes{v1.0}{2014/04/05}{新增以定义新的参见命令。} % 定义一个新的带页码的参见命令。|#1| 是命令名,|#2| 是该命令使用的参见列 % 表,|#3| 是列表输出时使用的名字。 % \begin{macrocode} \newcommand\DeclareSeealsoMacro[3]{% % \end{macrocode} % 首先定义参见命令 |#1| 本身。 % \begin{macrocode} \newcommand#1[2]{% \seealso@setactivecr \ifinlistcs{##1}{seealso@#2@list} {} {\listcsgadd{seealso@#2@list}{##1}}% \csuse{seealso@#2@pageformat}{##2}}% % \end{macrocode} % 将参见命令加入列表。 % \begin{macrocode} \listadd\seealso@macrolist{#2}% % \end{macrocode} % 定义 |name| 选项,用来设置 |\|\meta{macro}|name|。如 |\seename| 和 % |\alsoname|。 % \begin{macrocode} \define@key{seealso@#2}{name}{% \csdef{#2name}{##1}}% % \end{macrocode} % 如果事先没有定义,则定义 |\|\meta{macro}|name| 为 |#3|。 % \begin{macrocode} \ifcsdef{#2name} {} {\setkeys{seealso@#2}{name=#3}}% % \end{macrocode} % 定义无参选项。 % \begin{macrocode} \def\do##1{% \define@key{seealso@#2}{##1}{% \csdef{seealso@#2@##1}{####1}}% \setkeys{seealso@#2}{##1=\csuse{seealso@##1}}}% \docsvlist{listsep,itemsep}% % \end{macrocode} % 定义有一个参数的选项。 % \begin{macrocode} \def\do##1{% \define@key{seealso@#2}{##1}{% \csdef{seealso@#2@##1}########1{####1}}% \setkeys{seealso@#2}{##1=\csuse{seealso@##1}{####1}}}% \docsvlist{nameformat,itemformat,pageformat}} \@onlypreamble{\DeclareSeealsoMacro} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifseealso@iscractive} % 判断当前换行符是否已经被激活。 % \begin{macrocode} \newif\ifseealso@iscractive % \end{macrocode} % \end{macro} % % \begin{macro}{\seealso@setactivecr} % |activecr| 选项为真时,设置换行符为 |\seealso@cr| 并激活。 % \begin{macrocode} \def\seealso@setactivecr{% \ifseealso@activecr \unless\ifseealso@iscractive \catcode`\^^M=\active \seealso@charlet\^^M\seealso@cr \seealso@iscractivetrue \fi \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\seealso@cr} % 是在 |activecr| 选项下,换行符的定义。它取消激活换行符为宏,并输出参见列表。 % \begin{macrocode} \def\seealso@cr{% \catcode`\^^M=5 \seealso@iscractivefalse \SeealsoPrintList} % \end{macrocode} % \end{macro} % % 下面定义参见列表的默认输出格式。以下宏给出的都是全局的默认值,可以单独修改每 % 一项的输出格式。 % \begin{macro}{\seealso@listsep} % 参见列表之前的分隔符。 % \begin{macrocode} \def\seealso@listsep{,\space} % \end{macrocode} % \end{macro} % \begin{macro}{\seealso@itemsep} % 参见列表项之间的分隔符。 % \begin{macrocode} \def\seealso@itemsep{,\space} % \end{macrocode} % \end{macro} % \begin{macro}{\seealso@nameformat} % 参见名“see also”的输出格式。 % \begin{macrocode} \def\seealso@nameformat#1{\emph{#1}\space} % \end{macrocode} % \end{macro} % \begin{macro}{\seealso@itemformat} % 参见列表项的输出格式。 % \begin{macrocode} \def\seealso@itemformat#1{#1} % \end{macrocode} % \end{macro} % \begin{macro}{\seealso@pageformat} % 参见页码的输出格式。 % \begin{macrocode} \def\seealso@pageformat#1{#1} % \end{macrocode} % \end{macro} % % \begin{macro}{\seealso@define@key} % \begin{macro}{\seealso@define@keyarg} % 定义 |seealso| 族的键,用于设置输出格式。 % \begin{macrocode} \def\seealso@define@key#1{% \define@key{seealso}{#1}{% \csdef{seealso@#1}{##1}}} \def\seealso@define@keyarg#1{% \define@key{seealso}{#1}{% \csdef{seealso@#1}####1{##1}}} % \end{macrocode} % \end{macro} % \end{macro} % 为每个输出格式定义键。 % \begin{macrocode} \forcsvlist\seealso@define@key{listsep,itemsep} \forcsvlist\seealso@define@keyarg{nameformat,itemformat,pageformat} % \end{macrocode} % % \begin{macro}{\SeealsoGobble} % \changes{v1.0}{2014/04/06}{支持吞掉分隔符的页码格式,即不显示页码。} % 检查后面的字符是否 |#1|,如果是则吞掉分隔符 |#1| 及后面的空格。这个宏可用于 % 设置 |pageformat| 格式,吞掉一个类似 |,\space| 类型的分隔符。 % \begin{macrocode} \def\SeealsoGobble#1{\@ifnextchar#1{\seealso@gobbleignorespaces}{}} % \end{macrocode} % \end{macro} % \begin{macro}{\seealso@gobbleignorespaces} % 吞掉参数并忽略后面的空格。 % \begin{macrocode} \def\seealso@gobbleignorespaces#1{\ignorespaces} % \end{macrocode} % \end{macro} % % \subsection{定义用户接口} % % \begin{macro}{\seealsosetup} % \changes{v1.0}{2014/04/05}{新增格式设置。} % 设置输出格式。可选参数是一个逗号列表:如果可选参数为空,用 |#2| 设置默认的输 % 出格式;否则对可选参数的每一项,设置参数 |#2| 的格式。使用 |\forcsvlist| 而 % 没有使用 |\docsvlist| 是为了避免因嵌套定义造成使用时参数不得不使用双重 % |##|。 % \begin{macrocode} \newcommand\seealsosetup[2][]{% \ifstrempty{#1}{% \setkeys{seealso}{#2}% }{% \def\do##1{\setkeys{seealso@##1}{#2}}% \forcsvlist{\do}{#1}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\seenopage} % \begin{macro}{\seealsonopage} % 保存旧的 |\see| 与 |\seealso| 命令定义,使用 |override| 选项时可临时使用旧的 % 定义。 % \begin{macrocode} \let\seenopage\see \let\seealsonopage\seealso % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\seepage} % \begin{macro}{\seealsopage} % 带页码输出的 |\seepage| 与 |\seealsopage|。使用 |override| 选项时可直接使用 % |\see| 与 |\seealso| 代替 |\seepage| 与 |\seealsopage|。 % % 如果之前没有定义,这里会同时定义 |\seename| 和 |\alsoname|,与 \pkg{makeidx} % 初始值一致。 % \begin{macrocode} \DeclareSeealsoMacro\seepage{see}{see} \DeclareSeealsoMacro\seealsopage{also}{see also} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\see} % \begin{macro}{\seealso} % 使用 |override| 时,重定义 |\see| 与 |\seealso|。 % \begin{macrocode} \ifseealso@override \def\see{\seepage} \def\seealso{\seealsopage} \fi % \end{macrocode} % \end{macro} % \end{macro} % % \iffalse % % \fi % % \Finale \endinput