1

Suppose I would like to sort an index file called "xchp.idx" that includes the following information:

    \indexentry{{Chp  1 } cherry}{1}
    \indexentry{{Chp  1 } apple}{1}
    \indexentry{{Chp  1 } banana}{1}
    \indexentry{{Chp  2 } banana}{1}
    \indexentry{{Chp  2 } cherry}{1}
    \indexentry{{Chp  2 } apple}{1}
    \indexentry{{Chp  10 } banana}{1}
    \indexentry{{Chp  10 } cherry}{1}
    \indexentry{{Chp  10 } apple}{1}
    \indexentry{{Chp  12 } apple}{1}
    \indexentry{{Chp  12 } cherry}{1}
    \indexentry{{Chp  12 } banana}{1}

If I attempt such a sort operation using

    makeindex xchp.idx

then I get

    \item {Chp  1 } apple, 1  
    \item {Chp  1 } banana, 1 
    \item {Chp  1 } cherry, 1 
    \item {Chp  10 } apple, 1 
    \item {Chp  10 } banana, 1
    \item {Chp  10 } cherry, 1
    \item {Chp  12 } apple, 1 
    \item {Chp  12 } banana, 1
    \item {Chp  12 } cherry, 1
    \item {Chp  2 } apple, 1  
    \item {Chp  2 } banana, 1 
    \item {Chp  2 } cherry, 1 

This is sorting everything lexicographically, whereas I would like the second token in each string to be sorted numerically like this:

    \item {Chp  1 } apple, 1  
    \item {Chp  1 } banana, 1 
    \item {Chp  1 } cherry, 1 
    \item {Chp  2 } apple, 1  
    \item {Chp  2 } banana, 1 
    \item {Chp  2 } cherry, 1 
    \item {Chp  10 } apple, 1 
    \item {Chp  10 } banana, 1
    \item {Chp  10 } cherry, 1
    \item {Chp  12 } apple, 1 
    \item {Chp  12 } banana, 1
    \item {Chp  12 } cherry, 1

To that end, I might try to use the "page_precedence" option in a style file called "xchp.ist" containing this:

    page_precedence "anaan"

where a=alphabetic lower and n=numeric.

Here I might be tempted to complain, that while this option is mentioned here and there on stackexchange, there seems to be no clear documentation to its use...not even in Table 11.1 of "The LaTeX Companion" second edition. But then I would stop myself from complaining, and profusely apologize, because I am getting makeindex for free ... and so who am I to complain?

Now if I try

    makeindex -s xchp.ist xchp.idx

I get

    \item {Chp  1 } apple, 1  
    \item {Chp  1 } banana, 1 
    \item {Chp  1 } cherry, 1     
    \item {Chp  10 } apple, 1 
    \item {Chp  10 } banana, 1
    \item {Chp  10 } cherry, 1
    \item {Chp  12 } apple, 1 
    \item {Chp  12 } banana, 1
    \item {Chp  12 } cherry, 1
    \item {Chp  2 } apple, 1  
    \item {Chp  2 } banana, 1 
    \item {Chp  2 } cherry, 1 

Which is still not what I want. Can anyone help me out? I suspect that xindy may have a solution. But that may be another post. For now, is there a way to perform the desired operation with makeindex?

MUmla
  • 181
  • If the sort value is purely numerical, makeindex will perform a numerical sort, so you'd need the entries to be in the form \indexentry{1@{Chp 1 } cherry}{1}. – Nicola Talbot Nov 23 '17 at 22:44
  • Assume the xchp.idx file is non-editable (carved in stone or burned into ROM, or a protected world heritage site). Is there a solution under this constraint? – Daniel J. Greenhoe Nov 23 '17 at 22:56
  • Can't think of how to do it in makeindex without changing the index file. Are you willing to use a pipe (sed etc)? The page_precedence setting relates to the page number ordering (in the second argument of \indexentry). So if you have \indexentry{foo}{IX}, \indexentry{foo}{10} and \indexentry{foo}{xii} then page_precedence "rnR" will put the lower-case roman numerals at the start of the page list, followed by the arabic numerals, followed by upper case roman numerals. So you end up with foo, xii, 10, IX. – Nicola Talbot Nov 23 '17 at 23:13
  • What about using xindy? Interestingly, it seems to work out of the box. Try texindy xchap.idx – David Purton Nov 24 '17 at 04:31
  • Oh, I just read your last sentence! Sorry! Never mind, perhaps my answer will give you enough information to use xindy. – David Purton Nov 24 '17 at 04:56
  • Thank you @NicolaTalbot for your very useful reply. Often having a negative solution of "No Solution" is just as useful as a positive solution---it saves me much wasted time digging around trying to find a method that does not exist. It is a little curious though---I read that makeindex.exe was written in C, and C has the function strtok(...), which allows one to parse "tokens" separated by delimiters, which is basically what I want. – Daniel J. Greenhoe Nov 24 '17 at 13:24
  • Thank you @DavidPurton for your xindy recommendation. I did try texindy xchap.idx, but got an error with "input file xchap.idx does not exist at" [a texlive distribution path]. That is, it seems to be looking for my xchap.idx file in the same directory as texindy.pl. I suspect maybe that this problem may be resolved if I let xelatex call texindy implicitly, but I prefer to call it explicitly myself from within a makefile (perhaps due to some distorted world view). I will continue to tinker around with it. If I can't get it working, I will likely post again in a separate thread. – Daniel J. Greenhoe Nov 24 '17 at 13:44
  • I more often have trouble with texindy running from within latex and have to run it manually. So it's meant to work fine. Asking a separate question is probably your best option. – David Purton Nov 24 '17 at 13:51
  • @DavidPurton makeindex is on the restricted list (that is, it's a trusted application) so it can be run using TeX's shell escape in restricted mode. xindy isn't on the restricted list (there's a comment about it in texmf.cnf) so it can't be run from the shell escape in restricted mode. It needs the unrestricted -shell-escape which is less secure. – Nicola Talbot Nov 24 '17 at 14:04
  • Whoa. So surprising. Today I tried texindy xchp.idx again, and this time it worked giving me an xchp.ind file (not the error message I got before). And, as @DavidPurton said, it sorted correctly ("correctly" here meaning the way I egocentrically wanted it). I don't know what happened before. But the good news is, based on past experience, once an intermittent problem appears once, it will likely appear again. Something to look forward to. Many thanks to Nicola and David again, and to stackexchange, even though apparently it will not support me using @ tags in the same comment twice. – Daniel J. Greenhoe Nov 24 '17 at 22:55
  • I also tested using texindy xchp.idx on a much larger xelatex project with \indexentry statements involving font size switching, typeface switching, Asian glyphs, a teckit mapping (for PinYin tone diacritic marks), and hyper-link support, like this ...
        \indexentry{{\relax \fontsize  {8}{9.5}\selectfont  1} brain(n) {\fntNotoSansCJK 頭腦}({t/'ou n/>ao})|hyperpage}{3}
    
    

    Everything appears to work "correctly" right out of the box. Thank you again.

    – Daniel J. Greenhoe Nov 24 '17 at 23:59

1 Answers1

1

You can sort it correctly using xindy.

Compile it using pdflatex -shell-escape. If it doesn't run xindy, you might have to do that manually (texindy), then run pdflatex again.

\documentclass{article}
\usepackage[nonewpage,xindy]{imakeidx}
\makeindex
\indexsetup{firstpagestyle=empty}
\begin{document}
Filler text.
\index{{Chp  1 } cherry}
\index{{Chp  1 } apple}
\index{{Chp  1 } banana}
\index{{Chp  2 } banana}
\index{{Chp  2 } cherry}
\index{{Chp  2 } apple}
\index{{Chp  10 } banana}
\index{{Chp  10 } cherry}
\index{{Chp  10 } apple}
\index{{Chp  12 } apple}
\index{{Chp  12 } cherry}
\index{{Chp  12 } banana}
\printindex
\end{document}

enter image description here

David Purton
  • 25,884