7

I'm trying to create a Japanese to English dictionary for particular words used earlier in my document.

I successfully created an English to Japanese version using the glossaries package, now I want to go the other way. The problem is, I can't put Japanese characters in the "name" field, only in the "description" field. If possible, I'd like to put them in the name field.

That is \newglossaryentry{aaa}{type=JtoE,name={},description={\begin{CJK}{UTF8}{min}あ\end{CJK}}} works, while \newglossaryentry{aaa}{type=JtoE,name={\begin{CJK}{UTF8}{min}あ\end{CJK}}},description={a} does not.

There seems to be a solution to a similar problem here, but it doesn't work in my case; I've used the CJKutf8 package for japanese characters throughout my document and I'd rather not go back and change it all the way through.

Of course, I would like to be able to use both kana and kanji in the name.

Here's a minimal working example.

\documentclass{article}


\usepackage{CJKutf8}
\usepackage[overlap, CJK]{ruby}
\renewcommand{\rubysep}{0.01ex}
\usepackage[nopostdot,nonumberlist]{glossaries}
\usepackage{glossary-mcols}
\setglossarystyle{mcolindex}

\newglossary*{EtoJ}{English to Japanese}
\newglossary*{JtoE}{Japanese to English}

\makenoidxglossaries

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% English to Japanese Gloss %%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newglossaryentry{squareroot}
{
type=EtoJ,
name={squareroot},
description={\begin{CJK}{UTF8}{min}ルート\end{CJK}}%
}

\newglossaryentry{monomial}
{
type=EtoJ,
name={monomial},
description={\begin{CJK}{UTF8}{min}\ruby{単}{たん}\ruby{項}{こう}\ruby{式}{し
き}\end{CJK}}%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% Japanese to English Gloss %%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newglossaryentry{aaa}
{
type=JtoE,
name={},
description={\begin{CJK}{UTF8}{min}あ\end{CJK}}
}

\begin{document}
\glsaddall

\printnoidxglossary[type=EtoJ]
\newpage
\printnoidxglossary[type=JtoE]

%\printnoidxglossaries


\end{document}
  • Welcome to TeX.SX! Are you using the makeindex backend for makeglosaries or xindy (I guess the former)? – TeXnician Sep 7 '17 at 5:35
  • I doubt that makeindex will work here. Most likely xindy is the way to go – user31729 Sep 7 '17 at 6:48
  • Thank you. I think you've hit the source of the problem. I'm using \makenoidxglossaries which doesn't use either makeindex or xindy. I'll try with xindy. – James Sep 7 '17 at 7:30
  • As an update, I've successfully used xindy for English, but it appears to be missing a Japanese folder in MikTex 2.9 > xindy > modules > lang. Is it therefore not possible? And, if it is possible, will I only be able to use glossaries with English or Japanese names? I would like to be able to use both. – James Sep 7 '17 at 8:13
6

\makenoidxglossaries is only designed for ASCII. (See No printed glossaries when switching to \makenoidxglossaries.) The comments have recommended xindy, which has the best multilingual support of the three indexing methods that work with the glossaries package, but there are still some more problems.

If we first start without setting up the indexing:

\documentclass{article}

\usepackage{CJKutf8}
\usepackage{glossaries}

\newglossaryentry{squareroot}{name={\begin{CJK}{UTF8}{min}ルート\end{CJK}},
  description={square root}}

\begin{document}

\begin{CJK}{UTF8}{min}ルート\end{CJK}% for comparison

\gls{squareroot}

\end{document}

then this causes the error:

! Undefined control sequence.
\in@ #1#2->\begingroup \def \in@@ 
                                  ##1#1{}\toks@ \expandafter {\in@@ #2{}{}#1...

If this error occurs with \newglossaryentry then the problem is typically an expansion issue. This can be switched off with \glsnoexpandfields. It's also a good idea to have a wrapper command that takes a single argument if the name field needs formatting. The sort value is copied from the name and the \begin{CJK}{UTF8}{min} part will interfere with the collator.

Here's the modified version:

\documentclass{article}

\usepackage{CJKutf8}
\usepackage{glossaries}

\newrobustcmd{\cjkname}[1]{\begin{CJK}{UTF8}{min}#1\end{CJK}}
\glsnoexpandfields

\newglossaryentry{squareroot}{name={\cjkname{ルート}},
  description={square root}}

\begin{document}

\begin{CJK}{UTF8}{min}ルート\end{CJK}

\gls{squareroot}

\end{document}

This now compiles and produces:

ルート ルート

The next step is to add the code to generate the index. A listing of xindy's modules/lang directory shows:

albanian    finnish    icelandic      mongolian   spanish
belarusian  french     italian        norwegian   swedish
bulgarian   general    klingon        persian     turkish
croatian    georgian   korean         polish      ukrainian
czech       german     kurdish        portuguese  upper-sorbian
danish      greek      latin          romanian    vietnamese
dutch       gypsy      latvian        russian
english     hausa      lithuanian     serbian
esperanto   hebrew     lower-sorbian  slovak
estonian    hungarian  macedonian     slovenian

so there doesn't seem to be any support for Japanese. The closest is Korean. The number group needs to be switched off as it's designed for Latin alphabets:

\documentclass{article}

\usepackage{CJKutf8}
\usepackage[xindy={language={korean},glsnumbers=false}]{glossaries}

\makeglossaries

\newrobustcmd{\cjkname}[1]{\begin{CJK}{UTF8}{min}#1\end{CJK}}
\glsnoexpandfields

\newglossaryentry{squareroot}{name={\cjkname{ルート}},
  description={square root}}

\begin{document}

\begin{CJK}{UTF8}{min}ルート\end{CJK}

\gls{squareroot}

\printglossaries
\end{document}

If the file is called test.tex, then the build process is:

pdflatex test
makeglossaries test
pdflatex test

(There's also a Lua version makeglossaries-lite for those who don't have Perl installed, but since xindy is also a Perl script you'll need the Perl interpreter for that anyway.)

Alternatively you can explicitly run xindy:

pdflatex test
xindy -L korean -C utf8 -I xindy -M test -t test.glg -o test.gls test.glo
pdflatex test

The resulting document looks like:

image of document

The file created by xindy has the code used to display the glossary:

\begin{theglossary}\glossaryheader
\glsgroupheading{default}\relax\glsresetentrylist
\glossentry{squareroot}{\glossaryentrynumbers{\relax
\glsXpageXglsnumberformat{}{1}}}%
\end{theglossary}\glossarypostamble

The \glsgroupheading{default} part shows that xindy doesn't recognise the Japanese characters and has put the entry in the default letter group. This means that you can't use any of the letter group styles, such as indexgroup. It may also indicate that it doesn't have a rule that can correctly sort ルート.

There's a fourth indexing option, and that's to use bib2gls which requires the extension package glossaries-extra with the record option. bib2gls is a command line application (requires at least Java 7)¹ that can be used to sort and collate entries. This method requires that all the entries are defined in a .bib file. For example, suppose the file called testcjk.bib contains:

@entry{squareroot,
  name={\cjkname{ルート}},
  description={square root}
}

Then the document now looks like:

\documentclass{article}

\usepackage{CJKutf8}

\usepackage[record]{glossaries-extra}

\newrobustcmd{\cjkname}[1]{\begin{CJK}{UTF8}{min}#1\end{CJK}}
\glsnoexpandfields

\GlsXtrLoadResources[
  src=testcjk,% bib file
  sort={ja-JP}% locale
]

\begin{document}

\begin{CJK}{UTF8}{min}ルート\end{CJK}

\gls{squareroot}

\printunsrtglossaries
\end{document}

The build process is now:

pdflatex test
bib2gls test
pdflatex test

This produces:

image of document

If you want letter groups, you need to use the --group switch:

pdflatex test
bib2gls --group test
pdflatex test

as well as setting a glossary style that supports letter groups (such as indexgroup). With the --group switch, this example makes bib2gls write the following code to the file loaded by \GlsXtrLoadResources:

\bibglssetlettergrouptitle{{ルー}{ルー}{9568256}{}}

This means that bib2gls thinks that "ルート" belongs to the "ルー" letter group. I don't know any Japanese so I don't know if this is correct, but the group title will need encapsulating within the CJK environment. Expansion is also an issue here since the Japanese characters are active with CJKutf8. Here's the amended example:

\documentclass{article}

\usepackage{CJKutf8}
\usepackage[record,style=indexgroup]{glossaries-extra}

\newrobustcmd{\cjkname}[1]{\begin{CJK}{UTF8}{min}#1\end{CJK}}
\glsnoexpandfields

\newcommand{\bibglslettergrouptitle}[4]{\unexpanded{\cjkname{#1}}}

\GlsXtrLoadResources[
  src=testcjk,% bib file
  sort={ja-JP}% locale
]

\begin{document}

\begin{CJK}{UTF8}{min}ルート\end{CJK}

\gls{squareroot}

\printunsrtglossaries
\end{document}

The build process is now:

pdflatex test
bib2gls --group test
pdflatex test

The resulting document looks like:

ルート ルート Glossary ルー ルート square root 1

For the English to Japanese glossary, if it's a straight swap of name and description you can change the .bib file to

@dualentry{squareroot,
  name={\cjkname{ルート}},
  description={square root}
}

The letter group heading should only be encapsulated for the japanese glossary type. This can be dealt with by making \bibglslettergrouptitle check the glossary type:

\newcommand*{\englishlettergroup}[1]{#1}% heading used for `type=english`
\newcommand*{\japaneselettergroup}[1]{\cjkname{#1}}% heading used for `type=japanese`

\newcommand{\bibglslettergrouptitle}[4]{% #4 = type
 \unexpanded{\csuse{#4lettergroup}{#1}}}

The document file is now:

\documentclass{article}

\usepackage{CJKutf8}
\usepackage[record,style=indexgroup,nomain]{glossaries-extra}

\newglossary*{japanese}{Japanese to English}
\newglossary*{english}{English to Japanese}

\newrobustcmd{\cjkname}[1]{\begin{CJK}{UTF8}{min}#1\end{CJK}}
\glsnoexpandfields

\newcommand*{\englishlettergroup}[1]{#1}
\newcommand*{\japaneselettergroup}[1]{\cjkname{#1}}
\newcommand*{\bibglslettergrouptitle}[4]{\unexpanded{\csuse{#4lettergroup}{#1}}}

\GlsXtrLoadResources[
  src=testcjk,% bib file
  sort={ja-JP},% locale used to sort primary entries
  dual-sort={en-GB},% locale used to sort secondary entries
  type=japanese,% put the primary entries in the 'japanese' glossary
  dual-type=english% put the dual entries in the 'english' glossary
]

\begin{document}

Japanese: \gls{squareroot}

English: \gls{dual.squareroot}

\printunsrtglossaries
\end{document}

(You can use just the language code without the region: sort=ja,dual-sort=en.)

This produces:

image of document

You can change the default dual prefix dual. if required. For example:

\documentclass{article}

\usepackage{CJKutf8}
\usepackage[record,style=indexgroup,nomain]{glossaries-extra}

\newglossary*{japanese}{Japanese to English}
\newglossary*{english}{English to Japanese}

\newrobustcmd{\cjkname}[1]{\begin{CJK}{UTF8}{min}#1\end{CJK}}
\glsnoexpandfields

\newcommand*{\englishlettergroup}[1]{#1}
\newcommand*{\japaneselettergroup}[1]{\cjkname{#1}}
\newcommand*{\bibglslettergrouptitle}[4]{\unexpanded{\csuse{#4lettergroup}{#1}}}

\GlsXtrLoadResources[
  src=testcjk,% bib file
  sort={ja-JP},% locale used to sort primary entries
  dual-sort={en-GB},% locale used to sort secondary entries
  type=japanese,% put the primary entries in the 'japanese' glossary
  dual-type=english,% put the dual entries in the 'english' glossary
  dual-prefix={en.}
]

\begin{document}

Japanese: \gls{squareroot}

English: \gls{en.squareroot}

\printunsrtglossaries
\end{document}

You can provide the definition of \cjkname in a .bib file, but it needs to be protected from bib2gls's interpreter to prevent it from interfering with the sort value. For example, if the file defs-nointerpret.bib contains:

@preamble{"\providerobustcmd{\cjkname}[1]{\begin{CJK}{UTF8}{min}#1\end{CJK}}
\providecommand*{\englishlettergroup}[1]{#1}
\providecommand*{\japaneselettergroup}[1]{\cjkname{#1}}
\providecommand*{\bibglslettergrouptitle}[4]{\unexpanded{\csuse{#4lettergroup}{#1}}}"}

then the document is now:

\documentclass{article}

\usepackage{CJKutf8}
\usepackage[record,style=indexgroup,nomain]{glossaries-extra}

\newglossary*{japanese}{Japanese to English}
\newglossary*{english}{English to Japanese}

\glsnoexpandfields

\GlsXtrLoadResources[
   src={defs-nointerpret}, % bib file containing @preamble
   interpret-preamble=false % write the @preamble contents but don't try to interpret
]

\GlsXtrLoadResources[
  src=testcjk,% bib file
  sort={ja-JP},% locale used to sort primary entries
  dual-sort={en-GB},% locale used to sort secondary entries
  type=japanese,% put the primary entries in the 'japanese' glossary
  dual-type=english,% put the dual entries in the 'english' glossary
  dual-prefix={en.}
]

\begin{document}

Japanese: \gls{squareroot}

English: \gls{en.squareroot}

\printunsrtglossaries
\end{document}

This hides away the commands that are used by the glossary entries but aren't used explicitly in the document. A more general purpose approach for the letter group headings is:

\newcommand*{\englishlettergroup}[1]{#1}
\newcommand*{\japaneselettergroup}{\cjklettergroup}
\newcommand*{\cjklettergroup}[1]{\cjkname{#1}}

\newcommand{\bibglslettergrouptitle}[4]{%
 \unexpanded{%
   \ifcsdef{#4lettergroup}%
   {\csuse{#4lettergroup}{#1}}%
   {\cjklettergroup{#1}}%
 }%
}

This will use \englishlettergroup if type=english, \japaneselettergroup if type=japanese, and will just use \cjklettergroup if type is something else (such as the default main). So the file defs-nointerpret.bib now contains:

@preamble{"\providerobustcmd{\cjkname}[1]{\begin{CJK}{UTF8}{min}#1\end{CJK}}
\providecommand*{\englishlettergroup}[1]{#1}
\providecommand*{\japaneselettergroup}{\cjklettergroup}
\providecommand*{\cjklettergroup}[1]{\cjkname{#1}}    
\providecommand{\bibglslettergrouptitle}[4]{%
 \unexpanded{%
   \ifcsdef{#4lettergroup}%
   {\csuse{#4lettergroup}{#1}}%
   {\cjklettergroup{#1}}%
 }%
}"}

Addendum: iterative commands like \glsaddall don't work with the record option because on the first LaTeX run no entries are defined so there's nothing to iterate over. If you want to select all entries, regardless of whether they've been used in the document, use selection=all:

\GlsXtrLoadResources[
  src={testcjk},% bib file list
  selection=all,% select all entries provided in this 'src' list
  sort={ja-JP},% locale used to sort primary entries
  dual-sort={en-GB},% locale used to sort secondary entries
  type=japanese,% put the primary entries in the 'japanese' glossary
  dual-type=english,% put the dual entries in the 'english' glossary
  dual-prefix={en.}
]

Note that \glsaddall internally uses \glsadd (which always adds a location to the location list). This means that nonumberlist has to be used otherwise you end up with the same location in every entry in the glossary. With bib2gls if an entry is selected through selection=all it will only have a location list if it's been indexed in the document with commands like \gls or \glsadd.


¹ Note that Java 7 has now reached its end of life and is deprecated. Java 8 includes support for the Common Locale Data Repository (CLDR) which provides more extensive locale support.

  • Thank you Nicola, your answer really helped. The second method you mention looks like it could be a really elegant solution. Can you expand a little on the bib2gls --group test step? It seems to be something I'd have to do in Java, which I'm not familiar with. Also, will \glsaddall still work? – James Sep 7 '17 at 23:36
  • @James \glsaddall doesn't work with bib2gls. Instead you need to do selection=all in the \GlsXtrLoadResources options. You need the Java Runtime Environment installed to run bib2gls. (At least Java 7.) There are some other useful TeX-related Java applications, such as arara and JabRef. (In fact, JabRef could be a useful tool to manage the .bib files used with bib2gls) The TeX distributions usually convert the .jar files to .exe for Windows users, so once bib2gls is uploaded to CTAN, it's possible the same will happen with it. (I'll update the answer then.) – Nicola Talbot Sep 7 '17 at 23:43
  • 1
    @James bib2gls is now in TeX Live 2017 so if you want to use and you have TL you can install it from the TL package manager. (It's not currently in MikTeX.) – Nicola Talbot Sep 11 '17 at 19:15
  • 1
    @James bib2gls is now also in MikTeX. – Nicola Talbot Sep 12 '17 at 14:26
  • Apologies, it's been some months, I let it lay for a while (it seems MikTex wasn't working well for a while). I've now managed to get bib2gls working when not using Japanese. However, when I try to insert Japanese text (i.e. copying one of your examples), I get the error ! LaTeX Error: Command \guillemotleft unavailable in encoding OT1. Is there something I'm missing? – James Apr 25 '18 at 20:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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