# Using characters to delimit commands (like markdown)

I recently came accross the \DefineShortVerb command of the fancyvrb package, which lets you "define a special character as an abbreviation to enclose verbatim text", so for example:

\documentclass{article}
\usepackage{fancyvrb}
\DefineShortVerb{\|}
\begin{document}
|this is verbatim|
\end{document}


I was wondering if and how this could be done for any other character and any other command. For example, say I wanted the text enclosed by the character  to be displayed in italic:

\documentclass{article}
% some code
\begin{document}
this and \textit{this} should be the same.
\end{document}


how could I do this?

• This kind of markup is good for text with little typographic needs. I'd avoid it: with a good editor it's easy to set up “command-i” (or “control-i”) to insert \textit{} and place the cursor between the braces. – egreg Nov 16 '19 at 16:59
• Did you see tex.stackexchange.com/a/15374/4427 ? – egreg Nov 17 '19 at 0:17
• I hadn't, thanks for sharing. – noibe Nov 17 '19 at 11:53

The basic idea of \DefineShortVerb is that it makes the character in the argument active (\catcode#1=\active), so that the character behaves like a macro. Then it defines that character to be a verbatim command using the "lowercase trick". You can change that to define the character to a custom macro.

Here's a \DefineShortCommand<char>{<definition>} macro which defines the <char> to expand to <definition>. This eventually does something like \def<char>#1<char>{<definition>}, in which <char> is an active character token. In the <definition>, #1 is the argument, grabbed between the first and the next (brace-balanced) <char>.

\documentclass{article}
\def\DefineShortCommand#1{%
\catcode#1=\active
\begingroup
\lccode\~=#1
\lowercase{\endgroup
\def~##1~}}
\begin{document}

\DefineShortCommand\{\textit{#1}}
this and \textit{this} should be the same.

\end{document}


Take care not to activate "dangerous" characters and beware with possible conflicts with babel.

To use with Verbatim, the character  is especially painful because this character is reset by LaTeX's \@noligs to avoid that it forms ligatures in verbatim mode. fancyvrb uses \@noligs after the user's catcode settings, so anything you change to the character  is overridden. You need to remove it from the verbatim ligature list:

\documentclass{article}
\usepackage{fancyvrb}
\def\DefineShortCommand#1{%
\catcode#1=\active
\begingroup
\lccode\~=#1
\lowercase{\endgroup
\def~##1~}}
\begin{document}

\makeatletter
\def\verbatim@nolig@list{\do\<\do\>\do\,\do\'\do\-}
\def\backtickit{\DefineShortCommand\{\textit{##1}}}
\makeatother

\begin{Verbatim}[codes={\backtickit}]
x=1/sqrt(z**2) <- This is an equation
\end{Verbatim}

\end{document}


As Mico noted, when two  are used (like in should'') you usually don't want to apply the special formatting. To detect this case you can check that the argument of active- is empty and then use the original  character instead.

Suppose you have a \tlifempty{<token list>}{<empty>}{<not empty>} (shown below) conditional, then this could be accomplished with:

\DefineShortCommand\{%
\tlifempty{#1}
{\char96\char96\relax}
{\textit{#1}}}


(96 is the ASCII code for ).

To go an extra mile and allow the eventual usage of  (or other character that you happen to use with \DefineShortCommand) in an expansion-only context, you need to save the original meaning of  and then retrieve it later with an auxiliary macro.

In the code below, \DefineShortCommand saves the original meaning of the argument as (for example ) \the@char@96. Later you can retrieve it with \thechar{}. As an extra safety, the code does some normalisation so that both  or \ retrieve the same character:

\documentclass{article}
\makeatletter
\def\DefineShortCommand#1{%
\expandafter\edef\csname the@char@\number#1\endcsname
{\unless\if\@backslashchar\string#1%
\string#1\else\expandafter\@gobble\string#1\fi}%
\catcode#1=\active
\begingroup
\lccode\~=#1
\lowercase{\endgroup
\def~##1~}}
\def\thechar#1{\csname the@char@\number#1\endcsname}
% Checking if the argument is empty
\def\tlifempty#1{%
\if\relax\detokenize{#1}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
\makeatother
\begin{document}
\DefineShortCommand\{%
\tlifempty{#1}
{\thechar{}\thechar{\}}
{\textit{#1}}}

this and \textit{this} should'' be the same.
\end{document}

• I tried using it in a Verbatim environment, with the option [commandchars=\], but that just printed the  character. Is it possible to get that to work? – noibe Nov 16 '19 at 12:43
• @noibe The commandchar key takes three tokens as argument, not just one. These tokens are supposed to be replacements to \, {, and }, respectively. You could use, for instance, commandchars=|[]. But this wouldn't help you here. The appropriate key is codes (plus a few tweaks :-). See the edit – Phelype Oleinik Nov 16 '19 at 13:18
• Thanks! I would upvote twice if I could. – noibe Nov 16 '19 at 13:24
• How might your first solution be generalized to allow the continued use of "normal" (i.e., consecutive) double backticks, as in that''? – Mico Nov 16 '19 at 14:31
• @Mico With a bit more code, checking if the argument of the active- is empty. For the specific case of the backtick one could use some kind of lookahead with futurelet, but this would be more fragile (not that making  active is robust ;-), so I opted to generalise for any character and leave the emptyness check in the definition of . See the edit :-) – Phelype Oleinik Nov 16 '19 at 15:13

I want the text enclosed by [backtick] characters to be displayed in italic

Here's a LuaLaTeX-based solution. It doesn't require making the backtick character, , "active".

Observe that the "normal" use of double backticks, , as in that'', is not affected by the processing of material enclosed in pairs of single backticks.

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode}
%% Lua-side code:
\begin{luacode}

function backtick2textit ( s )
s = s:gsub ( "(.-)''" , "@@@@@%1@@@@@" ) -- save ...'' cases
s = s:gsub ( "(..-)", "\\textit{%1}" )   -- ignore consecutive backticks
s = s:gsub ( "@@@@@(.-)@@@@@" , "%1''" ) -- restore ...'' cases
return s
end

\end{luacode}
%% LaTeX-side code:
"process_input_buffer", backtick2textit ,
"backtick2textit" )}}

\begin{document}
\dots\ and this and that'' and why'' and who and \dots
\end{document}


Addendum to explain how the solution works:

• The Lua function backtick2textit is assigned to the process_input_buffer callback, which operates at a very early stage, i.e., before TeX performs its usual work of expanding macros, etc.

• The function backtick2textit employs the Lua function string.gsub (I believe that "gsub" stands for "global substitution") to perform its job.

• First, strings enclosed in double-backticks/double apostrophes (non-greedy matching) are set aside.

• A pattern match occurs if a backtick is encountered, followed by 1 or more arbitrary characters (non-greedy matching), followed by another backtick. If a match occurs, the material enclosed by the backticks is encased in a \textit` directive.

• Finally, the material to rendered in double-quote marks is restored.

• The Lua function will not perform correctly if you use both single and double quote characters to quote material. The code posted above doesn't guard against this eventuality as I assume that you mentioned the use of backtick characters just as an example.