From eb0188be025e61dd6da473e22b9842cd22adf2ce Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 18 Oct 2018 20:29:35 +0000 Subject: grabbox (18oct18) git-svn-id: svn://tug.org/texlive/trunk@48933 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/latex/grabbox/grabbox.dtx | 385 +++++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100644 Master/texmf-dist/source/latex/grabbox/grabbox.dtx (limited to 'Master/texmf-dist/source/latex') diff --git a/Master/texmf-dist/source/latex/grabbox/grabbox.dtx b/Master/texmf-dist/source/latex/grabbox/grabbox.dtx new file mode 100644 index 00000000000..66a814cb724 --- /dev/null +++ b/Master/texmf-dist/source/latex/grabbox/grabbox.dtx @@ -0,0 +1,385 @@ +% \iffalse meta-comment +% +% File: grabbox.dtx Copyright (C) 2018 Jonathan P. Spratte +% +% It may be distributed and/or modified under the conditions of the LaTeX +% Project Public License (LPPL), either version 1.3c of this license or (at your +% option) any later version. The latest version of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% ------------------------------------------------------------------------------ +% +%<*driver> +\def\nameofplainTeX{plain} +\ifx\fmtname\nameofplainTeX\else + \expandafter\begingroup +\fi +\input l3docstrip.tex +\askforoverwritefalse +\preamble + +-------------------------------------------------------------- +grabbox -- utilities to get an argument as a box +E-mail: jspratte@yahoo.de +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt +-------------------------------------------------------------- + +Copyright (C) 2018 Jonathan P. Spratte + +This work may be distributed and/or modified under the conditions of the +LaTeX Project Public License (LPPL), either version 1.3c of this license or +(at your option) any later version. The latest version of this license is in +the file: + + http://www.latex-project.org/lppl.txt + +This work is "maintained" (as per LPPL maintenance status) by + Jonathan P. Spratte. + +This work consists of the file grabbox.dtx +and the derived files grabbox.pdf and + grabbox.sty. + +\endpreamble +% stop docstrip adding \endinput +\postamble +\endpostamble +\generate{\file{grabbox.sty}{\from{grabbox.dtx}{pkg}}} +\ifx\fmtname\nameofplainTeX + \expandafter\endbatchfile +\else + \expandafter\endgroup +\fi +% +% +%<*driver> +\ProvidesFile{grabbox.dtx} + [% + \csname grabbox@date\endcsname\ + utilities to get an argument as a box% + ] +\expandafter\def\csname @classoptionslist\endcsname{} +\RequirePackage[british]{babel} +\documentclass{l3doc} +\usepackage{duckuments} +\usepackage{microtype} +\usepackage{grabbox} +\renewcommand*{\thefootnote}{\fnsymbol{footnote}} +\let\metaOrig\meta +\renewcommand\meta[1] + {% + \texttt{\metaOrig{#1}}% + } +\begin{document} + \DocInput{grabbox.dtx} +\end{document} +% +%<*pkg> +\newcommand*\grabbox@date{2018-10-18} +\newcommand*\grabbox@version{1.0b} +\ProvidesPackage{grabbox} + [\grabbox@date\ v\grabbox@version\ utilities to get an argument as a box] +% +% \fi +% +% \begin{center} +% \LARGE The \pkg{grabbox} package\\[\bigskipamount] +% \large +% \setcounter{footnote}{1}% +% Jonathan P. Spratte\footnotemark\\[\medskipamount] +% Version \csname grabbox@version\endcsname\\[\smallskipamount] +% Released \csname grabbox@date\endcsname +% \end{center} +% \footnotetext{E-mail: jspratte@yahoo.de} +% +% \tableofcontents +% +% \begin{documentation} +% +% \section{Introduction} +% +% Sometimes I happen to write macros and environments which don't care for the +% exact contents of an argument but only for that contents typeset +% representation and its dimensions. In that case I personally dislike the fact +% that those arguments couldn't contain verbatim material if coded straight +% forward. Thus the macros distributed hereby came into existence. +% +% This package provides \cs{grabbox} to grab an argument inside of a box. The +% used mechanism allows category code changes in that argument as long as it is +% used in a place allowing category code changes (so not inside of another +% argument). +% +% It is written as a docstrip file: executing |latex grabbox.dtx| generates the +% \file{grabbox.sty} file and typesets this documentation; execute +% |tex grabbox.dtx| to only generate \file{grabbox.sty}. +% +% \section{Acknowledgement} +% +% I want to thank Enrico Gregorio for helping me develop first versions of the +% used mechanisms for the second iteration of my \pkg{ducksay} package. If he +% hadn't helped me back then, I wouldn't have considered the used method +% further -- because the user interface would've been too clumsy and require +% strange markup like |\foo arg}| -- and therefore this package wouldn't have +% been created. +% +% \section{The macro} +% +% \begin{function}{\grabbox} +% \begin{syntax} +% \cs{grabbox}\meta{*}\marg{box register}\ignorespaces^^A +% \oarg{inject pre}\marg{box type}\oarg{inject post}\ignorespaces^^A +% \marg{afterwards} +% \end{syntax} +% grabs the next braced argument and stores it inside of the box \meta{box +% register}. The box is of \meta{box type}, which should be one of \cs{hbox} +% or \cs{vbox} or \cs{vtop}. \meta{inject pre} will be injected at the +% beginning of the box and can affect its contents, \meta{inject post} will be +% injected after the box but can't be affected by stuff inside of \meta{inject +% pre}. Unless the \meta{*} is given leading and trailing spaces will be +% stripped from the box. After the box is read in \meta{afterwards} will be +% inserted. +% \end{function} +% +% \smallskip +% All assignments are made local. Currently it is not safe to nest macros +% which use \cs{grabbox}. It should become safe if your macros use +% \cs{grabbox} inside of a group, so the inner \cs{grabbox} doesn't affect the +% outer one. +% +% \cs{grabbox} uses \cs{afterassignment} and \cs{aftergroup} to do its magic. +% The former should be safe where it is used, the latter is used inside of the +% boxed argument before any contents are inserted. +% +% Since \cs{grabbox} works by setting a boxregister using \cs{setbox} (and a +% bunch of temporary macros), it is of course not expandable and defined +% \cs{protected}. Bear in mind that macros created with \cs{grabbox} are +% not expandable. +% +% \section{Useless Example!} +% +% First we need to reserve us a box register for this example: +% \begin{verbatim} +% \newsavebox\ourbox +% \end{verbatim} +% Next we define a macro which takes some arguments and uses \cs{grabbox}: +% \begin{verbatim} +% \newcommand\examplecmd[2] +% {% +% \begingroup +% \grabbox\ourbox[\itshape]\hbox[ \sffamily is]{\examplecmdOut{#1}{#2}} +% } +% \end{verbatim} +% And we need our helper macro which is executed after \cs{grabbox}: +% \begin{verbatim} +% \newcommand\examplecmdOut[3] +% {% +% \begin{tabular}[t]{@{}ll@{}} +% Arg1: & #1\\ +% Arg2: & #2\\ +% Box: & \unhbox\ourbox\\ +% Arg3: & #3 +% \end{tabular}% +% \endgroup +% } +% \end{verbatim} +% +% The result is a macro that takes two ordinary arguments, after those a +% box in horizontal mode and finally another ordinary argument. If we use this +% macro we get the following: +% \begin{center} +% \newsavebox\ourbox +% \newcommand\examplecmd[2] +% {% +% \begingroup +% \grabbox\ourbox[\itshape]\hbox[ \sffamily is]{\examplecmdOut{#1}{#2}} +% }% +% \newcommand\examplecmdOut[3] +% {% +% \begin{tabular}[t]{@{}ll@{}} +% Arg1: & #1\\ +% Arg2: & #2\\ +% Box: & \unhbox\ourbox\\ +% Arg3: & #3 +% \end{tabular}% +% \endgroup +% }% +% \examplecmd{Hi,}{my}{\verb|name|}{Steve!} +% \end{center} +% One can see that \verb|\sffamily is| of \meta{inject post} is not affected by +% the |\itshape| in \meta{inject pre}. The used code to generate that table was: +% +% \begin{verbatim} +% \examplecmd{Hi,}{my}{\verb|name|}{Steve!} +% \end{verbatim} +% +% \section{Useful Example?} +% +% This example provides a macro which typesets its mandatory argument in a block +% of a definable number of lines, it is meant for a single paragraph. +% +% \begin{verbatim} +% % Getting a box register: +% \newsavebox\RectangleBox +% % Defining the main macro: +% \newcommand\Rectangle[1][4] +% {% +% \begingroup +% \grabbox\RectangleBox\hbox +% {% +% % Since we don't want to read more arguments after the box, +% % we don't need a second macro and can put the output routine +% % here. +% \begin{minipage}{\dimexpr\wd\RectangleBox/#1\relax} +% \parfillskip0pt +% \unhbox\RectangleBox +% \end{minipage}% +% \endgroup +% }% +% } +% \end{verbatim} +% +% As you can see, this macro uses \cs{grabbox} in a group delimited by +% \cs{begingroup} and \cs{endgroup}. It should therefore be safe to nest it +% inside other macros using \cs{grabbox}. +% +% Finally a usage example of our new macro (with the \pkg{duckuments} package +% loaded): +% +% \begin{verbatim} +% \begin{center} +% \Rectangle[9]{\blindduck} +% \end{center} +% \end{verbatim} +% Results in: +% \begin{center} +% \newsavebox\RectangleBox +% \newcommand\Rectangle[1][4] +% {% +% \begingroup +% \grabbox\RectangleBox\hbox +% {% +% \begin{minipage}{\dimexpr\wd\RectangleBox/#1\relax} +% \parfillskip0pt +% \unhbox\RectangleBox +% \end{minipage}% +% \endgroup +% }% +% } +% \Rectangle[9]{\blindduck} +% \end{center} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{Implementation} +% +% \begin{macrocode} +%<*pkg> +% \end{macrocode} +% +% \begin{macrocode} +\@ifdefinable{\if@grabbox@spaces@}{\newif\if@grabbox@spaces@} +\newcommand\grabbox@def[2] + {% + \@ifdefinable#1{\protected\def#1{#2}}% + } +\newcommand\grabbox@def@step[4] + {% + \@ifdefinable#1{\protected\def#1##1{\def#2{##1}\grabbox@opt#3#4}}% + } +\long\def\grabbox@check@bracket #1[#2\endgrabbox@check@bracket + {% + \if\relax\detokenize{#2}\relax + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + } +\protected\def\grabbox@opt#1#2% + {% + \@ifnextchar[ + {\grabbox@opt@get#1#2} + {\def#1{}#2}% + } +\long\def\grabbox@opt@get#1#2#3]% + {% + \expandafter\grabbox@opt@get@a\expandafter{\@gobble#3}#1#2% + } +\protected\long\def\grabbox@opt@get@a#1#2#3% + {% + \grabbox@check@bracket #1[\endgrabbox@check@bracket + {\def#2{#1}#3} + {\grabbox@opt@get@b#2#3{#1]}}% + } +\protected\long\def\grabbox@opt@get@b#1#2#3#4]% + {% + \grabbox@check@bracket #4[\endgrabbox@check@bracket + {\def#1{#3#4}#2} + {\grabbox@opt@get@b#1#2{#3#4]}}% + } +\grabbox@def\grabbox@unpack + {% + \expandafter\ifx\grabbox@type\hbox + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + \unhbox + \unvbox + \grabbox@name + } +\grabbox@def\grabbox + {% + \@ifstar + {\@grabbox@spaces@true\grabbox@a} + {\@grabbox@spaces@false\grabbox@a}% + } +\grabbox@def@step\grabbox@a\grabbox@name\grabbox@into@pre\grabbox@b +\grabbox@def@step\grabbox@b\grabbox@type\grabbox@into@post\grabbox@c +\protected\long\def\grabbox@c#1% + {% + \def\grabbox@final{#1}% + \afterassignment\grabbox@intermediate + \setbox\grabbox@name\grabbox@type + } +\grabbox@def\grabbox@intermediate + {% + \aftergroup\grabbox@after + \grabbox@into@pre + \if@grabbox@spaces@ + \else + \ignorespaces + \fi + } +\grabbox@def\grabbox@after + {% + \if@grabbox@spaces@ + \setbox\grabbox@name\grabbox@type + {% + \grabbox@unpack + \grabbox@into@post + }% + \else + \setbox\grabbox@name\grabbox@type + {% + \grabbox@unpack + \ifhmode\unskip\fi + \grabbox@into@post + }% + \fi + \grabbox@final + } +% \end{macrocode} +% +% \begin{macrocode} +\endinput +% \end{macrocode} +% +% \end{implementation} +% +% \begin{macrocode} +% +% \end{macrocode} -- cgit v1.2.3