有可能在 \ifthenelse 内拥有 tcblisting 环境吗?

有可能在 \ifthenelse 内拥有 tcblisting 环境吗?

我想根据布尔标志选择要打印的代码。

如果我使用\ifthenelse纯文本,它可以完美运行,但如果我放置tcblisting环境而不是纯文本,它会给我这个错误:

Runaway argument?
! File ended while scanning use of \next.
<inserted text> 
                \par 
<*> main.tex

I suspect you have forgotten a `}', causing me
to read past where you wanted me to stop.
I'll try to recover; but if the error is serious,
you'd better type `E' or `X' now and fix your file.

! Emergency stop.

这是我的 MWE:

\documentclass{book}
\usepackage{xcolor}
\definecolor{marrone}{RGB}{215,151,66}
\definecolor{blu}{RGB}{0,58,121}
\definecolor{verde}{RGB}{0, 108, 36}
\definecolor{arancione}{RGB}{236, 100, 0}
\definecolor{giallo}{RGB}{236, 189, 0}

\usepackage{relsize}

\usepackage{ifthen}
\newboolean{publicedition}
\setboolean{publicedition}{true}
%\setboolean{publicedition}{false}

\usepackage[most]{tcolorbox}
\tcbuselibrary{listings}

\usepackage{listings}

\newcommand{\stilestringa}{\color{blue!40!red}\ttfamily}
\newcommand{\stilecomandoa}{\color{blue!60!black}\bfseries}
\newcommand{\stilecomandob}{\color{blue!80!cyan}}
\newcommand{\stilecommenti}{\color[RGB]{77,159,53}\ttfamily}
\newcommand{\stilewarnings}{\color[RGB]{93,138,168}\ttfamily}
\newcommand{\stileerrori}{\color{red}\ttfamily}

\lstdefinestyle{saslst}{               
    columns=flexible,
    language=SAS,
    escapechar=|, 
    alsoletter={\%},
    deletekeywords={SET, KEEP, LIBNAME, OBS, FIRSTOBS, DROP, IF, THEN,
        ELSE, RENAME, WHERE, PUT, DO, OR, AND, NOT, END, LENGTH,
        LABEL, OUTPUT},
    morekeywords=[1]{quit, proc, let, \%macro, mend },
    morekeywords=[2]{access, obs, firstobs,  append, sort, sql,
        transpose, compare, in, when, otherwise, select, 
        format, informat, attrib,
        set, keep, libname, drop, if, then, else, rename, where, \%put, do,
        or, and, not, end, length,  label, output, lenght},
    morecomment=[f]{*}, 
    morecomment=[s]{/*}{*/}, 
    morecomment=[n]{/*}{*/}, 
    morestring=[b]{"},
    otherkeywords={\&},
    morekeywords = [3]{\&},
    keywordstyle={[1]\stilecomandoa},
    keywordstyle={[2]\stilecomandob},
    keywordstyle={[3]\stilecomandoa},
    commentstyle=\stilecommenti,
    stringstyle=\stilestringa,
    showstringspaces=false, 
    keepspaces=true, 
    sensitive=false,
    breaklines=true,
    breakindent=0pt,
    aboveskip=-4pt plus 2pt minus 2pt,
    belowskip=-4pt plus 2pt minus 2pt,
    inputencoding=utf8/latin1
}

\newtcblisting{sas}{%
    listing only,
    enhanced,
    opacityfill=0,
    left=0mm,
    boxsep=0pt,
    boxrule=0pt,
    listing engine=listings,
    listing options={%
        style=saslst,            
        basicstyle=\relsize{0}\ttfamily
        }
}

\begin{document} 
\ifthenelse{\boolean{publicedition}}{%
this works
}{%
and this works
}

\ifthenelse{\boolean{publicedition}}{%
\begin{sas}
this doesn't work
\end{sas}
}{%
\begin{sas}
and this doesn't work
\end{sas}
}
\end{document}

答案1

您不能lstlisting在另一个命令的参数中包含环境,因为它就像verbatim

解决方案:\newboolean{foo}定义。如果跳过的部分中\iffoo\if...\else或标记,则此操作将无法正常工作。\fi

\documentclass{book}
\usepackage{xcolor}
\definecolor{marrone}{RGB}{215,151,66}
\definecolor{blu}{RGB}{0,58,121}
\definecolor{verde}{RGB}{0, 108, 36}
\definecolor{arancione}{RGB}{236, 100, 0}
\definecolor{giallo}{RGB}{236, 189, 0}

\usepackage{relsize}

\usepackage{ifthen}
\newboolean{publicedition}
\setboolean{publicedition}{true}
%\setboolean{publicedition}{false}

\usepackage[most]{tcolorbox}
\tcbuselibrary{listings}

\usepackage{listings}

\newcommand{\stilestringa}{\color{blue!40!red}\ttfamily}
\newcommand{\stilecomandoa}{\color{blue!60!black}\bfseries}
\newcommand{\stilecomandob}{\color{blue!80!cyan}}
\newcommand{\stilecommenti}{\color[RGB]{77,159,53}\ttfamily}
\newcommand{\stilewarnings}{\color[RGB]{93,138,168}\ttfamily}
\newcommand{\stileerrori}{\color{red}\ttfamily}

\lstdefinestyle{saslst}{               
    columns=flexible,
    language=SAS,
    escapechar=|, 
    alsoletter={\%},
    deletekeywords={SET, KEEP, LIBNAME, OBS, FIRSTOBS, DROP, IF, THEN,
        ELSE, RENAME, WHERE, PUT, DO, OR, AND, NOT, END, LENGTH,
        LABEL, OUTPUT},
    morekeywords=[1]{quit, proc, let, \%macro, mend },
    morekeywords=[2]{access, obs, firstobs,  append, sort, sql,
        transpose, compare, in, when, otherwise, select, 
        format, informat, attrib,
        set, keep, libname, drop, if, then, else, rename, where, \%put, do,
        or, and, not, end, length,  label, output, lenght},
    morecomment=[f]{*}, 
    morecomment=[s]{/*}{*/}, 
    morecomment=[n]{/*}{*/}, 
    morestring=[b]{"},
    otherkeywords={\&},
    morekeywords = [3]{\&},
    keywordstyle={[1]\stilecomandoa},
    keywordstyle={[2]\stilecomandob},
    keywordstyle={[3]\stilecomandoa},
    commentstyle=\stilecommenti,
    stringstyle=\stilestringa,
    showstringspaces=false, 
    keepspaces=true, 
    sensitive=false,
    breaklines=true,
    breakindent=0pt,
    aboveskip=-4pt plus 2pt minus 2pt,
    belowskip=-4pt plus 2pt minus 2pt,
    inputencoding=utf8/latin1
}

\newtcblisting{sas}{%
    listing only,
    enhanced,
    opacityfill=0,
    left=0mm,
    boxsep=0pt,
    boxrule=0pt,
    listing engine=listings,
    listing options={%
        style=saslst,            
        basicstyle=\relsize{0}\ttfamily
        }
}

\begin{document} 

\ifthenelse{\boolean{publicedition}}{%
this works
}{%
and this works
}

\ifpublicedition
\begin{sas}
this works too
\end{sas}
\else
\begin{sas}
and also this works
\end{sas}
\fi

\end{document}

使用 jfbu 的想法的另一种实现。如果标记\THEN或出现在所处理的语言中,则可以轻松地将它们更改为其他内容。对标记的影响很小\ELSE\FI

\documentclass{book}
\usepackage{xcolor}
\definecolor{marrone}{RGB}{215,151,66}
\definecolor{blu}{RGB}{0,58,121}
\definecolor{verde}{RGB}{0, 108, 36}
\definecolor{arancione}{RGB}{236, 100, 0}
\definecolor{giallo}{RGB}{236, 189, 0}

\usepackage{relsize}

\usepackage{ifthen}
\newboolean{publicedition}
\setboolean{publicedition}{true}
%\setboolean{publicedition}{false}

\usepackage[most]{tcolorbox}
\tcbuselibrary{listings}

\usepackage{listings}

\newcommand{\stilestringa}{\color{blue!40!red}\ttfamily}
\newcommand{\stilecomandoa}{\color{blue!60!black}\bfseries}
\newcommand{\stilecomandob}{\color{blue!80!cyan}}
\newcommand{\stilecommenti}{\color[RGB]{77,159,53}\ttfamily}
\newcommand{\stilewarnings}{\color[RGB]{93,138,168}\ttfamily}
\newcommand{\stileerrori}{\color{red}\ttfamily}

\lstdefinestyle{saslst}{               
    columns=flexible,
    language=SAS,
    escapechar=|, 
    alsoletter={\%},
    deletekeywords={SET, KEEP, LIBNAME, OBS, FIRSTOBS, DROP, IF, THEN,
        ELSE, RENAME, WHERE, PUT, DO, OR, AND, NOT, END, LENGTH,
        LABEL, OUTPUT},
    morekeywords=[1]{quit, proc, let, \%macro, mend },
    morekeywords=[2]{access, obs, firstobs,  append, sort, sql,
        transpose, compare, in, when, otherwise, select, 
        format, informat, attrib,
        set, keep, libname, drop, if, then, else, rename, where, \%put, do,
        or, and, not, end, length,  label, output, lenght},
    morecomment=[f]{*}, 
    morecomment=[s]{/*}{*/}, 
    morecomment=[n]{/*}{*/}, 
    morestring=[b]{"},
    otherkeywords={\&},
    morekeywords = [3]{\&},
    keywordstyle={[1]\stilecomandoa},
    keywordstyle={[2]\stilecomandob},
    keywordstyle={[3]\stilecomandoa},
    commentstyle=\stilecommenti,
    stringstyle=\stilestringa,
    showstringspaces=false, 
    keepspaces=true, 
    sensitive=false,
    breaklines=true,
    breakindent=0pt,
    aboveskip=-4pt plus 2pt minus 2pt,
    belowskip=-4pt plus 2pt minus 2pt,
    inputencoding=utf8/latin1
}

\newtcblisting{sas}{%
    listing only,
    enhanced,
    opacityfill=0,
    left=0mm,
    boxsep=0pt,
    boxrule=0pt,
    listing engine=listings,
    listing options={%
        style=saslst,            
        basicstyle=\relsize{0}\ttfamily
        }
}

\newcommand\IF[1]{%
  \begingroup
  \csname if#1\endcsname
    \let\THEN\relax
    \let\ELSE\skipsecondpart
  \else
    \let\THEN\skipfirstpart
    \def\FI{\endgroup}%
  \fi
}
\let\ELSE\relax
\let\FI\endgroup
\long\def\skipsecondpart#1\FI{\endgroup}
\long\def\skipfirstpart#1\ELSE{}

\begin{document} 

\section{True}

\IF{publicedition}\THEN
\begin{sas}
this works too
\end{sas}
\ELSE
\begin{sas}
and also this works
\end{sas}
\FI

\section{False}

\setboolean{publicedition}{false}

\IF{publicedition}\THEN
\begin{sas}
this works too
\end{sas}
\ELSE
\begin{sas}
and also this works
\end{sas}
\FI

\end{document}

答案2

解决方法

\documentclass{book}
\usepackage{xcolor}
\definecolor{marrone}{RGB}{215,151,66}
\definecolor{blu}{RGB}{0,58,121}
\definecolor{verde}{RGB}{0, 108, 36}
\definecolor{arancione}{RGB}{236, 100, 0}
\definecolor{giallo}{RGB}{236, 189, 0}

\usepackage{relsize}

\usepackage{ifthen}
\newboolean{publicedition}
\setboolean{publicedition}{true}
%\setboolean{publicedition}{false}

\usepackage[most]{tcolorbox}
\tcbuselibrary{listings}

\usepackage{listings}

\newcommand{\stilestringa}{\color{blue!40!red}\ttfamily}
\newcommand{\stilecomandoa}{\color{blue!60!black}\bfseries}
\newcommand{\stilecomandob}{\color{blue!80!cyan}}
\newcommand{\stilecommenti}{\color[RGB]{77,159,53}\ttfamily}
\newcommand{\stilewarnings}{\color[RGB]{93,138,168}\ttfamily}
\newcommand{\stileerrori}{\color{red}\ttfamily}

\lstdefinestyle{saslst}{               
    columns=flexible,
    language=SAS,
    escapechar=|, 
    alsoletter={\%},
    deletekeywords={SET, KEEP, LIBNAME, OBS, FIRSTOBS, DROP, IF, THEN,
        ELSE, RENAME, WHERE, PUT, DO, OR, AND, NOT, END, LENGTH,
        LABEL, OUTPUT},
    morekeywords=[1]{quit, proc, let, \%macro, mend },
    morekeywords=[2]{access, obs, firstobs,  append, sort, sql,
        transpose, compare, in, when, otherwise, select, 
        format, informat, attrib,
        set, keep, libname, drop, if, then, else, rename, where, \%put, do,
        or, and, not, end, length,  label, output, lenght},
    morecomment=[f]{*}, 
    morecomment=[s]{/*}{*/}, 
    morecomment=[n]{/*}{*/}, 
    morestring=[b]{"},
    otherkeywords={\&},
    morekeywords = [3]{\&},
    keywordstyle={[1]\stilecomandoa},
    keywordstyle={[2]\stilecomandob},
    keywordstyle={[3]\stilecomandoa},
    commentstyle=\stilecommenti,
    stringstyle=\stilestringa,
    showstringspaces=false, 
    keepspaces=true, 
    sensitive=false,
    breaklines=true,
    breakindent=0pt,
    aboveskip=-4pt plus 2pt minus 2pt,
    belowskip=-4pt plus 2pt minus 2pt,
    inputencoding=utf8/latin1
}

\newtcblisting{sas}{%
    listing only,
    enhanced,
    opacityfill=0,
    left=0mm,
    boxsep=0pt,
    boxrule=0pt,
    listing engine=listings,
    listing options={%
        style=saslst,            
        basicstyle=\relsize{0}\ttfamily
        }
}

\begin{document} 
\ifthenelse{\boolean{publicedition}}{%
this works
}{%
and this works
}

\let\ENDOFGOBBLE\empty
\let\ENDOFGABBLE\empty
\long\def\GOBBLETOEND#1\ENDOFGOBBLE{}
\long\def\GABBLETOEND#1\ENDOFGABBLE{}

\ifthenelse{\boolean{publicedition}}
   {}{\GABBLETOEND}
\begin{sas}
this does work
\end{sas}
\GOBBLETOEND
\ENDOFGABBLE
\begin{sas}
and this does work too
\end{sas}
\ENDOFGOBBLE

\end{document}

在此处输入图片描述

并且布尔值为false

在此处输入图片描述

答案3

tcolorbox 有一个void键可以丢弃一个框。你可以将它与样式一起使用以排除一些框:

\documentclass{book}

\usepackage[most]{tcolorbox}
\tcbuselibrary{listings}

\usepackage{listings}


\newtcblisting{sas}[1][]{%
    listing only,
    enhanced,
    opacityfill=0,
    left=0mm,
    boxsep=0pt,
    boxrule=0pt,
    listing engine=listings,
     #1   
}

\newif\ifsaspub

\tcbset{saspub/.style={\ifsaspub\else void\fi},sasdraft/.style={\ifsaspub void\fi}}

\begin{document}
x%
\begin{sas}[sasdraft]
draft \section{}
\end{sas}
y%
\begin{sas}[saspub]
pup \section{}
\end{sas}
z

\saspubtrue

x%
\begin{sas}[sasdraft]
draft
\end{sas}
y%
\begin{sas}[saspub]
pup
\end{sas}
z

\saspubfalse

x%
\begin{sas}[sasdraft]
draft
\end{sas}
y%
\begin{sas}[saspub]
pup
\end{sas}
z

\end{document}

在此处输入图片描述

答案4

这可能是也可能不是一个可接受的解决方法。在测试之前将两个条件放在临时框中\ifthenelse,然后使用正确的框作为测试结果。

\documentclass{book}
\usepackage{xcolor}
\definecolor{marrone}{RGB}{215,151,66}
\definecolor{blu}{RGB}{0,58,121}
\definecolor{verde}{RGB}{0, 108, 36}
\definecolor{arancione}{RGB}{236, 100, 0}
\definecolor{giallo}{RGB}{236, 189, 0}

\usepackage{relsize}

\usepackage{ifthen}
\newboolean{publicedition}
\setboolean{publicedition}{true}
\setboolean{publicedition}{false}

\usepackage[most]{tcolorbox}
\tcbuselibrary{listings}

\usepackage{listings}

\newcommand{\stilestringa}{\color{blue!40!red}\ttfamily}
\newcommand{\stilecomandoa}{\color{blue!60!black}\bfseries}
\newcommand{\stilecomandob}{\color{blue!80!cyan}}
\newcommand{\stilecommenti}{\color[RGB]{77,159,53}\ttfamily}
\newcommand{\stilewarnings}{\color[RGB]{93,138,168}\ttfamily}
\newcommand{\stileerrori}{\color{red}\ttfamily}

\lstdefinestyle{saslst}{               
    columns=flexible,
    language=SAS,
    escapechar=|, 
    alsoletter={\%},
    deletekeywords={SET, KEEP, LIBNAME, OBS, FIRSTOBS, DROP, IF, THEN,
        ELSE, RENAME, WHERE, PUT, DO, OR, AND, NOT, END, LENGTH,
        LABEL, OUTPUT},
    morekeywords=[1]{quit, proc, let, \%macro, mend },
    morekeywords=[2]{access, obs, firstobs,  append, sort, sql,
        transpose, compare, in, when, otherwise, select, 
        format, informat, attrib,
        set, keep, libname, drop, if, then, else, rename, where, \%put, do,
        or, and, not, end, length,  label, output, lenght},
    morecomment=[f]{*}, 
    morecomment=[s]{/*}{*/}, 
    morecomment=[n]{/*}{*/}, 
    morestring=[b]{"},
    otherkeywords={\&},
    morekeywords = [3]{\&},
    keywordstyle={[1]\stilecomandoa},
    keywordstyle={[2]\stilecomandob},
    keywordstyle={[3]\stilecomandoa},
    commentstyle=\stilecommenti,
    stringstyle=\stilestringa,
    showstringspaces=false, 
    keepspaces=true, 
    sensitive=false,
    breaklines=true,
    breakindent=0pt,
    aboveskip=-4pt plus 2pt minus 2pt,
    belowskip=-4pt plus 2pt minus 2pt,
    inputencoding=utf8/latin1
}

\newtcblisting{sas}{%
    listing only,
    enhanced,
    opacityfill=0,
    left=0mm,
    boxsep=0pt,
    boxrule=0pt,
    listing engine=listings,
    listing options={%
        style=saslst,            
        basicstyle=\relsize{0}\ttfamily
        }
}

\begin{document} 
\ifthenelse{\boolean{publicedition}}{%
this works
}{%
and this works
}

\setbox0=\hbox{%
\begin{sas}
this doesn't work
\end{sas}
}
\setbox2=\hbox{%
\begin{sas}
and this doesn't work
\end{sas}
}

\ifthenelse{\boolean{publicedition}}{\copy0}{\copy2}


\end{document}

在此处输入图片描述

相关内容