@warleon/jsonresume-theme-compact
Version:
A JSON Resume theme, compatible with the latest resume schema
445 lines (430 loc) • 13.8 kB
JavaScript
(function(c,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("@rbardini/html"),require("micromark"),require("striptags"),require("feather-icons")):typeof define=="function"&&define.amd?define(["exports","@rbardini/html","micromark","striptags","feather-icons"],e):(c=typeof globalThis<"u"?globalThis:c||self,e(c.jsonresumeThemeEven={},c.html,c.micromark,c.striptags,c.feather))})(this,function(c,e,j,L,b){"use strict";var x=Object.freeze,J=Object.defineProperty;var k=(c,e)=>x(J(c,"raw",{value:x(e||c.slice())}));var w;const C=`
: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;
}
}
article {
> header {
display: flex;
> .meta{
display: flex;
gap: 0.25rem;
&::before{
content: ":";
}
}
}
> .timeline {
margin-left: 0.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
> div {
> div:first-child {
display: flex;
> .meta{
display: flex;
gap: 0.25rem;
&::before{
content: ":";
margin-right: 0.25rem;
}
}
}
> p {
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
> ul {
justify-content: flex-start;
flex-direction: column;
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 d(i,t=!1){const n=j(i);return t?L(n):n}const I=i=>new Date(i).toLocaleDateString("en",{month:"short",year:"numeric",timeZone:"UTC"});function p(i){return e.html`<time datetime="${i}">${I(i)}</time>`}function q(i=[]){return i.length>0&&e.html`
<section id="awards">
<h3>Awards</h3>
<div class="stack">
${i.map(({awarder:t,date:n,summary:a,title:r})=>e.html`
<article>
<header>
<h4>${r}</h4>
<div class="meta">
${t&&e.html`<div>Awarded by <strong>${t}</strong></div>`} ${n&&p(n)}
</div>
</header>
${a&&d(a)}
</article>
`)}
</div>
</section>
`}const P=i=>i.replace(/^(https?:|)\/\//,"").replace(/\/$/,"");function h(i,t){return t?i?e.html`<a href="${i}">${t}</a>`:t:i&&e.html`<a href="${i}">${P(i)}</a>`}function R(i=[]){return i.length>0&&e.html`
<section id="certificates">
<h3>Certificates</h3>
<div class="stack">
${i.map(({date:t,issuer:n,name:a,url:r})=>e.html`
<article>
<header>
<h4>${h(r,a)}</h4>
<div class="meta">
${n&&e.html`<div>Issued by <strong>${n}</strong></div>`} ${t&&p(t)}
</div>
</header>
</article>
`)}
</div>
</section>
`}function g(i,t){return t===i?p(t):e.html`<time-duration>${p(i)} – ${t?p(t):"Present"}</time-duration>`}function S(i=[]){return i.length>0&&e.html`
<section id="education">
<h3>Education</h3>
<div class="stack">
${i.map(({area:t,courses:n=[],institution:a,startDate:r,endDate:o,studyType:l,url:s})=>e.html`
<article>
<header>
<h4>${h(s,a)}</h4>
<div class="meta">
${t&&e.html`<strong>${t}</strong>`}
${r&&e.html`<div>${g(r,o)}</div>`}
</div>
</header>
${l&&d(l)}
${n.length>0&&e.html`
<h5>Courses</h5>
<ul>
${n.map($=>e.html`<li>${d($)}</li>`)}
</ul>
`}
</article>
`)}
</div>
</section>
`}function v(i,t){return(b.icons[i.toLowerCase()]||t&&b.icons[t.toLowerCase()])?.toSvg({width:16,height:16})}const T=i=>Intl.DisplayNames?new Intl.DisplayNames(["en"],{type:"region"}).of(i):i;function z(i={}){const{email:t,image:n,label:a,location:r,name:o,phone:l,profiles:s=[],summary:$,url:m}=i;return e.html`
<header class="masthead">
${n&&e.html`<img src="${n}" alt="" />`}
<div>${o&&e.html`<h1>${o}</h1>`} ${a&&e.html`<h2>${a}</h2>`}</div>
${$&&e.html`<article>${d($)}</article>`}
<ul class="icon-list">
${r?.city&&e.html`
<li>
${v("map-pin")} ${r.city}${r.countryCode&&e.html`, ${T(r.countryCode)}`}
</li>
`}
${t&&e.html`
<li>
${v("mail")}
<a href="mailto:${t}">${t}</a>
</li>
`}
${l&&e.html`
<li>
${v("phone")}
<a href="tel:${l.replace(/\s/g,"")}">${l}</a>
</li>
`}
${m&&e.html`<li>${v("link")} ${h(m)}</li>`}
${s.map(({network:u,url:f,username:y})=>e.html`
<li>
${u&&v(u,"user")} ${h(f,y)}
${u&&e.html`<span class="network">(${u})</span>`}
</li>
`)}
</ul>
</header>
`}function A(i=[]){return i.length>0&&e.html`
<section id="interests">
<h3>Interests</h3>
<div class="grid-list">
${i.map(({keywords:t=[],name:n})=>e.html`
<div>
${n&&e.html`<h4>${n}</h4>`}
${t.length>0&&e.html`
<ul class="tag-list">
${t.map(a=>e.html`<li>${a}</li>`)}
</ul>
`}
</div>
`)}
</div>
</section>
`}function E(i=[]){return i.length>0&&e.html`
<section id="languages">
<h3>Languages</h3>
<div class="grid-list">
${i.map(({fluency:t,language:n})=>e.html`<div>${n&&e.html`<h4>${n}</h4>`} ${t}</div>`)}
</div>
</section>
`}function O(i={}){const{name:t,summary:n}=i;return e.html`
${t&&e.html`<title>${t}</title>`}
${n&&e.html`<meta name="description" content="${d(n,!0)}" />`}
`}const W=i=>Intl.ListFormat?new Intl.ListFormat("en").format(i):i.join(", ");function F(i=[]){return i.length>0&&e.html`
<section id="projects">
<h3>Projects</h3>
<div class="stack">
${i.map(({description:t,entity:n,highlights:a=[],keywords:r=[],name:o,startDate:l,endDate:s,roles:$=[],type:m,url:u})=>e.html`
<article>
<header>
<h4>${h(u,o)}</h4>
<div class="meta">
<div>
${$.length>0&&e.html`<strong>${W($)}</strong>`}
${n&&e.html`at <strong>${n}</strong>`}
</div>
${l&&e.html`<div>${g(l,s)}</div>`} ${m&&e.html`<div>${m}</div>`}
</div>
</header>
${t&&d(t)}
${a.length>0&&e.html`
<ul>
${a.map(f=>e.html`<li>${d(f)}</li>`)}
</ul>
`}
${r.length>0&&e.html`
<ul class="tag-list">
${r.map(f=>e.html`<li>${f}</li>`)}
</ul>
`}
</article>
`)}
</div>
</section>
`}function M(i=[]){return i.length>0&&e.html`
<section id="publications">
<h3>Publications</h3>
<div class="stack">
${i.map(({name:t,publisher:n,releaseDate:a,summary:r,url:o})=>e.html`
<article>
<header>
<h4>${h(o,t)}</h4>
<div class="meta">
${n&&e.html`<div>Published by <strong>${n}</strong></div>`}
${a&&p(a)}
</div>
</header>
${r&&d(r)}
</article>
`)}
</div>
</section>
`}function N(i=[]){return i.length>0&&e.html`
<section id="references">
<h3>References</h3>
<div class="stack">
${i.map(({name:t,reference:n})=>e.html`
<blockquote>
${n&&d(n)}
${t&&e.html`
<p>
<cite>${t}</cite>
</p>
`}
</blockquote>
`)}
</div>
</section>
`}function U(i=[]){return i.length>0&&e.html`
<section id="skills">
<h3>Skills</h3>
<div class="grid-list">
${i.map(({keywords:t=[],name:n})=>e.html`
<div>
${n&&e.html`<h4>${n}</h4>`}
${t.length>0&&e.html`
<ul class="tag-list">
${t.map(a=>e.html`<li>${a}</li>`)}
</ul>
`}
</div>
`)}
</div>
</section>
`}function V(i=[]){return i.length>0&&e.html`
<section id="volunteer">
<h3>Volunteer</h3>
<div class="stack">
${i.map(({highlights:t=[],organization:n,position:a,startDate:r,endDate:o,summary:l,url:s})=>e.html`
<article>
<header>
<h4>${h(s,n)}</h4>
<div class="meta">
<strong>${a}</strong>
${r&&e.html`<div>${g(r,o)}</div>`}
</div>
</header>
${l&&d(l)}
${t.length>0&&e.html`
<ul>
${t.map($=>e.html`<li>${d($)}</li>`)}
</ul>
`}
</article>
`)}
</div>
</section>
`}function B(i=[]){const t=i.reduce((n,{description:a,name:r,url:o,...l})=>{const s=n[n.length-1];return s&&s.name===r&&s.description===a&&s.url===o?s.items.push(l):n.push({description:a,name:r,url:o,items:[l]}),n},[]);return i.length>0&&e.html`
<section id="work">
<h3>Work</h3>
<div class="stack">
${t.map(({description:n,name:a,url:r,items:o=[]})=>e.html`
<article>
<header>
<h4>${h(r,a)}</h4>
<div class="meta">${n&&e.html`<div>${n}</div>`}</div>
</header>
<div class="timeline">
${o.map(({highlights:l=[],location:s,position:$,startDate:m,endDate:u,summary:f})=>e.html`
<div>
<div>
<h5>${$}</h5>
<div class="meta">
${m&&e.html`<div>${g(m,u)}</div>`}
${s&&e.html`<div>${s}</div>`}
</div>
</div>
${f&&d(f)}
${l.length>0&&e.html`
<ul>
${l.map(y=>e.html`<li>${d(y)}</li>`)}
</ul>
`}
</div>
`)}
</div>
</article>
`)}
</div>
</section>
`}function H(i,{css:t,js:n}={}){return e.html`
<html lang="en">
<head>
<meta charset="utf-8" />
${O(i.basics)}
<meta name="viewport" content="width=device-width, initial-scale=1" />
${t&&e.html`<style>
${t}
</style>`}
${n&&e.html(w||(w=k([`<script type="module">
`,`
<\/script>`])),n)}
</head>
<body>
${z(i.basics)} ${B(i.work)} ${V(i.volunteer)} ${S(i.education)}
${F(i.projects)} ${q(i.awards)} ${R(i.certificates)}
${M(i.publications)} ${U(i.skills)} ${E(i.languages)}
${A(i.interests)} ${N(i.references)}
</body>
</html>`}const Z={mediaType:"print",printBackground:!0},G=i=>H(i,{css:C,js:""});c.pdfRenderOptions=Z,c.render=G,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});