[Tex/LaTex] Centering clrscode3e codebox horizontally

algorithmshorizontal alignment

How can I center a codebox (from clrscode3e package) horizontally in a document ?

Best Answer

Since the codebox is ultimately typeset in a tabbing environment, its width may vary. Moreover, it is typeset in a box which is only processed at the end of the codebox environment. As such, you would need a slight work-around in order to center it horizontally.

The varwidth package is capable of shrinking its width to the natural width of its contents. As such, wrapping the codebox environment within a varwidth environment allows for centering capability:

enter image description here

\documentclass{article}
\usepackage[showframe]{geometry}% http://ctan.org/pkg/geometry
\usepackage{clrscode3e}% http://www.cs.dartmouth.edu/~thc/clrscode/
\usepackage{varwidth}% http://ctan.org/pkg/varwidth
\begin{document}
\begin{center}
  \begin{varwidth}{\linewidth}
    \begin{codebox}
      \Procname{$\proc{Insertion-Sort}(A)$}
      \li \For $j \gets 2$ \To $\attrib{A}{length}$
      \li \Do $\id{key} \gets A[j]$
      \li \Comment Insert $A[j]$ into the sorted sequence $A[1 \twodots j-1]$.
      \li $i \gets j-1$
      \li \While $i > 0$ and $A[i] > \id{key}$
      \li \Do
            $A[i+1] \gets A[i]$
      \li $i \gets i-1$
          \End
      \li $A[i+1] \gets \id{key}$
      \End
    \end{codebox}
  \end{varwidth}
\end{center}
\end{document}

The varwidth environment is set to the maximum (\linewidth), since it will shrink to the desired width if the codebox is not as wide.

The showframe option to geometry allows for a visual of the text block boundaries.


My original approach was to use the savepos module of the zref package to mark the left-most and right-most points in the code via the macro \zsavepos{<label>}. Then, using \zposx{<ref>}, one can extract the x-coordinate (in small point sp units) of the label. So, marking the left-most point using \zsavepos{codeL} and the right-most point using \zsavepos{codeR},

\dimexpr\zposx{codeR}sp-\zposx{codeL}sp\relax

gives the horizontal width (or dimension) of the codebox. Subsequently, putting the entire codebox environment in a minipage of this width allows us to constrain the horizontal span and center the object. The correct width also avoids overfull \hbox warnings (if a chosen minipage width is too small) or incorrect centering (if a chosen minipage width is too large).

\documentclass{article}
\usepackage[showframe]{geometry}% http://ctan.org/pkg/geometry
\usepackage{clrscode3e}% http://www.cs.dartmouth.edu/~thc/clrscode/
\usepackage[savepos]{zref}% http://ctan.org/pkg/zref
\begin{document}
\begin{center}
  \begin{minipage}{\dimexpr\zposx{codeR}sp-\zposx{codeL}sp\relax}
    \begin{codebox}
      \Procname{\zsavepos{codeL}$\proc{Insertion-Sort}(A)$}
      \li \For $j \gets 2$ \To $\attrib{A}{length}$
      \li \Do $\id{key} \gets A[j]$
      \li \Comment Insert $A[j]$ into the sorted sequence $A[1 \twodots j-1]$.\zsavepos{codeR}
      \li $i \gets j-1$
      \li \While $i > 0$ and $A[i] > \id{key}$
      \li \Do
            $A[i+1] \gets A[i]$
      \li $i \gets i-1$
          \End
      \li $A[i+1] \gets \id{key}$
      \End
    \end{codebox}
  \end{minipage}
\end{center}
\end{document}

The above code (or procedure) was taken directly from the clrscode3e package documentation. The right-most label depends on the code segment being typeset, while the left-most label is typeset to the left of the procedure name. However, it is not necessary for the final production and centering capabilities. Since this uses the zref package, at least two compiles are required to obtain the correct positioning of the labels/references.

Related Question