我已经尝试解决这个问题好几天了。我浏览了这个网站上提出的许多问题,但似乎没有一个能解决我的问题。
基本上,在表格中,我想“削减”一些单元格。这意味着在我想要削减的单元格上创建一条对角线。棘手的部分是我需要将文本置于单元格的中心。我们可以假设单元格的宽度和高度始终相同。
我找到了一个非常接近的解决方案,但只有手动对需要删除的每个单元格的值进行硬编码,才能得到完全正确的结果。我希望有一个更强大的解决方案,无论文本是什么,它都能正常工作。请参阅下面的 MWE:
\documentclass[letterpaper, 12pt]{article}
\usepackage{array}
\usepackage{tikz}
\begin{document}
\begin{table}[!ht] \centering
\renewcommand{\arraystretch}{1.6}
\begin{tabular}{|c|c|c|}
\hline
\tikz[overlay,line width=0.8pt]{\draw (\dimexpr0.1cm-2\tabcolsep-2.5\arrayrulewidth,-0.6em) -- (\dimexpr1.1cm-\tabcolsep-\arrayrulewidth,1em+4.5pt)}AAA & A & AA \\
\hline
\tikz[overlay,line width=0.8pt]{\draw (\dimexpr0.1cm-2\tabcolsep-2.5\arrayrulewidth,-0.6em) -- (\dimexpr1.1cm-\tabcolsep-\arrayrulewidth,1em+4.5pt)}AA & AAA & A \\
\hline
\tikz[overlay,line width=0.8pt]{\draw (\dimexpr0.1cm-2\tabcolsep-2.5\arrayrulewidth,-0.6em) -- (\dimexpr1.1cm-\tabcolsep-\arrayrulewidth,1em+4.5pt)}A & A & AAA\\
\hline
\end{tabular}
\end{table}
\end{document}
编辑:我编辑了上述 MWE 以包含多列。
答案1
TikzTab
环境将名为 X 的单元格的每个角放在从顶行开始计数的 A、B、... 和从左行开始计数的 n 的tikzmark
单元格的每个角上。Xn
\documentclass[letterpaper, 12pt]{article}
\pagestyle{empty}
\usepackage{tikz,array,xparse,luacode,tabularx}
\usetikzlibrary{tikzmark}
\newcounter{TikzTabCount}
% insert a phantom line (no height) between two real lines
% containing the tikzmarks
\makeatletter
\NewDocumentCommand{\TikzTabEnd}{O{\NbCols}}{%
\\[-\ht\@arstrutbox]%
\Row{#1}\stepcounter{TikzTabCount}%
\\[-\dp\@arstrutbox]}
\makeatother
\ExplSyntaxOn
\NewDocumentCommand{\CountColumns}{m}
{% count the number of & tokens in \@preamble
\regex_count:nvN { \cT\& } { @preamble } \l_tmpa_int
% they're one less than the columns
\cs_gset:Npx #1 { \int_eval:n { 1 + \l_tmpa_int } }
}
\cs_generate_variant:Nn \regex_count:nnN { nv }
\ExplSyntaxOff
% #1 is the real environment : tabular, array, tabularx...
% #2 is optional length for tabularx - don't use otherwise
% #3 tabular optional vertical alignment
% #4 columns pattern
\NewDocumentEnvironment{TikzTab}{md<>O{c}mO{\NbCols}}{%
\IfNoValueTF{#2}{%
\setcounter{TikzTabCount}{2}%
\begin{#1}[#3]{#4}%
}{%
\tabularx{#2}[#3]{#4}%
}%
\noalign{\CountColumns{#5}\tikzmark[yshift=5pt]{TTtop}}%
}{%
\IfNoValueTF{#2}{%
\end{#1}%
}{%
\endtabularx%
}%
\foreach \i in {0,...,4} {%
\tikz[overlay,remember picture]
\tikzmark{A\i}{({pic cs:TTtop}-|{pic cs:B\i})};
}
}
% Loop creating the tikzmarkz
\newcommand{\Row}[1]{\directlua{row(#1)}}
\begin{luacode}
function row (s)
a = "\\multicolumn{1}{@{}c@{}}{\\tikzmark{\\Alph{TikzTabCount}0}"
for i = 1,s-1
do
a=a.."\\strut\\hfill\\tikzmark{\\Alph{TikzTabCount}"..i.."}}&\\multicolumn{1}{@{}c@{}}{"
end
a=a.."\\strut\\hfill\\tikzmark{\\Alph{TikzTabCount}"..s.."}}"
tex.print (a)
--print (a)
end
\end{luacode}
\begin{document}
\begin{table}[!ht] \centering
\renewcommand{\arraystretch}{1.6}
\begin{TikzTab}{tabular}{|c|c|c|}
\hline
AAA & A & AA \TikzTabEnd
\hline
\rule{0pt}{3em}AA & AAA & A \TikzTabEnd
\hline
\rule[-2em]{0pt}{5em}A & A & AAA\TikzTabEnd
\hline
\end{TikzTab}
\end{table}
\tikz[overlay,remember picture]
\draw (pic cs:B0) -- (pic cs:A1)
(pic cs:C0) -- (pic cs:B1)
(pic cs:D0) -- (pic cs:C1) ;
\foreach \j in {A,B,C,D} {%
\foreach \i in {0,...,3} {%
\tikz[overlay,remember picture]
\node[red] at (pic cs:\j\i) {\tiny \j\i} ;
}}
\end{document}
答案2
完成修订:免责声明: 这是不是旨在与 Tarass 的出色解决方案竞争。相反,它是一种性能较低的替代方案,但不需要 lualatex,这就是我发布它的原因。事实上,除了您已经加载的内容之外,它唯一需要的是 Ti钾Z 库计算。此代码带有一种新的列类型,仅插入 Ti钾\MeasureLastTable
您需要放置的Z 节点和宏后表格,您需要在其中指定列数。此宏确定除一个额外的垂直移位之外的所有相关长度:单元格内容未垂直居中,并且根据您的示例,此移位是 2pt。(这个数字似乎来自但我无法以很好的方式提取它。)在“测量”表格后,您可以用其中指定单元格索\abovedisplayskip
引的单个单元格划掉,这是一种不言自明的惯例。\CrossOut{x}
x
\documentclass[letterpaper, 12pt]{article}
\usepackage{array}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcounter{cellindex}
\newcolumntype{C}{>{\stepcounter{cellindex}%
\begin{tikzpicture}[remember picture,baseline=(Cell-\thecellindex-left.base),inner sep=0pt]
\node (Cell-\thecellindex-left){\strut};
\end{tikzpicture}
}c<{\begin{tikzpicture}[remember picture,baseline=(Cell-\thecellindex-right.base),inner sep=0pt]
\node (Cell-\thecellindex-right){\strut};
\end{tikzpicture}}}
\newcommand{\MeasureLastTable}[1]{
\pgfmathtruncatemacro{\LeftCellIndex}{\thecellindex-1}
\pgfmathtruncatemacro{\AboveCellIndex}{\thecellindex-#1}
\begin{tikzpicture}[overlay,remember picture]
\path let \p0 = (Cell-\thecellindex-right.east),
\p1 = (Cell-\thecellindex-left.west),
\p2 = (Cell-\LeftCellIndex-right.east),
\p3 = (Cell-\LeftCellIndex-left.west) in
\pgfextra{\pgfmathsetmacro{\tmp}{(\x0+\x1-\x2-\x3)/4}
\xdef\HorSep{\tmp pt} % horizontal distance between two cell centers
};
\path let \p0 = (Cell-\thecellindex-right.north west),
\p1 = (Cell-\thecellindex-left.south west),
\p2 = (Cell-\AboveCellIndex-right.north west),
\p3 = (Cell-\AboveCellIndex-left.south west) in
\pgfextra{\pgfmathsetmacro{\tmp}{(\y2+\y3-\y0-\y1)/4}
\xdef\VertSep{\tmp pt} % vertical distance between two cell centers
}; % I know that in principle two coordinates would be sufficient here
\end{tikzpicture}%
}
\newcommand{\CrossOut}[2][]{
\tikz[overlay,remember picture]{
\path let \p0 = (Cell-#2-left.west),
\p1 = (Cell-#2-right.east),
\p2 = (Cell-#2-left.north west),
\p3 = (Cell-#2-left.south west) in
\pgfextra{\pgfmathsetmacro{\tmp}{\HorSep-(\x1-\x0)/2}
\xdef\myxoffset{\tmp pt}
\pgfmathsetmacro{\tmp}{\VertSep-(\y2-\y3)/2}
\xdef\myyoffset{\tmp pt}
};
\draw[thick,#1] ([xshift=-\myxoffset,yshift=-\myyoffset+2pt]Cell-#2-left.south west) --
([xshift=\myxoffset,yshift=\myyoffset+2pt]Cell-#2-right.north east);
}}
\begin{document}
\begin{table}[!ht] \centering
\renewcommand{\arraystretch}{1.6}
\begin{tabular}{|C|C|C|}
\hline
AAA & A & AA \\
\hline
AA & AAA & A \\
\hline
A & A & AAA\\
\hline
\end{tabular}
\end{table}
\MeasureLastTable{3} %<- the argument is the number of columns of the last table
\CrossOut{1}
\CrossOut{3}
\CrossOut{5}
\CrossOut{8}
\end{document}
当然,\CrossOut
用其他一些花哨的注释来代替宏也是很简单的。
原始答案:问题在于,您总是可以更改表格尺寸,但在某个时候,您的宏会中断。在这种简单的单列表格情况下,至少可以确保对角线端点的水平位置不必手动调整。垂直位置仍是硬编码的。
\documentclass[letterpaper, 12pt]{article}
\usepackage{array}
\usepackage{tikz}
\newcommand{\tikznode}[2]{\tikz[remember picture,baseline=(#1.base),inner
sep=0pt]{\node(#1)[inner sep=0pt]{#2};}}
\newcommand{\CrossOut}[2][]{
\tikz[overlay,remember picture]{
\draw[thick,#1] ([yshift=-7pt]#2.south west-|tl.south east) --
([yshift=7pt]#2.north east-|br.north west);
}}
\begin{document}
\begin{table}[!ht] \centering
\renewcommand{\arraystretch}{1.6}
\tikznode{tl}{\strut}%
\begin{tabular}{| c |}
\hline
\tikznode{AA1}{AA1}\\
\hline
\tikznode{A2}{A2}\\
\hline
\tikznode{A3}{A3*}\\
\hline
\end{tabular}\tikznode{br}{\strut}
\end{table}
\CrossOut{AA1}\CrossOut{A2}\CrossOut{A3}
\end{document}