@warleon/jsonresume-theme-compact
Version:
A JSON Resume theme, compatible with the latest resume schema
578 lines (563 loc) • 14.1 kB
JavaScript
var y = Object.freeze, w = Object.defineProperty;
var b = (i, e) => y(w(i, "raw", { value: y(e || i.slice()) }));
import { html as t } from "@rbardini/html";
import j from "micromark";
import C from "striptags";
import x from "feather-icons";
const L = `
:root {
--color-background: #ffffff;
--color-dimmed: #f3f4f5;
--color-primary: #191e23;
--color-secondary: #6c7781;
--color-accent: #0073aa;
--scale-ratio: 1.2;
--scale0: 0.875rem;
--scale1: calc(var(--scale0) * var(--scale-ratio));
--scale2: calc(var(--scale1) * var(--scale-ratio));
--scale3: calc(var(--scale2) * var(--scale-ratio));
--scale4: calc(var(--scale3) * var(--scale-ratio));
--scale5: calc(var(--scale4) * var(--scale-ratio));
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-size: 12px;
}
body {
background: var(--color-background);
color: var(--color-primary);
display: flex;
flex-direction: column;
gap: 1rem;
}
h3,h1 {
font-weight: bold;
text-transform: uppercase;
}
.masthead {
> article {
margin-bottom: 0.5rem;
}
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
display: flex;
gap: 1.5rem ;
flex-wrap: wrap;
justify-content: center;
> li {
display: flex;
text-wrap: nowrap;
}
}
section {
> .stack {
margin-left: 1rem;
}
}
.meta{
display: flex;
gap: 1.5rem;
margin-left: 1.5rem;
> div{
display: flex;
gap: 1.5rem;
}
}
article {
> header {
display: flex;
}
> .timeline {
margin-left: 0.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
> div {
> div:first-child {
display: flex;
}
> p {
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
> ul {
justify-content: flex-start;
gap: 0;
> li {
&::before {
content: "•";
margin-right: 0.25rem;
}
}
}
}
}
}
#volunteer,#education,#projects,#awards,#publications {
article {
> p,ul,h5 {
margin-left: 0.5rem;
}
> ul {
display: flex;
justify-content: flex-start;
gap: 0.25rem 0.5rem;
> li {
&::before {
content: "•";
margin: auto 0.25rem;
}
}
}
}
}
.grid-list {
margin-left: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
> div {
display: flex;
gap: 1.5rem;
flex-wrap: nowrap;
> ul {
display: flex;
flex-wrap: wrap;
gap: 0.25rem 0.5rem;
justify-content: flex-start;
> li {
&::before {
content: "•";
margin: auto 0.25rem;
}
}
}
}
}
blockquote {
> p{
display: inline;
}
> p:last-child {
margin-left: auto;
&::before {
content: "—";
margin: auto 0.25rem;
font-size: 1.5rem;
font-weight: bold;
}
}
}
`;
function s(i, e = !1) {
const a = (
/** @type {string} */
j(i)
);
return e ? C(a) : a;
}
const I = (i) => new Date(i).toLocaleDateString("en", {
month: "short",
year: "numeric",
timeZone: "UTC"
});
function v(i) {
return t`<time datetime="${i}">${I(i)}</time>`;
}
function P(i = []) {
return i.length > 0 && t`
<section id="awards">
<h3>Awards</h3>
<div class="stack">
${i.map(
({ awarder: e, date: a, summary: n, title: r }) => t`
<article>
<header>
<h4>${r}</h4>
<div class="meta">
${e && t`<div>Awarded by <strong>${e}</strong></div>`} ${a && v(a)}
</div>
</header>
${n && s(n)}
</article>
`
)}
</div>
</section>
`;
}
const R = (i) => i.replace(/^(https?:|)\/\//, "").replace(/\/$/, "");
function p(i, e) {
return e ? i ? t`<a href="${i}">${e}</a>` : e : i && t`<a href="${i}">${R(i)}</a>`;
}
function S(i = []) {
return i.length > 0 && t`
<section id="certificates">
<h3>Certificates</h3>
<div class="stack">
${i.map(
({ date: e, issuer: a, name: n, url: r }) => t`
<article>
<header>
<h4>${p(r, n)}</h4>
<div class="meta">
${a && t`<div>Issued by <strong>${a}</strong></div>`} ${e && v(e)}
</div>
</header>
</article>
`
)}
</div>
</section>
`;
}
function u(i, e) {
return e === i ? v(e) : t`<time-duration>${v(i)} – ${e ? v(e) : "Present"}</time-duration>`;
}
function q(i = []) {
return i.length > 0 && t`
<section id="education">
<h3>Education</h3>
<div class="stack">
${i.map(
({ area: e, courses: a = [], institution: n, startDate: r, endDate: c, studyType: l, url: o }) => t`
<article>
<header>
<h4>${p(o, n)}</h4>
<div class="meta">
${l && t`<strong>${l}</strong> on`}
${e && t`<strong>${e}</strong>`}
${r && t`<div>${u(r, c)}</div>`}
</div>
</header>
${a.length > 0 && t`
<h5>Courses</h5>
<ul>
${a.map((d) => t`<li>${s(d)}</li>`)}
</ul>
`}
</article>
`
)}
</div>
</section>
`;
}
function f(i, e) {
return (x.icons[
/** @type {FeatherIconNames} */
i.toLowerCase()
] || e && x.icons[
/** @type {FeatherIconNames} */
e.toLowerCase()
])?.toSvg({ width: 16, height: 16 });
}
const z = (i) => (
/*Intl.DisplayNames ? new Intl.DisplayNames(['en'], { type: 'region' }).of(countryCode) :*/
i
);
function A(i = {}) {
const { email: e, image: a, label: n, location: r, name: c, phone: l, profiles: o = [], summary: d, url: $ } = i;
return t`
<header class="masthead">
${a && t`<img src="${a}" alt="" />`}
<div>${c && t`<h1>${c}</h1>`} ${n && t`<h2>${n}</h2>`}</div>
${d && t`<article>${s(d)}</article>`}
<ul class="icon-list">
${r?.city && t`
<li>
${f("map-pin")} ${r.city}${r.countryCode && t`, ${z(r.countryCode)}`}
</li>
`}
${e && t`
<li>
${f("mail")}
<a href="mailto:${e}">${e}</a>
</li>
`}
${l && t`
<li>
${f("phone")}
<a href="tel:${l.replace(/\s/g, "")}">${l}</a>
</li>
`}
${$ && t`<li>${f("link")} ${p($)}</li>`}
${o.map(
({ network: h, url: m, username: g }) => t`
<li>
${h && f(h, "user")} ${p(m, g)}
${h && t`<span class="network">(${h})</span>`}
</li>
`
)}
</ul>
</header>
`;
}
function W(i = []) {
return i.length > 0 && t`
<section id="interests">
<h3>Interests</h3>
<div class="grid-list">
${i.map(
({ keywords: e = [], name: a }) => t`
<div>
${a && t`<h4>${a}</h4>`}
${e.length > 0 && t`
<ul class="tag-list">
${e.map((n) => t`<li>${n}</li>`)}
</ul>
`}
</div>
`
)}
</div>
</section>
`;
}
function E(i = []) {
return i.length > 0 && t`
<section id="languages">
<h3>Languages</h3>
<div class="grid-list">
${i.map(
({ fluency: e, language: a }) => t`<div>${a && t`<h4>${a}</h4>`} ${e}</div>`
)}
</div>
</section>
`;
}
function F(i = {}) {
const { name: e, summary: a } = i;
return t`
${e && t`<title>${e}</title>`}
${a && t`<meta name="description" content="${s(a, !0)}" />`}
`;
}
const T = (i) => Intl.ListFormat ? new Intl.ListFormat("en").format(i) : i.join(", ");
function U(i = []) {
return i.length > 0 && t`
<section id="projects">
<h3>Projects</h3>
<div class="stack">
${i.map(
({
description: e,
entity: a,
highlights: n = [],
keywords: r = [],
name: c,
startDate: l,
endDate: o,
roles: d = [],
type: $,
url: h
}) => t`
<article>
<header>
<h4>${p(h, c)}</h4>
<div class="meta">
<div>
${d.length > 0 && t`<strong>${T(d)}</strong>`}
${a && t`at <strong>${a}</strong>`}
</div>
${l && t`<div>${u(l, o)}</div>`} ${$ && t`<div>${$}</div>`}
</div>
</header>
${e && s(e)}
${n.length > 0 && t`
<ul>
${n.map((m) => t`<li>${s(m)}</li>`)}
</ul>
`}
${r.length > 0 && t`
<ul class="tag-list">
${r.map((m) => t`<li>${m}</li>`)}
</ul>
`}
</article>
`
)}
</div>
</section>
`;
}
function V(i = []) {
return i.length > 0 && t`
<section id="publications">
<h3>Publications</h3>
<div class="stack">
${i.map(
({ name: e, publisher: a, releaseDate: n, summary: r, url: c }) => t`
<article>
<header>
<h4>${p(c, e)}</h4>
<div class="meta">
${a && t`<div>Published by <strong>${a}</strong></div>`}
${n && v(n)}
</div>
</header>
${r && s(r)}
</article>
`
)}
</div>
</section>
`;
}
function B(i = []) {
return i.length > 0 && t`
<section id="references">
<h3>References</h3>
<div class="stack">
${i.map(
({ name: e, reference: a }) => t`
<blockquote>
${a && s(a)}
${e && t`
<p>
<cite>${e}</cite>
</p>
`}
</blockquote>
`
)}
</div>
</section>
`;
}
function H(i = []) {
return i.length > 0 && t`
<section id="skills">
<h3>Skills</h3>
<div class="grid-list">
${i.map(
({ keywords: e = [], name: a }) => t`
<div>
${a && t`<h4>${a}</h4>`}
${e.length > 0 && t`
<ul class="tag-list">
${e.map((n) => t`<li>${n}</li>`)}
</ul>
`}
</div>
`
)}
</div>
</section>
`;
}
function M(i = []) {
return i.length > 0 && t`
<section id="volunteer">
<h3>Volunteer</h3>
<div class="stack">
${i.map(
({ highlights: e = [], organization: a, position: n, startDate: r, endDate: c, summary: l, url: o }) => t`
<article>
<header>
<h4>${p(o, a)}</h4>
<div class="meta">
<strong>${n}</strong>
${r && t`<div>${u(r, c)}</div>`}
</div>
</header>
${l && s(l)}
${e.length > 0 && t`
<ul>
${e.map((d) => t`<li>${s(d)}</li>`)}
</ul>
`}
</article>
`
)}
</div>
</section>
`;
}
function O(i = []) {
const e = i.reduce(
(a, { description: n, name: r, url: c, ...l }) => {
const o = a[a.length - 1];
return o && o.name === r && o.description === n && o.url === c ? o.items.push(l) : a.push({ description: n, name: r, url: c, items: [l] }), a;
},
/** @type {NestedWork[]} */
[]
);
return i.length > 0 && t`
<section id="work">
<h3>Work</h3>
<div class="stack">
${e.map(
({ description: a, name: n, url: r, items: c = [] }) => t`
<article>
<header>
<h4>${p(r, n)}</h4>
<div class="meta">${a && t`<div>${a}</div>`}</div>
</header>
<div class="timeline">
${c.map(
({ highlights: l = [], location: o, position: d, startDate: $, endDate: h, summary: m }) => t`
<div>
<div>
<h5>${d}</h5>
<div class="meta">
${$ && t`<div>${u($, h)}</div>`}
${o && t`<div>${o}</div>`}
</div>
</div>
${m && s(m)}
${l.length > 0 && t`
<ul>
${l.map((g) => t`<li>${s(g)}</li>`)}
</ul>
`}
</div>
`
)}
</div>
</article>
`
)}
</div>
</section>
`;
}
var k;
function Z(i, { css: e, js: a } = {}) {
return t`<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
${F(i.basics)}
<meta name="viewport" content="width=device-width, initial-scale=1" />
${e && t`<style>
${e}
</style>`}
${a && t(k || (k = b([`<script type="module">
`, `
<\/script>`])), a)}
</head>
<body>
${A(i.basics)} ${O(i.work)} ${M(i.volunteer)} ${q(i.education)}
${U(i.projects)} ${P(i.awards)} ${S(i.certificates)}
${V(i.publications)} ${H(i.skills)} ${E(i.languages)}
${W(i.interests)} ${B(i.references)}
</body>
</html>`;
}
const X = {
mediaType: "print",
printBackground: !0
}, Y = (i) => Z(i, { css: L, js: "" });
export {
X as pdfRenderOptions,
Y as render
};