4

It seems I cannot color an RTL language in babel. The (xelatex) code below colors the first line in black, not red:

\documentclass{article}
\setlength{\parindent}{0pt}
\usepackage{xcolor}
\usepackage[bidi=default]{babel}
\babelprovide[import,main]{arabic}
\babelfont{rm}{FreeSerif}
\begin{document}

\begingroup
\color{red}English and $math$   % black
\endgroup

\color{red}English and $math$   % red

\end{document}

The mere difference is a group. I don't understand why a group matters.

A related question might be Create an adapted \color macro for RTL mode (pdflatex and xelatex) But it doesn't use babel, and it doesn't seem to be solved.

10
  • it works if you have a blank line before the endgroup, but really we should try to make this better, but right to left in xetex (tex--xet) is actively hostile to the \special mechanism used for xetex color, so it's harder than it ought to be. Aug 1, 2020 at 20:20
  • 1
    it is a problem with the xelatex engine. color is done with specials, and they are in the wrong order with xelatex. Better use lualatex and [bidi=basic]. Aug 1, 2020 at 20:22
  • @UlrikeFischer but if I knew I was in a RTL block I could (possibly) add the colour specials in the wrong order so that tex--xet flipped them round. Perhaps. Aug 1, 2020 at 20:23
  • @DavidCarlisle but wouldn't you always get problems if line breaks are involved? Aug 1, 2020 at 20:24
  • @UlrikeFischer I always get problems. Aug 1, 2020 at 20:25

2 Answers 2

3

xetex's right to left mechanism, known as TeX--XeT works essentially as a post processor to the generated dvi file. (The original version of the algorithm, TeX-XeT, was a post processor, TeX--XeT is essentially the same but built in to the etex and xetex engines.)

This means that almost all processing happens as if for left to right processing, then at the final stage each line separately is more or less naively written out to the dvi file in reverse order.

This has several drawbacks compared with the direction support in luatex (which is derived from Omega). Notably:

  • you can not specify right to left between paragraphs (in vertical mode). (This is why it is hard to have longtable columns right to left in xetex.)

  • Paired \special like color start and color end will be written out in the wrong order if they are on the same line.

This is why having the paragraph end before the group (or having no group) makes the color work in your example: the color start is on one line and the color end is on a later line, and so even when each line is reversed the start is before the end.

If the color command knows the color was going to end on the same line, and it is an rtl region, it could write out the specials in the wrong order, so TeX--XeT would reverse them making them correct, however in general if it wrote them in the wrong order but there was a line break, the color end would again appear in the dvi before the color start.


This is a Non-answer marked as community wiki, if anyone has anything more coherent to add, feel free to edit...


From Cicada:

As given in the code, the main language for the document is defined as Arabic, so even English text (or any other text) will come out in RTL order.

In an RTL environment, put the \color command token at the front (=on the right), so it comes first.

But better, why not use babel's \selectlanguage{} command to switch languages?

babel language

MWE

\documentclass{article}
\setlength{\parindent}{0pt}
\usepackage{xcolor}
\usepackage[bidi=default]{babel}
\babelprovide[import,main]{arabic}
\babelfont{rm}{FreeSerif}
\begin{document}

\begingroup
English and $math$ -- this is blue\color{blue}   % black
\endgroup

\color{red}English and $math$ -- this is red   % red

هذا أحمر أم أزرق؟


\selectlanguage{english}

hadha 'ahmar 'am 'azaraq?

\begingroup
\color{blue}  English and $math$ -- this is blue (in front, in English)% black
\endgroup

\color{red}English and $math$ -- this is red   % red
\end{document}
2
  • If I move \color into the middle of line like this: English \color{red}and $math$ Then it is English that gets colored red, with or without a linebreak. Why wouldn't a linebreak solve this new problem?
    – Cyker
    Aug 1, 2020 at 20:55
  • @Cyker sorry no time to debug tonight you can add \showoutput and see where the specials end up, but it really is tricky in xetex, babel/bidi/color are all trying to do the right thing but the underlying primitive behaviour is really lacking features and what exactly happens in any particular case usually requires spending an hour tracing the tex execution, even for people like myself who wrote parts of the code. Aug 1, 2020 at 21:26
1

You could always use xecolor for bidi texts. It is by the same developer as [bidi] and solves color problems in TeX--XeT (it basically handles colors as font features, not specials).

\documentclass{article}
\setlength{\parindent}{0pt}
\usepackage{xcolor}
\usepackage[bidi=default]{babel}
\babelprovide[import,main]{arabic}
\babelfont{rm}{FreeSerif}
\begin{document}

\begingroup
\xecolor{red}English and $math$   % black
\endgroup

\xecolor{red}English and $math$   % red

\end{document}
1
  • This work only for coloring text not drawing stuff like rules.
    – Salim Bou
    Sep 21, 2020 at 6:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .