cv-tools-cli 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cv_tools/__init__.py +7 -0
- cv_tools/__main__.py +5 -0
- cv_tools/api.py +123 -0
- cv_tools/bib.py +122 -0
- cv_tools/charset.py +142 -0
- cv_tools/cli.py +384 -0
- cv_tools/doctor.py +185 -0
- cv_tools/engine.py +320 -0
- cv_tools/loader.py +424 -0
- cv_tools/markup.py +614 -0
- cv_tools/migrate.py +222 -0
- cv_tools/model.py +192 -0
- cv_tools/render/__init__.py +1 -0
- cv_tools/render/html.py +581 -0
- cv_tools/render/latex.py +154 -0
- cv_tools/schema/cv-v2.schema.json +707 -0
- cv_tools/starter/cv.yaml +129 -0
- cv_tools/starter/publications.bib +55 -0
- cv_tools/templates/html/cv.css +252 -0
- cv_tools/templates/html/cv.html.jinja +19 -0
- cv_tools/templates/html/icons/github.svg +1 -0
- cv_tools/templates/html/icons/linkedin.svg +1 -0
- cv_tools/templates/html/icons/orcid.svg +1 -0
- cv_tools/templates/html/icons/twitter.svg +1 -0
- cv_tools/templates/html/macros.jinja +89 -0
- cv_tools/templates/latex/cv.tex.jinja +45 -0
- cv_tools/templates/latex/layouts/dated.jinja +12 -0
- cv_tools/templates/latex/layouts/entries-inline.jinja +23 -0
- cv_tools/templates/latex/layouts/entries.jinja +29 -0
- cv_tools/templates/latex/layouts/list.jinja +24 -0
- cv_tools/templates/latex/layouts/pairs.jinja +14 -0
- cv_tools/templates/latex/layouts/publications.jinja +14 -0
- cv_tools/templates/latex/layouts/text.jinja +10 -0
- cv_tools/templates/latex/orcid.pdf +0 -0
- cv_tools/templates/latex/packages.txt +47 -0
- cv_tools/templates/latex/resume.cls +265 -0
- cv_tools/templates/latex/unicode.txt +398 -0
- cv_tools/v1.py +484 -0
- cv_tools/validate.py +165 -0
- cv_tools/watch.py +76 -0
- cv_tools_cli-2.0.0.dist-info/METADATA +498 -0
- cv_tools_cli-2.0.0.dist-info/RECORD +46 -0
- cv_tools_cli-2.0.0.dist-info/WHEEL +5 -0
- cv_tools_cli-2.0.0.dist-info/entry_points.txt +2 -0
- cv_tools_cli-2.0.0.dist-info/licenses/LICENSE +21 -0
- cv_tools_cli-2.0.0.dist-info/top_level.txt +1 -0
cv_tools/watch.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Rebuild when the CV file or one of its .bib files changes (polling, which works everywhere)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
import time
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Callable, Iterable, Optional, TextIO
|
|
9
|
+
|
|
10
|
+
from .model import Document
|
|
11
|
+
|
|
12
|
+
Signature = Optional[tuple[int, int]] # (mtime in ns, size), or None for a missing file
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def watched_files(doc: Document, config: Path) -> set[Path]:
|
|
16
|
+
"""The CV file and every .bib file it references."""
|
|
17
|
+
return {Path(config).resolve()} | {s.bib for s in doc.sections if s.bib is not None}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def signature(path: Path) -> Signature:
|
|
21
|
+
try:
|
|
22
|
+
st = path.stat()
|
|
23
|
+
except OSError:
|
|
24
|
+
return None
|
|
25
|
+
return (st.st_mtime_ns, st.st_size)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def snapshot(paths: Iterable[Path]) -> dict[Path, Signature]:
|
|
29
|
+
return {p: signature(p) for p in paths}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _display(path: Path) -> str:
|
|
33
|
+
try:
|
|
34
|
+
return str(path.relative_to(Path.cwd()))
|
|
35
|
+
except ValueError:
|
|
36
|
+
return str(path)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def run(
|
|
40
|
+
build: Callable[[], Optional[Iterable[Path]]],
|
|
41
|
+
interval: float = 0.5,
|
|
42
|
+
*,
|
|
43
|
+
stop: Callable[[], bool] = lambda: False,
|
|
44
|
+
sleep: Callable[[float], None] = time.sleep,
|
|
45
|
+
out: TextIO = sys.stderr,
|
|
46
|
+
) -> None:
|
|
47
|
+
"""Call ``build`` now and after every change to the files it returns (None keeps the previous set)."""
|
|
48
|
+
# Wait one quiet interval, because editors often save in several steps.
|
|
49
|
+
files: set[Path] = set()
|
|
50
|
+
|
|
51
|
+
def rebuild() -> None:
|
|
52
|
+
nonlocal files, state
|
|
53
|
+
before = snapshot(files)
|
|
54
|
+
new = build()
|
|
55
|
+
if new is not None:
|
|
56
|
+
files = {Path(p) for p in new}
|
|
57
|
+
# Old signatures, so an edit during the build triggers another one.
|
|
58
|
+
state = {p: before[p] if p in before else signature(p) for p in files}
|
|
59
|
+
|
|
60
|
+
state: dict[Path, Signature] = {}
|
|
61
|
+
rebuild()
|
|
62
|
+
print(f"watching {', '.join(sorted(_display(p) for p in files))} (Ctrl-C to stop)", file=out, flush=True)
|
|
63
|
+
while not stop():
|
|
64
|
+
sleep(interval)
|
|
65
|
+
current = snapshot(files)
|
|
66
|
+
if current == state:
|
|
67
|
+
continue
|
|
68
|
+
while True:
|
|
69
|
+
sleep(interval)
|
|
70
|
+
settled = snapshot(files)
|
|
71
|
+
if settled == current:
|
|
72
|
+
break
|
|
73
|
+
current = settled
|
|
74
|
+
changed = sorted(_display(p) for p in files if current.get(p) != state.get(p))
|
|
75
|
+
print(f"changed: {', '.join(changed)}; rebuilding", file=out, flush=True)
|
|
76
|
+
rebuild()
|
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cv-tools-cli
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Generate a LaTeX CV from a YAML file
|
|
5
|
+
Author: Phone Thiha Kyaw
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/mlsdpk/cv-tools
|
|
8
|
+
Project-URL: Repository, https://github.com/mlsdpk/cv-tools
|
|
9
|
+
Project-URL: Issues, https://github.com/mlsdpk/cv-tools/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/mlsdpk/cv-tools/blob/master/CHANGELOG.md
|
|
11
|
+
Keywords: cv,resume,latex,yaml,curriculum-vitae,bibtex
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
24
|
+
Classifier: Topic :: Text Processing :: Markup :: LaTeX
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: PyYAML>=6.0
|
|
29
|
+
Requires-Dist: Jinja2>=3.0
|
|
30
|
+
Requires-Dist: pybtex>=0.24
|
|
31
|
+
Requires-Dist: jsonschema>=4.18
|
|
32
|
+
Requires-Dist: ruamel.yaml>=0.17.21
|
|
33
|
+
Provides-Extra: test
|
|
34
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
35
|
+
Requires-Dist: hypothesis>=6; extra == "test"
|
|
36
|
+
Requires-Dist: Pillow>=9; extra == "test"
|
|
37
|
+
Requires-Dist: pytest-cov>=4; extra == "test"
|
|
38
|
+
Requires-Dist: pypdf==7.1.0; extra == "test"
|
|
39
|
+
Provides-Extra: fidelity
|
|
40
|
+
Requires-Dist: playwright==1.64.1; extra == "fidelity"
|
|
41
|
+
Dynamic: license-file
|
|
42
|
+
|
|
43
|
+
<!-- markdownlint-disable-next-line -->
|
|
44
|
+
<div align="center">
|
|
45
|
+
|
|
46
|
+
<!-- markdownlint-disable-next-line -->
|
|
47
|
+
|
|
48
|
+
# CV Tools
|
|
49
|
+
|
|
50
|
+
A tool to automate the creation of professional LaTeX-based CVs.
|
|
51
|
+
|
|
52
|
+

|
|
53
|
+

|
|
54
|
+

|
|
55
|
+
|
|
56
|
+

|
|
57
|
+
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
CV Tools turns a YAML file into a professional LaTeX CV. You write your details in YAML, keep your publications in a BibTeX file, and get a PDF.
|
|
61
|
+
|
|
62
|
+
# Build Status
|
|
63
|
+
|
|
64
|
+
| Tests | Docker image | Web app |
|
|
65
|
+
| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
|
|
66
|
+
|  |  |  |
|
|
67
|
+
|
|
68
|
+
# Table of Contents
|
|
69
|
+
|
|
70
|
+
- [Use It in Your Browser](#use-it-in-your-browser)
|
|
71
|
+
- [Getting Started](#getting-started)
|
|
72
|
+
- [YAML Configuration](#yaml-configuration)
|
|
73
|
+
- [Text Formatting](#text-formatting)
|
|
74
|
+
- [Editor Support](#editor-support)
|
|
75
|
+
- [BibTeX Configuration](#bibtex-configuration)
|
|
76
|
+
- [Migrating from v1](#migrating-from-v1)
|
|
77
|
+
- [Contributing](#contributing)
|
|
78
|
+
|
|
79
|
+
# Use It in Your Browser
|
|
80
|
+
|
|
81
|
+
Open [cv-tools.phonethk.com](https://cv-tools.phonethk.com/), edit the YAML and download the PDF. Nothing to install, just an up-to-date browser.
|
|
82
|
+
|
|
83
|
+

|
|
84
|
+
|
|
85
|
+
# Getting Started
|
|
86
|
+
|
|
87
|
+
## Installation
|
|
88
|
+
|
|
89
|
+
Install cv-tools with [pipx](https://pipx.pypa.io). It needs Python 3.10 or newer.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
$ pipx install cv-tools-cli
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Usage
|
|
96
|
+
|
|
97
|
+
`cv-tools init` writes a starter `cv.yaml` and `publications.bib`. `cv-tools build` turns them into `cv.pdf`.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
$ mkdir my-cv && cd my-cv
|
|
101
|
+
$ cv-tools init
|
|
102
|
+
$ cv-tools build cv.yaml
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`cv-tools watch cv.yaml` rebuilds the PDF every time you save.
|
|
106
|
+
|
|
107
|
+
## Getting a PDF
|
|
108
|
+
|
|
109
|
+
`cv-tools build` needs pdflatex or Docker. Without either, you can still send your CV to Overleaf.
|
|
110
|
+
|
|
111
|
+
- **TeX Live**: Install [TeX Live](https://www.tug.org/texlive/). With a small installation such as BasicTeX, `cv-tools doctor --tlmgr` prints the command that installs the packages cv-tools needs.
|
|
112
|
+
- **Docker**: With Docker running, no TeX is needed. `cv-tools build` uses it when pdflatex or its packages are missing, or you can ask for it.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
$ cv-tools build cv.yaml --engine docker
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- **Overleaf**: `cv-tools build cv.yaml --zip` writes `cv.zip`. Upload it to [Overleaf](https://www.overleaf.com) with New Project, then Upload Project.
|
|
119
|
+
|
|
120
|
+
## Commands
|
|
121
|
+
|
|
122
|
+
| Command | Description |
|
|
123
|
+
| --------------------------- | ------------------------------------------------------------- |
|
|
124
|
+
| `cv-tools init` | Write a starter `cv.yaml` and `publications.bib`. |
|
|
125
|
+
| `cv-tools build cv.yaml` | Build the PDF. Add `--zip` or `--tex-only` for LaTeX sources. |
|
|
126
|
+
| `cv-tools watch cv.yaml` | Rebuild the PDF every time you save. |
|
|
127
|
+
| `cv-tools validate cv.yaml` | Check the file and report errors with line numbers. |
|
|
128
|
+
| `cv-tools migrate old.yaml` | Convert a v1 file to the new format. |
|
|
129
|
+
| `cv-tools doctor` | Check that pdflatex, the TeX packages or Docker are ready. |
|
|
130
|
+
|
|
131
|
+
# YAML Configuration
|
|
132
|
+
|
|
133
|
+
A CV file has a header and a list of sections. The complete example is [`examples/cv.yaml`](https://github.com/mlsdpk/cv-tools/blob/master/examples/cv.yaml).
|
|
134
|
+
|
|
135
|
+
## Header
|
|
136
|
+
|
|
137
|
+
| Key | Type | Description | Required |
|
|
138
|
+
| ---------- | ------ | --------------------------------------------------------------------------- | -------- |
|
|
139
|
+
| `version` | int | Always `2`. | Yes |
|
|
140
|
+
| `name` | string | Your name, printed as the page heading. | Yes |
|
|
141
|
+
| `contact` | list | Up to three lines under the name. Each line is a list of items. | No |
|
|
142
|
+
| `date` | string | The text that `{date}` prints. The default `auto` prints the compile date. | No |
|
|
143
|
+
| `sections` | list | The sections of the CV, in order. | No |
|
|
144
|
+
|
|
145
|
+
A contact item is plain text or one of `url`, `orcid`, `linkedin`, `github` and `twitter`. Links print as links, and the others print as icons.
|
|
146
|
+
|
|
147
|
+
```yaml
|
|
148
|
+
version: 2
|
|
149
|
+
name: John Doe
|
|
150
|
+
|
|
151
|
+
contact:
|
|
152
|
+
- - url: https://www.johndoeportfolio.com
|
|
153
|
+
- orcid: 0000-0000-0000-0000
|
|
154
|
+
- linkedin: https://linkedin.com/in/johndoe
|
|
155
|
+
- - johndoe@email.com
|
|
156
|
+
- Curriculum Vitae, {date}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+

|
|
160
|
+
|
|
161
|
+
## Sections
|
|
162
|
+
|
|
163
|
+
Every section has a `title` and a `layout`, and lists its rows under `entries`. An optional `description` adds a line of text under the heading. Keys mean the same thing in every layout, so nested points are always `bullets` and a row has a `title`, a `text` and a `date`.
|
|
164
|
+
|
|
165
|
+
| Layout | Use it for |
|
|
166
|
+
| ----------------------------------- | --------------------------------------------- |
|
|
167
|
+
| [`entries`](#entries) | Positions with a role, a date and bullets |
|
|
168
|
+
| [`entries-inline`](#entries-inline) | A more compact version of `entries` |
|
|
169
|
+
| [`list`](#list) | Bullet points, optionally with nested bullets |
|
|
170
|
+
| [`pairs`](#pairs) | A label on the left and text on the right |
|
|
171
|
+
| [`dated`](#dated) | One line per item with a date in front |
|
|
172
|
+
| [`text`](#text) | Paragraphs of free text |
|
|
173
|
+
| [`publications`](#publications) | Entries of a BibTeX file |
|
|
174
|
+
| [`newpage`](#newpage) | A page break |
|
|
175
|
+
|
|
176
|
+
### `entries`
|
|
177
|
+
|
|
178
|
+
The `entries` layout lists positions, such as jobs or teaching.
|
|
179
|
+
|
|
180
|
+
| Field | Type | Description | Required |
|
|
181
|
+
| ---------- | ------ | -------------------------------------------------------- | -------- |
|
|
182
|
+
| `title` | string | The organisation, in bold. | Yes |
|
|
183
|
+
| `location` | string | Printed after the title. | No |
|
|
184
|
+
| `date` | string | Printed on the right of the first line. | No |
|
|
185
|
+
| `subtitle` | string | The second line, for example your position. | No |
|
|
186
|
+
| `note` | string | Printed on the right of the second line. | No |
|
|
187
|
+
| `details` | list | Extra lines, such as a department or a city. | No |
|
|
188
|
+
| `bullets` | list | Bullet points. | No |
|
|
189
|
+
|
|
190
|
+
```yaml
|
|
191
|
+
- title: Teaching and Volunteering
|
|
192
|
+
layout: entries
|
|
193
|
+
entries:
|
|
194
|
+
- title: Virtual Coding Academy
|
|
195
|
+
date: January 2020 - December 2021
|
|
196
|
+
subtitle: Instructor
|
|
197
|
+
note: 'Supervisor: Dr. Eve Code'
|
|
198
|
+
details:
|
|
199
|
+
- Department of Computer Science
|
|
200
|
+
- Imaginaria, Wonderland
|
|
201
|
+
bullets:
|
|
202
|
+
- Taught introductory and advanced courses in Python programming.
|
|
203
|
+
- Mentored students on their final projects and provided guidance on coding best practices.
|
|
204
|
+
- title: Tech Youth Initiative
|
|
205
|
+
date: July 2019 - June 2020
|
|
206
|
+
subtitle: Volunteer Coordinator
|
|
207
|
+
details:
|
|
208
|
+
- Nowhere City, Utopia
|
|
209
|
+
bullets:
|
|
210
|
+
- Organized coding boot camps and hackathons for underprivileged youth.
|
|
211
|
+
- Managed a team of volunteers and ensured smooth operation of all events.
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+

|
|
215
|
+
|
|
216
|
+
### `entries-inline`
|
|
217
|
+
|
|
218
|
+
The `entries-inline` layout takes the same fields as `entries` and prints them more compactly. It suits education.
|
|
219
|
+
|
|
220
|
+
```yaml
|
|
221
|
+
- title: Education
|
|
222
|
+
layout: entries-inline
|
|
223
|
+
entries:
|
|
224
|
+
- title: Fictional University
|
|
225
|
+
location: Imaginaria, Wonderland
|
|
226
|
+
date: September 2021 - June 2024
|
|
227
|
+
subtitle: Bachelor of Science in *Computer Science*
|
|
228
|
+
note: '**Magna Cum Laude**'
|
|
229
|
+
details:
|
|
230
|
+
- "Thesis Title: *An Exploration of ['Quantum Computing'](https://en.wikipedia.org/wiki/Quantum_computing) in Virtual Environments*"
|
|
231
|
+
- 'Supervisor: Dr. Alice Wonder'
|
|
232
|
+
- title: Imaginary Institute of Technology
|
|
233
|
+
location: Nowhere City, Utopia
|
|
234
|
+
date: August 2018 - May 2021
|
|
235
|
+
subtitle: Associate Degree in Artificial Intelligence
|
|
236
|
+
details:
|
|
237
|
+
- 'Supervisor: Dr. Bob Builder'
|
|
238
|
+
bullets:
|
|
239
|
+
- 'Relevant Coursework: Machine Learning, Advanced Algorithms'
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+

|
|
243
|
+
|
|
244
|
+
### `list`
|
|
245
|
+
|
|
246
|
+
The `list` layout prints bullet points. An entry is plain text, or a `text` with nested `bullets`.
|
|
247
|
+
|
|
248
|
+
| Field | Type | Description | Required |
|
|
249
|
+
| --------- | ------ | -------------------------------- | -------- |
|
|
250
|
+
| `text` | string | The bullet point. | Yes |
|
|
251
|
+
| `bullets` | list | Nested points under this bullet. | No |
|
|
252
|
+
|
|
253
|
+
```yaml
|
|
254
|
+
- title: Honors and Awards
|
|
255
|
+
layout: list
|
|
256
|
+
entries:
|
|
257
|
+
- Dean's List (2023, 2022)
|
|
258
|
+
- Best Paper Award at Tech Innovations Conference (2023)
|
|
259
|
+
- Outstanding Graduate Award, Fictional University (2024)
|
|
260
|
+
|
|
261
|
+
- title: Professional Activities
|
|
262
|
+
layout: list
|
|
263
|
+
description: Served/ing as a reviewer for
|
|
264
|
+
entries:
|
|
265
|
+
- text: Journals
|
|
266
|
+
bullets:
|
|
267
|
+
- Journal of Artificial Intelligence Research (JAIR)
|
|
268
|
+
- Journal of Machine Learning Research (JMLR)
|
|
269
|
+
- text: Conferences
|
|
270
|
+
bullets:
|
|
271
|
+
- IEEE Conference on Computer Vision and Pattern Recognition (CVPR)
|
|
272
|
+
- International Conference on Learning Representations (ICLR)
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+

|
|
276
|
+
|
|
277
|
+
### `pairs`
|
|
278
|
+
|
|
279
|
+
The `pairs` layout prints a label on the left and its text on the right, useful for skills and languages.
|
|
280
|
+
|
|
281
|
+
| Field | Type | Description | Required |
|
|
282
|
+
| ------- | ------ | ---------------------- | -------- |
|
|
283
|
+
| `title` | string | The label on the left. | Yes |
|
|
284
|
+
| `text` | string | The text on the right. | Yes |
|
|
285
|
+
|
|
286
|
+
```yaml
|
|
287
|
+
- title: Skills
|
|
288
|
+
layout: pairs
|
|
289
|
+
entries:
|
|
290
|
+
- title: Spoken Languages
|
|
291
|
+
text: English (Fluent), Spanish (Intermediate)
|
|
292
|
+
- title: Programming Languages
|
|
293
|
+
text: Python, Java, C++, SQL, JavaScript
|
|
294
|
+
- title: Tools and Technologies
|
|
295
|
+
text: AWS, Docker, Kubernetes, TensorFlow, Git, Jenkins, Linux, Jira
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+

|
|
299
|
+
|
|
300
|
+
### `dated`
|
|
301
|
+
|
|
302
|
+
The `dated` layout prints one line per entry with the date in front.
|
|
303
|
+
|
|
304
|
+
| Field | Type | Description | Required |
|
|
305
|
+
| ------ | ------ | ------------------------------ | -------- |
|
|
306
|
+
| `date` | string | The date, such as `Nov. 2023`. | No |
|
|
307
|
+
| `text` | string | The talk, event or item. | Yes |
|
|
308
|
+
|
|
309
|
+
```yaml
|
|
310
|
+
- title: Invited Talks/Workshops
|
|
311
|
+
layout: dated
|
|
312
|
+
entries:
|
|
313
|
+
- date: Nov. 2023
|
|
314
|
+
text: "'AI in Everyday Life', Invited talk, Tech Conference 2023, Imaginaria."
|
|
315
|
+
- date: Oct. 2022
|
|
316
|
+
text: "'Cloud Computing for Beginners', Workshop, FutureTech Expo 2022, Nowhere City."
|
|
317
|
+
- date: May 2024
|
|
318
|
+
text: "'Robotics in Modern Industry', Guest lecture, Imaginary Institute of Technology."
|
|
319
|
+
- date: Aug. 2023
|
|
320
|
+
text: "'Building Scalable Systems with Docker and Kubernetes', Workshop, DevOps World 2023, Tech City."
|
|
321
|
+
- date: Sep. 2022
|
|
322
|
+
text: "'Ethics in AI', Panel discussion, Ethics in Technology Conference 2022, Metropolis."
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+

|
|
326
|
+
|
|
327
|
+
### `text`
|
|
328
|
+
|
|
329
|
+
The `text` layout prints one paragraph per entry, for a summary or a research statement.
|
|
330
|
+
|
|
331
|
+
| Field | Type | Description | Required |
|
|
332
|
+
| ------ | ------ | -------------- | -------- |
|
|
333
|
+
| `text` | string | The paragraph. | Yes |
|
|
334
|
+
|
|
335
|
+
```yaml
|
|
336
|
+
- title: Summary
|
|
337
|
+
layout: text
|
|
338
|
+
entries:
|
|
339
|
+
- Software engineer with five years of experience in *cloud platforms* and *robotics*.
|
|
340
|
+
- Interested in autonomous navigation, scalable systems and teaching programming to new developers.
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+

|
|
344
|
+
|
|
345
|
+
### `publications`
|
|
346
|
+
|
|
347
|
+
The `publications` layout lists the entries of a BibTeX file. It has no `entries`. See [BibTeX Configuration](#bibtex-configuration).
|
|
348
|
+
|
|
349
|
+
| Key | Type | Description | Required |
|
|
350
|
+
| ----------- | ------ | ---------------------------------------------------------- | -------- |
|
|
351
|
+
| `bib` | string | The `.bib` file, relative to the YAML file. | Yes |
|
|
352
|
+
| `highlight` | list | Author names to print in bold. The default is your `name`. | No |
|
|
353
|
+
|
|
354
|
+
```yaml
|
|
355
|
+
- title: Publications
|
|
356
|
+
layout: publications
|
|
357
|
+
bib: publications.bib
|
|
358
|
+
highlight: [John Doe]
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+

|
|
362
|
+
|
|
363
|
+
### `newpage`
|
|
364
|
+
|
|
365
|
+
The plain string `newpage` in the section list starts a new page.
|
|
366
|
+
|
|
367
|
+
```yaml
|
|
368
|
+
sections:
|
|
369
|
+
- title: Honors and Awards
|
|
370
|
+
layout: list
|
|
371
|
+
entries:
|
|
372
|
+
- Dean's List (2023, 2022)
|
|
373
|
+
- Best Paper Award at Tech Innovations Conference (2023)
|
|
374
|
+
|
|
375
|
+
- newpage
|
|
376
|
+
|
|
377
|
+
- title: Certifications
|
|
378
|
+
layout: entries
|
|
379
|
+
entries:
|
|
380
|
+
- title: Certified Kubernetes Administrator
|
|
381
|
+
date: Graduated December 2023
|
|
382
|
+
subtitle: Cloud Native Computing Foundation
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+

|
|
386
|
+
|
|
387
|
+
# Text Formatting
|
|
388
|
+
|
|
389
|
+
Every text field understands a small Markdown-like markup.
|
|
390
|
+
|
|
391
|
+
| Write | Result |
|
|
392
|
+
| ----------------------------- | --------------------------------------- |
|
|
393
|
+
| `**Bold**` | **Bold** |
|
|
394
|
+
| `*Italic*` | *Italic* |
|
|
395
|
+
| `[My Portfolio](https://...)` | A link |
|
|
396
|
+
| `"First line\nSecond line"` | A line break |
|
|
397
|
+
| two spaces | A small space |
|
|
398
|
+
| four spaces or a tab | A wider space |
|
|
399
|
+
| `'quoted phrase'` | “quoted phrase” with LaTeX quotes |
|
|
400
|
+
| `30% of R&D` | Printed as written, with no escaping |
|
|
401
|
+
| `5\* rating` | 5\* rating, with a literal star |
|
|
402
|
+
| `{latex: '\textsc{Name}'}` | Raw LaTeX, inserted as it is |
|
|
403
|
+
|
|
404
|
+
Accented letters, Greek letters and common math symbols print as they are. See [the full list of supported characters](https://github.com/mlsdpk/cv-tools/blob/master/src/cv_tools/templates/latex/unicode.txt).
|
|
405
|
+
|
|
406
|
+
```yaml
|
|
407
|
+
- title: Text Formatting
|
|
408
|
+
layout: list
|
|
409
|
+
entries:
|
|
410
|
+
- "**Bold**, *italic* and ***bold italic*** text"
|
|
411
|
+
- "A [link to my portfolio](https://www.johndoeportfolio.com)"
|
|
412
|
+
- "A 'quoted phrase' becomes LaTeX quotes"
|
|
413
|
+
- "First line\nSecond line"
|
|
414
|
+
- "Two spaces and four spaces"
|
|
415
|
+
- "LaTeX specials print as written: 30% & $5 for #1 in C_1"
|
|
416
|
+
- "Literal escapes: 5\\* rating and \\[not a link\\](x)"
|
|
417
|
+
- "Unicode: café, naïve, α ≤ β, x → ∞"
|
|
418
|
+
- {latex: "Raw \\LaTeX: \\textsc{Small Caps}"}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+

|
|
422
|
+
|
|
423
|
+
# Editor Support
|
|
424
|
+
|
|
425
|
+
Files from `cv-tools init` start with a schema comment. With the [YAML extension for VS Code](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml), it gives autocompletion and shows errors as you type.
|
|
426
|
+
|
|
427
|
+
```yaml
|
|
428
|
+
# yaml-language-server: $schema=https://cv-tools.phonethk.com/schema/v2.json
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
`cv-tools validate cv.yaml` checks a file and reports errors with line numbers.
|
|
432
|
+
|
|
433
|
+
# BibTeX Configuration
|
|
434
|
+
|
|
435
|
+
Keep your publications in a BibTeX file and add a `publications` section that points to it with `bib`.
|
|
436
|
+
|
|
437
|
+
```bibtex
|
|
438
|
+
@article{doe2024quantum,
|
|
439
|
+
author = {John Doe and Jane Smith and Alice Wonder},
|
|
440
|
+
title = {Quantum Computing: Bridging the Gap Between Theory and Application},
|
|
441
|
+
journal = {Journal of Computer Science},
|
|
442
|
+
year = {2024},
|
|
443
|
+
url = {https://example.com/quantum-computing-paper}
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
> cv-tools prints your name in bold in the author list. Set `highlight` in the section to bold other names.
|
|
448
|
+
|
|
449
|
+
> Most BibTeX entries have no `url` field. cv-tools adds a [Link] only when the entry has one, so add the field by hand where you want the link.
|
|
450
|
+
|
|
451
|
+
Publications appear in the order of the `.bib` file. An example BibTeX file is provided [here](https://github.com/mlsdpk/cv-tools/blob/master/examples/publications.bib).
|
|
452
|
+
|
|
453
|
+
# Migrating from v1
|
|
454
|
+
|
|
455
|
+
v1 files (with `heading`, `subheading` and `type:` sections) still build, with a deprecation warning. Support for them will be removed in a future release. Convert your file once and keep the new one.
|
|
456
|
+
|
|
457
|
+
```bash
|
|
458
|
+
$ cv-tools migrate old.yaml -o cv.yaml
|
|
459
|
+
$ cv-tools build cv.yaml
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
The new file gives the same PDF.
|
|
463
|
+
|
|
464
|
+
| v1 | v2 |
|
|
465
|
+
| --------------------------------------------------- | ------------------------------------- |
|
|
466
|
+
| `heading: {name: ...}` | `name` |
|
|
467
|
+
| `subheading` with `links` and `socials` | `contact` |
|
|
468
|
+
| `type: education` | `layout: entries-inline` |
|
|
469
|
+
| `type: experience` | `layout: entries` |
|
|
470
|
+
| `type: bullets` with `item`, `subitems` | `layout: list` with `text`, `bullets` |
|
|
471
|
+
| `type: skills` with `name`, `data` | `layout: pairs` with `title`, `text` |
|
|
472
|
+
| `type: talks` with `name`, `month`, `year` | `layout: dated` with `text`, `date` |
|
|
473
|
+
| `type: publications` with `bibfile` | `layout: publications` with `bib` |
|
|
474
|
+
| `type: newpage` | `newpage` |
|
|
475
|
+
| `content` | `entries` |
|
|
476
|
+
| `university`, `organization` | `title` |
|
|
477
|
+
| `degree`, `position` | `subtitle` |
|
|
478
|
+
| `dates` | `date` |
|
|
479
|
+
| `responsibilities` | `bullets` |
|
|
480
|
+
|
|
481
|
+
A few small fixes change the PDF of some v1 files. See the [CHANGELOG](https://github.com/mlsdpk/cv-tools/blob/master/CHANGELOG.md).
|
|
482
|
+
|
|
483
|
+
`run.sh` still works but is deprecated. Use `cv-tools build` instead.
|
|
484
|
+
|
|
485
|
+
# Contributing
|
|
486
|
+
|
|
487
|
+
Feel free to contribute to this project by submitting issues or pull requests. Contributions are welcome to improve the templates, add new features, or fix bugs.
|
|
488
|
+
|
|
489
|
+
- Python tests run with `pytest` after `pip install -e '.[test]'`.
|
|
490
|
+
- Web app tests run with `npm --prefix web test`.
|
|
491
|
+
|
|
492
|
+
# Acknowledgments
|
|
493
|
+
|
|
494
|
+
The LaTeX template currently supported in this project is based on the **Medium Length Professional CV** template from [LaTeXTemplates.com](https://www.latextemplates.com/template/medium-length-professional-cv), which has been extensively modified for this project. The original template was created by [Trey Hunner](https://treyhunner.com).
|
|
495
|
+
|
|
496
|
+
# License
|
|
497
|
+
|
|
498
|
+
This project is licensed under the [MIT License](https://opensource.org/license/mit).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
cv_tools/__init__.py,sha256=Auc8kf5VQ7Y_1UceKtikrrwD9LwZxDelmccCP13X_A0,257
|
|
2
|
+
cv_tools/__main__.py,sha256=E6Gls0DNz8GQK2K-kOUIx8cYhgANW_CH54VKrfCfs14,52
|
|
3
|
+
cv_tools/api.py,sha256=6-V4pcrfkWY1r-5n7Ouc9vP3EDB-M6ljDQosQN-NiFE,4591
|
|
4
|
+
cv_tools/bib.py,sha256=FCQOiy0Dft44IjmZq0ZBJcjgo_CVWclORuvgVaE-Zag,4422
|
|
5
|
+
cv_tools/charset.py,sha256=ng6fgaBSaXFaXDy6T0NxbXifl4fa0v8E5fTRkGfPl1M,5617
|
|
6
|
+
cv_tools/cli.py,sha256=wJ-h88wf1nVkY20HwhduUR4uZoehlKXnnIrtnc50if4,15537
|
|
7
|
+
cv_tools/doctor.py,sha256=O_oMclgv5zjY7BZ9B3JUPz8OadmiRg7F2_kzJZQDhd8,6900
|
|
8
|
+
cv_tools/engine.py,sha256=xWb8jvqlF-2kdMbujKEyto0OLNDAKcfChf5G8xvdD6k,12937
|
|
9
|
+
cv_tools/loader.py,sha256=LzkWzbb_J1y2k9lJ7qIUQIN6K8LuFOeeRXvhyhUuf_Q,17324
|
|
10
|
+
cv_tools/markup.py,sha256=lZ3yo6vn4SORPKGDl16tMA2o9wu4lk1-NtRyjC1x6wE,20167
|
|
11
|
+
cv_tools/migrate.py,sha256=iLM9AT8_7oBqBvLyUahj1AfsDE0b126XhJNuv04jDd8,8538
|
|
12
|
+
cv_tools/model.py,sha256=InQ_kpMXYOm4nNYilpHFxM7QP28IuOkc8vN9s5Q1lEs,7014
|
|
13
|
+
cv_tools/v1.py,sha256=01n-jhShhkknR4U6bN0IJT05yTlQUtvTPqYQweMdkc0,22070
|
|
14
|
+
cv_tools/validate.py,sha256=D979FOyUW2fv3H5lSQpmgj9g20egYeh2FhHMda0d150,6273
|
|
15
|
+
cv_tools/watch.py,sha256=bF2MRLfo0JxmfJoi30Y2J1wFmD3VKT4KXdxHw1Wvc2o,2409
|
|
16
|
+
cv_tools/render/__init__.py,sha256=UG29NiCiOioCEptga5SKXtxe1VtX-WFuR-93y79lI4g,83
|
|
17
|
+
cv_tools/render/html.py,sha256=VLg_n6XM9vK_3NHZfedwsCaLk1AU4vtP0KvLruGPXqI,23034
|
|
18
|
+
cv_tools/render/latex.py,sha256=Mv5QIWsKHgz8zZFsdeOguOGNNZa9FD8Q0lKIJC1zVb4,5049
|
|
19
|
+
cv_tools/schema/cv-v2.schema.json,sha256=6uztM4SshwX1jHL4QGj1rcY8QfqE93x64kE706NxSrg,15785
|
|
20
|
+
cv_tools/starter/cv.yaml,sha256=vru1NseZmFOVkBFxE5FRhiDVB7SoLoVIJcsMeE0Nk74,4869
|
|
21
|
+
cv_tools/starter/publications.bib,sha256=itobCMRkuNSCllEDGG-SgrJbwTzyjvjYsbIlvTIeTJM,1872
|
|
22
|
+
cv_tools/templates/html/cv.css,sha256=ITfQL-FokIxPhTQe6x8Hc7945DGoEMklvWKD2zzD1S8,9232
|
|
23
|
+
cv_tools/templates/html/cv.html.jinja,sha256=-a7UQnhLsNKkrlZNLHhf4NKni2AnvStJN4dIsBjrzXk,619
|
|
24
|
+
cv_tools/templates/html/macros.jinja,sha256=73PpljPSy_CXq3-CELGWt7OHJI5Mq4OLOKYsDt3vu5A,4204
|
|
25
|
+
cv_tools/templates/html/icons/github.svg,sha256=qKBoNae4v4I3PXjN9Wn5BaDaT4ON4G0vpLA4YzvDqXM,1417
|
|
26
|
+
cv_tools/templates/html/icons/linkedin.svg,sha256=A0alWEwrPaxd5WCA15YZJayEUgCA7563oOr6Fg3fhzg,555
|
|
27
|
+
cv_tools/templates/html/icons/orcid.svg,sha256=nCPIrzJoVb2jFGi3-PRpFiIxdE9L6OlyCKyPxTzaIoM,565
|
|
28
|
+
cv_tools/templates/html/icons/twitter.svg,sha256=_A9T24l3nWbGzU6J_7lPssUZ5e5JLmEmBb8OlvY4kic,618
|
|
29
|
+
cv_tools/templates/latex/cv.tex.jinja,sha256=MdfczGdnN1toh-xkICnw1lv6nyuaakTqYEc4kVSCDF4,1523
|
|
30
|
+
cv_tools/templates/latex/orcid.pdf,sha256=ubzGIVZQCoH-WqPNUesCNxh8XhMQC9jzCSaaqrC_1lA,1180
|
|
31
|
+
cv_tools/templates/latex/packages.txt,sha256=FOBScx-IGD7E2AmAPRYyr2dabX-JDwHb_LpVEnXzoYk,562
|
|
32
|
+
cv_tools/templates/latex/resume.cls,sha256=07kMVZXw2ZJ425qfceSK2v3b_vZky7sanTvceQBdhvo,11340
|
|
33
|
+
cv_tools/templates/latex/unicode.txt,sha256=WAkMx-QQC32TlpQA-MUbw8m_2MZl6fq4XbI8w0fHAa0,15296
|
|
34
|
+
cv_tools/templates/latex/layouts/dated.jinja,sha256=xBj3Y-2Bjsz3IgTizxmgo1SSxWrgy8YFqnc4gb1gQME,511
|
|
35
|
+
cv_tools/templates/latex/layouts/entries-inline.jinja,sha256=N127hp7hvt37zNGpHUYrBQ0faHGSBc7_rhgHLlvb14o,929
|
|
36
|
+
cv_tools/templates/latex/layouts/entries.jinja,sha256=JCMH2fmMeCM0QE9iUpDdzglU0zuMUhmeCRBWJcYTyFE,953
|
|
37
|
+
cv_tools/templates/latex/layouts/list.jinja,sha256=q2SN-FD-Hn8GSQQtvmOuROlVxWd148s5sX13xHRRWYU,720
|
|
38
|
+
cv_tools/templates/latex/layouts/pairs.jinja,sha256=4PXfau7dC8wXRHIqVPGRG7Hy2LkyRl_6Ea-3BSmFwrg,527
|
|
39
|
+
cv_tools/templates/latex/layouts/publications.jinja,sha256=5jvrR8hMiLjetLxaYXP6kddKY6xigawTdhFeYhOgPZk,466
|
|
40
|
+
cv_tools/templates/latex/layouts/text.jinja,sha256=KdyhYnfoyJnRLask6yXX392LobVvoT-QSrgAGew7gv8,378
|
|
41
|
+
cv_tools_cli-2.0.0.dist-info/licenses/LICENSE,sha256=ucArA3h-2wcE6JUePkXB2r8QLokPZm2RSN8dxcTLcPA,1073
|
|
42
|
+
cv_tools_cli-2.0.0.dist-info/METADATA,sha256=8gPj_zs8ycnuJ7Le8kW5ojYgDKrztxlT1qMOPJ9QsWY,22150
|
|
43
|
+
cv_tools_cli-2.0.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
44
|
+
cv_tools_cli-2.0.0.dist-info/entry_points.txt,sha256=O1C0XUUybBtIuYaXpm1BRNcU1RsY-ZwEzrLwdDg6F_g,47
|
|
45
|
+
cv_tools_cli-2.0.0.dist-info/top_level.txt,sha256=JKz5Q8QNyF-4uw3goA61IehbgLJexBT8d3V-v1KS6r8,9
|
|
46
|
+
cv_tools_cli-2.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Phone Thiha Kyaw
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cv_tools
|