5

I need to use the \textvisiblespace character and the Mac Command splat (⌘) in code listings, with the lstlisting environment and with \lstinputlisting from an external file. I'm using the \cmd macro from the menukeys package to get the splat.

With the MWE below, it works in pdflatex but in XeLaTeX it ignores the literate= parameter of \lstset and tries to find both ⌘ and ␣ in the font.

What am I doing wrong?

\documentclass{article}
%%%%%%%%%%%%%%%%%%%%%%%%% either these two lines:
%\usepackage{fontspec}
%\usepackage{libertine} % or any other font
%%%%%%%%%%%%%%%%%%%%%%%%% or these two lines:
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{listings}
\usepackage{menukeys}
\lstset{extendedchars=true,
  literate={⌘}{{\cmd}}1{␣}{{\textvisiblespace}}1,
  showstringspaces=false,
  columns=fullflexible,
  keepspaces=true}
\lstloadlanguages{XML,[LaTeX]TeX}
\begin{document}
Here is a listing:
\begin{lstlisting}[language=TeX]
Mac␣users press ⌘-C
\end{lstlisting}
Here is a listing from a file:
\lstinputlisting{foobar.sh}
\end{document}

External file foobar.sh says:

Mac␣users press ⌘-C

In pdflatex, it gets the characters right but issues the error:

! Package tikz Error: Sorry, some package has redefined the meaning of the math
-mode dollar sign. This is incompatible with tikz and its calc library 
and might cause unrecoverable errors.

See the tikz package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.18 Mac␣users press ⌘
                          -C

In XeLaTeX (using the Libertine font) it misplaces the visible space (either to the left of the line in the environment version, or on the line above the code in the version input from the file), and it prints the "unknown character" (square with an X) for the splat. Using the plex-serif font package, I get a thick vertical line for both characters and the error message in the log file (repeated for the splat):

Missing character: There is no ␣ in font [IBMPlexSerif-Regular.otf]/OT:script=l
atn;language=DFLT;mapping=tex-text;mapping=tex-text;!

Omitting the font (ie using CM), I get a similar result to Libertine, but with no character at all for the splat.

  • I find listings a pain with non-ascii characters. Have a look at my answer here: tex.stackexchange.com/a/389822/87678 I can give a full answer that works if you need. – David Purton Jan 22 '18 at 12:54
  • Fortunately I am not trying to use CJK. It would be nice to work on a version of listings that handled whatever XeLaTeX handles, so that whatever you enabled for XeLaTeX would automatically work inside a listing. – Peter Flynn Jan 23 '18 at 22:01
6

You are asking two questions: How to use \cmd inside a listings, and how to use non-ascii chars with xelatex.

For the first you should locally reset the catcode of $. For the second you need to add the non-ascii chars to the parsing list of listings (see also The 'listings' package and UTF-8)

\documentclass{article}
%%%%%%%%%%%%%%%%%%%%%%%%% either these two lines:
%\usepackage{fontspec}
%\usepackage{libertine} % or any other font
%%%%%%%%%%%%%%%%%%%%%%%%% or these two lines:
%\usepackage[utf8]{inputenc}
%\usepackage[T1]{fontenc}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{listings}
\usepackage{menukeys}

\makeatletter %for xelatex:
\lst@InputCatcodes
\def\lst@DefEC{%
 \lst@CCECUse \lst@ProcessLetter
  ^^80^^81^^82^^83^^84^^85^^86^^87^^88^^89^^8a^^8b^^8c^^8d^^8e^^8f%
  ^^90^^91^^92^^93^^94^^95^^96^^97^^98^^99^^9a^^9b^^9c^^9d^^9e^^9f%
  ^^a0^^a1^^a2^^a3^^a4^^a5^^a6^^a7^^a8^^a9^^aa^^ab^^ac^^ad^^ae^^af%
  ^^b0^^b1^^b2^^b3^^b4^^b5^^b6^^b7^^b8^^b9^^ba^^bb^^bc^^bd^^be^^bf%
  ^^c0^^c1^^c2^^c3^^c4^^c5^^c6^^c7^^c8^^c9^^ca^^cb^^cc^^cd^^ce^^cf%
  ^^d0^^d1^^d2^^d3^^d4^^d5^^d6^^d7^^d8^^d9^^da^^db^^dc^^dd^^de^^df%
  ^^e0^^e1^^e2^^e3^^e4^^e5^^e6^^e7^^e8^^e9^^ea^^eb^^ec^^ed^^ee^^ef%
  ^^f0^^f1^^f2^^f3^^f4^^f5^^f6^^f7^^f8^^f9^^fa^^fb^^fc^^fd^^fe^^ff%
  ^^^^2318^^^^2423% for xelatex
  ^^00}
\lst@RestoreCatcodes
%\makeatother

\lstset{extendedchars=true,
  literate={⌘}{{\catcode`\$=3 \cmd}}1{␣}{{\textvisiblespace}}1,
  showstringspaces=false,
  columns=fullflexible,
  keepspaces=true}
\lstloadlanguages{XML,[LaTeX]TeX}
\begin{document}
Here is a listing:
\begin{lstlisting}[language=TeX]
Mac␣users press ⌘-C
\end{lstlisting}

Here is a listing from a file:
%\lstinputlisting{foobar.sh}
\end{document}

enter image description here

  • That is wonderful, thanks. I'm not clear why using \cmd needs the catcode of $ resetting, as it works on its own in XeLaTeX anyway; what you are adding as "non-ASCII" is in fact the codepoints, is that correct (like &#x2318; or &#x2423;) rather than the bytes which make up the UTF-8 representation? – Peter Flynn Jan 23 '18 at 22:06
  • Xelatex is not an 8-bit engine, it doesn't read byte wise. And you are inside a listing which does a lot of catcode magic. – Ulrike Fischer Jan 23 '18 at 23:43

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.