3

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: Required Format

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:

enter image description here

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? enter image description here

  • 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. – egreg Apr 17 '21 at 21:53

2 Answers2

2

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:

enter image description here


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}}

enter image description here

Marijn
  • 37,699
1

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}
\newcommand{\strokeshead}[1]{%
  \rmfamily\large\textbf{#1 stroke\ifnum#1>1 s\fi}%
}
%%%%%% --------------- This is the new solution --------------- %%%%%%
\begin{filecontents*}{stroke.ist}
headings_flag 0
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]
\newcommand{\strindex}[2]{\index[stroke]{#1@\strokeshead{#1}!#2}}

\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}
headings_flag 0
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 --------------- %%%%%%

enter image description here