2

Let's say I write a LaTeX document that usually is compiled with xelatex (and polyglossia), but I'd like to have pdflatex (and babel) as a fallback (when I send it to someone who might not have xelatex installed). For this I'd write \textspanish{} in the document and I came up with the following redefinition (wrapped basically in if pdflatex):

\newcommand{\textspanish}[2][]{\foreignlanguage{spanish}{#2}}

This approach seems to work fine for most languages, but for some reason babel has already a \textspanish command defined. So I tried the same with \renewcommand but this went into infinite recursion or something (TeX capacity exceeded, sorry [grouping levels=255]) for a reason I don't understand.

Sample document (works with xelatex, fails with pdflatex):

\documentclass[english,]{article}
\usepackage{lmodern}
\usepackage{ifxetex,ifluatex}
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
  \usepackage[shorthands=off,spanish,english]{babel}
  \newcommand{\textspanish}[2][]{\foreignlanguage{spanish}{#2}}
\else
  \usepackage{polyglossia}
  \setmainlanguage[]{english}
  \setotherlanguage[]{spanish}
\fi
\begin{document}

Hello \textspanish{Hola}

\end{document}
6
  • 1
    Polyglossia already defines \textspanish, which exactly does the same as you want to obtain.
    – egreg
    Commented Oct 17, 2015 at 9:43
  • huh, but I cannot use Polyglossia with pdflatex, right? (see first sentence of my question..)
    – mb21
    Commented Oct 17, 2015 at 9:47
  • Of course not, but having an example would be better.
    – egreg
    Commented Oct 17, 2015 at 9:48
  • No, an example of a simple document and what you mean by “fallback”.
    – egreg
    Commented Oct 17, 2015 at 9:56
  • That is quite complicated to test for the engine.
    – Johannes_B
    Commented Oct 17, 2015 at 10:07

3 Answers 3

3

Here is a solution not requiring another package:

\documentclass[english]{article}
\usepackage{lmodern}
\usepackage{ifxetex,ifluatex}
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex\
  \usepackage[shorthands=off,spanish,main=english]{babel}
  \let\oritextspanish\textspanish
  \AddBabelHook{spanish}{beforeextras}
    {\renewcommand{\textspanish}{\oritextspanish}}
  \AddBabelHook{spanish}{afterextras}
    {\renewcommand{\textspanish}[2][]{\foreignlanguage{spanish}{##2}}}
\else
  \usepackage{polyglossia}
  \setmainlanguage[]{english}
  \setotherlanguage[]{spanish}
\fi
\begin{document}

Hello \textspanish{Hola n\sptext{os}}

\end{document}

An issue related to the main language is also fixed (and I wonder if [2][] is intended, because the optional argument is not used at all).

3
  • Thanks, that looks even better! The [2][] is due to polyglossia's \textenglish[variant=british] syntax...
    – mb21
    Commented Oct 18, 2015 at 9:13
  • "main language has been fixed": you mean changing \usepackage[spanish,english]{babel} to \usepackage[spanish,main=english]{babel}? What's the difference?
    – mb21
    Commented Oct 18, 2015 at 9:18
  • @mb21 The behavior is not well defined when a language is set as global and as package option. With the key main= we make sure which the main language is (look at the log file when this key is no used). Commented Oct 18, 2015 at 18:16
2

I'm not sure what you mean by “fallback”. The problem seems to be that with polyglossia a \textspanish command already exists as soon as you enable Spanish; the good news is that this command essentially does \foreignlanguage{spanish}.

The bad news is that babel-spanish defines \textspanish (I don't know why they chose this name) and there's essentially no hope of using it as you'd like.

Here's an example of how \textspanish is used in spanish.ldf, that also hints at what it does, that is, it does some setup:

203 \def\extrasspanish{%
204   \textspanish
205   \mathspanish
206   \ifx\shorthandsspanish\@empty
207     \expandafter\spanishdeactivate\expandafter{\es@shlist}%
208     \languageshorthands{none}%
209   \else
210     \shorthandsspanish
211   \fi}

The definition of \textspanish is made step by step, so it's not readily available. My opinion is that this should be an internal command (so with a different name), because it does nothing really useful at the user level (and it's not documented, by the way). But it would be quite complicated (and not portable across documents without also copying the patches), changing spanish.ldf macros so that they use a different name.

Conversely, polyglossia uses a consistent interface: for every language <language> loaded, one has \text<language> that's an abbreviation for \foreignlanguage{<language>} plus some adaptations for it doing the right thing also in context of right-to-left languages.

8
  • Thanks, but I get Command \textspanish already defined. Or name \end... illegal, see p.192 of the manual. with pdfTeX 3.14159265-2.6-1.40.15 (TeX Live 2014). Does this really work with your pdfTex (which version)?
    – mb21
    Commented Oct 17, 2015 at 10:10
  • @mb21 I don't get the error.
    – egreg
    Commented Oct 17, 2015 at 10:18
  • I tried with pdflatex in TeX Live 2013, 2014 and 2015 and there's no \textspanish command defined if loading babel. Of course you have a wrong setting of babel, having language options both local and global.
    – egreg
    Commented Oct 17, 2015 at 10:25
  • Really? That's odd. Actually my version is MacTeX-2014, so maybe that makes a difference. But this Babel 2009 manual even mentions \textspanish..?
    – mb21
    Commented Oct 17, 2015 at 10:29
  • @mb21 Very curious. I'm investigating. Anyway, there's little hope of being able to use \textspanish as you want.
    – egreg
    Commented Oct 17, 2015 at 10:37
2

The main problem is that \textspanish is used in the language switching commands. so you can try something like this:

\documentclass[english,]{article}
\usepackage{lmodern}
\usepackage{ifxetex,ifluatex,xpatch}
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex\
  \usepackage[shorthands=off,spanish,english]{babel}
  \let\oritextspanish\textspanish
  \patchcmd\extrasspanish{\textspanish}{\oritextspanish}{}{}
  \patchcmd\noextrasspanish{\textspanish}{\oritextspanish}{}{}
  \renewcommand{\textspanish}[2][]{\foreignlanguage{spanish}{#2}}
\else
  \usepackage{polyglossia}
  \setmainlanguage[]{english}
  \setotherlanguage[]{spanish}
\fi
\begin{document}

Hello \textspanish{Hola}

\end{document}
6
  • Wow, works nicely thanks! Do I read this correctly that you are 1) saving the original \textspanish as \oritextspanish 2) path the babel-spanish commands to use \oritextspanish instead of \textspanish?
    – mb21
    Commented Oct 17, 2015 at 13:00
  • Yes, but be aware that I didn't made really thorough tests. Also I agree with egreg that the name in babel-spanish is not good. You should inform the author. Commented Oct 17, 2015 at 13:06
  • @UlrikeFischer There are so many unfortunate macro names out there... This name backs to 1997 and for almost 20 years there has been very little trouble with it. I think it's too late to change it, and with the new babel I'm working on many of those pitfalls will vanish (hopefully). Commented Oct 17, 2015 at 13:18
  • There is also \notextspanish to keep in mind. And this is what I called "non portable": you can't fetch some text to another document without also adding the patches in the preamble.
    – egreg
    Commented Oct 17, 2015 at 13:51
  • @egreg \notextspanish is simply defined as \bbl@nonfrenchspacing, so it shouldn't be affected by a redefinition of \textspanish. Also you always need preamble commands (definitions, \usepackage, tikz libraries, ...) before you can compile a snippet -- that's why we request complet document so often -- so I don't see why a few lines more line in the preamble suddenly count as "non portable". Commented Oct 17, 2015 at 14:02

You must log in to answer this question.

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