Как получить позицию элемента в LaTeX?

Как получить позицию элемента в LaTeX?

У меня есть тест с флажками, сделанный в LaTeX для распознавания результатов вqueXF. Это работает нормально, но если я что-то меняю в исходном коде, поля смещаются, а поля распознавания queXF становятся недействительными.

Можно ли вывести абсолютную позицию и размеры элемента блока во внешний файл?

Например, у меня есть следующий код:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand{\checkBox}[1]{
    \begin{tikzpicture}[color=black, line width=0.2mm]
        \draw (0,0) rectangle (5mm,5mm);
    \end{tikzpicture}
}
\begin{document}
    Question:\\
    \checkBox{Q1A}~Answer A\\
    \checkBox{Q1B}~Answer B\\
    \checkBox{Q1C}~Answer C\\
    \checkBox{Q1D}~Answer D\\
\end{document}

Выходные данные:

введите описание изображения здесь

И я хочу получить информацию о позициях и размерах коробок (если это возможно) по их идентификаторам. Может быть, что-то вроде этого:

\Q1A{3cm}{2cm}{5mm}{5mm}
\Q2B{3cm}{2.5cm}{5mm}{5mm}

Или в любом другом формате, который можно проанализировать.

Любые идеи будут высоко оценены.

решение1

Если вы используете remember pictureопцию tikzpictureизображения, то источник записывается во вспомогательный файл ( .aux). Используемая единица измерения —масштабированные баллы spчто составляет 65536sp = 1pt = 1/72.27inch. Начало координат IIRC - нижний левый угол страницы. Вы также можете сохранить любое содержимое в регистре ящиков и записать его размер во вспомогательный файл или другой.

Еще лучше zref-absposпакет, который позволяет получить абсолютное положение любой точки, также в sp. Вам нужно поместить a \zsavepos{<name>}в эти координаты, а затем можно получить координаты после одной компиляции с помощью \zposx{<name>}и \zposy{<name>}. В руководстве указано, что это хорошо только для относительных положений, поскольку нет официального начала отсчета, но во всех моих тестах это также был нижний левый угол страницы.

Следующий код должен это продемонстрировать:

\documentclass{article}
\usepackage{zref-user}
\usepackage{zref-abspos}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand{\checkBox}[1]{%
    \begin{tikzpicture}[color=black, line width=0.2mm]
        \draw (0,0)
            node {\zsavepos{#1-ll}}
            rectangle (5mm,5mm)
            node {\zsavepos{#1-ur}};
    \end{tikzpicture}%
    \write\mywrite{#1: \zposx{#1-ll}, \zposy{#1-ll}, \zposx{#1-ur}, \zposy{#1-ur}}%
}
\newwrite\mywrite
\openout\mywrite=\jobname.pos\relax
\begin{document}
    Question:\\
    \checkBox{Q1A}~Answer A\\
    \checkBox{Q1B}~Answer B\\
    \checkBox{Q1C}~Answer C\\
    \checkBox{Q1D}~Answer D\\
\end{document}

Он записывает .posфайл, который хранит позиции следующим образом:

Q1A: 9017948, 41890363, 9950287, 42822702
Q1B: 9017948, 40455628, 9950287, 41387967
Q1C: 9017948, 39020893, 9950287, 39953232
Q1D: 9017948, 37586158, 9950287, 38518497

Формат также можно изменить, чтобы получить значения в ptдругих единицах измерения или в точке отсчета плюс размер вместо абсолютного положения нижнего левого и верхнего правого угла, как сейчас.

Для вывода в формате mm замените \writeсодержимое на:

\write\mywrite{#1: (%
    \dimtomm{\zposx{#1-ll}sp},
    \dimtomm{\zposy{#1-ll}sp}) + (%
    \dimtomm{\zposx{#1-ur}sp-\zposx{#1-ll}sp},
    \dimtomm{\zposy{#1-ur}sp-\zposy{#1-ll}sp})%
}%

и добавьте следующий макрос:

\makeatletter
\newcommand\dimtomm[1]{%
    \strip@pt\dimexpr 0.351459804\dimexpr#1\relax\relax mm%
}
\makeatother

Тогда вы получите:

Q1A: (48.36134mm, 224.64914mm) + (4.99992mm, 4.99992mm)
Q1B: (48.36134mm, 216.95496mm) + (4.99992mm, 4.99992mm)
Q1C: (48.36134mm, 209.26077mm) + (4.99992mm, 4.99992mm)
Q1D: (48.36134mm, 201.5666mm) + (4.99992mm, 4.99992mm)

Если вас смущает показанная точность и вы предпочитаете округлять числа, взгляните на \pgfmathprintnumberPGF/TikZ. Однако, если вы все равно анализируете эти файлы, вы можете сделать это и тогда.


Если вы используете режим DVI (т.е. latexне pdflatex), то tikzpictureсоздается с помощью кода PostScript, выполняемогоdvips послеобработка TeX. В этом случае оба узла еще не размещены и получают те же координаты, которые должны быть началом изображения. Вместо этого я бы сохранил только одну точку и измерил бы размер изображения, чтобы получить другое. Обратите внимание, что я добавил немного кода PGF/TiKZ, чтобы убедиться, что это \zsaveposне повлияет на размер изображения.

\documentclass[a4paper]{article}
\usepackage{zref-user}
\usepackage{zref-abspos}
\usepackage{tikz}
\usetikzlibrary{calc}
\newsavebox\mybox
\newcommand{\checkBox}[1]{%
    \begingroup
    \sbox\mybox{%
        \begin{tikzpicture}[color=black, line width=0.2mm]
            % Pace the save pos "whatsit" without influencing the bounding box / size of the picture
            \begin{pgfinterruptboundingbox}
                \node at (0,0) {\zsavepos{#1-ll}};
            \end{pgfinterruptboundingbox}
            \draw (0,0) rectangle (5mm,5mm);
        \end{tikzpicture}%
    }%
    \usebox\mybox
    \immediate\write\mywrite{#1: (%
        \dimtomm{\zposx{#1-ll}sp},
        \dimtomm{\zposy{#1-ll}sp}) + (%
        \dimtomm{\wd\mybox},
        \dimtomm{\ht\mybox+\dp\mybox})%
    }%
    \endgroup
}
\makeatletter
\newcommand\dimtomm[1]{%
    \strip@pt\dimexpr 0.351459804\dimexpr#1\relax\relax mm%
}
\makeatother
\newwrite\mywrite
\immediate\openout\mywrite=\jobname.pos\relax
\begin{document}
    Question:\\
    \checkBox{Q1A}~Answer A\\
    \checkBox{Q1B}~Answer B\\
    \checkBox{Q1C}~Answer C\\
    \checkBox{Q1D}~Answer D\\
\end{document}

решение2

использование tikzдля коробок совершенно излишне ...

\documentclass{article}
\usepackage{xcolor,zref-savepos}
\newcommand\checkBox[1]{\zsavepos{#1}{\fboxsep=0pt\fbox{\color{white}\rule{5mm}{5mm}}}}
\newdimen\DimX \newdimen\DimY
\makeatletter
\newcommand\getCM[1]{%
  \DimX=\zposx{#1}sp\relax \DimX=0.0347\DimX
  \DimY=\zposy{#1}sp\relax \DimY=0.0347\DimY
  \strip@pt\DimX:\strip@pt\DimY}
\makeatother

\begin{document}
    Question:\\
    \checkBox{Q1A}~Answer A\\
    \checkBox{Q1B}~Answer B\\
    \checkBox{Q1C}~Answer C\\
    \checkBox{Q1D}~Answer D

\bigskip\noindent
\getCM{Q1A}\\
\getCM{Q1B}\\
\getCM{Q1C}\\
\getCM{Q1D}

\end{document}

введите описание изображения здесь

Связанный контент