4

Please consider the following MWE :

\documentclass{article}

\newcommand{\mymargin}{\hspace*{3em}}
\newcommand{\innerbox}[1]{\mymargin\fbox{#1}\mymargin}
\newcommand{\outerbox}[1]{\fbox{#1}}

\begin{document}

test \innerbox{Hello} test% OK

test \outerbox{\innerbox{Hello} test \innerbox{Hello} test \innerbox{Hello}}%   I don't want space at beginning and end of box

test \outerbox{\fbox{Hello}\mymargin{} test \innerbox{Hello} test \mymargin\fbox{Hello}}%   what i'd like

\end{document}

(actually, the definitions of boxes are more complex but I think that doesn't change anything to the logic)

I'd like the use of \innerbox inside \outerbox not to induce spaces at the beginning and at the end of the box.

I suppose i should expand argument #1 (once got rid of the unnecessary spaces) from \outerbox and detect if the first and last token are equal \mymargin and then make the necessary changes but I really don't know how to do it. Any ideas?

4

You can check (ignoring spaces) whether the first token in the argument of \outerbox is \innerbox and, in this case, insert a negative space for compensation.

At the end you can recursively remove all glue nodes.

\documentclass{article}

\newcommand{\mymarginwidth}{3em}
\newcommand{\mymargin}{\hspace*{\mymarginwidth}}
\newcommand{\negmymargin}{\hspace*{-\mymarginwidth}}

\newcommand{\innerbox}[1]{\mymargin\fbox{#1}\mymargin}
\makeatletter
\newcommand{\outerbox}[1]{%
  \fbox{%
    \@ifnextchar\innerbox{\negmymargin}{}#1%
    \forever@unskip
  }%
}
\newcommand{\forever@unskip}{%
  \ifnum\lastnodetype=11
    \expandafter\unskip\expandafter\forever@unskip
  \fi
}
\makeatother

\begin{document}

test \innerbox{Hello} test

test \outerbox{\innerbox{Hello} test \innerbox{Hello} test \innerbox{Hello}}

test \outerbox{\fbox{Hello}\mymargin{} test \innerbox{Hello} test \mymargin\fbox{Hello}}

test \outerbox{test \innerbox{Hello} test \innerbox{Hello}}

test \outerbox{\innerbox{Hello} test \innerbox{Hello} test}

test \outerbox{ test \innerbox{Hello} test \innerbox{Hello} }

test \outerbox{ \innerbox{Hello} test \innerbox{Hello} test }

\end{document}

enter image description here

  • Thanks a lot, it works perfectly well... for this example of use. But, actually, \innerbox is defined with an optional argument (as \newcommand{\innerbox}[2][]{...}) and, in this case, your code leads to an error : ! Use of \\innerbox doesn't match its definition.. What should i change in your code to have it work ? – user30654 Apr 17 at 11:41
  • @user30654 Added the code – egreg Apr 17 at 16:01
  • Your new code is all working fine, thank you very much ! – user30654 Apr 18 at 14:28
3

This version omits the space if \innerbox is in any hbox, not just \outerbox

enter image description here

\documentclass{article}

\newcommand{\mymargin}{\hspace*{3em}}
\newcommand{\innerbox}[1]{\ifhmode\ifinner\else\mymargin\fi\fi\fbox{#1}\ifhmode\ifinner\else\mymargin\fi\fi}
\newcommand{\outerbox}[1]{\fbox{#1}}

\begin{document}

test \innerbox{Hello} test% OK

test \outerbox{\innerbox{Hello} test \innerbox{Hello} test \innerbox{Hello}}%   I don't want space at beginning and end of box

test \outerbox{\fbox{Hello}\mymargin{} test \innerbox{Hello} test \mymargin\fbox{Hello}}%   what i'd like

\end{document}

egreg notes that you may not be what you wanted, so..

enter image description here

\documentclass{article}

\newcommand{\mymargin}{\hspace*{3em}}
\newcommand{\innerbox}[1]{\ifhmode\ifnum\lastpenalty=-1\else\mymargin\fi\fi\fbox{#1}\mymargin}
\newcommand{\outerbox}[1]{\fbox{\penalty-1#1\unskip\unskip}}

\begin{document}

test \innerbox{Hello} test% OK

test \outerbox{\innerbox{Hello} test \innerbox{Hello} test \innerbox{Hello}}%   I don't want space at beginning and end of box

test \outerbox{\fbox{Hello}\mymargin{} test \innerbox{Hello} test \mymargin\fbox{Hello}}%   what i'd like

\end{document}
  • Which is rather different from the output the OP seems to want. Look at the “what I'd like” line. – egreg Apr 16 at 16:51
  • @egreg 2nd version added (shame, first version was more fun) – David Carlisle Apr 16 at 17:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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