1

My Memoir section titles contain French accented characters and some suit symbols (e.g. \Ts). The former can be used directly in PDF bookmarks but I haven't found any reliable way of replacing the suit symbols. That's not really an issue, it's fine to approximate e.g. the club suit with the letter "T" (for Trèfles) and I've written a Bsection function in Lua to generate an acceptable \texorpdfstring function. For example,

\Bsection{Réponses à l'ouverture de 1|Ts : Le traitement Walsh} 

returns the string

\texorpdfstring{Réponses à l'ouverture de 1\Ts : Le traitement Walsh}{Réponses à l'ouverture de 1T : Le traitement Walsh}

So no real problem here (a minor irritation is using the input |Ts instead of the correct \Ts because I haven't been able to change the catcode of "\").

What I'd like to do is take the input string "Réponses à l'ouverture de 1|Ts : Le traitement Walsh" and "clean" it so that no characters unacceptable to texorpdfstring are written back. So I can't naively parse on [a-z] because, unless I set the locale first, that will strip the French accented characters too. What's the right way to do this and what's a simple workaround? Is os.setlocale relevant?

MWE:

\documentclass[a4paper, 11pt, twoside, onecolumn, dvipsnames, final]{memoir}%

\RequirePackage[scale=0.8]{fdsymbol}%

\RequirePackage[T1]{fontenc}%
\RequirePackage{fontspec}%

\RequirePackage{unicode-math}%
\setmainfont[Numbers={OldStyle,Proportional},Ligatures=TeX,Scale=MatchLowercase,Renderer=Basic]{Minion Pro}%
\newfontfamily\MinionProportional[Ligatures=TeX, Ligatures=Common,Numbers=Monospaced]{Minion Pro}%
\setmathfont{Asana Math}%

\newcommand{\Ts}{\ensuremath{\clubsuit}}%

\usepackage{luacode} 

\RequirePackage[unicode=true,
psdextra,
colorlinks=true,  
citecolor=DarkBlue,       
filecolor=DarkBlue,  
linkcolor=DarkBlue,  
urlcolor=DarkBlue,
hyperfootnotes=false,
linktoc=all]{hyperref}%

\directlua{require "lualoader"%
assert(loadfile("TeXmacros.lua"))("French")%
}%

\DeclareRobustCommand{\Bsection}[1]{\directlua{Bsection([[#1]])}}%

\begin{document} 

\chapter{Chapter the first}

\section{\Bsection{Réponses à l'ouverture de 1|Ts : Le traitement Walsh}}

\end{document} 

Lua function (which wrongly strips out accented chars):

function Bsection(s)
    local t=""
    -- Take a clean copy of the input section title.
    t = string.gsub(s, "[\192-\255][\128-\191]*", "")

    -- Write a text only version of this string for the PDF bookmark.
    t = string.gsub(t, "|Ts", "T")

    -- Write Tex macro version of this string for the Memoir section.
    s = string.gsub(s, "|Ts", "\\Ts")

    -- Write the section back to LuaLaTeX.
    t = "\\texorpdfstring{" .. s .. "}{" .. t .. "}"
    tex.sprint(t)
    return t
end
  • 2
    don't to \RequirePackage[T1]{fontenc}% with luatex (fortunately here you load fontspec afterwardwards not before so this does nothing in this case) what is the intention of t = string.gsub(s, "[\192-\255][\128-\191]*", "" if not to remove non-ascii characters? – David Carlisle Jul 5 '18 at 6:42
  • Yes, it's obviously wrong. What I'm trying to ask is what range would keep French accents, but strip most/all characters that texorpdfstring would object to. – DLyons Jul 5 '18 at 7:11
  • You may need to strip unexpandable tex commands but all unicode character data may go in a pdfstring (they may not all display depending on the system font used) but certainly all european accents will work) – David Carlisle Jul 5 '18 at 8:51
  • Thanks David. That makes sense and indeed I'm currently using ^^^^2660 etc. – DLyons Jul 5 '18 at 9:00
  • or just using ♠ directly is simpler (depending on input methods used) – David Carlisle Jul 5 '18 at 9:07
2

The easiest solution to the problem doesn't need any Lua and gives an actual suit symbol instead of a T in the PDF outline:

\documentclass[a4paper, 11pt, twoside, onecolumn, dvipsnames, final]{memoir}%

\RequirePackage[scale=0.8]{fdsymbol}%

\RequirePackage{fontspec}%

\RequirePackage{unicode-math}%
% I am not rich enough for these fonts
% \setmainfont[Numbers={OldStyle,Proportional},Ligatures=TeX,Scale=MatchLowercase,Renderer=Basic]{Minion Pro}%
% \newfontfamily\MinionProportional[Ligatures=TeX, Ligatures=Common,Numbers=Monospaced]{Minion Pro}%
\setmathfont{Asana Math}%

\newcommand{\Ts}{\ensuremath{\clubsuit}}%

\usepackage{luacode} 

\RequirePackage[unicode=true,
psdextra,
colorlinks=true,  
citecolor=DarkBlue,       
filecolor=DarkBlue,  
linkcolor=DarkBlue,  
urlcolor=DarkBlue,
hyperfootnotes=false,
linktoc=all]{hyperref}%

\pdfstringdefDisableCommands{%
  \renewcommand\Ts{\Uchar"2663 }%
  % Inside PDF strings, \Ts is replaced by Unicode char U+2663 "BLACK CLUB SUIT"
}

\begin{document} 

\chapter{Chapter the first}

\section{Opening 1\Ts : The Walsh treatment}

\end{document} 
  • I didn't know about pdfstringdefDisableCommands! I could get the unicode 2663, 2665, 2666, 2660 to appear but it always led to something subsequently hanging. I always had to delete the .ptc file, etc etc. Will try your approach thanks, – DLyons Jul 5 '18 at 0:58
2

Using fontspec

This solution uses a text font rather than a math-mode symbol. These four symbols are present in a number of fonts, but one free, particularly comprehensive font family is the DejaVu fonts. It does not change any of your main fonts, but scales the symbol to whatever font you select.

\documentclass[varwidth, preview]{standalone}
\usepackage{fontspec}
\usepackage{polyglossia}

\setdefaultlanguage{french}

%% \setmainfont goes here.
\defaultfontfeatures{Scale=MatchUppercase}
\newfontfamily\symbolfamily{DejaVu Serif}

\DeclareRobustCommand\Ts{{\symbolfamily\char"2663}\relax}

\begin{document}

\textbf{Réponses à l'ouverture de 1\Ts : Le traitement Walsh} \\

\end{document}

੧ in DejaVu Serif

Here is a version that incorporates part of Marcel Kruger’s answer, to properly set up your PDF document outline in Hyperref:

\documentclass[varwidth, preview]{standalone}
\usepackage{fontspec}
\usepackage{polyglossia}
\usepackage[HTML, hyperref, svgnames]{xcolor}
\usepackage[ bookmarks, unicode, colorlinks, allcolors=DarkBlue
           ]{hyperref}

\setdefaultlanguage{french}

%% \setmainfont goes here.
\defaultfontfeatures{Scale=MatchUppercase}
\newfontfamily\symbolfamily{DejaVu Serif}

\DeclareRobustCommand\Ts{{\symbolfamily\char"2663}\relax}

\pdfstringdefDisableCommands{%
  \renewcommand\Ts{\Uchar"2663\relax}%
  % Inside PDF strings, \Ts is replaced by Unicode char U+2663 "BLACK CLUB SUIT"
}

\begin{document}

\section{Réponses à l'ouverture de 1\Ts : Le traitement Walsh}\label{sec:1}

\end{document}

Using Legacy Encodings

If you must use the older toolchain, the suit symbols are also available in the pifont package. You can look up the encoding in the psnfss documentation.

\documentclass[varwidth, preview]{standalone}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[utf8]{inputenc} % The default since 2018.
\usepackage[french]{babel}
\usepackage{pifont}

\DeclareRobustCommand\Ts{\ding{168}\relax}

\begin{document}

\textbf{Réponses à l'ouverture de 1\Ts : Le traitement Walsh} \\

\end{document}

Sample with pifont

The same hyperref code should still work with this.

  • That's potentially much simpler. I'll need a colour next \DeclareRobustCommand\Ks{{\color{red}\symbolfamily\char"2666}\relax} Now I'll have a problem with the bookmark but I can fix that with a texorpdfstring? – DLyons Jul 5 '18 at 4:47
  • @DLyons Yes, I believe Marcel Kruger’s solution to the outline headings will still work, as in my second example. – Davislor Jul 5 '18 at 5:09
  • Thanks for that Davislor. I've coloured the suits and it all works nicely. While you answer is fuller I'm going to accept Marcel's as having the key idea first. – DLyons Jul 6 '18 at 10:17
  • @DLyons That was a great answer, and I learned something from it too. Glad I could still help! – Davislor Jul 6 '18 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.