[Tex/LaTex] XeLaTeX French guillemets non-breaking space best practice

babelcsquotesfontspecpdftexxetex

What is the best approach to get a non-breaking space just before the closing French guillemet » ?

I wish to be able to type in the natural style, which in French is « bonjour » with non-breaking spaces before » and after «. It would be great if the code were clever enough to forgive my occasional use of the English-style «bonjour» and add the forgotten space for me. Now I get this:

enter image description here

I am using the babel package with the [french] option. I am also using the csquotes package with the [babel] option. I have also included the xspace package in the belief/hope that it would help with the spaces. I am not committed to these packages or options, although I believe they are common. I am open to using the panglossia package, which is also quite popular to typeset foreign languages, if that would help. For this particular project, I am committed to using XeLaTeX, but the problem also exists when I compile with PDFLaTeX. I am compiling a French text with UTF-8 encoding enabled. Is there anything I am overlooking here? Do I need to redefine guillemets commands? I have seen several ways to do this, but as they did not seem to work I am leaving them out of my MWE so as not to have misleading, deprecated code around.

% !TeX TXS-program:compile = txs:///xelatex/[--shell-escape]
\documentclass[12pt]{article}
\usepackage[paperwidth=14cm,paperheight=20.5cm]{geometry}
\usepackage{libertine}% use this font and geometry width to reproduce bad break
\usepackage{ifxetex}
\ifxetex
  \usepackage{fontspec}
  \defaultfontfeatures{Ligatures={TeX}}
\else
  \usepackage[utf8]{inputenc}
  \usepackage[T1]{fontenc}
  \usepackage{lmodern} 
\fi
\usepackage[french]{babel}
\usepackage{xspace}
\usepackage[babel,french=guillemets]{csquotes}

\begin{document}

Je n'ai rien à dire --- mais je le dis bien : je suis un « beau parleur ».

Je n'ai rien à dire -- mais je le dis bien: je suis un «beau parleur».

Je n'ai rien à dire :  je suis un «  beau parleur  » .

Je n'ai rien à dire:je suis un «beau parleur» .

\end{document}

Edit I have been explicit about the requirement that I use the guillemets directly and not a shortcut like \fg or \og. This is because I co-write with someone who will be typing in a standard text processor (and I will be copy-pasting their text back and forth several times).

Best Answer

For babel, you have to use \frenchbsetup{og=«, fg=»}. For polyglossia, you have nothing to do, except that the package inserts a breakable space (bug?), so in case the space does break, you have to insert an unbreakable thin space by hand (\,).

% !TeX TXS-program:compile = txs:///xelatex/[--shell-escape]
\documentclass[12pt]{article}
\usepackage[paperwidth=14cm,paperheight=20.5cm]{geometry}
\usepackage{libertine}% use this font and geometry width to reproduce bad break
\usepackage{ifxetex}
\ifxetex
  \usepackage{fontspec}
  \defaultfontfeatures{Ligatures={TeX}}
\usepackage{polyglossia}
\setmainlanguage{french}
\else
  \usepackage[utf8]{inputenc}
  \usepackage[T1]{fontenc}
  \usepackage{lmodern}
\usepackage[french]{babel}
\frenchbsetup{og=«, fg=»}
\fi
\usepackage[french=guillemets]{csquotes}
\usepackage{xspace}

\begin{document}

Je n'ai rien à dire -- mais je le dis bien : je suis un «\,beau parleur ».

Je n'ai rien à dire -- mais je le dis bien: je suis un «beau parleur».

Je n'ai rien à dire : je suis un « beau parleur » .

Je n'ai rien à dire: je suis un «beau parleur» .

\end{document}

enter image description here

Related Question