我想在页面上定位“网格”。我将它们放在一个范围内,命名为本地边界框,并尝试使用它进行相对定位,例如shift={($(myscope.center)+(1cm,1cm)$)}
。我也尝试过在页面上定位,例如($(page.south west)$)
,但对结果不太满意。
具体来说,在下面的屏幕截图中,我希望能够将三个网格的左侧相对于左边距对齐:目前第二个网格对齐得很好,但第一个和第三个网格离左边距有点太远了。我可以继续尝试调整偏移,但我觉得有比这更好的方法。
为了提供我的问题的背景,网格是“多项选择”表的一部分。我改编了expl3
在接受的答案中找到的一些代码这里。\vgrid
和\hgrid
命令产生垂直/水平网格:整数是问题编号;字母是答案选项;问题的起始数字可以更改;正确答案以蓝色显示(0 表示问题未回答)。请参阅下面的详细信息:
% ARGUMENTS of \vgrid and \hgrid
% [starting question number] [total number of questions] [total number of answer choices] [scaling factor] {list of zeros or list of the correct answer numbers, separated by semi-colons}
% #1 : question sequence starting number, default 1
% #2 : total number of questions in sequence, default 20
% #3 : total number of choices for each question, default 5
% #4 : scaling factor, default 1.0
% #5 : semi-colon separated list of numbers corresponding to correct answers, e.g. 1 for A, 2 for B, and 0 for not-answered
\documentclass[12pt]{article}
\usepackage[papersize={8.5in,11in},left=0.5in,right=0.5in,nohead,top=0.5in,nofoot,bottom=0.5in,marginparsep=0pt,showframe]{geometry}
\setlength{\parindent}{0pt}
\usepackage{tikz}
\usetikzlibrary{calc,positioning}
% HORIZONTAL GRID
\ExplSyntaxOn
\NewDocumentCommand{\hgrid}{ O{1} O{20} O{5} O{0.9} m}{%
\seq_set_split:Nnn \l_tmpa_seq{;}{#5}
% print question key (A, B, C...)
\int_step_inline:nnnn {1} {1} {#3} {%
\node at (0*#4, #3*#4-##1*#4) {\int_to_Alph:n{##1}};}
% print question number (1, 2, 3...)
\int_step_inline:nnnn {#1} {1} {#1+#2-1} {%
\node at (##1*#4-#1*#4+1*#4, #3*#4) {##1};
\int_step_inline:nnnn {1} {1} {#3} {%
% draw an empty box for each question number/key
\node[draw,line~width=1*#4pt,minimum~width=0.8*#4cm,minimum~height=0.8*#4cm] at (##1*#4-#1*#4+1*#4, #3*#4-####1*#4) {};
% fill the correct box (0 to leave it empty)
\int_compare:nNnTF {####1} = {\seq_item:Nn \l_tmpa_seq {#1+#2-##1}} {\node[fill=blue,minimum~width=0.8*#4cm,minimum~height=0.8*#4cm] at (#1*#4+#2*#4-##1*#4, #3*#4-####1*#4) {};}{}
}
}
}
\ExplSyntaxOff
% VERTICAL GRID
\ExplSyntaxOn
\NewDocumentCommand{\vgrid}{ O{1} O{20} O{5} O{0.9} m}{%
\seq_set_split:Nnn \l_tmpa_seq{;}{#5}
% print question key (A, B, C...)
\int_step_inline:nnnn {1} {1} {#3} {%
\node at (##1*#4, #2*#4) {\int_to_Alph:n{##1}};}
% print question number (1, 2, 3...)
\int_step_inline:nnnn {#1} {1} {#1+#2-1} {%
\node at (0*#4, #1*#4+#2*#4-1*#4-##1*#4) {##1};
\int_step_inline:nnnn {1} {1} {#3} {%
% draw an empty box for each question number/key
\node[draw,line~width=1*#4pt,minimum~width=0.8*#4cm,minimum~height=0.8*#4cm] at (####1*#4, ##1*#4-#1*#4) {};
% fill the correct box (0 to leave it empty)
\int_compare:nNnTF {####1} = {\seq_item:Nn \l_tmpa_seq {#1+#2-##1}} {\node[fill=blue,minimum~width=0.8*#4cm,minimum~height=0.8*#4cm] at (####1*#4, ##1*#4-#1*#4) {};}{}
}
}
}
\ExplSyntaxOff
\begin{document}\pagestyle{empty}
\begin{tikzpicture}[x=1cm, y=1cm, font=\scriptsize\bfseries]
% short horizontal grid
\begin{scope}[anchor=south east,
local bounding box=bb1]
\hgrid{0;2;3;4;5;4;3;2;1;2;3;4;5;4;3;2;1;2;3;4}
\end{scope}
% long horizontal grid
\begin{scope}[anchor=south east,
shift={($(bb1.south west)+(0cm,-5cm)$)},
local bounding box=bb2]
\hgrid[21][30][6][0.6]{0;2;3;4;5;6;5;4;3;2;1;2;3;4;5;6;5;4;3;2;1;2;3;4;5;6;5;4;3;2}
\end{scope}
% short vertical grid
\begin{scope}[anchor=south east,
shift={($(bb2.south west)+(1cm,-12cm)$)},
local bounding box=bb3]
\vgrid[51][10][4][1.1]{0;2;3;4;5;4;3;2;1;2}
\end{scope}
\end{tikzpicture}
\end{document}
笔记:我对我的问题进行了重大修改,并在此过程中修复了一些错误。如果仍有错误,那不是故意的!
答案1
我尝试将你的网格重新设想为pic
s,这意味着固定 TiKZ 图片可以使用。显然,我推荐使用 tikzmark 解决方案。
\documentclass[12pt]{article}
%\url{https://tex.stackexchange.com/q/619620/86}
\usepackage[papersize={8.5in,11in},left=0.5in,right=0.5in,nohead,top=0.5in,nofoot,bottom=0.5in,marginparsep=0pt,showframe]{geometry}
\setlength{\parindent}{0pt}
\usepackage{tikz}
\usetikzlibrary{calc,positioning,fit}
% HORIZONTAL AND VERTICAL GRIDS
\ExplSyntaxOn
\cs_new_nopar:Npn \grid_val:n #1
{
\pgfkeysvalueof{/tikz/grid/#1}
}
\tikzset{
grid/.is~ family,
grid/start/.initial=1,
grid/total/.initial=20,
grid/choices/.initial=5,
horizontal~ grid/.pic={
\seq_set_split:Nnn \l_tmpa_seq{;}{#1}
% print question key (A, B, C...)
\int_step_inline:nnnn {1} {1} {\grid_val:n {choices}
} {%
\node at (0, \grid_val:n {choices}-##1) {\int_to_Alph:n{##1}};
}
% print question number (1, 2, 3...)
\int_step_inline:nnnn {\grid_val:n {start} } {1} {\grid_val:n {start} + \grid_val:n {total} - 1} {%
\node at (##1-\grid_val:n {start} +1, \grid_val:n {choices} ) {##1};
\int_step_inline:nnnn {1} {1} {\grid_val:n {choices}} {%
% fill the correct box (0 to leave it empty)
\int_compare:nNnT {####1} = {\seq_item:Nn \l_tmpa_seq {\grid_val:n {start} + \grid_val:n {total} - ##1} } {
\fill[gray]
(\grid_val:n {start} + \grid_val:n {total} -##1, \grid_val:n {choices} - ####1)
+(-.4,-.4) rectangle +(.4,.4);
}
% draw an empty box for each question number/key
\draw
(##1-\grid_val:n {start}+1, \grid_val:n {choices} -####1)
+(-.4,-.4) rectangle +(.4,.4);
}
}
\node[
draw=red,
line~width=2pt,
dashed,
overlay,
fit={
(1, \grid_val:n {choices}-1)
(\grid_val:n {total}, 0)
}
] (-grid) {};
\node[
draw=blue,
line~width=2pt,
dashed,
overlay,
fit={
(0, \grid_val:n {choices})
(\grid_val:n {total}, 0)
}
] (-picture) {};
},
vertical~ grid/.pic={
\seq_set_split:Nnn \l_tmpa_seq{;}{#1}
% print question key (A, B, C...)
\int_step_inline:nnnn {1} {1} {\grid_val:n {choices}
} {%
\node at (##1, \grid_val:n {total}) {\int_to_Alph:n{##1}};
}
% print question number (1, 2, 3...)
\int_step_inline:nnnn {\grid_val:n {start} } {1} {\grid_val:n {start} + \grid_val:n {total} - 1} {%
\node at (0,\grid_val:n {start} + \grid_val:n {total} -1 - ##1 ) {##1};
\int_step_inline:nnnn {1} {1} {\grid_val:n {choices}} {%
% fill the correct box (0 to leave it empty)
\int_compare:nNnT {####1} = {\seq_item:Nn \l_tmpa_seq {\grid_val:n {start} + \grid_val:n {total} - ##1} } {
\fill[gray]
(####1, ##1 - \grid_val:n {start})
+(-.4,-.4) rectangle +(.4,.4);
}
% draw an empty box for each question number/key
\draw
(####1, ##1 - \grid_val:n {start})
+(-.4,-.4) rectangle +(.4,.4);
}
}
\node[
draw=red,
line~width=2pt,
dashed,
overlay,
fit={
(\grid_val:n {choices}, 0)
(1, \grid_val:n {total}-1)
}
] (-grid) {};
\node[
draw=blue,
line~width=2pt,
dotted,
overlay,
fit={
(\grid_val:n {choices}, 0)
(0, \grid_val:n {total})
}
] (-picture) {};
}
}
\ExplSyntaxOff
\begin{document}\pagestyle{empty}
\begin{tikzpicture}[font=\scriptsize\bfseries]
\pic [scale=.9] [grid/start=44] [grid/choices=8] [grid/total=10] {vertical grid={0;2;3;4;5;4;3;2;1;2}};
\end{tikzpicture}
\begin{tikzpicture}[font=\scriptsize\bfseries]
\pic [scale=.9] [grid/start=21] [grid/choices=4] [grid/total=10] {horizontal grid={0;2;3;4;5;4;3;2;1;2}};
\end{tikzpicture}
\begin{tikzpicture}[font=\scriptsize\bfseries]
\pic [scale=.9] [grid/start=1] [grid/choices=5] [grid/total=20] {horizontal grid={0;2;3;4;5;4;3;2;1;2;3;4;5;4;3;2;1;2;3;4}};
\end{tikzpicture}
\end{document}
更新 2021-10-23tikzmark
以下是使用图片锚定方法的示例。请注意,该方法目前仅在开发tikzmark
版本中可用github并且我还没有完全确定语法(因此非常欢迎改进建议)。
\documentclass[12pt]{article}
%\url{https://tex.stackexchange.com/q/619620/86}
\usepackage[papersize={8.5in,11in},left=0.5in,right=0.5in,nohead,top=0.5in,nofoot,bottom=0.5in,marginparsep=0pt,showframe]{geometry}
\setlength{\parindent}{0pt}
\usepackage{tikz}
\usetikzlibrary{calc,positioning,fit,tikzmark}
% HORIZONTAL GRID
\ExplSyntaxOn
\cs_new_nopar:Npn \grid_val:n #1
{
\pgfkeysvalueof{/tikz/grid/#1}
}
\seq_new:N \l__grid_answers_seq
% #1 - ;-separated list of correct answers
% #2 - choices per question
% #3 - start number of questions
% #4 - total number of questions
\cs_new_nopar:Npn \grid_horizontal:nnnn #1#2#3#4
{
% Split the answers into a sequence
\seq_set_split:Nnn \l__grid_answers_seq {;} {#1}
% Print the choice labels
\int_step_inline:nnnn {1} {1} {#2}
{
\node at (0, -##1) {\int_to_Alph:n{##1}};
}
% Print question numbers
\int_step_inline:nnnn {1} {1} {#4}
{
\node at (##1, 0) {\int_eval:n{##1 + #3 - 1}};
}
% Set out the grid
\int_step_inline:nnnn {1} {1} {#2}
{
\int_step_inline:nnnn {1} {1} {#4}
{
\int_compare:nNnTF {##1} = {\seq_item:Nn \l__grid_answers_seq {####1}}
{
\filldraw[fill=blue,draw=black]
}
{
\draw
}
(####1,-##1) +(-.4,-.4) rectangle +(.4,+.4);
}
}
\node[
draw=green,
overlay,
fit={
(.5,-.5) (#4+.5,-#2-.5)
}
] (-grid) {};
\node[
draw=orange,
overlay,
fit={
(-.5,.5) (#4+.5,-#2-.5)
}
] (-picture) {};
}
% #1 - ;-separated list of correct answers
% #2 - choices per question
% #3 - start number of questions
% #4 - total number of questions
\cs_new_nopar:Npn \grid_vertical:nnnn #1#2#3#4
{
% Split the answers into a sequence
\seq_set_split:Nnn \l__grid_answers_seq {;} {#1}
% Print the choice labels
\int_step_inline:nnnn {1} {1} {#2}
{
\node at (##1,0) {\int_to_Alph:n{##1}};
}
% Print question numbers
\int_step_inline:nnnn {1} {1} {#4}
{
\node at (0,-##1) {\int_eval:n{##1 + #3 - 1}};
}
% Set out the grid
\int_step_inline:nnnn {1} {1} {#2}
{
\int_step_inline:nnnn {1} {1} {#4}
{
\int_compare:nNnTF {##1} = {\seq_item:Nn \l__grid_answers_seq {####1}}
{
\filldraw[fill=blue,draw=black]
}
{
\draw
}
(##1,-####1) +(-.4,-.4) rectangle +(.4,+.4);
}
}
\node[
draw=green,
overlay,
fit={
(.5,-.5) (#2+.5,-#4-.5)
}
] (-grid) {};
\node[
draw=orange,
overlay,
fit={
(-.5,.5) (#2+.5,-#4-.5)
}
] (-picture) {};
}
\cs_generate_variant:Nn \grid_horizontal:nnnn {nvvv}
\cs_generate_variant:Nn \grid_vertical:nnnn {nvvv}
\cs_new_nopar:Npn \grid_horizontal_from_keys:nnnn #1#2#3#4
{
\grid_horizontal:nvvv {#1} {pgfk@/tikz/grid/#2} {pgfk@/tikz/grid/#3} {pgfk@/tikz/grid/#4}
}
\cs_new_nopar:Npn \grid_vertical_from_keys:nnnn #1#2#3#4
{
\grid_vertical:nvvv {#1} {pgfk@/tikz/grid/#2} {pgfk@/tikz/grid/#3} {pgfk@/tikz/grid/#4}
}
\tikzset{
grid/.is~ family,
grid/start/.initial=1,
grid/total/.initial=20,
grid/choices/.initial=5,
horizontal~ grid/.pic={
\grid_horizontal_from_keys:nnnn {#1} {choices} {start} {total}
},
vertical~ grid/.pic={
\grid_vertical_from_keys:nnnn {#1} {choices} {start} {total}
}
}
\ExplSyntaxOff
\begin{document}\pagestyle{empty}
\begin{tikzpicture}[x=1cm, y=1cm, font=\scriptsize\bfseries]
\fill[red] (0,0) circle[radius=5pt];
\pic[
scale=.7,
pic anchor=(-grid.east),
grid/.cd,
start=3,
total=15
]
{horizontal grid={0;2;3;4;5;4;3;2;1;2;3;4;5;4;3;2;1;2;3;4}};
\pic[
scale=.7,
pic anchor=(-picture.west),
grid/.cd,
start=3,
total=15
]
{vertical grid={0;2;3;4;5;4;3;2;1;2;3;4;5;4;3;2;1;2;3;4}};
\end{tikzpicture}
\end{document}
我重新调整了 pic 代码,将 L3 代码分解为单独的命令,然后从 pic 代码中调用这些命令。这还允许插入一个层来整理从 pgf 键获取的值,这样就不会弄乱主代码。我做的另一个调整是从顶部向下布局网格,而不是从底部向上布局。
我保留了网格和图片节点的轮廓,以便定位更加明显。显然,在最终版本中,这些将被删除(只是轮廓 - 而不是节点本身!)。