Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
Revisions: 7 A Fancy Resume Éric NICOLAS
Latest: 2026-07-06 ============== ccjmne@gmail.com
This project lets me build my current, static, professional resume.
Find it at https://ccjmne.sh/resume, where it is generated anew every
night.
Inside the Box -----------------------------------------------------------------
This works by generating plain HTML pages, then printing them to PDF
using Puppeteer [1].
It may also generate a plain PNG image, whose output is stable
enough to satisfy diff-ing needs; I am quite controlling regarding
hyphenation—and many other things—and require that the resulting
artefacts look a certain, authoritative way.
Tools and Technologies -----------------------------------------------------
Under the hood, it's all a labour of love: no pointless Web
frameworks, nor any library for any sort of elements. No canned
designs, only a moving target that I find to suit my tastes of
the year.
It's all SVGs entirely generated by code, entirely hand-rolled.
The seeds for the random number sequences are playful references
to events that are meaningful to me.
I composed a simple class, src/utils/easy-htmlelement.ts, that
lets me compose the page in a single JavaScript expression; see
src/1.ts and src/2.ts, respectively.
The rendering of the VCS (dare I say Git?)-like tracks on
the second page is also built in-house for the purpose of
this resume. It's a fairly lovely piece of code, found at
src/utils/timeline.ts; it works off some bespoke data format
that I found to be particularly practical to maintain, see the
*timeline* variable exported by src/profile.ts.
A few Lavish Affordances -----------------------------------------------
This does use TypeScript for the data as well: what do you know,
it's merely some more expressive and elegant JSON.
In the end, I did also splurge for a ready-made bundler (I
believe I went through plain shell scripts, then Grunt, then
Gulp, then Webpack, then Vite—I've been at it a while),
and ended up using SASS for some of its favourite features.
I couldn't quite call this project minimalist; but heh, it
saw the light of day at a time I was still bright-eyed and
bushy-tailed: let the eager zeal of the overindulging youth
of yesteryear permeate the mantle of what is today a frugal,
austere, relentlessly economical contributor.
How-To -------------------------------------------------------------------------
This project is packaged according to standard Node.js [2] practices
(using pnpm [3], for good reasons):
install dependencies: pnpm install
run in development mode: pnpm start
compile artefact once: pnpm build
Other utilities are available; package.json collates them.
The output will be generated under *dist*.
------------------------------ Build Options -------------------------------
The following environment variables can be set to customise the build:
OUTPUT the name of the output file
- generates a screenshot if output ends in *.png*; otherwise
coerces extension to *.pdf*
- defaults to *resume.pdf*
HYPHENATE whether to insert soft-hyphens [4] wherever applicable
- is disabled by default in production builds, because having
­ littered throughout each and every word isn't quite
SEO-friendly, and might even throw off ATSes [5]
- is enabled when starting with *y*; defaults to *no*
TWOPASS whether to render the background as a raster image to be
embedded as-is, then render the text in a superimposed layer
- works around the staggering variance across various PDF
visualisers, at the cost of non-scalable backgrounds and
somewhat greater document size
- is enabled when starting with *y*; defaults to *no*
BROWSER_KEEPALIVE how long to keep the spawned browser instance alive
(for successive reprints in development mode)
- is expressed in milliseconds
- defaults to 30,000 (30 seconds) for development, 0 for
production runs
BROWSER_EXECUTABLE the path to the Chromium executable to use
- if unspecified, uses the first available executable among:
chromium, chromium-browser, google-chrome-stable,
google-chrome
--------------------------- Deployment Procedure ---------------------------
None. Gets rebuilt and redeployed every night, so as to provide
the most up-to-date employment durations.
Continuous Integration is achieved via GitHub Actions [6],
whereby in the dead of night (by the reasonable understanding of
folks living in the Europe/Paris timezone), this here repository
is checked out, its dependencies are installed (if not cached
already), two PNG versions of the document are generated and
compared (with and without automatic soft-hyphenation as per
the rules expected of the adept English speaker), and if all is
above board, the document is generated in two passes (see the
TWOPASS build option) as a PDF and subsequently compressed to
acceptable levels with Ghostscript [7].
Provided that all of the above succeeded, that resulting
artefact gets uploaded to a simple GitHub Pages [8]
environment.
Licensing ----------------------------------------------------------------------
GPL-3.0
You may copy, distribute and modify the software as long as
you track changes/dates in source files. Any modifications to
or software including (via compiler) GPL-licensed code must
also be made available under the GPL along with build & install
instructions.
In short, I didn't go most permissive. This is ours. It can be yours
too, but neither it nor its descendants can be yours only.
Refer to the LICENSE file for more details.
References -------------------------------------------------------------
[1]: https://github.com/GoogleChrome/puppeteer
[2]: https://nodejs.org
[3]: https://pnpm.io
[4]: https://en.wikipedia.org/wiki/Soft_hyphen
[5]: https://en.wikipedia.org/wiki/Applicant_tracking_system
[6]: https://docs.github.com/en/actions
[7]: https://ghostscript.com
[8]: https://pages.github.com