How to set tikzmarks with \noalign at the edge of tabular rows

The contents of \noalign is appended to the enclosing vertical list at the specified point; the enclosing vertical list is a \vbox, \vtop or \vcenter depending on the optional argument to tabular (default \vcenter).

Your \hfill starts a paragraph, which will use the current \hsize, so you get an unwanted vertical space and the arrow will be as wide as \linewidth.

The enclosing box's width is not known until the \halign is unpacked as a list of horizontal boxes. For measuring it one can hook in \endtabular, after the \crcr\egroup that finishes off the \halign, using \lastbox tricks.

For instance,

\def\endtabular{\crcr\egroup\tabularhook\egroup$\egroup}
\newdimen\tabularwidth
\def\tabularhook{%
  \setbox0=\lastbox
  \global\tabularwidth=\wd0
  \nointerlineskip\box0 }

will store in \tabularwidth the width of the just ended tabular. But it's too late for your purposes.

Inserting a “phantom line” does the job:

\documentclass[]{article}

\usepackage{tikz}
\usetikzlibrary{tikzmark}

\makeatletter
\newcommand{\measureit}[3]{%
  \\[-\ht\@arstrutbox]
  \multicolumn{#1}{@{}c@{}}{%
    \pgfmark{#2}\hfill\pgfmark{#3}}%
  \\[-\dp\@arstrutbox]}
\makeatother

\begin{document}
\renewcommand\arrayrulewidth{4pt}

\begin{tabular}{l}
abc    \\\noalign{\hrule height \arrayrulewidth}
blub   \measureit{1}{testa}{testb}
abc\tikz [remember picture] \draw [overlay,->] (pic cs:testa)--(pic cs:testb);
\end{tabular}%
\begin{tabular}{l}
abc    \\\noalign{\hrule height \arrayrulewidth}
blub   \\
abc
\end{tabular}

\end{document}

enter image description here

Not a nice syntax and probably improvable.


As egreg said, but as you hinted you were using colortbl it is already putting a coloured rule under the cell, so you can just ask it to stick a tikzmark at each end of that, so you know where it is:

enter image description here

\documentclass[]{article}
\usepackage{colortbl}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\makeatletter
\newcount\U@CT@
\def\CT@@do@color{%
\U@tm
  \global\let\CT@do@color\relax
        \@tempdima\wd\z@
        \advance\@tempdima\@tempdimb
        \advance\@tempdima\@tempdimc
        \kern-\@tempdimb
        \leaders\vrule
%^^A                     \@height\p@\@depth\p@
                \hskip\@tempdima\@plus  1fill
\U@tm
        \kern-\@tempdimc
        \hskip-\wd\z@ \@plus -1fill }


\def\U@tm{%
\global\advance\U@CT@\@ne
\tikzmark{test\the\U@CT@}}
%
\makeatother
\begin{document}
\renewcommand\arrayrulewidth{4pt}

\begin{tabular}{l}
\rowcolor{yellow}abc    \\
blub   \\
abc\tikz [remember picture] \draw [overlay,->] (pic cs:test1)--(pic cs:test2);
\end{tabular}

\end{document}

If you want the left edge of the arrow to be the left edge of the colour rather than the cell contents, move the first \U@tm down a few lines after the \kern-\@tempdimb