21

We're using LaTeX to render a PDF with a form that will be filled in by humans, using a pen, and then fed to an OpenCV application for recognition. The form consists of questions with small squares (\fbox symbols) that people fill to answer yes or no.

The thing is, our recognition algorithm works better when we can provide to it some hint as to where are the \fboxes located. So we arrange them in a pattern, with some fixed distance from the borders and in between. However, if we want to create more complex layouts, we need to first render the document, and then looking at the PDF figure out the margins, separations, etc.

We would like to automate this process as much as possible, so the general question is: what is the best way to "mark" some symbols in LaTeX so that I can later somehow recover their location in the rendered PDF (probably using a second tool to look inside the PDF, I guess)?

  • Does your project will be free ? – projetmbc Oct 22 '14 at 9:12
  • Yes, it is for a free academic open-source project called autoexam that generates exam sheets which can later be automatically evaluated. It is hosted on Github, though it is a bit out of sync with our current master branch. – Alejandro Piad Oct 22 '14 at 14:12
  • Cool ! Is this project : github.com/matcom/autoexam ? – projetmbc Oct 23 '14 at 15:14
  • Yes it is! I'm impressed that you find it? I didn't published a link here because I felt it would be like advertising myself. Feel free to comment, submit issues, fork it, and use it whatever way you desire! – Alejandro Piad Oct 23 '14 at 16:01
  • I have starred your project and I will contribute if I can. Thanks for this project ! – projetmbc Oct 24 '14 at 17:54
35
+200

Use

\fbox{%
\pdfsavepos\write-1{hello is at \the\pdflastxpos,\the\pdflastypos}%
hello%
}

and the log file will have the coordinates in scaled points

The above produces a line such as the following in the log file:

hello is at 10005380,43282099
  • Great! That'll do it. Just one more question. How can I scale those values back to something like inches, cm, etc? – Alejandro Piad Oct 15 '14 at 15:21
  • @AlejandroPiad 2^{16}sp= 1pt and 72.27pt=1in and 72bp=1in and a postscript point = 1bp, you could get tex to do some arithmetic while writing it out, but possibly easier to do it in whatever software is post processing this – David Carlisle Oct 15 '14 at 15:28
18

Here is a possible solution via TikZ:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand\mybox{%
  \begin{tikzpicture}[remember picture]
    \draw (0,0) rectangle (.6em,.6em);
    \path let \p1=($(.3em,.3em) - (current page.south west)$)
    in \pgfextra{
      \pgfmathsetmacro\xpos{\x1/1cm}
      \pgfmathsetmacro\ypos{\y1/1cm}
      \typeout{checkboxpos:(\xpos cm,\ypos cm)}
    };
  \end{tikzpicture}%
}
\begin{document}

This is a test \mybox{}.

\begin{itemize}
\item[\mybox{}] First item.
  \begin{itemize}
  \item[\mybox{}] First subitem.
  \item[\mybox{}] Second subitem.
  \item[\mybox{}] Third subitem.
  \end{itemize}
\item[\mybox{}] Second item.
\item[\mybox{}] Third item.
\end{itemize}

\end{document}

After two compilations, you got this log:

checkboxpos:(7.49284cm,23.29828cm)
checkboxpos:(5.30951cm,22.52507cm)
checkboxpos:(6.08272cm,21.82214cm)
checkboxpos:(6.08272cm,21.25981cm)
checkboxpos:(6.08272cm,20.69748cm)
checkboxpos:(5.30951cm,19.99455cm)
checkboxpos:(5.30951cm,19.29164cm)
  • Thanks @PaulGaborit for answering. I like your solution a lot, and will definitely give it a try. +1d'! – Alejandro Piad Oct 15 '14 at 15:34
8

The main point of this task is usage of pdfTeX primitives \pdfsavepos, \pdflastxpos, \pdflastypos. You can create a macro \saveposition which saves the actual position to the file \jobname.pos in the form:

1: 67.65254mm, 267.37009mm
2: 101.77405mm, 267.37009mm
3: 67.65254mm, 261.73753mm
4: 101.77405mm, 261.73753mm

The number of the checkbox is here followed by x and y coordinate. The (0,0) of coordinate system is the left-bottom corner of the paper. You need not two pass of TeX processing. This file is created immediately after first TeX run.

The implemetation of \saveposition macro can be as following:

\newcount\posnum
\newwrite\posout

\immediate\openout\posout=\jobname.pos

\def\saveposition{\global\advance\posnum by1 \pdfsavepos
   \write\posout\expandafter{\the\posnum: \tomm\pdflastxpos, \tomm\pdflastypos}}

\def\tomm#1{\expandafter\ignorept\the\dimexpr.35146\dimexpr#1sp\relax\relax mm}
{\lccode`\?=`\p \lccode`\!=`\t  \lowercase{\gdef\ignorept#1?!{#1}}}

The conversion from sp to mm unit is done by \tomm macro using eTeX primitive \dimexpr.

Now the test. You need to put the \saveposition to your \fbox macro. Because I don't use LaTeX, I have to create the whole \fbox:

\def\fbox{\leavevmode \saveposition
  \lower3pt \hbox{\vrule \vbox{\hrule width1cm \kern.5cm \hrule}\vrule}%
}

aghd sajhas hds ddjds \fbox\ dhjdka ak das \fbox

aghd sajhas hds ddjds \fbox\ dhjdka ak das \fbox

\end

Note that you needn't use any special package (like tikz mentioned here in an another answer).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.