5

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 at 16:59
  • Did you see tex.stackexchange.com/a/15374/4427 ? – egreg Nov 17 at 0:17
  • I hadn't, thanks for sharing. – noibe Nov 17 at 11:53
11

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 at 12:43
  • 2
    @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 at 13:18
  • Thanks! I would upvote twice if I could. – noibe Nov 16 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 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 at 15:13
6

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".

enter image description here

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:
\AtBeginDocument{\directlua{luatexbase.add_to_callback( 
   "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.

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.