Esta es una continuación de la pregunta:¿Cómo puedo componer un comando y su equivalente literal en un entorno?
Obviamente, también sería útil manejar entornos. Me imagino algo como lo siguiente:
Sintaxis
\begin{environment}{env_name}{env_description}
\begin{env_name}
some example text
\end{env_name}
\end{environment}
Salida deseada
La salida sería algo como esto:
Pseudocódigo
\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}
Actualización 27-04-2015
Agregué el siguiente código al preámbulo:
\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
La salida debe ser un ejemplo de código literal y un ejemplo de cómo se vería cuando estuviera tipográfico.
Problema al insertar código automáticamente:
%\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}
Otra opción en la que estaba pensando debido a las dificultades para capturar el texto dentro del entorno es colocar los datos tabulares en arg3 y mover la descripción al cuerpo del entorno (simplemente intercambiarlos).Si hago esto, todavía me encuentro con el problema de que necesito agregar \begin{
+ arg1 + }
+ arg2 + arg3 + \end{
+ arg1 + }
. No estoy seguro de cómo hacer esto.
Respuesta1
No utilicé el código del OP, pero aquí muestro cómo se pueden usar los paquetes filecontents
, etoolbox
y para escribir código y mostrar la fuente, todo en un solo entorno.verbatimbox
EDITADO para incluirlo en un solo entorno, usando la sintaxis
\begin{enviro}{name}{description}
<code>
\end{enviro}
Configuré la salida usando mi propio formato simplista, pero se puede cambiar para adaptarlo al formato del usuario.
Debo tener en cuenta que solía \verbfilebox
configurar la lista de códigos, lo que me permite obtener \fbox
el resultado y evitará saltos de página a mitad del código. Si uno quisiera codificar para poder dividir páginas (usando una \textwidth
lista completa), podría usar la \verbfilenobox
macro en su lugar.
\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}
Respuesta2
Dudo que esto sea lo que quiere el OP, pero de vez en cuando es bueno hacer algo desde (casi) los primeros principios y convencerme de que todo ese tiempo que pasé hace años leyendo el libro de Stephan von BechtolsheimTeX en la prácticano fue completamente desperdiciado.
Tenga en cuenta que el uso de \scantokens
supone que etex
se utiliza.
\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}
Respuesta3
Mi solución utiliza el archivo externo temporal. Los datos se escanean textualmente y se guardan en el archivo. Luego, el archivo se lee con la configuración normal del código cat, por lo que se imprime la salida normal. Luego, los datos del escaneo textual se utilizan para la producción textual.
\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}
Respuesta4
Usando un truco del example
paquete.
Podría ser una buena idea crear directamente su propio paquete basado en example.sty
en lugar de confundir el preámbulo de esta manera.
\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}