cgal/Manual_tools/sty/cc_manual_index.sty

1982 lines
63 KiB
TeX

% ========================================================================
% CGAL reference manual indexing style file
%
% $Id$
% ========================================================================
%
% Make sure the cc_manual style file is included since some of the commands
% used in this file are defined there
%
\usepackage{cc_manual}
\usepackage{makeidx}
%\RCSdef{\ccRevision}{$Id$}
%\RCSdefDate{\ccDate}{$Date$}
% Print a release note.
\catcode`\@=11\relax
\newwrite\@unused
\def\typeout#1{{\let\protect\string\immediate\write\@unused{#1}}}
\catcode`\@=12\relax
% ========================================================================
% Definitions of fonts for the different categories of non-C++ items
% ========================================================================
\def\ccUnderscoreFont{}
\def\ccIndexAbbreviationFont{}
%\def\ccIndexConceptFont{\ccUnderscoreFont}
\def\ccIndexConceptFont{}
\def\ccIndexFunctionalityFont{}
\def\ccIndexDSFont{}
\def\ccIndexHintFont{}
\def\ccIndexLibraryFont{}
\def\ccIndexPackageFont{}
\def\ccIndexTermFont{}
\newcount\ccIndex \ccIndex=\ccTrue%
\newcount\ccAutoIndex \ccAutoIndex=\ccTrue%
\newcount\ccIndexCrossRef \ccIndexCrossRef=\ccTrue%
\newcount\ccIndexModifierCrossRef \ccIndexModifierCrossRef=\ccTrue%
% ========================================================================
% Text that is between a pair of ccIndexingOff and ccIndexingOn commands
% will not produce any entries in the index, automatically or otherwise
% ========================================================================
\newcommand{\ccIndexingOff}{\ccIndex=\ccFalse}%
\newcommand{\ccIndexingOn}{\ccIndex=\ccTrue}%
% ========================================================================
% Text that is between a pair of ccAutoIndexingOff and ccAutoIndexingOn
% commands will not produce any entries in the index automatically.
% You can do indexing manually, though, using any of the commands.
% ========================================================================
\newcommand{\ccAutoIndexingOff}{\ccAutoIndex=\ccFalse}%
\newcommand{\ccAutoIndexingOn}{\ccAutoIndex=\ccTrue}%
% ========================================================================
% Text that is between a pair of ccModifierCrossRefOff and
% ccModifierCrossRefOn commands will not produce cross referencing entries
% automatically for main item text that contains a comma.
% ========================================================================
\newcommand{\ccModifierCrossRefOff}{\ccIndexModifierCrossRef=\ccFalse}%
\newcommand{\ccModifierCrossRefOn}{\ccIndexModifierCrossRef=\ccTrue}%
% ========================================================================
% Text that is between a pair of ccNonmodifierCrossRefOff and
% ccNonmodifierCrossRefOn commands will produce cross referencing entries
% automatically only for main item text that contains a comma.
% ========================================================================
\newcommand{\ccNonmodifierCrossRefOff}{\ccIndexCrossRef=\ccFalse}%
\newcommand{\ccNonmodifierCrossRefOn}{\ccIndexCrossRef=\ccTrue}%
% ========================================================================
% Text that is between a pair of ccCrossRefOff and ccCrossRefOn commands
% will not produce ANY cross referencing entries automatically.
% ========================================================================
\newcommand{\ccCrossRefOff}{\ccIndexModifierCrossRef=\ccFalse%
\ccIndexCrossRef=\ccFalse}%
\newcommand{\ccCrossRefOn}{\ccIndexModifierCrossRef=\ccTrue%
\ccIndexCrossRef=\ccTrue}%
% ------------------------------------------------------------------------
% Commands needed for including indexing characters in the index
% ------------------------------------------------------------------------
\def\doubleVerticalBar{||}
\def\singleVerticalBar{|}
\def\verticalBarEqual{|=}
\def\doubleExclamation{!!}
\def\singleExclamation{!}
\def\doubleAmpersand{\&\&}
\def\singleAmpersand{\&}
\def\ampersandEqual{\&=}
\def\exclamationEqual{!=}
\def\singleAt{@}
% ========================================================================
% Generic indexing macros
%
% The following 14 commands are generic commands for producing main items,
% subitems, and subsubitems in the index. For each of these three types of
% entries, there are four kinds of commands:
%
% 1. produce a single page number entry
% 2. begin an entry with a range of pages associated with it
% 3. end an entry with a range of pages associated with it
% 4. produce a definition entry (single page number in bold face type)
%
% There are also 2 commands, one for subitems and one for subsubitems,
% for producing "see also <text>" entries
%
% Each of these commands requires some number of arguments which supply
% the text to be used in indexing. Main item commands require 1 argument;
% subitem commands require 2 arguments (main item and subitem text);
% subsubitem commands require 3 arguments (main item, subitem, and subsubitem
% text).
%
% All 14 commands have an optional argument, which is the category of
% the main item being indexed. The valid values for this category argument
% are:
% C -- for class or other C++ name
% c -- for concept
% d -- for data structure
% f -- for functionality
% h -- for hint
% l -- for library
% p -- for package
% t -- for term
% The default value of this argument is empty, indicating an entry that
% does not fall into any of the established categories for the index.
% Depending on the category specified, the appropriate font will be used
% to format the main item text. Fonts can also be supplied in the
% text arguments and these fonts override any font indicated by the
% category argument.
% ========================================================================
% ------------------------------------------------------------------------
% Main item generic indexing macros
% ------------------------------------------------------------------------
%
% Usage: \ccIndexMainItem[category]{item}
%
\newcommand{\ccIndexMainItem}[2][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\ifx\empty\mainSeeText%
\index{\mainText}%
\else%
\index{\mainText}%
\index{\mainSeeText}%
\fi%
\fi%
}
%
% Usage: \ccIndexMainItemBegin[category]{item with range}
% ... <item description> ...
% \ccIndexMainItemEnd[cateogry]{item with range}
%
\newcommand{\ccIndexMainItemBegin}[2][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\ifx\empty\mainSeeText%
\index{\mainText|(}%
\else%
\index{\mainText|(}%
\index{\mainSeeText}%
\fi%
\fi%
}
\newcommand{\ccIndexMainItemEnd}[2][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\ifx\empty\mainSeeText%
\index{\mainText|)}%
\else%
\index{\mainText|)}%
\index{\mainSeeText}%
\fi%
\fi%
}
%
% Usage: \ccIndexMainItemDef[category]{item}
%
\newcommand{\ccIndexMainItemDef}[2][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\ifx\empty\mainSeeText%
\index{\mainText|textbf}%
\else%
\index{\mainText|textbf}%
\index{\mainSeeText}%
\fi%
\fi%
}
% ------------------------------------------------------------------------
% Subitem generic indexing macros
% ------------------------------------------------------------------------
%
% Usage: \ccIndexSubitem[category]{item}{subitem}
%
\newcommand{\ccIndexSubitem}[3][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\subitemTextParse{#3}%
\ifx\empty\mainSeeText%
\index{\mainText!\subitemText}%
\else%
\index{\mainText!\subitemText}%
\index{\mainSeeText}%
\fi%
\fi%
}
%
% Usage: \ccIndexOperatorSubitem{item}{subitem}
%
\newcommand{\ccIndexOperatorSubitem}[2]{%
\ifnum\ccIndex=\ccTrue%
\subitemTextParse{#2}%
\ifnum\ccOperatorCat=\ccDoubleVerticalBar%
\index{#1@$\protect\doubleVerticalBar$!\subitemText}%
\else\ifnum\ccOperatorCat=\ccSingleVerticalBar%
\index{#1@$\protect\singleVerticalBar$!\subitemText}%
\else\ifnum\ccOperatorCat=\ccVerticalBarEqual%
\index{#1@$\protect\verticalBarEqual$!\subitemText}%
\else\ifnum\ccOperatorCat=\ccDoubleExclamation%
\index{#1@$\protect\doubleExclamation$!\subitemText}%
\else\ifnum\ccOperatorCat=\ccSingleExclamation%
\index{#1@$\protect\singleExclamation$!\subitemText}%
\else\ifnum\ccOperatorCat=\ccSingleAmpersand%
\index{#1@$\protect\singleAmpersand$!\subitemText}%
\else\ifnum\ccOperatorCat=\ccDoubleAmpersand%
\index{#1@$\protect\doubleAmpersand$!\subitemText}%
\else\ifnum\ccOperatorCat=\ccAmpersandEqual%
\index{#1@$\protect\ampersandEqual$!\subitemText}%
\else\ifnum\ccOperatorCat=\ccExclamationEqual%
\index{#1@$\protect\exclamationEqual$!\subitemText}%
\else\ifnum\ccOperatorCat=\ccSingleAt%
\index{#1@$\protect\singleAt$!\subitemText}%
%
% the ~, % and ^ operators need a change in catcode in order to work properly
% so they are used with ccc. ccc cannot be used for the other operands since
% the actual characters must not be put in the index (they have special
% meaning in the index) and ccc will expand its arguments.
%
\else\ifnum\ccOperatorCat=\ccTildeOperator%
\index{#1@\protect\ccc{#1}!\subitemText}%
\else\ifnum\ccOperatorCat=\ccModOperator%
\index{#1@\protect\ccc{#1}!\subitemText}%
\else\ifnum\ccOperatorCat=\ccModEqualOperator%
\index{#1@\protect\ccc{#1}!\subitemText}%
\else\ifnum\ccOperatorCat=\ccPowerOperator%
\index{#1@\protect\ccc{#1}!\subitemText}%
\else\ifnum\ccOperatorCat=\ccPowerEqualOperator%
\index{#1@\protect\ccc{#1}!\subitemText}%
\else
\index{#1@$#1$!\subitemText}%
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
\fi%
}
%
% Usage: \ccIndexSubitemBegin[category]{item}{subitem}
% ... <subitem description> ...
% \ccIndexSubitemEnd[category]{item}{subitem}
%
\newcommand{\ccIndexSubitemBegin}[3][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\subitemTextParse{#3}%
\ifx\empty\mainSeeText%
\index{\mainText!\subitemText|(}%
\else%
\index{\mainText!\subitemText|(}%
\index{\mainSeeText}%
\fi%
\fi%
}
\newcommand{\ccIndexSubitemEnd}[3][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\subitemTextParse{#3}%
\ifx\empty\mainSeeText%
\index{\mainText!\subitemText|)}%
\else%
\index{\mainText!\subitemText|)}%
\index{\mainSeeText}%
\fi%
\fi%
}
%
% Usage: \ccIndexSubitemDef[category]{item}{subitem}
%
\newcommand{\ccIndexSubitemDef}[3][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\subitemTextParse{#3}%
\ifx\empty\mainSeeText%
\index{\mainText!\subitemText|textbf}%
\else%
\index{\mainText!\subitemText|textbf}%
\index{\mainSeeText}%
\fi%
\fi%
}
%
% Usage: \ccIndexSubitemSeeAlso[category]{item}{subitem}
%
\newcommand{\ccIndexSubitemSeeAlso}[3][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\subitemSeeAlsoTextParse{#3}%
\ifx\empty\mainSeeText%
\index{\mainText!\subitemSeeAlsoText|none}%
\else%
\index{\mainText!\subitemSeeAlsoText|none}%
\index{\mainSeeText}%
\fi%
\fi%
}
% ------------------------------------------------------------------------
% Subsubitem generic indexing macros
% ------------------------------------------------------------------------
%
% Usage: \ccIndexSubsubitem[category]{item}{subitem}{subsubitem}
%
\newcommand{\ccIndexSubsubitem}[4][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\subitemTextParse{#3}%
\subsubitemTextParse{#4}%
\ifx\empty\mainSeeText%
\index{\mainText!\subitemText!\subsubitemText}%
\else%
\index{\mainText!\subitemText!\subsubitemText}%
\index{\mainSeeText}%
\fi%
\fi%
}
%
% Usage: \ccIndexSubsubitemBegin[category]{item}{subitem}{subsubitem}
% ... <subsubitem description> ...
% \ccIndexSubsubitemEnd[category]{item}{subitem}{subsubitem}
%
\newcommand{\ccIndexSubsubitemBegin}[4][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\subitemTextParse{#3}%
\subsubitemTextParse{#4}%
\ifx\empty\mainSeeText%
\index{\mainText!\subitemText!\subsubitemText|(}%
\else%
\index{\mainText!\subitemText!\subsubitemText|(}%
\index{\mainSeeText}%
\fi%
\fi%
}
\newcommand{\ccIndexSubsubitemEnd}[4][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\subitemTextParse{#3}%
\subsubitemTextParse{#4}%
\ifx\empty\mainSeeText%
\index{\mainText!\subitemText!\subsubitemText|)}%
\else%
\index{\mainText!\subitemText!\subsubitemText|)}%
\index{\mainSeeText}%
\fi%
\fi%
}
%
% Usage: \ccIndexSubsubitemDef[category]{item}{subitem}{subsubitem}
%
\newcommand{\ccIndexSubsubitemDef}[4][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\subitemTextParse{#3}%
\subsubitemTextParse{#4}%
\ifx\empty\mainSeeText%
\index{\mainText!\subitemText!\subsubitemText|textbf}%
\else%
\index{\mainText!\subitemText!\subsubitemText|textbf}%
\index{\mainSeeText}%
\fi%
\fi%
}
%
% Usage: \ccIndexSubsubitemSeeAlso[category]{item}{subitem}{subsubitem}
%
\newcommand{\ccIndexSubsubitemSeeAlso}[4][]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{{#1}}{#2}%
\subitemTextParse{#3}%
\subsubitemSeeAlsoTextParse{#4}%
\ifx\empty\mainSeeText%
\index{\mainText!\subitemText!\subsubitemSeeAlsoText|none}%
\else%
\index{\mainText!\subitemText!\subsubitemSeeAlsoText|none}%
\index{\mainSeeText}%
\fi%
\fi%
}
% ========================================================================
% Assertion flag macros
% ========================================================================
%
% Usage: \ccIndexAssertionFlagsUse
%
\newcommand{\ccIndexAssertionFlagsUse}{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItem{assertion flags}%
\fi%
}
%
% Usage: \ccIndexAssertionFlagName{flag_name}
%
\newcommand{\ccIndexAssertionFlagName}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItem[C]{#1}%
\fi%
}
% ========================================================================
% Enums, enum tags, global structs, global variables, global constants
% global functions, typedefs
% ========================================================================
%
% Usage: \ccIndexEnum{enum}
%
\newcommand{\ccIndexEnum}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItem[C]{#1}%
\fi%
}
%
% Usage: \ccIndexEnum{enum_tag}
%
\newcommand{\ccIndexEnumTag}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItem[C]{#1}%
\fi%
}
%
% Usage: \ccIndexGlobalStruct{struct}
%
\newcommand{\ccIndexGlobalStruct}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItem[C]{#1}%
\fi%
}
%
% Usage: \ccIndexGlobalVariable{variable}
%
\newcommand{\ccIndexGlobalVariable}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItem[C]{#1}%
\fi%
}
%
% Usage: \ccIndexGlobalConstant{constant}
%
\newcommand{\ccIndexGlobalConstant}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItem[C]{#1}%
\fi%
}
%
% Usage: \ccIndexMacro{macro_name}
%
\newcommand{\ccIndexMacro}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItem[C]{#1}%
\fi%
}
%
% Usage: \ccIndexGlobalFunction{function}
%
\newcommand{\ccIndexGlobalFunction}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItem[C]{#1}%
\fi%
}
% Usage: \ccIndexGlobalFunctionBegin{function}
% <function description>
% \ccIndexGlobalFunctionEnd{function}
%
\newcommand{\ccIndexGlobalFunctionBegin}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItemBegin[C]{#1}%
\fi%
}
\newcommand{\ccIndexGlobalFunctionEnd}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItemEnd[C]{#1}%
\fi%
}
%
% Usage: \ccIndexGlobalOperator{operator}{class name}
%
% Note: operator must not contain one of the "special" index charcters.
% In other words, it should have already passed through
% \escapeIndexOperatorSymbols
\newcommand{\ccIndexGlobalOperator}[2]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexOperatorSubitem{#1}{\ccFont #2}%
\fi%
}
%
% Usage: \ccIndexTypedef{typedef}
%
\newcommand{\ccIndexTypedef}[1]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItem[C]{#1}%
\fi%
}
% ========================================================================
% Member functions
% ========================================================================
%
% Usage: \ccIndexMemberFunction{function_name}
%
\newcommand{\ccIndexMemberFunction}[1]{%
\ifnum\ccIndex=\ccTrue%
\ifnum\inConcept=\ccTrue%
\ccIndexSubitem[C]{#1}{\ccIndexConceptFont \ccIndexClassName}%
\else
\ccIndexSubitem[C]{#1}{\ccFont \ccIndexClassName}%
\fi\fi%
}
%
% Usage: \ccIndexMemberFunctionBegin{function_name}
% <member function description>
% \ccIndexMemberFunctionEnd{function_name}
%
\newcommand{\ccIndexMemberFunctionBegin}[1]{%
\ifnum\ccIndex=\ccTrue%
\ifnum\inConcept=\ccTrue
\ccIndexSubitemBegin[C]{#1}{\ccIndexConceptFont \ccIndexClassName}%
\else
\ccIndexSubitemBegin[C]{#1}{\ccFont \ccIndexClassName}%
\fi\fi%
}
\newcommand{\ccIndexMemberFunctionEnd}[1]{%
\ifnum\ccIndex=\ccTrue%
\ifnum\inConcept=\ccTrue
\ccIndexSubitemEnd[C]{#1}{\ccIndexConceptFont \ccIndexClassName}%
\else
\ccIndexSubitemEnd[C]{#1}{\ccFont \ccIndexClassName}%
\fi\fi%
}
% ========================================================================
% Abbreviations
% ========================================================================
%
% Usage: \ccIndexAbbreviation{abbr}{unabbreviated term}
%
\newcommand{\ccIndexAbbreviation}[2]{%
\ifnum\ccIndex=\ccTrue%
\mainTextParse{a}{#1}%
\index{\mainText|see{{#2}}}
\ifnum\ccIndexCrossRef=\ccTrue%
\ccIndexMainItem{#2}%
\fi%
\fi
}
% ========================================================================
% Hints as subitems and subsubitems
% ========================================================================
%
% Usage: \ccIndexHintAsSubitem[category]{item}{hint}
% where category is an optional argument with the following possible
% values
% C -- for class or other C++ name
% c -- for concept
% d -- for data structure
% f -- for functionality
% h -- for hint
% l -- for library
% p -- for package
% t -- for term
%
\newcommand{\ccIndexHintAsSubitem}[3][]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexSubitem[#1]{#2}{\ccIndexHintFont #3}%
\fi%
}
%
% Usage: \ccIndexHintAsSubitem[category]{item}{subitem}{hint}
%
\newcommand{\ccIndexHintAsSubsubitem}[4][]{%
\ifnum\ccIndex=\ccTrue%
\ccIndexSubsubitem[#1]{#2}{#3}{\ccIndexHintFont #4}%
\fi%
}
% ========================================================================
% Classes
% ========================================================================
\newcommand{\ccIndexClassName}{}%
% ------------------------------------------------------------------------
% Environment to be used for indexing classes if the automatic indexing
% doesn't do the right thing.
%
%
% Usage: \begin{ccIndexClass}{class name}
% ...<class description>...
% \end{ccIndexClass}
%
% ------------------------------------------------------------------------
\newenvironment{ccIndexClass}[1]{%
\ifnum\ccIndex=\ccTrue%
\isEmpty{#1}\ifnum\ccBool=\ccTrue%
\errmessage{The class name for indexing cannot be empty}
\else
\def\ccIndexClassName{#1}%
\ccIndexMainItemBegin[C]{\ccIndexClassName}%
\fi
\fi%
}
{%
\ifnum\ccIndex=\ccTrue%
\expandafter\isEmpty{\ccIndexClassName}\ifnum\ccBool=\ccFalse%
\ccIndexMainItemEnd[C]{\ccIndexClassName}%
\fi%
\fi%
}
% ========================================================================
% These macros MUST be used inside either a ccClass, ccTemplateClass or
% ccIndexClass environment since they employ the ccIndexClassName
% variable defined in these environments.
% ========================================================================
%
% Usage: \ccIndexClassCreation
%
\newcommand{\ccIndexClassCreation}{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue%
\errmessage{This command must be used inside a ccIndexClass, ccClass,
or ccTemplateClass environment. I'm going to ignore it}%
\else
\ccIndexSubitem[C]{\ccIndexClassName}{creation}%
\fi
\fi%
}
%
% Usage: \ccIndexClassDefault
%
\newcommand{\ccIndexClassDefault}{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue%
\errmessage{This command must be used inside a ccIndexClass, ccClass,
or ccTemplateClass environment. I'm going to ignore it}%
\else
\ccIndexSubitem[C]{\ccIndexClassName}{default}%
\fi \fi%
}
%
% Usage: \begin{ccIndexMemberFunctions}
% ...<member function descriptions>
% \end{IndexMemberFunctions}
%
\newenvironment{ccIndexMemberFunctions}{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue%
\errmessage{This command must be used inside a ccIndexClass, ccClass,
or ccTemplateClass environment. I'm going to ignore it}%
\else
\ccIndexSubitemBegin[C]{\ccIndexClassName}{member functions}%
\fi \fi%
}
{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccFalse
\ccIndexSubitemEnd[C]{\ccIndexClassName}{member functions}%
\fi \fi%
}
%
% Usage: \ccIndexMemberFunctionGroup{group}
%
\newcommand{\ccIndexMemberFunctionGroup}[1]{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue
\errmessage{This command must be used inside a ccIndexClass, ccClass,
or ccTemplateClass environment. I'm going to ignore it}%
\else
\ccIndexSubsubitem[C]{\ccIndexClassName}{member functions}{#1}%
\ifnum\ccIndexCrossRef=\ccTrue%
\ccIndexSubitem{#1}{\ccFont \ccIndexClassName}%
\fi%
\fi
\fi%
}
%
% Usage: \ccIndexNestedClasses
%
\newcommand{\ccIndexNestedClasses}{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue
\errmessage{This command must be used inside a ccIndexClass, ccClass,
or ccTemplateClass environment. I'm going to ignore it}%
\else
\ccIndexSubitem[C]{\ccIndexClassName}{nested classes}%
\fi
\fi%
}
%
% Usage: \ccIndexClassTypes
%
\newcommand{\ccIndexClassTypes}{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue
\errmessage{This command must be used inside a ccIndexClass, ccClass,
or ccTemplateClass environment. I'm going to ignore it}%
\else
\ccIndexSubitem[C]{\ccIndexClassName}{types}%
\fi
\fi%
}
% ========================================================================
% Packages
% ========================================================================
\newcommand{\ccIndexPackageName}{}%
\newenvironment{ccPackage}[1]{%
\isEmpty{#1}\ifnum\ccBool=\ccTrue
\errmessage{Package name cannot be empty}
\else
\def\ccIndexPackageName{#1}%
\ccIndexMainItemBegin[p]{\ccIndexPackageName}%
\fi
}
{%
\expandafter\expandafter\isEmpty{\ccIndexPackageName}%
\ifnum\ccBool=\ccFalse
\ccIndexMainItemEnd[p]{\ccIndexPackageName}%
\def\ccIndexPackageName{}%
\fi
}%
% ========================================================================
% Classes or Packages
% These macros MUST be used inside either a ccClass, ccTemplateClass,
% ccTraitsClass, ccTraitsClassTemplate, ccIndexClass, or ccPackage
% environment. They check first for inclusion in a class environment
% and then for inclusion in a package environment and if you are in
% both, only the class entry will be generated.
% ========================================================================
%
%
% Usage: \ccIndexAssertionFlag[package name]
%
\newcommand{\ccIndexAssertionFlag}[1][]{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue %
\expandafter\expandafter\isEmpty{\ccIndexPackageName}%
\ifnum\ccBool=\ccTrue
\errmessage{You must be inside a package or a class
environment to use this command. Go
on and I'll ignore this command}
\else
\ccIndexSubitem[p]{\ccIndexPackageName}{assertion flags}%
\ifnum\ccIndexCrossRef=\ccTrue
\ccIndexSubitem{assertion flags}{\ccIndexPackageName}%
\fi
\fi
\else
\isEmpty{#1}\ifnum\ccBool=\ccTrue
\errmessage{You must supply a package name for class \ccIndexClassName. I'm
going to ignore this command}
\else
\ccIndexSubitem[C]{\ccIndexClassName}{assertion flags}%
\ifnum\ccIndexCrossRef=\ccTrue
\ccIndexSubitem{assertion flags}{#1}%
\fi
\fi
\fi%
\fi%
}
%
% Usage: \ccIndexDesign
%
\newcommand{\ccIndexDesign}{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexPackageName}%
\ifnum\ccBool=\ccTrue
\errmessage{You must be inside a package or class
environment to use this command. Go
on and I'll ignore this command}
\else
\ccIndexSubitem[p]{\ccIndexPackageName}{design}%
\fi
\else
\ccIndexSubitem[C]{\ccIndexClassName}{design}%
\fi%
\fi%
}
%
% Usage: \begin{ccIndexGlobalFunctions}
% ... <global function descriptions> ...
% \end{ccIndexGlobalFunctions}
%
\newenvironment{ccIndexGlobalFunctions}{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue
\expandafter\expandafter\isEmpty{\ccIndexPackageName}%
\ifnum\ccBool=\ccTrue
\errmessage{You must be inside a package or class
environment to use this command. Go
on and I'll ignore this command}
\else
\ccIndexSubitemBegin[p]{\ccIndexPackageName}{global functions}%
\fi
\else
\ccIndexSubitemBegin[C]{\ccIndexClassName}{global functions}%
\fi%
\fi%
}
{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue
\expandafter\expandafter\isEmpty{\ccIndexPackageName}%
\ifnum\ccBool=\ccTrue
\errmessage{You must be inside a package or class
environment to use this command. Go
on and I'll ignore this command}
\else
\ccIndexSubitemEnd[p]{\ccIndexPackageName}{global functions}%
\fi
\else
\ccIndexSubitemEnd[C]{\ccIndexClassName}{global functions}%
\fi
\fi%
}
%
% Usage: \ccIndexGlobalFunctionGroup{group}
%
\newcommand{\ccIndexGlobalFunctionGroup}[1]{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexPackageName}%
\ifnum\ccBool=\ccTrue%
\errmessage{You must be inside a package or class
environment to use this command. Go
on and I'll ignore this command}
\else
\ccIndexSubsubitem[p]{\ccIndexPackageName}{global functions}{#1}%
\ifnum\ccIndexCrossRef=\ccTrue
\ccIndexSubitem{#1}{\ccIndexPackageFont \ccIndexPackageName}%
\fi
\fi
\else
\ccIndexSubsubitem[C]{\ccIndexClassName}{global functions}{#1}%
\ifnum\ccIndexCrossRef=\ccTrue
\ccIndexSubitem{#1}{\ccFont \ccIndexClassName}%
\fi
\fi
\fi%
}
%
% Usage: \ccIndexImplementation
%
\newcommand{\ccIndexImplementation}{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexPackageName}%
\ifnum\ccBool=\ccTrue%
\errmessage{You must be inside a package or class
environment to use this command. Go
on and I'll ignore this command}
\else
\ccIndexSubitem[p]{\ccIndexPackageName}{implementation}%
\fi
\else
\ccIndexSubitem[C]{\ccIndexClassName}{implementation}%
\fi%
\fi%
}
%
% Usage: \ccIndexRequirements
%
\newcommand{\ccIndexRequirements}{%
\ifnum\ccIndex=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexClassName}%
\ifnum\ccBool=\ccTrue%
\expandafter\expandafter\isEmpty{\ccIndexPackageName}%
\ifnum\ccBool=\ccTrue%
\errmessage{You must be inside a package or class
environment to use this command. Go
on and I'll ignore this command}
\else
\ccIndexSubitem[p]{\ccIndexPackageName}{requirements}%
\fi
\else
\ccIndexSubitem[C]{\ccIndexClassName}{requirements}%
\fi
\fi%
}
% ------------------------------------------------------------------------
% Traits classes associated with a class or package
% ------------------------------------------------------------------------
% #1 name of traits class
% #2 semicolon-separated list of associated classes
% #3 semicolon-separated list of associated packages
\newcommand\ccIndexTraitsClassBegin[3]{
\ifnum\ccIndex=\ccTrue%
\def\ccIndexClassName{#1}%
\ccIndexMainItemBegin[C]{\ccIndexClassName}%
\ifnum\ccIndexCrossRef=\ccTrue
\isEmpty{#2}\ifnum\ccBool=\ccFalse
\ccIndexTraitsClassForClasses{#2}
\fi
\isEmpty{#3}\ifnum\ccBool=\ccFalse
\ccIndexTraitsClassForPackages{#3}
\fi
\fi
\fi%
}
\newcommand\ccIndexTraitsClassEnd{
\ifnum\ccIndex=\ccTrue%
\ccIndexMainItemEnd[C]{\ccIndexClassName}%
\fi
\def\ccIndexClassName{}
}
\newcommand\ccIndexTraitsClassForClasses[1]{
\ccIndexTraitsClassForClassesX#1;/ccEnd%
}
\def\ccIndexTraitsClassForClassesX#1;#2/ccEnd{
\ccIndexSubsubitemSeeAlso[C]{#1}{traits class}{\ccFont \ccIndexClassName}%
\isEmpty{#2}\ifnum\ccBool=\ccFalse
\ccIndexTraitsClassForClassesX #2/ccEnd%
\fi
}
\newcommand\ccIndexTraitsClassForPackages[1]{
\ccIndexTraitsClassForPackagesX#1;/ccEnd%
}
\def\ccIndexTraitsClassForPackagesX#1;#2/ccEnd{
\ccIndexSubsubitemSeeAlso[p]{#1}{traits class}{\ccFont \ccIndexClassName}%
\isEmpty{#2}\ifnum\ccBool=\ccFalse
\ccIndexTraitsClassForPackagesX #2/ccEnd%
\fi
}
%
% Usage:
% \ccIndexTraitsClassDefault[p_or_C]{associated package or class}
%
\newcommand{\ccIndexTraitsClassDefault}[2][C]{%
\ifnum\ccIndex=\ccTrue%
\isEmpty{#2}\ifnum\ccBool=\ccTrue
\errmessage{Associated package or class name empty.
I'm going to ignore this command}
\else
\ccIndexSubsubitem[#1]{#2}{traits class}{default}%
\fi \fi
}
%
% Usage:
% \ccIndexTraitsClassRequirements[p_or_C]{associated package or class}
%
\newcommand{\ccIndexTraitsClassRequirements}[2][C]{%
\ifnum\ccIndex=\ccTrue%
\isEmpty{#2}\ifnum\ccBool=\ccTrue
\errmessage{Associated package or class name empty.
I'm going to ignore this command}
\else
\ccIndexSubsubitem[#1]{#2}{traits class}{requirements}%
\fi \fi
}
% ========================================================================
% Internal commands
% ========================================================================
\def\noFont{}
\newif\ifdimmodifier
\newcommand{\ccIndexSeeAlso}[1]{\emph{see also} #1}
%\newcommand{\ccIndexSeeAlso}[1]{$\rightarrow$ #1}
\newcommand{\none}[1]{}
% variables to hold the various pieces of text
\newcommand{\mainFont}{}
\newcommand{\mainModifier}{}
\newcommand{\mainUnmodifiedText}{}
\newcommand{\mainText}{}
\newcommand{\mainSeeText}{}
\newcommand{\subitemFont}{}
\newcommand{\subitemModifier}{}
\newcommand{\subitemUnmodifiedText}{}
\newcommand{\subitemText}{}
\newcommand{\subitemSeeAlsoText}{}
\newcommand{\subsubitemFont}{}
\newcommand{\subsubitemModifier}{}
\newcommand{\subsubitemUnmodifiedText}{}
\newcommand{\subsubitemText}{}
\newcommand{\subsubitemSeeAlsoText}{}
% variables that say something about what kind of font is supplied
% with the text
\newcommand{\emptyIndexingFont}{\ccTrue}%
\newcommand{\indexingFontIsCC}{\ccFalse}%
\newcommand{\allowUnderscores}{\ccTrue}%
\newcommand{\inConcept}{\ccFalse}%
% variable to hold the first type name for a global operator
\newcommand{\typeName}{}%
% #1 - first character of category
% #2 - rest of category name (possibly empty)
% #3 - text of the form [\font] text[, modifier]
% #4 - place to put the font
% #5 - place to put the modifier
% #6 - place to put the unmodified text
\def\parseTextWithCategory#1#2\ccEnd#3#4#5#6{%
% \xdef\allowUnderscores{\ccFalse}%
\isEmpty{#1}\ifnum\ccBool=\ccTrue% unclassified item
\indexTextParse{\noFont}{#3}{#4}{#5}{#6}%
\else \if#1a% abbreviation
\indexTextParse{\ccIndexAbbreviationFont}{#3}{#4}{#5}{#6}%
\else \if#1C% class or other C++ name
\indexTextParse{\ccFont}{#3}{#4}{#5}{#6}%
\else \if#1c% concept
\indexTextParse{\ccIndexConceptFont}{#3}{#4}{#5}{#6}%
% \xdef\allowUnderscores{\ccTrue}%
\else \if#1d% data structure
\indexTextParse{\ccIndexDSFont}{#3}{#4}{#5}{#6}%
\else \if#1f% functionality
\indexTextParse{\ccIndexFunctionalityFont}{#3}{#4}{#5}{#6}%
\else \if#1h% hint
\indexTextParse{\ccIndexHintFont}{#3}{#4}{#5}{#6}%
\else \if#1l% library
\indexTextParse{\ccIndexLibraryFont}{#3}{#4}{#5}{#6}%
\else \if#1p% package
\indexTextParse{\ccIndexPackageFont}{#3}{#4}{#5}{#6}%
\else \if#1t% term
\indexTextParse{\ccIndexTermFont}{#3}{#4}{#5}{#6}%
\else%
\errmessage{Unknown indexing category: --#1--.
The indexing command will be ignored}%
\fi \fi \fi \fi \fi \fi \fi \fi \fi \fi%
}
% #1 - category
% #2 - text in the form [\font] text[, modifier]
\newcommand{\mainTextParse}[2]{%
\parseTextWithCategory #1\ccEnd{#2}{\mainFont}{\mainModifier}%
{\mainUnmodifiedText}%
\makeIndexText{\mainFont}{\mainModifier}{\mainUnmodifiedText}%
{\mainText}{\mainSeeText}%
}
% #1 - subitem text in the form [\font] subitem[, modifier]
\newcommand{\subitemTextParse}[1]{%
\parseTextWithCategory{}\ccEnd{#1}%
{\subitemFont}{\subitemModifier}{\subitemUnmodifiedText}%
\makeIndexText{\subitemFont}{\subitemModifier}{\subitemUnmodifiedText}%
{\subitemText}{\subitemSeeText}%
}
% #1 - subitem text in the form [\font] subitem[, modifier]
\newcommand{\subitemSeeAlsoTextParse}[1]{%
\parseTextWithCategory{}\ccEnd{#1}%
{\subitemFont}{\subitemModifier}{\subitemUnmodifiedText}%
\makeIndexSeeAlsoText{\subitemFont}{\subitemModifier}%
{\subitemUnmodifiedText}{\subitemSeeAlsoText}%
}
% #1 - subsubitem text in the form [\font] text[, modifier]
\newcommand{\subsubitemTextParse}[1]{%
\parseTextWithCategory{}\ccEnd{#1}%
{\subsubitemFont}{\subsubitemModifier}{\subsubitemUnmodifiedText}%
\makeIndexText{\subsubitemFont}{\subsubitemModifier}%
{\subsubitemUnmodifiedText}{\subsubitemText}{\subsubitemSeeText}%
}
% #1 - subsubitem text in the form [\font] text[, modifier]
\newcommand{\subsubitemSeeAlsoTextParse}[1]{%
\parseTextWithCategory{}\ccEnd{#1}%
{\subsubitemFont}{\subsubitemModifier}{\subsubitemUnmodifiedText}%
\makeIndexSeeAlsoText{\subsubitemFont}{\subsubitemModifier}%
{\subsubitemUnmodifiedText}{\subsubitemSeeAlsoText}%
}
% #1 is first character of a command (the \). Captured in the variable
% \commandChar so it can be used to compare against the first in the
% string of characters produced from the first token of a indexing text
% argument
%
% #2 is the rest of the command, which must be swallowed here or it
% will appear in the document
\def\captureCommandChar#1#2\ccEnd{%
\def\commandChar{#1}%
}
% #1 - first in the string of characters representing a token (either a
% single character or a command)
% #2 - the rest of the string of characters
\def\isCommand#1#2\end{%
\expandafter\isCommandX\string#1\ccEnd%
}
\def\isCommandX#1#2\ccEnd{%
\expandafter\captureCommandChar\string\bf\ccEnd%
\if#1\commandChar\ccBool=\ccTrue%
\else \ccBool=\ccFalse%
\fi%
}
% #1 - 0 if arg #2 should not be expanded, 1 if it should
% #2 - text argument for an indexing command
%
% Result:
% \indexingFont contains the leading command if there is one
%
% if there is a leading command and this command corresponds to an
% empty command, \emptyIndexingFont is set to true
%
% if there is a leading command and this command is \ccFont,
% \indexingFontIsCC is set to true
%
% \indexText contains the entire text
%
\def\findText#1#2{%
\ifx#2\leda % have to do this nasty special case testing because I can't
% find a way to get inside the braces to pick out the
% font and text here. #2 = {\sc Leda}. I need to remove the
% { and } to make it work with the rest of the macros. The
% \string command seems the best bet, but it doesn't produce
% the braces.
\ccBool=\ccTrue
\findTextX\sc Leda\end%
\else\ifx#2\stl
\ccBool=\ccTrue
\findTextX\sc STL\end%
\else\ifx#2\cgal
\ccBool=\ccTrue
\findTextX\sc Cgal\end%
\else
\ifx#11% text should be expanded
\edef\expandedText{#2}%
\expandafter\isCommand\expandedText\end%
\findTextX#2\end%
\else%
\ccBool=\ccFalse% must assume there is no command
\findTextX#2\end%
\fi%
\fi \fi \fi %
}
% #1 - command or first character of text
% #2 - (remainder of) text
%
\def\findTextX#1#2\end{%
\ifnum\ccBool=\ccTrue % this is from the test for isCommand
\gdef\indexingFont{#1}%
\ifx#1\empty%
\xdef\emptyIndexingFont{\ccTrue}%
\fi%
\ifx#1\ccFont%
\xdef\indexingFontIsCC{\ccTrue}%
\fi%
\ifx#1\ccUnderscoreFont%
\xdef\allowUnderscores{\ccTrue}%
\fi%
\gdef\indexText{#2}%
\else%
\gdef\indexText{#1#2}%
\fi%
}
\def\findFont#1{\findFontX#1\end}
\def\findFontX#1{%
\ifx#1\end\let\next=\relax%
\else \if#1\sc\gdef\indexingFont{#1}%
\fi%
\let\next=\findFontX\fi\next%
}
%
% Usage: \separateFontFromText{text_with_font}
% where text_with_font is of the form: [\font] text
%
% results in the definition of two macros:
% \indexingFont (possibly empty) and \indexText (without font)
% and two Boolean variables are set
% \emptyIndexingFont and \indexingFontIsCC
\def\separateFontFromText#1#2{%
\gdef\indexingFont{}%
\xdef\emptyIndexingFont{\ccFalse}%
\xdef\indexingFontIsCC{\ccFalse}%
\gdef\indexText{}%
{\findText{#1}{#2}}% braces are necessary to limit the scope of the font
% if there is one
}
% Usage: \seaparteModifier{text_with_modifier}
% where text_with_modifier is of the form: text[, modifier]
%
% result: \modifier == modifier (possibly empty) and \unmodifiedText==text
\def\separateModifier#1#2{%
\ifx#11%
\edef\argument{#2}% needed in case the argument is a macro
\expandafter\separateModifierX\argument,\ccEnd%
\else%
\def\unmodifiedText{#2}%
\def\modifier{}%
\fi%
}
\def\separateModifierX #1,#2\ccEnd{%
\def\texParseLocalVar{#2}\ifx\texParseLocalVar\empty%
\def\unmodifiedText{#1}%
\def\modifier{}%
\else%
\def\unmodifiedText{#1}%
\texParseStripTrailingComma #2\ccEnd%
\fi%
}
\def\texParseStripTrailingComma #1,\ccEnd{%
\isDimModifier{#1}% % determines if the modifier is a dimension modifier
\hasLeadingSpace{#1}\ifnum\ccBool=\ccTrue%
\def\modifier{#1}%
\else
\def\modifier{ #1}% make sure all modifiers are preceded by a space
% so duplicate entries are not produced
\fi
}
% determines if the supplied argument is of the form
% 2D, 3D, or dD
% and sets the proper value for \isdimmodifier.
%
% ???
% could perhaps be written more generally to look for any undesired
% modifier if I could figure out how to get TeX to walk through two
% strings of tokens at the same time
% ???
\def\isDimModifier #1{%
\def\dparams{#1}\ifx\dparams\empty\dimmodifierfalse%
\else\isDimModifierX#1\ccEnd\fi%
}%
\def\isDimModifierX #1#2\ccEnd{%
\dimmodifierfalse%
\ifx#2D%
\ifx#12\dimmodifiertrue\else%
\ifx#13\dimmodifiertrue\else%
\ifx#1d\dimmodifiertrue%
\fi \fi \fi \fi%
}%
%
% #1 - 1 if second argument should be expanded
% - 0 if second argument should not be expanded
% #2 - text of the form [\font] text[, modifier]
%
% results in three definitions
% \modifier == modifier
% \unmodifiedText == text
% \indexingFont == \font
%
\def\parseText#1#2{%
\separateFontFromText{#1}{#2}%
\separateModifier{#1}{\indexText}%
}
% #1 = font
% #2 = modifier
% #3 = unmodified text
% #4 = place to put the regular entry text
% #5 = place to put the cross referencing entry text
\newcommand\makeIndexText[5]{%
\ifx#2\empty% no modifier
\ifnum\emptyIndexingFont=\ccTrue% no font
\ifnum\allowUnderscores=\ccTrue% allow underscores
\gdef#4{#3@\protect\ccConceptStyle{#3}}%
\else% don't allow underscores
\gdef#4{#3}%
\fi
\else\ifnum\indexingFontIsCC=\ccTrue% ccFont
\gdef#4{#3@\protect\ccc{#3}}%
\else% other font
\ifnum\allowUnderscores=\ccTrue% allow underscores
\gdef#4{#3@{#1 \protect\ccConceptStyle{#3}}}%
\else% don't allow underscores
\gdef#4{#3@{#1 #3}}%
\fi
\fi \fi%
\gdef#5{}%
\else\ifdimmodifier% dimension modifier
\ifnum\emptyIndexingFont=\ccTrue% no font
\ifnum\allowUnderscores=\ccTrue% allow underscores
\gdef#4{#3, #2@\protect\ccConceptStyle{#3, #2}}%
\else% don't allow underscores
\gdef#4{#3, #2}%
\fi
\else\ifnum\indexingFontIsCC=\ccTrue% ccFont
\gdef#4{#3, #2@\protect\ccc{#3, #2}}%
\else% other font
\ifnum\allowUnderscores=\ccTrue% allow underscores
\gdef#4{#3, #2@{#1 \protect\ccConceptStyle{#3, #2}}}%
\else% don't allow underscores
\gdef#4{#3, #2@{#1 #3, #2}}%
\fi
\fi \fi%
\gdef#5{}%
\else\ifnum\ccIndexModifierCrossRef=\ccFalse% no cross referencing wanted
\ifnum\emptyIndexingFont=\ccTrue% no font
\ifnum\allowUnderscores=\ccTrue% allow underscores
\gdef#4{#3, #2@\protect\ccConceptStyle{#3, #2}}%
\else% don't allow underscores
\gdef#4{#3, #2}%
\fi
\else\ifnum\indexingFontIsCC=\ccTrue% ccFont
\gdef#4{#3, #2@\protect\ccc{#3, #2}}%
\else% other font
\ifnum\allowUnderscores=\ccTrue% allow underscores
\gdef#4{#3, #2@{#1 \protect\ccConceptStyle{#3, #2}}}%
\else% don't allow underscores
\gdef#4{#3, #2@{#1 #3, #2}}%
\fi
\fi \fi%
\gdef#5{}%
\else% non-dimensional modifier
\ifnum\emptyIndexingFont=\ccTrue% no font
\ifnum\allowUnderscores=\ccTrue% allow underscores
\gdef#4{#3, #2@\protect\ccConceptStyle{#3, #2}}%
\gdef#5{#2\ #3@\protect\ccConceptStyle{#2\ #3}|see{\protect\ccConceptStyle{#3, #2}}}%
\else% don't allow underscores
\gdef#4{#3, #2}%
\gdef#5{#2\ #3|see{#3, #2}}%
\fi
\else\ifnum\indexingFontIsCC=\ccTrue% ccFont
\gdef#4{#3, #2@\protect\ccc{#3, #2}}%
\gdef#5{#2\ #3@\protect\ccc{#2\ #3}|see{\protect\ccc{#3, #2}}}%
\else% other font; no _s possible
\gdef#4{#3, #2@{#1 #3, #2}}%
\gdef#5{#2\ #3@{#1 #2\ #3}|see{{#1 #3, #2}}}%
\fi \fi%
\ifnum\ccIndexModifierCrossRef=\ccFalse%
\gdef#5{}%
\fi%
\fi \fi \fi%
}
% #1 = font
% #2 = modifier
% #3 = unmodified text
% #4 = place to put the text that will come after "see also"
\newcommand\makeIndexSeeAlsoText[4]{%
\ifx#2\empty% no modifier
\ifnum\emptyIndexingFont=\ccTrue% no font
\gdef#4{ZZZ#3@\ccIndexSeeAlso{#3}}%
\else\ifnum\indexingFontIsCC=\ccTrue% ccFont
\gdef#4{ZZZ#3@\ccIndexSeeAlso{\protect\ccc{#3}}}%
\else% other font
\gdef#4{ZZZ#1 #3@\ccIndexSeeAlso{{#1 #3}}}%
\fi \fi%
\else% modifier
\ifnum\emptyIndexingFont=\ccTrue% no font
\gdef#4{ZZZ#3, #2@\ccIndexSeeAlso{#3, #2}}%
\else\ifnum\indexingFontIsCC=\ccTrue% ccFont
\gdef#4{ZZZ#3, #2@\ccIndexSeeAlso{{\protect\ccc{#3, #2}}}}%
\else% other font
\gdef#4{ZZZ#3, #2@\ccIndexSeeAlso{{#1 #3, #2}}}%
\fi \fi%
\fi%
}
\def\containsInteriorCommandX#1 #2\ccEnd{%
\isEmpty{#2}\ifnum\ccBool=\ccFalse%
\expandafter\isCommand#2\end%
\ifnum\ccBool=\ccFalse%
\containsInteriorCommandX#2 \ccEnd%
\fi%
\else%
\ccInvert%
\fi%
}
\def\containsInteriorCommand#1{%
\expandafter\captureCommandChar\string\bf\ccEnd%
\edef\expandedText{#1 }%
\expandafter\containsInteriorCommandX\expandedText \ccEnd%
}
% #1 font for main item if one not supplied in #2
% if no font is to be used, supply \noFont as the first argument
% if this is left blank (as in \indexTextParse{}...) the test
% \ifx#1\empty% will be false. If this option is desired, you will
% have to add
% \isEmpty{#1}\ifnum\ccBool=\ccTrue%
% \xdef\emptyIndexingFont{\ccTrue}
% \fi%
% AS WELL AS the test \ifx#1\empty
% #2 main text in the form: [\font] text[, modifier]
% #3 the place to put the font
% #4 the place to put the modifier
% #5 the place to put the unmodified text
\newcommand\indexTextParse[5]{%
\isEmpty{#2}\ifnum\ccBool=\ccTrue% empty text argument
\errmessage{Empty text argument in indexing command; makeindex won't
like this}%
\edef#3{}%
\xdef\emptyIndexingFont{\ccTrue}%
\xdef\fontIsCC{\ccFalse}%
\edef#4{}%
\edef#5{}%
\else\containsInteriorCommand{#2}\ifnum\ccBool=\ccTrue%
\typeout{}%
\typeout{***Index Warning***}%
\typeout{ Your indexing text contains formatting commands in
the interior. I'll do what I can with this, but
you may be in trouble.}%
\typeout{}%
\parseText{0}{#2}%
\def#5{\unmodifiedText}%
\ifx\modifier\empty%
\def#4{}%
\else%
\def#4{\modifier}%
\fi%
\ifx\indexingFont\empty%
\ifx#1\empty%
\xdef\emptyIndexingFont{\ccTrue}%
\fi%
\ifx#1\ccFont%
\xdef\indexingFontIsCC{\ccTrue}%
\fi%
\ifx#1\ccUnderscoreFont%
\xdef\allowUnderscores{\ccTrue}%
\fi%
\let#3=#1%
\else%
\let#3=\indexingFont%
\fi%
\else%
\parseText{1}{#2}%
\removeTrailingSpaces{\unmodifiedText}%
\edef#5{\accumulator}%
\isEmpty{\modifier}\ifnum\ccBool=\ccFalse%
\removeTrailingSpaces{\modifier}%
\edef#4{\accumulator}%
\else%
\edef#4{\modifier}%
\fi%
\ifx\indexingFont\empty%
\ifx#1\empty%
\xdef\emptyIndexingFont{\ccTrue}%
\fi%
\ifx#1\ccFont%
\xdef\indexingFontIsCC{\ccTrue}%
\fi%
\ifx#1\ccUnderscoreFont%
\xdef\allowUnderscores{\ccTrue}%
\fi%
\let#3=#1%
\else%
\let#3=\indexingFont%
\fi%
\fi \fi%
}%
%
% #1 - first word
% #2 - rest of the words, if any
% #3 - 0 if operator, 1 for anything else
% #4 - place to put the last word
%
\def\findLastWord#1 #2\ccEnd#3#4{%
\isEmpty{#2}\ifnum\ccBool=\ccTrue%
\ifnum#3=1%
\isLetter{#1}\ifnum\ccBool=\ccTrue%
\gdef#4{#1}%
\else
\removeNonLetterFromLastWord#1\ccEnd#4%
\fi
\else
\gdef#4{#1}%
\fi
\else
\findLastWord#2 \ccEnd#3#4%
\ifx#4\empty
\removeScopePrefixFromLastWord#1::\ccEnd\lastWord%
\fi
\fi
}
% #1 -- everything up to the first <, which could include a const
% and will include the type name
% #2 -- first template parameter, which is of no interest (maybe empty)
%
\def\findFirstTypeName #1<#2\ccEnd{%
\isEmpty{#2}\ifnum\ccBool=\ccFalse%
\findLastWord #1 \ccEnd0\typeName%
\else % no templated parameters, so #1 contains entire list of parameters
\ifnum\ccOperatorCat=\ccExtractionOperator% first type name is stream
\findSecondTypeName #1,\ccEnd%
\else\ifnum\ccOperatorCat=\ccInsertionOperator% first type name is stream
\findSecondTypeName #1,\ccEnd%
\else%
\findFirstTypeNameX #1,\ccEnd%
\fi\fi%
\fi%
}
\def\findFirstTypeNameX #1 #2,#3\ccEnd{%
\isEmpty{#1}\ifnum\ccBool=\ccTrue % gets rid of leading spaces in type name
\findFirstTypeNameX #2,#3\ccEnd%
\else
\def\typeName{#1}%
\fi
}
% #1 -- everything up to the first comma (i.e., the first parameter)
% #2 -- everything after the first comma
%
\def\findSecondTypeName #1,#2\ccEnd{%
\isEmpty{#2}\ifnum\ccBool=\ccTrue%
\findLastWord #1 \ccEnd0\typeName% no second parameter so first parameter
% is used. This shouldn't happen.
\else % there is a second parameter but it has no template argument
\findSecondTypeNameX #2&\ccEnd%
\fi%
}
% #1 -- everything up to the first &
% #2 -- name of parameter (perhaps empty if paramenter not passed by reference)
\def\findSecondTypeNameX #1&#2\ccEnd{%
\isEmpty{#2}\ifnum\ccBool=\ccFalse% type name should be just before the &
\findLastWord #1 \ccEnd0\typeName%
\else % parameter not passed by reference, so find the type name as the
% next-to-last word in #1
\findSecondTypeNameXX #1 \ccEnd%
\fi
}
% #1 -- typename, possibly including a const
% #2 -- parameter name
\def\findSecondTypeNameXX #1 #2\ccEnd{%
\isEmpty{#1}\ifnum\ccBool=\ccTrue % get rid of leading spaces
\findSecondTypeNameXX #2\ccEnd%
\else
\findLastWord #1 \ccEnd0\typeName%
\fi
}
% #1 stuff before first ::
% #2 stuff after first ::
% #3 place to put the stripped name
\def\removeScopePrefixFromLastWord#1::#2\ccEnd#3{%
\def\localVar{#2}\ifx\localVar\empty%
\def#3{#1}%
\else%
\stripTrailingScope#2\ccEnd#3%
\fi%
}
% #1 stuff before first ::
% #2 stuff after first ::
% #3 place to put the stripped name
\def\stripTrailingScope#1::#2\ccEnd#3{%
\xdef#3{#1}%
}
\def\removeNonLetterFromLastWord#1#2\ccEnd#3{%
\isEmpty{#2}\ifnum\ccBool=\ccTrue%
\def#3{}%
\else \isLetter{#2}\ifnum\ccBool=\ccTrue%
\def#3{#2}%
\else%
\removeNonLetterFromLastWord#2\ccEnd#3%
\fi \fi%
}
% #1 - 0 for member function, 1 for global function
% #2 - possibly part of the return type plus the function name
\newcommand\ccIndexFunction[2]{%
\ifnum\ccIndex=\ccTrue%
\findLastWord #2 \ccEnd1\lastWord%
\ifnum#1=0%
\ccIndexMemberFunction{\lastWord}%
\else%
\ccIndexGlobalFunction{\lastWord}%
\fi%
\fi%
}
\newcommand\ccIndexFunctionBegin[2]{%
\ifnum\ccIndex=\ccTrue%
\expandafter\findLastWord #2 \ccEnd1\lastWord%
\ifnum#1=0%
\ccIndexMemberFunctionBegin{\lastWord}%
\else%
\ccIndexGlobalFunctionBegin{\lastWord}%
\fi%
\fi%
}
\newcommand\ccIndexFunctionEnd[2]{%
\ifnum\ccIndex=\ccTrue%
\expandafter\findLastWord #2 \ccEnd1\lastWord%
\ifnum#1=0%
\ccIndexMemberFunctionEnd{\lastWord}%
\else%
\ccIndexGlobalFunctionEnd{\lastWord}%
\fi%
\fi%
}
% if the operator begins with !, @ or |, then it must be quoted in the
% indexing entry since these characters have special meaning otherwise.
% These two macros look for these three characters at the beginning of
% the operator. It is assumed that such characters will not appear
% in the interior.
\def\isAnIndexOperator#1{%
\isAnIndexOperatorX#1\ccEnd%
}%
\def\isAnIndexOperatorX#1#2\ccEnd{%
\ccBool=\ccFalse%
\if#1!\ccBool=\ccTrue%
\else\if#1@\ccBool=\ccTrue%
\else\if#1|\ccBool=\ccTrue\fi\fi\fi%
}
% #1 -- the operator
\def\escapeIndexOperatorSymbols#1{%
\gdef\escapedLastWord{}%
\expandafter\escapeIndexOperatorSymbolsX#1\ccEnd%
}
% #1 -- first operator character
% #2 -- rest of operator
\def\escapeIndexOperatorSymbolsX#1#2\ccEnd{
\isEmpty{#2}\ifnum\ccBool=\ccFalse%
\escapeIndexOperatorSymbolsX#2\ccEnd%
\isAnIndexOperator{#1}\ifnum\ccBool=\ccTrue%
\edef\escapedLastWord{"#1\escapedLastWord}%
\else%
\edef\escapedLastWord{#1\escapedLastWord}%
\fi%
\else%
\isAnIndexOperator{#1}\ifnum\ccBool=\ccTrue%
\edef\escapedLastWord{"#1\escapedLastWord}%
\else%
\edef\escapedLastWord{#1\escapedLastWord}%
\fi%
\fi%
}
\newcount\ccOperatorCat
\newcount\ccNotAnIndexOperator \ccNotAnIndexOperator=0
\newcount\ccSingleVerticalBar \ccSingleVerticalBar=1
\newcount\ccDoubleVerticalBar \ccDoubleVerticalBar=2
\newcount\ccSingleExclamation \ccSingleExclamation=3
\newcount\ccDoubleExclamation \ccDoubleExclamation=4
\newcount\ccSingleAmpersand \ccSingleAmpersand=5
\newcount\ccDoubleAmpersand \ccDoubleAmpersand=6
\newcount\ccAmpersandEqual \ccAmpersandEqual=7
\newcount\ccExclamationEqual \ccExclamationEqual=8
\newcount\ccVerticalBarEqual \ccVerticalBarEqual=9
\newcount\ccSingleAt \ccSingleAt=10
\newcount\ccInsertionOperator \ccInsertionOperator=11
\newcount\ccExtractionOperator \ccExtractionOperator=12
\newcount\ccModOperator \ccModOperator=13
\newcount\ccModEqualOperator \ccModEqualOperator=14
\newcount\ccPowerOperator \ccPowerOperator=15
\newcount\ccPowerEqualOperator \ccPowerEqualOperator=16
\newcount\ccTildeOperator \ccTildeOperator=17
\def\whichOperator#1{
\ccOperatorCat=\ccNotAnIndexOperator%
\expandafter\whichOperatorX #1\ccEnd%
}
%% change catcodes here in order to detect the %, %=, ^ and ^= operators
%% properly
\begingroup
\ccCatcode \catcode`\#=6 \catcode`\@=14
\gdef\whichOperatorX #1#2\ccEnd{
\isEmpty{#2}\ifnum\ccBool=\ccTrue@
\ifx#1%\ccOperatorCat=\ccModOperator@
\else\if#1^\ccOperatorCat=\ccPowerOperator@
\else\if#1~\ccOperatorCat=\ccTildeOperator@
\else\if#1!\ccOperatorCat=\ccSingleExclamation@
\else\if#1|\ccOperatorCat=\ccSingleVerticalBar@
\else\if#1@\ccOperatorCat=\ccSingleAt@
\else\if#1&\ccOperatorCat=\ccSingleAmpersand\fi\fi\fi\fi\fi\fi\fi@
\else@ two-character operators
\if#1!\if#2!\ccOperatorCat=\ccDoubleExclamation\fi\fi@
\if#1!\if#2=\ccOperatorCat=\ccExclamationEqual\fi\fi@
\if#1|\if#2|\ccOperatorCat=\ccDoubleVerticalBar\fi\fi@
\if#1|\if#2=\ccOperatorCat=\ccVerticalBarEqual\fi\fi@
\if#1&\if#2&\ccOperatorCat=\ccDoubleAmpersand\fi\fi@
\if#1&\if#2=\ccOperatorCat=\ccAmpersandEqual\fi\fi@
\if#1>\if#2>\ccOperatorCat=\ccInsertionOperator\fi\fi@
\if#1<\if#2<\ccOperatorCat=\ccExtractionOperator\fi\fi@
\if#1%\if#2=\ccOperatorCat=\ccModEqualOperator\fi\fi@
\if#1^\if#2=\ccOperatorCat=\ccPowerEqualOperator\fi\fi@
\fi@
}
\endgroup
% #1 -- 0 if a member function; 1 if a global function
% #2 -- (part of) the return type of the operator
% #3 -- the operator, possibly with leading or trailing spaces
% #4 -- parameter list, which is needed for global operators
\def\ccIndexOperator#1#2operator#3,#4,\ccEnd{%
\ifnum\ccIndex=\ccTrue%
\findLastWord #3 \ccEnd0\lastWord% % gets rid of leading spaces
\whichOperator\lastWord%
\ifnum#1=0%
\escapeIndexOperatorSymbols\lastWord%
\ifnum\inConcept=\ccTrue
\ccIndexOperatorSubitem{\escapedLastWord}{\ccIndexConceptFont \ccIndexClassName}%
\else
\ccIndexOperatorSubitem{\escapedLastWord}{\ccFont \ccIndexClassName}%
\fi
\else%
\escapeIndexOperatorSymbols\lastWord%
\findFirstTypeName #4<\ccEnd%
\ccIndexGlobalOperator{\escapedLastWord}{\typeName}%
\fi%
\fi%
}
%
% variables to indicate what kind of formatting command has last been
% used
%
\newcount\ccCurrentIndexCat
\newcount\ccIndexEnumCat \ccIndexEnumCat=0
\newcount\ccIndexStructCat \ccIndexStructCat=1
\newcount\ccIndexTypedefCat \ccIndexTypedefCat=2
\newcount\ccIndexVariableCat \ccIndexVariableCat=3
\newcount\ccIndexConstantCat \ccIndexConstantCat=4
\newcount\ccIndexConceptCat \ccIndexConceptCat=5
\newcount\ccIndexFunctionCat \ccIndexFunctionCat=6
\newcount\ccIndexFunctionObjectConceptCat \ccIndexFunctionObjectConceptCat=7
\newcount\ccIndexFunctionObjectClassCat \ccIndexFunctionObjectClassCat=8
\newcount\ccIndexClassCat \ccIndexClassCat=9
\newcount\ccIndexMacroCat \ccIndexMacroCat=10
% #1 - enum tag
% #2 - value assigned (possibly empty)
\def\removeAssignmentAndIndex#1=#2\ccEnd{%
\ccIndexEnumTag{#1}%
}
% #1 - comma-separated list of enum tags, possibly with value assignments
\def\findEnumTags#1{%
\findEnumTagsX#1,\ccEnd%
}
% #1 - enum tag of the form TAG[ = value]
% #2 - rest of the list of tags (possibly empty)
\def\findEnumTagsX#1,#2\ccEnd{%
\def\localVar{#2}\ifx\localVar\empty%
\removeAssignmentAndIndex#1=\ccEnd%
\else%
\removeAssignmentAndIndex#1=\ccEnd%
\findEnumTagsX#2\ccEnd%
\fi%
}
% #1 - enum or struct name together with C++ key words "enum" or "struct"
% #2 - list of enum tags or struct fields
\def\ccIndexEnumOrStruct#1\{#2\}\ccEnd{%
\ifnum\ccIndex=\ccTrue%
\findLastWord #1 \ccEnd1\lastWord%
\ifnum\ccCurrentIndexCat=\ccIndexEnumCat%
\ccIndexEnum{\lastWord}%
\findEnumTags{#2}%
\else
\ccIndexGlobalStruct{\lastWord}%
\fi%
\fi%
}
% #1 - typedef or variable name possibly with preceding key words
\def\ccIndexTypedefOrVariable#1{%
\ifnum\ccIndex=\ccTrue%
\findLastWord #1 \ccEnd1\lastWord%
\ifnum\ccCurrentIndexCat=\ccIndexTypedefCat%
\ccIndexTypedef{\lastWord}%
\else
\ccIndexGlobalVariable{\lastWord}%
\fi
\fi%
}
%
% #1 - a single text argument for indexing, possibly with trailing spaces
%
% result: \accumulator will contain the same text with any trailing spaces
% removed
\def\removeTrailingSpaces#1{%
\gdef\accumulator{}%
\edef\argument{#1 }% needed in case the argument is a macro
\expandafter\removeTrailingSpacesX\argument \ccEnd%
}
\def\removeTrailingSpacesX#1 #2\ccEnd{%
\isEmpty{#2}\ifnum\ccBool=\ccTrue%
\ifx\accumulator\empty%
\gdef\accumulator{#1}%
\else%
\edef\previous{\accumulator\ }%
\gdef\accumulator{\previous #1}%
\fi%
\else%
\ifx\accumulator\empty%
\gdef\accumulator{#1}%
\else%
\edef\previous{\accumulator\ }%
\gdef\accumulator{\previous #1}%
\fi%
\removeTrailingSpacesX#2 \ccEnd%
\fi%
}
% #1 - everything up to the first "<"
% #2 - everything after the first "<"
% #3 - the place to put the stripped class name
\gdef\ccStripTemplates #1<#2\ccEnd#3{%
\gdef#3{#1}
}
%
% in \ccRefDeclarationX, the argument to a \begin{ccRef...}{<arg>}
% is stored in \ccPureClassTemplateName (even when <arg> is not
% "Class"), so this is the name to use for indexing. If an optional
% argument was given as in \begin[scope::]{ccRef...}, it has been
% stored in \ccIndexClassName without the trailing "::", if any.
%
\def\ccIndexRefDeclarationBegin{%
%
% replaces the value of ccIndexClassName by the name stored in
% ccPureClassTemplateName since the names of nested classes are not indexed
% under the nesting class.
%
\ifnum\ccCurrentIndexCat=\ccIndexClassCat%
\expandafter\ccStripTemplates\ccPureClassTemplateName<\ccEnd\ccIndexClassName%
\ccIndexMainItemBegin[C]{\ccIndexClassName}%
\else\ifnum\ccCurrentIndexCat=\ccIndexFunctionObjectClassCat%
\expandafter\ccStripTemplates\ccPureClassTemplateName<\ccEnd\ccIndexClassName%
\ccIndexMainItemBegin[C]{\ccIndexClassName}%
\else\ifnum\ccCurrentIndexCat=\ccIndexFunctionCat%
\expandafter\expandafter\isEmpty\ccIndexClassName\ifnum\ccBool=\ccTrue%
\ccIndexFunctionBegin1\ccPureClassTemplateName%
\else
\ccIndexFunctionBegin0\ccPureClassTemplateName%
\fi
% concepts can act like classes in the sense that they have things that look
% like member functions and all that, so ccIndexClassName needs to be defined
\else\ifnum\ccCurrentIndexCat=\ccIndexConceptCat%
\xdef\inConcept{\ccTrue}
\expandafter\ccStripTemplates\ccPureClassTemplateName<\ccEnd\ccIndexClassName%
\ccIndexMainItemBegin[c]{\ccIndexClassName}%
\else\ifnum\ccCurrentIndexCat=\ccIndexFunctionObjectConceptCat%
\xdef\inConcept{\ccTrue}
\expandafter\ccStripTemplates\ccPureClassTemplateName<\ccEnd\ccIndexClassName%
\ccIndexMainItemBegin[c]{\ccIndexClassName}%
\else% all other things are C++ names
\expandafter\expandafter\isEmpty{\ccIndexClassName}\ifnum\ccBool=\ccTrue
\ccIndexMainItemBegin[C]{\ccPureClassTemplateName}%
\else
\ccIndexSubitemBegin[C]{\ccIndexClassName}{\ccFont \ccPureClassTemplateName}%
\fi
\fi\fi\fi\fi\fi%
}
\def\ccIndexRefDeclarationEnd{%
\ifnum\ccCurrentIndexCat=\ccIndexClassCat%
\ccIndexMainItemEnd[C]{\ccIndexClassName}%
\else\ifnum\ccCurrentIndexCat=\ccIndexFunctionObjectClassCat%
\ccIndexMainItemEnd[C]{\ccIndexClassName}%
\else\ifnum\ccCurrentIndexCat=\ccIndexFunctionCat%
\expandafter\expandafter\isEmpty{\ccIndexClassName}\ifnum\ccBool=\ccTrue
\ccIndexFunctionEnd1\ccPureClassTemplateName%
\else
\ccIndexFunctionEnd0\ccPureClassTemplateName%
\fi
\else\ifnum\ccCurrentIndexCat=\ccIndexConceptCat%
\xdef\inConcept{\ccFalse}
\ccIndexMainItemEnd[c]{\ccIndexClassName}%
\else\ifnum\ccCurrentIndexCat=\ccIndexFunctionObjectConceptCat%
\ccIndexMainItemEnd[c]{\ccIndexClassName}%
\xdef\inConcept{\ccFalse}
\else% all other things are C++ names
\expandafter\expandafter\isEmpty{\ccIndexClassName}\ifnum\ccBool=\ccTrue
\ccIndexMainItemEnd[C]{\ccPureClassTemplateName}%
\else
\ccIndexSubitemEnd[C]{\ccIndexClassName}{\ccFont \ccPureClassTemplateName}%
\fi
\fi\fi\fi\fi\fi%
\gdef\ccIndexClassName{}%
}