\ProvidesFile{lstpseudocode.sty}
    [2019/03/25 1.1 listings pseudocode language file]
% Author: Nelson Lago
% Licence: LPPL 1.3 or later

% The pseudocode "language":
%
%   * Comments follow the C++ style (// and /* ... */).
%
%   * Comment delimiters are printed as a small triangle.
%
%   * ":=", "<>", "<=", ">=", "!=" are substituted for the
%     appropriate mathematical symbol.
%
%   * You may add keywords beyond the obvious "if", "and" etc.
%     with either the "morekeywords={keyword1,keyword2}" option
%     or with "\lstset{morekeywords={keyword1,keyword2}}".
%
%   * "$...$" activates math mode anywhere
%
%   * Other LaTeX commands work only inside comments; out of them, the
%     language simulates some predefined ones (\textit{}, \texttt{}...)
%
%   * \label{} works within comments and the corresponding reference
%     points to the line number. To use it without a visible comment,
%     use "///"; it works similarly to "//" but does not print the
%     comment indicator (the small triangle).
%
%   * To prevent automatic formatting, use \noparse{blah}.
%
%   * To force some text to be formatted as function, identifier, keyword
%     or comment, use \func{blah}, \id{blah}, \kw{blah} or \comment{blah}.
%
%   * Keywords inside comments are *not* automatically formatted; if that
%     is needed, use \func{}, \id{} etc. or standard LaTeX commands.
%
%   * The keywords "Program", "Procedure" and "Function" have special
%     formatting and make the next word to be formatted as a function.
%     Functions in other places are *not* automatically detected;
%     use \func{}, the "functions={func1,func2}" option or
%     "\lstset{functions={func1,func2}}" to make them be.
%
%   * Besides functions, keywords, strings, comments, and identifiers,
%     there are "specialidentifiers". You may use them with
%     \specialid{blah}, with the "specialidentifiers={id1,id2}" option,
%     or with "\lstset{specialidentifiers={id1,id2}}".

%%%%%%%%%% ASPECTS %%%%%%%%

% I am not sure whether it makes sense to keep these in different
% aspects or whether they should all be part of a single one.

\lst@BeginAspect{simulatex}
  \lst@Key{simulatex}\relax[true]{
    \lstKV@SetIf{#1}{\lst@ifsimulatex}

    \lst@ifsimulatex
      \lstset{
        moredelim=**[is][\normalfont]{\\textnormal\{}{\}},
        moredelim=**[is][\itshape]{\\textit\{}{\}},
        moredelim=**[is][\scshape]{\\textsc\{}{\}},
        moredelim=**[is][\slshape]{\\textsl\{}{\}},
        moredelim=**[is][\upshape]{\\textup\{}{\}},
        moredelim=**[is][\bfseries]{\\textbf\{}{\}},
        moredelim=**[is][\mdseries]{\\textmd\{}{\}},
        moredelim=**[is][\rmfamily]{\\textrm\{}{\}},
        moredelim=**[is][\sffamily]{\\textsf\{}{\}},
        moredelim=**[is][\ttfamily]{\\texttt\{}{\}},
        moredelim=**[is][\em]{\\emph\{}{\}},
      }
    \fi

  }
\lst@EndAspect

% "excludedelims" makes the chosen delimiters (comments, strings, or
% tags) to not be formatted in the same style as whatever they delimit.
% This aspect creates the "invisibledelims" option that makes them
% invisible instead (by patching the default macros). Note that this
% only affects the delimiters indicated by excludedelims.
\lst@BeginAspect{invisibledelims}
  \lst@Key{invisibledelims}\relax[true]{
    \lstKV@SetIf{#1}{\lst@ifinvisibledelims}

    \lst@ifinvisibledelims
      \def\lst@DelimOpen##1##2##3##4##5##6\@empty{%
        \lst@TrackNewLines \lst@XPrintToken
        \lst@EnterMode{##4}{\def\lst@currstyle##5}%
        \lst@DelimPrint{##1##2}{##6}%
        ##3}

      \def\lst@DelimClose##1##2##3\@empty{%
        \lst@TrackNewLines \lst@XPrintToken
        \lst@DelimPrint{##1##2}{##3}%
        \lst@LeaveMode}
    \fi

  }
\lst@EndAspect

\lst@BeginAspect[emph,procnames,comments,style,keywords,invisibledelims]{pseudocode}

  % Use emph[10] and emphstyle[10] to automatically identify and format
  % the given function names with the same formatting as procnamestyle
  \lst@Key{functions}\relax{
    \lstset{emph={[10]#1}}
    \lstset{emphstyle={[10]\lst@procnamestyle}}
  }

  % Use keywords[10] and keywordstyle[10] to format the keywords in
  % procnamekeys with a specific format. It is not so great to do
  % "keywords={[10]...} here (this should be done in the marco that
  % handles the "keywords" key), but it works.
  \lst@Key{procnamekeystyle}\relax{
    % Trick to force \lst@procnamekeys to be expanded before \lstset
    \edef\@tempa{\noexpand\lstset{keywords={[10]\lst@procnamekeys}}}\@tempa
    \lstset{keywordstyle={[10]#1}}
  }

  % Just a more friendly name for "emph[11] / emphstyle[11]".
  \lst@Key{specialidentifiers}\relax{\lstset{emph={[11]#1}}}
  \lst@Key{specialidentifierstyle}\relax{\lstset{emphstyle={[11]#1}}}

  % Use with excludedelims=comments to typeset a triangle as
  % the comment indicator character. Notice the use of global
  % in only some of the boolean commands: AtBeginComment is
  % set globally, so we need to the boolean to always exist and,
  % therefore, we define it globally. BUT we set its *local*
  % value to determine whether to typeset the triangle or not.
  \global\let\lst@ifTriangleComments\iffalse

  \lst@AddToHook{AfterBeginComment}{\lst@ifTriangleComments{\hspace*{0.5em}\ensuremath{\triangleright}}\fi}

  \lst@Key{trianglecomments}\relax[true]{
    \lstKV@SetIf{#1}{\lst@ifTriangleComments}

    \lst@ifTriangleComments
      \lstset{invisibledelims}
    \fi

  }

  \lst@Key{manualclassification}\relax[true]{
    \lstKV@SetIf{#1}{\lst@ifmanualclassification}

    \lst@ifmanualclassification
      % Make it possible to manually set specific formatting
      \lstset{
        moredelim=**[is][identifierstyle]{\\id\{}{\}},
        moredelim=**[is][commentstyle]{\\comment\{}{\}},
        moredelim=**[is][keywordstyle]{\\kw\{}{\}},
        moredelim=**[is][procnamestyle]{\\func\{}{\}},
        moredelim=**[is][emphstyle11]{\\specialid\{}{\}},
        moredelim=[is][]{\\noparse\{}{\}},
      }
      % Make the same commands available to LaTeX so that
      % they may be used in comments with the "texcl" option.
      % These definitions are local, so they only work within
      % the listing itself.
      \def\id##1{\lst@identifierstyle##1}
      \def\comment##1{\lst@commentstyle##1}
      \def\kw##1{\lst@keywordstyle##1}
      \def\func##1{\lst@procnamestyle##1}
      \def\specialid##1{\csname lst@emphstyle11\endcsname##1}
    \fi

  }

\lst@EndAspect

%%%%%% LANGUAGE %%%%%%

\lst@definelanguage[brazilian]{pseudocode}[base]{pseudocode}{
  keywords={
    faca, feito, cancele, continue,
    inicio, fim,
    escolhe, caso,
    para, de, ate,
    laco, enquanto, repita, vapara,
    se, entao, senao,
    e, ou, oux, nao,
    verdadeiro, falso, estrutura, conjunto,
    devolva,
  },
  procnamekeys={programa,rotina,funcao},
}

\lst@definelanguage[english]{pseudocode}[base]{pseudocode}{
  keywords={
    do, done, break, continue,
    begin, end,
    switch, case,
    for, from, to,
    loop, while, repeat, until, goto,
    if, then, else,
    and, or, xor, not,
    true, false, struct, set,
    return,
  },
  procnamekeys={program,procedure,function},
}

\lst@definelanguage[base]{pseudocode}{
  mathescape=true,
  sensitive=false,
  texcl=true,
  %escapechar=\&,
  simulatex,
  excludedelims={comments,strings},
  invisibledelims,
  manualclassification,
  trianglecomments,
  morestring=[b]{'},
  morestring=[b]{"},
  morecomment=[s]{/*}{*/},
  morecomment=[l]{//},
  escapeinside={///}{\^^M},
  literate=
  % This is what we want to add here
  {:=}{{$\,\gets\,$}}2
  {<=}{{$\,\leq\,$}}2
  {>=}{{$\,\geq\,$}}2
  {<>}{{$\,\neq\,$}}2
  {!=}{{$\,\neq\,$}}2
  % These are accented characters; we have defined them
  % elsewhere but "literate" resets everything, so we
  % repeat these definitions here.
  {á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1
  {Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1
  {à}{{\`a}}1 {è}{{\`e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1
  {À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1
  {ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1
  {Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1
  {â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1
  {Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1
  {Ã}{{\~A}}1 {ã}{{\~a}}1 {Õ}{{\~O}}1 {õ}{{\~o}}1
  {œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1
  {ű}{{\H{u}}}1 {Ű}{{\H{U}}}1 {ő}{{\H{o}}}1 {Ő}{{\H{O}}}1
  {ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1
  {€}{{\euro}}1 {£}{{\pounds}}1 {«}{{\guillemotleft}}1
  {»}{{\guillemotright}}1 {ñ}{{\~n}}1 {Ñ}{{\~N}}1 {¿}{{?`}}1,
}[keywords,comments,strings,procnames,simulatex,invisibledelims,pseudocode]
