summaryrefslogtreecommitdiff
path: root/macros/generic/expkv-bundle/preamble-enverb.tex
diff options
context:
space:
mode:
Diffstat (limited to 'macros/generic/expkv-bundle/preamble-enverb.tex')
-rw-r--r--macros/generic/expkv-bundle/preamble-enverb.tex348
1 files changed, 348 insertions, 0 deletions
diff --git a/macros/generic/expkv-bundle/preamble-enverb.tex b/macros/generic/expkv-bundle/preamble-enverb.tex
new file mode 100644
index 0000000000..22f39cd31c
--- /dev/null
+++ b/macros/generic/expkv-bundle/preamble-enverb.tex
@@ -0,0 +1,348 @@
+\RequirePackage{expkv-def}
+
+\ExplSyntaxOn
+\cs_new_eq:NN \enverb@count \tl_count:n
+\cs_set:Npx \enverb@othercr { \char_generate:nn {13} {12} }
+\ExplSyntaxOff
+%% key setup
+\ekvdefinekeys{enverb}
+ {
+ boolTF auto-ignore = \enverb@ifautoignore
+ ,initial auto-ignore
+ ,protected code ignore = \let\enverb@ifautoignore\@secondoftwo
+ ,eint more-ignore = \enverb@moreignore
+ ,initial more-ignore = 2
+ ,also eint ignore = \enverb@ignore
+ ,boolTF same-line = \enverb@ifsameline
+ ,unknown-choice same-line =
+ \let\enverb@ifsameline\@firstoftwo\edef\enverb@codeshare{\unexpanded{#1}}
+ ,initial same-line = 0.75
+ ,invboolTF other-line = \enverb@ifsameline
+ ,nmeta below = {same-line=false, no-aboveskip, no-belowskip}
+ ,nmeta undo-below = {same-line=true, aboveskip, belowskip}
+ ,store same-line-lst = \enverb@options@lst@same
+ ,store same-line-tcb = \enverb@options@tcb@same
+ ,initial same-line-lst = {aboveskip=0pt,belowskip=0pt}
+ ,initial same-line-tcb = {nobeforeafter,box align=center}
+ ,store other-line-lst = \enverb@options@lst@other
+ ,store other-line-tcb = \enverb@options@tcb@other
+ ,meta slst = same-line-lst={#1}
+ ,meta stcb = same-line-tcb={#1}
+ ,meta olst = other-line-lst={#1}
+ ,meta otcb = other-line-tcb={#1}
+ ,store lst = \enverb@options@lst
+ ,store tcb = \enverb@options@tcb
+ ,long store bol = \enverb@bol@content
+ ,long store eol = \enverb@eol@content
+ ,einitial eol = \enverb@othercr
+ ,boolTF no-lst = \enverb@ifno@lst
+ ,also nmeta no-lst = below
+ ,boolTF no-tcb = \enverb@ifno@tcb
+ ,also nmeta no-tcb = below
+ ,nmeta undo-no-tcb = {no-tcb=false, undo-below}
+ ,store inter = \enverb@inter
+ ,data gappend = \enverb@append
+ ,dataT pre-tcb = \enverb@pretcb
+ ,store after = \enverb@after
+ ,nmeta store = gappend=\enverb@store
+ ,noval no-store = \let\enverb@append\@secondoftwo
+ ,nmeta restore = {pre-tcb=\enverb@store,after=\enverb@clear@store}
+ ,code aboveskip = \edef\enverb@aboveskip{\vskip\unexpanded{#1}\relax}
+ ,code belowskip = \edef\enverb@belowskip{\vskip\unexpanded{#1}\relax}
+ ,default aboveskip = \medskipamount
+ ,default belowskip = \medskipamount
+ ,initial aboveskip
+ ,initial belowskip
+ ,noval no-aboveskip = \let\enverb@aboveskip\@empty
+ ,noval no-belowskip = \let\enverb@belowskip\@empty
+ }
+\protected\long\ekvsetdef\enverbsetup{enverb}
+\protected\def\enverb@clear@store{\global\let\enverb@store\@empty}
+\enverb@clear@store
+
+%% start of nested environments
+\newcommand\enverb@tcb
+ {%
+ \expanded
+ {%
+ \noexpand\begin{exresult}%
+ [{%
+ \enverb@options@tcb,%
+ \enverb@ifsameline\enverb@options@tcb@same\enverb@options@tcb@other
+ }]%
+ }%
+ {\linewidth\enverb@ifsameline{-\enverb@codeshare\linewidth}{}}%
+ }
+\newcommand\enverb@lst
+ {%
+ \expanded
+ {%
+ \noexpand\begin{lstlisting}%
+ [{%
+ \enverb@options@lst,%
+ \enverb@ifsameline\enverb@options@lst@same\enverb@options@lst@other
+ }]%
+ }%
+ }
+
+%% auxiliary error function
+\newcommand\enverb@error[1]
+ {%
+ \GenericError
+ {(enverb)\@spaces\@spaces\@spaces\@spaces}%
+ {Environment enverb error: #1}%
+ {Just use it correctly!}%
+ {Read the sources.}%
+ }
+
+%% setup for weird category code regime
+\begingroup
+\lccode`\~=`\^^M
+\catcode`\:=13
+\lccode`\:=`\ % <- space
+\catcode`\;=13
+\lccode`\;=`\^^I % <- tab
+\lowercase{\endgroup
+%% code for spaces and CR
+\def\enverb@body@space{}%
+\def\enverb@body@tab{}%
+\def\enverb@body@newline#1~%
+ {\enverb@ifnotend{#1}{\enverb@bol\unexpanded{#1}\enverb@eol~}}%
+%% activate the category code regime of the body
+\protected\def\enverb@body@setup
+ {%
+ \let\enverb@collected@body\@empty
+ \let\do\@makeother\dospecials
+ \catcode`\^^M=13 \let~\enverb@body@newline
+ \catcode`\ =13 \let:\enverb@body@space
+ \catcode`\^^I=13 \let;\enverb@body@tab
+ \let\enverb@bol\relax
+ \let\enverb@eol\relax
+ }
+%% check for optional argument
+\newcommand\enverb@search@oarg@a
+ {%
+ \ifx:\next
+ \ifenverb@firsteol
+ \else
+ \enverb@body@add{:}%
+ \fi
+ \let\next\enverb@search@oarg@b
+ \else
+ \ifx~\next
+ \ifenverb@firsteol
+ \enverb@firsteolfalse
+ \else
+ \enverb@body@add{~}%
+ \fi
+ \let\next\enverb@search@oarg@b
+ \else
+ \ifx[\next\@gobble]%
+ \let\next\enverb@oarg
+ \else
+ \ifenverb@firsteol
+ \let\next\enverb@body@after@begin
+ \else
+ \let\next\enverb@body
+ \fi
+ \fi
+ \fi
+ \fi
+ \next
+ }
+%% start body collection
+\newcommand\enverb@body
+ {\edef\enverb@collected@body{\iffalse}\fi\expandafter~\enverb@collected@body}
+%% check the line after an oarg
+\def\enverb@body@after@oarg#1~%
+ {\enverb@ensure@blank{#1}{closing bracket}\enverb@body}
+%% check the line after the \begin statement
+\def\enverb@body@after@begin#1~%
+ {\enverb@ensure@blank{#1}{\string\begin}\enverb@body}
+}
+%% quick check for empty line
+\newcommand\enverb@ensure@blank[2]
+ {%
+ \expandafter\enverb@ifempty\expanded{{#1}}{}%
+ {%
+ \expanded{%
+ \noexpand\enverb@error
+ {%
+ Line after #2 not empty.\noexpand\MessageBreak
+ Contains: \detokenize\expandafter{\romannumeral`\^^@#1}%
+ }%
+ }%
+ }%
+ }
+%% quick check for empty argument
+\newcommand\enverb@ifempty[1]
+ {%
+ \enverb@ifempty@\enverb@ifempty@A#1\enverb@ifempty@B.\enverb@ifempty@true
+ \enverb@ifempty@A\enverb@ifempty@B
+ }
+\def\enverb@ifempty@#1\enverb@ifempty@A\enverb@ifempty@B#2#3{#3}
+\def\enverb@ifempty@true\enverb@ifempty@A\enverb@ifempty@B#1#2{#1}
+\newcommand\enverb@gadd[2]{\xdef#1{\unexpanded\expandafter{#1#2}}}
+\newcommand\enverb@body@add[1]
+ {%
+ \edef\enverb@collected@body
+ {\unexpanded\expandafter{\enverb@collected@body#1}}%
+ }
+% start of environment `enverb'
+\newcommand\enverb
+ {%
+ \begingroup
+ \def\tmp{enverb}%
+ \expandafter
+ \endgroup
+ \expandafter\enverb@ifnotend@setup@perhaps\expanded
+ {{\string{\@currenvir\string}}}%
+ \begingroup
+ \enverb@body@setup
+ \enverb@firsteoltrue
+ \let\enverb@collected@oarg\@empty
+ \enverb@search@oarg
+ }
+\newif\ifenverb@firsteol
+\newcommand\enverb@search@oarg{\futurelet\next\enverb@search@oarg@a}
+\newcommand\enverb@search@oarg@b{\expandafter\enverb@search@oarg\@gobble}
+\newcommand\enverb@oarg{\endgroup\enverb@oarg@}
+\NewDocumentCommand\enverb@oarg@{O{}}
+ {%
+ \edef\enverb@collected@oarg{\unexpanded{#1}}%
+ \begingroup
+ \enverb@body@setup
+ \enverb@body@after@oarg
+ }
+\def\enverb@ifnotend#1%
+ {%
+ \def\enverb@ifnotend##1%
+ {%
+ \enverb@ifnotend@
+ ##1\enverb@mark\enverb@ifnotend@maybe
+ #1\enverb@mark\@thirdofthree
+ \enverb@stop
+ }%
+ \def\enverb@ifnotend@##1#1##2\enverb@mark##3##4\enverb@stop{##3{##1}{##2}}%
+ }
+\expandafter\enverb@ifnotend\expanded{{\expandafter\@gobble\string\\end}}
+\newcommand\enverb@ifnotend@maybe[2]
+ {\expandafter\enverb@ifnotend@perhaps\expandafter{\romannumeral`\^^@#2}{#1}}
+\newcommand\enverb@ifnotend@setup@perhaps[1]
+ {%
+ \def\enverb@ifnotend@perhaps##1%
+ {%
+ \enverb@ifnotend@perhaps@\enverb@mark##1\enverb@mark\enverb@ifnotend@end
+ \enverb@mark#1\enverb@mark\@thirdofthree
+ \enverb@stop
+ }%
+ \def\enverb@ifnotend@perhaps@
+ ##1\enverb@mark#1##2\enverb@mark##3##4\enverb@stop
+ {##3{##2}}%
+ }
+\providecommand\@thirdofthree[3]{#3}
+\outer\def\myabsolutestop{\stop}
+\newcommand\enverb@ifnotend@end[3]
+ {%
+ \iffalse{\fi}%
+ \enverb@ensure@blank{#1}{\string\end}%
+ \expanded
+ {%
+ \endgroup
+ \enverbsetup
+ {\unexpanded\expandafter{\enverb@collected@oarg}}%
+ \noexpand\enverb@output
+ {\unexpanded\expandafter{\enverb@collected@body}}%
+ }%
+ {#2}%
+ \expandafter\end\expandafter{\@currenvir}%
+ }
+\long\def\enverb@output#1#2%
+ {%
+ \enverb@ifautoignore
+ {\enverb@setup@ignore{\enverb@count{#2}+\enverb@moreignore}}%
+ {\enverb@setup@ignore\enverb@ignore}%
+ \edef\enverb@line##1\enverb@eol
+ {%
+ \noexpand\detokenize{##1}%
+ \noexpand\unexpanded{\unexpanded\expandafter{\enverb@eol@content}}%
+ }%
+ \edef\enverb@collected@body{#1}%
+ \expanded
+ {\unexpanded{\enverb@append\enverb@gadd\@gobble}\expandafter}%
+ \expandafter{\enverb@collected@body}%
+ \par
+ \enverb@aboveskip
+ \enverb@ifno@lst{}%
+ {%
+ \enverb@ifsameline
+ {\noindent\begin{minipage}[c]{\enverb@codeshare\linewidth}}%
+ {}%
+ \begingroup
+ \everyeof{\noexpand}%
+ \expandafter
+ \endgroup
+ \scantokens\expanded
+ {{%
+ \noexpand\csname enverb@lst\endcsname
+ \enverb@othercr
+ \enverb@collected@body
+ \string\end{lstlisting}\enverb@othercr
+ }}%
+ \enverb@ifsameline{\end{minipage}}{}%
+ }%
+ \enverb@inter
+ \enverb@ifno@tcb{}%
+ {%
+ \begingroup
+ \everyeof{\noexpand}%
+ \newlinechar=\endlinechar
+ \expandafter
+ \endgroup
+ \scantokens\expanded
+ {{%
+ \noexpand\csname enverb@tcb\endcsname
+ \enverb@pretcb{\unexpanded\expandafter}%
+ \enverb@collected@body
+ \noexpand\end{exresult}%
+ }}%
+ }%
+ \par
+ \enverb@belowskip
+ \enverb@after
+ \@endpetrue
+ }
+\providecommand\@firstofnine[9]{#1}
+\newcommand\enverb@setup@ignore[1]
+ {\expandafter\enverb@setup@ignore@\the\numexpr#1\relax;\enverb@line}
+\def\enverb@setup@ignore@#1;#2%
+ {%
+ \ifnum#1>9
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {\expandafter\enverb@setup@ignore@\the\numexpr#1-8;{\@firstofnine{#2}}}%
+ {%
+ \let\enverb@bol@gobble\@empty % just so that renewcommand doesn't go nuts
+ \expanded
+ {%
+ \unexpanded{\renewcommand\enverb@bol@gobble}\ifnum#1>\z@[#1]\fi
+ {%
+ \noexpand\unexpanded
+ {\unexpanded\expandafter{\enverb@bol@content}}%
+ \unexpanded{#2}%
+ }%
+ \unexpanded{\def\enverb@bol##1\enverb@eol}%
+ {%
+ \noexpand\unexpanded
+ {\unexpanded\expandafter{\enverb@bol@content}}%
+ \unexpanded{\expandafter\enverb@ifempty\expanded}{{##1}}%
+ {\noexpand\enverb@line}%
+ {\noexpand\enverb@bol@gobble}%
+ ##1\unexpanded{\enverb@eol}%
+ }%
+ }%
+ }%
+ }
+\let\endenverb\@empty