123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- % \iffalse meta-comment
- %
- % File: grabbox.dtx Copyright (C) 2018-2019 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-2019 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>
- %
- %<*driver>
- \ProvidesFile{grabbox.dtx}
- [%
- \csname grabbox@date\endcsname\space
- 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}
- %</driver>
- %<*pkg>
- \newcommand*\grabbox@date{2019-05-08}
- \newcommand*\grabbox@version{1.4}
- \ProvidesPackage{grabbox}
- [%
- \grabbox@date\space v\grabbox@version\space utilities to get an argument as
- a box%
- ]
- %</pkg>
- % \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 for macros. For environments this is quite easy to create thanks to
- % \env{lrbox}, for macros this approach unfortunately doesn't work without the
- % enduser's cooperation. 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.
- %
- % Additionally I want to thank David Carlisle for helping me making \cs{grabbox}
- % respect surrounding text colours.
- %
- % \section{The macro}
- %
- % \begin{function}{\grabbox}
- % \begin{syntax}
- % \cs{grabbox}\meta{*}\oarg{inject pre pre}\ignorespaces^^A
- % \marg{box register}\oarg{inject pre}\marg{box type}\ignorespaces^^A
- % \oarg{inject post}\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}. The contents of the box except for
- % \meta{inject pre pre} and \meta{inject post} will be contained in an
- % additional level of grouping to ensure colour safety (similar to \LaTeX's
- % \cs{sbox}). \meta{inject pre pre} will be injected at the beginning of the
- % box before this additional group is opened, \meta{inject pre} will be
- % injected at the beginning of the box and can affect its contents,
- % \meta{inject post} will be injected at the end of the box but can't be
- % affected by stuff inside of \meta{inject pre} or added content unless they
- % are using global definitions -- \meta{inject pre pre} however can affect the
- % contents of \meta{inject post}.
- % 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.
- % The complete contents of the box will be something like:
- % \begin{center}
- % \csname verbatim@font\endcsname
- % \meta{inject pre pre}^^A
- % \{\cs{set@color}\meta{inject pre}\meta{argument}\}^^A
- % \meta{inject post}
- % \end{center}
- % \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}.
- %
- % \begin{function}{\@grabbox}
- % \begin{syntax}
- % \cs{@grabbox}\meta{*}\marg{inject pre pre}\ignorespaces^^A
- % \marg{box register}\marg{inject pre}\marg{box type}\ignorespaces^^A
- % \marg{inject post}\marg{afterwards}
- % \end{syntax}
- % This is a variant of \cs{grabbox} that should be faster because it doesn't
- % parse for optional arguments. Instead every argument is mandatory except for
- % the star, just leave the arguments empty if you'd otherwise not use the
- % corresponding optional argument in \cs{grabbox}.
- % \end{function}
- %
- % \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| in \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} -- like the useless example. 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@nospaces@}{\newif\if@grabbox@nospaces@}
- \@ifdefinable{\grabbox@def}
- {\long\def\grabbox@def#1#2#{\grabbox@def@a{}#1{#2}}}
- \@ifdefinable{\grabbox@ldef}
- {\long\def\grabbox@ldef#1#2#{\grabbox@def@a\long#1{#2}}}
- \@ifdefinable{\grabbox@def@a}
- {%
- \protected\long\def\grabbox@def@a#1#2#3#4%
- {\@ifdefinable#2{\protected#1\def#2#3{#4}}}%
- }
- \newcommand\grabbox@def@step[4]
- {%
- \grabbox@def#1##1{\def#2{##1}\grabbox@opt#3#4}%
- }
- \grabbox@def\grabbox@opt#1#2%
- {%
- \@ifnextchar[
- {\grabbox@opt@get#1#2}
- {\def#1{}#2}%
- }
- \grabbox@ldef\grabbox@opt@get#1#2[#3]%
- {%
- \def#1{#3}#2%
- }
- \grabbox@def\grabbox@set@color
- {%
- \@ifundefined{set@color}{}
- {\global\let\grabbox@set@color\set@color\grabbox@set@color}%
- }
- \AtBeginDocument
- {%
- \@ifundefined{set@color}
- {\gdef\grabbox@set@color{}}
- {\global\let\grabbox@set@color\set@color}%
- }%
- \newcommand*\grabbox@unskip@space
- {%
- \ifhmode\unskip\fi
- }
- \grabbox@def\grabbox
- {%
- \@ifstar
- {\@grabbox@nospaces@false\grabbox@a}
- {\@grabbox@nospaces@true\grabbox@a}%
- }
- \grabbox@def\grabbox@a
- {%
- \grabbox@opt\grabbox@into@prepre\grabbox@b
- }
- \grabbox@def@step\grabbox@b\grabbox@name\grabbox@into@pre\grabbox@c
- \grabbox@def@step\grabbox@c\grabbox@type\grabbox@into@post\grabbox@d
- \grabbox@ldef\grabbox@d#1%
- {%
- \def\grabbox@final{#1}%
- \afterassignment\grabbox@intermediate
- \setbox\grabbox@name\grabbox@type
- }
- \grabbox@def\@grabbox
- {%
- \@ifstar
- {\@grabbox@nospaces@false\@grabbox@a}
- {\@grabbox@nospaces@true\@grabbox@a}%
- }
- \grabbox@ldef\@grabbox@a#1#2#3#4#5%
- {%
- \def\grabbox@into@prepre{#1}%
- \def\grabbox@name {#2}%
- \def\grabbox@into@pre {#3}%
- \def\grabbox@type {#4}%
- \def\grabbox@into@post {#5}%
- \grabbox@d
- }
- \grabbox@def\grabbox@intermediate
- {%
- \grabbox@into@prepre
- \bgroup
- \if@grabbox@nospaces@
- \aftergroup\grabbox@unskip@space
- \fi
- \grabbox@set@color
- \aftergroup\grabbox@after
- \grabbox@into@pre
- \if@grabbox@nospaces@
- \ignorespaces
- \fi
- }
- \newcommand*\grabbox@after@aux@b[1]
- {%
- \grabbox@after@aux@a
- }
- \grabbox@def\grabbox@after@aux@a
- {%
- \@ifnextchar\reset@color
- {\reset@color\grabbox@after@aux@b}
- {\egroup\grabbox@final}%
- }
- \grabbox@def\grabbox@after
- {%
- \grabbox@into@post
- \endgraf
- \grabbox@after@aux@a
- }
- % \end{macrocode}
- %
- % \begin{macrocode}
- \endinput
- % \end{macrocode}
- %
- % \end{implementation}
- %
- % \begin{macrocode}
- %</pkg>
- % \end{macrocode}
|