diff options
author | Karl Berry <karl@freefriends.org> | 2016-02-25 22:40:22 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-02-25 22:40:22 +0000 |
commit | 561ad89d0840ad3b9ddb197efec1739e5089f1b6 (patch) | |
tree | cffe22aac21aedf3c717d43de9798c5b09d2733e /Master/texmf-dist/tex | |
parent | e609261d18e7ce4dd1708dcc6d4679b22ba2d814 (diff) |
xsavebox (25feb16)
git-svn-id: svn://tug.org/texlive/trunk@39866 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r-- | Master/texmf-dist/tex/latex/xsavebox/xsavebox.sty | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/xsavebox/xsavebox.sty b/Master/texmf-dist/tex/latex/xsavebox/xsavebox.sty new file mode 100644 index 00000000000..cbbd3b25f76 --- /dev/null +++ b/Master/texmf-dist/tex/latex/xsavebox/xsavebox.sty @@ -0,0 +1,210 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% xsavebox.sty +% +% Copyright 2016--\today, Alexander Grahn +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Provides commands for saving and repeating any content (typeset text, external +% and inline [TikZ/PGF, PSTricks] graphics) similar to standard LaTeX's +% \savebox, \sbox, \usebox commands and the `lrbox' environment, but without +% code replication for smaller PDF output size +% +% content saving: +% +% (starred `*' variants allow for colour injection [pdflatex/lualatex only]) +% +% \xsavebox{<name>}[<width>][<position>]{...} +% \xsavebox*{<name>}[<width>][<position>]{...} +% +% \xsbox{<name>}{...} +% +% \begin{xlrbox}{<name>}...\end{xlrbox} +% \begin{xlrbox*}{<name>}...\end{xlrbox*} +% +% content insertion: +% +% \xusebox{<name>} +% \the<name> %short form of \xusebox{<name>} for <name> composed of [a-zA-Z] +% +% Supports all known engines and backends including +% pdflatex, latex+dvips+ps2pdf, xelatex, latex+dvipdfmx, lualatex. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% 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://mirrors.ctan.org/help/Catalogue/licenses.lppl.html +% 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 A. Grahn. + +\RequirePackage{xparse} +\RequirePackage{pdfbase} %everything with `pbs_' prefix + +\def\g@xsb@version@tl{0.1} +\def\g@xsb@date@tl{2016/02/25} +\ProvidesExplPackage{xsavebox}{\g@xsb@date@tl}{\g@xsb@version@tl} +{saveboxes for repeating content without code replication} + +\msg_set:nnnn{xsavebox}{support~outdated}{ + Support~package~`#1'~too~old. +}{ + Please~install~an~up~to~date~version~of~`#1'.\\ + Loading~xsavebox~will~abort! +} +\@ifpackagelater{pdfbase}{2016/02/25}{}{ + \msg_error:nnn{xsavebox}{support~outdated}{pdfbase} + \tex_endinput:D +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% content insertion (referencing, actually) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\DeclareDocumentCommand\xusebox{m}{\tl_use:c{the#1}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% saving content +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\DeclareDocumentCommand\xsavebox{smO{\width}O{c}m}{ + \group_begin: + \IfBooleanTF{#1}{ + %later colour injection possible (pdfTeX, LuaTeX) + \hbox_set:Nn\l_xsb_raw_box{\color@begingroup#5\color@endgroup} %raw + \hbox_set:Nn\l_xsb_box{ %content re-aligned + \makebox[#3][#4]{\color@begingroup#5\color@endgroup} + } + }{ + %the LaTeX way (no colour injection) + \sbox\l_xsb_raw_box{#5} %raw content + \savebox\l_xsb_box[#3][#4]{#5} %re-aligned + } + %process one of \l_xsb_raw_box or \l_xsb_box + \dim_compare:nTF{\box_wd:N\l_xsb_raw_box>\box_wd:N\l_xsb_box}{ + \str_if_eq_x:nnTF{#4}{s}{ + %sqeezing content correctly + \IfBooleanTF{#1}{ + %for colour injection + \hbox_set:Nn\l_xsb_box{ + \makebox[\box_wd:N\l_xsb_raw_box][l]{ + \makebox[#3][s]{\color@begingroup#5\color@endgroup} + } + } + }{ + %no colour injection + \savebox\l_xsb_box[\box_wd:N\l_xsb_raw_box][l]{ + \makebox[#3][s]{#5} + } + } + \xsb_process_box:nnnN{#2}{#3}{#4}\l_xsb_box + }{ + \xsb_process_box:nnnN{#2}{#3}{#4}\l_xsb_raw_box + } + }{ + \xsb_process_box:nN{#2}\l_xsb_box + } + \group_end: +} + +\DeclareDocumentCommand\xsbox{mm}{\xsavebox{#1}{#2}} + +\DeclareDocumentEnvironment{xlrbox}{m}{ + \xsb_xlrbox: +}{ + \xsb_endxlrbox:n{#1} +} + +\DeclareDocumentEnvironment{xlrbox*}{m}{ + \xsb_xlrbox_star: +}{ + \xsb_endxlrbox_star:n{#1} +} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\cs_new_nopar:Nn\xsb_xlrbox:{ + \group_begin: + \hbox_set:Nn\l_xsb_box\bgroup\bgroup + \ignorespaces +} + +\cs_new_nopar:Nn\xsb_endxlrbox:n{ + \unskip + \egroup\egroup + \sbox\l_xsb_box{\hbox_unpack_clear:N\l_xsb_box} + \xsb_process_box:nN{#1}\l_xsb_box + \group_end: +} + +\cs_new_nopar:Nn\xsb_xlrbox_star:{ + \group_begin: + \hbox_set:Nn\l_xsb_box\bgroup\color@begingroup + \ignorespaces +} + +\cs_new_nopar:Nn\xsb_endxlrbox_star:n{ + \unskip + \color@endgroup\egroup + \xsb_process_box:nN{#1}\l_xsb_box + \group_end: +} + +\cs_new_nopar:Nn\xsb_process_box:nN{ %process a readily resized (new width) box + %measure box + \tl_set:Nx\l_xsb_wd_tl{\dim_use:N\box_wd:N#2} + \tl_set:Nx\l_xsb_ht_tl{\dim_use:N\box_ht:N#2} + \tl_set:Nx\l_xsb_dp_tl{\dim_use:N\box_dp:N#2} + %push the box bounds somewhat to get everything while distilling, as + %glyphs tend to be larger than their bounding boxes + \hbox_set_to_wd:Nnn#2{\l_xsb_wd_tl+6pt}{\hss\hbox_unpack_clear:N#2\hss} + \box_set_ht:Nn#2{\l_xsb_ht_tl+3pt} + \box_set_dp:Nn#2{\l_xsb_dp_tl+3pt} + %distill box into PDF Form XObject + \pbs_pdfxform:nn{0}{#2}% + %define command for inserting the h-boxed XObject reference + \tl_gset:cx{the#1}{ + \exp_not:N\hbox_to_wd:nn{\l_xsb_wd_tl}{ + \exp_not:N\vrule~width~\c_zero_dim~height~\l_xsb_ht_tl~ + depth~\l_xsb_dp_tl + \exp_not:N\skip_horizontal:n{\dim_eval:n{-3pt}} + \exp_not:N\pbs_pdfrefxform:n{\pbs_pdflastxform:}\hss + } + } +} + +\cs_new_nopar:Nn\xsb_process_box:nnnN{ %first distill, then put XObject ref + %measure natural dimensions into mbox of user defined size + \cs_set_nopar:Npn\width {\box_wd:N#4} + \cs_set_nopar:Npn\height{\box_ht:N#4} + \cs_set_nopar:Npn\depth {\box_dp:N#4} + \cs_set_nopar:Npn\totalheight{\dimexpr\height+\depth\relax} + \tl_set:Nx\l_xsb_wd_tl{\dim_use:N\width} + \tl_set:Nx\l_xsb_ht_tl{\dim_use:N\height} + \tl_set:Nx\l_xsb_dp_tl{\dim_use:N\depth} + %evaluate width argument (allowing for calc-type expressions) + \setlength\l_tmpa_dim{#2} + \tl_set:Nx\l_xsb_new_wd_tl{\dim_use:N\l_tmpa_dim} + \hbox_set_to_wd:Nnn#4{\width+6pt}{\hss\hbox_unpack_clear:N#4\hss} + \box_set_ht:Nn#4{\height+3pt} + \box_set_dp:Nn#4{\depth+3pt} + \pbs_pdfxform:nn{0}{#4}% + %define command for inserting the m-boxed XObject reference + \tl_gset:cx{the#1}{ + \exp_not:N\makebox[\l_xsb_new_wd_tl][#3]{ + \exp_not:N\hbox_to_wd:nn{\l_xsb_wd_tl}{ + \exp_not:N\vrule~width~\c_zero_dim~height~\l_xsb_ht_tl~ + depth~\l_xsb_dp_tl + \exp_not:N\skip_horizontal:n{\dim_eval:n{-3pt}} + \exp_not:N\pbs_pdfrefxform:n{\pbs_pdflastxform:}\hss + } + } + } +} + +\box_new:N\l_xsb_box %for saving the re-aligned content +\box_new:N\l_xsb_raw_box %for saving the raw content |