1

I wish to define such a command with which one can skip to a horizontal position that is an integer multiple of 1em. For example, if one is at the position 1.2em from left, then with this command one should arrive at the position 2em from left.

I have some idea in mind using \zsaveposx of the zref package, but the code would be long and tricky. I also read this question, which mentioned the tabto package, which I think might be useful, but I don't know how much to tab to.

How could one define such a command?

Jinwen
  • 8,518
  • using \zsavepos (or the underlying \pdfsavepos primitive) will always take at least two latex runs and be unstable if you have more than one of these in a paragraph, taking more runs to converge. In almost all cases such an alignment is more naturally achieved in tex using an \halign based alignment such as tabular or tabbing, what is the actual use case here? – David Carlisle Feb 01 '21 at 15:22
  • @DavidCarlisle I'm using a typewriter font and am trying to make characters vertically aligned. Elements like math or non-monospaced character can disrupt this alignment and thus I want such a command to make the following characters aligned. – Jinwen Feb 01 '21 at 15:30
  • note that tex does a least cost line breaking calculation over an entire paragraph so adding a comma in the last line can affect the line breaking in the whole paragraph changing which is the "next" tab for any places in the para where you are using this command. – David Carlisle Feb 01 '21 at 15:31
  • easier just to make sure every inline math expression is a multiple of your character width. – David Carlisle Feb 01 '21 at 15:32
  • @DavidCarlisle How to "make every inline math expression is a multiple of character width"? I thought it was impossible as I was once told modifying math environment would be dangerous. – Jinwen Feb 01 '21 at 15:35

2 Answers2

2

If the real use case is to ensure that inline math does not disturb the character alignment you can place it in a box that is a multiple of the character width, compare the first and second block here

enter image description here

\documentclass{article}

\newcommand\zz[1]{{\ttfamily\sbox0{$#1$}% \sbox2{A}% \makebox[\numexpr1+(\wd0/\wd2)\relax\wd2]{\usebox0}}}

\begin{document} \raggedright \ttfamily

ABCDEF ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ZZ ABCDEF ONE WO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ABCDEF ONE TWO Z $x^2+\alpha$ THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ABCDEF ONE TWO Z THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ABCDEF ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ABCDEF ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN

\bigskip

ABCDEF ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ZZ ABCDEF ONE WO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ABCDEF ONE TWO Z \zz{x^2+\alpha} THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ABCDEF ONE TWO Z THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ABCDEF ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ABCDEF ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN

\end{document}

David Carlisle
  • 757,742
2

This makes use of the fact that lengths can be stored in \newcount registers as numbers (in sp units). With this trick, I can divide two lengths using \divide and achieve truncation of the decimal portion.

The macro \nexttab tabs to the next increment of \reflen, here specified as 1em. In the MWE, I place an X at the next available tab location. The rules underneath are there merely to confirm the authenticity of the tab.

\documentclass{article}
\usepackage{tabto}
\newlength\reflen
\newcount\z
\newcount\refsp
\reflen=1em
\refsp=\reflen
\newcommand\nexttab{%
  \tabto*{0em}%
  \z=\TabPrevPos
  \divide\z by \refsp
  \tabto{\the\numexpr\z +1\relax\reflen}%
}
\begin{document}
\noindent This is a test\nexttab X\\
This is a\nexttab X\\
This is\nexttab X\\
This\nexttab X

\noindent\smash{% \rule{.02\reflen}{2ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{2ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{2ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{5ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{8ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{8ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{11ex}\rule{.98\reflen}{1pt}} \end{document}

enter image description here

If \reflen is adjusted to 1.1em, the result is

enter image description here

Finally, we learn that a CM m is actually 0.84em in width

\documentclass{article}
\usepackage{tabto}
\newlength\reflen
\newcount\z
\newcount\refsp
\reflen=.84em
\refsp=\reflen
\newcommand\nexttab{%
  \tabto*{0em}%
  \z=\TabPrevPos
  \divide\z by \refsp
  \tabto{\the\numexpr\z +1\relax\reflen}%
}
\begin{document}
\noindent This is a test\nexttab mmmmm\\
This is a\nexttab mmmmm\\
This is\nexttab mmmmm\\
This\nexttab mmmmm

\noindent\smash{% \rule{.02\reflen}{2ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{2ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{2ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{5ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{8ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{8ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{11ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{11ex}\rule{.98\reflen}{1pt}% \rule{.02\reflen}{11ex}\rule{.98\reflen}{1pt}% } \end{document}

enter image description here