Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Currently I set up a box of given length #1 and width #2 like this:

\newcommand{\mybox}[2]{
   This is a box of #1 by #2 centimeters:
   \framebox{\hbox to #1cm {\vbox to #2cm}}
}

% Usage:
\mybox{5}{8]

However this causes an error as it's not allowed to append cm to the parameters #1 and #2.

Is there a way to append a unit to a command argument? Unfortunately, it is not possible to pass the unit as an argument because I also use the parameters in their original raw form.

share|improve this question
2  
You shouldn't need \hbox and \vbox here. The optional arguments to the LaTeX \parbox command are designed to specify the required height and width. –  David Carlisle Jan 29 '12 at 11:53
add comment

3 Answers

up vote 5 down vote accepted

You have no content for your second box, and are missing the required brace group:

\documentclass{article}
\newcommand{\mybox}[2]{%
   This is a box of #1 by #2 centimeters:
   \framebox{\hbox to #1cm {\vbox to #2cm{}}}%
}
\begin{document}
% Usage:
\mybox{5}{8}
\end{document}
share|improve this answer
    
Thank you for your fast and simple answer! –  SecStone Jan 29 '12 at 21:55
add comment

Here is a way of doing it, plus an alternative that doesn't use \hbox or \vbox, but zero-width rules rather:

Boxes of specific width/height in cm

\documentclass{article}
\newcommand{\mybox}[2]{%
   This is a box of~#1 by~#2 centimeters:
   \framebox{\hbox to \dimexpr#1 cm\relax {\vbox to \dimexpr#2 cm\relax{}}}%
}
\newcommand{\myboxx}[2]{%
  This is a box of~#1 by~#2 centimeters:
  \fbox{\rule{\dimexpr#1cm\relax}{0pt}\rule{0pt}{\dimexpr#2cm\relax}}%
}
\begin{document}
\mybox{5}{8} \par
\myboxx{2}{2}
\end{document}

The key to modifying your argument from number to dimension is to use \dimexpr. Also, similar to using \hbox to .. {...}, you need to enclose the \vbox to .. {...} with braces as well.

share|improve this answer
add comment

A cheap way to add a default unit of measure to an argument is to say

\sbox0{\dimen0=#1cm}

(instead of cm one can use any legal unit of measure). If #1 is a number without a unit attached, the assignment will leave nothing to typeset in the box, which will have zero width. Otherwise cm will be typeset.

So here's a way:

\documentclass{article}
\newcommand\testforunit[2]{%
  \sbox0{\dimen#1=#2cm}%
  \ifdim\wd0=0pt
    \dimen#1=#2cm
  \else
    \dimen#1=#2\relax
  \fi}

\newcommand{\mybox}[2]{%
  This is a box of #1 by #2 (default unit centimeters):\hfill
  \begingroup\fboxsep=-\fboxrule
  \testforunit{0}{#1}\testforunit{2}{#2}%
  \framebox[\dimen0]{\rule{0pt}{\dimen2}}%
  \endgroup\par}

\begin{document}
\mybox{2}{3}

\mybox{2cm}{3cm}

\mybox{1in}{2in}
\end{document}

With \testforunit we perform the test on #2 adding cm if necessary and store the requested length in \dimen#1. The construction of the box is done with those two length but in a group where \fboxsep is set to \fboxrule, so that the frame will have the exact requested dimensions. In the example the first and second boxes are identical.

As suggested by Joseph, here is the "official" LaTeX kernel way of defining \testforunit:

\makeatletter
\newcommand{\testforunit}[2]{\@defaultunits\dimen#1=#2cm\relax\@nnil}
\makeatother

enter image description here

share|improve this answer
    
Wouldn't \@defaultunits be as good an approach here (via a \dimen)? –  Joseph Wright Jan 29 '12 at 9:56
    
What about a \dim_set_withdefaultunit:Nnn \l_my_dim { #1 } { cm }? You'll need it, eventually. –  egreg Jan 29 '12 at 10:11
    
I'm not sure we will, actually :-) We have some need for this in implementing the NFSS in expl3, but there it's clear that the default unit is fixed (as pt). –  Joseph Wright Jan 29 '12 at 10:32
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.