10

Assuming the following structure (auto-generated from another document), how should I define \csup and \csub to line the sup boxes to line up with the top of the neighbouring box, and the sub boxes to line up with the bottom?

\documentclass{article}
\newcommand*{\csup}[1]{\scriptsize{#1}}
\newcommand*{\csub}[1]{\scriptsize{#1}}
\newcommand*{\cnotation}[1]{#1}
\newcommand*{\crepeat}[1]{\fbox{#1}}
\newcommand*{\cwrapper}[1]{#1}

\begin{document}
\cwrapper{\crepeat{%
    AAA
    \cwrapper{\crepeat{%
        BBB
        \cwrapper{\crepeat{CCC}\csup{pC}\csub{bC}}}
      \csup{pB}\csub{bB}}}
  \csup{pA}\csub{bA}}
\end{document}

In other words, how do I change the document to produce this:

desired result

instead of this?

current result

I tried raisebox and adjustbox, but the following is the best I could get:

\newcommand*{\csup}[1]{\adjustbox{valign=t}{\scriptsize{\rlap{#1}}}}
\newcommand*{\csub}[1]{\adjustbox{valign=b}{\scriptsize{#1}}}

failed-attempt

0

4 Answers 4

7

(simplified the answer to show both candidate solution methods in one go)

Here are two candidate solutions. The first positions the sub- and superscript terms relative to the right-hand edge of the immediately preceding box, while the second ignores the height of the immediately preceding box.

The main changes, relative to your code, are (a) making \cwrapper take three arguments (#1: the material to be placed in a box; #2 and #3: the superscript and subscript terms) and (b) using math mode to help position the super- and subscript terms relative to the preceding material.

enter image description here

\documentclass{article}
\newcommand*{\cscr}[1]{\textnormal{\scriptsize #1}}
\newcommand*{\cwrappera}[3]{%
    $\left.{\textnormal{\fbox{#1}}}\ \right.^{\cscr{#2}}_{\cscr{#3}}$}
\newcommand*{\cwrapperb}[3]{%
    \fbox{#1} ${\vphantom{\textnormal{#1}}}^{\cscr{#2}}_{\cscr{#3}}$}

\begin{document}
\cwrappera{AAA
    \cwrappera{BBB
        \cwrappera{CCC}{pC}{bC}}
        {pB}{bB}}
    {pA}{bA} 

\medskip
\cwrapperb{AAA
    \cwrapperb{BBB
        \cwrapperb{CCC}{pC}{bC}}
        {pB}{bB}}
    {pA}{bA}        
\end{document}
4
  • Yes! So there's no way around wrapping everything in math?
    – Clément
    Commented May 22, 2016 at 7:01
  • @Clément - One has to make the subscript and superscript terms aware of the vertical dimensions of the preceding rectangular box, right? Encasing the box in a \left. ... \right. "wrapper" achieves this objective. There may well be other methods.
    – Mico
    Commented May 22, 2016 at 7:04
  • @Clément - I've updated my answer to provide an additional solution method and to display the output of the two solution methods in one and the same screenshot.
    – Mico
    Commented May 22, 2016 at 7:41
  • Thanks Mico. Your first solution works really nicely, and it actually doesn't require changing the signature of my command (which is great, because the LaTeX is auto-generated by Sphinx). However, the math aspect breaks hyperref; no idea why. I've open another question about that.
    – Clément
    Commented May 22, 2016 at 8:16
4

The original syntax of the OP can be preserved with this formulation:

\documentclass{article}
\usepackage{amsmath}
\newcommand*{\csub}[1]{_\textnormal{~#1}}
\newcommand*{\csup}[1]{^\textnormal{~#1}}
\newcommand*{\cnotation}[1]{#1}
\newcommand*{\crepeat}[1]{\fbox{#1}}
\newcommand*{\cwrapper}[1]{\ensuremath{#1}}
\begin{document}
\cwrapper{\crepeat{%
    AAA
    \cwrapper{\crepeat{%
        BBB
        \cwrapper{\crepeat{CCC}\csup{pC}\csub{bC}}}
      \csup{pB}\csub{bB}}}
  \csup{pA}\csub{bA}}
\end{document}

enter image description here

I use \cwrapper to ensure math mode, and then use \csub and \csup to employ math sub and superscripts with \text macros.


If one wants the sub- and superscripts tighter, then this would do, where I have moved the subscript up 1pt and the superscript down 2.5pt:

\documentclass{article}
\usepackage{amsmath}
\newcommand*{\csub}[1]{_\textnormal{~#1}}
\newcommand*{\csup}[1]{^\textnormal{~#1}}
\newcommand*{\cnotation}[1]{#1}
\newcommand*{\crepeat}[1]{\setbox0=\hbox{\fbox{#1}}\ht0=\dimexpr\ht0-2.5pt\relax%
  \dp0=\dimexpr\dp0-1pt\relax\box0}
\newcommand*{\cwrapper}[1]{\ensuremath{#1}}
\begin{document}
\cwrapper{\crepeat{%
    AAA
    \cwrapper{\crepeat{%
        BBB
        \cwrapper{\crepeat{CCC}\csup{pC}\csub{bC}}}
      \csup{pB}\csub{bB}}}
  \csup{pA}\csub{bA}}
\end{document}

enter image description here

10
  • Neat, +1; that's exactly what I was referring to in my comment to Mico.
    – Clément
    Commented May 22, 2016 at 21:03
  • 1
    Are _ and ^ reversed in the definitions of \csub and \csup? Separately, for extra stability -- and to improve the chances of getting @egreg's stamp of approval :-) -- one might also replace ^\text{~#1} with ^{\textnormal{~#1}}, etc.
    – Mico
    Commented May 22, 2016 at 21:13
  • @Clément That's not the alginment you asked for is it? It doesn't match what's shown in your target image. (I matched the target although the question leaves the handling of a subscript with a descender ambiguous.)
    – cfr
    Commented May 22, 2016 at 22:36
  • @cfr: Looks fine to me :) What do you think is wrong with it?
    – Clément
    Commented May 23, 2016 at 4:31
  • @Clément I meant in the first one, I think.
    – cfr
    Commented May 23, 2016 at 20:33
3

Here's a version respecting the clumsy syntax you want.

\documentclass{article}

\makeatletter
\newcommand{\cwrapper}[1]{%
  \leavevmode\check@mathfonts
  \begingroup\ignorespaces
  #1%
  \clement@wrap
  \endgroup
}
\newcommand{\crepeat}[1]{%
  \def\clement@repeat{#1}\ignorespaces
}
\newcommand{\csup}[1]{\def\clement@sup{#1}\ignorespaces}
\newcommand{\csub}[1]{\def\clement@sub{#1}\ignorespaces}
\newcommand{\clement@wrap}{%
  \sbox\z@{\fbox{\clement@repeat}}%
  \copy\z@
  \raisebox{-\dp\z@}{%
    \vbox to \dimexpr\ht\z@+\dp\z@{
      \hrule height\z@
      \hbox{\fontsize\sf@size\z@\selectfont\clement@sup}
      \vss
      \hbox{\fontsize\sf@size\z@\selectfont\clement@sub}
      \hrule height\z@
    }%
  }%
}
\makeatother

\begin{document}

\cwrapper{\crepeat{AAA}\csup{a}\csub{b}}

\cwrapper{\crepeat{%
    AAA
    \cwrapper{\crepeat{%
        BBB
        \cwrapper{\crepeat{CCC}\csup{pC}\csub{bC}}}
      \csup{pB}\csub{bB}}}
  \csup{pA}\csub{bA}}

\Large
\cwrapper{\crepeat{AAA}\csup{a}\csub{b}}

\end{document}

Note that also font size changes are respected.

enter image description here

0
3

Just because it is there, here's a version which uses coffins to arrange and typeset the boxes.

The syntax is identical to that specified in the question except that \cwrapper can take an optional argument specifying the horizontal distance between the larger box and the superscript and subscripts. Since this is optional, the OP's syntax can be used unchanged. In that case, the default is 1pt, but this can obviously be modified as desired.

Essentially, each of \csup, \csub and \crepeat is defined to put its content into a coffin. \cwrapper is defined to join the coffins appropriately and typeset the result. Nesting works as expected, as shown in the extended example below.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\coffin_new:N \l_clement_main_coffin
\coffin_new:N \l_clement_tmpa_coffin
\coffin_new:N \l_clement_sup_coffin
\coffin_new:N \l_clement_sub_coffin
\dim_new:N \l_clement_spacer_dim
\NewDocumentCommand \csup { m }
{
  \hcoffin_set:Nn \l_clement_sup_coffin { \scriptsize #1 }
}
\NewDocumentCommand \csub { m }
{
  \hcoffin_set:Nn \l_clement_sub_coffin { \scriptsize #1 }
}
\NewDocumentCommand \crepeat { m }
{
  \hcoffin_set:Nn \l_clement_tmpa_coffin { \fbox { \tl_trim_spaces:n { #1 } } }
}
\NewDocumentCommand \cwrapper { O { 1pt } m }
{
  \group_begin:
    \clement_cwrapper:nn { #1 } { #2 }
  \group_end:
}
\cs_generate_variant:Nn \coffin_join:NnnNnnnn { NnnNnnVn }
\cs_new_protected:Npn \clement_cwrapper:nn #1 #2
{
  #2
  \dim_set:Nn \l_clement_spacer_dim { #1 }
  \coffin_join:NnnNnnVn \l_clement_tmpa_coffin { r } { t } \l_clement_sup_coffin { l } { t } \l_clement_spacer_dim { 0pt }
  \coffin_join:NnnNnnVn \l_clement_tmpa_coffin { \l_clement_tmpa_coffin-r } { \l_clement_tmpa_coffin-b } \l_clement_sub_coffin { l } { b } \l_clement_spacer_dim { 0pt }
  \coffin_set_eq:NN \l_clement_main_coffin \l_clement_tmpa_coffin
  \coffin_typeset:Nnnnn \l_clement_main_coffin { l } { H } { 0pt } { 0pt }
}
\ExplSyntaxOff
\begin{document}
\cwrapper{\crepeat{%
    AAA
  }%
  \csup{pA}\csub{bA}%
}

\cwrapper{\crepeat{%
    AAA
    \cwrapper{\crepeat{%
        BBB
      }%
      \csup{pB}\csub{bB}%
    }%
  }%
  \csup{pA}\csub{bA}%
}

\cwrapper{\crepeat{%
    AAA
    \cwrapper{\crepeat{%
        BBB
        \cwrapper{\crepeat{CCC}\csup{pC}\csub{bC}%
        }%
      }%
      \csup{pB}\csub{bB}%
    }%
  }%
  \csup{pA}\csub{bA}%
}

\cwrapper[5pt]{\crepeat{%
    AAA
    \cwrapper{\crepeat{%
        BBB
        \cwrapper[10pt]{\crepeat{CCC}\csup{pC}\csub{bC}%
        }%
      }%
    }%
  }%
  \csup{pA}\csub{bA}%
}

\cwrapper{\crepeat{%
    AAA
    \cwrapper{\crepeat{%
        BBB
        \cwrapper{\crepeat{CCC}\csup{pC}%
        }%
      }%
      \csub{bB}%
    }%
  }%
}

\end{document}

coffin series

5
  • 1
    Bonus point for naming something clement_main_coffin :) But that doesn't really match what I was looking for: the baselines of AAA, BBB, and CCC are not aligned in your example.
    – Clément
    Commented May 23, 2016 at 4:32
  • @Clément Ah. You're right - I missed that. I'll take a look later. (About to leave here now as need to catch a bus.)
    – cfr
    Commented May 23, 2016 at 20:33
  • @Clément Please see edit. I think you just wanted to pick a different pole? Is H right?
    – cfr
    Commented May 23, 2016 at 23:04
  • Brilliant, spot on. I had never hear of TeX coffins before.
    – Clément
    Commented May 24, 2016 at 2:59
  • 1
    @Clément I've been playing with them and they are kind of cool. I'm quite impressed they do so well nested like this. Take a look at the documentation for xcoffins - kind of neat, though I find they take some getting used to ;).
    – cfr
    Commented May 24, 2016 at 3:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .