forked from mirrors/org-cv
Compare commits
64 commits
fontawesom
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
dbbe6e85b2 | ||
|
049859ca7a | ||
|
c5c5f8da2f | ||
|
07fc1e0f0f | ||
|
73280f3070 | ||
|
c6805e1d92 | ||
|
f1fe584ad5 | ||
|
98875d53f5 | ||
|
e3532737bd | ||
|
a94bf0e5ad | ||
|
d89628c2ed | ||
|
25fdcbfa01 | ||
|
70bab953d9 | ||
|
fdfdc4f3cb | ||
|
09408fd67f | ||
|
c3e111b18e | ||
|
eae0b9a789 | ||
|
4ac644cc34 | ||
|
2d95e3c640 | ||
|
45d9271165 | ||
|
bab87823e2 | ||
|
e3146f494c | ||
|
f62d53b82e | ||
|
e934bcf91d | ||
|
5109cbf0c8 | ||
|
210d9c2720 | ||
|
332c72880d | ||
|
24bcd82348 | ||
|
59c5fe6cca | ||
|
30c4a660e2 | ||
|
4df7fa67a9 | ||
|
059668cb6a | ||
|
b885e66e86 | ||
|
2e9d4bc857 | ||
|
32beb20aea | ||
|
ee6e42c857 | ||
|
99ea2e0878 | ||
|
e372aa78be | ||
|
e8eb9d9bc4 | ||
|
7c06e78fb4 | ||
|
ca5b098123 | ||
|
58fd53f743 | ||
|
59cf8ffd52 | ||
|
30e93ab103 | ||
|
cb32990168 | ||
|
6fcf2e43b5 | ||
|
c9ddf59080 | ||
|
de6feffebe | ||
|
81cc0ed4a4 | ||
|
dc1889f543 | ||
|
95c9051532 | ||
|
2a322a9b12 | ||
|
51c7ef8ed5 | ||
|
91e5a55fe1 | ||
|
dcbe20b52d | ||
|
395069b130 | ||
|
0b433116d1 | ||
|
2100516ffc | ||
|
daf7295688 | ||
|
4e059491c0 | ||
|
3900071b8d | ||
|
19213346a8 | ||
|
fbf6dd3a67 | ||
|
c3b43b361e |
23 changed files with 1939 additions and 304 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
*.elc
|
||||||
|
/dev.org
|
|
@ -8,22 +8,24 @@ before_script:
|
||||||
|
|
||||||
test:
|
test:
|
||||||
script:
|
script:
|
||||||
- emacs --batch -Q --script genfiles.el
|
- emacs --batch -Q --script genfiles.el
|
||||||
- cd doc; hugo
|
- cd doc; hugo
|
||||||
except:
|
except:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- doc/public
|
- doc/public
|
||||||
|
- org-cv-exports
|
||||||
|
when: always
|
||||||
|
|
||||||
pages:
|
pages:
|
||||||
script:
|
script:
|
||||||
- emacs --batch -Q --script genfiles.el
|
- emacs --batch -Q --script genfiles.el
|
||||||
- cd doc; hugo
|
- cd doc; hugo
|
||||||
- mv public/ ../public/ # Because I remain now in the doc folder
|
- mv public/ ../public/ # Because I remain now in the doc folder
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- public
|
- public
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
|
|
@ -2,10 +2,16 @@ baseURL = "https://titan-c.gitlab.io/org-cv/"
|
||||||
languageCode = "en-us"
|
languageCode = "en-us"
|
||||||
title = "Org CV"
|
title = "Org CV"
|
||||||
theme = "project-landing-page"
|
theme = "project-landing-page"
|
||||||
|
[markup.goldmark.renderer]
|
||||||
|
unsafe = true
|
||||||
|
|
||||||
|
[markup.goldmark.parser.attribute]
|
||||||
|
title = true
|
||||||
|
block = true
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
description = "Org-mode backend exporters for Curriculum Vita"
|
description = "Org-mode backend exporters for Curriculum Vita"
|
||||||
author_url = "http://blog.oscarnajera.com"
|
author_url = "http://oscarnajera.com"
|
||||||
author = "Titan-C"
|
author = "Titan-C"
|
||||||
project_url = "https://gitlab.com/Titan-C/org-cv/"
|
project_url = "https://gitlab.com/Titan-C/org-cv/"
|
||||||
logo = "https://upload.wikimedia.org/wikipedia/commons/a/a6/Org-mode-unicorn.svg"
|
logo = "https://upload.wikimedia.org/wikipedia/commons/a/a6/Org-mode-unicorn.svg"
|
||||||
|
|
|
@ -14,12 +14,11 @@ The basic structure of an org file containing your CV is shown next.
|
||||||
put your foreseen job.
|
put your foreseen job.
|
||||||
|
|
||||||
<div class="ox-hugo-table table table-striped">
|
<div class="ox-hugo-table table table-striped">
|
||||||
<div></div>
|
|
||||||
|
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
|----------|----------------------------------------------------|
|
|----------|----------------------------------------------------|
|
||||||
| TITLE | Desired job |
|
| TITLE | Desired job |
|
||||||
| AUTHOR | Who you are? |
|
| AUTHOR | Who are you? |
|
||||||
| EMAIL | Your contact email |
|
| EMAIL | Your contact email |
|
||||||
| ADDRESS | Mailing address, this can span over multiple lines |
|
| ADDRESS | Mailing address, this can span over multiple lines |
|
||||||
| HOMEPAGE | URL of your website |
|
| HOMEPAGE | URL of your website |
|
||||||
|
@ -32,9 +31,10 @@ put your foreseen job.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
```org
|
```org
|
||||||
#+TITLE: My dream job
|
#+TITLE: My dream job an ORG-CV example
|
||||||
#+AUTHOR: John Doe
|
#+AUTHOR: John Doe
|
||||||
#+email: john@doe.lost
|
#+email: john@doe.lost
|
||||||
|
#+options: tags:nil
|
||||||
|
|
||||||
#+ADDRESS: My Awesome crib
|
#+ADDRESS: My Awesome crib
|
||||||
#+ADDRESS: Fantastic city -- Planet Earth
|
#+ADDRESS: Fantastic city -- Planet Earth
|
||||||
|
@ -47,14 +47,22 @@ put your foreseen job.
|
||||||
```
|
```
|
||||||
|
|
||||||
You can use org-modes hierarchical structure to describe your CV. To make a
|
You can use org-modes hierarchical structure to describe your CV. To make a
|
||||||
specific subtree an item describing an experience point (Job you have,
|
specific subtree an item describing an experience point (Job you have, degree
|
||||||
degree you pursued, etc.) you use the org properties drawer and with the
|
you pursued, etc.) you use the org properties drawer and with the `:CV_ENV:
|
||||||
`:CV_ENV: cventry` property. You should also include the `FROM` and `TO`
|
cventry` property. You should also include the `FROM` and `TO` properties
|
||||||
properties defining the span of the event, as `LOCATION` and `EMPLOYER`.
|
defining the span of the entry, as well as `LOCATION` and `EMPLOYER`.
|
||||||
|
|
||||||
|
Because work isn't everything we do, it is more meaningful to label differently
|
||||||
|
the host of those other events like studies, events, certifications, etc. Thus
|
||||||
|
`HOST`, `ORGANIZATION`, `INSTITUTION`, `SCHOOL`, `EMPLOYER` or `EVENT` are all
|
||||||
|
equivalent and the first match in that order has precedence.
|
||||||
|
|
||||||
|
`DATE` is a shortcut for `FROM` and `TO` when you have a single date in mind
|
||||||
|
instead of a range. Both `FROM` and `TO` override `DATE`.
|
||||||
|
|
||||||
```org
|
```org
|
||||||
* Employement
|
* Employement :cventries:
|
||||||
** One job
|
** One job :cventry:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CV_ENV: cventry
|
:CV_ENV: cventry
|
||||||
:FROM: <2014-09-01>
|
:FROM: <2014-09-01>
|
||||||
|
@ -64,9 +72,8 @@ properties defining the span of the event, as `LOCATION` and `EMPLOYER`.
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
I write about awesome stuff I do.
|
I write about awesome stuff I do.
|
||||||
** Other job
|
** Other job :cventry:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CV_ENV: cventry
|
|
||||||
:FROM: <2013-09-01>
|
:FROM: <2013-09-01>
|
||||||
:TO: <2014-08-07>
|
:TO: <2014-08-07>
|
||||||
:LOCATION: my city, your country
|
:LOCATION: my city, your country
|
||||||
|
|
|
@ -5,11 +5,14 @@ draft = false
|
||||||
weight = 1001
|
weight = 1001
|
||||||
+++
|
+++
|
||||||
|
|
||||||
This project aims to generate from an org-mode file with reasonably ordered
|
This project exports an org-mode file with reasonably structured items into
|
||||||
items a latex file which compiles into a reasonably nice CV. In the same
|
a latex file, which compiles into a nice CV. In the same spirit the
|
||||||
spirit the org-mode file must export to markdown so that it can be uses for
|
org-mode file may export to markdown so that it can be used for a web based
|
||||||
web based CV.
|
CV.
|
||||||
|
|
||||||
- Online documentation in <https://titan-c.gitlab.io/org-cv/>
|
- Online documentation in <https://titan-c.gitlab.io/org-cv/>
|
||||||
- Development happens in the gitlab repository: <https://gitlab.com/Titan-C/org-cv>
|
- Development happens in the gitlab repository: <https://gitlab.com/Titan-C/org-cv>
|
||||||
- There is a mirror in github for backup: <https://github.com/Titan-C/org-cv>
|
- There is a mirror in github for backup: <https://github.com/Titan-C/org-cv>
|
||||||
|
|
||||||
|
This project dog feeds itself and produces the examples on this
|
||||||
|
documentation page directly.
|
||||||
|
|
|
@ -16,5 +16,43 @@ exclude some tags during export.
|
||||||
(org-export-to-file 'hugocv "hugocv.md"))
|
(org-export-to-file 'hugocv "hugocv.md"))
|
||||||
```
|
```
|
||||||
|
|
||||||
You are responsible for styling your website. Icons used here use
|
You are responsible for styling your website. Use all the CSS magic you know.
|
||||||
FontAwesome 5.
|
Each entry is inside a `div` container and each element of the properties has
|
||||||
|
its own class.
|
||||||
|
|
||||||
|
Make sure that your hugo config has the markup parser attributes active and allows
|
||||||
|
for html rendering.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
markup:
|
||||||
|
goldmark:
|
||||||
|
renderer:
|
||||||
|
unsafe: true
|
||||||
|
parser:
|
||||||
|
attribute:
|
||||||
|
title: true
|
||||||
|
block: true
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use an awards section for a different styling. Here you tag each
|
||||||
|
entry with `cvhonor`.
|
||||||
|
|
||||||
|
```org
|
||||||
|
* Awards
|
||||||
|
** First place :cvhonor:
|
||||||
|
:PROPERTIES:
|
||||||
|
:CV_ENV: cventry
|
||||||
|
:DATE: <2014-09-01>
|
||||||
|
:LOCATION: a city, a country
|
||||||
|
:EVENT: The RACE
|
||||||
|
:END:
|
||||||
|
|
||||||
|
** Sport Scholarship :cvhonor:
|
||||||
|
:PROPERTIES:
|
||||||
|
:DATE: <2013-09-01>
|
||||||
|
:LOCATION: my city, your country
|
||||||
|
:ORGANIZATION: The nice millionaire
|
||||||
|
:END:
|
||||||
|
```
|
||||||
|
|
||||||
|
Next is the rendered result for the special entries with styling.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
title = "Installation"
|
title = "Installation"
|
||||||
author = ["Óscar Nájera"]
|
author = ["Óscar Nájera"]
|
||||||
draft = false
|
draft = false
|
||||||
weight = 1001
|
weight = 1002
|
||||||
+++
|
+++
|
||||||
|
|
||||||
This project is not on MELPA so you have to do a manual installation. First
|
This project is not on MELPA so you have to do a manual installation. First
|
||||||
|
|
|
@ -8,11 +8,11 @@ weight = 1004
|
||||||
## Using modern-cv {#using-modern-cv}
|
## Using modern-cv {#using-modern-cv}
|
||||||
|
|
||||||
[moderncv](https://www.ctan.org/tex-archive/macros/latex/contrib/moderncv) is a standard \\(\LaTeX\\) package that you can find in many of your
|
[moderncv](https://www.ctan.org/tex-archive/macros/latex/contrib/moderncv) is a standard \\(\LaTeX\\) package that you can find in many of your
|
||||||
latex distributions. For I maintain for personal purposes a fork of it to
|
latex distributions. I maintain a fork of it, to work with my use case at
|
||||||
better work with my use case at <https://github.com/Titan-C/moderncv.git>
|
<https://github.com/Titan-C/moderncv.git> Feel free to use any or even your
|
||||||
Feel free to use any or even your personal fork for your desired use case.
|
personal fork for your desired use case.
|
||||||
|
|
||||||
To configure the export for moderncv you need the addition options in your
|
To configure the export for moderncv you need the additional options in your
|
||||||
org file.
|
org file.
|
||||||
|
|
||||||
```org
|
```org
|
||||||
|
@ -92,3 +92,229 @@ 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">
|
<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>
|
<p>Alternative text - include a link <a href="altacv.org.pdf">to the PDF!</a></p>
|
||||||
</object>
|
</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">
|
||||||
|
|
||||||
|
| 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">
|
||||||
|
|
||||||
|
| 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">
|
||||||
|
|
||||||
|
| 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>
|
||||||
|
|
19
doc/content/post/license.md
Normal file
19
doc/content/post/license.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
+++
|
||||||
|
title = "License"
|
||||||
|
author = ["Óscar Nájera"]
|
||||||
|
draft = false
|
||||||
|
weight = 1007
|
||||||
|
+++
|
||||||
|
|
||||||
|
> org-cv
|
||||||
|
> Copyright (C) 2018-2023 Óscar Nájera
|
||||||
|
>
|
||||||
|
> 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 of the License, 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.
|
22
doc/content/post/tips.md
Normal file
22
doc/content/post/tips.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
+++
|
||||||
|
title = "Tips"
|
||||||
|
author = ["Óscar Nájera"]
|
||||||
|
draft = false
|
||||||
|
weight = 1008
|
||||||
|
+++
|
||||||
|
|
||||||
|
If you have found this project useful. Please consider giving back. You can
|
||||||
|
kindly tip me for this project
|
||||||
|
|
||||||
|
Stellar
|
||||||
|
: GDPTOFND6HSE5AVHPRXOCJFOA6NPFB65JAEWKTN23EBUGBB2AU4PLIBD
|
||||||
|
|
||||||
|
liberapay
|
||||||
|
: [Titan-C](https://liberapay.com/Titan-C/)
|
||||||
|
|
||||||
|
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
|
||||||
|
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||||
|
<input type="hidden" name="hosted_button_id" value="Y3VB5VL7PD3QC" />
|
||||||
|
<input type="image" src="https://www.paypalobjects.com/en_US/DK/i/btn/btn_donateCC_LG.gif" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Donate with PayPal button" />
|
||||||
|
<img alt="" border="0" src="https://www.paypal.com/en_DE/i/scr/pixel.gif" width="1" height="1" />
|
||||||
|
</form>
|
38
doc/layouts/partials/head.html
Normal file
38
doc/layouts/partials/head.html
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="description" content="" />
|
||||||
|
<meta name="author" content="" />
|
||||||
|
<base href="{{ .Site.BaseURL }}" />
|
||||||
|
<title>{{ .Title }}</title>
|
||||||
|
|
||||||
|
<!-- Bootstrap Core CSS -->
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
<!-- Custom CSS -->
|
||||||
|
<link href="css/landing-page.css" rel="stylesheet" />
|
||||||
|
<link href="css/cv.css" rel="stylesheet" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Custom Fonts -->
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic"
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
{{ printf "%v" (partial "template.css" . ) | safeCSS }}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
</html>
|
125
doc/static/css/cv.css
vendored
Normal file
125
doc/static/css/cv.css
vendored
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
.cv-entry .cv-host,
|
||||||
|
.cv-entry .cv-date,
|
||||||
|
.cv-entry .cv-location,
|
||||||
|
.cv-honor .cv-host,
|
||||||
|
.cv-honor .cv-date,
|
||||||
|
.cv-honor .cv-location {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry .cv-host::before,
|
||||||
|
.cv-honor .cv-host::before {
|
||||||
|
font-family: "Font Awesome 6 Free";
|
||||||
|
content: "\f1ad";
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry .cv-location::before,
|
||||||
|
.cv-honor .cv-location::before {
|
||||||
|
font-family: "Font Awesome 6 Free";
|
||||||
|
content: "\f041";
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry .cv-role::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
background-color: #79c753;
|
||||||
|
border-radius: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry .cv-date::before {
|
||||||
|
font-family: "Font Awesome 6 Free";
|
||||||
|
content: "\f133";
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-honor .cv-role {
|
||||||
|
margin-left: 5.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-honor .cv-date {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0.05rem;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-honor .cv-date::before {
|
||||||
|
font-family: "Font Awesome 6 Free";
|
||||||
|
color: #ffb700;
|
||||||
|
content: "\f559";
|
||||||
|
font-weight: 900;
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry {
|
||||||
|
border-left-style: solid;
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-honor .cv-host,
|
||||||
|
.cv-honor .cv-location,
|
||||||
|
.cv-entry .cv-date,
|
||||||
|
.cv-entry .cv-location {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry .cv-host,
|
||||||
|
.cv-entry .cv-date,
|
||||||
|
.cv-entry .cv-location,
|
||||||
|
.cv-honor .cv-host,
|
||||||
|
.cv-honor .cv-date,
|
||||||
|
.cv-honor .cv-location {
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry .cv-host,
|
||||||
|
.cv-entry .cv-date,
|
||||||
|
.cv-entry .cv-location,
|
||||||
|
.cv-honor .cv-host,
|
||||||
|
.cv-honor .cv-date,
|
||||||
|
.cv-honor .cv-location {
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry .cv-host,
|
||||||
|
.cv-entry .cv-date,
|
||||||
|
.cv-entry .cv-location,
|
||||||
|
.cv-honor .cv-host,
|
||||||
|
.cv-honor .cv-date,
|
||||||
|
.cv-honor .cv-location {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry,
|
||||||
|
.cv-honor {
|
||||||
|
padding-left: 2rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
margin-left: 1rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry p,
|
||||||
|
.cv-entry ul,
|
||||||
|
.cv-honor p,
|
||||||
|
.cv-honor ul {
|
||||||
|
padding-top: 0.25rem;
|
||||||
|
padding-bottom: 0.25rem;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cv-entry .cv-role {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
2
doc/themes/project-landing-page
vendored
2
doc/themes/project-landing-page
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 55a73ff9c1b7a674d8aa6ee20a52f8ce9f481882
|
Subproject commit 5da34f691d936bb5e9ce8b5b898b74deca54eb23
|
76
genfiles.el
76
genfiles.el
|
@ -1,34 +1,58 @@
|
||||||
;; remember the current directory, find-file changes it
|
(defvar cv-cwd default-directory
|
||||||
(defvar cwd default-directory)
|
"remember the current directory, find-file changes it")
|
||||||
(defvar workdir "/tmp/org-cv-exports/")
|
(defvar cv-workdir (expand-file-name "org-cv-exports/"))
|
||||||
(find-file "/tmp/install-org.el")
|
(toggle-debug-on-error)
|
||||||
(eval-buffer)
|
(with-current-buffer (find-file-noselect "/tmp/install-org.el")
|
||||||
|
(eval-buffer))
|
||||||
|
|
||||||
(add-to-list 'load-path cwd)
|
(use-package ox-hugo
|
||||||
|
:ensure t
|
||||||
|
:pin melpa
|
||||||
|
:after ox)
|
||||||
|
|
||||||
(require 'ox-moderncv)
|
(use-package ox-moderncv
|
||||||
|
:load-path cv-cwd
|
||||||
|
:ensure dash
|
||||||
|
:init
|
||||||
|
(require 'ox-altacv)
|
||||||
|
(require 'ox-hugocv)
|
||||||
|
(require 'ox-awesomecv)
|
||||||
|
(require 'ox-awesomecv2))
|
||||||
|
|
||||||
(require 'ox-altacv)
|
(defun export-with (backend file ext)
|
||||||
|
(let ((workfile (concat cv-workdir file))
|
||||||
(let ((readme (concat cwd "readme.org")))
|
(outfile (concat cv-workdir file ext)))
|
||||||
(find-file readme)
|
(message (format "%s exists: %s" workfile (file-exists-p workfile)))
|
||||||
(make-directory workdir t)
|
(with-current-buffer
|
||||||
(cd workdir)
|
(find-file-noselect workfile)
|
||||||
(org-babel-tangle))
|
(org-mode)
|
||||||
|
(message "back %S, out %S" backend outfile)
|
||||||
(copy-file (concat cwd "doc/smile.png") workdir)
|
(org-export-to-file backend outfile))
|
||||||
|
outfile))
|
||||||
|
|
||||||
(defun export-latex (backend file)
|
(defun export-latex (backend file)
|
||||||
(let ((workfile (concat workdir file))
|
(let ((outfile (export-with backend file ".tex"))
|
||||||
(outfile (concat workdir file ".tex")))
|
(pdffile (concat cv-workdir file ".pdf")))
|
||||||
(message (format "%s exists: %s" workfile (file-exists-p workfile)))
|
(cd cv-workdir)
|
||||||
(find-file workfile)
|
(message (format "%s exists: %s" outfile (file-exists-p outfile)))
|
||||||
(org-mode)
|
(shell-command (format "xelatex --output-directory=%s %s" cv-workdir outfile) "*Messages*" "*Messages*")
|
||||||
(org-export-to-file backend outfile)
|
(message (format "%s exists: %s" pdffile (file-exists-p pdffile)))
|
||||||
(shell-command (format "pdflatex %s" outfile) "*Messages*" "*Messages*")
|
(copy-file pdffile (concat cv-cwd "/doc/static/" (concat file ".pdf")) t)))
|
||||||
(copy-file (concat file ".pdf") (concat cwd "/doc/static/" (concat file ".pdf")))
|
|
||||||
))
|
|
||||||
|
|
||||||
(make-directory (concat cwd "/doc/static/") t)
|
(let ((readme (concat cv-cwd "readme.org")))
|
||||||
|
(make-directory cv-workdir t)
|
||||||
|
(with-current-buffer
|
||||||
|
(find-file-noselect readme)
|
||||||
|
(cd cv-workdir)
|
||||||
|
(org-babel-tangle)))
|
||||||
|
|
||||||
|
(copy-file (concat cv-cwd "doc/smile.png") cv-workdir t)
|
||||||
|
(make-directory (concat cv-cwd "/doc/static/") t)
|
||||||
(export-latex 'altacv "altacv.org")
|
(export-latex 'altacv "altacv.org")
|
||||||
(export-latex 'moderncv "moderncv.org")
|
(export-latex 'moderncv "moderncv.org")
|
||||||
|
(export-latex 'awesomecv2 "awesomecv.org")
|
||||||
|
(export-latex 'awesomecv "awesomecv.org")
|
||||||
|
(export-latex 'awesomecv "awesome-letter.org")
|
||||||
|
(copy-file
|
||||||
|
(export-with 'hugocv "hugocv.org" ".md")
|
||||||
|
(concat cv-cwd "/doc/content/post/cv.md"))
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
wget https://github.com/gohugoio/hugo/releases/download/v0.39/hugo_0.39_Linux-64bit.deb
|
wget https://github.com/gohugoio/hugo/releases/download/v0.100.2/hugo_0.100.2_Linux-64bit.deb
|
||||||
dpkg -i hugo*.deb
|
dpkg -i hugo*.deb
|
||||||
|
|
||||||
echo "Installed Hugo:"
|
echo "Installed Hugo:"
|
||||||
hugo version
|
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
|
# Latex
|
||||||
latexdir=/root/texmf/tex/latex
|
latexdir=/root/texmf/tex/latex
|
||||||
mkdir -p $latexdir
|
mkdir -p $latexdir
|
||||||
|
@ -15,3 +18,6 @@ unzip -j sections.zip -d $latexdir/AltaCV
|
||||||
echo "Install moderncv"
|
echo "Install moderncv"
|
||||||
wget https://github.com/Titan-C/moderncv/archive/master.zip
|
wget https://github.com/Titan-C/moderncv/archive/master.zip
|
||||||
unzip -j master.zip -d $latexdir/moderncv
|
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
|
||||||
|
|
82
org-cv-utils.el
Normal file
82
org-cv-utils.el
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
;;; org-cv-utils.el --- Common utility functions for CV exporters -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
;; Author: 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 some utility functions
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'org)
|
||||||
|
(require 'ox)
|
||||||
|
(require 'org-element)
|
||||||
|
|
||||||
|
(defun org-cv-utils-org-timestamp-to-shortdate (date_str)
|
||||||
|
"Format orgmode timestamp DATE_STR into a short form date.
|
||||||
|
Other strings are just returned unmodified
|
||||||
|
|
||||||
|
e.g. <2012-08-12 Mon> => Aug 2012
|
||||||
|
today => today"
|
||||||
|
(if (string-match (org-re-timestamp 'all) date_str)
|
||||||
|
(let* ((dte (org-parse-time-string date_str))
|
||||||
|
(month (nth 4 dte))
|
||||||
|
(year (nth 5 dte))) ;;'(02 07 2015)))
|
||||||
|
(concat
|
||||||
|
(calendar-month-name month 'abbreviate) " " (number-to-string year)))
|
||||||
|
date_str))
|
||||||
|
|
||||||
|
(defun org-cv-utils--format-time-window (from-date to-date)
|
||||||
|
"Join date strings in a time window.
|
||||||
|
FROM-DATE -- TO-DATE
|
||||||
|
in case TO-DATE is nil return Present.
|
||||||
|
If both dates are the same, return just FROM-DATE"
|
||||||
|
(let ((from (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 (or (string= from to))
|
||||||
|
from
|
||||||
|
(concat from " -- " to))))
|
||||||
|
|
||||||
|
(defun org-cv-utils--parse-cventry (headline info)
|
||||||
|
"Return alist describing the entry in HEADLINE.
|
||||||
|
INFO is a plist used as a communication channel."
|
||||||
|
(let* ((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
|
||||||
|
(user-error "No FROM property provided for cventry %s" title)))
|
||||||
|
(to-date (or (org-element-property :TO headline) date))
|
||||||
|
(host (or (org-element-property :HOST headline)
|
||||||
|
(org-element-property :ORGANIZATION headline)
|
||||||
|
(org-element-property :INSTITUTION headline)
|
||||||
|
(org-element-property :SCHOOL headline)
|
||||||
|
(org-element-property :EMPLOYER headline)
|
||||||
|
(org-element-property :EVENT headline) "")))
|
||||||
|
`((title . ,title)
|
||||||
|
(date . , (org-cv-utils--format-time-window from-date to-date))
|
||||||
|
(host . ,host)
|
||||||
|
(location . ,(or (org-element-property :LOCATION headline) ""))
|
||||||
|
(image . ,(org-element-property :IMAGE headline)))))
|
||||||
|
|
||||||
|
(provide 'org-cv-utils)
|
||||||
|
;;; org-cv-utils.el ends here
|
135
ox-altacv.el
135
ox-altacv.el
|
@ -30,15 +30,16 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
(require 'cl-lib)
|
(require 'cl-lib)
|
||||||
(require 'ox-latex)
|
(require 'ox-latex)
|
||||||
|
(require 'org-cv-utils)
|
||||||
|
|
||||||
;; Install a default set-up for altacv export.
|
;; Install a default set-up for altacv export.
|
||||||
(unless (assoc "altacv" org-latex-classes)
|
(unless (assoc "altacv" org-latex-classes)
|
||||||
(add-to-list 'org-latex-classes
|
(add-to-list 'org-latex-classes
|
||||||
'("altacv"
|
'("altacv"
|
||||||
"\\documentclass{altacv}"
|
"\\documentclass{altacv}"
|
||||||
("\\section{%s}" . "\\section*{%s}")
|
("\n\\section{%s}" . "\n\\section*{%s}")
|
||||||
("\\subsection{%s}" . "\\subsection*{%s}")
|
("\\subsection{%s}" . "\\subsection*{%s}")
|
||||||
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))
|
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))
|
||||||
|
|
||||||
|
|
||||||
;;; User-Configurable Variables
|
;;; User-Configurable Variables
|
||||||
|
@ -66,7 +67,7 @@
|
||||||
(:latex-title-command nil nil "\\begin{fullwidth}\n\\makecvheader\n\\end{fullwidth}")
|
(:latex-title-command nil nil "\\begin{fullwidth}\n\\makecvheader\n\\end{fullwidth}")
|
||||||
)
|
)
|
||||||
:translate-alist '((template . org-altacv-template)
|
:translate-alist '((template . org-altacv-template)
|
||||||
(headline . org-altacv-headline)))
|
(headline . org-altacv-headline)))
|
||||||
|
|
||||||
(defun colorconf ()
|
(defun colorconf ()
|
||||||
"puts color"
|
"puts color"
|
||||||
|
@ -82,8 +83,7 @@
|
||||||
colorlinks=true,
|
colorlinks=true,
|
||||||
urlcolor=olive!50!black!30!green,
|
urlcolor=olive!50!black!30!green,
|
||||||
}
|
}
|
||||||
"
|
")
|
||||||
)
|
|
||||||
;;;; Template
|
;;;; Template
|
||||||
;;
|
;;
|
||||||
;; Template used is similar to the one used in `latex' back-end,
|
;; Template used is similar to the one used in `latex' back-end,
|
||||||
|
@ -94,11 +94,11 @@
|
||||||
CONTENTS is the transcoded contents string. INFO is a plist
|
CONTENTS is the transcoded contents string. INFO is a plist
|
||||||
holding export options."
|
holding export options."
|
||||||
(let ((title (org-export-data (plist-get info :title) info))
|
(let ((title (org-export-data (plist-get info :title) info))
|
||||||
(spec (org-latex--format-spec info)))
|
(spec (org-latex--format-spec info)))
|
||||||
(concat
|
(concat
|
||||||
;; Time-stamp.
|
;; Time-stamp.
|
||||||
(and (plist-get info :time-stamp-file)
|
(and (plist-get info :time-stamp-file)
|
||||||
(format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
|
(format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
|
||||||
;; LaTeX compiler.
|
;; LaTeX compiler.
|
||||||
(org-latex--insert-compiler info)
|
(org-latex--insert-compiler info)
|
||||||
;; Document class and packages.
|
;; Document class and packages.
|
||||||
|
@ -107,20 +107,20 @@ holding export options."
|
||||||
;; Possibly limit depth for headline numbering.
|
;; Possibly limit depth for headline numbering.
|
||||||
(let ((sec-num (plist-get info :section-numbers)))
|
(let ((sec-num (plist-get info :section-numbers)))
|
||||||
(when (integerp sec-num)
|
(when (integerp sec-num)
|
||||||
(format "\\setcounter{secnumdepth}{%d}\n" sec-num)))
|
(format "\\setcounter{secnumdepth}{%d}\n" sec-num)))
|
||||||
|
|
||||||
;; Title and subtitle.
|
;; Title and subtitle.
|
||||||
(let* ((subtitle (plist-get info :subtitle))
|
(let* ((subtitle (plist-get info :subtitle))
|
||||||
(formatted-subtitle
|
(formatted-subtitle
|
||||||
(when subtitle
|
(when subtitle
|
||||||
(format (plist-get info :latex-subtitle-format)
|
(format (plist-get info :latex-subtitle-format)
|
||||||
(org-export-data subtitle info))))
|
(org-export-data subtitle info))))
|
||||||
(separate (plist-get info :latex-subtitle-separate)))
|
(separate (plist-get info :latex-subtitle-separate)))
|
||||||
(concat
|
(concat
|
||||||
(format "\\tagline{%s%s}\n" title
|
(format "\\tagline{%s%s}\n" title
|
||||||
(if separate "" (or formatted-subtitle "")))
|
(if separate "" (or formatted-subtitle "")))
|
||||||
(when (and separate subtitle)
|
(when (and separate subtitle)
|
||||||
(concat formatted-subtitle "\n"))))
|
(concat formatted-subtitle "\n"))))
|
||||||
;; Hyperref options.
|
;; Hyperref options.
|
||||||
(let ((template (plist-get info :latex-hyperref-template)))
|
(let ((template (plist-get info :latex-hyperref-template)))
|
||||||
(and (stringp template)
|
(and (stringp template)
|
||||||
|
@ -129,8 +129,8 @@ holding export options."
|
||||||
"\\begin{document}\n\n"
|
"\\begin{document}\n\n"
|
||||||
;; Author.
|
;; Author.
|
||||||
(let ((author (and (plist-get info :with-author)
|
(let ((author (and (plist-get info :with-author)
|
||||||
(let ((auth (plist-get info :author)))
|
(let ((auth (plist-get info :author)))
|
||||||
(and auth (org-export-data auth info))))))
|
(and auth (org-export-data auth info))))))
|
||||||
(format "\\name{%s}\n" author))
|
(format "\\name{%s}\n" author))
|
||||||
;; photo
|
;; photo
|
||||||
(let ((photo (org-export-data (plist-get info :photo) info)))
|
(let ((photo (org-export-data (plist-get info :photo) info)))
|
||||||
|
@ -139,81 +139,66 @@ holding export options."
|
||||||
"\\personalinfo{\n"
|
"\\personalinfo{\n"
|
||||||
;; address
|
;; address
|
||||||
(let ((address (org-export-data (plist-get info :address) info)))
|
(let ((address (org-export-data (plist-get info :address) info)))
|
||||||
(when (org-string-nw-p address) (format "\\mailaddress{%s}\n"
|
(when (org-string-nw-p address)
|
||||||
(mapconcat (lambda (line) (format "%s" line))
|
(format "\\mailaddress{%s}\n" (mapconcat (lambda (line)
|
||||||
(split-string address "\n") " -- "))))
|
(format "%s" line))
|
||||||
|
(split-string address "\n") " -- "))))
|
||||||
;; email
|
;; email
|
||||||
(let ((email (and (plist-get info :with-email)
|
(let ((email (and (plist-get info :with-email)
|
||||||
(org-export-data (plist-get info :email) info))))
|
(org-export-data (plist-get info :email) info))))
|
||||||
(when email (format "\\email{%s}\n" email)))
|
(when (org-string-nw-p email)
|
||||||
|
(format "\\email{%s}\n" email)))
|
||||||
;; phone
|
;; phone
|
||||||
(let ((mobile (org-export-data (plist-get info :mobile) info)))
|
(let ((mobile (org-export-data (plist-get info :mobile) info)))
|
||||||
(when mobile (format "\\phone{%s}\n" mobile)))
|
(when (org-string-nw-p mobile)
|
||||||
|
(format "\\phone{%s}\n" mobile)))
|
||||||
;; homepage
|
;; homepage
|
||||||
(let ((homepage (org-export-data (plist-get info :homepage) info)))
|
(let ((homepage (org-export-data (plist-get info :homepage) info)))
|
||||||
(when homepage (format "\\homepage{%s}\n" homepage)))
|
(when (org-string-nw-p homepage)
|
||||||
|
(format "\\homepage{%s}\n" homepage)))
|
||||||
(mapconcat (lambda (social-network)
|
(mapconcat (lambda (social-network)
|
||||||
(let ((command (org-export-data (plist-get info
|
(let ((command (org-export-data (plist-get info
|
||||||
(car social-network))
|
(car social-network))
|
||||||
info)))
|
info)))
|
||||||
(and command (format "\\%s{%s}\n"
|
(and command (format "\\%s{%s}\n"
|
||||||
(nth 1 social-network)
|
(nth 1 social-network)
|
||||||
command))))
|
command))))
|
||||||
'((:github "github")
|
'((:github "github")
|
||||||
(:gitlab "gitlab")
|
(:gitlab "gitlab")
|
||||||
(:linkedin "linkedin"))
|
(:linkedin "linkedin"))
|
||||||
"")
|
"")
|
||||||
"}\n"
|
"}\n"
|
||||||
;; Title command.
|
;; Title command.
|
||||||
(let* ((title-command (plist-get info :latex-title-command))
|
(let* ((title-command (plist-get info :latex-title-command))
|
||||||
(command (and (stringp title-command)
|
(command (and (stringp title-command)
|
||||||
(format-spec title-command spec))))
|
(format-spec title-command spec))))
|
||||||
(org-element-normalize-string
|
(org-element-normalize-string
|
||||||
(cond ((not (plist-get info :with-title)) nil)
|
(cond ((not (plist-get info :with-title)) nil)
|
||||||
((string= "" title) nil)
|
((string= "" title) nil)
|
||||||
((not (stringp command)) nil)
|
((not (stringp command)) nil)
|
||||||
((string-match "\\(?:[^%]\\|^\\)%s" command)
|
((string-match "\\(?:[^%]\\|^\\)%s" command)
|
||||||
(format command title))
|
(format command title))
|
||||||
(t command))))
|
(t command))))
|
||||||
;; Document's body.
|
;; Document's body.
|
||||||
contents
|
contents
|
||||||
;; Creator.
|
;; Creator.
|
||||||
(and (plist-get info :with-creator)
|
(and (plist-get info :with-creator)
|
||||||
(concat (plist-get info :creator) "\n"))
|
(concat (plist-get info :creator) "\n"))
|
||||||
;; Document end.
|
;; Document end.
|
||||||
"\\end{document}")))
|
"\\end{document}")))
|
||||||
|
|
||||||
|
|
||||||
(defun org-altacv-timestamp-to-shortdate (date_str)
|
|
||||||
"Format orgmode timestamp DATE_STR into a short form date.
|
|
||||||
|
|
||||||
e.g. <2002-08-12 Mon> => Aug 2012"
|
|
||||||
(let* ((abbreviate 't)
|
|
||||||
(dte (org-parse-time-string date_str))
|
|
||||||
(month (nth 4 dte))
|
|
||||||
(year (nth 5 dte)));;'(02 07 2015)))
|
|
||||||
(concat (calendar-month-name month abbreviate)
|
|
||||||
" "
|
|
||||||
(number-to-string year))))
|
|
||||||
|
|
||||||
(defun org-altacv--format-cventry (headline contents info)
|
(defun org-altacv--format-cventry (headline contents info)
|
||||||
"Format HEADLINE as as cventry.
|
"Format HEADLINE as as cventry.
|
||||||
CONTENTS holds the contents of the headline. INFO is a plist used
|
CONTENTS holds the contents of the headline. INFO is a plist used
|
||||||
as a communication channel."
|
as a communication channel."
|
||||||
(let ((from-date (org-element-property :FROM headline))
|
(let* ((entry (org-cv-utils--parse-cventry headline info))
|
||||||
(to-date (org-element-property :TO headline))
|
(divider (if (org-export-last-sibling-p headline info) "\n" "\\divider")))
|
||||||
(title (org-export-data (org-element-property :title headline) info))
|
(format "\n\\cvevent{%s}{%s}{%s}{%s}%s\n%s\n\n"
|
||||||
(employer (org-element-property :EMPLOYER headline))
|
(alist-get 'title entry)
|
||||||
(location (or (org-element-property :LOCATION headline) ""))
|
(alist-get 'host entry)
|
||||||
(divider (if (org-export-last-sibling-p headline info) "" "\\divider")))
|
(alist-get 'date entry)
|
||||||
(format "\n\\cvevent{%s}{%s}{%s}{%s}%s\n%s"
|
(alist-get 'location entry) contents divider)))
|
||||||
title
|
|
||||||
employer
|
|
||||||
(concat (org-altacv-timestamp-to-shortdate from-date)
|
|
||||||
" -- "
|
|
||||||
(org-altacv-timestamp-to-shortdate to-date))
|
|
||||||
location contents divider)))
|
|
||||||
|
|
||||||
|
|
||||||
;;;; Headline
|
;;;; Headline
|
||||||
(defun org-altacv-headline (headline contents info)
|
(defun org-altacv-headline (headline contents info)
|
||||||
|
@ -221,11 +206,11 @@ as a communication channel."
|
||||||
CONTENTS is the contents of the headline. INFO is a plist used
|
CONTENTS is the contents of the headline. INFO is a plist used
|
||||||
as a communication channel."
|
as a communication channel."
|
||||||
(unless (org-element-property :footnote-section-p headline)
|
(unless (org-element-property :footnote-section-p headline)
|
||||||
(let ((environment (let ((env (org-element-property :CV_ENV headline)))
|
(let ((environment (cons (org-element-property :CV_ENV headline)
|
||||||
(or (org-string-nw-p env) "block"))))
|
(org-export-get-tags headline info))))
|
||||||
(cond
|
(cond
|
||||||
;; is a cv entry
|
;; is a cv entry
|
||||||
((equal environment "cventry")
|
((member "cventry" environment)
|
||||||
(org-altacv--format-cventry headline contents info))
|
(org-altacv--format-cventry headline contents info))
|
||||||
((org-export-with-backend 'latex headline contents info))))))
|
((org-export-with-backend 'latex headline contents info))))))
|
||||||
|
|
||||||
|
|
445
ox-awesomecv.el
Normal file
445
ox-awesomecv.el
Normal file
|
@ -0,0 +1,445 @@
|
||||||
|
;;; 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-red" 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)))
|
||||||
|
|
||||||
|
;; quote
|
||||||
|
(let ((quote (plist-get info :quote)))
|
||||||
|
(when quote
|
||||||
|
(format "\\quote{%s}\n" quote)))
|
||||||
|
|
||||||
|
;; 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
|
||||||
|
(cl-find-if (lambda (s) (or (string-prefix-p "cv" s)
|
||||||
|
(string-prefix-p "letter" s)))
|
||||||
|
(cons (org-element-property :CV_ENV headline)
|
||||||
|
(org-export-get-tags headline info))))
|
||||||
|
(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"
|
||||||
|
title
|
||||||
|
employer
|
||||||
|
location
|
||||||
|
(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 (cons (org-element-property :CV_ENV headline)
|
||||||
|
(org-export-get-tags headline info)))
|
||||||
|
(pagebreak (org-string-nw-p (org-element-property :PAGEBREAK headline))))
|
||||||
|
(concat
|
||||||
|
(when pagebreak "\\clearpage\n")
|
||||||
|
(cond
|
||||||
|
;; is a cv entry or subentry
|
||||||
|
((seq-intersection environment '("cventry"
|
||||||
|
"cvsubentry"
|
||||||
|
"cvemployer"
|
||||||
|
"cvschool"
|
||||||
|
"cvhonor"
|
||||||
|
"cvletter"
|
||||||
|
"cvletter_notitle"
|
||||||
|
"lettersection"
|
||||||
|
"letterheader"))
|
||||||
|
(org-awesomecv--format-cventry headline contents info))
|
||||||
|
((seq-intersection environment '("cventries" "cvhonors"))
|
||||||
|
(org-awesomecv--format-cvenvironment
|
||||||
|
(car (seq-intersection environment '("cventries" "cvhonors"))) 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
|
307
ox-awesomecv2.el
Normal file
307
ox-awesomecv2.el
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
;;; ox-awesomecv2.el --- LaTeX awesomecv Back-End for Org Export Engine -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
;; Author: Oscar Najera <hi AT oscarnajera.com DOT com>
|
||||||
|
;; Maintainer: Óscar Nájera <hi@oscarnajera.com>
|
||||||
|
|
||||||
|
;; 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]"
|
||||||
|
("\n\\cvsection{%s}" . "\n\\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 'awesomecv2 '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-red" 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-cv-awesome2-template)
|
||||||
|
(headline . org-cv-awesome2-headline)
|
||||||
|
(plain-list . org-cv-awesome2-plain-list)
|
||||||
|
(item . org-cv-awesome2-item)
|
||||||
|
(property-drawer . ignore)))
|
||||||
|
|
||||||
|
;;;; Template
|
||||||
|
;;
|
||||||
|
;; Template used is similar to the one used in `latex' back-end,
|
||||||
|
;; excepted for the table of contents and awesomecv themes.
|
||||||
|
|
||||||
|
(defun org-cv-awesome2-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-cv-awesome2--cventry-right-img-code (file)
|
||||||
|
"Include the image on 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-cv-awesome2--entry (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* ((entrytags (org-element-property :tags headline))
|
||||||
|
(element (cl-find-if (lambda (s) (string-prefix-p "cv" s)) entrytags))
|
||||||
|
(entry (org-cv-utils--parse-cventry headline info)))
|
||||||
|
;; Usage: \cvhonor{<position>}{<title>}{<location>}{<date>}
|
||||||
|
;; Usage: \cventry{<position>}{<title>}{<location>}{<date>}{<description>}
|
||||||
|
(if (member element '("cventry" "cvhonor"))
|
||||||
|
(format "\n\\%s%s%s\n"
|
||||||
|
element
|
||||||
|
(mapconcat (lambda (s) (format "{%s}" (alist-get s entry)))
|
||||||
|
'(title host location date)
|
||||||
|
"")
|
||||||
|
(if (string= "cventry" element)
|
||||||
|
(concat "{" contents "}")
|
||||||
|
""))
|
||||||
|
(user-error "Incorrect section %s" (alist-get 'title entry)))))
|
||||||
|
|
||||||
|
;;;; Headlines of type "cventries"
|
||||||
|
(defun org-cv-awesome2--format-cvenvironment (environment headline contents info)
|
||||||
|
"Format HEADLINE 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-cv-awesome2-headline (headline contents info)
|
||||||
|
"Transcode HEADLINE element into moderncv 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 (cons (org-element-property :CV_ENV headline)
|
||||||
|
(org-export-get-tags headline info))))
|
||||||
|
(cond
|
||||||
|
;; is a cv entry
|
||||||
|
((seq-intersection environment '("cventries" "cvhonors"))
|
||||||
|
(org-cv-awesome2--format-cvenvironment
|
||||||
|
(car (seq-intersection environment '("cventries" "cvhonors"))) headline contents info))
|
||||||
|
((seq-intersection environment '("cventry" "cvhonor"))
|
||||||
|
(org-cv-awesome2--entry headline contents info))
|
||||||
|
((org-export-with-backend 'latex headline contents info))))))
|
||||||
|
|
||||||
|
;;;; Plain List, to intercept and transform "cvskills" lists
|
||||||
|
|
||||||
|
(defun org-cv-awesome2-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* ((type (org-element-property :type plain-list))
|
||||||
|
(tags (org-export-get-tags plain-list info nil 'inherited))
|
||||||
|
(parent-type (car (org-element-property :parent plain-list))))
|
||||||
|
(cond
|
||||||
|
((and (eq type 'descriptive) (member "skills" tags))
|
||||||
|
(format "\\begin{cvskills}\n%s\\end{cvskills}" contents))
|
||||||
|
((and (eq parent-type 'section) (seq-intersection tags '("cventry" "cvsubentry" "cvschool")))
|
||||||
|
(format "\\begin{cvitems}\n%s\\end{cvitems}" contents))
|
||||||
|
(t
|
||||||
|
(org-latex-plain-list plain-list contents info)))))
|
||||||
|
|
||||||
|
;;;; Item, to intercept and transform "skills" lists
|
||||||
|
(defun org-cv-awesome2-item (item contents info)
|
||||||
|
"Transcode an ITEM element from Org to awesomecv LaTeX.
|
||||||
|
CONTENTS holds the contents of the item. INFO is a plist holding
|
||||||
|
contextual information."
|
||||||
|
(let* ((env-tags (org-export-get-tags item info nil 'inherited))
|
||||||
|
(label (let ((tag (org-element-property :tag item)))
|
||||||
|
(and tag (org-export-data tag info)))))
|
||||||
|
(if (and (member "skills" env-tags) label)
|
||||||
|
(format "\\cvskill{%s}{%s}\n" label (org-trim contents))
|
||||||
|
(org-latex-item item contents info))))
|
||||||
|
|
||||||
|
(provide 'ox-awesomecv2)
|
||||||
|
;;; ox-awesomecv2.el ends here
|
121
ox-hugocv.el
121
ox-hugocv.el
|
@ -1,5 +1,6 @@
|
||||||
;;; ox-hugocv.el --- LaTeX hugocv Back-End for Org Export Engine -*- lexical-binding: t; -*-
|
;;; ox-hugocv.el --- LaTeX hugocv Back-End for Org Export Engine -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Package-Requires: ((emacs "28.1") (dash "2.19.1"))
|
||||||
;; Copyright (C) 2018 Free Software Foundation, Inc.
|
;; Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;; Author: Oscar Najera <hi AT oscarnajera.com DOT com>
|
;; Author: Oscar Najera <hi AT oscarnajera.com DOT com>
|
||||||
|
@ -29,11 +30,13 @@
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
(require 'ox-hugo)
|
(require 'ox-hugo)
|
||||||
|
(require 'dash)
|
||||||
|
(require 'org-cv-utils)
|
||||||
|
|
||||||
;;; User-Configurable Variables
|
;;; User-Configurable Variables
|
||||||
|
|
||||||
(defgroup org-export-hugocv nil
|
(defgroup org-export-hugocv nil
|
||||||
"Options for exporting Org mode files to Hugo-compatible Markdown"
|
"Options for exporting Org mode files to Hugo-compatible Markdown."
|
||||||
:tag "Org Export Hugo CV"
|
:tag "Org Export Hugo CV"
|
||||||
:group 'org-export
|
:group 'org-export
|
||||||
:version "25.3")
|
:version "25.3")
|
||||||
|
@ -41,107 +44,67 @@
|
||||||
;;; Define Back-End
|
;;; Define Back-End
|
||||||
(org-export-define-derived-backend 'hugocv 'hugo
|
(org-export-define-derived-backend 'hugocv 'hugo
|
||||||
:options-alist
|
:options-alist
|
||||||
'(
|
'((:mobile "MOBILE" nil nil parse)
|
||||||
(:mobile "MOBILE" nil nil parse)
|
|
||||||
(:homepage "HOMEPAGE" nil nil parse)
|
(:homepage "HOMEPAGE" nil nil parse)
|
||||||
(:address "ADDRESS" nil nil newline)
|
(:address "ADDRESS" nil nil newline)
|
||||||
(:photo "PHOTO" nil nil parse)
|
(:photo "PHOTO" nil nil parse)
|
||||||
(:gitlab "GITLAB" nil nil parse)
|
(:gitlab "GITLAB" nil nil parse)
|
||||||
(:github "GITHUB" nil nil parse)
|
(:github "GITHUB" nil nil parse)
|
||||||
(:linkedin "LINKEDIN" nil nil parse)
|
(:linkedin "LINKEDIN" nil nil parse)
|
||||||
(:with-email nil "email" t t)
|
(:with-email nil "email" t t))
|
||||||
)
|
:translate-alist '((headline . org-hugocv-headline)))
|
||||||
:translate-alist '((headline . org-hugocv-headline)
|
|
||||||
(inner-template . org-hugocv-inner-template)))
|
|
||||||
|
|
||||||
(defun org-hugocv-timestamp-to-shortdate (date_str)
|
(defun org-hugocv--entry-with-icon (field entry)
|
||||||
"Format orgmode timestamp DATE_STR into a short form date.
|
"HTML entry for given FIELD when it is specified in ENTRY."
|
||||||
|
(cl-ecase field
|
||||||
e.g. <2002-08-12 Mon> => Aug 2012"
|
(host
|
||||||
(let* ((abbreviate 't)
|
(-some->> (alist-get 'host entry)
|
||||||
(dte (org-parse-time-string date_str))
|
(org-string-nw-p)
|
||||||
(month (nth 4 dte))
|
(format "%s\n{.cv-host}")))
|
||||||
(year (nth 5 dte)));;'(02 07 2015)))
|
(date
|
||||||
(concat (calendar-month-name month abbreviate)
|
(-some->>
|
||||||
" "
|
(alist-get 'date entry)
|
||||||
(number-to-string year))))
|
(format "%s\n{.cv-date}")))
|
||||||
|
(location
|
||||||
|
(-some->> (alist-get 'location entry)
|
||||||
|
(org-string-nw-p)
|
||||||
|
(format "%s\n{.cv-location}")))))
|
||||||
|
|
||||||
(defun org-hugocv--format-cventry (headline contents info)
|
(defun org-hugocv--format-cventry (headline contents info)
|
||||||
"Format HEADLINE as as cventry.
|
"Format HEADLINE as as cventry.
|
||||||
CONTENTS holds the contents of the headline. INFO is a plist used
|
CONTENTS holds the contents of the headline. INFO is a plist used
|
||||||
as a communication channel."
|
as a communication channel."
|
||||||
(let ((from-date (org-element-property :FROM headline))
|
(let* ((environment (org-export-get-tags headline info))
|
||||||
(to-date (org-element-property :TO headline))
|
(env-class (replace-regexp-in-string "^cv" "" (cl-find-if (lambda (s) (string-prefix-p "cv" s)) environment)))
|
||||||
(title (org-export-data (org-element-property :title headline) info))
|
(entry (org-cv-utils--parse-cventry headline info))
|
||||||
(employer (org-element-property :EMPLOYER headline))
|
(loffset (string-to-number (plist-get info :hugo-level-offset))) ;"" -> 0, "0" -> 0, "1" -> 1, ..
|
||||||
(location (or (org-element-property :LOCATION headline) "")))
|
(level (org-export-get-relative-level headline info))
|
||||||
(format "\n<div class=\"cventry\">
|
(title (concat (make-string (+ loffset level) ?#) " "
|
||||||
<h3>%s</h3>
|
(alist-get 'title entry)
|
||||||
<ul>
|
" {.cv-role}")))
|
||||||
<li class=\"fas fa-building\"> %s</li>
|
(format "<div class=\"cv-%s\">\n\n%s\n\n%s\n\n%s\n</div>"
|
||||||
<li class=\"fas fa-map-marker-alt\"> %s</li>
|
env-class
|
||||||
<li class=\"far fa-calendar\"> %s</li>
|
|
||||||
<ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
%s
|
|
||||||
"
|
|
||||||
title
|
title
|
||||||
employer
|
(mapconcat (lambda (field) (org-hugocv--entry-with-icon field entry))
|
||||||
location
|
'(host date location)
|
||||||
(concat (org-hugocv-timestamp-to-shortdate from-date)
|
"\n")
|
||||||
" -- "
|
|
||||||
(org-hugocv-timestamp-to-shortdate to-date))
|
|
||||||
contents)))
|
contents)))
|
||||||
|
|
||||||
|
|
||||||
;;;; Headline
|
;;;; Headline
|
||||||
(defun org-hugocv-headline (headline contents info)
|
(defun org-hugocv-headline (headline contents info)
|
||||||
"Transcode HEADLINE element into hugocv code.
|
"Transcode HEADLINE element into hugocv code.
|
||||||
CONTENTS is the contents of the headline. INFO is a plist used
|
CONTENTS is the contents of the headline. INFO is a plist used
|
||||||
as a communication channel."
|
as a communication channel."
|
||||||
(unless (org-element-property :footnote-section-p headline)
|
(unless (org-element-property :footnote-section-p headline)
|
||||||
(let ((environment (let ((env (org-element-property :CV_ENV headline)))
|
(let ((environment (cons (org-element-property :CV_ENV headline)
|
||||||
(or (org-string-nw-p env) "block"))))
|
(org-export-get-tags headline info))))
|
||||||
(cond
|
(cond
|
||||||
;; is a cv entry
|
((cl-find-if (lambda (s) (and (string-prefix-p "cv" s)
|
||||||
((equal environment "cventry")
|
;; avoid conflict with awesomecv block environments
|
||||||
|
(not (member s '("cventries" "cvhonors")))))
|
||||||
|
environment)
|
||||||
(org-hugocv--format-cventry headline contents info))
|
(org-hugocv--format-cventry headline contents info))
|
||||||
((org-export-with-backend 'hugo headline contents info))))))
|
((org-export-with-backend 'hugo headline contents info))))))
|
||||||
|
|
||||||
(defun org-hugocv-inner-template (contents info)
|
|
||||||
"Return body of document after converting it to Hugo-compatible Markdown.
|
|
||||||
CONTENTS is the transcoded contents string. INFO is a plist
|
|
||||||
holding export options."
|
|
||||||
(concat "<ul id=\"cvcontacts\">\n"
|
|
||||||
;; email
|
|
||||||
(let ((email (and (plist-get info :with-email)
|
|
||||||
(org-export-data (plist-get info :email) info))))
|
|
||||||
(when email (format "<a href=\"mailto:%s\"><li class=\"far fa-envelope\"></li> %s</a>\n" email email)))
|
|
||||||
;; homepage
|
|
||||||
(let ((homepage (org-export-data (plist-get info :homepage) info)))
|
|
||||||
(when homepage (format "<a href=\"https://%s\"><li class=\"fas fa-globe\"></li> %s</a>\n" homepage homepage)))
|
|
||||||
;; social media
|
|
||||||
(mapconcat (lambda (social-network)
|
|
||||||
|
|
||||||
(let ((command (org-export-data (plist-get info
|
|
||||||
(car social-network))
|
|
||||||
|
|
||||||
info)))
|
|
||||||
|
|
||||||
(and command (format "<a href=\"https://%s/%s\"><li class=\"fab fa-%s\"></li> %s</a>\n"
|
|
||||||
(nth 2 social-network)
|
|
||||||
command
|
|
||||||
(nth 1 social-network)
|
|
||||||
command))))
|
|
||||||
|
|
||||||
'((:github "github" "www.github.com")
|
|
||||||
(:gitlab "gitlab" "www.gitlab.com")
|
|
||||||
(:linkedin "linkedin" "www.linkedin.com/in"))
|
|
||||||
"")
|
|
||||||
"</ul>\n\n"
|
|
||||||
(org-hugo-inner-template contents info)))
|
|
||||||
|
|
||||||
|
|
||||||
(provide 'ox-hugocv)
|
(provide 'ox-hugocv)
|
||||||
;;; ox-hugocv ends here
|
;;; ox-hugocv.el ends here
|
||||||
|
|
134
ox-moderncv.el
134
ox-moderncv.el
|
@ -30,15 +30,16 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
(require 'cl-lib)
|
(require 'cl-lib)
|
||||||
(require 'ox-latex)
|
(require 'ox-latex)
|
||||||
|
(require 'org-cv-utils)
|
||||||
|
|
||||||
;; Install a default set-up for moderncv export.
|
;; Install a default set-up for moderncv export.
|
||||||
(unless (assoc "moderncv" org-latex-classes)
|
(unless (assoc "moderncv" org-latex-classes)
|
||||||
(add-to-list 'org-latex-classes
|
(add-to-list 'org-latex-classes
|
||||||
'("moderncv"
|
'("moderncv"
|
||||||
"\\documentclass{moderncv}"
|
"\\documentclass{moderncv}"
|
||||||
("\\section{%s}" . "\\section*{%s}")
|
("\\section{%s}" . "\\section*{%s}")
|
||||||
("\\subsection{%s}" . "\\subsection*{%s}")
|
("\\subsection{%s}" . "\\subsection*{%s}")
|
||||||
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))
|
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))
|
||||||
|
|
||||||
|
|
||||||
;;; User-Configurable Variables
|
;;; User-Configurable Variables
|
||||||
|
@ -65,7 +66,7 @@
|
||||||
(:with-email nil "email" t t)
|
(:with-email nil "email" t t)
|
||||||
)
|
)
|
||||||
:translate-alist '((template . org-moderncv-template)
|
:translate-alist '((template . org-moderncv-template)
|
||||||
(headline . org-moderncv-headline)))
|
(headline . org-moderncv-headline)))
|
||||||
|
|
||||||
|
|
||||||
;;;; Template
|
;;;; Template
|
||||||
|
@ -78,11 +79,11 @@
|
||||||
CONTENTS is the transcoded contents string. INFO is a plist
|
CONTENTS is the transcoded contents string. INFO is a plist
|
||||||
holding export options."
|
holding export options."
|
||||||
(let ((title (org-export-data (plist-get info :title) info))
|
(let ((title (org-export-data (plist-get info :title) info))
|
||||||
(spec (org-latex--format-spec info)))
|
(spec (org-latex--format-spec info)))
|
||||||
(concat
|
(concat
|
||||||
;; Time-stamp.
|
;; Time-stamp.
|
||||||
(and (plist-get info :time-stamp-file)
|
(and (plist-get info :time-stamp-file)
|
||||||
(format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
|
(format-time-string "%% Created %Y-%m-%d %a %H:%M\n"))
|
||||||
;; LaTeX compiler.
|
;; LaTeX compiler.
|
||||||
(org-latex--insert-compiler info)
|
(org-latex--insert-compiler info)
|
||||||
;; Document class and packages.
|
;; Document class and packages.
|
||||||
|
@ -92,44 +93,49 @@ holding export options."
|
||||||
(when cvstyle (format "\\moderncvstyle{%s}\n" cvstyle)))
|
(when cvstyle (format "\\moderncvstyle{%s}\n" cvstyle)))
|
||||||
;; cvcolor
|
;; cvcolor
|
||||||
(let ((cvcolor (org-export-data (plist-get info :cvcolor) info)))
|
(let ((cvcolor (org-export-data (plist-get info :cvcolor) info)))
|
||||||
(when cvcolor (format "\\moderncvcolor{%s}\n" cvcolor)))
|
(when (not (string-empty-p cvcolor)) (format "\\moderncvcolor{%s}\n" cvcolor)))
|
||||||
;; Possibly limit depth for headline numbering.
|
;; Possibly limit depth for headline numbering.
|
||||||
(let ((sec-num (plist-get info :section-numbers)))
|
(let ((sec-num (plist-get info :section-numbers)))
|
||||||
(when (integerp sec-num)
|
(when (integerp sec-num)
|
||||||
(format "\\setcounter{secnumdepth}{%d}\n" sec-num)))
|
(format "\\setcounter{secnumdepth}{%d}\n" sec-num)))
|
||||||
;; Author.
|
;; Author.
|
||||||
(let ((author (and (plist-get info :with-author)
|
(let ((author (and (plist-get info :with-author)
|
||||||
(let ((auth (plist-get info :author)))
|
(let ((auth (plist-get info :author)))
|
||||||
(and auth (org-export-data auth info))))))
|
(and auth (org-export-data auth info))))))
|
||||||
(format "\\name{%s}{}\n" author))
|
(format "\\name{%s}{}\n" author))
|
||||||
;; photo
|
;; photo
|
||||||
(let ((photo (org-export-data (plist-get info :photo) info)))
|
(let ((photo (org-export-data (plist-get info :photo) info)))
|
||||||
(when (org-string-nw-p photo) (format "\\photo{%s}\n" photo)))
|
(when (org-string-nw-p photo)
|
||||||
|
(format "\\photo{%s}\n" photo)))
|
||||||
;; email
|
;; email
|
||||||
(let ((email (and (plist-get info :with-email)
|
(let ((email (and (plist-get info :with-email)
|
||||||
(org-export-data (plist-get info :email) info))))
|
(org-export-data (plist-get info :email) info))))
|
||||||
(when email (format "\\email{%s}\n" email)))
|
(when (org-string-nw-p email)
|
||||||
|
(format "\\email{%s}\n" email)))
|
||||||
;; phone
|
;; phone
|
||||||
(let ((mobile (org-export-data (plist-get info :mobile) info)))
|
(let ((mobile (org-export-data (plist-get info :mobile) info)))
|
||||||
(when mobile (format "\\phone[mobile]{%s}\n" mobile)))
|
(when (org-string-nw-p mobile)
|
||||||
|
(format "\\phone[mobile]{%s}\n" mobile)))
|
||||||
;; homepage
|
;; homepage
|
||||||
(let ((homepage (org-export-data (plist-get info :homepage) info)))
|
(let ((homepage (org-export-data (plist-get info :homepage) info)))
|
||||||
(when homepage (format "\\homepage{%s}\n" homepage)))
|
(when (org-string-nw-p homepage)
|
||||||
|
(format "\\homepage{%s}\n" homepage)))
|
||||||
;; address
|
;; address
|
||||||
(let ((address (org-export-data (plist-get info :address) info)))
|
(let ((address (org-export-data (plist-get info :address) info)))
|
||||||
(when address (format "\\address%s\n" (mapconcat (lambda (line) (format "{%s}" line))
|
(when (org-string-nw-p address)
|
||||||
(split-string address "\n") ""))))
|
(format "\\address%s\n" (mapconcat (lambda (line)
|
||||||
|
(format "{%s}" line))
|
||||||
|
(split-string address "\n") ""))))
|
||||||
(mapconcat (lambda (social-network)
|
(mapconcat (lambda (social-network)
|
||||||
(let ((command (org-export-data (plist-get info
|
(let ((network (org-export-data
|
||||||
(car social-network))
|
(plist-get info (car social-network)) info)))
|
||||||
info)))
|
(when (org-string-nw-p network)
|
||||||
(and command (format "\\social[%s]{%s}\n"
|
(format "\\social[%s]{%s}\n"
|
||||||
(nth 1 social-network)
|
(nth 1 social-network) network))))
|
||||||
command))))
|
'((:github "github")
|
||||||
'((:github "github")
|
(:gitlab "gitlab")
|
||||||
(:gitlab "gitlab")
|
(:linkedin "linkedin"))
|
||||||
(:linkedin "linkedin"))
|
"")
|
||||||
"")
|
|
||||||
|
|
||||||
;; Date.
|
;; Date.
|
||||||
(let ((date (and (plist-get info :with-date) (org-export-get-date info))))
|
(let ((date (and (plist-get info :with-date) (org-export-get-date info))))
|
||||||
|
@ -137,16 +143,16 @@ holding export options."
|
||||||
|
|
||||||
;; Title and subtitle.
|
;; Title and subtitle.
|
||||||
(let* ((subtitle (plist-get info :subtitle))
|
(let* ((subtitle (plist-get info :subtitle))
|
||||||
(formatted-subtitle
|
(formatted-subtitle
|
||||||
(when subtitle
|
(when subtitle
|
||||||
(format (plist-get info :latex-subtitle-format)
|
(format (plist-get info :latex-subtitle-format)
|
||||||
(org-export-data subtitle info))))
|
(org-export-data subtitle info))))
|
||||||
(separate (plist-get info :latex-subtitle-separate)))
|
(separate (plist-get info :latex-subtitle-separate)))
|
||||||
(concat
|
(concat
|
||||||
(format "\\title{%s%s}\n" title
|
(format "\\title{%s%s}\n" title
|
||||||
(if separate "" (or formatted-subtitle "")))
|
(if separate "" (or formatted-subtitle "")))
|
||||||
(when (and separate subtitle)
|
(when (and separate subtitle)
|
||||||
(concat formatted-subtitle "\n"))))
|
(concat formatted-subtitle "\n"))))
|
||||||
;; Hyperref options.
|
;; Hyperref options.
|
||||||
(let ((template (plist-get info :latex-hyperref-template)))
|
(let ((template (plist-get info :latex-hyperref-template)))
|
||||||
(and (stringp template)
|
(and (stringp template)
|
||||||
|
@ -158,49 +164,33 @@ holding export options."
|
||||||
(command (and (stringp title-command)
|
(command (and (stringp title-command)
|
||||||
(format-spec title-command spec))))
|
(format-spec title-command spec))))
|
||||||
(org-element-normalize-string
|
(org-element-normalize-string
|
||||||
(cond ((not (plist-get info :with-title)) nil)
|
(cond ((not (plist-get info :with-title)) nil)
|
||||||
((string= "" title) nil)
|
((string= "" title) nil)
|
||||||
((not (stringp command)) nil)
|
((not (stringp command)) nil)
|
||||||
((string-match "\\(?:[^%]\\|^\\)%s" command)
|
((string-match "\\(?:[^%]\\|^\\)%s" command)
|
||||||
(format command title))
|
(format command title))
|
||||||
(t command))))
|
(t command))))
|
||||||
;; Document's body.
|
;; Document's body.
|
||||||
contents
|
contents
|
||||||
;; Creator.
|
;; Creator.
|
||||||
(and (plist-get info :with-creator)
|
(and (plist-get info :with-creator)
|
||||||
(concat (plist-get info :creator) "\n"))
|
(concat (plist-get info :creator) "\n"))
|
||||||
;; Document end.
|
;; Document end.
|
||||||
"\\end{document}")))
|
"\\end{document}")))
|
||||||
|
|
||||||
|
|
||||||
(defun org-moderncv-timestamp-to-shortdate (date_str)
|
|
||||||
"Format orgmode timestamp DATE_STR into a short form date.
|
|
||||||
|
|
||||||
e.g. <2002-08-12 Mon> => Aug 2012"
|
|
||||||
(let* ((abbreviate 't)
|
|
||||||
(dte (org-parse-time-string date_str))
|
|
||||||
(month (nth 4 dte))
|
|
||||||
(year (nth 5 dte)));;'(02 07 2015)))
|
|
||||||
(concat (calendar-month-name month abbreviate)
|
|
||||||
" "
|
|
||||||
(number-to-string year))))
|
|
||||||
|
|
||||||
(defun org-moderncv--format-cventry (headline contents info)
|
(defun org-moderncv--format-cventry (headline contents info)
|
||||||
"Format HEADLINE as as cventry.
|
"Format HEADLINE as as cventry.
|
||||||
CONTENTS holds the contents of the headline. INFO is a plist used
|
CONTENTS holds the contents of the headline. INFO is a plist used
|
||||||
as a communication channel."
|
as a communication channel."
|
||||||
(let ((from-date (org-element-property :FROM headline))
|
(let* ((entry (org-cv-utils--parse-cventry headline info))
|
||||||
(to-date (org-element-property :TO headline))
|
(note (or (org-element-property :NOTE headline) "")))
|
||||||
(title (org-export-data (org-element-property :title headline) info))
|
(format "\\cventry{%s}{%s}{%s}{%s}{%s}{%s}\n"
|
||||||
(employer (org-element-property :EMPLOYER headline))
|
(alist-get 'date entry)
|
||||||
(location (or (org-element-property :LOCATION headline) ""))
|
(alist-get 'title entry)
|
||||||
(note (or (org-element-property :NOTE headline) "")))
|
(alist-get 'host entry)
|
||||||
(format "\\cventry{\\textbf{%s}}{%s}{%s}{%s}{%s}{%s}\n"
|
(alist-get 'location entry)
|
||||||
(concat (org-moderncv-timestamp-to-shortdate from-date)
|
note contents)))
|
||||||
" -- "
|
|
||||||
(org-moderncv-timestamp-to-shortdate to-date))
|
|
||||||
title employer location note contents)))
|
|
||||||
|
|
||||||
|
|
||||||
;;;; Headline
|
;;;; Headline
|
||||||
(defun org-moderncv-headline (headline contents info)
|
(defun org-moderncv-headline (headline contents info)
|
||||||
|
@ -208,11 +198,11 @@ as a communication channel."
|
||||||
CONTENTS is the contents of the headline. INFO is a plist used
|
CONTENTS is the contents of the headline. INFO is a plist used
|
||||||
as a communication channel."
|
as a communication channel."
|
||||||
(unless (org-element-property :footnote-section-p headline)
|
(unless (org-element-property :footnote-section-p headline)
|
||||||
(let ((environment (let ((env (org-element-property :CV_ENV headline)))
|
(let ((environment (cons (org-element-property :CV_ENV headline)
|
||||||
(or (org-string-nw-p env) "block"))))
|
(org-export-get-tags headline info))))
|
||||||
(cond
|
(cond
|
||||||
;; is a cv entry
|
;; is a cv entry
|
||||||
((equal environment "cventry")
|
((member "cventry" environment)
|
||||||
(org-moderncv--format-cventry headline contents info))
|
(org-moderncv--format-cventry headline contents info))
|
||||||
((org-export-with-backend 'latex headline contents info))))))
|
((org-export-with-backend 'latex headline contents info))))))
|
||||||
|
|
||||||
|
|
354
readme.org
354
readme.org
|
@ -10,15 +10,18 @@
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:EXPORT_FILE_NAME: goal
|
:EXPORT_FILE_NAME: goal
|
||||||
:END:
|
:END:
|
||||||
This project aims to generate from an org-mode file with reasonably ordered
|
This project exports an org-mode file with reasonably structured items into
|
||||||
items a latex file which compiles into a reasonably nice CV. In the same
|
a latex file, which compiles into a nice CV. In the same spirit the
|
||||||
spirit the org-mode file must export to markdown so that it can be uses for
|
org-mode file may export to markdown so that it can be used for a web based
|
||||||
web based CV.
|
CV.
|
||||||
|
|
||||||
- Online documentation in [[https://titan-c.gitlab.io/org-cv/]]
|
- Online documentation in [[https://titan-c.gitlab.io/org-cv/]]
|
||||||
- Development happens in the gitlab repository: https://gitlab.com/Titan-C/org-cv
|
- Development happens in the gitlab repository: https://gitlab.com/Titan-C/org-cv
|
||||||
- There is a mirror in github for backup: https://github.com/Titan-C/org-cv
|
- There is a mirror in github for backup: https://github.com/Titan-C/org-cv
|
||||||
|
|
||||||
|
This project dog feeds itself and produces the examples on this
|
||||||
|
documentation page directly.
|
||||||
|
|
||||||
* Installation
|
* Installation
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:EXPORT_FILE_NAME: installation
|
:EXPORT_FILE_NAME: installation
|
||||||
|
@ -52,7 +55,7 @@ put your foreseen job.
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
|----------+----------------------------------------------------|
|
|----------+----------------------------------------------------|
|
||||||
| TITLE | Desired job |
|
| TITLE | Desired job |
|
||||||
| AUTHOR | Who you are? |
|
| AUTHOR | Who are you? |
|
||||||
| EMAIL | Your contact email |
|
| EMAIL | Your contact email |
|
||||||
| ADDRESS | Mailing address, this can span over multiple lines |
|
| ADDRESS | Mailing address, this can span over multiple lines |
|
||||||
| HOMEPAGE | URL of your website |
|
| HOMEPAGE | URL of your website |
|
||||||
|
@ -63,9 +66,10 @@ put your foreseen job.
|
||||||
| PHOTO | path to photo file |
|
| PHOTO | path to photo file |
|
||||||
|
|
||||||
#+BEGIN_SRC org :tangle basic_cv.org
|
#+BEGIN_SRC org :tangle basic_cv.org
|
||||||
,#+TITLE: My dream job
|
,#+TITLE: My dream job an ORG-CV example
|
||||||
,#+AUTHOR: John Doe
|
,#+AUTHOR: John Doe
|
||||||
,#+email: john@doe.lost
|
,#+email: john@doe.lost
|
||||||
|
,#+options: tags:nil
|
||||||
|
|
||||||
,#+ADDRESS: My Awesome crib
|
,#+ADDRESS: My Awesome crib
|
||||||
,#+ADDRESS: Fantastic city -- Planet Earth
|
,#+ADDRESS: Fantastic city -- Planet Earth
|
||||||
|
@ -78,13 +82,22 @@ put your foreseen job.
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
You can use org-modes hierarchical structure to describe your CV. To make a
|
You can use org-modes hierarchical structure to describe your CV. To make a
|
||||||
specific subtree an item describing an experience point (Job you have,
|
specific sub-tree an item describing an experience point (Job you have, degree
|
||||||
degree you pursued, etc.) you use the org properties drawer and with the
|
you pursued, etc.) you use the org properties drawer and with the =:CV_ENV:
|
||||||
=:CV_ENV: cventry= property. You should also include the =FROM= and =TO=
|
cventry= property. You should also include the =FROM= and =TO= properties
|
||||||
properties defining the span of the event, as =LOCATION= and =EMPLOYER=.
|
defining the span of the entry, as well as =LOCATION= and =EMPLOYER=.
|
||||||
|
|
||||||
|
Because work isn't everything we do, it is more meaningful to label differently
|
||||||
|
the host of those other events like studies, events, certifications, etc. Thus
|
||||||
|
=HOST=, =ORGANIZATION=, =INSTITUTION=, =SCHOOL=, =EMPLOYER= or =EVENT= are all
|
||||||
|
equivalent and the first match in that order has precedence.
|
||||||
|
|
||||||
|
=DATE= is a shortcut for =FROM= and =TO= when you have a single date in mind
|
||||||
|
instead of a range. Both =FROM= and =TO= override =DATE=.
|
||||||
|
|
||||||
#+BEGIN_SRC org :tangle workcontent.org
|
#+BEGIN_SRC org :tangle workcontent.org
|
||||||
,* Employement
|
,* Employement :cventries:
|
||||||
,** One job
|
,** One job :cventry:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CV_ENV: cventry
|
:CV_ENV: cventry
|
||||||
:FROM: <2014-09-01>
|
:FROM: <2014-09-01>
|
||||||
|
@ -94,9 +107,8 @@ properties defining the span of the event, as =LOCATION= and =EMPLOYER=.
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
I write about awesome stuff I do.
|
I write about awesome stuff I do.
|
||||||
,** Other job
|
,** Other job :cventry:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CV_ENV: cventry
|
|
||||||
:FROM: <2013-09-01>
|
:FROM: <2013-09-01>
|
||||||
:TO: <2014-08-07>
|
:TO: <2014-08-07>
|
||||||
:LOCATION: my city, your country
|
:LOCATION: my city, your country
|
||||||
|
@ -117,11 +129,11 @@ I write about awesome stuff I do.
|
||||||
|
|
||||||
** Using modern-cv
|
** Using modern-cv
|
||||||
[[https://www.ctan.org/tex-archive/macros/latex/contrib/moderncv][moderncv]] is a standard \(\LaTeX\) package that you can find in many of your
|
[[https://www.ctan.org/tex-archive/macros/latex/contrib/moderncv][moderncv]] is a standard \(\LaTeX\) package that you can find in many of your
|
||||||
latex distributions. For I maintain for personal purposes a fork of it to
|
latex distributions. I maintain a fork of it, to work with my use case at
|
||||||
better work with my use case at https://github.com/Titan-C/moderncv.git
|
https://github.com/Titan-C/moderncv.git Feel free to use any or even your
|
||||||
Feel free to use any or even your personal fork for your desired use case.
|
personal fork for your desired use case.
|
||||||
|
|
||||||
To configure the export for moderncv you need the addition options in your
|
To configure the export for moderncv you need the additional options in your
|
||||||
org file.
|
org file.
|
||||||
#+BEGIN_SRC org :tangle moderncv.org
|
#+BEGIN_SRC org :tangle moderncv.org
|
||||||
# CV theme - options include: 'casual' (default), 'classic', 'oldstyle' and 'banking'
|
# CV theme - options include: 'casual' (default), 'classic', 'oldstyle' and 'banking'
|
||||||
|
@ -213,6 +225,219 @@ When exporting you can call the following function to get the latex file.
|
||||||
</object>
|
</object>
|
||||||
#+END_EXPORT
|
#+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
|
* Markdown Hugo Exporter
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:EXPORT_FILE_NAME: hugo_export
|
:EXPORT_FILE_NAME: hugo_export
|
||||||
|
@ -228,9 +453,98 @@ exclude some tags during export.
|
||||||
(org-export-to-file 'hugocv "hugocv.md"))
|
(org-export-to-file 'hugocv "hugocv.md"))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
You are responsible for styling your website. Icons used here use
|
You are responsible for styling your website. Use all the CSS magic you know.
|
||||||
FontAwesome 5.
|
Each entry is inside a =div= container and each element of the properties has
|
||||||
|
its own class.
|
||||||
|
|
||||||
|
Make sure that your hugo config has the markup parser attributes active and allows
|
||||||
|
for html rendering.
|
||||||
|
#+begin_src yaml
|
||||||
|
markup:
|
||||||
|
goldmark:
|
||||||
|
renderer:
|
||||||
|
unsafe: true
|
||||||
|
parser:
|
||||||
|
attribute:
|
||||||
|
title: true
|
||||||
|
block: true
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
# Next block is to generate exports
|
||||||
|
#+BEGIN_SRC org :exports none :tangle hugocv.org
|
||||||
|
,#+hugo_custom_front_matter: :weight 1006
|
||||||
|
,#+include: basic_cv.org
|
||||||
|
,#+include: workcontent.org
|
||||||
|
|
||||||
|
# (org-export-to-file 'hugocv "doc/content/post/cv.md")
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
You can also use an awards section for a different styling. Here you tag each
|
||||||
|
entry with =cvhonor=.
|
||||||
|
#+BEGIN_SRC org :tangle hugocv.org
|
||||||
|
,* Awards
|
||||||
|
,** First place :cvhonor:
|
||||||
|
:PROPERTIES:
|
||||||
|
:CV_ENV: cventry
|
||||||
|
:DATE: <2014-09-01>
|
||||||
|
:LOCATION: a city, a country
|
||||||
|
:EVENT: The RACE
|
||||||
|
:END:
|
||||||
|
|
||||||
|
,** Sport Scholarship :cvhonor:
|
||||||
|
:PROPERTIES:
|
||||||
|
:DATE: <2013-09-01>
|
||||||
|
:LOCATION: my city, your country
|
||||||
|
:ORGANIZATION: The nice millionaire
|
||||||
|
:END:
|
||||||
|
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Next is the rendered result for the special entries with styling.
|
||||||
|
* CV
|
||||||
|
:PROPERTIES:
|
||||||
|
:EXPORT_FILE_NAME: cv
|
||||||
|
:END:
|
||||||
|
Place holder stuff
|
||||||
|
* License
|
||||||
|
:PROPERTIES:
|
||||||
|
:EXPORT_FILE_NAME: license
|
||||||
|
:END:
|
||||||
|
#+begin_quote
|
||||||
|
org-cv
|
||||||
|
Copyright (C) 2018-2023 Óscar Nájera
|
||||||
|
|
||||||
|
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 of the License, 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.
|
||||||
|
#+end_quote
|
||||||
|
|
||||||
|
* Tips
|
||||||
|
:PROPERTIES:
|
||||||
|
:EXPORT_FILE_NAME: tips
|
||||||
|
:END:
|
||||||
|
|
||||||
|
If you have found this project useful. Please consider giving back. You can
|
||||||
|
kindly tip me for this project
|
||||||
|
|
||||||
|
- Stellar :: GDPTOFND6HSE5AVHPRXOCJFOA6NPFB65JAEWKTN23EBUGBB2AU4PLIBD
|
||||||
|
- liberapay :: [[https://liberapay.com/Titan-C/][Titan-C]]
|
||||||
|
|
||||||
|
|
||||||
|
#+BEGIN_EXPORT md
|
||||||
|
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
|
||||||
|
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||||
|
<input type="hidden" name="hosted_button_id" value="Y3VB5VL7PD3QC" />
|
||||||
|
<input type="image" src="https://www.paypalobjects.com/en_US/DK/i/btn/btn_donateCC_LG.gif" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Donate with PayPal button" />
|
||||||
|
<img alt="" border="0" src="https://www.paypal.com/en_DE/i/scr/pixel.gif" width="1" height="1" />
|
||||||
|
</form>
|
||||||
|
#+END_EXPORT
|
||||||
|
|
||||||
* Local Variables :ARCHIVE:
|
* Local Variables :ARCHIVE:
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
|
|
31
test-org-cv.el
Normal file
31
test-org-cv.el
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
;;; test-org-cv.el --- Test Org-cv -*- lexical-binding: t; -*-
|
||||||
|
;;
|
||||||
|
;; Copyright (C) 2022 Óscar Nájera
|
||||||
|
;;
|
||||||
|
;; Author: Óscar Nájera <hi@oscarnajera.com>
|
||||||
|
;; Maintainer: Óscar Nájera <hi@oscarnajera.com>
|
||||||
|
;; Created: August 19, 2022
|
||||||
|
;; Modified: August 19, 2022
|
||||||
|
;; Version: 0.0.1
|
||||||
|
;; Keywords: abbrev bib c calendar comm convenience data docs emulations extensions faces files frames games hardware help hypermedia i18n internal languages lisp local maint mail matching mouse multimedia news outlines processes terminals tex tools unix vc wp
|
||||||
|
;; Homepage: https://github.com/titan/test-org-cv
|
||||||
|
;; Package-Requires: ((emacs "24.3"))
|
||||||
|
;;
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
;;
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
|
;; Test Org-cv
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'org-cv-utils)
|
||||||
|
(ert-deftest test-org-cv-utils-org-timestamp-to-shortdate ()
|
||||||
|
(pcase-dolist (`(,input ,expected)
|
||||||
|
'(("<2002-08-12 Mon>" "Aug 2002")
|
||||||
|
("[2012-05-24]" "May 2012")
|
||||||
|
("today" "today")))
|
||||||
|
(should (string= (org-cv-utils-org-timestamp-to-shortdate input) expected))))
|
||||||
|
|
||||||
|
(provide 'test-org-cv)
|
||||||
|
;;; test-org-cv.el ends here
|
Loading…
Reference in a new issue