Files
2colscv/2colscv.cls
2025-06-07 16:01:59 +02:00

389 lines
10 KiB
TeX

%%%%%%%%%%%%%%%%%%%%
%
% License: MIT
%
% https://git.hadow.fr/sam.hadow/2colscv
%
% based on the template twentysecondscv (https://github.com/spagnuolocarmine/TwentySecondsCurriculumVitae-LaTex)
%
%%%%%%%%%%%%%%%%%%%%
% CLASS
%%%%%%%%%%
\ProvidesClass{2colscv}[CV class]
\LoadClass{article}
\NeedsTeXFormat{LaTeX2e}
% PACKAGES
%%%%%%%%%%
\RequirePackage[sfdefault]{ClearSans}
\RequirePackage[T1]{fontenc}
\RequirePackage{tikz}
\usetikzlibrary{calc}
\RequirePackage{xcolor}
\RequirePackage[absolute,overlay]{textpos}
\RequirePackage{ragged2e}
\RequirePackage{etoolbox}
\RequirePackage{ifmtarg}
\RequirePackage{ifthen}
\RequirePackage{pgffor}
\RequirePackage{marvosym}
\RequirePackage{parskip}
\RequirePackage{array}
\RequirePackage{xstring}
\RequirePackage{fontawesome5}
% OPTIONS
%%%%%%%%%%
\DeclareOption{print}{\def\@cv@print{}}
\DeclareOption*{
\PassOptionsToClass{\CurrentOption}{article}
}
\ProcessOptions\relax
% page settings
\RequirePackage[left=7.3cm,top=0.1cm,right=0.5cm,bottom=0.2cm,nohead,nofoot]{geometry}
\RequirePackage{hyperref}
% COLORS
%%%%%%%%%%
\definecolor{white}{RGB}{255,255,255}
\definecolor{darkgray}{HTML}{333333}
\definecolor{gray}{HTML}{4D4D4D}
\definecolor{sidecolor}{HTML}{E7E7E7}
\definecolor{lightgray}{HTML}{999999}
\definecolor{green}{HTML}{C2E15F}
\definecolor{orange}{HTML}{FDA333}
\definecolor{purple}{HTML}{D3A4F9}
\definecolor{red}{HTML}{FB0B00}
\definecolor{blue}{HTML}{6CE0F1}
\definecolor{mainblue}{HTML}{0E5484}
\definecolor{cerulean}{HTML}{007BA7}
\definecolor{maingray}{HTML}{B9B9B9}
\definecolor{maindarkgray}{HTML}{B3B3B3}
\ifdefined\@cv@print
\colorlet{green}{gray}
\colorlet{orange}{gray}
\colorlet{purple}{gray}
\colorlet{red}{gray}
\colorlet{blue}{gray}
\colorlet{fillheader}{white}
\colorlet{asidecolor}{sidecolor}
\colorlet{header}{gray}
\else
\colorlet{fillheader}{gray}
\colorlet{header}{white}
\colorlet{asidecolor}{sidecolor}
\fi
\colorlet{textcolor}{gray}
\colorlet{headercolor}{gray}
%%%%%%%%%%%%%%%%%%%%
% PROFILE
%%%%%%%%%%%%%%%%%%%%
% LEFT SIDEBAR
%%%%%%%%%%
\setlength{\TPHorizModule}{1cm}
\setlength{\TPVertModule}{1cm}
% compute size of profile picture
\newcommand{\imsize}{\linewidth}
\newlength\imagewidth
\newlength\imagescale
\renewcommand{\imsize}{0.618\linewidth}
\pgfmathsetlength{\imagewidth}{5cm}%
\pgfmathsetlength{\imagescale}{\imagewidth/600}%
\newcommand{\profilesection}[2]{{\noindent\color{black!80} \huge #1 \rule[0.15\baselineskip]{#2}{1pt} \vspace{1pt}}}
\newcommand{\cvdate}[1]{\renewcommand{\givencvdate}{#1}} % date
\newcommand{\cvmail}[1]{\renewcommand{\givencvmail}{#1}} % mail
\newcommand{\cvnumberphone}[1]{\renewcommand{\givennumberphone}{#1}} % phone
\newcommand{\cvaddress}[1]{\renewcommand{\givencvaddress}{#1}} % address
\newcommand{\cvsite}[1]{\renewcommand{\givencvsite}{#1}} % site
\newcommand{\aboutme}[1]{
\renewcommand{\givenaboutme}{
\leavevmode
\vadjust pre{\vspace*{0.75em}}
\justifying{#1}
\vspace{1em}
\\
}
} % about me
\newcommand{\profilepic}[1]{\renewcommand{\givenprofilepic}{#1}} % picture
\newcommand{\cvname}[1]{\renewcommand{\givencvname}{#1}} % name
\newcommand{\cvjobtitle}[1]{\renewcommand{\givencvjobtitle}{#1}} % job title
\newcommand{\givencvname}{REQUIRED!} % name
\newcommand{\givencvdate}{} % date
\newcommand{\givencvmail}{} % mail
\newcommand{\givennumberphone}{} % phone
\newcommand{\givencvaddress}{} % address
\newcommand{\givenaboutme}{} % about me
\newcommand{\givenprofilepic}{} % picture
\newcommand{\givencvsite}{} % site
\newcommand{\givencvjobtitle}{} % job title
% icon in blue circle; #1 -> icon
\newcommand*\icon[1]{\tikz[baseline=(char.base)]{
\node[shape=circle,draw,inner sep=1pt, minimum size=1.5em, fill=mainblue,mainblue,text=white] (char) {#1};}
}
% Text in square node with rounded corners; #1 -> text, #2 -> color
\newcommand*\round[2]{%
\tikz[baseline=(char.base)]\node[anchor=north west, draw,rectangle,
rounded corners, inner sep=3pt, minimum size=5.5mm, text height=3.6mm,
fill=#2,#2,text=white](char){#1};%
}
% langskills macro
% language, CEFR level (A1 to C2), certification%
% Usage: \langskills{%
% English/C2/CPE,%
% Spanish/C1/DELE%
% }
\newcommand\langskills[1]{%
\renewcommand{\givenskill}{%
\noindent
\begin{tikzpicture}[x=1cm,y=1cm]
% Loop over entries <Language>/<CEFR-code>/<Certification>
\foreach [count=\i] \L/\CEFR/\CERT in {#1} {%
% (a) Compute the vertical position for row \i (1.2 cm between rows):
\pgfmathsetmacro{\y}{-\i * 1.7} % e.g. for i=1, y=-1.2; for i=2, y=-2.4, etc.
% (b) Language name
\node[anchor=west] at (0, { \y + 0.8 }) {\large{\L}};
% (c) Certification
\node[anchor=east] at (6, { \y + 0.8 }) {\CERT};
% (d) Gray background bar
\draw[fill=maingray, draw=none] (0,\y) rectangle (6,\y + 0.4);
% (e) Convert CEFR code to integer 1..6
\def\nCEFR{0}%
\IfStrEq{\CEFR}{A1}{\def\nCEFR{1}}{%
\IfStrEq{\CEFR}{A2}{\def\nCEFR{2}}{%
\IfStrEq{\CEFR}{B1}{\def\nCEFR{3}}{%
\IfStrEq{\CEFR}{B2}{\def\nCEFR{4}}{%
\IfStrEq{\CEFR}{C1}{\def\nCEFR{5}}{%
\IfStrEq{\CEFR}{C2}{\def\nCEFR{6}}{}}}}}}%
% (f) Fill the bar in blue from x=0 to x=CEFR:
\draw[fill=mainblue, draw=none] (0,\y) rectangle (\nCEFR,\y + 0.4);
% (g) Draw 7 tick-marks at x=0,…,6 with CEFR labels 1->A1, …, 6->C2:
\draw[thick] (0,\y - 0.1) -- (6,\y - 0.1); % baseline
\foreach \z in {0,...,6} {
\draw (\z,\y - 0.1) -- (\z,\y - 0.2);
\ifnum\z>0
\edef\tmp{%
\ifnum\z=1 A1\fi
\ifnum\z=2 A2\fi
\ifnum\z=3 B1\fi
\ifnum\z=4 B2\fi
\ifnum\z=5 C1\fi
\ifnum\z=6 C2\fi
}%
\node[font=\scriptsize, anchor=north] at (\z,\y - 0.2) {\tmp};
\fi
}
} % end \foreach
\end{tikzpicture}%
}% end \renewcommand{\givenskill}
}% end \newcommand{\langskills}
% text style skills
\newcommand{\givenskill}{}
\newcommand\skillstext[1]{
\renewcommand{\giventextskill}{
\begin{flushleft}
\noindent
\foreach [count=\i] \x/\y in {#1}
{
\x$ \star $\y
}
\end{flushleft}
}
}
% empty fallback
\newcommand{\giventextskill}{}
\newcommand{\makeprofile}
{
% grey bar on the left side
\begin{tikzpicture}[remember picture,overlay]
\node [rectangle, fill=asidecolor, anchor=north, minimum width=9.90cm, minimum height=\paperheight+1cm] (box) at (-5cm,0.5cm){};
\end{tikzpicture}
\begin{textblock}{6}(0.5, 0.2)
% profile picture (centered)
\begin{flushleft}
\centering
\ifthenelse{\equal{\givenprofilepic}{}}{}{\begin{tikzpicture}[x=\imagescale,y=-\imagescale]
\clip (600/2, 567/2) circle (567/2);
\node[anchor=north west, inner sep=0pt, outer sep=0pt] at (0,0) {\includegraphics[width=\imagewidth]{\givenprofilepic}};
\end{tikzpicture}}
\end{flushleft}
\begin{flushleft}
\hspace{13pt}
% name
{\Huge\color{mainblue}\givencvname}
% jobtitle
\begin{flushright}
{\Large\color{black!80}\givencvjobtitle}
\end{flushright}
\renewcommand{\arraystretch}{1.6}
% personnal info with icons
\begin{tabular}{c l}
% CV birthdate
\ifthenelse{\equal{\givencvdate}{}}{}{\textsc{\Large\icon{\Info}} & \givencvdate\\}%
% CV address
\ifthenelse{\equal{\givencvaddress}{}}{}{\textsc{\Large\icon{\Letter}} & \givencvaddress\\}%
% CV phone
\ifthenelse{\equal{\givennumberphone}{}}{}{\textsc{\Large\icon{\faMobile*}} & \givennumberphone\\}%
% CV website
\ifthenelse{\equal{\givencvsite}{}}{}{\textsc{\Large\icon{\faGlobe}} & \href{\givencvsite}{\textcolor{cerulean}{\givencvsite}}\\}%
% CV email
\ifthenelse{\equal{\givencvmail}{}}{}{\textsc{\Large\icon{\faEnvelope[regular]}} & \href{mailto:\givencvmail}{\givencvmail}}%
\end{tabular}
% about me text
\profilesection{About me}{3.2cm}
\givenaboutme
% skills section
% languages
\profilesection{Languages}{2.7cm}
\givenskill
% other skills
\giventextskill
\noindent
\scriptsize
\noindent
\end{flushleft}
\end{textblock}
\vspace{-10pt}
}
% SECTIONS
%%%%%%%%%%
\newcounter{colorCounter}
\def\@sectioncolor #1{
{%
% Switch between blue and gray
\round{#1}{%
\ifodd\value{colorCounter}%
mainblue%
\else%
maingray%
\fi%
}%
}%
\stepcounter{colorCounter}%
}
\renewcommand{\section}[1]{%
\par
{%
\LARGE
\color{headercolor}%
\@sectioncolor{#1}%
}%
\par\vspace{\parskip}%
}
\newcommand{\sectionicon}[2]{
\par%
{%
\LARGE
#1
\color{headercolor}%
\@sectioncolor #2%
}
\par\vspace{\parskip}
}
\renewcommand{\subsection}[1]{
\par\vspace{.5\parskip}%
{%
\large\color{headercolor} #1%
}
\par\vspace{.25\parskip}%
}
\pagestyle{empty}
% experience/education list environment
%%%%%%%%%%
\setlength{\tabcolsep}{0pt}
\newenvironment{experience}{%
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}ll}
}{%
\end{tabular*}
}
\renewcommand{\bfseries}{\color{headercolor}}
\newcommand{\experienceitem}[4]{%
\hspace{5pt}#1&\parbox[t]{11.2cm}{%
\textbf{#2}%
\hfill%
{\footnotesize#3}\\%
#4\vspace{\parsep}%
}\\%
}
\setlength{\tabcolsep}{0pt}
\newenvironment{cvicon}{%
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}ll}
}{%
\end{tabular*}
}
\renewcommand{\bfseries}{\color{headercolor}}
\newcommand{\cviconitem}[5]{%
\hspace{3pt}\faicon{#1}\hspace{2pt}#2&\parbox[t]{11.2cm}{%
\textbf{#3}%
\hfill%
{\footnotesize#4}\\%
#5\vspace{\parsep}%
}\\%
}
% short list environment (publication)
%%%%%%%%%%
\setlength{\tabcolsep}{0pt}
\newenvironment{shortlist}{%
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}ll}
}{%
\end{tabular*}
}
\renewcommand{\bfseries}{\color{headercolor}}
\newcommand{\shortlistitem}[2]{%
\hspace{5pt}#1&\parbox[t]{11.5cm}{%
\textbf{#2}%
}\\%
}
\setlength{\tabcolsep}{0pt}
\newenvironment{cviconshort}{%
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}ll}
}{%
\end{tabular*}
}
\renewcommand{\bfseries}{\color{headercolor}}
\newcommand{\cviconshortitem}[3]{%
\hspace{3pt}\faicon{#1}\hspace{3pt}#2&
\parbox[t]{11.5cm}{%
\textbf{#3}%
}\\%
}