4

Is there a way to embed data (e.g. CSV data) into a PDF. I want to have a table with numeric data and the reader should be able to get the data directly, without need to copy & paste from the pdf (which often doesn't work).

Using a data URI, it's possible to create a link that contains the data itself. For example putting data:text/plain;charset=utf-8;base64,MSAyIDMNCjQgNSA2 as into a html-link will lead to a 'website' showing the plain text data:

1 2 3
4 5 6

I tried putting this into a PDF with latex, using \href{URI}{click here to get data} in the pdf, but clicking on the link, nothing happens (it only works if I copy and paste the link in a browser).

Is there some way of embedding the machine-readable data of the table?

Here's what I have done so far:

\documentclass{article}
\usepackage{hyperref}
\begin{document}
\begin{table}
 \centering
 \begin{tabular}{ccc}
  1 & 2 & 3 \\
  4 & 5 & 6 \\
 \end{tabular}
 \caption{To get the data, click \href{data:text/plain;charset=utf-8;base64,MSAyIDMNCjQgNSA2}{here}.}
\end{table}
\end{document}
  • Could you post a full minimal example code? – Bernard May 30 '18 at 18:44
  • Thanks for the comment. I added a minimum (not) working example. – John Smith May 30 '18 at 18:53
  • PDF viewers can have problems with the protocol data:. Some (evince, sumatraPDF) at least allow to copy the target URL. Then the URL can be copied to the address bar of a browser to show the numbers. – Heiko Oberdiek May 30 '18 at 19:20
2

Files can be embedded using the attachfile package. However, opening the embedded file does not work with all pdf viewers, e.g., it works in Adobe Reader but it does not work (properly) in Evince.

Note that the file is actually embedded in the pdf, i.e., you don't need to provide the file separately when distributing your document.

MWE:

\documentclass{article}
\usepackage{attachfile}
\begin{document}
The csv file is attached: \attachfile{embed.csv}
\end{document}

Result:

enter image description here

  • this is almost perfect - I'll accept it. I wish this was supported more widely by pdf viewers tough. – John Smith May 30 '18 at 19:14
2

I here use features of the accsupp package. Here I introduce csvtabular environment that typesets the tabular in the normal way, but using a copy/paste on the PDF, produces CSV style output.

It does this, by taking \BODY that the environ package provides and using a listofitems parsing to replace & with , and replace \\ with \n. Note that having a trailing \\ on the last row of data, while innocuous to tabular, will break csvtabular...don't do it!

\documentclass{article}
\usepackage{accsupp,environ,listofitems}
\makeatletter
\NewEnviron{csvtabular}[1]{
  \setsepchar{\\/&}%
  \readlist*\mylist{\BODY}%
  \def\tmp{}%
  \foreachitem\myrow\in\mylist{%
    \foreachitem\mycol\in\mylist[1]{%
      \ifnum\mycolcnt=1\else\g@addto@macro\tmp{, }\fi%
      \expandafter\expandafter\expandafter\g@addto@macro%
        \expandafter\expandafter\expandafter\tmp\expandafter%
           \expandafter\expandafter{\mylist[\myrowcnt,\mycolcnt]}
    }%
    \g@addto@macro\tmp{\string\n }%
  }%
  \BeginAccSupp{method=escape,ActualText={\tmp}}
  \begin{tabular}{#1}
  \BODY
  \end{tabular}
  \EndAccSupp{}
}
\makeatother
\begin{document}
\begin{table}
 \centering
 \begin{csvtabular}{ccc}
  1 & 2 & 3 \\
  4 & 5 & 6 
 \end{csvtabular}
 \caption{To get the data, highlight the tabular data and copy/paste.}
\end{table}
\end{document}

enter image description here

Here is what you get when you copy and paste the tabular data:

1, 2, 3\n4, 5, 6\n

ORIGINAL (MANUAL) APPROACH

\documentclass{article}
\usepackage{accsupp}
\begin{document}
\begin{table}
 \centering
 \BeginAccSupp{method=escape,ActualText={1, 2, 3<CR> 4, 5, 6<CR>}}
 \begin{tabular}{ccc}
  1 & 2 & 3 \\
  4 & 5 & 6 \\
 \end{tabular}
 \EndAccSupp{}
 \caption{To get the data, highlight the tabular data and copy/paste.}
\end{table}
\end{document}
  • ok, this is already much better than the attempt to copy from the table as it was, but it's not quite as convenient as I'd like it to be. – John Smith May 30 '18 at 19:11
  • 1
    Numbers are not problematic, thus method plain can be used to get new line characters (\n via \string\n): \BeginAccSupp{method=plain,ActualText={1, 2, 3\string\n4, 5, 6}} – Heiko Oberdiek May 30 '18 at 19:15
  • @JohnSmith I fully understand. – Steven B. Segletes May 30 '18 at 19:15
  • @JohnSmith I have autoencapsulated the process into the environment csvtabular. – Steven B. Segletes May 30 '18 at 19:36

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.