3

This is a follow-up to the question: How can I typeset a command and its literal equivalent in an environment?

It would obviously be useful to handle environments too. I imagine something like the following:

Syntax

\begin{environment}{env_name}{env_description}
\begin{env_name}
some example text
\end{env_name}
\end{environment}

Desired Output

The output would be something like this:

enter image description here

Pseudo Code

\documentclass{article}
\usepackage{fontspec}
\usepackage{menukeys}
\usepackage{xparse}
\usepackage{booktabs} % Adds support for \toprule, \midrule, \bottomrule
\usepackage{array} % https://tex.stackexchange.com/a/4816/13552
\newcolumntype{$}{>{\global\let\currentrowstyle\relax}}
\newcolumntype{^}{>{\currentrowstyle}}
\newcommand{\rowstyle}[1]{\gdef\currentrowstyle{#1}%
  #1\ignorespaces
}
\setlength\parindent{0pt}

% Some flipped out function called "environment" goes here:
% \NewEnviron is what I would normally use to capture the body in \BODY
% \NewDocumentEnvironment is what egreg used for the command solution.


\begin{document}

\begin{environment}{mytab}{This environment is a wrapper for the standard latex table environment. This environment is a wrapper for the standard latex table environment. You can optionally adjust the alignment of columns by adding parameters. (e.g. \string$c\string^c\string^c)}
\begin{mytab}
\headrowstart
col1 & col2 & col3 \\
\headrowend
dat1 & dat2 & dat3 \\
dat4 & dat5 & dat6 \\
\end{mytab}
\end{environment}

\end{document}

Update 27-04-2015

I've added the following code to the preamble:

\ExplSyntaxOn

\NewDocumentEnvironment{environment}{vvv}
 {
  \tl_set:Nn \l_env_argument_i_tl { #1 }
  \tl_set:Nn \l_env_argument_ii_tl { #2 }
  \tl_set:Nn \l_env_argument_iii_tl { #3 }
  \par\vspace{\baselineskip}
  \noindent
  \bgroup\ttfamily
  \l_env_argument_i_tl\par
  \ignorespaces
  \egroup
  \par\nopagebreak
  \noindent
  \l_env_argument_iii_tl \par\noindent % Description
  \textbf{Example:~}\par
    \texttt
   {
  \string\begin\string{\l_env_argument_i_tl\string}\l_env_argument_ii_tl\\
  \string\end\string{\l_env_argument_i_tl\string}
   }
  \\*
 }
 {
  \tl_set_rescan:NnV \l_env_argument_tl {} \l_env_argument_i_tl
  \tl_if_blank:VF \l_env_argument_ii_tl
   {
    \tl_set_rescan:NnV \l_env_temp_tl {} \l_env_argument_ii_tl
    \tl_put_right:Nx \l_env_argument_tl { { \exp_not:V \l_env_temp_tl } }
   }\\*
 }
\tl_new:N \l_env_argument_tl
\tl_new:N \l_env_argument_i_tl
\tl_new:N \l_env_argument_ii_tl
\tl_new:N \l_env_argument_iii_tl
\tl_new:N \l_env_temp_tl
\cs_generate_variant:Nn \tl_set_rescan:Nnn { NnV }
\ExplSyntaxOff

The output should be an example of literal code and an example as it would look when typeset.

enter image description here

Problem with automatically inserting code:

%\begin{environment}{<environment>}{<any parameters>}{<description>}
\begin{environment}{tabular}{{ccc}}{This is the standard latex environment for tabular data.}
% \begin{tabular}{ccc} <-- This gets automatically inserted
col1 & col2 & col3 \\
dat1 & dat2 & dat3 \\
% \end{tabular} <-- This gets automatically inserted
\end{environment}

Another option I was thinking about due to difficulties capturing the text inside the environment is to put the tabular data into arg3 and move the description into the body of the environment (just exchange them). If I do this, I still run into the problem that I need to add \begin{ + arg1 + } + arg2 + arg3 + \end{ + arg1 + }. I am not sure how to do this.

  • 2
    Did you try out the solutions at your earlier question with environments? At least several of them should do environments too. An example environment was even shown in one of the answers there. – Paul Gessler Apr 24 '15 at 11:07
  • @PaulGessler If you are referring to tcolorbox, it is not an option due to compatibility issues with hyperref. – Jonathan Komar Apr 27 '15 at 12:32
  • What about the solution with package example: \begin{example} \fbox{\begin{minipage}{4cm} \raggedright \tiny\lipsum[2] \end{minipage}} \end{example} – Paul Gessler Apr 27 '15 at 12:51
  • 2
    @macmadness86: What's the precise problem between tcolorbox and hyperref? – user31729 Apr 27 '15 at 16:21
  • Have you looked at the environ package? (If I'm remembering it right.) – cfr Apr 28 '15 at 0:51
3
+50

I did not use the OP's code, but I show here how the filecontents, etoolbox and verbatimbox packages can be used to both typeset some code and display the source, all in one environment.

EDITED to include it in a single environment, using the syntax

\begin{enviro}{name}{description}
 <code>
\end{enviro}

I set the output using my own simplistic format, but that can be changed to suit the format of the user.

I should note that I used \verbfilebox to set the code listing, which allows me to \fbox the result, and will prevent page breaks mid code. If one wanted to code to be able to break pages (using a full \textwidth listing), one could use the \verbfilenobox macro instead.

\documentclass[12pt]{article}
\usepackage{filecontents,verbatimbox}
\usepackage{etoolbox}
\parindent 0pt
\makeatletter
\newenvironment{enviro}[2]
{\gdef\environame{#1}\gdef\envirodescription{#2}%
  \@tempswafalse\filec@ntents{tmp}}
{\endfilecontents}
\makeatother
\newcommand\setenviro{
  \textbf{\Large\environame:}\par\bigskip
  \envirodescription\par\bigskip
  \textbf{Example:} \input{tmp}\par\bigskip
  \textbf{Code:}
  \verbfilebox[\footnotesize]{tmp}
  \fbox{\theverbbox}
}
\AfterEndEnvironment{enviro}{\setenviro}
\begin{document}
\begin{enviro}{tabular}{This is the standard latex environment for 
  tabular data.}
\begin{tabular}{|c|c|}
\hline
My & tabular\\
\hline
is & here\\
\hline
\end{tabular}
\end{enviro}
\end{document}

enter image description here

| improve this answer | |
  • Is it possible to have LaTeX automatically delete the tmp.tex file after compilation? – Jonathan Komar May 4 '15 at 9:08
  • 1
    @macmadness86 With the so-called write18 feature of LaTeX (turned off by default for security reasons), one can invoke operating system commands from within a LaTeX compilation. But as an alternative, I would probably see if I could have tmp.tex open, not in the working directory, but in a system temp directory. That way, it wouldn't be deleted, but nor would it clutter your current directory. – Steven B. Segletes May 4 '15 at 9:48
3

Doubt this is what the OP wants, but every now and then it's nice to do something from (almost) first principles, and convince myself that all that time I spent years ago reading Stephan von Bechtolsheim's TeX in practice wasn't completely wasted.

Note that the use of \scantokens assumes that etex is used.

\documentclass[border=10]{standalone}

\edef\vbatcatcode{\the\catcode`\@}
\catcode`\@=11

\def\vb@other{11}
\def\vb@active{13}

\def\vb@makeactive#1{\catcode`#1=\vb@active\relax}
\def\vb@makeother#1{\catcode`#1=\vb@other\relax}

\def\vb@dospecials{\let\vb@do=\vb@makeother%
\vb@do\\\vb@do\{\vb@do\}\vb@do\$\vb@do\#\vb@do\%\vb@do\^\vb@do\&\vb@do\~\vb@do\_}

{\catcode`\|=\catcode`\\
\catcode`\[=\catcode`\{
\catcode`\]=\catcode`\}
\vb@makeactive\^^M%
\vb@makeother\{%
\vb@makeother\}%
\vb@makeother\\%
|long|gdef|vb@collect^^M#1^^M\end{vb}[|vb@collected[#1]]%
]

{\vb@makeactive\ %
\vb@makeactive\^^M%
\vb@makeactive\^^I%
\gdef\vb@dospaces{\vb@makeactive\ \def {\vb@typesetspace}}%
\gdef\vb@doreturns{\vb@makeactive\^^M\def^^M{\vb@typesetreturn}}%
\gdef\vb@dotabs{\vb@makeactive\^^I\def^^I{\vb@typesettab}}%
\gdef\vb@returnspacing{%
\vb@makeactive\ \def {\space}%
\vb@makeactive\^^M\def^^M{\space}%
\vb@makeactive\^^I\def^^I{\space}}%
} 

\def\vb@typesetspace{\ }
\long\def\vb@typesetreturn{\par\leavevmode}
\def\vb@typesettab{\ \ \ }

\def\vb#1#2{%
  \def\vbname{#1}%
  \def\vbdescription{#2}%
  \begingroup%
    \vb@dospaces%
    \vb@doreturns%
    \vb@dotabs%
    \vb@dospecials%
    \vb@collect%
}

\long\def\vb@collected#1{%
    \gdef\vbexamplecode{\vb@dospaces\vb@doreturns\vb@dotabs#1}%
  \endgroup%
  \gdef\vbexecutedcode{\begingroup\vb@returnspacing\scantokens{#1\ignorespaces}\endgroup}%
  \vbtypeset%
  \vbend%
}

\def\vbend{%
  \endgroup%
}

\catcode`\@=\vbatcatcode%

\newdimen\vbtmpdimen

\def\vbtypeset{%
  \parindent=0pt
  \begin{minipage}[t]{0.75in}\tt\vbname\end{minipage}%
  \vbtmpdimen=\linewidth
  \advance\vbtmpdimen-0.75in%
  \begin{minipage}[t]{\vbtmpdimen}
    \vbdescription\medskip\par\leavevmode
    Example:
    \medskip\par\leavevmode%
    \vbexecutedcode%
    \medskip\par\leavevmode
    {\ttfamily\vbexamplecode}%
  \end{minipage}%
  \bigskip}

\begin{document}
\begin{vb}{tabular}
{This is the standard latex environment for tabular data.}
\begin{tabular}{ccc}
\hline
  col1 & col2 & col3 \\
\hline
  dat1 & dat2 & dat3 \\
  dat4 & dat5 & dat6 \\
\hline
\end{tabular}
\end{vb}

\end{document}

enter image description here

| improve this answer | |
  • The time you spent reading Stephan von Bechtolsheim's "TeX in practice" wasn't completely wasted :D – Jonathan Komar Apr 30 '15 at 5:57
3

My solution uses the temporary external file. The data are scanned in verbatim mode and saved to the file. Then the file is read with normal catcode settings, so the normal output is printed. Then the data from verbatim scan is used for verbatim output.

\documentclass{article}

\newwrite\verbfile
\def\setverb{\def\do##1{\catcode`##1=12}\dospecials}
\def\begverbA{\bgroup \setverb \obeyspaces \obeylines \begverbB}
\def\tmp#1{}\edef\bslash{\expandafter\tmp\string\\}
\edef\tmp{\def\noexpand\begverbB##1\bslash end\string{showcode\string}##2}
\tmp{\egroup\par
   %%% normal output:
   {\newlinechar=`\^^J \obeylinesJ
    \immediate\openout\verbfile=verb-tmp.tex
    \immediate\write\verbfile{#1}%
    \immediate\closeout\verbfile}
   \input verb-tmp.tex
   \par\bigskip
   %%% verbatim output:
   {\tt\def\par##1{\endgraf\ifx##1\relax\else\leavevmode\fi##1}
    \obeylines#1\relax}%
   \par\medskip
   \end{showcode}%
}
{\catcode`\^^M=\active \gdef\obeylinesJ{\catcode`\^^M\active \def^^M{^^J}}}

\newenvironment{showcode}[2]{%
   \par\medskip
   \bgroup\leftskip=5em
          \noindent\llap{\tt#1\quad}#2\par
          \bigskip\begverbA}
   \egroup

\begin{document}
\begin{showcode}{tabular}
                {This is the standard \LaTeX\ environment for tabular data.}
\begin{tabular}{ccc}
\hline
  col1 & col2 & col3 \\
\hline
  dat1 & dat2 & dat3 \\
  dat4 & dat5 & dat6 \\
\hline
\end{tabular}
\end{showcode}

\end{document}
| improve this answer | |
  • Could you explain the macros that do the heavy lifting? \setverb sets all chars to the same cat code (12), right? That is about as far as I got. What else is interesting here? \begverbA is the verbatim code? What is the purpose of \edef\bslash{\expandafter\tmp\string\\}? – Jonathan Komar May 10 '16 at 19:44
3

Using a hack of the example package.

It could be a good idea make directly your own package based in example.sty instead of muddle the preamble on this way.

MWE

\documentclass[a4paper]{article}
\usepackage[margin=3cm]{geometry,xcolor}
\usepackage{example,booktabs}
\parindent0pt\parskip0em
\columnsep .1\textwidth  
\makeatletter
\chardef\escape=0
\chardef\open=1
\chardef\close=2
\chardef\letter=11
\chardef\other=12
\chardef\uscode=\catcode`\_   
\catcode`\_=\letter
\def\example#1#2{
\fboxsep1em
\fboxrule0em
\bigskip{\color{blue!10}\rule{\textwidth}{2.5pt}}\par\bigskip
\noindent\hangindent.2\linewidth\makebox[.2\linewidth][l]{\texttt{#1}}%
#2\par\bigskip\noindent{\color{blue!10}\rule{\textwidth}{2pt}}\par\bigskip
   \par
   \immediate\openout\example_file\example_name
   \begingroup
      \@makeother\"\let\do\@makeother \dospecials
      \obeylines \obeyspaces
      \@ignoretrue \copy_line
      }

\def\ExampleSet{%
\noindent\fcolorbox{red}{cyan!10}{
   \begin{minipage}[t]{.4\textwidth}%
      \hrule height\z@
      \def\markboth##1##2{}%
      \def\markright##1{}%
      \def\addcontentsline##1##2##3{}%
      \input \example_name
      \par
      \hrule height\z@
   \end{minipage}}}      

   \def\ExampleVerb{%
\noindent\fcolorbox{red}{green!10}{%
   \begin{minipage}[t]{.4\textwidth}%
      \hrule height\z@
      \begingroup
         \small
         \parindent\z@
         \rightskip\@flushglue
         \@makeother\"\@verbatim
         \frenchspacing \@vobeyspaces \@vobeytabs
         \input \example_name
         \endverbatim
      \endgroup
      \hrule height\z@
   \end{minipage}}}

\makeatother

\begin{document}

\begin{example}{tabular}{This is the standard \LaTeX\ environment for tabular data, with optional horizontal and vertical lines.}
%\begin{example}
\begin{tabular}{ccc}
\toprule 
col1 & col2 & col3 \\
\midrule
dat1 & dat2 & dat3 \\
dat4 & dat5 & dat6 \\
\bottomrule
\end{tabular} 
\end{example}

\begin{example}{quote}{This is a  standard \LaTeX\ environment for quotes.}
This is main text.
\begin{quote}
This is a quote
\end{quote} 
This is again the main text.
\end{example}

\end{document}
| improve this answer | |
  • Hey that looks great. Could you elaborate as to where the example hack starts and ends? What are the \chardefs doing? Normally set special characters to have class 11 (letter) for verbatim information, right? – Jonathan Komar May 4 '15 at 7:09
  • @macmadness86 the whole preamble is the hack. The \chardefseries is the same that inside the example.sty, but I have to load again to redefine \example. The hack of \example is mainly add two arguments (the original does not support any) and the code for the format of the header (the rules and so on). \ExampleSet and \ExampleVerb are almost the same that the originals, excepting the width of the minipages and the background color using \fcolorboxes. – Fran May 4 '15 at 14:23

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.