From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/multienv/README | 35 ++ macros/latex/contrib/multienv/multienv.dtx | 548 +++++++++++++++++++++++++++++ macros/latex/contrib/multienv/multienv.ins | 10 + macros/latex/contrib/multienv/multienv.pdf | Bin 0 -> 207894 bytes 4 files changed, 593 insertions(+) create mode 100644 macros/latex/contrib/multienv/README create mode 100644 macros/latex/contrib/multienv/multienv.dtx create mode 100644 macros/latex/contrib/multienv/multienv.ins create mode 100644 macros/latex/contrib/multienv/multienv.pdf (limited to 'macros/latex/contrib/multienv') diff --git a/macros/latex/contrib/multienv/README b/macros/latex/contrib/multienv/README new file mode 100644 index 0000000000..69cfafc754 --- /dev/null +++ b/macros/latex/contrib/multienv/README @@ -0,0 +1,35 @@ +LaTeX package 'multienv' +======================== +Copyright (c) 2012 by Martin Scharrer +CTAN: +Code repository: + +This package provides a multienv environment which allows to easily +add multiple environments using a key=value syntax. Macros to define +environments using this syntax are also provided. + +Example: +-------- + +The following 'multienv' environment: + + \begin{multienv}{enva,envb=arg,add code={code before}{code after}, + envc=[oarg]{marg}} + content + \end{multienv} + +is basically identical to: + + \begin{enva} + \begin{envb}{arg} + code before + \begin{enc}[oarg]{marg} + content + \end{enc} + code after + \end{envb} + \end{enva} + +except that actually the "plain" form together with explicit groups +is used: \begingroup\enva .. \endenva\endgroup. + diff --git a/macros/latex/contrib/multienv/multienv.dtx b/macros/latex/contrib/multienv/multienv.dtx new file mode 100644 index 0000000000..7c3c021826 --- /dev/null +++ b/macros/latex/contrib/multienv/multienv.dtx @@ -0,0 +1,548 @@ +% \iffalse meta-comment +%<=*COPYRIGHT> +%% Copyright (C) 2012 by Martin Scharrer +%% -------------------------------------------------------------------- +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, 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 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Martin Scharrer. +%% +%% This work consists of the files multienv.dtx and multienv.ins +%% and the derived filebase multienv.sty. +%% +%<=/COPYRIGHT> +% \fi +% +% \iffalse +%<*driver> +\ProvidesFile{multienv.dtx}[% +%<=*DATE> + 2012/05/20 +%<=/DATE> +%<=*VERSION> + v1.0 +%<=/VERSION> + DTX file for multienv.sty] +\documentclass{ydoc} +\GetFileInfo{multienv.dtx} +\usepackage{multienv}[\filedate] +\providecommand\enquote[1]{``#1''} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\OnlyDescription +\optionaloff +\begin{document} + \DocInput{\jobname.dtx} + \PrintChanges + \PrintIndex +\end{document} +% +% \fi +% +% \CheckSum{297} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% +% \changes{v1.0}{2012/05/20}{First release.} +% +% \DoNotIndex{\newcommand,\newenvironment} +% +% \GetFileInfo{multienv.dtx} +% \author{Martin Scharrer} +% \email{martin@scharrer-scharrer.de} +% \ifdefined\repository +% \repository{https://bitbucket.org/martin_scharrer/multienv} +% \fi +% +% \maketitle +% +% \begin{abstract}\noindent +% This package provides a \env{multienv} environment which allows to +% easily add multiple environments using a key=value syntax. +% Macros to define environments using this syntax are also provided. +% \end{abstract} +% +% \section{Introduction} +% It is sometimes required to add multiple environments around some text +% in order to achieve a specific format. This macro simplifies this task +% especially for larger number of environments by allowing the environments +% and their arguments to be specified using a key=value syntax. +% A special \Key{add code} key is also provided to allow arbitrary code being +% added before and after the environment content. +% Furthermore macros are provided to allow the definition of new environments +% which contain multiple other environments and code. +% +% \section{Usage} +% \vspace{-3ex} +% \DescribeEnv[]{multienv}{',',\ldots} +% This environment takes a comma separated list of key=values where the keys are usually environment +% names and the values the arguments to this environment. +% The environments are added around the content in the given order, i.e.\ the first environment +% is the most outer one and further environments are placed inside it. +% +% At the moment only the following key is defined. Any other key is taken as an environment name. +% +% \DescribeKey{add code}={}{} +% This adds the given code before and after the content. +% Any code is permitted including macro argument tokens like `|#1|'. +% +% \DescribeKey{\meta{environment}} +% \DescribeKey{\meta{environment}}= +% Any unknown key is taken as environment name and the value as argument(s) to the environment. +% If the value does not start with a brace `|{|', bracket `|[|' or angle `|<|' it is taken +% as a single mandatory argument and is placed inside braces after the environment, +% otherwise it is placed unchanged after the environment: +% \par\medskip\par\noindent +% \begin{tabular}{@{}l@{ $\Rightarrow$ }l@{}} +% \Key{\meta{env}} & \Macro\begin{}\ldots\Macro\end{} \\ +% \Key{\meta{env}}= & \Macro\begin{}\ldots\Macro\end{} \\ +% \Key{\meta{env}}= & \Macro\begin{}{}\ldots\Macro\end{} \\ +% \Key{\meta{env}}={} & \Macro\begin{}{}\ldots\Macro\end{} \\ +% \Key{\meta{env}}={}{} & \Macro\begin{}{}{}\ldots\Macro\end{} \\ +% \Key{\meta{env}}=[] & \Macro\begin{}[]\ldots\Macro\end{} \\ +% \Key{\meta{env}}=[]{} & \Macro\begin{}[]{}\ldots\Macro\end{} \\ +% \Key{\meta{env}}=<< >> & \Macro\begin{}<< >>\ldots\Macro\end{} \\ +% \Key{\meta{env}}=<< >>{} & \Macro\begin{}<< >>{}\ldots\Macro\end{} \\ +% \multicolumn{2}{@{}l@{}}{etc.} \\ +% \end{tabular} +% \par\bigskip\par +% +% \DescribeEnv[]{multienv*}{',',\ldots} +% This environment is identical to \env{multienv} but will apply the keys in the reverse order, +% i.e.\ every environment or code is added around the existing environments or code. +% +% +% \DescribeMacro\newmultienvironment{}[][]{,\ldots} +% This macro defines a new environment like \Macro\newenvironment does but uses the \env{multienv} +% syntax. The resulting environment will contain all given environments and code. +% The environment can have arguments including one leading optional argument. +% The arguments can be used as part of the keys and values. +% It should be noted that it is not allowed to use arguments in the second argument of +% the \Key{add code} key, because that code will be part of \Macro\end{}. +% +% An error is raised if the environment already exists. +% +% \DescribeMacro\renewmultienvironment{}[][]{,\ldots} +% Like \Macro\newmultienvironment but can be used to redefine existing environments. +% It is is not relevant \emph{how} the environment was defined previously. +% An error is raised if the environment does not already exist. +% +% +% \DescribeMacro\providemultienvironment{}[][]{,\ldots} +% Like \Macro\newmultienvironment but the environment is only defined if it is not already defined. +% The environment is also not defined if there a macro with the same name exists. +% +% \section{Examples} +% \lstset{gobble=4,language=[latex]tex} +% The following \env{multienv} environment usage: +% \begin{lstlisting} +% \begin{multienv}{enva,envb=arg,add code={code before}{code after}, +% envc=[oarg]{marg}} +% content +% \end{multienv} +% \end{lstlisting} +% \noindent is basically identical to: +% \begin{lstlisting} +% \begin{enva} +% \begin{envb}{arg} +% code before +% \begin{enc}[oarg]{marg} +% content +% \end{enc} +% code after +% \end{envb} +% \end{enva} +% \end{lstlisting} +% \noindent Using \env{multienv*} the order the environments can be given in the opposite order: +% \begin{lstlisting} +% \begin{multienv}{envc=[oarg]{marg},add code={code before}{code after}, +% envb=arg,enva} +% content +% \end{multienv} +% \end{lstlisting} +% +% \par\bigskip\par\noindent +% The following code defines a \env{centeredminipage} environment which content is placed +% in a centered \env{minipage} which inner content is also centered. +% \begin{lstlisting} +% \newmultienvironment{centeredminipage}[1] +% {center,minipage=#1,add code={\centering}{}} +% \end{lstlisting} +% \par\noindent +% This is basically identical to:\par +% \begin{lstlisting} +% \newenvironment{centeredminipage}[1] +% {\begin{center}\begin{minipage}{#1}\centering} +% {\end{minipage}\end{center}} +% \end{lstlisting} +% \par\noindent +% However actually the \enquote{plain} form of the environment are used, because it is more efficient +% and will also produce a correct error message if an incorrect \cs{end} macro is found:\par +% \begin{lstlisting} +% \newenvironment{centeredminipage}[1] +% {\begingroup\center\begingroup\minipage{#1}\centering} +% {\endminipage\endgroup\endcenter\endgroup} +% \end{lstlisting} +% \par\noindent +% The groups are added because some environments require to be placed in a group by themselves, +% which is normally done by |\begin| and |\end|. +% +% \StopEventually{} +% \clearpage +% \section{Implementation} +% +% \iffalse +%<*multienv.sty> +% \fi +% \begin{macrocode} +% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesPackage{multienv}[% +% +% +%<*DRIVER> + 2099/01/01 develop +% + Add multiple environments using a Key=value syntax] +% \end{macrocode} +% +% +% \begin{macro}{\multienv} +% \begin{macrocode} +\newcommand{\multienv}{% + \begingroup + \@ifstar{% + \let\multienv@addcode\multienv@addcode@out + \multienv@readkeys + }{% + \let\multienv@addcode\multienv@addcode@in + \multienv@readkeys + }% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\endmultienv} +% \begin{macrocode} +\def\endmultienv{\end@multienv\endgroup} +% \end{macrocode} +% \end{macro} +% +% +% \begin{environment}{multienv*} +% \begin{macrocode} +\newenvironment{multienv*}{% + \begingroup + \let\multienv@addcode\multienv@addcode@out + \multienv@readkeys +}{% + \end@multienv\endgroup +} +% \end{macrocode} +% \end{environment} +% +% +% \begin{macro}{\newmultienvironment} +% \begin{macrocode} +\newcommand\newmultienvironment{% + \let\@multi@environment\newenvironment + \@multienvironment +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\renewmultienvironment} +% \begin{macrocode} +\newcommand\renewmultienvironment{% + \let\@multi@environment\renewenvironment + \@multienvironment +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\providemultienvironment} +% \begin{macrocode} +\newcommand\providemultienvironment{% + \@ifstar + {\@providemultienvironment*}% + {\@providemultienvironment{}}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@providemultienvironment} +% \begin{macrocode} +\def\@providemultienvironment#1#2{% + \@ifundefined{#2}% + {\newmultienvironment#1{#2}}% + {\begingroup\tracingall\renewcommand\@tempa[1][]{\renewcommand\@tempa[1][]{\expandafter\endgroup\@gobble}\@tempa}\@tempa}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@multienvironment} +% \begin{macrocode} +\def\@multienvironment{% + \@ifstar{% + \let\multienv@addcode\multienv@addcode@out + \newmultienvironment@marg + }{% + \let\multienv@addcode\multienv@addcode@in + \newmultienvironment@marg + }% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\newmultienvironment@marg} +% \begin{macrocode} +\long\def\newmultienvironment@marg#1{% + \@testopt{\newmultienvironment@oarg{#1}}{[0]}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\newmultienvironment@oarg} +% \begin{macrocode} +\long\def\newmultienvironment@oarg#1[#2]{% + \@ifnextchar[{% + \newmultienvironment@oargb{#1}{#2}% + }{% + \newmultienvironment@def{#1}{[#2]}% + }% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\newmultienvironment@oargb} +% \begin{macrocode} +\long\def\newmultienvironment@oargb#1#2[#3]{% + \newmultienvironment@def{#1}{[#2][#3]}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\newmultienvironment@def} +% \begin{macrocode} +\long\def\newmultienvironment@def#1#2#3{% + \begingroup + \multienv@readkeys@{#3}% + \def\@tempa{\@multi@environment*{#1}#2}% + \@temptokena\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter{\expandafter\begin@multienv\expandafter}\expandafter{\end@multienv}}% + \expandafter\expandafter\expandafter + \endgroup + \expandafter\@tempa\the\@temptokena +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multienv@readkeys} +% \begin{macrocode} +\long\def\multienv@readkeys#1{% + \multienv@readkeys@{#1}% + \begin@multienv +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multienv@readkeys@} +% \begin{macrocode} +\long\def\multienv@readkeys@#1{% + \let\begin@multienv\@empty + \let\end@multienv\@empty + \multienv@readkeyval#1,\@nnil,\@nnil +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\let\begin@multienv\@empty +\let\end@multienv\@empty +% \end{macrocode} +% +% \begin{macro}{\multienv@readkeyval} +% \begin{macrocode} +\long\def\multienv@readkeyval#1,{% + \ifx\@nnil#1\relax + \expandafter\@gobble + \else + \multienv@sepkeyval#1=\@nnil=\@nnil\relax + \expandafter\multienv@readkeyval + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multienv@sepkeyval} +% \begin{macrocode} +\long\def\multienv@sepkeyval#1=#2={% + \ifx\@nnil#2\relax + \multienv@handlekeyval{#1}{}% + \expandafter\@gobble + \else + \multienv@handlekeyval{#1}{#2}% + \expandafter + \@gobblefour + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multienv@handlekeyval} +% \begin{macrocode} +\long\def\multienv@handlekeyval#1#2{% + \@ifundefined{multienv@key@#1}{% + \multienv@addenv{#1}{#2}% + }{% + \@nameuse{multienv@key@#1}#2\@nnil + }% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multienv@addenv} +% \begin{macrocode} +\long\def\multienv@addenv#1#2{% + \@ifnextchar\bgroup{% + \multienv@@addenv + }{% + \ifcase0% + \expandafter\ifx\csname @let@token\endcsname\@nnil1\else + \expandafter\ifx\csname @let@token\endcsname[1\else + \expandafter\ifx\csname @let@token\endcsname<1\fi\fi\fi + \relax + \expandafter\multienv@@addenv@ + \else + \expandafter\multienv@@addenv + \fi + }#2\@nnil{#1}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multienv@@addenv@} +% \begin{macrocode} +\long\def\multienv@@addenv@#1\@nnil{% + \multienv@@addenv{{#1}}\@nnil +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multienv@@addenv} +% \begin{macrocode} +\long\def\multienv@@addenv#1\@nnil#2{% + \multienv@addcode{\multi@env{#2}#1}{\endmulti@env{#2}}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multi@env} +% \begin{macrocode} +\long\def\multi@env#1{% + \begingroup + \@ifundefined{#1}% + {\@latex@error{Environment #1 undefined}\@eha}% + {\csname #1\endcsname}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\endmulti@env} +% \begin{macrocode} +\def\endmulti@env#1{\csname end#1\endcsname\endgroup} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multienv@addcode@out} +% \begin{macrocode} +\long\def\multienv@addcode@out#1#2{% + \@temptokena{#1}% + \@temptokena\expandafter\expandafter\expandafter{\expandafter\the\expandafter\@temptokena\begin@multienv}% + \edef\begin@multienv{\the\@temptokena}% + \@temptokena\expandafter{\end@multienv#2}% + \edef\end@multienv{\the\@temptokena}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multienv@addcode@in} +% \begin{macrocode} +\long\def\multienv@addcode@in#1#2{% + \@temptokena\expandafter{\begin@multienv#1}% + \edef\begin@multienv{\the\@temptokena}% + \@temptokena{#2}% + \@temptokena\expandafter\expandafter\expandafter{\expandafter\the\expandafter\@temptokena\end@multienv}% + \edef\end@multienv{\the\@temptokena}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\multienv@key@add} +% \begin{macrocode} +\long\@namedef{multienv@key@add code}#1\@nnil{% +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} + \multienv@addcode#1{}{}% +} +% \end{macrocode} +% +% \begin{macro}{\multienv@key@adjustbox} +% \begin{macrocode} +\long\@namedef{multienv@key@adjustbox}#1\@nnil{% + \multienv@addcode{\csname adjustbox@noindent\endcsname\adjustbox{#1}\bgroup\ignorespaces}{\ifhmode\unskip\fi\egroup}% +} +% \end{macrocode} +% \end{macro} +% +% \iffalse +% +% \fi +% +% \Finale +\endinput diff --git a/macros/latex/contrib/multienv/multienv.ins b/macros/latex/contrib/multienv/multienv.ins new file mode 100644 index 0000000000..29da38404f --- /dev/null +++ b/macros/latex/contrib/multienv/multienv.ins @@ -0,0 +1,10 @@ +\input ydocstrip.tex +\keepsilent +\askforoverwritefalse + +\generate{% + \file{multienv.sty}{\nopreamble\from{multienv.dtx}{multienv.sty}}% +} +\endbatchfile + +%% vim: ft=tex diff --git a/macros/latex/contrib/multienv/multienv.pdf b/macros/latex/contrib/multienv/multienv.pdf new file mode 100644 index 0000000000..cd9d99ea7c Binary files /dev/null and b/macros/latex/contrib/multienv/multienv.pdf differ -- cgit v1.2.3