9

My usual goto for writing pseudocode is the listings package, but unfortunately, I find myself writing a document in my native language (portuguese) and I need to write UTF-8 characters in pseudocode, and listings is not playing along.

Furthermore, I also need to use mathmode.

The code I'm trying to do in specific is this:

\begin{lstlisting}[mathescape=true]
Para todo $B \subseteq N$:
  Se as colunas de $A_B$ são linearmente independentes:
    Resolver o sistema $A_B x = b$.
    Se este tiver solução $x$:
      Se $x \geq 0$:
        Definir $v \in \mathbb R^n$ de modo a que $v_B = x$ e $v_{N\setminus B} = 0$
        Adicionar $v$ à lista de vértices.
\end{lstlisting}

This particular bit of code doesn't work, as I get the following error:

! Package inputenc Error: Unicode char �\expandafter (U+4F1)
(inputenc)                not set up for use with LaTeX.

(Though I do need inputenc to typeset UTF-8 characters, and as far as I can tell, it's a listings problem.)

The specific package does not matter, I'm just looking for a way to typeset pseudocode in my native language while still being able to use mathmode.

This also rules out fancyvrb and alltt, as those didn't play along with sub and superscripts.

TIA

11

You should compile the code with XeLaTeX. It works well with this type of coding.

enter image description here

\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[portuguese]{babel}
\usepackage{amsmath,amssymb}
\usepackage{listings}
\begin{document}
Português para principiantes with formula
\[A(\lambda)=\cos \lambda + \sin \lambda\]

\begin{lstlisting}[mathescape=true]
Para todo $B \subseteq N$:
  Se as colunas de $A_B$ são linearmente independentes:
    Resolver o sistema $A_B x = b$.
    Se este tiver solução $x$:
      Se $x \geq 0$:
        Definir $v \in \mathbb R^n$ de modo a que $v_B = x$ e $v_{N\setminus B} = 0$
        Adicionar $v$ à lista de vértices.
\end{lstlisting}

\end{document}
  • This is not what I want. I already have UTF-8 working fine in my document, I am just looking for a pseudocode environment that also allows it. – Robly18 Aug 11 '18 at 20:14
  • 1
    @Robly18 I have tried to understand your question. You haven't entered any code inside so we can all understand it better. – Sebastiano Aug 11 '18 at 20:20
  • Okay, I added a code snippet in response. Thank you for the feedback. As for the suggested code, it might work, but I'd like some more flexibility with the keywords. For example, I'd like to write "se" instead of "if". – Robly18 Aug 11 '18 at 20:25
  • @Robly18 Was that what you expected? You are a new user: sorry I didn't welcome you on TeX.SE. – Sebastiano Aug 11 '18 at 20:31
  • 1
    Okay, yeah, that works perfectly. I was hoping for a more portable solution, but if I can't find anything better, this is good. Thanks a lot! – Robly18 Aug 11 '18 at 20:34
12

Sebastiano's answer works well with UTF-8 based engines. To use with pdfLaTeX you can use \lstset{literate=...}:

\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[portuguese]{babel}
\usepackage{amsmath,amssymb}
\usepackage{listings}

\newcommand{\R}{\mathbb R}

% taken from: https://tex.stackexchange.com/a/381647/134574
\lstset{
  keepspaces, % Apparently this works... (https://tex.stackexchange.com/a/46695/134574)
  literate=
  {á}{{\'a}}1
  {à}{{\`a}}1
  {ã}{{\~a}}1
  {é}{{\'e}}1
  {ê}{{\^e}}1
  {í}{{\'i}}1
  {ó}{{\'o}}1
  {õ}{{\~o}}1
  {ú}{{\'u}}1
  {ü}{{\"u}}1
  {ç}{{\c{c}}}1
}

\begin{document}

\begin{lstlisting}[mathescape=true]
Para todo $B \subseteq N$:
  Se as colunas de $A_B$ são linearmente independentes:
    Resolver o sistema $A_B x = b$.
    Se este tiver solução $x$:
      Se $x \geq 0$:
        Definir $v \in \R^n$ de modo a que $v_B = x$ e $v_{N\setminus B} = 0$
        Adicionar $v$ à lista de vértices.
\end{lstlisting}

\end{document}

About the spacing issue pointed out in the comments. It looks like there's a bug in listings which, after mathescaped text, the space after literated text disappears. I asked a question about this issue and Ulrich Diez apparently fired out what the problem was.

To fix the problem, add the following definition to your file:

\makeatletter
\def\lst@Literate#1#2#3{%
    \ifx\relax#2\@empty\else
        \lst@CArgX #1\relax\lst@CDef
            {}
            {\let\lst@next\@empty
             \lst@ifxliterate
                \lst@ifmode \let\lst@next\lst@CArgEmpty \fi
             \fi
             \ifx\lst@next\@empty
                 \ifx\lst@OutputBox\@gobble\else
                   \lst@XPrintToken \let\lst@scanmode\lst@scan@m
                   \lst@token{#2}\lst@length#3\relax
                   \lst@XPrintToken
                   % ↓ Missing switch added by Ulrich Diez to fix the spacing issue
                   \lst@whitespacefalse %!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                 \fi
                 \let\lst@next\lst@CArgEmptyGobble
             \fi
             \lst@next}%
            \@empty
        \expandafter\lst@Literate
    \fi}
\makeatother

or, more compactly:

\usepackage{etoolbox}
\makeatletter
\patchcmd\lst@Literate
  {\lst@XPrintToken\fi}
  {\lst@XPrintToken\lst@whitespacefalse\fi}
  {}{}
  • Thank you very much for quoting my name. Obviously the best must be given what Caesar is to Caesar. +1. – Sebastiano Aug 11 '18 at 20:34
  • This solution is more portable, but there is a small problem. It's messing up some of the spacing. To see an example, see: i.imgur.com/92Fk3Tg.png Namely, notice the spacing between 'à' and 'lista'. It can be fixed by adding an extra space between the two characters, however. – Robly18 Aug 11 '18 at 20:40
  • @Robly18 Strange indeed. Note that if you write à lista à lista (duplicated), the second à lista is printed correctly. I think it's a bug... But using the keepspaces option apparently solves the problem temporarily. – Phelype Oleinik Aug 11 '18 at 21:02
  • @Robly18 Actually, the problem because of the $v$. If you write Adicionar v à lista $v$ à lista, the second space disappears. – Phelype Oleinik Aug 11 '18 at 21:09
  • You're right. I added the option keepspaces. Thank you! – Robly18 Aug 11 '18 at 21:19
11

Heiko Oberdiek's listingsutf8-package offers a workaround to the problem:

It enhances the syntax of the \lstinputlisting-command so that it can read files that are encoded in utf8 and internally re-encode them in some 8bit-encoding before "feeding" to the internals of the listings package.

In case the latin-1-encoding (ISO8859-1), which is an 8bit-encoding, can encode all characters needed in your pseudocode, you can probably use the filecontents*-environment from the filecontents-package for writing an utf8-encoded temporary file, and then use the \lstinputlisting-command which is enhanced by the listingsutf8-package for reading that utf8-file and internally re-encoding it in latin-1 before feeding it to the internals of the listings-package.

Instead of latin-1, as in the example below, you can use other 8bit-encodings in case they do better suit your needs.

In any case using the listingsutf8-package requires ε-TeX-extensions and the \pdffiledump-primitive from pdfTeX. In other words: No matter if run in .dvi-mode or run in .pdf-mode, you need some pdfLaTeX-engine with ε-TeX-extensions.

\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[portuguese]{babel}
\usepackage{amsmath,amssymb}
\usepackage{listings}
\usepackage{listingsutf8}
\usepackage{filecontents}


\begin{document}

\begin{filecontents*}{tempfile.tex}
Para todo $B \subseteq N$:
  Se as colunas de $A_B$ são linearmente independentes:
    Resolver o sistema $A_B x = b$.
    Se este tiver solução $x$:
      Se $x \geq 0$:
        Definir $v \in \mathbb R^n$ de modo a que $v_B = x$ e $v_{N\setminus B} = 0$
        Adicionar $v$ à lista de vértices.
\end{filecontents*}
\lstinputlisting[mathescape=true, inputencoding=utf8/latin1]{tempfile.tex}

\end{document}

enter image description here

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.