LaTeX forum ⇒ GeneralWrapper for subcaptionbox: automatic vertical alignment Topic is solved

LaTeX specific issues not fitting into one of the other forums of this category.
woj-k
Posts: 15
Joined: Wed Jul 28, 2010 7:25 pm

Wrapper for subcaptionbox: automatic vertical alignment

Postby woj-k » Thu Jun 13, 2013 9:44 pm

Hello everyone,

I got stuck on designing easy-to-use command wrappers for multipanel floats (i.e. subfigures/subtables) built around the subcaption package. The problem has to do with vertical alignment of the individual panels of the float: the 'default' behaviour I have observed is bottom-alignment, but I would like the users to be able to specify rows where the panels are verticaly centered or top-aligned. This would require raising some of the panels by an amount which is dependent on the height of the 'tallest' panel in the given row.

In the MWE below I have omitted top-aligned panels for brevity.

The panel-environment evaluates its contents and dumps them into a macro \panelcontents. Although it does nothing with this value, it does evaluate the contents' height and stores it in \currentpanelheight---I imagine the final version will have to do it anyway, to decide which panel is the tallest automatically.

The problem disappears if I specify the tallest panel's height by hand (line 89 of the MWE). It is to have LaTeX determine this value automatically for each row that poses a problem. I considered a solution where each panel exports a value to an external file, and a separate macro selects the tallest panel on a subsequent run, rather than on-the-fly. There is probably a more elegant way to do it, but I am missing a piece of the puzzle. Can anyone offer any advice?

  1. \documentclass{book}
  2. \usepackage{subcaption}
  3. \usepackage[labelsep=space]{caption}
  4.  
  5. %Housekeeping code
  6. \newlength\tallestpanelinrow
  7. \newlength\currentpanelheight
  8. \newlength\currentpanelwidth
  9.  
  10. \newif\ifcenterpanels
  11. \newif\ifbottomalignpanels
  12.  
  13. \newcommand{\CenterPanels}{%
  14. \centerpanelstrue
  15. \bottomalignpanelsfalse
  16. }%
  17. \newcommand{\BottomAlignPanels}{%
  18. \centerpanelsfalse
  19. \bottomalignpanelstrue
  20. }%
  21. \BottomAlignPanels
  22.  
  23.  
  24. %Row environments
  25. \newenvironment{Bpanelrow}{\par\BottomAlignPanels}{}
  26.  
  27. %Centered panels dump contents in a savebox
  28. %for future repositioning
  29. \newsavebox{\rowpanelbox}
  30. \newenvironment{Cpanelrow}{\par\CenterPanels%
  31. \begin{lrbox}{\rowpanelbox}}%
  32. {\end{lrbox}%
  33. \usebox\rowpanelbox%
  34. }
  35.  
  36.  
  37. %The panel environment
  38. \newsavebox{\panelbox}
  39. \newenvironment{panel}[2][1.0]{%
  40. %Housekeeping code
  41. \setlength{\currentpanelwidth}{#1\textwidth}%
  42. \def\panellabel{#2}%
  43. %This code stores the panelcontents in the \panelbin savebox
  44. \begin{lrbox}{\panelbox}}{\end{lrbox}%
  45. \def\panelcontents{\usebox\panelbox}%
  46. %The panel contents are now stored in \panelcontents
  47. %
  48. %Initialise \currentpanelheight
  49. \settoheight{\currentpanelheight}{\panelcontents}
  50. %
  51. %First panel assumes it is the tallest, if no tallest panel has been defined
  52. \ifdim\tallestpanelinrow<0pt%
  53. \setlength{\tallestpanelinrow}{\currentpanelheight}
  54. \fi
  55. %
  56. %Output the panel
  57. \ifbottomalignpanels
  58. \subcaptionbox{\strut\label{\panellabel}}%
  59. [\currentpanelwidth]%
  60. {\vbox to\tallestpanelinrow{\vfil\hbox{\panelcontents}}}%
  61. \else\ifcenterpanels
  62. \subcaptionbox{\strut\label{\panellabel}}%
  63. [\currentpanelwidth]%
  64. {\vbox to\tallestpanelinrow{\vfil\hbox{\panelcontents}\vfil}}%
  65. \fi
  66. \fi
  67. }
  68.  
  69. %The table
  70. \newenvironment{multipaneltable}[3][tbhp]{%
  71. \begin{table}[#1]
  72. \begin{center}%
  73. \captionsetup{type=table,hypcap=false,position=bottom,subrefformat=parens}
  74. \caption{#2\label{#3}}%
  75. \setlength{\tallestpanelinrow}{-1pt}%To detect first panel
  76. }%
  77. {%
  78. \end{center}%
  79. \end{table}%
  80. }
  81.  
  82.  
  83.  
  84. \begin{document}
  85.  
  86. Some text.
  87.  
  88. \begin{multipaneltable}[h]{Caption goes here.}{tablelabel}%
  89. %
  90. %Un-comment this line to make vert. alignment work.
  91. %\setlength{\tallestpanelinrow}{8em}
  92. %
  93. \begin{Bpanelrow}
  94. \begin{panel}[0.2]{panelone}
  95. \rule{1em}{8em}
  96. \end{panel}
  97. \begin{panel}[0.2]{paneltwo}
  98. \rule{1em}{1em}
  99. \end{panel}
  100. \begin{panel}[0.2]{panelthree}
  101. \rule{1em}{3em}
  102. \end{panel}
  103. \end{Bpanelrow}
  104. %
  105. \begin{Cpanelrow}
  106. \begin{panel}[0.2]{panelfour}
  107. \rule{1em}{8em}
  108. \end{panel}
  109. \begin{panel}[0.2]{panelfive}
  110. \rule{1em}{1em}
  111. \end{panel}
  112. \begin{panel}[0.2]{panelsix}
  113. \rule{1em}{3em}
  114. \end{panel}
  115. \end{Cpanelrow}
  116. %
  117. \begin{Cpanelrow}
  118. \begin{panel}[0.2]{panelfour}
  119. \rule{1em}{1em}
  120. \end{panel}
  121. \begin{panel}[0.2]{panelfive}
  122. \rule{1em}{3em}
  123. \end{panel}
  124. \begin{panel}[0.2]{panelsix}
  125. \rule{1em}{8em}
  126. \end{panel}
  127. \end{Cpanelrow}
  128. %
  129. \end{multipaneltable}
  130.  
  131. Some text.
  132.  
  133. \end{document}
Last edited by woj-k on Mon Jun 17, 2013 2:27 pm, edited 1 time in total.

Tags:

woj-k
Posts: 15
Joined: Wed Jul 28, 2010 7:25 pm

Postby woj-k » Mon Jun 17, 2013 2:26 pm

Fixed up a solution using the \VerbatimOut facility of the fancyvrb package, with export of each row to an external file and using the code twice---once to determine the size and once to print the correctly aligned row. It all happens on the same run. Had to redefine \panel for the size-determination step, and for some reason I could not simply return it to the previous version using \global\let---had to use \renewcommand again instead. Here's a top-aligned and centred example.

  1. \documentclass{article}
  2. \usepackage{fancyvrb,caption}
  3. \usepackage[labelsep=space]{subcaption}
  4.  
  5. \newlength\currentheight
  6. \newlength\tallesttemp
  7. \newlength\currentpanelwidth
  8.  
  9.  
  10. \newenvironment{multipaneltable}[3][tbhp]{%
  11. \begin{table}[#1]%
  12. \begin{center}%
  13. \captionsetup{type=table,hypcap=false,position=bottom,subrefformat=parens}%
  14. \caption{#2\label{#3}}%
  15. }%
  16. {\end{center}\end{table}}
  17.  
  18.  
  19. \newenvironment{Cpanelrow}%
  20. {%
  21. \newcommand{\panel}[3][1.0]{\setlength{\tallesttemp}{0.0pt}%
  22. \setlength{\currentpanelwidth}{##1\textwidth}%
  23. \gdef\panellabel{##2}%
  24. \gdef\panelcontents{##3}%
  25. \settoheight{\currentheight}{\panelcontents}\addtolength{\tallesttemp}{-\currentheight}%
  26. \subcaptionbox{\strut\label{\panellabel}}[\currentpanelwidth]{\raisebox{0.5\tallesttemp}{\panelcontents}}}%
  27. \VerbatimOut{\jobname.pnl}%
  28. }%
  29. {%
  30. \endVerbatimOut\par%
  31. \renewcommand{\panel}[3][1.0]{\gdef\panelcontents{##3}\raisebox{0.5\tallesttemp}{\panelcontents}}%
  32. \settoheight{\tallesttemp}{\input{\jobname.pnl}}%
  33. \xdef\hhtemp{\the\tallesttemp}%
  34. %
  35. \renewcommand{\panel}[3][1.0]{\setlength{\tallesttemp}{0.0pt}%
  36. \setlength{\currentpanelwidth}{##1\textwidth}%
  37. \gdef\panellabel{##2}%
  38. \gdef\panelcontents{##3}%
  39. \settoheight{\currentheight}{\panelcontents}%
  40. \setlength{\tallesttemp}{\hhtemp}%
  41. \addtolength{\tallesttemp}{-\currentheight}%
  42. \subcaptionbox{\strut\label{\panellabel}}[\currentpanelwidth]{\raisebox{0.5\tallesttemp}{\panelcontents}}}%
  43. %
  44. \input{\jobname.pnl}%
  45. }%
  46.  
  47. \newenvironment{Tpanelrow}%
  48. {%
  49. \newcommand{\panel}[3][1.0]{\setlength{\tallesttemp}{0.0pt}%
  50. \setlength{\currentpanelwidth}{##1\textwidth}%
  51. \gdef\panellabel{##2}%
  52. \gdef\panelcontents{##3}%
  53. \settoheight{\currentheight}{\panelcontents}\addtolength{\tallesttemp}{-\currentheight}%
  54. \subcaptionbox{\strut\label{\panellabel}}[\currentpanelwidth]{\raisebox{1.0\tallesttemp}{\panelcontents}}}%
  55. \VerbatimOut{\jobname.pnl}%
  56. }%
  57. {%
  58. \endVerbatimOut\par%
  59. \renewcommand{\panel}[3][1.0]{\gdef\panelcontents{##3}\raisebox{1.0\tallesttemp}{\panelcontents}}%
  60. \settoheight{\tallesttemp}{\input{\jobname.pnl}}%
  61. \xdef\hhtemp{\the\tallesttemp}%
  62. %
  63. \renewcommand{\panel}[3][1.0]{\setlength{\tallesttemp}{0.0pt}%
  64. \setlength{\currentpanelwidth}{##1\textwidth}%
  65. \gdef\panellabel{##2}%
  66. \gdef\panelcontents{##3}%
  67. \settoheight{\currentheight}{\panelcontents}%
  68. \setlength{\tallesttemp}{\hhtemp}%
  69. \addtolength{\tallesttemp}{-\currentheight}%
  70. \subcaptionbox{\strut\label{\panellabel}}[\currentpanelwidth]{\raisebox{1.0\tallesttemp}{\panelcontents}}}%
  71. %
  72. \input{\jobname.pnl}%
  73. }%
  74. \begin{document}
  75.  
  76. \begin{multipaneltable}{Vertical alignment: \subref{panelonelabel}--\subref{panelthreelabel}~centred row; \subref{panelfourlabel}--\subref{panelsixlabel}~top-aligned row.}{tab:tablelabel}
  77. \begin{Cpanelrow}
  78. \panel[0.2]{panelonelabel}{\rule{4em}{5em}}
  79. \panel[0.2]{paneltwolabel}{\rule{4em}{2em}}
  80. \panel[0.2]{panelthreelabel}{\rule{4em}{8em}}
  81. \end{Cpanelrow}
  82. \begin{Tpanelrow}
  83. \panel[0.2]{panelfourlabel}{\rule{4em}{6em}}
  84. \panel[0.2]{panelfivelabel}{\rule{4em}{3em}}
  85. \panel[0.2]{panelsixlabel}{\rule{4em}{1em}}
  86. \end{Tpanelrow}
  87. \end{multipaneltable}
  88.  
  89. \end{document}


Return to “General”

Who is online

Users browsing this forum: No registered users and 10 guests