3

I'm trying to apply \scalebox for each cell in a column, using >{...}, <{...} operators from array package.

Here's my attempt to make it work

\documentclass{article}
\usepackage{array}
\usepackage{graphics}

\begin{document}

\begin{tabular}{cc>{\scalebox{1.5}\bgroup}c<{\egroup}} some & simple & text \end{tabular}

\end{document}

but it simply swallows the last column enter image description here

Note that I'm not looking for solutions that suggest use \large or \fontsize{...}. I need exactly \scalebox make to work.

antshar
  • 4,238
  • 9
  • 30
  • I guess there's a solution of storing the cell in a box then scale it, but that's a bit difficult. – user202729 Jun 26 '22 at 11:33
  • use \begin{lrbox} and \end{lrbox} – David Carlisle Jun 26 '22 at 11:36
  • @DavidCarlisle could you post it as an answer? – antshar Jun 26 '22 at 11:53
  • I could have done but Rmano's answer is fine and easier – David Carlisle Jun 26 '22 at 11:55
  • @DavidCarlisle it's preferable for me to load as least packages as possible. – antshar Jun 26 '22 at 11:56
  • 1
    why? If I give you some code in an answer and you put it in s.sty that's a new package load and if you put the source of collcell in your preamble instead of referencing a file that's one less package load. There is no conceptual or actual difference between packge code and code from some random internet post – David Carlisle Jun 26 '22 at 12:02
  • 1
    but @user202729 showed this anyway:-) – David Carlisle Jun 26 '22 at 12:03
  • @DavidCarlisle I'm not sure, probably it's a mental thing. It feels like it's not right to fill the preamble with a bunch of packages which are used only for one little thing. I would rather use one block of code that I'm sure that does that specific thing. – antshar Jun 26 '22 at 12:06
  • In that case I guess it's mostly Knuth's fault for making TeX have too little functionality/too difficult to program in that people have to use all these packages; on the other hand expl3 mostly mitigate that by providing most "basic" functions. // Side note, there are some things box solutions cannot do that collcell can e.g. the obvious one of reading the "content" of the cell. – user202729 Jun 26 '22 at 12:08

2 Answers2

3

You can use the collcell package:

\documentclass{article}
\usepackage{array}
\usepackage{graphics}
\usepackage{collcell}
\newcommand{\myresize}[1]{\scalebox{1.5}{#1}}

\begin{document}

\begin{tabular}{cc>{\collectcell\myresize}c<{\endcollectcell}} some & simple & text \end{tabular}

\end{document}

enter image description here

Rmano
  • 40,848
  • 3
  • 64
  • 125
3

Apart from the "trivial" solution of using lrbox environment...

%! TEX program = lualatex
\documentclass{article}
\usepackage{array}
\usepackage{graphics}

\begin{document}

\newsavebox{\mybox}

\begin{tabular}{cc>{\begin{lrbox}{\mybox}}c<{\end{lrbox}% \scalebox{1.5}{\usebox{\mybox}}% }} some & simple & te \verb+x+ t \end{tabular}

\end{document}

there is also the solution of adapting the implementation of scalebox (the problem is obvious -- once the graphicx package changes the macro definition your code might break/is incompatible)

%! TEX program = lualatex
\documentclass{article}
\usepackage{array}
\usepackage{graphics}

\begin{document}

\makeatletter

% scalebox is defined as: % \protected macro:#1->@ifnextchar [{\Gscale@box {#1}}{\Gscale@box {#1}[#1]} % so \scalebox{factor}{content} = \Gscale@box{factor}[factor]{content}

% \Gscale@box body is % \leavevmode \def \Gscale@x {#1}\def \Gscale@y {#2}\setbox \z@ \hbox {{#3}}\setbox \tw@ \hbox {\Gscale@start \rlap {\copy \z@ }\Gscale@end }\ifdim #2\p@ <\z@ \ht \tw@ -#2\dp \z@ \dp \tw@ -#2\ht \z@ \else \ht \tw@ #2\ht \z@ \dp \tw@ #2\dp \z@ \fi \ifdim #1\p@ <\z@ \hb@xt@ -#1\wd \z@ {\kern -#1\wd \z@ \box \tw@ \hss }\else \hb@xt@ #1\wd \z@ {\box \tw@ \kern #1\wd \z@ \hss }\fi % % take the part before #3 put into Gscaleboxfirst, and the part after that put in Gscaleboxsecond.

\def\Gscaleboxfirst #1#2{% \leavevmode \def \Gscale@x {#1}\def \Gscale@y {#2}\setbox \z@ \hbox \bgroup\bgroup% }

\def\Gscaleboxsecond #1#2{% \egroup\egroup \setbox \tw@ \hbox {\Gscale@start \rlap {\copy \z@ }\Gscale@end }\ifdim #2\p@ <\z@ \ht \tw@ -#2\dp \z@ \dp \tw@ -#2\ht \z@ \else \ht \tw@ #2\ht \z@ \dp \tw@ #2\dp \z@ \fi \ifdim #1\p@ <\z@ \hb@xt@ -#1\wd \z@ {\kern -#1\wd \z@ \box \tw@ \hss }\else \hb@xt@ #1\wd \z@ {\box \tw@ \kern #1\wd \z@ \hss }\fi % }

\makeatother

\newsavebox{\mybox}

\begin{tabular}{cc>{\Gscaleboxfirst{1.5}{1.5}}c<{\Gscaleboxsecond{1.5}{1.5}}} some & simple & te \verb+x+ t \end{tabular}

\end{document}

Read the code comment to see where the code comes from. Parsing optional argument/avoiding duplicating the arguments in both the first and the second part is left as an exercise for the reader.

Unlike collcell both of those does support verbatim (it's not like that non-boxing solutions cannot support verbatim, it's just more of a hassle to do that with set catcode & scantokens/input)


Talking about verbatim, I'd also mention my package cprotectinside (allows \verb and other verbatim-like commands/environments to be used with collcell solution)...

%! TEX program = lualatex
\documentclass{article}
\usepackage{array}
\usepackage{graphics}
\usepackage{collcell}
\usepackage{cprotectinside}
\newcommand{\myresize}[1]{\scalebox{1.5}{#1}}

\begin{document}

\cprotectinside{}{ \begin{tabular}{cc>{\collectcell\myresize}c<{\endcollectcell}} some & simple & te\verb+x+t* \end{tabular} }

\end{document}

user202729
  • 7,143
  • The "trivial" solution seem to be the most satisfying and yet the simplest and shortest one. Thanks – antshar Jun 26 '22 at 12:01
  • It requires one more box-copying though. (on the other hand collcell requires some token list copying, and I don't know that much of TeX implementation details to tell if there's any performance difference) – user202729 Jun 26 '22 at 12:02
  • (crosslink, question regarding lrbox environment https://tex.stackexchange.com/questions/70697/savebox-with-bgroup-egroup-doesnt-work-in-beamer-for-environment) – user202729 Jun 26 '22 at 12:09
  • Made the code slightly simpler and it now doesn't require creating a new box explicitly: >{\begin{lrbox}0}c<{\end{lrbox}\scalebox{1.5}{\box0}} – antshar Jun 26 '22 at 12:18
  • That's not "officially supported LaTeX syntax" though. Could as well use \setbox0 / \box0 (plain TeX syntax, the last one move instead of copy the box). – user202729 Jun 26 '22 at 12:21
  • Unfortunately, it doesn't work with \sbox, the issue mentioned in the link you've just provided. – antshar Jun 26 '22 at 12:22