# Rendering Farsi / Persian text with xelatex / pdflatex

A little while ago I asked some questions about the Greek and Korean languages in LaTeX and got some excellent responses. In the same context I'm looking now to the Farsi / Persian language.

The MWE:

\documentclass{book}

\usepackage[utf8]{inputenc}
\usepackage[LAE]{fontenc}
\usepackage[farsi]{babel}
\TOCLanguage{farsi}

\begin{document}
\chapter{فصل}
\section{بخش} % text missing

یک متن % text missing

$a^{2} = b^{2} + c^{2}$

a**2 = b**2 + c**2

\obeylines
00027         printf({"{}JUST A PRINT STATEMENT$$\backslash$$n"{}});
00027         printf({"{}Just a print statement$$\backslash$$n"{}});
00028         printf({"large یک متن Doxygen 1.8.19$$\backslash$$n"{}});
\begin{verbatim}
00027         printf({"{}JUST A PRINT STATEMENT SOME MORE TEXT$$\backslash$$n"{}});
00027         printf({"{}Just a print statement some more text$$\backslash$$n"{}});
00028         printf({"large یک متن Doxygen 1.8.19$$\backslash$$n"{}});
\end{verbatim}

\tableofcontents                                                                                                                    \end{document}


The output:

As you can see the output is (nearly) complete in the Farsi / Persian script, one exception is the a, b, c in the formula (but here the digit 2 is still translated).

Also the text of the section header and the line directly following is missing when rendering with xelatex, when using pdflatex this information is present again.

I also tried polyglossia, but here I have the problem that I get in a cycle regarding loading packages (analogous to: problem with polyglossia and hyperref).

As the code text is normally generated using language switches is not a real option (see e.g. the printf statement).

• The first thing that jumps out at me is that you’re mixing Farsi and English, but not declaring any secondary language or Latin font encoding. Jun 24 '20 at 17:51
• Indeed I mix Farsi and English text and I was hoping that there would be a solution analogous to the solution for Greek where it was not necessary to define the both languages (see tex.stackexchange.com/questions/548761/… and tex.stackexchange.com/questions/548901/…) Jun 25 '20 at 12:37

What you want—automatic detection of left-to-right/right-to-left script inside a verbatim environment—is not easily possible right now. (It could probably be done with interchar tokens in XeTeX, or Lua.) What you were trying to do was giving you mojibake gibberish.

You should always add the line \tracinglostchars=2 if you’re switching between different fonts to support different languages. That will warn you if the current font doesn’t support a glyph you asked for, which usually means you have the wrong language selected.

The following MWE almost works, in XeLaTeX or LuaLaTeX:

\tracinglostchars=2 % Warn if a glyph is missing from a font!
\documentclass{book}

\usepackage[bidi=default, layout=sectioning.counters, english]{babel}

% The environment defined by \babeltags fails to set the text direction.
\DeclareRobustCommand\textpersian[1]{\foreignlanguage{persian}{#1}}
\newenvironment{english}%
{\begin{otherlanguage}{english}}%
{\end{otherlanguage}}

\usepackage{unicode-math}
\defaultfontfeatures{ Renderer=HarfBuzz, Scale=MatchLowercase, Ligatures=TeX }
\babelfont{rm}
{Amiri}
\babelfont{tt}
{almfixed.otf}

\begin{document}
\chapter{فصل}
\section{بخش} % text missing

یک متن % text missing

$a^{2} = b^{2} + c^{2}$

a**2 = b**2 + c**2

\begin{english}
\obeylines
00027         printf({"{}JUST A PRINT STATEMENT$$\backslash$$n"{}});
00027         printf({"{}Just a print statement$$\backslash$$n"{}});
00028         printf({"large \textpersian{یک متن} Doxygen 1.8.19$$\backslash$$n"{}});
\begin{verbatim}
00027         printf({"{}JUST A PRINT STATEMENT SOME MORE TEXT$$\backslash$$n"{}});
00027         printf({"{}Just a print statement some more text$$\backslash$$n"{}});
00028         printf({"large ‏یک متن ‎Doxygen 1.8.19$$\backslash$$n"{}});
\end{verbatim}
\end{english}

\tableofcontents
\end{document}


If you look very closely, you’ll see that the Persian text in the \verbatim environment is not being displayed in the correct direction (even though I manually inserted right-to-left and left-to-right marks in the source).

You could get what you probably want by escaping out your text like in the first block and using alltt, listing, etc. instead of verbatim:

\tracinglostchars=2 % Warn if a glyph is missing from a font!
\documentclass{book}

\usepackage[bidi=default, layout=sectioning.counters, english]{babel}
\usepackage{alltt}

% The environment defined by \babeltags fails to set the text direction.
\DeclareRobustCommand\textpersian[1]{\foreignlanguage{persian}{#1}}
\newenvironment{english}%
{\begin{otherlanguage}{english}}%
{\end{otherlanguage}}

\usepackage{unicode-math}
\defaultfontfeatures{ Renderer=HarfBuzz,Scale=MatchLowercase, Ligatures=TeX }
\babelfont{rm}
{Amiri}
\babelfont{tt}
{almfixed.otf}
\setmathfont{LibertinusMath-Regular.otf}

\begin{document}
\chapter{فصل}
\section{بخش} % text missing

یک متن % text missing

$a^{2} = b^{2} + c^{2}$

a**2 = b**2 + c**2

\begin{english}
\obeylines
00027         printf({"{}JUST A PRINT STATEMENT$$\backslash$$n"{}});
00027         printf({"{}Just a print statement$$\backslash$$n"{}});
00028         printf({"large \textpersian{یک متن} Doxygen 1.8.19$$\backslash$$n"{}});

\begin{alltt}
00027         printf({"{}JUST A PRINT STATEMENT$$\backslash$$n"{}});
00027         printf({"{}Just a print statement$$\backslash$$n"{}});
00028         printf({"large \textpersian{یک متن} Doxygen 1.8.19$$\backslash$$n"{}});
\end{alltt}

\begin{verbatim}
00027         printf({"{}JUST A PRINT STATEMENT SOME MORE TEXT$$\backslash$$n"{}});
00027         printf({"{}Just a print statement some more text$$\backslash$$n"{}});
00028         printf({"large ‏یک متن ‎Doxygen 1.8.19$$\backslash$$n"{}});
\end{verbatim}
\end{english}

\tableofcontents
\end{document}


In theory, it’s supposed to be possible to set up XeTeX to automatically switch languages when you change scripts, wirh ucharclasses. The manual claims that something like this might do it:

\usepackage[Arabics]{ucharclasses}
\setTransitionsForArabics%
{\begingroup\selectlanguage{persian}}%
{\endgroup}


As of 2020, the package is broken and does not seem to be actively maintained. Many of the interactions between babel and fontspec appear to be broken in TeX Live 2020 as well, but those I was able to work around.

I’m going to omit a solution that supports PDFTeX, since it would be completely different and consist entirely of hacks around the fact that classic 8-bit TeX was never designed to support Persian.

• I think some of the problems I was having with fontspec and XeTeX were actually caused by missing fontconfig configuration files on my box. They seem to be fixed now. Jun 25 '20 at 7:42
• Thanks for the answer, I have to study it properly to see whether or not I can derive some points for my solution out of it. In the Question I already wrote: "As the code text is normally generated using language switches is not a real option (see e.g. the printf statement)." Going for xelatex is no problem. Jun 25 '20 at 12:40
• @albert That sentence is very ambiguous, and I don’t understand what you want the output to be or why language tags are not a real option. I took you to mean that you wanted something like the second listing in my last example, but apparently not? Jun 25 '20 at 18:51
• @albert Whatever it is you’re doing, you probably do not want to use verbatim for it. The solution might end up involving the built-in regex facilities of expl3 to pre-process, escape and format the generated code. Jun 25 '20 at 18:54

@albert

Do you know about xepersian package in XeLaTeX? It's amazing for Persian (Farsi) and Arabic and maybe English. It installs automatically when you setup TeX Live in CTAN. It is written by Dr.Vafa Khalighi (karen Pahlavi-Iranian) (see CTAN).

Note: You don't need babel package or polyglossia package.

If you use many packages (example amsmath) then \usepackage{xepersian} must be latest package in preamble. Then you type in preamble \settextfont{your ttf font}. It works for any TTF (true type fonts in your OS). XB fonts (example XB Yas.ttf or XB Zar.ttf etc. are Persian-English fonts-double languages).

Then you type \setlatintextfont{your ttf latin font} (If you want Persian font don't be Latin font. Note: If you want to use XB fonts-double language- for Persian and English text, then you don't need this command. and so you can type \setdigitfont{your ttf font} for digits in text or formulas in equations etc. If you select Persian (Arabic-English) font then all digits (even in formulas) will be Persian (Arabic-English) numbers.)

If in your text you want to write English or German or ... then you type \lr{your English text} or you type:

\begin{latin}
your latin text or index or ...
\end{latin}


xepersian automatically outputs a PDF file, Right to Left.

Use \leftline command to write Latin text in your output Left to Right.

If you write your TeX file in LaTeX or XeLaTeX then add above command in preamble or in document then will work well (Note: don't use babel or polyglossia commands or packages) and compile with XeLaTeX.

Now you can easily write your desired TeX file with the above description in xepersian and get your desired output.

For Persian index, Dr. Khalighi wrote quickindex. He even wrote a Persian poem with xepersian package. Or build Persian slides for conferences or ...

You search for xepersian and then you will discover new world in XeLaTeX.

• The question lists a couple of very specific problems which your answers only touches upon conceptually without providing a proper solution. Aug 11 '20 at 4:38