6

I would like to change the font in XeLaTeX when I enter a new Unicode block with a certain Script (e.g. Devanagari for Hindi languages). The ucharclasses package seems to do exactly that.

However, when I leave the place where the different script is used and go back to what I had before (e.g. latin script) I loose the formatting (e.g. boldface) and the font size.

To illustrate, try this:

\documentclass[10pt,a5paper,DIV12,BCOR8.25mm,twoside,parskip=half]{scrreprt}

\usepackage[Devanagari]{ucharclasses}
\usepackage{xltxtra}
\usepackage{fontspec}
\setmainfont[Mapping=tex-text]{Liberation Serif}
\setsansfont[Mapping=tex-text]{Liberation Sans}
\setmonofont[Mapping=tex-text]{Liberation Mono}
\newfontfamily\hindifont{Siddhanta}
\setTransitionsFor{Devanagari}{\hindifont}{\rm}


\begin{document}
\tableofcontents
\section{A latin script section}
Some latin script
\section{Devanagari: ताजा धनिया के साथ अनायास and so on}
A mixture \textbf{ of normal text and ताजा धनिया के साथ अनायास Devanagari script} in bold
\section{Some more latin script}
Some latin script
\end{document}

The output looks like this:

Script changes

The \setTransitionTo correctly picks up the Devanagari script and changes the font to Siddhanta. However, when I come back to latin script, the boldface is gone and the fontsize is increased. The table of contents line shows the same problem.

N.B. \setTransitionsFor{...}{...}{...} is what the documentation describes as \setTransitions. The doc seems to be wrong.

kongo09
  • 2,486
  • I don't know if this will solve your problem (and can't test right now, hence not an answer), but you should not use {\bf text}. Use \textbf{text} instead. For reasons as to why, see the l2tabu package. – Roelof Spijker Oct 21 '11 at 16:01
  • @whlt3 Thanks for your advice. I've changed the question to use \textbf but that doesn't help. I also added some text to the section title to show the same problem appearing in the table of contents. – kongo09 Oct 21 '11 at 16:07

2 Answers2

9

You can try something like this (I used the ^^-notation because I don't have an utf8-editor here):

\documentclass[10pt,a5paper,DIV12,BCOR8.25mm,twoside,parskip=half]{scrreprt}
\usepackage[Devanagari]{ucharclasses}
\usepackage{fontspec}

\newfontfamily\hindifont{Arial Unicode MS}
\makeatletter
\setTransitionsFor{Devanagari}%
 {\let\curfamily\f@family\let\curshape\f@shape\let\curseries\f@series\hindifont}
 {\fontfamily{\curfamily}\fontshape{\curshape}\fontseries{\curseries}\selectfont}
\makeatother

\begin{document} \tableofcontents \section{A latin script section} Some latin script

\section{Devanagari: ^^^^0908 ^^^^0909 and so on} A mixture \textbf{ of normal text and ^^^^0908 ^^^^0909 Devanagari script} in bold
\section{Some more latin script} Some latin script

\end{document}
Ulrike Fischer
  • 327,261
  • 1
    I bow my head and am deeply impressed. Works like a charm! – kongo09 Oct 21 '11 at 16:55
  • Would you please add some explanation as to what you did here, for us who are font impaired? – yannisl Oct 21 '11 at 17:14
  • @Yiannis: I simply stored the description of the actual font before switching to \hindifont and then called this font when quiting the devanangari block. – Ulrike Fischer Oct 21 '11 at 17:20
  • I think this actually doesn't work for mixtures of scripts, where you go from latin to script1 then to script2 and then back to latin. This can happen in Japanese, for example, that can go from kanji to katagana to hiragana and even latin script. – kongo09 Oct 21 '11 at 20:49
  • There is one additional caveat! When I use the non-latin script in the section title and the last latin character before the non-latin script is a / you need to add a \relax to make it work, e.g.: \section{Devanagari /\relax भारी धनिया संकट}. Otherwise, Ulrike's trick throws an error. – kongo09 Oct 22 '11 at 12:22
  • And one more: In my example, I used \usepackage[Devanagari]{ucharclasses}. This restricts the processing of ucharclasses to the Devanagari script, which helps with processing time as ucharclasses is incredibly slow. However, as a consequence, the detection of the end of the Devanagari script can then fail. Taking out the option helps - and makes the usage of the \relax as described above unnecessary. – kongo09 Oct 22 '11 at 12:34
  • @kongo09: 1. The docu doesn't say it explicitly but as far as I can see the transition commands are applied only at "boundary chars". That means things like "a^^^^0908" or "/^^^^0908" will not work. There must be a space or a \relax or a brace (a{^^^^0908}) between the scripts. 2. If more than one script is involved and you nest them a lot restoring the "correct" font can be difficult to do with such a command. In this cases grouping with braces (latin {^^^^0908} latin) may give better results (with braces it is not necessary to restore the font, simply switch to \hindifont at the start). – Ulrike Fischer Oct 22 '11 at 15:36
  • @UlrikeFischer So how would I use braces automatically? They would have to be escaped somehow when I put them into the command braces, right? – kongo09 Oct 22 '11 at 17:28
  • @kongo09: Use \bgroup and \egroup (macro form of braces); or \begingroup and \endgroup (low level grouping). – Leo Liu Oct 22 '11 at 17:37
  • This is generally working for me, but I find that the COLOR of the text is not being preserved. I tried the following – asllearner May 14 '12 at 08:07
  • I am losing the current color: \setTransitionsFor{LatinSupplement}% {\colorlet{currentcolor}{.}\let\curfamily\f@family\let\curshape\f@shape\let\curseries\f@series\JapSubstFont\color{currentcolor}} {\fontfamily{\curfamily}\fontshape{\curshape}\fontseries{\curseries}\selectfont} for example doesnt work. the color of the text is always black.. – asllearner May 14 '12 at 08:08
6

I think it's easy:

\def\ResetTransitionTo#1{%
  \XeTeXinterchartoks 255 \csname#1Class\endcsname{\relax}}
\setTransitionsFor{Devanagari}
  {\begingroup\ResetTransitionTo{Devanagari}\sethindifont}
  {\endgroup}

This is what we do in xeCJK. Note that we must reset the \XeTeXinterchartoks to make the group balance. It is a place that ucharclasses is not very well implemented.

Hmm, spaces between scripts are necessary here. It's very boring to define all transitions for all scripts in the document, if there are many.

Leo Liu
  • 77,365
  • 1
    Can you explain how your solution works? What does \ResetTransitionTo do? Is it better than a simple \setTransitionsFor{Devanagari}{\begingroup\sethindifont}{\endgroup}? – Olivier Cailloux Feb 09 '16 at 15:52
  • Note that the word boundary class currently has the number 4095 (since 2016) instead of 255. – Marijn Mar 10 '23 at 22:08