5

I try to align some HEX numbers in the style of 0x1FFFF and 0x00001 in a table. They have to be aligned to the right, but I also want them to have the same witdh per character, despite an F beeing a lot wider than a 0 or any other number. Otherwise it looks really silly when the 0x in the beginning do not aling with each other...

This code here

\begin{table}
\begin{center}
\begin{tabular}{@{}lr@{}} 
\toprule
\textbf{DEC} \hspace{10mm}      & \textbf{HEX} \\ 
\midrule
1           & 0x00001  \\
2           & 0x00002  \\
100         & 0x00064  \\   
131.071     & 0x1FFFF  \\
262143      & 0x3FFFF  \\
\bottomrule
\end{tabular}
\end{center}
\end{table}

creates this table

enter image description here

Is there some way to align the numbers on the right properly, so that I does not look like different amount of digits?

  • 5
    Welcome to TeX.SX! You probably need a monospaced font... – TeXnician Aug 9 '17 at 8:22
  • GOV.UK has a separate font which is identical to their main font, but with equally spaced characters. The font is specifically for tabular data like this. – ESR Aug 10 '17 at 5:04
12

Same width per character means that you need a font which matches this requirement. Usually that's a mono-spaced font you can access with \texttt.

hex

\documentclass{article}
\usepackage{booktabs}
\usepackage{array}
\begin{document}
\begin{table}
\centering
\begin{tabular}{@{}l>{\ttfamily}r@{}} 
\toprule
\textbf{DEC} \hspace{10mm}      & \textbf{HEX} \\ 
\midrule
1           & 0x00001  \\
2           & 0x00002  \\
100         & 0x00064  \\   
131.071     & 0x1FFFF  \\
262143      & 0x3FFFF  \\
\bottomrule
\end{tabular}
\end{table}
\end{document}
  • Ah, that seems a bit curious, when one column is in a different style, but it works. Thanks ;) – jusaca Aug 9 '17 at 8:36
  • is the \arraybackslash in the socund column definition really needed? also instead of \begin{center} ... \end{center}` is better \centering and all columns to use the same font family :) – Zarko Aug 9 '17 at 9:00
  • @Zarko Well, no. And you're right. I'll update. – TeXnician Aug 9 '17 at 9:01
6

Instead of a real monospaced font you could also fake it:

\documentclass{article}
\usepackage{booktabs}

\newcommand*{\fakemonochar}[1]{\makebox[.6em][c]{#1}}
\makeatletter
\newcommand*{\fakemonotext}[1]{%
  \@fakemonotext#1\\%
}
\newcommand*{\@fakemonotext}[1]{%
  \ifx #1\\\else\fakemonochar{#1}\expandafter\@fakemonotext\fi
}
\makeatother 

\begin{document}

\begin{tabular}{@{}lrr@{}} 
\toprule
\textbf{DEC} & \textbf{HEX} (faked) & \textbf{HEX} (mono)\\ 
\midrule
1           & \fakemonotext{0x00001} & \texttt{0x00001} \\
2           & \fakemonotext{0x00002} & \texttt{0x00002} \\
100         & \fakemonotext{0x00064} & \texttt{0x00064} \\   
131.071     & \fakemonotext{0x1FFFF} & \texttt{0x1FFFF} \\
262143      & \fakemonotext{0x3FFFF} & \texttt{0x3FFFF} \\
\bottomrule
\end{tabular}
\end{document}

comparing faked monospaced and real monospaced

  • 1
    Very nice idea. – TeXnician Aug 9 '17 at 9:03
  • @TeXnician I do not like the faked monospace. The letters are OK, but the digits … ugly. If I could, I would down-vote this answer. ;-) – Schweinebacke Aug 9 '17 at 9:21
  • 1
    I do not like the appearance either, but I like the idea to fake mono with boxes. – TeXnician Aug 9 '17 at 9:23
  • @TeXnician You could also use \newcommand*{\fakemonotext}[1]{\makebox[4em][s]{\fontdimen4\font=\fontdimen2\font #1}} and \fakemonotext{0x0 0 0 0 1}. This could even be used with a p-column with initial \fontdimen change. Then you would not need \fakemonotext. But the input in both cases have to be with spaces to have inter word space between the hex digits. – Schweinebacke Aug 9 '17 at 9:34
3

You can let TeX do the computations!

\documentclass{article}

\usepackage{xparse,booktabs,siunitx}

\ExplSyntaxOn
\NewDocumentCommand{\hexnum}{ O{ \l_hexnum_pad_int } m }
 {
  \hexnum_print:nn { #1 } { #2 }
 }
\NewDocumentCommand{\hexrow}{ O{ \l_hexnum_pad_int } m }
 {
  \num{#2} & \hexnum_print:nn { #1 } { #2 }
 }
\NewDocumentCommand{\sethexnumpad}{m}
 {
  \int_set:Nn \l_hexnum_pad_int { #1 }
 }

\int_new:N \l_hexnum_pad_int

\cs_new_protected:Nn \hexnum_print:nn
 {
  \texttt{ 0x \hexnum_pad:nf { #1 } { \int_to_Hex:n { #2 } } }
 }

\cs_new:Nn \hexnum_pad:nn
 {
  \int_compare:nF { #1 == 0 }
  {
   \prg_replicate:nn { #1 - \tl_count:n { #2 } } { 0 }
  }
  #2
 }
\cs_generate_variant:Nn \hexnum_pad:nn { nf }

\ExplSyntaxOff

\sethexnumpad{5} % initialize

\begin{document}

Stand alone: \hexnum[0]{35671} or \hexnum{35671}

\bigskip

\begin{tabular}{ l r }
\toprule
{DEC} & \multicolumn{1}{c}{HEX} \\
\midrule
\hexrow{1} \\
\hexrow{2} \\
\hexrow{100} \\
\hexrow{131071} \\
\hexrow{262143} \\
\bottomrule
\end{tabular}
%
\sethexnumpad{8}
%
\begin{tabular}{ l r }
\toprule
{DEC} & \multicolumn{1}{c}{HEX} \\
\midrule
\hexrow[1]{1} \\
\hexrow{2} \\
\hexrow{100} \\
\hexrow{131071} \\
\hexrow{262143} \\
\bottomrule
\end{tabular}

\end{document}

The padding is done to \l_hexnum_pad_int digits, which you can set either with \sethexnumpad or with the optional argument to \hexnum (or \hexrow that's a wrapper to it). If the value is set to 0, no padding is done.

enter image description here

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.