2

I'm trying to create a new command called \codeR:

\codeR{This will appear with a code format}

This might help me to avoid typing all the \begin{lstlisting}[language=R] and \end{lstlisting} commands everytime:

\usepackage{listings}

\begin{document}
\begin{lstlisting}[language=R]
     This will appear with a code format
\end{lstlisting}
\end{document}

I tried the following:

\newcommand{\codeR}[1]{
\begin{lstlisting}{language=R}
{#1}
\end{lstlisting}
}

But is not working. Might you help me please? Thank you.

  • Would a new environment also be OK? – user36296 Aug 21 '18 at 17:15
  • Don't you want [language=R], not { } in your newcommand? – Teepeemm Aug 21 '18 at 17:18
  • 4
    You probably want to look for \lstinline. – egreg Aug 21 '18 at 17:19
  • Thank you for your suggestions, I tried the @Ulrich Diez code as it was what I was trying to describe with my enquiry. – DNA Aug 22 '18 at 9:54
  • 1
    Just commenting that the reason why your approach has problems is that lstlisting is not a normal LaTeX environment; like all other verbatim-like environment it changes catcodes. For "normal" environments your approach basically would work (remove the extra braces {#1} and see also @Teepeemm's comment). – user4686 Aug 24 '18 at 16:15
2

Here is possibly shorter approach. For important fact related to \scantokens, I refer to @UlrichDiez detailed explanations from his answer.

\documentclass{article}
\usepackage{listings}
%\usepackage[T1]{fontenc}

\makeatletter
\newcommand\codeR{\begingroup
                  \obeylines
                  \let\do\@makeother\dospecials
                  \catcode`\{ 1 \catcode`\} 2
                  \@codeR}%
\newcommand\@codeR[1]{\endgroup\newlinechar`\^^M
  \scantokens{\begin{lstlisting}[language=R]%
#1}% notice that #1 incorporates an initial and final EOL
\end{lstlisting}%
\newlinechar`^^J }% back to LaTeX's default
\makeatother

\begin{document}
You asked for it. You got it.

\begin{lstlisting}[language=R]
   This will appear with a {\code} format (also ^^41)
1234567890123456789012345678901234567890
     This will appear with a {\code} format
          This will appear with a {\code} format
\end{lstlisting}

A

\codeR{
   This will appear with a {\code} format (also ^^41)
1234567890123456789012345678901234567890
     This will appear with a {\code} format
          This will appear with a {\code} format
}
B

\begin{lstlisting}[language=R]
   This will appear with a {\code} format (also ^^41)
1234567890123456789012345678901234567890
     This will appear with a {\code} format
          This will appear with a {\code} format
\end{lstlisting}
A

\codeR{
   This will appear with a {\code} format (also ^^41)
1234567890123456789012345678901234567890
     This will appear with a {\code} format
          This will appear with a {\code} format
}

B
\end{document}

Things to be taken into account:

  • as seen above, I prefer to use clearer syntax

    \codeR{
    first line of listing
    ....
    last line of listing
    }
    
  • in the non-environment form, braces in the contents must be paired.

  • I have completely left aside problems with non-ascii characters (now by default utf8 with LaTeX) because this is already difficulty with listings and I don't know the current status of the problem there.

  • all in all one does not quite see the benefits of the only slightly shorter input syntax form... as LaTeX is full of \begin...\end anyway and any reasonable editor will have shortcuts to insert environments like C-cC-e in Emacs.

  • the image shows that after removal of the blank line after environment/codeR and above the A or B, there is an indentation suppression effect, common to both cases, so behaviour identical.

enter image description here

  • 1
    as I require the input syntax for \codeR to start with linebreak after initial { one could add usage of \codeR{...} with no linebreak after the { to trigger the "inline" form. So \codeR could be used both for "inline" and "paragraph-like" verbatim typesetting, depending only on whether user chooses to add a linebreak in source after initial {. – user4686 Aug 24 '18 at 16:21
  • 1
    admission of guilt: the method I propose is compact but it would not work as is with other "verbatim"-environment. The way the environment ends (with a backslash in \end having its standard catcode) in \codeR is not like in the real lstlisting environment (which sets the backslash to be an active character rather). However I determined that closing \scantokens the way as above works fine. – user4686 Aug 25 '18 at 11:33
  • 1
    (including \end{lstlisting} in the \scantokens fails because as explained in Ulrich answer, there will be a space tacitly arising after \end and then the lstlisting environment never finds its legal end (because of extra space); this is why catcode are modified in Ulrich's answer - in mine the issue is solved by simply not including the \end in the \scantokens part...) – user4686 Aug 25 '18 at 12:10
7

A \newcommand won't work as soon as there should be fragile content. Instead use a \lstnewenvironment:

\documentclass{article}
\usepackage{listings}

\lstnewenvironment{codeR}{\lstset{language=R}}{}

\begin{document}
\begin{codeR}
     This will appear with a code format
\end{codeR}
\end{document}
  • Thank you for your answer, as it works fine, what I was trying is to simplify my code by only adding the \codeR{text} option and avoid adding the begin and end commands. I'm still new to LaTeX and I highly appreciate your effort. – DNA Aug 22 '18 at 9:53
3

(Make sure to have this encoded in some 8bit-encoding, e.g., latin1.)

\documentclass{article}
\usepackage{listings}

\makeatletter
%%=================================================================
%% Copyright (C) 2007 - 2018 by Ulrich Diez (eu_angelion@web.de)
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public Licence (LPPL), either
%% version 1.3 of this license or (at your option) any later
%% version. (The latest version of this license is in:
%% http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 1999/12/01 or later.)
%% The author of this work is Ulrich Diez.
%% This work has the LPPL maintenance status 'not maintained'.
%% Usage of any/every component of this work is at your own risk.
%% There is no warranty - neither for probably included
%% documentation nor for any other part/component of this work.
%% If something breaks, you usually may keep the pieces.
%%=================================================================
% Implement stuff for reading arguments "verbatim":
%
% Syntax of \UDcollectverbarg:
%
%   \UDcollectverbarg{<^^M-replacement>}{<Mandatory 1>}{<Mandatory 2>}<verbatim-Arg>
%
% yields:
%
%   <Mandatory 1>{<Mandatory2>{<verbatim-Arg>}}
%
% Syntax of \UDconcatverbarg:
%
%   \UDconcatverbarg{<^^M-replacement>}{<Mandatory 1>}{<Mandatory 2>}<verbatim-Arg>
%
% yields:
%
%   <Mandatory 1>{<Mandatory2><verbatim-Arg>}
%
% with each character ^^M (usually=\endline-char) replaced by
%   token-sequence <^^M-replacement>
%
% The Mandatory-Arguments are mandatory. If they consist of several
% tokens, they must be nested into catcode-1/2-character-pair / braces.
% If reading is necessary, they will be read under normal catcode-
% conditions.
% The verbatim-Arg is also mandatory. It will be read under
% verbatim-catcode-conditions. If its first character is a brace,
% it will be "assumed" that the argument is nested into braces.
% Otherwise it will be assumed, that the argument is delimited
% by the first character - like the argument of \verb.
%
% Empty-lines will not be ignored.
%
% By nesting calls to \UDcollectverbarg within \UDcollectverbarg's first
% argument, you can collect "verbatim-arguments" within its second
% argument.
%
% E.g.,
%
%   \UDcollectverbarg{<^^M-replacement>}{\UDcollectverbarg{<^^M-replacement>}{\UDcollectverbarg{<^^M-replacement>}{<actionA>}}}% <- Mandatory 1
%                {<actionB>}%                     <- Mandatory
%                <verbatim-Arg1><verbatim-Arg2><verbatim-Arg3>
%
% yields:
%
%  \UDcollectverbarg{<^^M-replacement>}{\UDcollectverbarg{<^^M-replacement>}{<actionA>}}% <- Mandatory 1
%               {<actionB><verbatim-Arg1>}%        <- Mandatory 2
%               <verbatim-Arg2><verbatim-Arg3>
%
% yields:
%
%  \UDcollectverbarg{<^^M-replacement>}{<actionA>}% <- Mandatory 1
%               {<actionB>{<verbatim-Arg1>}{<verbatim-Arg2>}}% <- Mandatory 2
%               <verbatim-Arg3>
%
% yields:
%
%  <actionA>{<actionB>{<verbatim-Arg1>}{<verbatim-Arg2>}{<verbatim-Arg3>}}
%
% Assume <actionA> = \@firstofone -> equals:
%
%     \@firstofone{<actionB>{<verbatim-Arg1>}{<verbatim-Arg2>}{<verbatim-Arg3>}}
%
%    yields:
%
%     <actionB>{<verbatim-Arg1>}{<verbatim-Arg2>}{<verbatim-Arg3>}
\begingroup
\catcode`\^^M=12 %
\@firstoftwo{%
  \endgroup%
  \newcommand\UDEndlreplace[2]{\romannumeral0\@UDEndlreplace{#2}#1^^M\relax{}}%
  \newcommand*\@UDEndlreplace{}%
  \long\def\@UDEndlreplace#1#2^^M#3\relax#4#5{%
    \@CheckWhetherNull{#3}%
    { #5{#4#2}}{\@UDEndlreplace{#1}#3\relax{#4#2#1}{#5}}%
  }%
}{}%
\newcommand\UDcollectverbarg{\@UDverbarg{\@UDcollectverbarg}}%
\newcommand\UDconcatverbarg{\@UDverbarg{\@UDconcatverbarg}}%
\newcommand\@UDverbarg[4]{%
  \@bsphack
  \begingroup
  \let\do\@makeother\dospecials
  \catcode`\{=1 %
  \catcode`\ =10 %
  \@ifnextchar\bgroup
  {\catcode`\}=2 \@@UDverbarg{#1}{#2}{#3}{#4}{}}%
  {\do\{\@@UDverbarg{#1}{#2}{#3}{#4}}%
}%
\newcommand\@@UDverbarg[5]{%
  \do\ %
  \catcode`\^^M=12 %
  \long\def\@tempb##1#5{%
    \edef\@tempb{##1}%
    \@onelevel@sanitize\@tempb
    \expandafter\UDEndlreplace\expandafter{\@tempb}{#2}{\def\@tempb}%
    \expandafter#1\expandafter{\@tempb}{#3}{#4}%
  }%
  \@tempb
}%
\newcommand\@UDcollectverbarg[3]{%
  \endgroup
  \@esphack
  #2{#3{#1}}%
}%
\newcommand\@UDconcatverbarg[3]{%
  \endgroup
  \@esphack
  #2{#3#1}%
}%
\newcommand\@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\expandafter\expandafter\@firstoftwo{ }{}%
  \@secondoftwo}{\expandafter\expandafter\@firstoftwo{ }{}\@firstoftwo}%
}%
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begingroup
\makeatletter
\catcode`\^^M=12 %
\catcode`\/=0 %
\catcode`\\=12 %
/@firstofone{%
  /endgroup%
  /newcommand/codeR{/UDconcatverbarg{^^M}{/innercodeR}{}}%
  /newcommand/innercodeR[1]{%
    /begingroup%
    /newlinechar=/endlinechar%
    /scantokens{%
       \endgroup%
       \begin{lstlisting}[language=R]
       #1
       \end{lstlisting}%
    }%
  }%
}%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

You asked for it. You got it.

I definitely prefer the environment because with the command the indention
of the first line of code is a bi confusing at first glimpse.

\begin{lstlisting}[language=R]
   This will appear with a code format
1234567890123456789012345678901234567890
     This will appear with a code format
          This will appear with a code format
\end{lstlisting}


\codeR|   This will appear with a code format
1234567890123456789012345678901234567890
     This will appear with a code format
          This will appear with a code format|


\codeR{   This will appear with a code format
1234567890123456789012345678901234567890
     This will appear with a code format
          This will appear with a code format}

\end{document}

enter image description here


Guidelines for the usage of \codeR.

Internally \codeR does use \scantokens. Due to the subtleties of the way in which \scantokens works, it is necessary to have \codeR read the input and tokenize the tokens that form its argument under verbatim-catcode-régime. Therefore \codeR does switch to verbatim-catcode-régime before fetching (and hereby—this is our hope—having to read input from the input file for tokenizing the tokens forming it) its argument and passing that argument on to \scantokens which in turn wraps a lstlisting-environment around it before re-processing and hereby re-tokenizing the whole thing.

Basic facts:

(La)TeX works on so-called tokens. Tokens are data-structures.

But when you think of (La)TeX as a factory for producing .pdf-files and the like, then you can think of tokens as nice little sparkling items that at the beginning of the assmbly-line of that factory are put on that assembly-line and then get transported into the deeper realms of that factory. Many people call that assmbly-line "token stream". So when (La)TeX does read your .tex-input file, it takes that file for a set of instructions for putting some of these nice little sparkling tokens on the beginning of the assembly line. (La)TeX "looks" at the input file and decides/chooses which tokens to put at the beginning of the assembly line/which tokens to insert at the fountainhead of the token-stream. The choice is influenced by so-called category codes. Each character that (La)TeX might see in the input-file has a so-called category code. The category code assigned to an input-character determines what token to put on the assembly-line/into the token stream when seeing that character in a .tex-input file. For example when (La)TeX in the input file sees a character where currently category code 0 is assigned to—usually category code 0 is assigned only to the backslash character \&mdash, it will take this character for the directive to gather the name of a control sequence token from following input characters and then putting the corresponding control sequence token onto the assembly line. For example when (La)TeX is not gathering the name of a control sequence token and in the input-file finds the character "A", while "A" has currently assigned the category code 11 (letter), it will put an explicit character token onto the assembly line, whose catcode is 11(letter) and whose charcode is 65. (Internally (La)TeX does represent all possible characters in ASCII, i.e., the range for encoding goes from 0 to 255 and thereof the range from 0 to 127 corresponds to ASCII while the range from 128 to 256 depends on what 8bit-encoding is en vogue on the side of the user/of the computer-platform where (La)TeX is run. "A" has number 65 in ASCII.)

Then there is another station in the factory. That's the expansion-station. Here (La)TeX looks at the tokens that are brought to the expansion-station by the assembly line and does remove some tokens and replace them by other tokens. The rules for doing this come both from the ⟨replacement texts⟩ of macro-definitions and from the meanings of expandable TeX primitives. E.g., \romannumeral is an expandable TeX-primitive whose expansion yields replacing token sequences that are considered representations of numbers by token sequnces that are considered representations of these numbers in the way the Romans wrote numbers.

So tokens can come into being in two ways:

  1. When (La)TeX does read and tokenize input. This is the moment when category codes do apply.

  2. When TeX does—during expansion—replace tokens by other tokens according to the rules given both by the ⟨replacement text⟩ of macro-definitions and by the meanings of expandable TeX-primitives.

Be aware that \codeR does rely on having its argument tokenized under verbatim-category-code-régime.

This means that you should use \codeR

  • neither in ways where it gets its argument passed by other macros. That's because then the arguments got read from the input and tokenized not at the time of carrying out \codeR but already at the time of expanding these other macros.
    That circumstance in turn implies that the likelihood is high that the tokens forming the argument of \codeR got tokenized under the wrong catcode-régime.

    (At first glimpse it might look as if things would work out anyway. But there are subtleties which have to do with the way in which the eTeX primitive \scantokens works:

    \scantokens emulates unexpanded writing tokens to a text file and reading back and hereby tokenizing anew that text file. With (La)TeX there are some subtle aspects when it comes to unexpanded-writing tokens to a text file:

    E.g., there will always be inserted a trailing space behind a control word.

    E.g., explicit character tokens of category code 6(parameter), i.e., hashes, will always be doubled when unexpanded-writing to text file.

    When during unexpanded writing encountering an explicit character token whose character code in terms of (La)TeX' internal character code representation (which is ASCII) equals the value of the integer parameter \newlinechar, then (La)TeX will not write that character but it will write a "newline" (LF or CR or CR+LF; depends on your computer platform) into the text file in question.

    Also there is this subtle ^^-notation-thingie for in the input representing other characters.
    A ^^-notation-thingie in the input file is a sequence of two equal characters of category code 7(math superscript) in the input file followed either by an ASCII-character or by a two-(lowercase)-digit-hex-number. Usually ^ has category code 7(math superscript).
    When encountering a ^^-notation-thingie at the time of reading and tokenizing input, (La)TeX will put a character token into the token stream. E.g., when in the input encountering the sequence ^^41, (La)TeX will take that for the input character A—A = 65 (decimal) = 41 (hexadecimal) in ASCII ;-) —and will put a character token with category code 11(letter) and character code 65 (decimal) into the token stream.
    When having done that, (La)TeX does not know any more whether it has done so due to encountering ^^-notation in the input file or due to encountering usual notation in the input-file. When unexpanded-writing to file according to the token-stream, TeX might write the usual representation of the character-token in question.
    With code-listings whose .tex-output should literally look the same as the input, this might lead to the undesired transforming of ^^-sequences into something else. E.g., ^^41 might be transformed to A.

    Therefore it must be ensured that (La)TeX does not perform such subtle things when \scantokens "unexpanded-writing"-part is carried out. Ensuring that performing such things does not happen is in turn done by ensuring that (La)TeX does not encounter circumstances where it does perform those things. This in turn is done by switching to the verbatim-category-code-régime where no character has category code 6(parameter) and where no character has category code 0(escape) and where no character has category code 10(space) and where no character has category code 7(math superscript) before letting (La)TeX read and tokenize the input that it shall process as a verbatim code listing.

    This way reading and tokenizing input does never yield a control word token (whereafter during \scantokens' unexpanded-writing-part an unwanted space would get inserted), does never yield a character token of category code 6(parameter) (which during \scantokens' unexpanded-writing-part would be doubled), does never lead to the situation that (La)TeX takes a sequence of characters of category code 7(math superscript) for ^^-notation (which during \scantokens' unexpanded-writing-part might yield writing the non-^^-representation instead). No character being of category code 10(space) has the nice side effect that several consecutive spaces that get tokenized from input will not be collapsed into one single space token.)

  • nor in ways where it gets arguments passed whose tokens came into being as a result of expansion with tokens of wrong catcode-régime as ⟨replacement text⟩. Tokens that are delivered due to the rules of the ⟨replacement text⟩ of a ⟨definition⟩ are copies of tokens that got tokenized under that category code régime that was current when reading and tokenizing the definition. The likelihood that this was/is the wrong category-code-régime is high also.

Always make sure that arguments of \codeR must get read from the input and tokenized at the time of carrying out \codeR.

E.g., don't do:

\newcommand\macro[1]{something fancy \codeR{#1} more fanciness}
...
\macro{some code \relax##}

When \macro gets expanded, the argument will be read and tokenized under non-verbatim category-code-régime. Then that argument is passed to \codeR. But \codeR in turn needs arguments that were tokenized under verbatim category-code-régime. So that's a problem.
(Due to \scantokens unexpanded-writing-part's subtle actions like putting spaces behind control words and doubling catcode-6-hashes, the output will be something like some code \relax*&langle;space&rangle;*####.

E.g., don't do:

\newcommand\SomeConstantCodeR{\codeR{I do need this snippet often \relax##}}.
...
\SomeConstantCodeR

Same here: The definition text gets tokenized at definition-time, thus \relax will be a control word token, not a sequence of explicit character tokens, and the hashes will be explicit character tokens of catcode 6(parameter). The former will lead to insertion of a trailing space between the x of \relax and the first # of ## when \scantokens performs its unexpanded-writing-part. The latter will be reduced to one hash when expanding \SomeConstantCodeR. The remaining single hash in turn gets doubled when \scantokens performs its unexpanded-writing-part.

If you want, you can do:

\newcommand\fanythingsbeforecode[1]{something fancy #1 \codeR}
 ...
\fanythingsbeforecode|This actually is the code.|

You can do this because expanding \fanythingsbeforecode does not lead to tokenizing things that later might get processed as arguments of \codeR.

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.