Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

This is a follow-up question to: How to automate a dictionary (sorting, headers)?

I was wondering if there is a way to sort the entries alphabetically in the following code.
I guess myself that xindy, glossaries or something similar should do the trick, but I don't know how to do that.
BTW, I'm using XeLaTeX on TL2012 on Win7 and my document is in Persian which is an RTL language and also, I'd prefer to do this without using additional packages.
Here is the code:

\documentclass[twoside]{article}
    \usepackage{multicol}
    \usepackage{fancyhdr}
    \usepackage[bf,sf,center]{titlesec}

% Headers and footers
    \fancyhead[L]{\textsf{\rightmark}}
    \fancyhead[R]{\textsf{\leftmark}}

    \fancyfoot[C]{\textbf{\textsf{\thepage}}}

    \renewcommand{\headrulewidth}{1.4pt}
    \renewcommand{\footrulewidth}{1.4pt}

% Entry command : \dict{<word>}{<gender>}{<text>}
    \newcommand{\dict}[3]{%
        \markboth{#1}{#1}%
        \par\vspace{0.25\baselineskip}%
        \textbf{\textsf{#1}} \textit{- #2 -} #3%
    }

    \pagestyle{fancy}

% For testing
    \usepackage{lipsum}


\begin{document}

\section*{A}

\begin{multicols}{2}
    \dict{adequate}{n}{\lipsum[1]}
    \dict{adhere}{n}{\lipsum[2]}
    \dict{adherence}{n}{\lipsum[3]}
    \dict{adhesion}{n}{\lipsum[4]}
    \dict{adhesive}{n}{\lipsum[5]}
    \dict{adjacent}{n}{\lipsum[6]}
    \dict{adjective}{n}{\lipsum[1]}
    \dict{adjoin}{n}{\lipsum[2]}
    \dict{adjourn}{n}{\lipsum[3]}
    \dict{adjournment}{n}{\lipsum[4]}
    \dict{adjunt}{n}{\lipsum[5]}
    \dict{adjust}{n}{\lipsum[6]}
\end{multicols}


\section*{M}

\begin{multicols}{2}
    \dict{main}{n}{\lipsum[3]}
    \dict{material}{n}{\lipsum[1]}
    \dict{mathematic}{n}{\lipsum[2]}
    \dict{more}{n}{\lipsum[2]}
\end{multicols}


\section*{Z}

\begin{multicols}{2}
    \dict{zebra}{n}{\lipsum \lipsum \lipsum}
    \dict{zero}{n}{\lipsum[4]}
\end{multicols}

\end{document}

Edit:
I should mention that I MUST only use xindy, because the Persian language has some problems with other programs such as makeindex.

share|improve this question
add comment

2 Answers

up vote 7 down vote accepted
+50

I know you prefer not to use any additional packages, but if no other answer suits you, here's how to do it using glossaries and xindy. First the LaTeX code:

\documentclass[twoside]{article}
\usepackage{multicol}
\usepackage{fancyhdr}
\usepackage[bf,sf,center]{titlesec}

% Headers and footers
\fancyhead[L]{\textsf{\rightmark}}
\fancyhead[R]{\textsf{\leftmark}}

\fancyfoot[C]{\textbf{\textsf{\thepage}}}

\renewcommand{\headrulewidth}{1.4pt}
\renewcommand{\footrulewidth}{1.4pt}

\pagestyle{fancy}

% For testing
\usepackage{lipsum}

\usepackage[xindy]{glossaries}

\makeglossaries

% The optional argument is in case you can't use the name as a label    
\newcommand{\dict}[4][]{%
  \newglossaryentry{#2}%
  {%
    name=#2,%
    symbol=#3,%
    description=#4,%
    #1%
  }%
  \glsadd{#2}%
}

\newglossarystyle{dict}%
{%
  \renewenvironment{theglossary}{}{\end{multicols}}%
  \renewcommand*{\glossaryheader}{}%
  \renewcommand*{\glsgroupheading}[1]{%
    \section*{##1}%
    \begin{multicols}{2}%
  }%
  \renewcommand*{\glsgroupskip}{\end{multicols}}%
  \renewcommand{\glossaryentryfield}[5]{%
    \markboth{##2}{##2}%
    \par\vspace{0.25\baselineskip}%
    \textbf{\textsf{##2}} \textit{- ##4 -} ##3%
  }%
}%

\renewcommand*{\glossarysection}[2][]{}

\begin{document}

    \dict{zero}{n}{\lipsum[4]}
    \dict{adhesive}{n}{\lipsum[5]}
    \dict{adhere}{n}{\lipsum[2]}
    \dict{adhesion}{n}{\lipsum[4]}
    \dict{adjacent}{n}{\lipsum[6]}
    \dict{adjust}{n}{\lipsum[6]}
    \dict{main}{n}{\lipsum[3]}
    \dict{material}{n}{\lipsum[1]}
    \dict{more}{n}{\lipsum[2]}
    \dict{zebra}{n}{\lipsum \lipsum \lipsum}
    \dict{adherence}{n}{\lipsum[3]}
    \dict{adjective}{n}{\lipsum[1]}
    \dict{adjoin}{n}{\lipsum[2]}
    \dict{mathematic}{n}{\lipsum[2]}
    \dict{adjourn}{n}{\lipsum[3]}
    \dict{adjournment}{n}{\lipsum[4]}
    \dict{adjunt}{n}{\lipsum[5]}
    \dict{adequate}{n}{\lipsum[1]}

\printglossary[style=dict]
\end{document}

To create the PDF you need to perform 3 steps:

  1. Use PDFLaTeX as usual, e.g. pdflatex myDoc.tex from a terminal/command prompt or click the PDFLaTeX button on your front-end/text editor.
  2. Either run the Perl script makeglossaries myDoc or explicitly call xindy (see Glossaries, Nomenclature, Lists of Symbols and Acronyms for more details).
  3. Repeat step 1.
share|improve this answer
add comment

A solution based on makeindex.

%%% test.tex %%%
\documentclass[twoside]{article}

    \usepackage{multicol}
    \usepackage{fancyhdr}   
    \usepackage[bf,sf,center]{titlesec}

% Headers and footers
    \fancyhead[L]{\textsf{\rightmark}}
    \fancyhead[R]{\textsf{\leftmark}}

    \fancyfoot[C]{\textbf{\textsf{\thepage}}}

    \renewcommand{\headrulewidth}{1.4pt}
    \renewcommand{\footrulewidth}{1.4pt}

% Entry command : \dictb{<word>}{<gender>}{<text>}
    \newcommand{\dictb}[3]{%
        \par\vspace{0.25\baselineskip}%
        \leavevmode
        \markboth{#1}{#1}%
        \textbf{\textsf{#1}} \textit{- #2 -} #3%
    }

    \pagestyle{fancy}  

% further formatting commands

\newenvironment{thedict}{}{}
\newenvironment*{dictsection}[1]{%
  \section*{#1}%
  \begin{multicols}{2}%
}{\end{multicols}}
\newcommand*{\dictitem}[4]{%
  \dictb{#1}{#2}{#3}%
}

\usepackage{makeidx}
\makeindex

\makeatletter
\newcommand*{\dict}{%
  \begingroup
    \@sanitize
    \@dblarg\@dict
}
\def\@dict[#1]#2#3#4{%
    \index{#1|{#2}{#3}{#4}}%
  \endgroup
}
\makeatother

% For testing
    \usepackage{lipsum}

\begin{document}

    \dict{adequate}{n}{\lipsum[1]}
    \dict{adhere}{n}{\lipsum[2]}  
    \dict{adherence}{n}{\lipsum[3]}
    \dict{adhesion}{n}{\lipsum[4]}
    \dict{adhesive}{n}{\lipsum[5]}
    \dict{adjacent}{n}{\lipsum[6]}
    \dict{adjective}{n}{\lipsum[1]}
    \dict{adjoin}{n}{\lipsum[2]}
    \dict{adjourn}{n}{\lipsum[3]}
    \dict{adjournment}{n}{\lipsum[4]}
    \dict{adjunt}{n}{\lipsum[5]}
    \dict{adjust}{n}{\lipsum[6]}
    \dict{main}{n}{\lipsum[3]}
    \dict{material}{n}{\lipsum[1]}
    \dict{mathematic}{n}{\lipsum[2]}
    \dict{more}{n}{\lipsum[2]}
    \dict{zebra}{n}{\lipsum \lipsum \lipsum}
    \dict{zero}{n}{\lipsum[4]}

\printindex

\end{document}
%%% test.tex %%%

The .idx file is generated with style dict.ist:

% Begin: Use characters not needed
encap '<'
level '>'
escape '['
quote ']'
% End: Use characters not needed
actual '|'
headings_flag 1
heading_prefix "\\begin{dictsection}{"
heading_suffix "}"
group_skip "\n\\end{dictsection}\n"
preamble "\\begin{thedict}\n"
postamble "\n\\end{dictsection}\n\\end{thedict}\n"
item_0 "\n  \\dictitem"
delim_0 "{"
delim_t "}"

The idea is that the index string that is written by LaTeX starts with the sort key, then | follows as separator and than the stuff follows that is actually used and set. Features like encapsulating command for page numbers, index levels and quoting/escaping are not needed. Therefore dict.ist uses <, >, [, ]. Replace these characters by characters not needed for the dictionary entries (I would use bytes 0x01, 0x02, 0x03, 0x04, do not use multiple bytes (UTF-8)).

Also \dict is defined in such a way, that it reads its arguments verbatim and uses an optional argument for the sort key. The first mandatory argument is used as default for the optional argument (feature of \@dblarg).

Then test.idx looks like:

\indexentry{adequate|{adequate}{n}{\lipsum[1]}}{1}
\indexentry{adhere|{adhere}{n}{\lipsum[2]}}{1}
\indexentry{adherence|{adherence}{n}{\lipsum[3]}}{1}
\indexentry{adhesion|{adhesion}{n}{\lipsum[4]}}{1}
\indexentry{adhesive|{adhesive}{n}{\lipsum[5]}}{1}
\indexentry{adjacent|{adjacent}{n}{\lipsum[6]}}{1}
\indexentry{adjective|{adjective}{n}{\lipsum[1]}}{1}
\indexentry{adjoin|{adjoin}{n}{\lipsum[2]}}{1}
\indexentry{adjourn|{adjourn}{n}{\lipsum[3]}}{1}
\indexentry{adjournment|{adjournment}{n}{\lipsum[4]}}{1}
\indexentry{adjunt|{adjunt}{n}{\lipsum[5]}}{1}
\indexentry{adjust|{adjust}{n}{\lipsum[6]}}{1}
\indexentry{main|{main}{n}{\lipsum[3]}}{1}
\indexentry{material|{material}{n}{\lipsum[1]}}{1}
\indexentry{mathematic|{mathematic}{n}{\lipsum[2]}}{1}
\indexentry{more|{more}{n}{\lipsum[2]}}{1}
\indexentry{zebra|{zebra}{n}{\lipsum \lipsum \lipsum}}{1}
\indexentry{zero|{zero}{n}{\lipsum[4]}}{1}

makeindex -s dict.ist test generates test.ind:

\begin{thedict}
\begin{dictsection}{A}
  \dictitem{adequate}{n}{\lipsum[1]}{1}
  \dictitem{adhere}{n}{\lipsum[2]}{1}
  \dictitem{adherence}{n}{\lipsum[3]}{1}
  \dictitem{adhesion}{n}{\lipsum[4]}{1}
  \dictitem{adhesive}{n}{\lipsum[5]}{1}
  \dictitem{adjacent}{n}{\lipsum[6]}{1}
  \dictitem{adjective}{n}{\lipsum[1]}{1}
  \dictitem{adjoin}{n}{\lipsum[2]}{1}
  \dictitem{adjourn}{n}{\lipsum[3]}{1}
  \dictitem{adjournment}{n}{\lipsum[4]}{1}
  \dictitem{adjunt}{n}{\lipsum[5]}{1}
  \dictitem{adjust}{n}{\lipsum[6]}{1}
\end{dictsection}
\begin{dictsection}{M}
  \dictitem{main}{n}{\lipsum[3]}{1}
  \dictitem{material}{n}{\lipsum[1]}{1}
  \dictitem{mathematic}{n}{\lipsum[2]}{1}
  \dictitem{more}{n}{\lipsum[2]}{1}
\end{dictsection}
\begin{dictsection}{Z}
  \dictitem{zebra}{n}{\lipsum \lipsum \lipsum}{1}
  \dictitem{zero}{n}{\lipsum[4]}{1}
\end{dictsection}
\end{thedict}

Running the example, e.g.:

  • pdflatex test
  • Optionally, edit dict.ist to change the characters of the first four settings to 1-byte characters not needed.
  • makeindex -s dict.ist test
  • pdflatex test
share|improve this answer
    
Thanks for your reply, but could you please tell me how I should run your code? –  Vahid Damanafshan Dec 2 '12 at 22:29
    
Thanks for your edit, but there are two problem: 1- As I said before, I should use Xelatex to run my files. 2- Unfortunately, the Persian language has some problems with makeindex, so I have to use xindy instead of makeindex. –  Vahid Damanafshan Dec 2 '12 at 22:54
    
By the way, could you please explain more about "Edit dict.ist to change the HTML entities by the real bytes."? I didn't understand what you meant. –  Vahid Damanafshan Dec 2 '12 at 22:58
    
Just use some characters that are not used in the dictionary, e.g. encap 'ä' or level '§'. Makeindex does not provide a method to disable these characters entirely. –  Heiko Oberdiek Dec 2 '12 at 23:12
    
I can't still run your code even using makeindex, because I don't know how to do "Edit dict.ist to change the HTML entities by the real bytes." –  Vahid Damanafshan Dec 3 '12 at 6:36
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.