Populate information from a csv file into a LaTeX document (specifically into the fields/arguments of commands therein)
Quick and dirty expl3
implementation:
First you load the CSV file with \LoadCSV{<label>}{<file>}
. This command will open the file and load the contents of the CSV into <label>
. The contents of the file are read verbatim (all catcodes are other
(12), except for space
s (10)).
Then you get a field with \GetCSV{<label>}{<line>}{<field>}
.
Replacing your mockup code with:
\LoadCSV {mycsv} {\jobname.csv}
\address{\GetCSV{mycsv}{1}{1}}{\GetCSV{mycsv}{1}{2}}{\GetCSV{mycsv}{1}{3}}
\phone[mobile]{\GetCSV{mycsv}{2}{1}}
\email{\GetCSV{mycsv}{3}{1}}
it prints:
Full code:
\RequirePackage{filecontents}
\begin{filecontents*}{\jobname.csv}
83 Fancy Avenue,Nowheresville,Gotham City 24061
123 456 7890
[email protected]
\end{filecontents*}
\documentclass[11pt,a4paper,sans]{moderncv}
\usepackage{expl3}
\ExplSyntaxOn
\ior_new:N \l__krishna_ior_tmpa
\cs_new:Npn \krishna_csv_load:nn #1 #2
{
\cs_if_free:cTF { l__krishna_ #1 _seq }
{ \__krishna_csv_load:nn { l__krishna_ #1 } {#2} }
{ \msg_error:nnn { krishna / csv } { name-used } {#1} }
}
\cs_new:Npn \__krishna_csv_load:nn #1 #2
{
\ior_open:Nn \l__krishna_ior_tmpa {#2}
\seq_new:c { #1 _seq }
\exp_args:Nc
\__krishna_csv_read:N { #1 _seq }
\ior_close:N \l__krishna_ior_tmpa
}
\cs_new:Npn \__krishna_csv_read:N #1
{
\ior_str_map_inline:Nn \l__krishna_ior_tmpa
{ \seq_put_right:Nn #1 {##1} }
}
\cs_new:Npn \krishna_csv_get:nnn #1 #2 #3
{
\exp_args:Nf
\clist_item:nn
{ \seq_item:cn { l__krishna_ #1 _seq } {#2} }
{#3}
}
\msg_new:nnn { krishna / csv } { name-used }
{ The~CSV~name~`#1'~is~already~taken }
\cs_new_eq:NN \LoadCSV \krishna_csv_load:nn
\cs_new_eq:NN \GetCSV \krishna_csv_get:nnn
\ExplSyntaxOff
\moderncvstyle{classic}
\firstname{John}
\familyname{Doe}
\LoadCSV {mycsv} {\jobname.csv}
\address{\GetCSV{mycsv}{1}{1}}{\GetCSV{mycsv}{1}{2}}{\GetCSV{mycsv}{1}{3}}
\phone[mobile]{\GetCSV{mycsv}{2}{1}}
\email{\GetCSV{mycsv}{3}{1}}
\begin{document}
\makecvtitle
\end{document}
But @Mensch's idea of a .tex
file with definitions is far simpler :)
With readarray
(and listofitems
included).
First, I employ readarray
macros
\readarraysepchar{\\}
\readdef{personalinfo.csv}\myrawdata
to take the contents of personalinfo.csv
and place it into the macro \myrawdata
, all the while converting end-of-record tokens into \\
. Then, with listofitems
macros,
\setsepchar{\\/,}
\readlist*{\mydata}{\myrawdata}
I set up a 2-tier parsing of \myrawdata
and place the result into the array named \mydata
. The \\
token separates the 1st tier items, and the ,
separates the 2nd-tier items within each 1st-tier item.
The syntax of listofitems
allows the array to be recalled by the indices of the parsing. Thus \mydata[1,2]
will extract the tokens of \myrawdata
that occurred before the 1st \\
and, within that set of tokens, those that are between the 1st and 2nd ,
.
The MWE:
\RequirePackage{filecontents}
\begin{filecontents*}{personalinfo.csv}
83 Fancy Avenue,Nowheresville,Gotham City 24061
123 456 7890
[email protected]
\end{filecontents*}
\documentclass[11pt,a4paper]{moderncv}
\usepackage{readarray}
\moderncvstyle{classic}
\moderncvcolor{green}
\renewcommand{\familydefault}{\rmdefault}
\firstname{John}
\familyname{Doe}
\title{Title}
\readarraysepchar{\\}
\readdef{personalinfo.csv}\myrawdata
\setsepchar{\\/,}
\readlist*{\mydata}{\myrawdata}
\address{\mydata[1,1]}{\mydata[1,2]}{\mydata[1,3]}
\phone[mobile]{\mydata[2,1]}
\email{\mydata[3,1]}
\begin{document}
\makecvtitle
\end{document}
Let us say we have the following code:
\documentclass[11pt,a4paper,sans]{moderncv}
% moderncv themes
\moderncvstyle{classic} % casual, classic, banking, oldstyle and fancy
\moderncvcolor{blue}
\usepackage[utf8]{inputenc}
\usepackage[scale=0.75]{geometry}
% personal data
\name{John}{Doe}
\title{Resumé title}
\address{street and number}{postcode city}{country}
\phone[mobile]{+1~(234)~567~890}
\phone[fixed]{+2~(345)~678~901}
\phone[fax]{+3~(456)~789~012}
\email{[email protected]}
\homepage{www.johndoe.com}
\social[linkedin]{john.doe}
\social[twitter]{jdoe}
\social[github]{jdoe}
\extrainfo{additional information}
\photo[64pt][0.4pt]{example-image-a}
\quote{Some quote}
\setlength{\footskip}{66pt}
\begin{document}
\makecvtitle
\section{Education}
\cventry{year--year}{Degree}{Institution--3}{City--4}{\textit{Grade}--5}{Description--6} % arguments 3 to 6 can be left empty
\cventry{year--year}{Degree}{Institution}{City}{\textit{Grade}}{Description}
\section{Master thesis}
\cvitem{title}{\emph{Title}}
\cvitem{supervisors}{Supervisors}
\cvitem{description}{Short thesis abstract}
\end{document}
Now move the personal data into a new file mydata.tex
:
\name{John}{Doe}
\title{Resumé title}
\address{street and number}{postcode city}{country}
\phone[mobile]{+1~(234)~567~890}
\phone[fixed]{+2~(345)~678~901}
\phone[fax]{+3~(456)~789~012}
\email{[email protected]}
\homepage{www.johndoe.com}
\social[linkedin]{john.doe}
\social[twitter]{jdoe}
\social[github]{jdoe}
\extrainfo{additional information}
\photo[64pt][0.4pt]{example-image-a}
\quote{Some quote}
After that you can use the new code (simply used \input
instead the original personal datas):
\documentclass[11pt,a4paper,sans]{moderncv}
% moderncv themes
\moderncvstyle{classic} % casual, classic, banking, oldstyle and fancy
\moderncvcolor{blue}
\usepackage[utf8]{inputenc}
\usepackage[scale=0.75]{geometry}
% personal data
\input{mydata.tex} % <===========================================
\setlength{\footskip}{66pt}
\begin{document}
\makecvtitle
\section{Education}
\cventry{year--year}{Degree}{Institution--3}{City--4}{\textit{Grade}--5}{Description--6} % arguments 3 to 6 can be left empty
\cventry{year--year}{Degree}{Institution}{City}{\textit{Grade}}{Description}
\section{Master thesis}
\cvitem{title}{\emph{Title}}
\cvitem{supervisors}{Supervisors}
\cvitem{description}{Short thesis abstract}
\end{document}
There are no differences in the both resulting pdfs ...
Post the shown mydata.tex
with the code for the cv on github and keep a copy of mydata.tex
for your own purpose, of course filled with your real informations for a real cv ...