13 Commits

Author SHA1 Message Date
Pedro Cabral
48775c8b9a added commit message 2026-07-17 15:57:05 +02:00
Pedro Cabral
ed1e7e1778 auto build only run after save 2026-07-17 13:20:49 +02:00
Pedro Cabral
9a410226b3 changed link to moderncv 2026-07-17 13:11:15 +02:00
Pedro Cabral
1e28e0ce7c removed reference to self 2026-07-17 13:10:44 +02:00
Pedro Cabral
3a6daf63dd added other CV variants to README.md 2026-07-17 13:09:23 +02:00
Pedro Cabral
2c58ebe28a added script to propagate commits across CV branches 2026-07-17 12:50:54 +02:00
Pedro Cabral
35e9e3ae5a deleting auto-generated files, iff pdf was successfully rendered 2026-07-17 12:39:17 +02:00
Pedro Cabral
b15d162916 renamed files and fixed path to photo 2026-07-17 11:49:45 +02:00
Pedro Cabral
17f242fb39 updated README.md 2026-07-17 11:49:45 +02:00
Pedro Cabral
88652088e4 merged .gitignore files 2026-07-17 11:49:34 +02:00
Pedro Cabral
82903010c5 moved files to root directory 2026-07-15 01:04:55 +02:00
Pedro Cabral
9ca759a5e1 removed moderncv variant 2026-07-15 00:19:09 +02:00
Pedro Cabral
735805ddf4 removed article type 2026-07-15 00:18:44 +02:00
10 changed files with 1042 additions and 126 deletions

12
.gitignore vendored
View File

@@ -1,14 +1,14 @@
# Ignore all files
*.*
# Whitelist
!.gitignore
!*.tex
!*.pdf
!*.cls
!*.jpg
!*.md
!.vscode/
!.vscode/**
!awesome-cv.cls
!*.tex
!*.pdf
!*.jpg
!*.md
!build/*.*

View File

@@ -16,5 +16,6 @@
}
],
"latex-workshop.latex.recipe.default": "Smart LaTeX Build",
"latex-workshop.formatting.latex": "latexindent"
"latex-workshop.formatting.latex": "latexindent",
"latex-workshop.latex.autoBuild.run": "onSave"
}

86
CV_Pedro_Cabral.tex Normal file
View File

@@ -0,0 +1,86 @@
\documentclass[11pt, a4paper]{awesome-cv}
% Configure page margins
\geometry{left=1.4cm, top=1.4cm, right=1.4cm, bottom=1.4cm, footskip=.5cm}
% Specify the location of the included fonts
\fontdir[fonts/]
% Color for highlights
\colorlet{awesome}{awesome-skyblue}
% Personal Information
\name{Pedro Miguel Pessoa}{Cabral}
\mobile{+49-(0)-17657-909188}
\email{pmpcabral@gmail.com}
\address{Rittmeisterkoppel 14-C, 22359 Hamburg, Germany}
% \github{}
% \linkedin{}
\photo{me_m_8x8_4x.jpg}
\begin{document}
% Make the header
\makecvheader
% Profile
\cvsection{Profile}
\begin{cvparagraph}
Date of Birth: January 17th, 1988 | Place of Birth: Setúbal, Portugal | Nationality: Portuguese
Languages: Portuguese (First language), German (Fluent), English (Fluent), Spanish (Good), French (Basic)
\end{cvparagraph}
% Experience
\cvsection{Experience}
\cventry
{Feb 2017 -- Present}
{Software Developer}
{HR4YOU AG}
{Großefehn, Germany}
{
\begin{cvitems}
\item {PHP, JavaScript, SQL}
\end{cvitems}
}
\cventry
{Sep 2014 -- Apr 2016}
{Support \& Operations}
{SAFIRA/KPMG}
{Carnaxide, Portugal}
{
\begin{cvitems}
\item {IBM Business Process Management, Forefront Identity Manager (FIM)}
\end{cvitems}
}
\cventry
{Apr 2013 -- Sep 2014}
{Software Developer}
{SAFIRA}
{Carnaxide, Portugal}
{
\begin{cvitems}
\item {IBM Business Process Management, IBM WebSphere Message Broker, SQL}
\end{cvitems}
}
% Education
\cvsection{Education}
\cventry
{2013}
{Bachelor of Science}
{Faculdade de Ciências e Tecnologia, Universidade Nova de Lisboa}
{Caparica, Portugal}
{}
% Skills
\cvsection{Skills}
\begin{cvskills}
\cvskill{Programming}{PHP, OOP, JavaScript, jQuery, CSS, SQL, SOAP, REST, PL/SQL, XML}
\end{cvskills}
\end{document}

View File

@@ -1,84 +0,0 @@
\documentclass[11pt,a4paper,sans]{pedro-moderncv}
\moderncvstyle{classic} % Style options: 'casual', 'classic', 'oldstyle', 'banking'
\moderncvcolor{blue} % Color options: 'blue', 'orange', 'green', 'red', 'purple', 'grey', 'black'
\usepackage[scale=0.75]{geometry}
% Personal data
\name{Pedro Miguel}{Pessoa Cabral}
\title{Curriculum Vitae}
\address{Rittmeisterkoppel 14C}{22359 Hamburg}{Germany}
\phone[mobile]{+49-(0)-17657-909188}
\email{pmpcabral@posteo.de}
\homepage{git.sueo.de/pcabral}
\social[]{} % Optional: GitHub, LinkedIn, etc.
\photo[3.5cm][0pt]{../me_m_8x8_4x.jpg}
\hyphenation{interpersonal}
\linespread{1.05}
\begin{document}
\makecvtitle
\begin{minipage}[t]{0.48\textwidth}
\section{Profile}
\cvitem{Date of Birth}{January 17\textsuperscript{th}, 1988}
\cvitem{Place of Birth}{Setúbal, Portugal}
\cvitem{Nationality}{Portuguese}
\end{minipage}\hfill
\begin{minipage}[t]{0.48\textwidth}
\section{Languages}
\cvitemwithcomment{Portuguese}{First Language}{}
\cvitemwithcomment{German}{Fluent}{}
\cvitemwithcomment{English}{Fluent}{}
\cvitemwithcomment{Spanish}{Good}{}
\cvitemwithcomment{French}{Basic}{}
\end{minipage}\hfill
\section{Experience}
\cventry{Apr 2025 -- Present}{Professional Sabbatical}{}{}{}{
Dedicated time to personal development and family life following an intensive period in my career. Used this
opportunity to recharge, reassess long-term goals, and return with renewed focus and motivation for software
engineering.
}
\cventry{Jun 2021 -- Apr 2025}{Software Developer}{For Sale Digital Internet-Agentur GmbH}{Hamburg, Germany}{}{
PHP (\textit{native, Laravel, WordPress}), JavaScript (\textit{Vanilla, jQuery}), MySQL, Google Cloud Platform, TypeScript, React, Jenkins, ShipIt, Docker, Shopify.
}
\cventry{Feb 2017 -- May 2021}{Software Developer}{HR4YOU AG}{Großefehn, Germany}{}{
PHP, JavaScript (\textit{Vanilla, jQuery}), MySQL, CSS, LESS.
}
\cventry{Sep 2014 -- Apr 2016}{Support \& Operations}{SAFIRA/KPMG}{Carnaxide, Portugal}{}{
IBM Business Process Management, Forefront Identity Manager (\textit{FIM}).
}
\cventry{Apr 2013 -- Sep 2014}{Software Developer}{SAFIRA}{Carnaxide, Portugal}{}{
IBM BPM, IBM WebSphere Message Broker, SQL.
}
\section{Education}
\cventry{2013}{Bachelor of Science}{Faculdade de Ciências e Tecnologia, Universidade Nova de Lisboa}{Caparica, Portugal}{}{}
\section{Skills}
\cvitem{Languages}{PHP, JavaScript (\textit{Vanilla}), TypeScript, MySQL, CSS, SCSS, HTML}
\cvitem{Frameworks \& Libraries}{Laravel, React, jQuery, Bootstrap}
\cvitem{Content Management Systems}{WordPress, Shopify}
\cvitem{Development Tools}{PHPStorm, Visual Studio Code, Git, Composer, npm, Vite}
\cvitem{DevOps \& Automation Tools}{Jenkins, ShipIt, Docker, Kubernetes, Google Cloud Platform}
\cvitem{Software Development Practices}{Test-Driven Development (TDD), Object-Oriented Programming (OOP), Mobile-First Design}
\cvitem{Soft Skills}{Effective team player, collaborator, and mentor; strong communication and interpersonal skills; experienced moderator}
\section{About me}
I believe there are no stupid questions --- only opportunities to learn, improve, and build better things together.
\bigskip % bigger gap before Personal section
When I'm not coding, you'll usually find me taking care of and entertaining my two lovely kids.
\medskip % slightly smaller gap within Personal block
I also love singing, acting, playing the didgeridoo, and chopping wood. I regularly take cold showers (or ice baths when temperatures drop below zero) in the morning.
\end{document}

View File

@@ -1,6 +1,7 @@
# Curriculum-Vitae
This project contains my *curriculum vitae* writen in `TeX`.
This project contains my *curriculum vitae* writen in `TeX` using the class
[`awesome-cv`](https://github.com/posquit0/Awesome-CV).
## Install TeX
@@ -12,5 +13,11 @@ Go to https://tug.org/texlive/ and install the correct TeX for your operating sy
If you are using VS Code, I highly recommend to install [LaTeX Workshop](https://marketplace.visualstudio.com/items?itemName=James-Yu.latex-workshop).
## Other CV variants
- [Article](../article/)
- [ModernCV](../moderncv)
- [Pedro-CV](../pedro-cv/)
##
Developed with ♥ by Pedro Pessoa Cabral

823
awesome-cv.cls Normal file
View File

@@ -0,0 +1,823 @@
%% Start of file `awesome-cv.cls'.
% Awesome CV Class File
%
% This class has been downloaded from:
% https://github.com/posquit0/Awesome-CV
%
% Author:
% Claud D. Park <posquit0.bj@gmail.com>
% http://www.posquit0.com
%
% Notes:
% 1) This class file defines the structure and layout of the template file (cv.tex, resume.tex).
% 2) It has been written in such a way that under most circumstances you
% should not need to edit it.
%
% Class license:
% LPPL v1.3c (http://www.latex-project.org/lppl)
%
%-------------------------------------------------------------------------------
% Identification
%-------------------------------------------------------------------------------
\ProvidesClass{awesome-cv}[2017/02/05 v1.6.1 Awesome Curriculum Vitae Class]
\NeedsTeXFormat{LaTeX2e}
%-------------------------------------------------------------------------------
% Class options
%
% (need to be done before the external package loading, for example because
% we need \paperwidth, \paperheight and \@ptsize to be defined before loading
% geometry and fancyhdr)
%-------------------------------------------------------------------------------
% Options for draft or final
\DeclareOption{draft}{\setlength\overfullrule{5pt}}
\DeclareOption{final}{\setlength\overfullrule{0pt}}
% Inherit options of article
\DeclareOption*{%
\PassOptionsToClass{\CurrentOption}{article}
}
\ProcessOptions\relax
\LoadClass{article}
%-------------------------------------------------------------------------------
% 3rd party packages
%-------------------------------------------------------------------------------
% Needed to make fixed length table
\RequirePackage{array}
% Needed to handle list environment
\RequirePackage{enumitem}
% Needed to handle text alignment
\RequirePackage{ragged2e}
% Needed to configure page layout
\RequirePackage{geometry}
% Needed to make header & footer efficiently
\RequirePackage{fancyhdr}
% Needed to manage colors
\RequirePackage{xcolor}
% Needed to use \ifxetex-\else-\fi statement
\RequirePackage{ifxetex}
% Needed to use \if-\then-\else statement
\RequirePackage{xifthen}
% Needed to strip chars from telephone number
\RequirePackage{xstring}
% Needed to use a toolbox of programming tools
\RequirePackage{etoolbox}
% Needed to change line spacing in specific environment
\RequirePackage{setspace}
% Needed to manage fonts
\RequirePackage[quiet]{fontspec}
% To support LaTeX quoting style
\defaultfontfeatures{Ligatures=TeX}
% Needed to manage math fonts
\RequirePackage{unicode-math}
% Needed to use icons from font-awesome
\RequirePackage{fontawesome6}
\RequirePackage{roboto}
\RequirePackage[default,opentype]{sourcesanspro}
% Needed for the photo ID
\RequirePackage[skins]{tcolorbox}
% Needed to deal a paragraphs
\RequirePackage{parskip}
% Needed to deal hyperlink
\RequirePackage[hidelinks,unicode,pdfpagelabels=false]{hyperref}
\hypersetup{%
pdftitle={},
pdfauthor={},
pdfsubject={},
pdfkeywords={}
}
% Solves issues Warning: File `cv.out' has changed
\RequirePackage{bookmark}
%-------------------------------------------------------------------------------
% Configuration for directory locations
%-------------------------------------------------------------------------------
% Configure an optional directory location for fonts(default: 'fonts/')
% Not required anymore but left in place for backward compatability.
\newcommand*{\fontdir}[1][fonts/]{\def\@fontdir{#1}}
%-------------------------------------------------------------------------------
% Configuration for layout
%-------------------------------------------------------------------------------
%% Page Layout
% Configure page margins with geometry
\geometry{left=2.0cm, top=1.5cm, right=2.0cm, bottom=2.0cm, footskip=.5cm}
%% Header & Footer
% Set offset to each header and footer
\fancyhfoffset{0em}
% Remove head rule
\renewcommand{\headrulewidth}{0pt}
% Clear all header & footer fields
\fancyhf{}
% Enable if you want to make header or footer using fancyhdr
\pagestyle{fancy}
%-------------------------------------------------------------------------------
% Configuration for colors
%-------------------------------------------------------------------------------
% Gray-scale colors
\definecolor{white}{HTML}{FFFFFF}
\definecolor{black}{HTML}{000000}
\definecolor{darkgray}{HTML}{333333}
\definecolor{gray}{HTML}{5D5D5D}
\definecolor{lightgray}{HTML}{999999}
% Basic colors
\definecolor{green}{HTML}{C2E15F}
\definecolor{orange}{HTML}{FDA333}
\definecolor{purple}{HTML}{D3A4F9}
\definecolor{red}{HTML}{FB4485}
\definecolor{blue}{HTML}{6CE0F1}
% Text colors
\definecolor{darktext}{HTML}{414141}
\colorlet{text}{darkgray}
\colorlet{graytext}{gray}
\colorlet{lighttext}{lightgray}
\colorlet{sectiondivider}{gray}
% Awesome colors
\definecolor{awesome-emerald}{HTML}{00A388}
\definecolor{awesome-skyblue}{HTML}{0395DE}
\definecolor{awesome-red}{HTML}{DC3522}
\definecolor{awesome-pink}{HTML}{EF4089}
\definecolor{awesome-orange}{HTML}{FF6138}
\definecolor{awesome-nephritis}{HTML}{27AE60}
\definecolor{awesome-concrete}{HTML}{95A5A6}
\definecolor{awesome-darknight}{HTML}{131A28}
\colorlet{awesome}{awesome-red}
% Boolean value to switch section color highlighting
\newbool{acvSectionColorHighlight}
\setbool{acvSectionColorHighlight}{true}
% Awesome section color
\def\@sectioncolor#1#2#3{%
\ifbool{acvSectionColorHighlight}{{\color{awesome}#1#2#3}}{#1#2#3}%
}
%-------------------------------------------------------------------------------
% Configuration for fonts
%-------------------------------------------------------------------------------
\newcommand*{\headerfont}{\roboto}
\newcommand*{\headerfontlight}{\robotolight}
\newcommand*{\footerfont}{\sourcesanspro}
\newcommand*{\bodyfont}{\sourcesanspro}
\newcommand*{\bodyfontlight}{\sourcesansprolight}
%-------------------------------------------------------------------------------
% Configuration for styles
%-------------------------------------------------------------------------------
% Configure styles for each CV elements
% For fundamental structures
\newcommand*{\headerfirstnamestyle}[1]{{\fontsize{32pt}{1em}\headerfontlight\color{graytext} #1}}
\newcommand*{\headerlastnamestyle}[1]{{\fontsize{32pt}{1em}\headerfont\bfseries\color{text} #1}}
\newcommand*{\headerpositionstyle}[1]{{\fontsize{7.6pt}{1em}\bodyfont\scshape\color{awesome} #1}}
\newcommand*{\headeraddressstyle}[1]{{\fontsize{8pt}{1em}\headerfont\itshape\color{lighttext} #1}}
\newcommand*{\headersocialstyle}[1]{{\fontsize{6.8pt}{1em}\headerfont\color{text} #1}}
\newcommand*{\headerquotestyle}[1]{{\fontsize{9pt}{1em}\bodyfont\itshape\color{darktext} #1}}
\newcommand*{\footerstyle}[1]{{\fontsize{8pt}{1em}\footerfont\scshape\color{lighttext} #1}}
\newcommand*{\sectionstyle}[1]{{\fontsize{16pt}{1em}\bodyfont\bfseries\color{text}\@sectioncolor #1}}
\newcommand*{\subsectionstyle}[1]{{\fontsize{12pt}{1em}\bodyfont\scshape\textcolor{text}{#1}}}
\newcommand*{\paragraphstyle}{\fontsize{9pt}{1em}\bodyfontlight\upshape\color{text}}
% For elements of entry
\newcommand*{\entrytitlestyle}[1]{{\fontsize{10pt}{1em}\bodyfont\bfseries\color{darktext} #1}}
\newcommand*{\entrypositionstyle}[1]{{\fontsize{8pt}{1em}\bodyfont\scshape\color{graytext} #1}}
\newcommand*{\entrydatestyle}[1]{{\fontsize{8pt}{1em}\bodyfontlight\slshape\color{graytext} #1}}
\newcommand*{\entrylocationstyle}[1]{{\fontsize{9pt}{1em}\bodyfontlight\slshape\color{awesome} #1}}
\newcommand*{\descriptionstyle}[1]{{\fontsize{9pt}{1em}\bodyfontlight\upshape\color{text} #1}}
% For elements of subentry
\newcommand*{\subentrytitlestyle}[1]{{\fontsize{8pt}{1em}\bodyfont\mdseries\color{graytext} #1}}
\newcommand*{\subentrypositionstyle}[1]{{\fontsize{7pt}{1em}\bodyfont\scshape\color{graytext} #1}}
\newcommand*{\subentrydatestyle}[1]{{\fontsize{7pt}{1em}\bodyfontlight\slshape\color{graytext} #1}}
\newcommand*{\subentrylocationstyle}[1]{{\fontsize{7pt}{1em}\bodyfontlight\slshape\color{awesome} #1}}
\newcommand*{\subdescriptionstyle}[1]{{\fontsize{8pt}{1em}\bodyfontlight\upshape\color{text} #1}}
% For elements of honor
\newcommand*{\honortitlestyle}[1]{{\fontsize{9pt}{1em}\bodyfont\color{graytext} #1}}
\newcommand*{\honorpositionstyle}[1]{{\fontsize{9pt}{1em}\bodyfont\bfseries\color{darktext} #1}}
\newcommand*{\honordatestyle}[1]{{\fontsize{9pt}{1em}\bodyfont\color{graytext} #1}}
\newcommand*{\honorlocationstyle}[1]{{\fontsize{9pt}{1em}\bodyfontlight\slshape\color{awesome} #1}}
% For elements of skill
\newcommand*{\skilltypestyle}[1]{{\fontsize{10pt}{1em}\bodyfont\bfseries\color{darktext} #1}}
\newcommand*{\skillsetstyle}[1]{{\fontsize{9pt}{1em}\bodyfontlight\color{text} #1}}
% For elements of the cover letter
\newcommand*{\lettersectionstyle}[1]{{\fontsize{14pt}{1em}\bodyfont\bfseries\color{text}\@sectioncolor #1}}
\newcommand*{\recipientaddressstyle}[1]{{\fontsize{9pt}{1em}\bodyfont\scshape\color{graytext} #1}}
\newcommand*{\recipienttitlestyle}[1]{{\fontsize{11pt}{1em}\bodyfont\bfseries\color{darktext} #1}}
\newcommand*{\lettertitlestyle}[1]{{\fontsize{10pt}{1em}\bodyfontlight\bfseries\color{darktext} \underline{#1}}}
\newcommand*{\letterdatestyle}[1]{{\fontsize{9pt}{1em}\bodyfontlight\slshape\color{graytext} #1}}
\newcommand*{\lettertextstyle}{\fontsize{10pt}{1.4em}\bodyfontlight\upshape\color{graytext}}
\newcommand*{\letternamestyle}[1]{{\fontsize{10pt}{1em}\bodyfont\bfseries\color{darktext} #1}}
\newcommand*{\letterenclosurestyle}[1]{{\fontsize{10pt}{1em}\bodyfontlight\slshape\color{lighttext} #1}}
%-------------------------------------------------------------------------------
% Commands for personal information
%-------------------------------------------------------------------------------
% Define photo ID
% Usage: \photo[circle|rectangle,edge|noedge,left|right]{<path-to-image>}
\newcommand{\photo}[2][circle,edge,left]{%
\def\@photo{#2}
\@for\tmp:=#1\do{%
\ifthenelse{\equal{\tmp}{circle} \or \equal{\tmp}{rectangle}}%
{\let\@photoshape\tmp}{}%
\ifthenelse{\equal{\tmp}{edge} \or \equal{\tmp}{noedge}}%
{\let\@photoedge\tmp}{}%
\ifthenelse{\equal{\tmp}{left} \or \equal{\tmp}{right}}%
{\let\@photoalign\tmp}{}%
}%
}
\def\@photoshape{circle}
\def\@photoedge{edge}
\def\@photoalign{left}
% Define writer's name
% Usage: \name{<firstname>}{<lastname>}
% Usage: \firstname{<firstname>}
% Usage: \lastname{<lastname>}
% Usage: \familyname{<familyname>}
\newcommand*{\name}[2]{\def\@firstname{#1}\def\@lastname{#2}}
\newcommand*{\firstname}[1]{\def\@firstname{#1}}
\newcommand*{\lastname}[1]{\def\@lastname{#1}}
\newcommand*{\familyname}[1]{\def\@lastname{#1}}
\def\@familyname{\@lastname}
% Define writer's address
% Usage: \address{<address>}
\newcommand*{\address}[1]{\def\@address{#1}}
% Define writer's position
% Usage: \position{<position>}
\newcommand*{\position}[1]{\def\@position{#1}}
% Defines writer's mobile (optional)
% Usage: \mobile{<mobile number>}
\newcommand*{\mobile}[1]
{
\def\@mobile{#1}
\def\@teluri{tel:\@mobile}
% Strip unwanted characters
\StrDel{\@teluri}{ }[\@teluri]%
\StrDel{\@teluri}{-}[\@teluri]%
\StrDel{\@teluri}{(}[\@teluri]%
\StrDel{\@teluri}{)}[\@teluri]%
}
% Defines writer's email (optional)
% Usage: \email{<email address>}
\newcommand*{\email}[1]{\def\@email{#1}}
% Defines writer's date of birth (optional)
% Usage: \dateofbirth{<date>}
\newcommand*{\dateofbirth}[1]{\def\@dateofbirth{#1}}
% Defines writer's homepage (optional)
% Usage: \homepage{<url>}
\newcommand*{\homepage}[1]{\def\@homepage{#1}}
% Defines writer's github (optional)
% Usage: \github{<github-nick>}
\newcommand*{\github}[1]{\def\@github{#1}}
% Defines writer's gitlab (optional)
% Usage: \gitlab{<gitlab-nick>}
\newcommand*{\gitlab}[1]{\def\@gitlab{#1}}
% Defines writer's bitbucket (optional)
% Usage: \bitbucket{<bitbucket-nick>}
\newcommand*{\bitbucket}[1]{\def\@bitbucket{#1}}
% Defines writer's stackoverflow profile (optional)
% Usage: \stackoverflow{<so userid>}{<so username>}
% e.g.https://stackoverflow.com/users/123456/sam-smith
% would be \stackoverflow{123456}{sam-smith}
\newcommand*{\stackoverflow}[2]{\def\@stackoverflowid{#1}\def\@stackoverflowname{#2}}
% Defines writer's linked-in (optional)
% Usage: \linkedin{<linked-in-nick>}
\newcommand*{\linkedin}[1]{\def\@linkedin{#1}}
% Defines writer's orcid (optional)
% Usage: \orcid{<orcid-num>}
\newcommand*{\orcid}[1]{\def\@orcid{#1}}
% Defines writer's twitter (optional)
% Usage: \twitter{<twitter handle>}
\newcommand*{\twitter}[1]{\def\@twitter{#1}}
% Defines writer's x (formerly twitter) (optional)
% Usage: \x{<x account>}
\newcommand*{\x}[1]{\def\@x{#1}}
% Defines writer's Mastodon (optional)
% Usage: \mastodon{<instance>}{<mastodon-nick>}
\newcommand*{\mastodon}[2]{\def\@mastodoninstance{#1}\def\@mastodonname{#2}}
% Defines writer's resarchgate (optional)
% Usage: \researchgate{<researchgate-account>}
\newcommand*{\researchgate}[1]{\def\@researchgate{#1}}
% Defines writer's skype (optional)
% Usage: \skype{<skype account>}
\newcommand*{\skype}[1]{\def\@skype{#1}}
% Defines writer's reddit (optional)
% Usage: \reddit{<reddit account>}
\newcommand*{\reddit}[1]{\def\@reddit{#1}}
% Defines writer's xing (optional)
% Usage: \xing{<xing name>}
\newcommand*{\xing}[1]{\def\@xing{#1}}
% Defines writer's medium profile (optional)
% Usage: \medium{<medium account>}
\newcommand*{\medium}[1]{\def\@medium{#1}}
% Defines writer's kaggle (optional)
% Usage: \kaggle{<kaggle handle>}
\newcommand*{\kaggle}[1]{\def\@kaggle{#1}}
% Defines writer's Hackerrank (optional)
% Usage: \hackerrank{<Hackerrank profile name>}
\newcommand*{\hackerrank}[1]{\def\@hackerrank{#1}}
% Defines writer's Telegram (optional)
% Usage: \telegram{<Telegram username>}
\newcommand*{\telegram}[1]{\def\@telegram{#1}}
% Defines writer's google scholar profile (optional)
% Usage: \googlescholar{<googlescholar userid>}{<googlescholar username>}
% e.g.https://scholar.google.co.uk/citations?user=wpZDx1cAAAAJ
% would be \googlescholar{wpZDx1cAAAAJ}{Name-to-display-next-icon}
% If 'googlescholar-name' is not provided than it defaults to
% '\firstname \lastname'
\newcommand*{\googlescholar}[2]{%
\def\@googlescholarid{#1}%
\ifthenelse{\equal{#2}{}}{%
\def\@googlescholarname{\@firstname~\@lastname}%
}{%
\def\@googlescholarname{#2}%
}%
}
% Defines writer's extra information (optional)
% Usage: \extrainfo{<extra information>}
\newcommand*{\extrainfo}[1]{\def\@extrainfo{#1}}
% Defines writer's quote (optional)
% Usage: \quote{<quote>}
\renewcommand*{\quote}[1]{\def\@quote{#1}}
% Defines recipient's information (cover letter only)
% Usage: \recipient{<recipient name>}{<recipient address>}
% Usage: \recipientname{<recipient name>}
% Usage: \recipientaddress{<recipient address>}
\newcommand*{\recipient}[2]{\def\@recipientname{#1}\def\@recipientaddress{#2}}
\newcommand*{\recipientname}[1]{\def\@recipientname{#1}}
\newcommand*{\recipientaddress}[1]{\def\@recipientaddress{#1}}
% Defines the title for letter (cover letter only, optional)
% Usage: \lettertitle{<title>}
\newcommand*{\lettertitle}[1]{\def\@lettertitle{#1}}
% Defines the date for letter (cover letter only)
% Usage: \letterdate{<date>}
\newcommand*{\letterdate}[1]{\def\@letterdate{#1}}
% Defines a message of opening for letter (cover letter only)
% Usage: \letteropening{<message>}
\newcommand*{\letteropening}[1]{\def\@letteropening{#1}}
% Defines a message of closing for letter (cover letter only)
% Usage: \letterclosing{<message>}
\newcommand*{\letterclosing}[1]{\def\@letterclosing{#1}}
% Defines an enclosure for letter (cover letter only, optional)
% Usage: \letterenclosure[<enclosure name>]{<enclosure>}
\newcommand*{\letterenclname}[1][Enclosure]{\def\@letterenclname{#1}}
\newcommand*{\letterenclosure}[2][]{%
% if an optional argument is provided, use it to redefine \enclname
\ifthenelse{\equal{#1}{}}{}{\def\@letterenclname{#1}}
\def\@letterenclosure{#2}
}
%-------------------------------------------------------------------------------
% Commands for extra
%-------------------------------------------------------------------------------
%% Define helper macros a user can change easily
% Header
\newcommand{\acvHeaderNameDelim}{\space}
\newcommand{\acvHeaderAfterNameSkip}{.4mm}
\newcommand{\acvHeaderAfterPositionSkip}{.4mm}
\newcommand{\acvHeaderAfterAddressSkip}{-.5mm}
\newcommand{\acvHeaderIconSep}{\space}
\newcommand{\acvHeaderSocialSep}{\quad\textbar\quad}
\newcommand{\acvHeaderAfterSocialSkip}{6mm}
\newcommand{\acvHeaderAfterQuoteSkip}{5mm}
% Others
\newcommand{\acvSectionTopSkip}{3mm}
\newcommand{\acvSectionContentTopSkip}{2.5mm}
%-------------------------------------------------------------------------------
% Commands for utilities
%-------------------------------------------------------------------------------
% Use to align an element of tabular table
\newcolumntype{L}[1]{>{\raggedright\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\newcolumntype{C}[1]{>{\centering\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\newcolumntype{R}[1]{>{\raggedleft\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
% Use to draw horizontal line with specific thickness
\def\vhrulefill#1{\leavevmode\leaders\hrule\@height#1\hfill \kern\z@}
% Use to execute conditional statements by checking empty string
\newcommand*{\ifempty}[3]{\ifthenelse{\isempty{#1}}{#2}{#3}}
%-------------------------------------------------------------------------------
% Commands for elements of CV structure
%-------------------------------------------------------------------------------
% Define a header for CV
% Usage: \makecvheader
\newcommand*{\makecvheader}[1][C]{%
\newcommand*{\drawphoto}{%
\ifthenelse{\isundefined{\@photo}}{}{%
\newlength{\photodim}
\ifthenelse{\equal{\@photoshape}{circle}}%
{\setlength{\photodim}{1.3cm}}%
{\setlength{\photodim}{1.8cm}}%
\ifthenelse{\equal{\@photoedge}{edge}}%
{\def\@photoborder{darkgray}}%
{\def\@photoborder{none}}%
\begin{tikzpicture}%
\node[\@photoshape, draw=\@photoborder, line width=0.3mm, inner sep=\photodim, fill overzoom image=\@photo] () {};
\end{tikzpicture}
}%
}
\newlength{\headertextwidth}
\newlength{\headerphotowidth}
\ifthenelse{\isundefined{\@photo}}{
\setlength{\headertextwidth}{\textwidth}
\setlength{\headerphotowidth}{0cm}
}{%
\setlength{\headertextwidth}{0.76\textwidth}
\setlength{\headerphotowidth}{0.24\textwidth}
}%
\begin{minipage}[c]{\headerphotowidth}%
\ifthenelse{\equal{\@photoalign}{left}}{\raggedright\drawphoto}{}
\end{minipage}
\begin{minipage}[c]{\headertextwidth}
\ifthenelse{\equal{#1}{L}}{\raggedright}{\ifthenelse{\equal{#1}{R}}{\raggedleft}{\centering}}
\headerfirstnamestyle{\@firstname}\headerlastnamestyle{{}\acvHeaderNameDelim\@lastname}%
\\[\acvHeaderAfterNameSkip]%
\ifthenelse{\isundefined{\@position}}{}{\headerpositionstyle{\@position\\[\acvHeaderAfterPositionSkip]}}%
\ifthenelse{\isundefined{\@address}}{}{\headeraddressstyle{\@address\\[\acvHeaderAfterAddressSkip]}}%
\headersocialstyle{%
\newbool{isstart}%
\setbool{isstart}{true}%
\ifthenelse{\isundefined{\@mobile}}%
{}%
{%
\href{\@teluri}{\faMobile\acvHeaderIconSep\@mobile}%
\setbool{isstart}{false}%
}%
\ifthenelse{\isundefined{\@email}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{mailto:\@email}{\faEnvelope\acvHeaderIconSep\@email}%
}%
\ifthenelse{\isundefined{\@dateofbirth}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
% \mbox prevents wrapping of elements%
\mbox{\faCakeCandles\acvHeaderIconSep\@dateofbirth}%
}%
\ifthenelse{\isundefined{\@homepage}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{http://\@homepage}{\faHouseChimney\acvHeaderIconSep\@homepage}%
}%
\ifthenelse{\isundefined{\@github}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://github.com/\@github}{\faSquareGithub\acvHeaderIconSep\@github}%
}%
\ifthenelse{\isundefined{\@gitlab}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://gitlab.com/\@gitlab}{\faGitlab\acvHeaderIconSep\@gitlab}%
}%
\ifthenelse{\isundefined{\@bitbucket}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://bitbucket.com/\@bitbucket}{\faBitbucket\acvHeaderIconSep\@bitbucket}%
}%
\ifthenelse{\isundefined{\@stackoverflowid}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://stackoverflow.com/users/\@stackoverflowid}{\faStackOverflow\acvHeaderIconSep\@stackoverflowname}%
}%
\ifthenelse{\isundefined{\@linkedin}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://www.linkedin.com/in/\@linkedin}{\faLinkedin\acvHeaderIconSep\@linkedin}%
}%
\ifthenelse{\isundefined{\@orcid}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://orcid.org/\@orcid}{\faOrcid\acvHeaderIconSep\@orcid}%
}%
\ifthenelse{\isundefined{\@twitter}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://twitter.com/\@twitter}{\faTwitter\acvHeaderIconSep\@twitter}%
}%
\ifthenelse{\isundefined{\@x}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://x.com/\@x}{\faXTwitter\acvHeaderIconSep\@x}%
}%
\ifthenelse{\isundefined{\@mastodonname}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://\@mastodoninstance/@\@mastodonname}{\faMastodon\acvHeaderIconSep\@mastodonname}%
}%
\ifthenelse{\isundefined{\@skype}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\faSkype\acvHeaderIconSep\@skype%
}%
\ifthenelse{\isundefined{\@reddit}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://www.reddit.com/user/\@reddit}{\faReddit\acvHeaderIconSep\@reddit}%
}%
\ifthenelse{\isundefined{\@researchgate}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://www.researchgate.net/profile/\@researchgate}{\faResearchgate\acvHeaderIconSep\@researchgate}%
}%
\ifthenelse{\isundefined{\@xing}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://www.xing.com/profile/\@xing}{\faSquareXing\acvHeaderIconSep\@xing}
}%
\ifthenelse{\isundefined{\@medium}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://medium.com/@\@medium}{\faMedium\acvHeaderIconSep\@medium}%
}%
\ifthenelse{\isundefined{\@kaggle}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://kaggle.com/\@kaggle}{\faKaggle\acvHeaderIconSep\@kaggle}%
}%
\ifthenelse{\isundefined{\@hackerrank}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://www.hackerrank.com/\@hackerrank}{\faHackerrank\acvHeaderIconSep\@hackerrank}%
}%
\ifthenelse{\isundefined{\@telegram}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://t.me/\@telegram}{\faTelegram\acvHeaderIconSep\@telegram}%
}%
\ifthenelse{\isundefined{\@googlescholarid}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\href{https://scholar.google.com/citations?user=\@googlescholarid}{\faGraduationCap\acvHeaderIconSep\@googlescholarname}%
}%
\ifthenelse{\isundefined{\@extrainfo}}%
{}%
{%
\ifbool{isstart}{\setbool{isstart}{false}}{\acvHeaderSocialSep}%
\@extrainfo%
}%
} \\[\acvHeaderAfterSocialSkip]%
\ifthenelse{\isundefined{\@quote}}%
{}%
{\headerquotestyle{\@quote\\}\vspace{\acvHeaderAfterQuoteSkip}}%
\end{minipage}%
\begin{minipage}[c]{\headerphotowidth}%
\ifthenelse{\equal{\@photoalign}{right}}{\raggedleft\drawphoto}{}
\end{minipage}
}
% Define a footer for CV
% Usage: \makecvfooter{<left>}{<center>}{<right>}
\newcommand*{\makecvfooter}[3]{%
\fancyfoot{}
\fancyfoot[L]{\footerstyle{#1}}
\fancyfoot[C]{\footerstyle{#2}}
\fancyfoot[R]{\footerstyle{#3}}
}
% Define a section for CV
% Usage: \cvsection{<section-title>}
\newcommand{\cvsection}[1]{%
\vspace{\acvSectionTopSkip}
\sectionstyle{#1}
\phantomsection
\color{sectiondivider}\vhrulefill{0.9pt}
}
% Define a subsection for CV
% Usage: \cvsubsection{<subsection-title>}
\newcommand{\cvsubsection}[1]{%
\vspace{\acvSectionContentTopSkip}
\vspace{-3mm}
\subsectionstyle{#1}
\phantomsection
}
% Define a paragraph for CV
\newenvironment{cvparagraph}{%
\vspace{\acvSectionContentTopSkip}
\vspace{-3mm}
\paragraphstyle
}{%
\par
\vspace{2mm}
}
% Define an environment for cventry
\newenvironment{cventries}{%
\vspace{\acvSectionContentTopSkip}
\begin{center}
}{%
\end{center}
}
% Define an entry of cv information
% Usage: \cventry{<position>}{<title>}{<location>}{<date>}{<description>}
\newcommand*{\cventry}[5]{%
\vspace{-2.0mm}
\setlength\tabcolsep{0pt}
\setlength{\extrarowheight}{0pt}
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}} L{\textwidth - 4.5cm} R{4.5cm}}
\ifempty{#2#3}
{\entrypositionstyle{#1} & \entrydatestyle{#4} \\}
{\entrytitlestyle{#2} & \entrylocationstyle{#3} \\
\entrypositionstyle{#1} & \entrydatestyle{#4} \\}
\ifstrempty{#5}
{}
{\multicolumn{2}{L{\textwidth}}{\descriptionstyle{#5}} \\}
\end{tabular*}%
}
% Define an environment for cvsubentry
\newenvironment{cvsubentries}{%
\begin{center}
}{%
\end{center}
}
% Define a subentry of cv information
% Usage: \cvsubentry{<position>}{<title>}{<date>}{<description>}
\newcommand*{\cvsubentry}[4]{%
\setlength\tabcolsep{0pt}
\setlength{\extrarowheight}{0pt}
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}} L{\textwidth - 4.5cm} R{4.5cm}}
\setlength\leftskip{0.2cm}
\subentrytitlestyle{#2} & \ifthenelse{\equal{#1}{}}
{\subentrydatestyle{#3}}{}
\ifthenelse{\equal{#1}{}}
{}
{\subentrypositionstyle{#1} & \subentrydatestyle{#3} \\}
\ifthenelse{\equal{#4}{}}
{}
{\multicolumn{2}{L{17.0cm}}{\subdescriptionstyle{#4}} \\}
\end{tabular*}
}
% Define an environment for cvhonor
\newenvironment{cvhonors}{%
\vspace{\acvSectionContentTopSkip}
\vspace{-2mm}
\begin{center}
\setlength\tabcolsep{0pt}
\setlength{\extrarowheight}{0pt}
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}} C{1.5cm} L{\textwidth - 4.0cm} R{2.5cm}}
}{%
\end{tabular*}
\end{center}
}
% Define a line of cv information(honor, award or something else)
% Usage: \cvhonor{<position>}{<title>}{<location>}{<date>}
\newcommand*{\cvhonor}[4]{%
\honordatestyle{#4} & \honorpositionstyle{#1}\ifempty{#2}{}{,} \honortitlestyle{#2} & \honorlocationstyle{#3} \\
}
% Define an environment for cvskill
\newenvironment{cvskills}{%
\vspace{\acvSectionContentTopSkip}
\vspace{-2.0mm}
\begin{center}
\setlength\tabcolsep{1ex}
\setlength{\extrarowheight}{0pt}
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}} r L{\textwidth * \real{0.9}}}
}{%
\end{tabular*}
\end{center}
}
% Define a line of cv information(skill)
% Usage: \cvskill{<type>}{<skillset>}
\newcommand*{\cvskill}[2]{%
\skilltypestyle{#1} & \skillsetstyle{#2} \\
}
% Define an environment for cvitems(for cventry)
\newenvironment{cvitems}{%
\vspace{-4.0mm}
\begin{justify}
\begin{itemize}[leftmargin=2ex, nosep, noitemsep]
\setlength{\parskip}{0pt}
\renewcommand{\labelitemi}{\bullet}
}{%
\end{itemize}
\end{justify}
\vspace{1.0mm}
}
%-------------------------------------------------------------------------------
% Commands for elements of Cover Letter
%-------------------------------------------------------------------------------
% Define an environment for cvletter
\newenvironment{cvletter}{%
\lettertextstyle
}{%
}
% Define a section for the cover letter
% Usage: \lettersection{<section-title>}
\newcommand{\lettersection}[1]{%
\par\addvspace{2.5ex}
\phantomsection{}
\lettersectionstyle{#1}
\color{sectiondivider}\vhrulefill{0.9pt}
\par\nobreak\addvspace{0.4ex}
\lettertextstyle
}
% Define a title of the cover letter
% Usage: \makelettertitle
\newcommand*{\makelettertitle}{%
\vspace{8.4mm}
\setlength\tabcolsep{0pt}
\setlength{\extrarowheight}{0pt}
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}} L{\textwidth - 4.5cm} R{4.5cm}}
\recipienttitlestyle{\@recipientname} & \letterdatestyle{\@letterdate}
\end{tabular*}
\begin{singlespace}
\recipientaddressstyle{\@recipientaddress} \\\\
\end{singlespace}
\ifthenelse{\isundefined{\@lettertitle}}
{}
{\lettertitlestyle{\@lettertitle} \\}
\lettertextstyle{\@letteropening}
}
% Define a closing of the cover letter
% Usage: \makeletterclosing
\newcommand*{\makeletterclosing}{%
\vspace{3.4mm}
\lettertextstyle{\@letterclosing} \\\\
\letternamestyle{\@firstname\ \@lastname}
\ifthenelse{\isundefined{\@letterenclosure}}
{\\}
{%
\\\\\\
\letterenclosurestyle{\@letterenclname: \@letterenclosure} \\
}
}

View File

@@ -19,6 +19,9 @@ FILE="$1"
# append .tex file extension, iff not already passed
[[ "$FILE" != *.tex ]] && FILE="${FILE}.tex"
# remove the .tex extension from the file name to get the base name
BASE="${FILE%.tex}"
# Check that the file exists
if [[ ! -f "$FILE" ]]; then
echo -e "${BOLD}${RED}Error${RESET}${RED}: File '$FILE' not found.${RESET}"
@@ -28,8 +31,24 @@ fi
# Detect active \usepackage{fontspec} (ignore commented lines)
if grep -Eq '^[^%]*\\usepackage\{fontspec\}' "$FILE"; then
echo -e "${BLUE}Detected fontspec → Using XeLaTeX${RESET}"
xelatex -synctex=1 -interaction=nonstopmode -file-line-error "$FILE"
LATEX_CMD=(xelatex -synctex=1 -interaction=nonstopmode -file-line-error "$FILE")
else
echo -e "${BLUE}No active fontspec → Using pdfLaTeX${RESET}"
pdflatex -synctex=1 -interaction=nonstopmode -file-line-error "$FILE"
LATEX_CMD=(pdflatex -synctex=1 -interaction=nonstopmode -file-line-error "$FILE")
fi
"${LATEX_CMD[@]}"
rm -f \
"${BASE}.aux" \
"${BASE}.bbl" \
"${BASE}.bcf" \
"${BASE}.blg" \
"${BASE}.fdb_latexmk" \
"${BASE}.fls" \
"${BASE}.log" \
"${BASE}.out" \
"${BASE}.run.xml" \
"${BASE}.synctex.gz" \
"${BASE}.toc" \
"${BASE}.xdv"

View File

@@ -0,0 +1,96 @@
#!/bin/bash
set -euo pipefail
# Color definitions
BOLD='\033[1m'
RED='\033[31m'
BLUE='\033[34m'
GREEN='\033[32m'
YELLOW='\033[33m'
RESET='\033[0m'
if [[ $# -ne 1 ]]; then
echo -e "${BOLD}${RED}Error${RESET}${RED}: No commit hash provided.${RESET}"
echo "Usage: $0 <commit-hash>"
exit 1
fi
COMMIT="$1"
START_BRANCH="$(git branch --show-current)"
if [[ -z "$START_BRANCH" ]]; then
echo -e "${BOLD}${RED}Error${RESET}${RED}: Detached HEAD is not supported.${RESET}"
exit 1
fi
if ! git rev-parse --verify --quiet "${COMMIT}^{commit}" >/dev/null; then
echo -e "${BOLD}${RED}Error${RESET}${RED}: Commit '$COMMIT' not found.${RESET}"
exit 1
fi
COMMIT="$(git rev-parse --short "$COMMIT")"
COMMIT_MSG="$(git log -1 --pretty=format:%s "$COMMIT")"
PARENT_COUNT="$(git rev-list --parents -n 1 "$COMMIT" | wc -w | tr -d ' ')"
if [[ "$PARENT_COUNT" -gt 2 ]]; then
echo -e "${BOLD}${RED}Error${RESET}${RED}: Merge commits are not supported.${RESET}"
exit 1
fi
if [[ -n "$(git status --porcelain)" ]]; then
echo -e "${BOLD}${RED}Error${RESET}${RED}: Working tree is not clean.${RESET}"
echo "Commit, stash, or discard local changes before replicating a commit."
exit 1
fi
restore_branch() {
git switch --quiet "$START_BRANCH"
}
handle_error() {
echo -e "${BOLD}${RED}Error${RESET}${RED}: Replication failed on branch '$(git branch --show-current)'.${RESET}"
if [[ -f "$(git rev-parse --git-path CHERRY_PICK_HEAD 2>/dev/null || true)" ]]; then
git cherry-pick --abort >/dev/null 2>&1 || true
fi
restore_branch
exit 1
}
trap handle_error ERR
echo -e "${BLUE}Propagating commit ${BOLD}'${COMMIT}: ${COMMIT_MSG}'${RESET}${BLUE} from '${START_BRANCH}' to local branches.${RESET}"
while IFS= read -r BRANCH; do
if [[ "$BRANCH" == "$START_BRANCH" ]]; then
continue
fi
git switch --quiet "$BRANCH"
if git merge-base --is-ancestor "$COMMIT" HEAD; then
echo -e "${YELLOW}Skipping ${BRANCH}: commit is already present.${RESET}"
continue
fi
echo -e "${BLUE}Cherry-picking ${COMMIT} onto ${BRANCH}.${RESET}"
if ! git cherry-pick "$COMMIT"; then
if git diff --quiet && git diff --cached --quiet; then
echo -e "${YELLOW}Skipping ${BRANCH}: commit is already applied as an equivalent patch.${RESET}"
git cherry-pick --skip
continue
fi
false
fi
echo -e "${GREEN}Commit successfully cherry-picked to ${BRANCH}.${RESET}"
git push
echo -e "${GREEN}Branch ${BRANCH} successfully pushed.${RESET}"
done < <(git for-each-ref --format='%(refname:short)' refs/heads)
restore_branch
echo -e "${GREEN}Done. Returned to '${START_BRANCH}'.${RESET}"

View File

@@ -1,32 +0,0 @@
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{pedro-moderncv}[2026/02/24 Custom moderncv wrapper]
\LoadClassWithOptions{moderncv}
\RequirePackage{tikz}
\RequirePackage{etoolbox}
\AtBeginDocument{%
\makeatletter
% Safe scaled length
\newlength{\@photowidthscaled}
\patchcmd{\makecvhead}
{\includegraphics[width=\@photowidth]{\@photo}}
{%
% Copy original width
\setlength{\@photowidthscaled}{\@photowidth}
% Scale safely (no calc/dimexpr/TikZ parser issues)
\setlength{\@photowidthscaled}{1.2\@photowidthscaled}
\begin{tikzpicture}
\clip (0, 0) circle (\@photowidth/2);
\node at (-0.2cm, -0.3cm) {
\includegraphics[width=\@photowidthscaled]{\@photo}
};
\end{tikzpicture}
}
{}{}
\makeatother
}