1

shortvrb's \MakeShortVerb allows defining single active tokens, e.g. |, in a way that makes |\foo| equivalent to \verb|\foo|. To do this, | is defined to expand to \verb| and added to both \dospecials and \@sanitize. Internally, \MakeShortVerb\| expands to \def\@shortvrbdef{\verb}\@MakeShortVerb\| and \@shortvrbdef is later used to set the expansion of |.

I want to use the same mechanism but with minted. In order to use the minted macro \code (as defined in the MWE below) insead of \verb, I defined

\def\MakeShortCode{\def\@shortvrbdef{\code}\@MakeShortVerb}

However, I get the error

! Paragraph ended before \minted@inline@ii was complete.

when using the shorthand. If I manually define

\def|{\code|}

the shorthand works fine. Inspection of the definition of | in both cases shows that they are indeed identical, so the only difference should be the registration of | in \dospecials and \@sanitize.

Why exactly does this error occur? How can I get around this without braking e.g. the verbatim environment? Is this a bug in minted or is there a good reason for this behavior?


\documentclass{article}

\usepackage{xparse}
\usepackage{minted}
\usepackage{shortvrb}

\newmintinline[code]{latex}{}

\makeatletter
  \def\MakeShortCode{\def\@shortvrbdef{\code}\@MakeShortVerb}
  \def\MakeShortLstinline{\def\@shortvrbdef{\lstinline}\@MakeShortVerb}
\makeatother

\ExplSyntaxOn
  \NewDocumentCommand\decompose{ m }
    {
      {
        \ttfamily
        \tl_analysis_map_inline:Nn #1 
          {
            \exp_last_unbraced:No \token_to_str:N { ##1 }
            \ensuremath { \sb {##3} }
          }
      }
    }
\ExplSyntaxOff

\begin{document}

\catcode`\|=\active

\def|{\code|}
|\foo|

\decompose|

\MakeShortCode\|
%|\foo| % This will cause an error.

\decompose|

\end{document}
0

2 Answers 2

2

Not sure why trying to overcomplicate things:

\documentclass{article}

\usepackage{minted}

\newmintinline[code]{latex}{}

\catcode`\|=\active
\makeatletter
\protected\def|{%
  \ifmmode
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\string|}{\code|}%
}
\makeatother

\begin{document}

|\foo|

$|a+b|$

\end{document}

enter image description here

A more complicated version that allows to locally remove a shorthand.

\documentclass{article}

\usepackage{minted}

\newmintinline[code]{latex}{}

\makeatletter
\newcommand{\makemintedshorthand}[1]{%
  \expandafter\chardef\csname catcode#1\endcsname=\catcode`#1
  \begingroup\lccode`~=`#1\lowercase{\endgroup
    \protected\def~{%
      \ifmmode
        \expandafter\@secondoftwo
      \else
        \expandafter\@firstoftwo
      \fi
      {\code~}{#1}%
  }}%
  \catcode`#1=\active
}
\newcommand{\removemintedshorthand}[1]{%
  \ifcsname catcode\string#1\endcsname
    \catcode`#1=\csname catcode\string#1\endcsname
  \fi
}
\makeatother

\makemintedshorthand{|}

\begin{document}

|\foo|

$|a+b|$

\begingroup
\removemintedshorthand{|}
\code$abc|def$ \code|abc$def|

\verb|xyz| \verb"a|b"
\endgroup

|\foo|

\end{document}

enter image description here

7
  • Because then | will break \verb and verbatim. By proxy, this also breaks minted. Try \code{The character | now breaks things.} or just \verb!|!.
    – schtandard
    Feb 24, 2020 at 10:13
  • @schtandard That's the reason why such shorthands are not really recommended. On the other hand, if you do \MakeShortVerb|, you can't use | inside |...| can you?
    – egreg
    Feb 24, 2020 at 10:18
  • Well, no, but you can still use it inside \verb and verbatim. (And one can define a second shorthand to use for these cases and reduce the situation one has to type \verb even further, which is what l3doc does. For me, it's okay to type \verb in those few cases, though.)
    – schtandard
    Feb 24, 2020 at 11:03
  • After thinking on it for a bit: Could you elaborate on why "such shorthands are not really recomended"? Are you saying that active characters in general are not recommended? If not, what makes using them for shorthands like this worse than other applications?
    – schtandard
    Feb 25, 2020 at 8:43
  • @schtandard Do you really think that |\foo| is clearer in the source than \code|\foo|?
    – egreg
    Feb 25, 2020 at 8:49
0

The problem is that when \code|\foo| is executed, TeX only scans for the second | after \dospecials changed its category code to 12. \@MakeShortVerb defines |13 to expand to \code0|13 (the indices denote category codes), so |\foo| effectively expands to \code0|13\foo0|12, which can't work.

We can fix this by modifying \MakeShortCode to define |13 as \code0|12.

\documentclass{article}

\usepackage{etoolbox}
\usepackage{minted}
\usepackage{shortvrb}

\newmintinline[code]{latex}{}

\makeatletter
  \def\MakeShortCode{\def\@shortvrbdef{\code}\@MakeShortCode}
  \let\@MakeShortCode\@MakeShortVerb
  \patchcmd\@MakeShortCode
    {\expandafter\gdef\expandafter~\expandafter{\@shortvrbdef~}}
    {\xdef~{\expandafter\noexpand\@shortvrbdef\expandafter\@gobble\string#1}}
    {}{}
\makeatother

\MakeShortCode\|

\begin{document}\makeatletter

|\foo{bar} baz|

\begin{minted}{latex}
  I wrote |\foo{bar} baz|.
\end{minted}

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .