TeX - LaTeX Asked on June 25, 2021
I’ve recently asked a question about the possibility to align cells in a tabular on something other than left, right and center. S. Segletes proposed a solution where cells had to be split in two parts, what I don’t want to do.
D. Carlisle suggested to extend the cell content to some fixed dimension in order to get the desired alignment by right aligning them.
I’ve tried to implement a solution quite similar to that but by optimizing the extra space used to get the perfect alignment. This requires a two-pass strategy where the dimension of every cell is stored on the first pass so that the correct additional spacing can be computed on the second pass.
The code below allowed me to get this result (bounding box of cell content is light blue) :
To achieve that, I had to find a way to identify preciseley the column a cell is in. I did that by defining a counter and two new column types that would allow for the counter to be reset and incremented.
newcolumntype{Q}{>{setcounter{@column}{0}}r}
newcolumntype{R}{>{stepcounter{@column}}r}
I am not satisfied with this solution.
Isn’t there already a mechanism (provided by tabular
) that would allow me to identify the column from inside a cell?
documentclass[margin=2cm]{standalone}
usepackage{array, tikz}
makeatletter
% Tounters for tables (useless for the moment)
% and columns:
newcounter{@table}
newcounter{@column}
% The @columns counter needs to be incremented
% each time we switch to a new column and reset
% each time we switch to a new row.
%
% Defining a new column type for the first column
% (resetting the counter) and for ordinary columns
% (increasing the counter).
newcolumntype{Q}{>{setcounter{@column}{0}}r}
newcolumntype{R}{>{stepcounter{@column}}r}
% The following macro will only be executed form the
% .aux file. It gradually computes the padding
% needed for a given column in a given table.
newcommand{@process@column@padding}[3]{%
% #1 : table number
% #2 : column number
% #3 : right extension of one cell
% --------------------------------
% If the padding register already exists...
ifcsname column@padding@#1@#2endcsname%
% ... replace it's content if the new padding
% length is bigger ...
ifdim@nameuse{column@padding@#1@#2}<#3%
global@namedef{column@padding@#1@#2}{#3}%
fi%
else%
% ... or define the padding register.
global@namedef{column@padding@#1@#2}{#3}
fi%
}
newcommand{mycell}[2][]{%
tikz[baseline=0, #1]{
% execute the cells tikz-code
#2
% visualize the anchor (debug):
draw[densely dotted, thick, blue] (0,-1)--(0,1);
% identify right side of bounding box:
path (current bounding box.east);
% recover it's coordinates:
pgfgetlastxy{@xcoord}{@ycoord}
% needed to avoid a "Undefined control
% sequence" error on @xcoord:
globaledef@extension{@xcoord}
% write processing command to aux file
immediatewrite@auxout{string@process@column@padding{the@table}{the@column}{@xcoord}}
% visualize bounding box (debug):
fill[blue, opacity=.1] (current bounding box.south west) rectangle (current bounding box.north east);
}%
% check if suitable padding register was already
% set:
ifcsname column@padding@the@table @the@columnendcsname%
% register is set, compute missing length
% for this cell...
pgfmathsetmacro{@padding}{@nameuse{column@padding@the@table @the@column}-@extension}%
% ... and add padding to the right
hspace{@padding pt}%
fi%
}
begin{document}
begin{tabular}{|Q|R|}
hline
center & mycell{draw[line width=5mm] circle (.6);}
hline
right & mycell{draw[line width=2mm] (1,0) circle (.6);}
hline
left & mycell{draw (-1,0) circle (.6);}
hline
end{tabular}
end{document}
If you just want to align the cell to the right or left without using another column, you should try the nicematrix
package.
Provides a Block
command that allows just that. In the example, the block is one column times one row wide, but it works the same way with multiple columns and multiple rows.
The package creates PGF/Tikz nodes below the cells to place the content. So it may take more than one compile.
Loading tikz
allows the execution of code in the nodes i-j
(the three circles) or using the intersections of the rules (the two red lines). Or from the middle of two nodes to the middle of two other nodes (vertical dotted blue line, using calc
).
From the manual (p.32):
documentclass[margin=2cm]{standalone}
usepackage{array, tikz}
usetikzlibrary{calc}
usepackage{nicematrix}
begin{document}
setlength{tabcolsep}{0pt}
newcommand{square}{color{blue!10}rule{2cm}{2cm}}
newcommand{squarei}{
begin{tikzpicture}
fill[red!10!white] (0,0) rectangle (2,2);
end{tikzpicture}
}
begin{NiceTabular}{m{1cm}m{4cm}}[hvlines]
Block[c]{}{center}& Block[c]{}{center square}
Block[r]{}{right} & Block[r]{}{right squarei}
Block[l]{}{left} & Block[l]{}{left square}
CodeAfter
tikz{%
draw (1-2)[ xshift=-0cm, yshift=-1ex] circle (1) ;
draw (2-2)[line width=1mm, xshift=0.995cm, yshift=-1ex] circle (0.95) ;
draw (3-2)[line width=2mm, xshift=-0.99cm, yshift=-1ex ] circle (0.9) ;
draw[color=red] (row-1-|col-3) -- (row-2-|col-2);
draw[color=red] (row-1-|col-2) -- (row-2-|col-3);
draw [densely dotted, thick, blue] ($(row-1-|col-2)!0.5!(row-1-|col-3)$) -- ($(row-4-|col-2)!0.5!(row-4-|col-3)$);
}
end{NiceTabular}
end{document}
Answered by Simon Dispa on June 25, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP