indexing

# Desired index result

I want an index using makeindexto have entries like the following (where I've used ~~~ and ~~~~~~ to indicate indenting for subentries and sub subentries):

nothing, 1
~~~ nil, 1
~~~~~~ and zero, 1
~~~ null, 1
null elements, 1

zero (see zero elements)
zero elements, 1

Note the following formatting requirements shown:

• A "See also …" for a main entry begins with an upper-case "S".
• A "(see also …)" for a subentry is indented below the subentry and enclosed in parens.
• A "(see …)" cross-reference is enclosed in parens.
• A "(see …)" cross-reference does not include a comma after the (sub)entry on its line.
• A "see" or "see also"/"See also" entry does not end with a page number.

Here's a screen shot of the printed index:

# A working source file that produces the result

The following source file will accomplish that:

\documentclass{book}
\usepackage{makeidx}

\newcommand\gobbleone[1]{}
\newcommand*{\seeonly}[2]{\ (\emph{\seename} #1)}
\newcommand*{\also}[2]{(\emph{\alsoname} #1)}

\makeindex

\begin{document}

This is a short book about zero. Therefore, it's also about nothing.
Which means null (or nil).

\index{nothing}
\index{nothing!nil}
\index{nothing!nil!and zero}   % added for clarity
\index{nothing!nil!zzzzz@\also{null elements}|gobbleone}
\index{nothing!null}
\index{nothing!zzzzz@\Also{zero elements}|gobbleone}
\index{null elements}

\index{zero \seeonly{zero elements}|gobbleone}
\index{zero elements}

\printindex

\end{document}


# Simplification & improvement sought

Can this be simplified by suitable definitions that would avoid having to explicitly include the |gobbleone in each "see only" and "see" entry? And it would even be better if I did not have to explicitly include the zzzzz@ sort key that puts the "see also" subentries after all others.

I would strongly prefer definitions written in LaTeX (using newcommand) rather than at lower-level TeX (using \def).

These related postings unfortunately do not seem to accomplish what I need:

SECOND EDIT

(I don't know what is the usual practice. I have left the initial answer and edit at the bottom and the new one here at the start).

To fullfill all the requirements, instead of manipulating the argument of \index, I have made three new commands with two arguments to take care of it. The first argument is the entry in the index and the second the see text. The commands are:

\seeonlyindex{<index entry>}{<see text>}
\alsoindex{<index entry>}{<see text>}
\Alsoindex{<index entry>}{<see text>}


The result is:

The complete code is:

\documentclass{book}
\usepackage{makeidx}

\newcommand\gobbleone[1]{}
\newcommand{\seeonly}[2]{\ (\emph{\seename} #1)}
\newcommand{\also}[2]{\unskip(\emph{\alsoname} #1)}
\let\oldindex\index
\renewcommand{\index}[1]{\def\exptoindex{#1}\expandafter\oldindex\expandafter{\exptoindex}}

\newcommand{\seeonlyindex}[2]{\index{#1@#1\protect\gobbleone|seeonly{#2}}}
\newcommand{\alsoindex}[2]{\index{#1!zzzz@\protect\gobbleone|also{#2}}}
\newcommand{\Alsoindex}[2]{\index{#1!zzzz@\protect\gobbleone|Also{#2}}}

\makeindex

\begin{document}

This is a short book about zero. Therefore, it's also about nothing.
Which means null (or nil).

\index{nothing}
\index{nothing!nil}
\index{nothing!nil!and zero}
\alsoindex{nothing!nil}{null elements}
\index{nothing!null}
\Alsoindex{nothing}{zero elements}
\index{null elements}

\seeonlyindex{zero}{zero elements}
\index{zero elements}

\printindex

\end{document}


OLD SECTION

To avoid the use of |gobbleone to get rid of the page numbers, you have to insert the commands the makeidx way with | and not the LaTeX way with \.

To have these entries in the last place, you still will need \gobbleone to eliminate the comma.

\index{nothing!nil!zzzz@\gobbleone|also{null elements}}


(edited to remove unwanted space)

An additional command \lastentrymakes typing easier, but the \index command must be renewed and then a \def is required to have the content of \index expanded.

The complete code: (edited to remove unwanted space)

\documentclass{book}
\usepackage{makeidx}

\newcommand\gobbleone[1]{}
\newcommand{\seeonly}[2]{\ (\emph{\seename} #1)}
\newcommand{\also}[2]{\unskip(\emph{\alsoname} #1)}

\makeindex

\begin{document}

This is a short book about zero. Therefore, it's also about nothing.
Which means null (or nil).

\let\oldindex\index
\renewcommand{\index}[1]{\def\exptoindex{#1}\expandafter\oldindex\expandafter{\exptoindex}}
\newcommand{\lastentry}{!zzzz@\protect\gobbleone}

\index{nothing}
\index{nothing!nil}
%\index{nothing!nil!zzzz@\gobbleone|also{null elements}}
\index{nothing!nil\lastentry|also{null elements}}
\index{nothing!null}
%\index{nothing!zzzz@\gobbleone|Also{zero elements}}
\index{nothing\lastentry|Also{zero elements}}
\index{null elements}

\index{zero|seeonly{zero elements}}
\index{zero elements}

\printindex

\end{document}