1
0
Fork 0

Merge branch 'awesomecv' into 'master'

Add support for AwesomeCV

See merge request Titan-C/org-cv!3
This commit is contained in:
Óscar Nájera 2021-07-08 18:56:50 +00:00
commit 24bcd82348
6 changed files with 904 additions and 10 deletions

View File

@ -92,3 +92,232 @@ When exporting you can call the following function to get the latex file.
<object data="altacv.org.pdf" type="application/pdf" width="100%" height="500px">
<p>Alternative text - include a link <a href="altacv.org.pdf">to the PDF!</a></p>
</object>
## Using AwesomeCV {#using-awesomecv}
[AwesomeCV](https://github.com/posquit0/Awesome-CV) is another LaTeX template for producing nice-looking
CVs and cover letters. This style also supports some additional options. For example:
```org
# CV color - options include: 'awesome-red (default), 'awesome-emerald,
# 'awesome-skyblue', 'awesome-pink', 'awesome-orange', 'awesome-nephritis',
# 'awesome-concrete' and 'awesome-darknight', plus any standard color names.
#+CVCOLOR: awesome-red
# Specify the position and style of the photo
#+PHOTOSTYLE: right,noedge
```
When exporting you can call the following function to get the latex file.
```emacs-lisp
(org-export-to-file 'awesomecv "awesomecv.tex")
(org-latex-compile "awesomecv.tex")
```
Note that AwesomeCV uses the `fontspec` package, so you need to set `org-latex-compiler` to `lualatex` or `xelatex` for it to work.
In addition to the regular document attributes, the following are supported:
<div class="ox-hugo-table table table-striped">
<div></div>
| Field | Description |
|------------------|-------------------------------------------------------------|
| PHOTOSTYLE | Style of photo to use. Comma-separated values can include |
| | circle/rectangle,edge/noedge,left/right. |
| CVCOLOR | Color of highlights. |
| STACKOVERFLOW | Stack overflow info, must be specified as "`ID username`" |
| FONTDIR | Directory where the fonts can be found, defaults |
| | to `fonts/` (as in the standard AwesomeCV) |
| CVHIGHLIGHTS | Whether to colorize highlights. Defaults to true |
| QUOTE | Optional quote to include at the top of the CV |
| FIRSTNAME | First name to be shown in the CV. By default the first |
| | space-separated part of AUTHOR is used. |
| LASTNAME | Last name to be shown in the CV. By default the second |
| | space-separated part of AUTHOR is used. |
| CVFOOTER\_LEFT | Text to include in the left footer. None by default |
| CVFOOTER\_MIDDLE | Text to include in the middle footer. None by default. |
| CVFOOTER\_RIGHT | Text to include in the right footer. None by default. |
| LATEX\_TITLE | Text to use as the title section. \makecvheader by default. |
| | (Can specify \makecvheader[R] to justify to the right) |
</div>
### CV environments {#cv-environments}
AwesomeCV supports a few additional types of environment types in `CV_ENV`,
including `cvemployer`, `cvskills`, `cvhonors` and `cvschool` (see full list below).
Some of these support additional property fields:
<div class="ox-hugo-table table table-striped">
<div></div>
| Field | Description |
|------------|----------------------------------------------------------------------|
| FROM | Start date of the entry |
| TO | End date of the entry |
| DATE | Shortcut to specify both `FROM` and `TO` as the same date. |
| | Both `FROM` and `TO` override `DATE`. |
| EMPLOYER | Employer or organization, can also be specified |
| | as `ORGANIZATION`, `SCHOOL`, `EVENT` or `POSITION` (different |
| | names make more sense depending on the type of environment) |
| LABEL | In `cvsubentry` environments, adds the given text to the left |
| | of the date range, can be used to add additional information |
| | to the entry. |
| RIGHT\_IMG | path to an image to include floating to the right of a `cventry`, |
| | a `cvsubentry` or `cvschool` entry. Meant to be used to show a logo. |
| PAGEBREAK | Causes a LaTeX `\clearpage` statement to be inserted in the |
| | exported output before the heading. |
</div>
All the supported values of `CV_ENV` for CVs are described below.
#### `cventries` {#cventries}
Enclose all the subheaders in a `cventries` environment. Subheaders can
be of type `cventry`, `cvschool`, or `cvemployer`.
#### `cvhonors` {#cvhonors}
Enclose all the subheaders in a `cvhonors` environment. Subheaders must
be of type `cvhonor`
#### `cventry` {#cventry}
Converts to a `\cventry` command. Supports attributes `FROM`, `TO`, `DATE`,
`EMPLOYER`, `LOCATION`, `RIGHT_IMG`.
#### `cvsubentry` {#cvsubentry}
Converts to a `\cvsubentry` command. Supports attributes `FROM`, `TO`, `DATE`,
`LABEL` `RIGHT_IMG`.
#### `cvemployer` {#cvemployer}
Converts to a `\cventry` with only the title line. Supports attributes
`FROM`, `TO`, `DATE` and `LOCATION`.
#### `cvschool` {#cvschool}
Converts to a `\cventry`. The headline should contain the degree
obtained, shown as the main title. Supports attributes `LOCATION`,
`SCHOOL`, `FROM`, `TO`, `DATE` and `RIGHT_IMG`.
#### `cvhonor` {#cvhonor}
Converts to a `\cvhonor` command (must be inside a `cvhonors`
headline). Supports attributes `LOCATION`, `EMPLOYER` (in this case `EVENT`
or `POSITION` might be more semantically accurate, and can also be
used), `FROM`, `TO`, `DATE`.
#### `cvskills` {#cvskills}
Converts to a `\cvskills` environment. The headline must contain a
[description list](https://orgmode.org/manual/Plain-lists.html), which gets converted into a sequence of `\cvskill`
commands, with the term as the skill title and the description as its
contents.
<object data="awesomecv.org.pdf" type="application/pdf" width="100%" height="500px">
<p>Alternative text - include a link <a href="awesomecv.org.pdf">to the PDF!</a></p>
</object>
### Cover letter environments {#cover-letter-environments}
AwesomeCV also supports generating cover letters. For this, `CV_ENV` can have a few additional values, shown below.
#### `letterheader` {#letterheader}
This environment provides heading/signature information for a cover letter. Supports attributes `RECIPIENT`. `EMPLOYER`, `LOCATION`, `LETTER_OPENING`, `LETTER_CLOSING`, `LETTER_ATTACHED`, `DATE`, `DATEFORMAT`.
Note that the text within the heading is not exported! You can use this, for example, to keep notes about your application or the employer. For example:
```org
* Recipient
:PROPERTIES:
:CV_ENV: letterheader
:RECIPIENT: International Recruiting team
:EMPLOYER: Employer Co.
:LOCATION: Someplace, the world
:LETTER_OPENING: Dear International Recruiting team
:LETTER_CLOSING: Kind regards,
:LETTER_ATTACHED: Curriculum Vitae
:END:
Title and content are not exported.
Add any notes about the recipient here
They will *not* be exported.
```
<div class="ox-hugo-table table table-striped">
<div></div>
| Field | Description |
|------------------|----------------------------------------------------------------------------------|
| RECIPIENT | Addressee E.g. Company Recruitment Team |
| EMPLOYER | Company name |
| LOCATION | Company address |
| LETTER\_OPENING | Letter opening, E.g. Dear Ms./Mr./Dr. LastName |
| LETTER\_CLOSING | Letter closing, E.g. Yours Sincerely, |
| DATE | The date used for the letter, uses \\\today as default if unspecified |
| DATEFORMAT | Specify an alternative date format for the letter header |
| | E.g. %e %M %Y might provide 19 March 2021 |
| LETTER\_ATTACHED | Attachments to the letter, will be listed at the bottom. E.g. "Curriculum Vitae" |
</div>
#### `cvletter` {#cvletter}
Converts to a `\cvletter` environment. This holds the content of a cover letter. The body can be subdivided using `lettersection` headings. The heading title is converted to a title line at the top of the letter.
```org
* Application for the position of /Awesome Job/ (job reference #123456)
:PROPERTIES:
:CV_ENV: cvletter
:END:
** About Me
:PROPERTIES:
:CV_ENV: lettersection
:END:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ullamcorper neque sit amet lectus facilisis sed luctus nisl iaculis. Vivamus at neque arcu, sed tempor quam. Curabitur pharetra tincidunt tincidunt. Morbi volutpat feugiat mauris, quis tempor neque vehicula volutpat. Duis tristique justo vel massa fermentum accumsan. Mauris ante elit, feugiat vestibulum tempor eget, eleifend ac ipsum. Donec scelerisque lobortis ipsum eu vestibulum. Pellentesque vel massa at felis accumsan rhoncus.
** Why Employer Co.?
:PROPERTIES:
:CV_ENV: lettersection
:END:
Suspendisse commodo, massa eu congue tincidunt, elit mauris pellentesque orci, cursus tempor odio nisl euismod augue. Aliquam adipiscing nibh ut odio sodales et pulvinar tortor laoreet. Mauris a accumsan ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse vulputate sem vehicula ipsum varius nec tempus dui dapibus. Phasellus et est urna, ut auctor erat. Sed tincidunt odio id odio aliquam mattis. Donec sapien nulla, feugiat eget adipiscing sit amet, lacinia ut dolor. Phasellus tincidunt, leo a fringilla consectetur, felis diam aliquam urna, vitae aliquet lectus orci nec velit. Vivamus dapibus varius blandit.
** Why me?
:PROPERTIES:
:CV_ENV: lettersection
:END:
Duis sit amet magna ante, at sodales diam. Aenean consectetur porta risus et sagittis. Ut interdum, enim varius pellentesque tincidunt, magna libero sodales tortor, ut fermentum nunc metus a ante. Vivamus odio leo, tincidunt eu luctus ut, sollicitudin sit amet metus. Nunc sed orci lectus. Ut sodales magna sed velit volutpat sit amet pulvinar diam venenatis.
```
#### `cvletter_notitle` {#cvletter-notitle}
Same as `cvletter`, but does not include a letter title at the top.
#### `lettersection` {#lettersection}
Converts to a `\lettersection` command. These are the headline portions of a cover letter.
<object data="awesome-letter.org.pdf" type="application/pdf" width="100%" height="500px">
<p>Alternative text - include a link <a href="awesome-letter.org.pdf">to the PDF!</a></p>
</object>

View File

@ -10,13 +10,16 @@
(require 'ox-altacv)
(require 'ox-awesomecv)
(let ((readme (concat cwd "readme.org")))
(find-file readme)
(make-directory workdir t)
(cd workdir)
(org-babel-tangle))
(copy-file (concat cwd "doc/smile.png") workdir)
(copy-file (concat cwd "doc/smile.png") workdir t)
(copy-directory "/root/texmf/tex/latex/Awesome-CV-master/fonts" workdir)
(defun export-latex (backend file)
(let ((workfile (concat workdir file))
@ -25,10 +28,12 @@
(find-file workfile)
(org-mode)
(org-export-to-file backend outfile)
(shell-command (format "pdflatex %s" outfile) "*Messages*" "*Messages*")
(copy-file (concat file ".pdf") (concat cwd "/doc/static/" (concat file ".pdf")))
(shell-command (format "lualatex %s" outfile) "*Messages*" "*Messages*")
(copy-file (concat file ".pdf") (concat cwd "/doc/static/" (concat file ".pdf")) t)
))
(make-directory (concat cwd "/doc/static/") t)
(export-latex 'altacv "altacv.org")
(export-latex 'moderncv "moderncv.org")
(export-latex 'awesomecv "awesomecv.org")
(export-latex 'awesomecv "awesome-letter.org")

View File

@ -6,6 +6,9 @@ dpkg -i hugo*.deb
echo "Installed Hugo:"
hugo version
# These installs could be moved to the Dockerfile
apt-get update && apt-get --no-install-recommends install -y texlive-luatex fonts-font-awesome
# Latex
latexdir=/root/texmf/tex/latex
mkdir -p $latexdir
@ -15,3 +18,6 @@ unzip -j sections.zip -d $latexdir/AltaCV
echo "Install moderncv"
wget https://github.com/Titan-C/moderncv/archive/master.zip
unzip -j master.zip -d $latexdir/moderncv
echo "Install AwesomeCV"
wget -O awesomecv.zip https://github.com/posquit0/Awesome-CV/archive/refs/heads/master.zip
unzip awesomecv.zip -d $latexdir

View File

@ -45,14 +45,19 @@ today => today"
date_str))
(defun org-cv-utils--format-time-window (from-date to-date)
"Join date strings in a time window.
"Join date strings in a time window.
FROM-DATE -- TO-DATE
in case TO-DATE is nil return Present"
(concat
(org-cv-utils-org-timestamp-to-shortdate from-date)
" -- "
(if (not to-date) "Present"
(org-cv-utils-org-timestamp-to-shortdate to-date))))
in case TO-DATE is nil return Present.
If both dates are the same, return just FROM-DATE"
(let ((from (when from-date (org-cv-utils-org-timestamp-to-shortdate from-date)))
(to (if (not to-date) "Present"
(org-cv-utils-org-timestamp-to-shortdate to-date))))
(if from
(if (string= from to)
from
(concat from " -- " to))
"")))
(defun org-cv-utils--parse-cventry (headline info)
"Return alist describing the entry

436
ox-awesomecv.el Normal file
View File

@ -0,0 +1,436 @@
;;; ox-awesomecv.el --- LaTeX awesomecv Back-End for Org Export Engine -*- lexical-binding: t; -*-
;; Copyright (C) 2018 Free Software Foundation, Inc.
;; Author: Diego Zamboni <diego@zzamboni.org> based on work by Oscar Najera <hi AT oscarnajera.com DOT com>
;; Keywords: org, wp, tex
;; This file is not part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;;
;; This library implements a LaTeX awesomecv back-end, derived from the
;; LaTeX one.
;;; Code:
(require 'ox-latex)
(require 'org-cv-utils)
;; Install a default set-up for awesomecv export.
(unless (assoc "awesomecv" org-latex-classes)
(add-to-list 'org-latex-classes
'("awesomecv"
"\\documentclass{awesome-cv}\n[NO-DEFAULT-PACKAGES]"
("\\cvsection{%s}" . "\\cvsection{%s}")
("\\cvsubsection{%s}" . "\\cvsubsection{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\cvparagraph{%s}" . "\\cvparagraph{%s}"))))
;;; User-Configurable Variables
(defgroup org-export-cv nil
"Options specific for using the awesomecv class in LaTeX export."
:tag "Org awesomecv"
:group 'org-export
:version "25.3")
;;; Define Back-End
(org-export-define-derived-backend 'awesomecv 'latex
; :menu-entry
; (?l 1
; ((?w "AwesomeCV format" (lambda (a s v b) (org-export-to-file 'awesomecv (org-export-output-file-name ".tex"))))))
:options-alist
'((:latex-class "LATEX_CLASS" nil "awesomecv" t)
(:cvstyle "CVSTYLE" nil "classic" t)
(:cvcolor "CVCOLOR" nil "awesome-emerald" t)
(:cvcolorizelinks "CVCOLORIZELINKS" nil nil t)
(:cvunderlinelinks "CVUNDERLINELINKS" nil nil t)
(:mobile "MOBILE" nil nil parse)
(:homepage "HOMEPAGE" nil nil parse)
(:address "ADDRESS" nil nil newline)
(:photo "PHOTO" nil nil t)
(:photostyle "PHOTOSTYLE" nil nil t)
(:gitlab "GITLAB" nil nil parse)
(:github "GITHUB" nil nil parse)
(:leanpub "LEANPUB" nil nil parse)
(:linkedin "LINKEDIN" nil nil parse)
(:twitter "TWITTER" nil nil parse)
(:stackoverflow "STACKOVERFLOW" nil nil split)
(:extrainfo "EXTRAINFO" nil nil parse)
(:with-email nil "email" t t)
(:fontdir "FONTDIR" nil "fonts/" t)
(:latex-title-command "LATEX_TITLE" nil "\\makecvheader" t)
(:cvhighlights "CVHIGHLIGHTS" nil "true" t)
(:quote "QUOTE" nil nil t)
(:firstname "FIRSTNAME" nil nil t)
(:lastname "LASTNAME" nil nil t)
(:cvfooter_left "CVFOOTER_LEFT" nil nil t)
(:cvfooter_middle "CVFOOTER_MIDDLE" nil nil t)
(:cvfooter_right "CVFOOTER_RIGHT" nil nil t))
:translate-alist '((template . org-awesomecv-template)
(headline . org-awesomecv-headline)
(plain-list . org-awesomecv-plain-list)
(item . org-awesomecv-item)
(property-drawer . org-awesomecv-property-drawer)))
;;;; Template
;;
;; Template used is similar to the one used in `latex' back-end,
;; excepted for the table of contents and awesomecv themes.
(defun org-awesomecv-template (contents info)
"Return complete document string after LaTeX conversion.
CONTENTS is the transcoded contents string. INFO is a plist
holding export options."
(let ((title (org-export-data (plist-get info :title) info))
(spec (org-latex--format-spec info)))
(concat
;; Time-stamp.
(and (plist-get info :time-stamp-file)
(format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
;; LaTeX compiler.
(org-latex--insert-compiler info)
;; Document class and packages.
(org-latex-make-preamble info nil t)
;; Possibly limit depth for headline numbering.
(let ((sec-num (plist-get info :section-numbers)))
(when (integerp sec-num)
(format "\\setcounter{secnumdepth}{%d}\n" sec-num)))
(format "\\fontdir[%s]\n" (plist-get info :fontdir))
(format "\\colorlet{awesome}{%s}\n" (plist-get info :cvcolor))
(format "\\setbool{acvSectionColorHighlight}{%s}\n" (plist-get info :cvhighlights))
(let ((cvcolorizelinks (plist-get info :cvcolorizelinks))
(cvunderlinelinks (plist-get info :cvunderlinelinks)))
(concat
(when (and (org-string-nw-p cvcolorizelinks)
(not (string-equal cvcolorizelinks "false")))
(format "\\colorizelinks%s\n"
(if (not (string-equal cvcolorizelinks "true"))
(format "[%s]" cvcolorizelinks) "")))
(when (and (org-string-nw-p cvunderlinelinks)
(not (string-equal cvunderlinelinks "false")))
(format "\\underlinelinks%s\n"
(if (not (string-equal cvunderlinelinks "true"))
(format "[%s]" cvunderlinelinks) "")))))
;; Author. If FIRSTNAME or LASTNAME are not given, try to deduct
;; their values by splitting AUTHOR on white space.
(let* ((author (split-string (org-export-data (plist-get info :author) info)))
(first-name-prop (org-export-data (plist-get info :firstname) info))
(last-name-prop (org-export-data (plist-get info :lastname) info))
(first-name (or (org-string-nw-p first-name-prop) (car author)))
(last-name (or (org-string-nw-p last-name-prop) (cadr author))))
(format "\\name{%s}{%s}\n" first-name last-name))
;; Title
(format "\\position{%s}\n" title)
;; photo
(let* ((photo (plist-get info :photo))
(photo-style (plist-get info :photostyle))
(style-str (if photo-style (format "[%s]" photo-style) "")))
(when (org-string-nw-p photo) (format "\\photo%s{%s}\n" style-str photo)))
;; address
(let ((address (org-export-data (plist-get info :address) info)))
(when (org-string-nw-p address)
(format "\\address{%s}\n" (mapconcat (lambda (line)
(format "%s" line))
(split-string address "\n") " -- "))))
;; email
(let ((email (and (plist-get info :with-email)
(org-export-data (plist-get info :email) info))))
(when (org-string-nw-p email)
(format "\\email{%s}\n" email)))
;; Other pieces of information
(mapconcat (lambda (info-key)
(let ((info (org-export-data (plist-get info info-key) info)))
(when (org-string-nw-p info) (format "\\%s{%s}\n"
(substring (symbol-name info-key) 1)
info))))
'(:mobile
:homepage
:github
:gitlab
:leanpub
:linkedin
:twitter
:skype
:reddit
:extrainfo)
"")
;; Stack overflow requires two values: ID and name
(let* ((so-list (plist-get info :stackoverflow))
(so-id (when so-list (car so-list)))
(so-name (when so-list (cadr so-list))))
(when (and (org-string-nw-p so-id) (org-string-nw-p so-name))
(format "\\stackoverflow{%s}{%s}\n" so-id so-name)))
;; Hyperref options.
(let ((template (plist-get info :latex-hyperref-template)))
(and (stringp template)
(format-spec template spec)))
;; Document start.
"\\begin{document}\n\n"
;; Title command.
(let* ((title-command (plist-get info :latex-title-command))
(command (and (stringp title-command)
(format-spec title-command spec))))
(org-element-normalize-string
(cond ((not (plist-get info :with-title)) nil)
((string= "" title) nil)
((not (stringp command)) nil)
((string-match "\\(?:[^%]\\|^\\)%s" command)
(format command title))
(t command))))
;; Footer command
(let* ((footer-left (format-spec (or (plist-get info :cvfooter_left) "") spec))
(footer-mid (format-spec (or (plist-get info :cvfooter_middle) "") spec))
(footer-right (format-spec (or (plist-get info :cvfooter_right) "") spec)))
(when (not (string= "" (concat footer-left footer-mid footer-right)))
(format "\\makecvfooter{%s}{%s}{%s}\n" footer-left footer-mid footer-right)))
;; Document's body.
contents
;; Creator.
(and (plist-get info :with-creator)
(concat (plist-get info :creator) "\n"))
;; Document end.
"\\end{document}")))
;;;; Produce latex code for a right-float image
(defun org-awesomecv--cventry-right-img-code (file)
(if file
(format "\\begin{wrapfigure}{r}{0.15\\textwidth}
\\raggedleft\\vspace{-4.0mm}
\\includegraphics[width=0.1\\textwidth]{%s}
\\end{wrapfigure}" file) ""))
;;;; Individual cventry/cvsubentry/cvemployer/cvschool headlines
(defun org-awesomecv--format-cventry (headline contents info)
"Format HEADLINE as as cventry.
CONTENTS holds the contents of the headline. INFO is a plist used
as a communication channel."
(let* ((entrytype (org-element-property :CV_ENV headline))
(title (org-export-data (org-element-property :title headline) info))
(date (org-element-property :DATE headline))
(from-date (or (org-element-property :FROM headline) date))
(to-date (or (org-element-property :TO headline) date))
(employer (or (org-element-property :ORGANIZATION headline)
(org-element-property :SCHOOL headline)
(org-element-property :EMPLOYER headline)
(org-element-property :EVENT headline)
(org-element-property :POSITION headline) ""))
(location (or (org-element-property :LOCATION headline) ""))
(right-img (org-element-property :RIGHT_IMG headline))
(label (or (org-element-property :LABEL headline) nil))
(label-str (if label (format "%s\\hfill{}" label) ""))
;; Other Coverletter properties
(recipient (or (org-element-property :RECIPIENT headline) ""))
(letter-dateformat (org-element-property :DATEFORMAT headline))
(letter-date
(format "\\letterdate{%s}"
(if date
(format "%s" (org-awesomecv-org-timestamp-to-dateformat date letter-dateformat t))
"\\today")))
(letter-opening (if (org-element-property :LETTER_OPENING headline)
(format "\\letteropening{%s}" (org-element-property :LETTER_OPENING headline))
""))
(letter-closing (if (org-element-property :LETTER_CLOSING headline)
(format "\\letterclosing{%s}" (org-element-property :LETTER_CLOSING headline))
""))
(letter-signature (if (org-element-property :LETTER_SIGNATURE headline)
(format "\\lettersignature{%s}" (org-element-property :LETTER_SIGNATURE headline))
""))
(letter-attached (if (org-element-property :LETTER_ATTACHED headline)
(format "\\letterenclosure[Attached]{%s}" (org-element-property :LETTER_ATTACHED headline))
"")))
(cond
((string= entrytype "cvemployer")
(format "\n\\cventry{%s}{%s}{}{}{}\n%s\n"
title
(format "%s\\hfill %s" (org-cv-utils--format-time-window from-date to-date) location)
contents)
)
((string= entrytype "cventry")
(format "\n\\cventry\n{%s}\n{%s}\n{%s}\n{%s}\n{%s%s}\n"
employer
location
title
(org-cv-utils--format-time-window from-date to-date)
(org-awesomecv--cventry-right-img-code right-img)
contents))
((string= entrytype "cvsubentry")
(format "\n\\cvsubentry\n{%s}\n{%s}\n{%s%s}\n"
title
(format "%s%s" label-str (org-cv-utils--format-time-window from-date to-date))
(org-awesomecv--cventry-right-img-code right-img)
contents))
((string= entrytype "cvschool")
(format "\n\\cventry\n{%s}\n{%s}\n{%s}\n{%s}\n{%s%s}\n"
title
location
employer
(org-cv-utils--format-time-window from-date to-date)
(org-awesomecv--cventry-right-img-code right-img)
contents))
((string= entrytype "cvhonor")
(format "\n\\cvhonor\n{%s}\n{%s}\n{%s}\n{%s}\n"
title
employer
location
(org-cv-utils--format-time-window from-date to-date)))
;; Coverletter sections
((string= entrytype "letterheader")
(format "\\recipient\n {%s}\n {%s%s%s}\n\n%s\n%s\n%s\n%s\n%s\n"
recipient
employer
(if (and employer location) "\\\\" "")
location
letter-date
letter-opening
letter-closing
letter-signature
letter-attached))
((string= entrytype "cvletter")
(format "\n\\lettertitle{%s}\n\\makelettertitle\n\n\\begin{cvletter}\n%s\n\\end{cvletter}\n\\makeletterclosing"
title
contents))
((string= entrytype "cvletter_notitle")
(format "\n\\makelettertitle\n\n\\begin{cvletter}\n%s\n\\end{cvletter}\n\\makeletterclosing"
contents))
((string= entrytype "lettersection")
(format "\n\\lettersection{%s}\n%s"
title
contents)))))
;;;; Headlines of type "cventries"
(defun org-awesomecv--format-cvenvironment (environment headline contents info)
"Format HEADLINE as as a cventries/cvhonors environment.
CONTENTS holds the contents of the headline. INFO is a plist used
as a communication channel."
(format "%s\n\\begin{%s}\n%s\\end{%s}\n"
(org-export-with-backend 'latex headline nil info)
environment contents environment))
;;;; Headline
(defun org-awesomecv-headline (headline contents info)
"Transcode HEADLINE element into awesomecv code.
CONTENTS is the contents of the headline. INFO is a plist used
as a communication channel."
(unless (org-element-property :footnote-section-p headline)
(let ((environment (let ((env (org-element-property :CV_ENV headline)))
(or (org-string-nw-p env) "block")))
(pagebreak (org-string-nw-p (org-element-property :PAGEBREAK headline))))
(concat
(when pagebreak "\\clearpage\n")
(cond
;; is a cv entry or subentry
((or (string= environment "cventry")
(string= environment "cvsubentry")
(string= environment "cvemployer")
(string= environment "cvschool")
(string= environment "cvhonor")
(string= environment "cvletter")
(string= environment "cvletter_notitle")
(string= environment "lettersection")
(string= environment "letterheader")
)
(org-awesomecv--format-cventry headline contents info))
((or (string= environment "cventries") (string= environment "cvhonors"))
(org-awesomecv--format-cvenvironment environment headline contents info))
((org-export-with-backend 'latex headline contents info)))))))
;;;; Plain List, to intercept and transform "cvskills" lists
(defun org-awesomecv-plain-list (plain-list contents info)
"Transcode a PLAIN-LIST element from Org to LaTeX.
CONTENTS is the contents of the list. INFO is a plist holding
contextual information."
(let* ((cv-env (org-entry-get (org-element-property :begin plain-list) "CV_ENV" nil))
(parent-type (car (org-element-property :parent plain-list))))
(cond
((string= cv-env "cvskills")
(format "\\begin{cvskills}\n%s\\end{cvskills}" contents))
((and (eq parent-type 'section) (or (string= cv-env "cventry") (string= cv-env "cvsubentry") (string= cv-env "cvschool")))
(format "\\begin{cvitems}\n%s\\end{cvitems}" contents))
(t
(org-latex-plain-list plain-list contents info)))))
;;;; Item, to intercept and transform "cvskills" lists
(defun org-awesomecv-item (item contents info)
(let* ((cv-env (org-entry-get (org-element-property :begin item) "CV_ENV" t))
(tag (let ((tag (org-element-property :tag item)))
(and tag (org-export-data tag info)))))
(if (and (string= cv-env "cvskills") tag)
(format "\\cvskill{%s}{%s}\n" tag (org-trim contents))
(org-latex-item item contents info))
)
)
;;;; Property Drawer, to avoid exporting them even when the option is set
(defun org-latex-property-drawer (property-drawer contents info)
"Transcode a PROPERTY-DRAWER element from Org to AwesomeCV.
This does not make sense in the AwesomeCV format, so it only
returns an empty string."
nil)
(defun org-awesomecv-org-timestamp-to-dateformat (date_str &optional FORMAT-STRING ORDINAL)
"Format orgmode timestamp DATE_STR into a date format FORMAT-STRING.
ORDINAL returns the date as an ordinal number, specified as %E in format.
Uses defaults that are consistent with awesomecv.
Other strings are just returned unmodified
e.g. <2002-08-12 Mon> => August 12th, 2012
today => today"
(if (string-match (org-re-timestamp 'active) date_str)
(let* ((dte (org-parse-time-string date_str))
(time (encode-time dte))
(day-format (if ORDINAL "%E" "%e"))
(format-string-0 (or FORMAT-STRING
(if (eql calendar-date-style 'american)
(format "%%B %s, %%Y" day-format)
(format "%s %%B, %%Y" day-format))))
(day-raw (format-time-string "%eth" time))
(day-ordinal
(let ((r0 "\\([04-9]\\|1[0-9]\\)th$")
(r1 "\\([1]\\)th$" )
(r2 "\\([2]\\)th$" )
(r3 "\\([3]\\)th$" )
)
(cond
((string-match r0 day-raw) (replace-regexp-in-string r0 "\\1th" day-raw))
((string-match r1 day-raw) (replace-regexp-in-string r1 "\\1st" day-raw))
((string-match r2 day-raw) (replace-regexp-in-string r2 "\\1nd" day-raw))
((string-match r3 day-raw) (replace-regexp-in-string r3 "\\1rd" day-raw )))))
(format-string (replace-regexp-in-string "%E" day-ordinal format-string-0 't)))
(format-time-string format-string time))
date_str))
(provide 'ox-awesomecv)
;;; ox-awesomecv ends here

View File

@ -216,6 +216,219 @@ When exporting you can call the following function to get the latex file.
</object>
#+END_EXPORT
** Using AwesomeCV
[[https://github.com/posquit0/Awesome-CV][AwesomeCV]] is another LaTeX template for producing nice-looking
CVs and cover letters. This style also supports some additional options. For example:
#+BEGIN_SRC org :tangle awesomecv.org
# CV color - options include: 'awesome-red (default), 'awesome-emerald,
# 'awesome-skyblue', 'awesome-pink', 'awesome-orange', 'awesome-nephritis',
# 'awesome-concrete' and 'awesome-darknight', plus any standard color names.
,#+CVCOLOR: awesome-red
# Specify the position and style of the photo
,#+PHOTOSTYLE: right,noedge
#+END_SRC
# Next block is to generate exports
#+BEGIN_SRC org :exports none :tangle awesomecv.org
#+include: basic_cv.org
#+include: sideactivities.org
#+include: workcontent.org
#+END_SRC
When exporting you can call the following function to get the latex file.
#+BEGIN_SRC emacs-lisp
(org-export-to-file 'awesomecv "awesomecv.tex")
(org-latex-compile "awesomecv.tex")
#+END_SRC
Note that AwesomeCV uses the =fontspec= package, so you need to set =org-latex-compiler= to =lualatex= or =xelatex= for it to work.
In addition to the regular document attributes, the following are supported:
#+attr_html: :class table table-striped
| Field | Description |
|-----------------+-------------------------------------------------------------|
| PHOTOSTYLE | Style of photo to use. Comma-separated values can include |
| | circle/rectangle,edge/noedge,left/right. |
| CVCOLOR | Color of highlights. |
| STACKOVERFLOW | Stack overflow info, must be specified as "=ID username=" |
| FONTDIR | Directory where the fonts can be found, defaults |
| | to =fonts/= (as in the standard AwesomeCV) |
| CVHIGHLIGHTS | Whether to colorize highlights. Defaults to true |
| QUOTE | Optional quote to include at the top of the CV |
| FIRSTNAME | First name to be shown in the CV. By default the first |
| | space-separated part of AUTHOR is used. |
| LASTNAME | Last name to be shown in the CV. By default the second |
| | space-separated part of AUTHOR is used. |
| CVFOOTER_LEFT | Text to include in the left footer. None by default |
| CVFOOTER_MIDDLE | Text to include in the middle footer. None by default. |
| CVFOOTER_RIGHT | Text to include in the right footer. None by default. |
| LATEX_TITLE | Text to use as the title section. \makecvheader by default. |
| | (Can specify \makecvheader[R] to justify to the right) |
*** CV environments
AwesomeCV supports a few additional types of environment types in =CV_ENV=,
including =cvemployer=, =cvskills=, =cvhonors= and =cvschool= (see full list below).
Some of these support additional property fields:
#+attr_html: :class table table-striped
| Field | Description |
|-----------+------------------------------------------------------------------|
| FROM | Start date of the entry |
| TO | End date of the entry |
| DATE | Shortcut to specify both =FROM= and =TO= as the same date. |
| | Both =FROM= and =TO= override =DATE=. |
| EMPLOYER | Employer or organization, can also be specified |
| | as =ORGANIZATION=, =SCHOOL=, =EVENT= or =POSITION= (different |
| | names make more sense depending on the type of environment) |
| LABEL | In =cvsubentry= environments, adds the given text to the left |
| | of the date range, can be used to add additional information |
| | to the entry. |
| RIGHT_IMG | path to an image to include floating to the right of a =cventry=, |
| | a =cvsubentry= or =cvschool= entry. Meant to be used to show a logo. |
| PAGEBREAK | Causes a LaTeX =\clearpage= statement to be inserted in the |
| | exported output before the heading. |
All the supported values of =CV_ENV= for CVs are described below.
**** =cventries=
Enclose all the subheaders in a =cventries= environment. Subheaders can
be of type =cventry=, =cvschool=, or =cvemployer=.
**** =cvhonors=
Enclose all the subheaders in a =cvhonors= environment. Subheaders must
be of type =cvhonor=
**** =cventry=
Converts to a =\cventry= command. Supports attributes =FROM=, =TO=, =DATE=,
=EMPLOYER=, =LOCATION=, =RIGHT_IMG=.
**** =cvsubentry=
Converts to a =\cvsubentry= command. Supports attributes =FROM=, =TO=, =DATE=,
=LABEL= =RIGHT_IMG=.
**** =cvemployer=
Converts to a =\cventry= with only the title line. Supports attributes
=FROM=, =TO=, =DATE= and =LOCATION=.
**** =cvschool=
Converts to a =\cventry=. The headline should contain the degree
obtained, shown as the main title. Supports attributes =LOCATION=,
=SCHOOL=, =FROM=, =TO=, =DATE= and =RIGHT_IMG=.
**** =cvhonor=
Converts to a =\cvhonor= command (must be inside a =cvhonors=
headline). Supports attributes =LOCATION=, =EMPLOYER= (in this case =EVENT=
or =POSITION= might be more semantically accurate, and can also be
used), =FROM=, =TO=, =DATE=.
**** =cvskills=
Converts to a =\cvskills= environment. The headline must contain a
[[https://orgmode.org/manual/Plain-lists.html][description list]], which gets converted into a sequence of =\cvskill=
commands, with the term as the skill title and the description as its
contents.
#+BEGIN_EXPORT md
<object data="awesomecv.org.pdf" type="application/pdf" width="100%" height="500px">
<p>Alternative text - include a link <a href="awesomecv.org.pdf">to the PDF!</a></p>
</object>
#+END_EXPORT
*** Cover letter environments
AwesomeCV also supports generating cover letters. For this, =CV_ENV= can have a few additional values, shown below.
**** =letterheader=
This environment provides heading/signature information for a cover letter. Supports attributes =RECIPIENT=. =EMPLOYER=, =LOCATION=, =LETTER_OPENING=, =LETTER_CLOSING=, =LETTER_ATTACHED=, =DATE=, =DATEFORMAT=.
Note that the text within the heading is not exported! You can use this, for example, to keep notes about your application or the employer. For example:
#+BEGIN_SRC org :exports none :tangle awesome-letter.org
#+include: basic_cv.org
#+END_SRC
#+begin_src org :tangle awesome-letter.org
,* Recipient
:PROPERTIES:
:CV_ENV: letterheader
:RECIPIENT: International Recruiting team
:EMPLOYER: Employer Co.
:LOCATION: Someplace, the world
:LETTER_OPENING: Dear International Recruiting team
:LETTER_CLOSING: Kind regards,
:LETTER_ATTACHED: Curriculum Vitae
:END:
Title and content are not exported.
Add any notes about the recipient here
They will *not* be exported.
#+end_src
#+attr_html: :class table table-striped
| Field | Description |
|-----------------+-----------------------------------------------------------------------------------|
| RECIPIENT | Addressee E.g. Company Recruitment Team |
| EMPLOYER | Company name |
| LOCATION | Company address |
| LETTER_OPENING | Letter opening, E.g. Dear Ms./Mr./Dr. LastName |
| LETTER_CLOSING | Letter closing, E.g. Yours Sincerely, |
| DATE | The date used for the letter, uses \\today as default if unspecified |
| DATEFORMAT | Specify an alternative date format for the letter header |
| | E.g. %e %M %Y might provide 19 March 2021 |
| LETTER_ATTACHED | Attachments to the letter, will be listed at the bottom. E.g. "Curriculum Vitae" |
**** =cvletter=
Converts to a =\cvletter= environment. This holds the content of a cover letter. The body can be subdivided using =lettersection= headings. The heading title is converted to a title line at the top of the letter.
#+begin_src org :tangle awesome-letter.org
,* Application for the position of /Awesome Job/ (job reference #123456)
:PROPERTIES:
:CV_ENV: cvletter
:END:
,** About Me
:PROPERTIES:
:CV_ENV: lettersection
:END:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ullamcorper neque sit amet lectus facilisis sed luctus nisl iaculis. Vivamus at neque arcu, sed tempor quam. Curabitur pharetra tincidunt tincidunt. Morbi volutpat feugiat mauris, quis tempor neque vehicula volutpat. Duis tristique justo vel massa fermentum accumsan. Mauris ante elit, feugiat vestibulum tempor eget, eleifend ac ipsum. Donec scelerisque lobortis ipsum eu vestibulum. Pellentesque vel massa at felis accumsan rhoncus.
,** Why Employer Co.?
:PROPERTIES:
:CV_ENV: lettersection
:END:
Suspendisse commodo, massa eu congue tincidunt, elit mauris pellentesque orci, cursus tempor odio nisl euismod augue. Aliquam adipiscing nibh ut odio sodales et pulvinar tortor laoreet. Mauris a accumsan ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse vulputate sem vehicula ipsum varius nec tempus dui dapibus. Phasellus et est urna, ut auctor erat. Sed tincidunt odio id odio aliquam mattis. Donec sapien nulla, feugiat eget adipiscing sit amet, lacinia ut dolor. Phasellus tincidunt, leo a fringilla consectetur, felis diam aliquam urna, vitae aliquet lectus orci nec velit. Vivamus dapibus varius blandit.
,** Why me?
:PROPERTIES:
:CV_ENV: lettersection
:END:
Duis sit amet magna ante, at sodales diam. Aenean consectetur porta risus et sagittis. Ut interdum, enim varius pellentesque tincidunt, magna libero sodales tortor, ut fermentum nunc metus a ante. Vivamus odio leo, tincidunt eu luctus ut, sollicitudin sit amet metus. Nunc sed orci lectus. Ut sodales magna sed velit volutpat sit amet pulvinar diam venenatis.
#+end_src
**** =cvletter_notitle=
Same as =cvletter=, but does not include a letter title at the top.
**** =lettersection=
Converts to a =\lettersection= command. These are the headline portions of a cover letter.
#+BEGIN_EXPORT md
<object data="awesome-letter.org.pdf" type="application/pdf" width="100%" height="500px">
<p>Alternative text - include a link <a href="awesome-letter.org.pdf">to the PDF!</a></p>
</object>
#+END_EXPORT
* Markdown Hugo Exporter
:PROPERTIES:
:EXPORT_FILE_NAME: hugo_export