12

I have some personal information stored in a plain CSV file personal_info.csv in the following format:

personal_info.csv

83 Fancy Avenue,Nowheresville,Gotham City 24061
123 456 7890
someone@xyz.com

I need to populate the relevant fields of the below main.tex (non-working/mockup) using class moderncv with this personal information as shown below.

Mock-up (non-working concept) of main.tex

\documentclass[11pt,a4paper,sans]{moderncv}
\moderncvstyle{classic}

\firstname{John}
\familyname{Doe}

%% NOT WORKING MOCKUP! (Relevant content to be read from csv file `personal_info.tex`)
\address{\firstfieldofline1}{\secondfieldofline1}{\thirdfieldofline2} 
\phone[mobile]{\firstfieldofline2}
\email{\firstfieldofline3}

\begin{document}
   \makecvtitle
\end{document}

to produce the desired output main.pdf (compiled with pdflatex).

desired output with populated fields from csv file

How can this be achieved?

  • May I ask why you want to do that? You need such personal only one time in your cv, I think it would be better to include them directly. Did you already tried something? Can you show us that code? – Kurt Feb 11 at 19:49
  • @Kurt I wish to open-source my CV in github (because my friends asked for it), but of course, don't want the whole world to know where I live. So, I shall be encrypting this csv file with gpg and committing to the repo. – Krishna Feb 11 at 19:50
  • 4
    Why so complicated? use a file mydata.tex, define there dummy infos for the github and call it in your cv. For personal use keep a copy with real informations. No needs to encrypt or using complicated tools causing perhaps unwanted errors ... I'm not sure -- not tested -- that moderncv cooperates wirh datatool etc. – Kurt Feb 11 at 19:59
8

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
someone@xyz.com
\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}

enter image description here

12

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 spaces (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:

enter image description here

Full code:

\RequirePackage{filecontents}
\begin{filecontents*}{\jobname.csv}
83 Fancy Avenue,Nowheresville,Gotham City 24061
123 456 7890
someone@xyz.com
\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 Kut's idea of a .txt file with definitions is far simpler :)

9

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{john@doe.org}
\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{john@doe.org}
\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 ...

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.