UNPKG

@warleon/jsonresume-theme-compact

Version:

A JSON Resume theme, compatible with the latest resume schema

578 lines (563 loc) 14.1 kB
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 };