You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

boxgrab.dtx 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. % \iffalse meta-comment
  2. %
  3. % File: boxgrab.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. boxgrab -- 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 boxgrab.dtx
  36. and the derived files boxgrab.pdf and
  37. boxgrab.sty.
  38. \endpreamble
  39. % stop docstrip adding \endinput
  40. \postamble
  41. \endpostamble
  42. \generate{\file{boxgrab.sty}{\from{boxgrab.dtx}{pkg}}}
  43. \ifx\fmtname\nameofplainTeX
  44. \expandafter\endbatchfile
  45. \else
  46. \expandafter\endgroup
  47. \fi
  48. %</driver>
  49. %
  50. %<*driver>
  51. \ProvidesFile{boxgrab.dtx}
  52. [%
  53. \csname boxgrab@date\endcsname\
  54. utilities to get an argument as a box%
  55. ]
  56. \documentclass{l3doc}
  57. \usepackage{duckuments}
  58. \usepackage{boxgrab}
  59. \author{Jonathan P. Spratte\thanks{Email: jspratte@yahoo.de}}
  60. \title{The \pkg{boxgrab} package}
  61. \makeatletter
  62. \date{\boxgrab@date\ v\boxgrab@version}
  63. \renewcommand*{\thefootnote}{\fnsymbol{footnote}}
  64. \makeatother
  65. \begin{document}
  66. \DocInput{boxgrab.dtx}
  67. \end{document}
  68. %</driver>
  69. %<*pkg>
  70. \newcommand*\boxgrab@date{2018-10-17}
  71. \newcommand*\boxgrab@version{1.0}
  72. \ProvidesPackage{boxgrab}
  73. [\boxgrab@date\ v\boxgrab@version\ utilities to get an argument as a box]
  74. \RequirePackage{xparse}
  75. %</pkg>
  76. % \fi
  77. %
  78. % \begin{center}
  79. % \LARGE The \pkg{boxgrab} package\\[\bigskipamount]
  80. % \large
  81. % \setcounter{footnote}{1}%
  82. % Jonathan P. Spratte\footnotemark\\[\medskipamount]
  83. % Version \csname boxgrab@version\endcsname\\[\smallskipamount]
  84. % Released \csname boxgrab@date\endcsname
  85. % \end{center}
  86. % \footnotetext{E-mail: jspratte@yahoo.de}
  87. %
  88. % \tableofcontents
  89. %
  90. % \begin{documentation}
  91. %
  92. % \section{Introduction}
  93. %
  94. % This package provides \cs{boxgrab} to grab an argument inside of a box. The
  95. % used mechanism allows category code changes in that argument as long as it is
  96. % used in a place allowing category code changes (so not inside of another
  97. % argument).
  98. %
  99. % It is written as a docstrip file: executing |latex boxgrab.dtx| generates the
  100. % \file{boxgrab.sty} file and typesets this documentation; execute
  101. % |tex boxgrab.dtx| to only generate \file{boxgrab.sty}.
  102. %
  103. % \section{The macro}
  104. %
  105. % \begin{function}{\boxgrab}
  106. % \begin{syntax}
  107. % \cs{boxgrab}\meta{*}
  108. % \marg{box register}\oarg{inject pre}\marg{box type}\oarg{inject post}
  109. % \marg{next}\oarg{save args}
  110. % \end{syntax}
  111. % Grabs the next braced argument inside of the box \meta{box register}. The
  112. % box is of \meta{box type}, which should be either \cs{hbox} or \cs{vbox}.
  113. % \meta{inject pre} will be injected at the beginning of the box and can
  114. % affect its contents, \meta{inject post} will be injected after the box but
  115. % can't be affected by stuff inside of \meta{inject pre}. Unless the \meta{*}
  116. % is given leading and trailing spaces will be stripped from the box. After
  117. % the box is read in \meta{next} will be executed. The usage is therefore
  118. % similar to the one of \cs{@ifstar}. You can specify arguments which should
  119. % be given to \meta{next} using \meta{save args}. The stuff you provide in
  120. % \meta{save args} will be given as is to \meta{next}, so if you want to give
  121. % an argument you should delimit it like with braces, like \verb|[{#1}]|, or
  122. % if you want to give two arguments, like \verb|[{#1}{#2}]|.
  123. %
  124. % All assignments are made local. Currently it is not save to nest macros
  125. % which use \cs{boxgrab}.
  126. % \end{function}
  127. %
  128. % \section{Useless Example!}
  129. %
  130. % First we need to reserve us a box register for this example:
  131. %
  132. %\begin{verbatim}
  133. % \newsavebox\ourbox
  134. %\end{verbatim}
  135. %
  136. % Next we define a macro which takes some arguments and uses our macro:
  137. %
  138. %\begin{verbatim}
  139. % \newcommand\examplecmd[2]
  140. % {%
  141. % \begingroup
  142. % \boxgrab\ourbox[\itshape]\hbox[ \sffamily is]\examplecmdOut[{#1}{#2}]
  143. % }
  144. %\end{verbatim}
  145. %
  146. % And we need our helper macro which is executed after \cs{boxgrab}:
  147. %
  148. %\begin{verbatim}
  149. % \newcommand\examplecmdOut[3]
  150. % {%
  151. % \begin{tabular}[t]{@{}ll@{}}
  152. % Arg1: & #1\\
  153. % Arg2: & #2\\
  154. % Box: & \unhbox\ourbox\\
  155. % Arg3: & #3
  156. % \end{tabular}%
  157. % \endgroup
  158. % }
  159. %\end{verbatim}
  160. %
  161. % The result is a macro that takes two ordinary arguments, after those a
  162. % box in horizontal mode and finally another ordinary argument. If we use this
  163. % macro we get the following:
  164. % \begin{center}
  165. % \newsavebox\ourbox
  166. % \newcommand\examplecmd[2]
  167. % {%
  168. % \begingroup
  169. % \boxgrab\ourbox[\itshape]\hbox[ \sffamily is]\examplecmdOut[{#1}{#2}]
  170. % }%
  171. % \newcommand\examplecmdOut[3]
  172. % {%
  173. % \begin{tabular}[t]{@{}ll@{}}
  174. % Arg1: & #1\\
  175. % Arg2: & #2\\
  176. % Box: & \unhbox\ourbox\\
  177. % Arg3: & #3
  178. % \end{tabular}%
  179. % \endgroup
  180. % }%
  181. % \examplecmd{Hi,}{my}{\verb|name|}{Steve!}
  182. % \end{center}
  183. % One can see, that the \verb|\sffamily is| of \meta{inject post} is not
  184. % affected by the |\itshape| in \meta{inject pre}.
  185. % The used code to generate that table was:
  186. %
  187. %\begin{verbatim}
  188. % \examplecmd{Hi,}{my}{\verb|name|}{Steve!}
  189. %\end{verbatim}
  190. %
  191. % \section{Useful Example?}
  192. %
  193. % This example provides a macro which typesets its mandatory argument in a block
  194. % of a definable number of lines, it is meant for a single paragraph.
  195. %
  196. %\begin{verbatim}
  197. % % Getting a box register:
  198. % \newsavebox\RectangleBox
  199. % % Defining the main macro
  200. % \newcommand\Rectangle[1][4]
  201. % {%
  202. % \begingroup
  203. % \boxgrab\RectangleBox\hbox\RectangleOut[{#1}]
  204. % }
  205. % % Defining the secondary macro
  206. % \newcommand\RectangleOut[1]
  207. % {%
  208. % \begin{minipage}{\dimexpr\wd\RectangleBox/#1\relax}
  209. % \parfillskip0pt
  210. % \unhbox\RectangleBox
  211. % \end{minipage}%
  212. % \endgroup
  213. % }
  214. %\end{verbatim}
  215. %
  216. % And a usage example of our new macro (with the \pkg{duckuments} package
  217. % loaded):
  218. %
  219. %\begin{verbatim}
  220. % \begin{center}
  221. % \Rectangle[9]{\blindduck}
  222. % \end{center}
  223. %\end{verbatim}
  224. % Results:
  225. % \newsavebox\RectangleBox
  226. % \newcommand\Rectangle[1][4]
  227. % {%
  228. % \begingroup
  229. % \boxgrab\RectangleBox\hbox\RectangleOut[{#1}]
  230. % }%
  231. % \newcommand\RectangleOut[1]
  232. % {%
  233. % \begin{minipage}{\dimexpr\wd\RectangleBox/#1\relax}
  234. % \parfillskip0pt
  235. % \unhbox\RectangleBox
  236. % \end{minipage}%
  237. % \endgroup
  238. % }%
  239. % \begin{center}
  240. % \Rectangle[9]{\blindduck}
  241. % \end{center}
  242. %
  243. % \end{documentation}
  244. %
  245. % \begin{implementation}
  246. %
  247. % \section{Implementation}
  248. %
  249. % \begin{macrocode}
  250. %<*pkg>
  251. % \end{macrocode}
  252. %
  253. % \begin{macrocode}
  254. \@ifdefinable{\if@boxgrab@spaces@}{\newif\if@boxgrab@spaces@}
  255. \newcommand*\boxgrab@args{}%
  256. \NewDocumentCommand \boxgrab { s m +O{} m +O{} m }
  257. {%
  258. \IfBooleanTF{#1}
  259. {\@boxgrab@spaces@true}
  260. {\@boxgrab@spaces@false}%
  261. \def\boxgrab@name{#2}%
  262. \if@boxgrab@spaces@
  263. \def\boxgrab@into@pre{#3}%
  264. \else
  265. \def\boxgrab@into@pre{#3\ignorespaces}%
  266. \fi
  267. \def\boxgrab@type{#4}%
  268. \def\boxgrab@into@post{#5}%
  269. \def\boxgrab@final{#6}%
  270. \@ifnextchar[
  271. {\boxgrab@get@args}
  272. {\def\boxgrab@args{}\boxgrab@a}
  273. }
  274. \newcommand \boxgrab@get@args {}
  275. \long\def\boxgrab@get@args#1]
  276. {%
  277. \expandafter\boxgrab@get@args@a\expandafter{\@gobble#1}%
  278. }
  279. \newcommand \boxgrab@get@args@a [1]
  280. {%
  281. \boxgrab@check@bracket #1[\endboxgrab@check@bracket
  282. {\def\boxgrab@args{#1}\boxgrab@a}%
  283. {\boxgrab@get@args@grabon{#1]}}%
  284. }
  285. \newcommand \boxgrab@get@args@grabon {}
  286. \long\def\boxgrab@get@args@grabon#1#2]
  287. {%
  288. \boxgrab@check@bracket #2[\endboxgrab@check@bracket
  289. {\def\boxgrab@args{#1#2}\boxgrab@a}
  290. {\boxgrab@get@args@grabon{#1#2]}}%
  291. }
  292. \newcommand \boxgrab@check@bracket {}
  293. \long\def\boxgrab@check@bracket #1[#2\endboxgrab@check@bracket
  294. {%
  295. \if\relax\detokenize{#2}\relax
  296. \expandafter\@firstoftwo
  297. \else
  298. \expandafter\@secondoftwo
  299. \fi
  300. }
  301. \newcommand* \boxgrab@a
  302. {%
  303. \afterassignment\boxgrab@intermediate
  304. \setbox\boxgrab@name\boxgrab@type
  305. }
  306. \newcommand*\boxgrab@intermediate
  307. {%
  308. \aftergroup\boxgrab@after
  309. \boxgrab@into@pre
  310. }
  311. \newcommand*\boxgrab@after
  312. {%
  313. \if@boxgrab@spaces@
  314. \setbox\boxgrab@name\boxgrab@type
  315. {%
  316. \boxgrab@unpack
  317. \boxgrab@into@post
  318. }%
  319. \else
  320. \setbox\boxgrab@name\boxgrab@type
  321. {%
  322. \boxgrab@unpack
  323. \ifhmode\unskip\fi
  324. \boxgrab@into@post
  325. }%
  326. \fi
  327. \expandafter\boxgrab@final@exp@args\expandafter{\boxgrab@args}%
  328. }
  329. \newcommand*\boxgrab@unpack
  330. {%
  331. \csname
  332. un%
  333. \expandafter\expandafter\expandafter\@gobble
  334. \expandafter\string\boxgrab@type
  335. \endcsname
  336. \boxgrab@name
  337. }
  338. \newcommand\boxgrab@final@exp@args[1]
  339. {%
  340. \def\boxgrab@args{}%
  341. \boxgrab@final#1%
  342. }
  343. % \end{macrocode}
  344. %
  345. % \begin{macrocode}
  346. \endinput
  347. % \end{macrocode}
  348. %
  349. % \end{implementation}
  350. %
  351. % \begin{macrocode}
  352. %</pkg>
  353. % \end{macrocode}