# Categorising and aligning entries in Index

I'm busy making a document on Japanese Kanji characters.

I want one Index (among several others) to have a specific format:

1. Kanji must be categorised according to "Stroke Count"
2. The Kanji itself, should be flushed to the left under it's respective category.
3. The page number on which the Kanji can be found, should be flushed to the right.

This image is a good example of what I'm trying to achieve:

I had a stab at producing the output I want, but to be frank it looks rather ugly. In the code block below you'll find a MWE:

\documentclass[10pt, a4paper]{ltjbook}
\usepackage{luatexja}
\usepackage{imakeidx}
\makeindex[name=stroke, columns=4, title={Index of 漢字 by Stroke Count}, intoc, columnseprule]
\newcommand{\strindex}[2]{\index[stroke]{#1@#1!#2}}

%-------------------------------------------------------
%-------------------------------------------------------
%-------------------------------------------------------
\begin{document}

The kanji for dry, 干, consists of 3 strokes.\strindex{3}{干}

The kanji for gold, 金, consists of 8 strokes.\strindex{8}{金}

Words > 語 > 14 strokes.\strindex{14}{語}

Gentleman > 士 > 3 strokes.\strindex{3}{士}

Morning > 朝 > 12 strokes.\strindex{12}{朝}

Blue > 青 > 8 strokes.\strindex{8}{青}

Earth > 土 > 3 strokes.\strindex{3}{土}

Hang > 掛 > 11 strokes.\strindex{11}{掛}

Ten Thousand > 万 > 3 strokes.\strindex{3}{万}

\printindex[stroke]
\end{document}


Edit 1 on 2021/04/29:
In addition to the question above, it would also be very helpful to know a solution whose format conforms to the one given in this solution for the sake of consistency. What I'm specifically referring to includes:

• A 'Group Demarcation' that is bold and also a slightly larger font than the entries belonging to that group.
• Vertical whitespace between different groups.
• A configuration that prevents a column/page break between the 'Group Demarcation' and the first entry below it.

Please see the image below as a reference guide:

Edit 2 on 2021/05/01:
With reference to the image below: Is there a way I can modify item_x1 to prevent a break between a new category and its first entry?

• You might look at mendex or upmendex. They aren't supported by imakeidx for lack of knowledge about them, as the documentation for mendex is only in Japanese. Apr 17, 2021 at 21:53

Here is a solution according to "Edit 1 on 2021/04/29"

EDIT (2021/05/02): Now a solution also according to Edit 2 on 2021/05/01. It appears the use of \\* or \nopagebreak isn't a reliable way to keep things together in a multicols environment. So the new solution uses a brute force approach. We put a command \strokesection before the "⟨n⟩ strokes" heading. This command puts that line and the following line (i.e. the first entry after that heading) together in a \parbox so that multicol cannot put a column break between them. In order to work properly all entries have to be terminated by \par. As the item_x declarations in stroke.ist specify what to put before an item rather than after, we also put a \par at the end of the multicols and before the \strokesection to make sure the macro always finds the correct two lines.

\documentclass[10pt, a4paper]{ltjbook}
\usepackage{luatexja}
\usepackage{imakeidx}
\usepackage[left=1.9cm,right=1.9cm,bottom=1.5cm,top=1.5cm]{geometry}
\setlength{\columnseprule}{0.4pt}
\setlength{\columnsep}{3em}
\rmfamily\large\textbf{#1 stroke\ifnum#1>1 s\fi}%
}
%%%%%% --------------- This is the new solution --------------- %%%%%%
\begin{filecontents*}{stroke.ist}
preamble "\\chapter*{\\indexname}%
\\begin{multicols}{4}\\raggedcolumns
\\setlength\\parindent{0pt}
\\setlength\\parskip{0pt}"
postamble "\\par\n\\end{multicols}
"
delim_1 "\\hfill "
item_0 "\\par\n\\strokesection "
item_1 "\\par\n"
item_x1 "\\par\n"
\end{filecontents*}
\newcommand\strokesection{} % to make sure we can use this command
\def\strokesection#1\par#2\par{\vspace{5pt}\par
\parbox[t]{\linewidth}{{#1}\\#2\strut}\par
}
%%%%%% --------------- End of the new solution --------------- %%%%%%
\makeindex[name=stroke, columns=4, title={Index of 漢字 by Stroke Count}, intoc, columnseprule,options=-s stroke.ist]

\begin{document}

One 一\strindex{1}{一}

The kanji for dry, 干, consists of 3 strokes.\strindex{3}{干}

The kanji for gold, 金, consists of 8 strokes.\strindex{8}{金}

Words > 語 > 14 strokes.\strindex{14}{語}

Gentleman > 士 > 3 strokes.\strindex{3}{士}

Morning > 朝 > 12 strokes.\strindex{12}{朝}

Blue > 青 > 8 strokes.\strindex{8}{青}

Earth > 土 > 3 strokes.\strindex{3}{土}

Hang > 掛 > 11 strokes.\strindex{11}{掛}

Ten Thousand > 万 > 3 strokes.\strindex{3}{万}

\printindex[stroke]
\end{document}


For comparison, here is the previous solution:

%%%%%% --------------- This is the previous solution --------------- %%%%%%
\begin{filecontents*}{stroke.ist}
preamble "\\chapter*{\\indexname}%
\\begin{multicols}{4}
\\setlength\\parindent{0pt}
\\setlength\\parskip{5pt}"
postamble "\n\\end{multicols}
"
delim_1 "\\hfill "
item_0 "\\par\n"
item_1 "\\\\\n"
item_x1 "\\\\*\n"
\end{filecontents*}
%%%%%% --------------- End of the previous solution --------------- %%%%%%


• Thank you @Pieter van Oostrum. Can you maybe help with Edit 2 on 2021/05/01? May 1, 2021 at 18:53
• The \\\\* was supposed to do that. But apparently multicol doesn't pay enough attention to it. Maybe you can try to add \\raggedcolumns after \\begin{multicols}{4} in stroke.ist, but in my toy example even that didn't help, although it is supposed to. May 1, 2021 at 21:37
• Actually, I did find a "brute force" method to do this, which doesn't depend on penalties. See the update in my answer. May 2, 2021 at 12:15
• I tried it out, and it works. Thank you! May 2, 2021 at 13:05

For the alignment of the page numbers you can write an index style file (.ist). The important keys here are delim0, delim1 and delim2. You can set them for \hfill to flush right, with the backslash escaped (so \\hfill).

For the alignment of the items you can redefine \subitem to \@idxitem, basically pretending that each individual kanji is a category, for layout purposes.

In the MWE below the .ist file is contained within the LaTeX source using filecontents, this is just for the example. You can either run it once or copy the contents manually to a file, then remove this part from the code. Note that the file name for the filecontents environment is set to be \jobname.ist, where the macro \jobname defaults to the name of the .tex file without the extension. If you use a file with a different name then you should also change the option setting options=-s \jobname.ist in \makeindex to the actual file, for example options=-s mysettings.ist.

MWE:

\documentclass[10pt, a4paper]{ltjbook}
\usepackage{luatexja}
\usepackage{imakeidx}
\begin{filecontents*}{\jobname.ist}
delim_0 "\\hfill"
delim_1 "\\hfill"
delim_2 "\\hfill"
\end{filecontents*}
\makeindex[name=stroke, columns=4, title={Index of 漢字 by Stroke Count}, intoc, columnseprule,options=-s \jobname.ist]
\newcommand{\strindex}[2]{\index[stroke]{#1@\textbf{#1 strokes}!#2}}
\makeatletter
\let\subitem\@idxitem
\makeatother
%-------------------------------------------------------
%-------------------------------------------------------
%-------------------------------------------------------
\begin{document}
The kanji for dry, 干, consists of 3 strokes.\strindex{3}{干}

The kanji for gold, 金, consists of 8 strokes.\strindex{8}{金}

Words > 語 > 14 strokes.\strindex{14}{語}

Gentleman > 士 > 3 strokes.\strindex{3}{士}

Morning > 朝 > 12 strokes.\strindex{12}{朝}

Blue > 青 > 8 strokes.\strindex{8}{青}

Earth > 土 > 3 strokes.\strindex{3}{土}

Hang > 掛 > 11 strokes.\strindex{11}{掛}

Ten Thousand > 万 > 3 strokes.\strindex{3}{万}

\printindex[stroke]
\end{document}


Result:

Edit for kanji with one stroke: you can print the s conditionally using \ifnum.

\newcommand{\strindex}[2]{\index[stroke]{#1@\textbf{#1 stroke\ifnum#1>1s\fi}!#2}}


• Excellent, Thank you so much! Apr 19, 2021 at 5:11
• My document also contains the kanji for "One", 一, which only consists of 1 stroke. Is there a way to adapt .ist so that in the Index of 漢字 by Stroke Count, we end up with a subcategory 1 stroke (note the Singular), instead of: 1 strokes. At the same time, the remaining subcategories should remain as is, i.e. in plural form, e.g.: 8 strokes, etc... @Marijn Apr 20, 2021 at 5:56
• @HenriBranken see edit. Apr 20, 2021 at 7:06
• How would I go about tweaking this Index to exactly conform to the format of the following Index for the sake of consistency? @Marijn Apr 28, 2021 at 16:35
• @HenriBranken I'm not sure what you mean, are you referring to the horizontal space left and right of the column lines? Apr 28, 2021 at 18:28