No Description

grabbox.dtx 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. % \iffalse meta-comment
  2. %
  3. % File: grabbox.dtx Copyright (C) 2018 Jonathan P. Spratte
  4. %
  5. % It may be distributed and/or modified under the conditions of the LaTeX
  6. % Project Public License (LPPL), either version 1.3c of this license or (at your
  7. % option) any later version. The latest version of this license is in the file
  8. %
  9. % https://www.latex-project.org/lppl.txt
  10. %
  11. % ------------------------------------------------------------------------------
  12. %
  13. %<*driver>
  14. \def\nameofplainTeX{plain}
  15. \ifx\fmtname\nameofplainTeX\else
  16. \expandafter\begingroup
  17. \fi
  18. \input l3docstrip.tex
  19. \askforoverwritefalse
  20. \preamble
  21. --------------------------------------------------------------
  22. grabbox -- utilities to get an argument as a box
  23. E-mail: jspratte@yahoo.de
  24. Released under the LaTeX Project Public License v1.3c or later
  25. See http://www.latex-project.org/lppl.txt
  26. --------------------------------------------------------------
  27. Copyright (C) 2018 Jonathan P. Spratte
  28. This work may be distributed and/or modified under the conditions of the
  29. LaTeX Project Public License (LPPL), either version 1.3c of this license or
  30. (at your option) any later version. The latest version of this license is in
  31. the file:
  32. http://www.latex-project.org/lppl.txt
  33. This work is "maintained" (as per LPPL maintenance status) by
  34. Jonathan P. Spratte.
  35. This work consists of the file grabbox.dtx
  36. and the derived files grabbox.pdf and
  37. grabbox.sty.
  38. \endpreamble
  39. % stop docstrip adding \endinput
  40. \postamble
  41. \endpostamble
  42. \generate{\file{grabbox.sty}{\from{grabbox.dtx}{pkg}}}
  43. \ifx\fmtname\nameofplainTeX
  44. \expandafter\endbatchfile
  45. \else
  46. \expandafter\endgroup
  47. \fi
  48. %</driver>
  49. %
  50. %<*driver>
  51. \ProvidesFile{grabbox.dtx}
  52. [%
  53. \csname grabbox@date\endcsname\space
  54. utilities to get an argument as a box%
  55. ]
  56. \expandafter\def\csname @classoptionslist\endcsname{}
  57. \RequirePackage[british]{babel}
  58. \documentclass{l3doc}
  59. \usepackage{duckuments}
  60. \usepackage{microtype}
  61. \usepackage{grabbox}
  62. \renewcommand*{\thefootnote}{\fnsymbol{footnote}}
  63. \let\metaOrig\meta
  64. \renewcommand\meta[1]
  65. {%
  66. \texttt{\metaOrig{#1}}%
  67. }
  68. \begin{document}
  69. \DocInput{grabbox.dtx}
  70. \end{document}
  71. %</driver>
  72. %<*pkg>
  73. \newcommand*\grabbox@date{2018-12-29}
  74. \newcommand*\grabbox@version{1.3}
  75. \ProvidesPackage{grabbox}
  76. [%
  77. \grabbox@date\space v\grabbox@version\space utilities to get an argument as
  78. a box%
  79. ]
  80. %</pkg>
  81. % \fi
  82. %
  83. % \begin{center}
  84. % \LARGE The \pkg{grabbox} package\\[\bigskipamount]
  85. % \large
  86. % \setcounter{footnote}{1}%
  87. % Jonathan P. Spratte\footnotemark\\[\medskipamount]
  88. % Version \csname grabbox@version\endcsname\\[\smallskipamount]
  89. % Released \csname grabbox@date\endcsname
  90. % \end{center}
  91. % \footnotetext{E-mail: jspratte@yahoo.de}
  92. %
  93. % \tableofcontents
  94. %
  95. % \begin{documentation}
  96. %
  97. % \section{Introduction}
  98. %
  99. % Sometimes I happen to write macros and environments which don't care for the
  100. % exact contents of an argument but only for that contents' typeset
  101. % representation and its dimensions. In that case I personally dislike the fact
  102. % that those arguments couldn't contain verbatim material if coded straight
  103. % forward for macros. For environments this is quite easy to create thanks to
  104. % \env{lrbox}, for macros this approach unfortunately doesn't work without the
  105. % enduser's cooperation. Thus the macros distributed hereby came into existence.
  106. %
  107. % This package provides \cs{grabbox} to grab an argument inside of a box. The
  108. % used mechanism allows category code changes in that argument as long as it is
  109. % used in a place allowing category code changes (so not inside of another
  110. % argument).
  111. %
  112. % It is written as a docstrip file: executing |latex grabbox.dtx| generates the
  113. % \file{grabbox.sty} file and typesets this documentation; execute
  114. % |tex grabbox.dtx| to only generate \file{grabbox.sty}.
  115. %
  116. % \section{Acknowledgement}
  117. %
  118. % I want to thank Enrico Gregorio for helping me develop first versions of the
  119. % used mechanisms for the second iteration of my \pkg{ducksay} package. If he
  120. % hadn't helped me back then, I wouldn't have considered the used method
  121. % further -- because the user interface would've been too clumsy and require
  122. % strange markup like |\foo arg}| -- and therefore this package wouldn't have
  123. % been created.
  124. %
  125. % Additionally I want to thank David Carlisle for helping me making \cs{grabbox}
  126. % respect surrounding text colours.
  127. %
  128. % \section{The macro}
  129. %
  130. % \begin{function}{\grabbox}
  131. % \begin{syntax}
  132. % \cs{grabbox}\meta{*}\oarg{inject pre pre}\ignorespaces^^A
  133. % \marg{box register}\oarg{inject pre}\marg{box type}\ignorespaces^^A
  134. % \oarg{inject post}\marg{afterwards}
  135. % \end{syntax}
  136. % grabs the next braced argument and stores it inside of the box \meta{box
  137. % register}. The box is of \meta{box type}, which should be one of \cs{hbox}
  138. % or \cs{vbox} or \cs{vtop}. The contents of the box except for
  139. % \meta{inject pre pre} and \meta{inject post} will be contained in an
  140. % additional level of grouping to ensure colour safety (similar to \LaTeX's
  141. % \cs{sbox}). \meta{inject pre pre} will be injected at the beginning of the
  142. % box before this additional group is opened, \meta{inject pre} will be
  143. % injected at the beginning of the box and can affect its contents,
  144. % \meta{inject post} will be injected at the end of the box but can't be
  145. % affected by stuff inside of \meta{inject pre} or added content unless they
  146. % are using global definitions -- \meta{inject pre pre} however can affect the
  147. % contents of \meta{inject post}.
  148. % Unless the \meta{*} is given leading and trailing spaces will be stripped
  149. % from the box. After the box is read in \meta{afterwards} will be inserted.
  150. % The complete contents of the box will be something like:
  151. % \begin{center}
  152. % \csname verbatim@font\endcsname
  153. % \meta{inject pre pre}^^A
  154. % \{\cs{set@color}\meta{inject pre}\meta{argument}\}^^A
  155. % \meta{inject post}
  156. % \end{center}
  157. % \end{function}
  158. %
  159. % \smallskip
  160. % All assignments are made local. Currently it is not safe to nest macros
  161. % which use \cs{grabbox}. It should become safe if your macros use
  162. % \cs{grabbox} inside of a group, so the inner \cs{grabbox} doesn't affect the
  163. % outer one.
  164. %
  165. % \cs{grabbox} uses \cs{afterassignment} and \cs{aftergroup} to do its magic.
  166. % The former should be safe where it is used, the latter is used inside of the
  167. % boxed argument before any contents are inserted.
  168. %
  169. % Since \cs{grabbox} works by setting a boxregister using \cs{setbox} (and a
  170. % bunch of temporary macros), it is of course not expandable and defined
  171. % \cs{protected}.
  172. %
  173. % \section{Useless Example!}
  174. %
  175. % First we need to reserve us a box register for this example:
  176. % \begin{verbatim}
  177. % \newsavebox\ourbox
  178. % \end{verbatim}
  179. % Next we define a macro which takes some arguments and uses \cs{grabbox}:
  180. % \begin{verbatim}
  181. % \newcommand\examplecmd[2]
  182. % {%
  183. % \begingroup
  184. % \grabbox\ourbox[\itshape]\hbox[ \sffamily is]{\examplecmdOut{#1}{#2}}
  185. % }
  186. % \end{verbatim}
  187. % And we need our helper macro which is executed after \cs{grabbox}:
  188. % \begin{verbatim}
  189. % \newcommand\examplecmdOut[3]
  190. % {%
  191. % \begin{tabular}[t]{@{}ll@{}}
  192. % Arg1: & #1\\
  193. % Arg2: & #2\\
  194. % Box: & \unhbox\ourbox\\
  195. % Arg3: & #3
  196. % \end{tabular}%
  197. % \endgroup
  198. % }
  199. % \end{verbatim}
  200. %
  201. % The result is a macro that takes two ordinary arguments, after those a
  202. % box in horizontal mode and finally another ordinary argument. If we use this
  203. % macro we get the following:
  204. % \begin{center}
  205. % \newsavebox\ourbox
  206. % \newcommand\examplecmd[2]
  207. % {%
  208. % \begingroup
  209. % \grabbox\ourbox[\itshape]\hbox[ \sffamily is]{\examplecmdOut{#1}{#2}}
  210. % }%
  211. % \newcommand\examplecmdOut[3]
  212. % {%
  213. % \begin{tabular}[t]{@{}ll@{}}
  214. % Arg1: & #1\\
  215. % Arg2: & #2\\
  216. % Box: & \unhbox\ourbox\\
  217. % Arg3: & #3
  218. % \end{tabular}%
  219. % \endgroup
  220. % }%
  221. % \examplecmd{Hi,}{my}{\verb|\name|}{Steve!}
  222. % \end{center}
  223. % One can see that \verb|\sffamily is| in \meta{inject post} is not affected by
  224. % the |\itshape| in \meta{inject pre}. The used code to generate that table was:
  225. %
  226. % \begin{verbatim}
  227. % \examplecmd{Hi,}{my}{\verb|\name|}{Steve!}
  228. % \end{verbatim}
  229. %
  230. % \section{Useful Example?}
  231. %
  232. % This example provides a macro which typesets its mandatory argument in a block
  233. % of a definable number of lines, it is meant for a single paragraph.
  234. %
  235. % \begin{verbatim}
  236. % % Getting a box register:
  237. % \newsavebox\RectangleBox
  238. % % Defining the main macro:
  239. % \newcommand\Rectangle[1][4]
  240. % {%
  241. % \begingroup
  242. % \grabbox\RectangleBox\hbox
  243. % {%
  244. % % Since we don't want to read more arguments after the box,
  245. % % we don't need a second macro and can put the output routine
  246. % % here.
  247. % \begin{minipage}{\dimexpr\wd\RectangleBox/#1\relax}
  248. % \parfillskip0pt
  249. % \unhbox\RectangleBox
  250. % \end{minipage}%
  251. % \endgroup
  252. % }%
  253. % }
  254. % \end{verbatim}
  255. %
  256. % As you can see, this macro uses \cs{grabbox} in a group delimited by
  257. % \cs{begingroup} and \cs{endgroup} -- like the useless example. It should
  258. % therefore be safe to nest it inside other macros using \cs{grabbox}.
  259. %
  260. % Finally a usage example of our new macro (with the \pkg{duckuments} package
  261. % loaded):
  262. %
  263. % \begin{verbatim}
  264. % \begin{center}
  265. % \Rectangle[9]{\blindduck}
  266. % \end{center}
  267. % \end{verbatim}
  268. % Results in:
  269. % \begin{center}
  270. % \newsavebox\RectangleBox
  271. % \newcommand\Rectangle[1][4]
  272. % {%
  273. % \begingroup
  274. % \grabbox\RectangleBox\hbox
  275. % {%
  276. % \begin{minipage}{\dimexpr\wd\RectangleBox/#1\relax}
  277. % \parfillskip0pt
  278. % \unhbox\RectangleBox
  279. % \end{minipage}%
  280. % \endgroup
  281. % }%
  282. % }
  283. % \Rectangle[9]{\blindduck}
  284. % \end{center}
  285. %
  286. % \end{documentation}
  287. %
  288. % \begin{implementation}
  289. %
  290. % \section{Implementation}
  291. %
  292. % \begin{macrocode}
  293. %<*pkg>
  294. % \end{macrocode}
  295. %
  296. % \begin{macrocode}
  297. \@ifdefinable{\if@grabbox@spaces@}{\newif\if@grabbox@spaces@}
  298. \@ifdefinable{\grabbox@def}
  299. {\long\def\grabbox@def#1#2#{\grabbox@def@a{}#1{#2}}}
  300. \@ifdefinable{\grabbox@ldef}
  301. {\long\def\grabbox@ldef#1#2#{\grabbox@def@a\long#1{#2}}}
  302. \@ifdefinable{\grabbox@def@a}
  303. {%
  304. \protected\long\def\grabbox@def@a#1#2#3#4%
  305. {\@ifdefinable#2{\protected#1\def#2#3{#4}}}%
  306. }
  307. \newcommand\grabbox@def@step[4]
  308. {%
  309. \grabbox@def#1##1{\def#2{##1}\grabbox@opt#3#4}%
  310. }
  311. \long\def\grabbox@afterelsefi#1\else#2\fi{\fi#1}
  312. \long\def\grabbox@afterfi#1\fi{\fi#1}
  313. \grabbox@def\grabbox@opt#1#2%
  314. {%
  315. \@ifnextchar[
  316. {\grabbox@opt@get#1#2}
  317. {\def#1{}#2}%
  318. }
  319. \grabbox@ldef\grabbox@opt@get#1#2[#3]%
  320. {%
  321. \def#1{#3}#2%
  322. }
  323. \grabbox@def\grabbox@set@color
  324. {%
  325. \@ifundefined{set@color}{}
  326. {\global\let\grabbox@set@color\set@color\grabbox@set@color}%
  327. }
  328. \AtBeginDocument
  329. {%
  330. \@ifundefined{set@color}
  331. {\gdef\grabbox@set@color{}}
  332. {\global\let\grabbox@set@color\set@color}%
  333. }%
  334. \newcommand*\grabbox@unskip@space
  335. {%
  336. \ifhmode\unskip\fi
  337. }
  338. \grabbox@def\grabbox@unpack
  339. {%
  340. \begingroup
  341. \edef\grabbox@test{\grabbox@type}%
  342. \expandafter\ifx\grabbox@test\hbox
  343. \endgroup
  344. \grabbox@afterelsefi\unhbox
  345. \else
  346. \endgroup
  347. \grabbox@afterfi\unvbox
  348. \fi
  349. \grabbox@name
  350. }
  351. \grabbox@def\grabbox
  352. {%
  353. \@ifstar
  354. {\@grabbox@spaces@true\grabbox@a}
  355. {\@grabbox@spaces@false\grabbox@a}%
  356. }
  357. \grabbox@def\grabbox@a
  358. {%
  359. \grabbox@opt\grabbox@into@prepre\grabbox@b
  360. }
  361. \grabbox@def@step\grabbox@b\grabbox@name\grabbox@into@pre\grabbox@c
  362. \grabbox@def@step\grabbox@c\grabbox@type\grabbox@into@post\grabbox@d
  363. \grabbox@ldef\grabbox@d#1%
  364. {%
  365. \def\grabbox@final{#1}%
  366. \afterassignment\grabbox@intermediate
  367. \setbox\grabbox@name\grabbox@type
  368. }
  369. \grabbox@def\grabbox@intermediate
  370. {%
  371. \grabbox@into@prepre
  372. \bgroup
  373. \if@grabbox@spaces@
  374. \else
  375. \aftergroup\grabbox@unskip@space
  376. \fi
  377. \grabbox@set@color
  378. \aftergroup\grabbox@after
  379. \grabbox@into@pre
  380. \if@grabbox@spaces@
  381. \else
  382. \ignorespaces
  383. \fi
  384. }
  385. \newcommand*\grabbox@after@aux@b[1]
  386. {%
  387. \grabbox@after@aux@a
  388. }
  389. \grabbox@def\grabbox@after@aux@a
  390. {%
  391. \@ifnextchar\reset@color
  392. {\reset@color\grabbox@after@aux@b}
  393. {\egroup\grabbox@final}%
  394. }
  395. \grabbox@def\grabbox@after
  396. {%
  397. \grabbox@into@post
  398. \endgraf
  399. \grabbox@after@aux@a
  400. }
  401. % \end{macrocode}
  402. %
  403. % \begin{macrocode}
  404. \endinput
  405. % \end{macrocode}
  406. %
  407. % \end{implementation}
  408. %
  409. % \begin{macrocode}
  410. %</pkg>
  411. % \end{macrocode}