Strike out a table cell
The following example uses package zref-savepos
to get the positions of the cell. \vadjust pre
(a newer feature invented by pdfTeX and also available in LuaTeX and XeTeX) puts the position marker right above the current cell and \vadjust
puts the marker below.
\notableentry
uses \multicolumn{1}{@{}c@{}|}
to get the full cell width without \tabcolsep
spacings. \hspace{0pt plus 1filll}
is used to override the c
specifier to get a position marker to the left and right of the cell.
The label names for the position markers (\zsavepos
) are automatically generated with the help of counter NoTableEntry
.
Finally the coordinates of the cell's bounding box are calculated and the cross drawn via tikz
.
\documentclass{article}
\pagestyle{empty}% for cropping
\usepackage{tikz,colortbl}
\usetikzlibrary{calc}
\usepackage{zref-savepos}
\newcounter{NoTableEntry}
\renewcommand*{\theNoTableEntry}{NTE-\the\value{NoTableEntry}}
\newcommand*{\notableentry}{%
\multicolumn{1}{@{}c@{}|}{%
\stepcounter{NoTableEntry}%
\vadjust pre{\zsavepos{\theNoTableEntry t}}% top
\vadjust{\zsavepos{\theNoTableEntry b}}% bottom
\zsavepos{\theNoTableEntry l}% left
\hspace{0pt plus 1filll}%
\zsavepos{\theNoTableEntry r}% right
\tikz[overlay]{%
\draw[red]
let
\n{llx}={\zposx{\theNoTableEntry l}sp-\zposx{\theNoTableEntry r}sp},
\n{urx}={0},
\n{lly}={\zposy{\theNoTableEntry b}sp-\zposy{\theNoTableEntry r}sp},
\n{ury}={\zposy{\theNoTableEntry t}sp-\zposy{\theNoTableEntry r}sp}
in
(\n{llx}, \n{lly}) -- (\n{urx}, \n{ury})
(\n{llx}, \n{ury}) -- (\n{urx}, \n{lly})
;
}%
}%
}
\begin{document}
\LARGE
\begin{tabular}{|c|c|}
\hline
alghreaiog & bghsah \\
\hline
cagja & \notableentry \\
\hline
\cellcolor{blue} & edkhaklgjaj \\
\hline
\end{tabular}
\begin{tabular}{|p{4cm}|p{3cm}|}
\hline
alghreaiog & bghsah \\
\hline
cagja\par bla & \notableentry \\
\hline
\cellcolor{blue} & edkhaklgjaj \par xyz \\
\hline
\end{tabular}
\end{document}
Restriction to package pgf
The following modification restricts the drawing to the low level package pgf
instead of using the front-end package tikz
.
\documentclass{article}
\pagestyle{empty}% for cropping
\usepackage{colortbl}
\usepackage{pgf}
\usepackage{zref-savepos}
\newcounter{NoTableEntry}
\renewcommand*{\theNoTableEntry}{NTE-\the\value{NoTableEntry}}
\newcommand*{\notableentry}{%
\multicolumn{1}{@{}c@{}|}{%
\stepcounter{NoTableEntry}%
\vadjust pre{\zsavepos{\theNoTableEntry t}}% top
\vadjust{\zsavepos{\theNoTableEntry b}}% bottom
\zsavepos{\theNoTableEntry l}% left
%
\begin{pgfpicture}%
\pgfsetlinewidth{.4pt}%
\pgfsetstrokecolor{red}%
\edef\llx{0sp}%
\edef\urx{%
\the\numexpr
\zposx{\theNoTableEntry r}%
-\zposx{\theNoTableEntry l}%
\relax sp%
}%
\edef\lly{%
\the\numexpr
\zposy{\theNoTableEntry b}%
-\zposy{\theNoTableEntry l}%
\relax sp%
}%
\edef\ury{%
\the\numexpr
\zposy{\theNoTableEntry t}%
-\zposy{\theNoTableEntry l}%
\relax sp%
}%
\pgfpathmoveto{\pgfpoint{\llx}{\lly}}%
\pgfpathlineto{\pgfpoint{\urx}{\ury}}%
\pgfpathmoveto{\pgfpoint{\llx}{\ury}}%
\pgfpathlineto{\pgfpoint{\urx}{\lly}}%
\pgfusepath{stroke}%
\pgfresetboundingbox
\end{pgfpicture}%
%
\hspace{0pt plus 1filll}%
\zsavepos{\theNoTableEntry r}% right
}%
}
\begin{document}
\LARGE
\begin{tabular}{|c|c|}
\hline
alghreaiog & bghsah \\
\hline
cagja & \notableentry \\
\hline
\cellcolor{blue} & edkhaklgjaj \\
\hline
\end{tabular}
\begin{tabular}{|p{4cm}|p{3cm}|}
\hline
alghreaiog & bghsah \\
\hline
cagja\par bla & \notableentry \\
\hline
\cellcolor{blue} & edkhaklgjaj \par xyz \\
\hline
\end{tabular}
\end{document}
Without pgf
The next solution uses \rotatebox
to rotate a rule with the length of the hypotenuse/diagonal and \reflectbox
to get the other diagonal of the cross.
The calculations of the length of the hypotenuse and the rotation angle are done via package l3fp
.
\documentclass{article}
\pagestyle{empty}% for cropping
\usepackage{colortbl}
\usepackage{zref-savepos}
\usepackage{graphicx}
\usepackage{xparse, l3fp}
\ExplSyntaxOn
\NewDocumentCommand { \NTECalcHypotenuse } { m m } {
\fp_to_int:n { sqrt ( #1 * #1 + #2 * #2 ) - 0.5 }
}
\NewDocumentCommand { \NTECalcAngle } { m m } {
\fp_to_decimal:n { atand ( #1 / #2 ) }
}
\ExplSyntaxOff
\newcounter{NoTableEntry}
\renewcommand*{\theNoTableEntry}{NTE-\the\value{NoTableEntry}}
\newcommand*{\notableentry}{%
\multicolumn{1}{@{}c@{}|}{%
\stepcounter{NoTableEntry}%
\vadjust pre{\zsavepos{\theNoTableEntry t}}% top
\vadjust{\zsavepos{\theNoTableEntry b}}% bottom
\zsavepos{\theNoTableEntry l}% left
%
\sbox0{%
\color{red}%
\edef\llx{0}%
\edef\urx{%
\the\numexpr
\zposx{\theNoTableEntry r}%
-\zposx{\theNoTableEntry l}%
\relax
}%
\edef\lly{%
\the\numexpr
\zposy{\theNoTableEntry b}%
-\zposy{\theNoTableEntry l}%
\relax
}%
\edef\ury{%
\the\numexpr
\zposy{\theNoTableEntry t}%
-\zposy{\theNoTableEntry l}%
\relax
}%
\edef\w{\the\numexpr\urx-\llx\relax}%
\edef\h{\the\numexpr\ury-\lly\relax}%
\ifnum\w=0 %
\else
\setbox0=\hbox{%
\edef\angle{\romannumeral-`x\NTECalcAngle{\h}{\w}}%
\raisebox{\the\numexpr\zposy{\theNoTableEntry b}%
-\zposy{\theNoTableEntry l}\relax sp%
}{%
\rotatebox{\angle}{%
\vrule width\NTECalcHypotenuse{\h}{\w}sp height.2pt depth.2pt%
}%
}%
}%
\rlap{\unhcopy0}%
\reflectbox{\unhcopy0}%
\fi
}%
\wd0=0pt %
\ht0=0pt %
\dp0=0pt %
\copy0 %
%
\hspace{0pt plus 1filll}%
\zsavepos{\theNoTableEntry r}% right
}%
}
\begin{document}
\LARGE
\begin{tabular}{|c|c|}
\hline
alghreaiog & bghsah \\
\hline
cagja & \notableentry \\
\hline
\cellcolor{blue} & edkhaklgjaj \\
\hline
\end{tabular}
\begin{tabular}{|p{4cm}|p{3cm}|}
\hline
alghreaiog & bghsah \\
\hline
cagja\par bla & \notableentry \\
\hline
\cellcolor{blue} & edkhaklgjaj \par xyz \\
\hline
\end{tabular}
\end{document}
With pict2e
Package pict2e
allows arbitrary real numbers in the range [-16383, 16383] for the slope arguments of \line
in parentheses. Therefore the example uses 1pt
as \unitlength
and recalculate the numbers of the \pdfsavepos
feature that are given with unit sp
to pt
.
\documentclass{article}
\pagestyle{empty}% for cropping
\usepackage{colortbl}
\usepackage{zref-savepos}
\usepackage{pict2e}
%\usepackage{picture}
\newcounter{NoTableEntry}
\renewcommand*{\theNoTableEntry}{NTE-\the\value{NoTableEntry}}
\makeatletter
\newcommand*{\notableentry}{%
\multicolumn{1}{@{}c@{}|}{%
\stepcounter{NoTableEntry}%
\vadjust pre{\zsavepos{\theNoTableEntry t}}% top
\vadjust{\zsavepos{\theNoTableEntry b}}% bottom
\zsavepos{\theNoTableEntry l}% left
%
\raisebox{%
\dimexpr\zposy{\theNoTableEntry b}sp
-\zposy{\theNoTableEntry l}sp\relax
}[0pt][0pt]{%
\color{red}%
\setlength{\unitlength}{1pt}%
\edef\w{%
\strip@pt\dimexpr\zposx{\theNoTableEntry r}sp%
-\zposx{\theNoTableEntry l}sp\relax
}%
\edef\h{%
\strip@pt\dimexpr\zposy{\theNoTableEntry t}sp%
-\zposy{\theNoTableEntry b}sp\relax
}%
\ifdim\w pt=0pt % prevent error in first run for \line(0,0)
\else
\begin{picture}(0,0)%
% the arguments of `\line` needs to be expanded,
% because `pict2e' needs to see the decimal dot
\edef\x{%
\noexpand\put(0,0){\noexpand\line(\w,\h){\w}}%
\noexpand\put(0,\h){\noexpand\line(\w,-\h){\w}}%
}\x
\end{picture}%
\fi
}%
\hspace{0pt plus 1filll}%
\zsavepos{\theNoTableEntry r}% right
}%
}
\begin{document}
\LARGE
\begin{tabular}{|c|c|}
\hline
alghreaiog & bghsah \\
\hline
cagja & \notableentry \\
\hline
\cellcolor{blue} & edkhaklgjaj \\
\hline
\end{tabular}
\begin{tabular}{|p{4cm}|p{3cm}|}
\hline
alghreaiog & bghsah \\
\hline
cagja\par bla & \notableentry \\
\hline
\cellcolor{blue} & edkhaklgjaj \par xyz \\
\hline
\end{tabular}
\end{document}
Variant with \notableentry
inside \multicolumn
In this variant, \notableentry
is used inside \multicolumn
with c
as column specifier. That allows more flexibility regarding the vertical lines and the number of columns, which are covered by the cross.
\documentclass{article}
\pagestyle{empty}% for cropping
\usepackage{colortbl}
\usepackage{zref-savepos}
\usepackage{pict2e}
%\usepackage{picture}
\newcounter{NoTableEntry}
\renewcommand*{\theNoTableEntry}{NTE-\the\value{NoTableEntry}}
\makeatletter
\newcommand*{\notableentry}{%
\kern-\tabcolsep
\stepcounter{NoTableEntry}%
\vadjust pre{\zsavepos{\theNoTableEntry t}}% top
\vadjust{\zsavepos{\theNoTableEntry b}}% bottom
\zsavepos{\theNoTableEntry l}% left
%
\raisebox{%
\dimexpr\zposy{\theNoTableEntry b}sp
-\zposy{\theNoTableEntry l}sp\relax
}[0pt][0pt]{%
\color{red}%
\setlength{\unitlength}{1pt}%
\edef\w{%
\strip@pt\dimexpr\zposx{\theNoTableEntry r}sp%
-\zposx{\theNoTableEntry l}sp\relax
}%
\edef\h{%
\strip@pt\dimexpr\zposy{\theNoTableEntry t}sp%
-\zposy{\theNoTableEntry b}sp\relax
}%
\ifdim\w pt=0pt % prevent error in first run for \line(0,0)
\else
\begin{picture}(0,0)%
% the arguments of `\line` needs to be expanded,
% because `pict2e' needs to see the decimal dot
\edef\x{%
\noexpand\put(0,0){\noexpand\line(\w,\h){\w}}%
\noexpand\put(0,\h){\noexpand\line(\w,-\h){\w}}%
}\x
\end{picture}%
\fi
}%
\hspace{0pt plus 1filll}%
\zsavepos{\theNoTableEntry r}% right
\kern-\tabcolsep
}
\begin{document}
\LARGE
\begin{tabular}{|c|c|}
\hline
alghreaiog & bghsah \\
\hline
\multicolumn{2}{|c|}{\notableentry} \\
\hline
\cellcolor{blue} & edkhaklgjaj \\
\hline
\end{tabular}
\begin{tabular}{|p{4cm}|p{3cm}|}
\hline
alghreaiog & bghsah \\
\hline
cagja\par bla & \multicolumn{1}{c|}{\notableentry} \\
\hline
\cellcolor{blue} & edkhaklgjaj \par xyz \\
\hline
\multicolumn{1}{|c|}{\notableentry} & asdf \\
\hline
\end{tabular}
\end{document}
colortbl
uses \leaders
with \vrule
to add the panel, normally the \vrule
extends to the full height/depth of the containing box which is why it fills the cell, however if you specify a fixed height and depth then you get a horizontal line. note that you can't see at the TeX macro layer what the extent of the box is, that is resolved later in the alignment code in TeX's internals. So even though \vrule
draws a line from top to bottom, you don't know where the "top" is so you can't draw a cross without using something like \pdfsavepos
which is what the tikz remember stuff is doing. Then of course even if you know the coordinates you need some back end code to draw a line of a given slope. (You don't need the whole of tikz, but you need something)
As it happens, I developed color
and colortbl
on a monochrome screen and since black-on-black is a bit hard to read There is a built in option to restrict colortbl to a thin horizontal line. (It would be easy to not use this option all the time and just have a command that locally uses this debug version but:
\documentclass{article}
\pagestyle{empty}% for cropping
\usepackage[debugshow]{colortbl}
\makeatletter
\def\notableentry{\cellcolor{blue}}
\makeatother
\begin{document}
\LARGE
\begin{tabular}{|c|c|}
\hline
alghreaiog & bghsah \\
\hline
cagja & \notableentry \\
\hline
\cellcolor{blue} & edkhaklgjaj \\
\hline
\end{tabular}
\end{document}