Add stackoverflow theme

This commit is contained in:
Arnaud Ysmal 2018-05-08 15:23:46 +02:00
parent 63df11b783
commit 53aacbe1b0
8 changed files with 1402 additions and 67 deletions

View File

@ -2,6 +2,7 @@ jsonresume written in go
------------------------
kendall and kendallfr themes are based on https://github.com/LinuxBozo/jsonresume-theme-kendall.
stackoverflow theme is based on https://github.com/francescoes/jsonresume-theme-stackoverflow.
`$ go build -o jsonresume ./cli`
`$ ./jsonresume -t kendall -r resume-schema/examples/valid/complete.json -o resume.html && cp themes/kendall/*.css .`

View File

@ -35,6 +35,7 @@ import (
"jsonresume/themes"
_ "jsonresume/themes/kendall"
_ "jsonresume/themes/kendallfr"
_ "jsonresume/themes/stackoverflow"
)
func main() {

View File

@ -104,6 +104,7 @@ type Work struct {
EndDate ResumeDate `json:"endDate"`
Summary string `json:"summary"`
Highlights []string `json:"highlights"`
Keywords []string `json:"keywords"`
}
// Volunteer is the volunteer details of the resume owner.
@ -115,6 +116,7 @@ type Volunteer struct {
EndDate ResumeDate `json:"endDate"`
Summary string `json:"summary"`
Highlights []string `json:"highlights"`
Keywords []string `json:"keywords"`
}
// Education is the education details of the resume owner.

View File

@ -26,12 +26,9 @@
package kendall
import (
"fmt"
"io/ioutil"
"jsonresume/model"
"jsonresume/themes"
"path"
"strings"
"text/template"
)
@ -46,10 +43,10 @@ var Theme = themes.Theme{
Name: "kendall",
Directory: packageDirectory,
Functions: template.FuncMap{
"iconClass": iconClass,
"formatDateWork": formatDateWork,
"formatDateEdu": formatDateEdu,
"formatDatePub": formatDatePub,
"iconClass": themes.IconClass,
"formatDateWork": themes.FormatDateWork,
"formatDateEdu": themes.FormatDateEdu,
"formatDatePub": themes.FormatDatePub,
"css": getCSS,
"printcss": getPrintCSS,
},
@ -68,63 +65,3 @@ func getPrintCSS() string {
r, _ := ioutil.ReadFile(path.Join(packageDirectory, fileCSSPrint))
return string(r)
}
func iconClass(network string) string {
network = strings.ToLower(network)
switch network {
// special cases
case "google-plus":
case "googleplus":
return "fa fa-google-plus"
case "flickr":
case "flicker":
return "fa fa-flickr"
case "dribbble":
case "dribble":
return "fa fa-dribbble"
case "codepen":
return "fa fa-codepen"
case "soundcloud":
return "fa fa-soundcloud"
case "reddit":
return "fa fa-reddit"
case "tumblr":
case "tumbler":
return "fa fa-tumblr"
case "stack-overflow":
case "stackoverflow":
return "fa fa-stack-overflow"
case "blog":
case "rss":
return "fa fa-rss"
case "gitlab":
return "fa fa-gitlab"
case "keybase":
return "fa fa-key"
default:
return "fa fa-" + network
}
return "fa fa-" + network
}
func formatDateWork(date model.ResumeDate) string {
if date.IsZero() {
return "Present"
}
return fmt.Sprintf("%s %d", date.Month().String(), date.Year())
}
func formatDateEdu(date model.ResumeDate) string {
if date.IsZero() {
return "Present"
}
return fmt.Sprintf("%d", date.Year())
}
func formatDatePub(date model.ResumeDate) string {
if date.IsZero() {
return "Present"
}
return fmt.Sprintf("%d %s %d", date.Day(), date.Month().String(), date.Year())
}

View File

@ -0,0 +1,500 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<title>Resume of {{.Basic.Name}}</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.12/css/all.css" integrity="sha384-G0fIWCsCzJIMAVNQPfjH08cyYaUtMwjJwqiRKxxE/rx96Uroj1BtIQ6MLJuheaO9" crossorigin="anonymous">
<style>
{{css}}
</style>
</head>
<body>
<div id="resume">
<header id="header" class="clear">
{{if .Basic.Image -}}
<img class="picture" src="{{.Basic.Image}}" alt="{{.Basic.Name}}" />
<div class="middle">
<h1 class="name">{{.Basic.Name}}</h1>
<h2 class="label">{{.Basic.Label}}</h2>
</div>
{{else -}}
<div>
<h1 class="name">{{.Basic.Name}}</h1>
<h2 class="label">{{.Basic.Label}}</h2>
</div>
{{- end}}
{{if .Basic.ResumeLocation.City}}
<span class="location">
{{if .Basic.ResumeLocation.Address}}
<span class="address">{{.Basic.ResumeLocation.Address}},</span>
{{- end}}
{{if .Basic.ResumeLocation.PostalCode}}
<span class="postalCode">{{.Basic.ResumeLocation.PostalCode}},</span>
{{- end}}
{{if .Basic.ResumeLocation.City}}
<span class="city">{{.Basic.ResumeLocation.City}},</span>
{{- end}}
{{if .Basic.ResumeLocation.Region}}
<span class="region">{{.Basic.ResumeLocation.Region}}</span>
{{- end}}
{{if .Basic.ResumeLocation.CountryCode}}
<span class="countryCode">{{.Basic.ResumeLocation.CountryCode}}</span>
{{- end}}
</span>
{{- end}}
<div id="contact">
{{if .Basic.URL}}
<div class="website">
<span class="fas fa-external-link-alt"></span>
<a target="_blank" target="_blank" href="{{.Basic.URL}}">{{.Basic.URL}}</a>
</div>
{{- end}}
{{if .Basic.Email}}
<div class="email">
<span class="far fa-envelope"></span>
<a href="mailto:{{.Basic.Email}}">{{.Basic.Email}}</a>
</div>
{{- end}}
{{if .Basic.Phone}}
<div class="phone">
<span class="fas fa-mobile-alt"></span>
<a href="tel:{{.Basic.Phone}}">{{.Basic.Phone}}</a>
</div>
{{- end}}
</div>
{{if .Basic.Profiles}}
<div id="profiles">
{{range .Basic.Profiles}}
<div class="item">
{{if .Network}}
<div class="username">
<span class="fab fa-{{tolower .Network}} {{.Network}} social"></span>
{{if .URL}}
<span class="url">
<a target="_blank" href="{{.URL}}">{{.UserName}}</a>
</span>
{{else}}
<span>{{.UserName}}</span>
{{- end}}
</div>
{{- end}}
</div>
{{- end}}
</div>
{{- end}}
</header>
{{if .Basic.Summary}}
<section class="section main-summary">
<section>
<div>{{.Basic.Summary}}</div>
</section>
</section>
{{- end}}
{{if .Skills}}
<section class="section margin1">
<header>
<h2 class='section-title'>Skills</h2>
</header>
<section id="skills">
{{range .Skills}}
<div class="item">
{{if .Name}}<h3 class="name">{{.Name}}</h3>{{end}}
{{if .Level}}<div class="level {{tolower .Level}}"><em>{{.Level}}</em><div class="bar"></div></div>{{end}}
{{if .Keywords -}}
<ul class="keywords">
{{range .Keywords}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
</div>
{{- end}}
</section>
</section>
{{- end}}
{{if .Work}}
<section class="section">
<header>
<h2 class='section-title'>Work Experience <span class="item-count">({{len .Work}})</span></h2>
</header>
<section id="work">
{{range $index, $w := .Work}}
<section class="work-item">
{{if $w.Name}}
{{if eq $index 0}}
<input id="work-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else}}
<input id="work-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="work-item-{{$index}}"></label>
<header>
{{if $w.Position}}
<div class="position">{{$w.Position}}</div>
{{- end}}
<div class="company">{{$w.Name}}</div>
<div class="date">
<span class="startDate">{{formatDateWork $w.StartDate}}</span>
<span class="endDate">- {{formatDateWork $w.EndDate}}</span>
</div>
</header>
{{- end}}
{{if $w.WorkLocation}}
<span class="location">
<span class="fas fa-map-marker-alt"></span>
{{if $w.WorkLocation}}
<span class="city">{{$w.WorkLocation}},</span>
{{- end}}
</span>
{{end}}
{{if $w.URL}}
<span class="website">
<a target="_blank" href="{{$w.URL}}">{{$w.URL}}</a>
</span> {{- end}}
{{if $w.Keywords -}}
<ul class="keywords">
{{range $w.Keywords}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
<div class="item" id="work-item">
{{if $w.Summary}}<div class="summary"><p>{{$w.Summary}}</p></div>{{end}}
{{if $w.Highlights -}}
<ul class="highlights">
{{range $w.Highlights}}<li>{{.}}</li>{{end}}
</ul>{{end}}
</div>
</section>
{{end}}
</section>
</section>
{{- end}}
{{if .Projects}}
<section class="section">
<header>
<h2 class='section-title'>Projects <span class="item-count">({{len .Projects}})</span></h2>
</header>
<section id="projects">
{{range $index, $p := .Projects}}
<section class="project-item">
{{if eq $index 0}}
<input id="project-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else}}
<input id="project-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="project-item-{{$index}}"></label>
{{if $p.Name}}
<header>
{{if $p.Name}}
<div class="position">{{$p.Name}}</div>
{{- end}}
{{if $p.StartDate}}
<div class="date">
<span class="startDate">{{formatDateWork $p.StartDate}}</span>
<span class="endDate">- {{formatDateWork $p.EndDate}}</span>
</div>
{{- end}}
</header>
{{- end}}
{{if $p.URL}}
<span class="website">
<a target="_blank" href="{{$p.URL}}">{{$p.URL}}</a>
</span>
{{- end}}
{{if $p.Keywords}}
<ul class="keywords">
{{range $p.Keywords}}
<li>{{.}}</li>
{{end}}
</ul>
{{- end}}
<div class="item">
{{if $p.Description}}<div class="summary"><p>{{$p.Description}}</p></div>{{end}}
{{if $p.Highlights}}<ul class="highlights">{{range $p.Highlights}}<li>{{.}}</li>{{end}}</ul>{{end}}
</div>
</section>
{{- end}}
</section>
</section>
{{- end}}
{{if .Volunteer}}
<section class="section">
<header>
<h2 class='section-title'>Volunteer</h2>
</header>
<section id="volunteer">
{{range $index, $v := .Volunteer}}
<section class="volunteer-item">
{{if $v.Organization}}
{{if eq $index 0}}
<input id="volunteer-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else}}
<input id="volunteer-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="volunteer-item-{{$index}}"></label>
<header>
<div class="header-left">
{{if $v.Position}}<div class="position">{{$v.Position}}</div>{{end}}
<div class="organization">
{{$v.Organization}}
</div>
</div>
<div class="date">
{{if $v.StartDate}}<span class="startDate">{{formatDateWork $v.StartDate}}</span>{{- end}}
<span class="endDate"> - {{formatDateWork $v.EndDate}}</span>
</div>
</header>
{{- end}}
{{if $v.URL}}
<div class="website">
<a target="_blank" href="{{$v.URL}}">{{$v.URL}}</a>
</div>
{{- end}}
{{if $v.Keywords}}<ul class="keywords">{{range $v.Keywords}}<li>{{.}}</li>{{end}}</ul>{{end}}
<div class="item">
<div class="summary"><p></p></div>
{{if $v.Summary}}<div class="summary"><p>{{$v.Summary}}</p></div>{{end}}
{{if $v.Highlights}}
<ul class="highlights">
{{range $v.Highlights}}<li><p>{{.}}</p></li>{{end}}
</ul>
{{- end}}
</div>
</section>
{{end}}
</section>
</section>
{{- end}}
{{if .Education}}
<section class="section">
<header>
<h2 class='section-title'>Education <span class="item-count">({{len .Education}})</span></h2>
</header>
<section id="education">
{{range $index, $e := .Education}}
<section class="education-item">
{{if eq $index 0}}
<input id="education-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else}}
<input id="education-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="education-item-{{$index}}"></label>
<header class="clear">
<div class="header-left">
{{if $e.StudyType}}<div class="studyType">{{$e.StudyType}}</div>{{end}}
{{if $e.Area}}<div class="area">{{$e.Area}}</div>{{end}}
{{if $e.Institution}} <div class="institution">{{$e.Institution}}</div>{{end}}
</div>
<div class="date">
{{if $e.StartDate}}<span class="startDate">{{formatDateEdu $e.StartDate}}</span>{{end}}
<span class="endDate"> - {{formatDateEdu $e.EndDate}} </span>
</div>
</header>
{{if $e.Courses}}
<ul class="courses">
{{range $e.Courses}}<li>{{.}}</li>{{end}}
</ul>
{{- end}}
<div class="item">
{{if $e.GPA}}
<div class='gpa'>
<strong> Grade:</strong> <span>{{$e.GPA}}</span>
</div>
{{- end}}
</div>
</section>
{{- end}}
</section>
</section>
{{- end}}
{{if .Awards}}
<section class="section">
<header>
<h2 class='section-title'>Awards</h2>
</header>
<section id="awards">
{{range $index, $a := .Awards}}
<section class="award-item">
{{if eq $index 0}}
<input id="award-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else}}
<input id="award-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="award-item-{{$index}}"></label>
<header>
<div class="header-left">
{{if $a.Title}}
<div class="title">
{{$a.Title}}
</div>
{{- end}}
{{if $a.Awarder}}
<div class="awarder">
{{$a.Awarder}}
</div>
{{- end}}
</div>
{{if $a.Date}}
<div class="date">
{{formatDatePub $a.Date}}
</div>
{{- end}}
</header>
<div class="item">
{{if $a.Summary}}
<div class="summary">
<p>{{$a.Summary}}</p>
</div>
{{- end}}
</div>
</section>
{{- end}}
</section>
</section>
{{- end}}
{{if .Publications}}
<section class="section">
<header>
<h2 class='section-title'>Publications</h2>
</header>
<section id="publications">
{{range $index, $p := .Publications}}
<section class="publication-item">
{{if eq $index 0}}
<input id="publication-item-{{$index}}" type="checkbox" class="toggle-item" checked="checked" />
{{else}}
<input id="publication-item-{{$index}}" type="checkbox" class="toggle-item" />
{{- end}}
<label for="publication-item-{{$index}}"></label>
<header>
<div class="header-left">
{{if $p.Name}}
<span class="name">
{{if $p.URL}}
<span class="website">
<a target="_blank" href="{{$p.URL}}">{{$p.Name}}</a>
</span>
{{else}}
{{$p.Name}}
{{- end}}
</span>
{{- end}}
{{if $p.Publisher}}
<span class="publisher">
in {{$p.Publisher}}
</span>
{{- end}}
</div>
{{if $p.ReleaseDate}}
<span class="date">
{{formatDatePub $p.ReleaseDate}}
</span>
{{- end}}
</header>
<div class="item">
{{if $p.Summary}}
<div class="summary">
<p>{{$p.Summary}}</p>
</div>
{{- end}}
</div>
</section>
{{end}}
</section>
</section>
{{- end}}
{{if .Languages}}
<section class="section margin1">
<header>
<h2 class='section-title'>Languages</h2>
</header>
<section id="languages">
{{range .Languages}}
<div class="display">
{{if .Language}}
<h3 class="language">
{{.Language}}
</h3>
{{- end}}
<div class="item">
{{if .Fluency}}
<div class="level fluency {{tolower .Fluency}}">
<em>{{.Fluency}}</em>
<div class="bar"></div>
</div>
{{- end}}
</div>
</div>
{{end}}
</section>
</section>
{{- end}}
{{if .Interests}}
<section class="section margin1">
<header>
<h2 class='section-title' class='section-title'>Interests</h2>
</header>
<section id="interests">
{{range .Interests}}
<div class="item">
{{if .Name}}
<h3 class="name">
{{.Name}}
</h3>
{{- end}}
{{if .Keywords}}
<ul class="keywords">
{{range .Keywords}}
<li>{{.}}</li>
{{- end}}
</ul>
{{- end}}
</div>
{{end}}
</section>
</section>
{{- end}}
{{if .References}}
<section class="section">
<header>
<h2 class='section-title'>References</h2>
</header>
<section id="references">
{{range .References}}
<div class="item">
{{if .Reference}}
<blockquote class="reference">
&#8220;&#32;{{.Reference}}&#32;&#8221;
</blockquote>
{{- end}}
{{if .Name}}
<div class="name">
{{.Name}}
</div>
{{- end}}
</div>
{{end}}
</section>
</section>
{{- end}}
</body>
</html>

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2018 Arnaud Ysmal. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
package kendall
import (
"io/ioutil"
"jsonresume/themes"
"path"
"strings"
"text/template"
)
const (
packageDirectory = "themes/stackoverflow"
fileCSS = "style.css"
fileTemplate = "resume.template"
)
var Theme = themes.Theme{
Name: "stackoverflow",
Directory: packageDirectory,
Functions: template.FuncMap{
"iconClass": themes.IconClass,
"formatDateWork": themes.FormatDateWork,
"formatDateEdu": themes.FormatDateEdu,
"formatDatePub": themes.FormatDatePub,
"css": getCSS,
"tolower": strings.ToLower,
},
Template: fileTemplate,
}
func init() {
(&Theme).Register()
}
func getCSS() string {
r, _ := ioutil.ReadFile(path.Join(packageDirectory, fileCSS))
return string(r)
}

771
themes/stackoverflow/style.css Executable file
View File

@ -0,0 +1,771 @@
/********************************************
* reset from
* http://meyerweb.com/eric/tools/css/reset/
*******************************************/
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
vertical-align: baseline;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/****************
* COMMONS
****************/
body,
html {
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-size: 13px;
color: #40484f;
font-weight: 400;
letter-spacing: 0;
line-height: 1.46153846;
text-align: left;
-webkit-text-size-adjust: 100%;
}
p {
display: block;
margin-bottom: 1.3em;
}
a {
color: #0095ff;
text-decoration: none;
}
a:hover {
color: #0c65a5;
text-decoration: underline;
}
ul {
margin-top: 1rem;
}
li {
list-style-type: square;
list-style-position: outside;
margin-left: 1.3em;
}
.highlights>li>p {
margin-bottom: 0.5em;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.67rem;
}
h3 {
font-size: 1.27rem;
}
em {
color: #757575;
}
blockquote {
margin-bottom: 1em;
}
strong {
font-weight: 700;
}
/* main container */
#resume {
padding: 1rem;
margin-top: 2rem;
}
/* every section wrapper */
.section {
margin-bottom: 1rem;
}
section .location {
margin-right: .5em;
color: #606d76;
font-weight: 700;
}
#contact {
margin-top: .5rem;
}
#profiles .item {
padding: 0;
}
#header>#profiles,
#header>#contact,
#skills,
#languages,
#interests {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
-webkit-justify-content: flex-start;
justify-content: flex-start;
}
#header>div {
line-height: 1.5;
}
#header>div>div {
margin-right: 1.2em;
}
#header h1.name {
font-size: 2.8rem;
font-weight: 100;
line-height: 100%;
}
#header h2.label {
color: #202931;
font-size: 1.47rem;
font-weight: 300;
}
#header .picture {
width: 11em;
float: right;
border-radius: 4px;
}
.main-summary {
background: #f1f8ff;
padding: 1.2em 1em;
margin-top: 1rem;
}
.main-summary p {
margin: .15em 0 0;
}
h2.section-title {
display: inline-block;
background: #fff;
padding: 0 1em 0.3em 0;
color: #ff6d1f;
text-transform: uppercase;
font-weight: 600;
border: none;
font-size: .9rem;
}
.section>header {
position: relative;
}
.fa {
margin-right: 0.25em;
}
.section>header::after {
position: absolute;
left: 0;
top: .7em;
height: 1px;
background: #ccc;
content: "";
width: 100%;
z-index: -100;
display: block;
}
.section.main-summary>section {
margin: 0;
}
.section>section>header {
font-size: 1.38rem;
position: relative;
margin-top: .7em;
}
.section>section>header:first-of-type {
margin: 0;
}
.section>section>header .space-left {
position: absolute;
left: -1.56rem;
top: 5px;
color: #aaa;
line-height: 1;
opacity: 0;
}
.position,
.company,
.organization,
.institution,
.date,
.area,
.studyType,
.title,
.awarder {
display: inline;
}
.position,
.studyType,
.area,
.title,
.language,
.name {
font-weight: 600;
}
.company::before,
.institution::before,
.organization::before,
.awarder::before {
content: "at "
}
.company,
.institution,
.organization,
.awarder {
color: #606d76;
font-weight: 400;
}
.section header .date {
font-size: 1rem;
display: inline-table;
padding: .1em 0;
font-weight: 600;
}
ul.keywords,
ul.courses {
margin-top: .5em;
}
ul.keywords li,
ul.courses li {
display: inline-block;
margin: 2px 2px 2px 0;
padding: 4px 5px 5px;
font-size: .9rem;
line-height: 1;
text-transform: lowercase;
color: #3e6d8e;
background-color: #dfeaf1;
border: 0 solid #dfeaf1;
white-space: nowrap;
}
ul.keywords li:hover,
ul.courses li:hover {
background: #dfeaf0;
}
.item {
padding: .5em 0;
}
.gpa {
padding-bottom: .5em;
}
.fa.social {
font-size: 1.1em;
}
/* Social Media Brand Colors */
.google-plus {
color: #dd4b39;
}
.tumblr {
color: #32506d;
}
.foursquare {
color: #0072b1;
}
.facebook {
color: #3b5998;
}
.linkedin {
color: #007bb6;
}
.pinterest {
color: #cb2027;
}
.dribbble {
color: #ea4c89;
}
.instagram {
color: #517fa4;
}
.twitter {
color: #00aced;
}
.soundcloud {
color: #ff3a00;
}
.wordpress {
color: #21759b;
}
.youtube {
color: #bb0000;
}
.github {
color: #171515;
}
.stack-overflow {
color: #828386;
position: relative;
}
.flickr {
color: #ff0084;
}
.reddit {
color: #ff4500;
}
.hacker-news {
color: #ff6600;
}
.stack-overflow::after {
position: absolute;
left: 0;
content: '\f16c';
color: #f68a1f;
overflow: hidden;
height: 100%;
}
.telegram {
color: #2291c3;
}
#languages .item,
#skills .item,
#interests .item {
width: 15em;
padding: 0 .5em .5em 0;
border-bottom: none;
}
#skills .item {
width: 16em;
}
#skills .item .keywords {
width: 15em;
}
/* Skill chart */
.level {
margin-bottom: .5em;
}
.level .bar {
border: 1px solid #ddd;
display: block;
width: 10em;
height: 5px;
position: relative;
}
.level .bar::after {
position: absolute;
content: " ";
top: 0;
left: 0;
background: black;
height: 5px;
}
.level.beginner .bar::after {
background: #EB5F51;
width: 2.5em;
}
.level.intermediate .bar::after {
background: #ffdf1f;
width: 5em;
}
.level.advanced .bar::after,
.level.fluent .bar::after {
background: #5CB85C;
width: 7.5em;
}
.level.master .bar::after,
.level.native.speaker .bar::after {
background: #59C596;
width: 10em;
}
#references .item {
padding-left: .5em;
border-left: 5px solid #ff6d1f;
}
.toggle-item {
visibility: hidden;
}
/******************
* HELPER CLASSES
******************/
.clear::after {
content: "";
display: table;
clear: both;
}
.display {
display: block;
opacity: 1 !important;
}
.margin1 {
margin-bottom: .5rem;
}
/****************
* TABLET
****************/
@media screen and (min-width: 602px) {
#resume {
width: 80%;
margin: 0 auto;
}
}
/****************
* LAPTOP
****************/
@media screen and (min-width: 1025px) {
li {
margin-left: 1.5em;
}
#resume {
width: 820px;
margin: 2rem auto;
}
.section>section>header .space-left {
opacity: 1;
cursor: pointer;
}
.section>section {
margin-left: 1.67rem;
}
.toggle-item {
transform: translate(-9999px);
}
.toggle-item+label {
display: block;
}
.toggle-item:checked+label:after {
content: "\f0d7";
}
.toggle-item+label:after {
float: left;
cursor: pointer;
margin-left: -20px;
color: #aaa;
font-size: 16px;
font-weight: 900;
font-family: "Font Awesome 5 Free";
content: "\f0da";
}
.toggle-item~.item {
height: 0;
opacity: 0;
}
.toggle-item:checked~.item {
height: auto;
opacity: 1;
transition: all .5s linear;
}
.company::before,
.institution::before,
.organization::before,
.awarder::before {
content: "| ";
}
.header-left {
float: left;
width: 70%;
word-break: normal;
}
.section header .date {
float: right;
padding: .2em;
}
.display {
display: none;
}
.display:not(.none) {
display: block;
}
}
@media print {
#resume {
margin: 0;
padding: 0;
-ms-word-wrap: break-word;
word-wrap: break-word;
line-height: 1.3;
/*font-family: Arial, Georgia, "Lucida Grande", sans-serif;*/
}
@page {
margin: 1cm 1.4cm;
}
.item-count {
display: none;
}
.company::before,
.institution::before,
.organization::before,
.awarder::before {
content: "at ";
}
.main-summary {
padding: 2rem 0;
}
.section {
margin: .8rem 0;
padding: 0;
}
.section header {
padding-bottom: .15rem;
}
.section .location {
padding-bottom: .15rem;
}
.stack-overflow::after {
content: "";
}
.fa.social {
color: #828386;
}
ul {
margin-top: .4em;
}
ul,
li {
padding: 0;
}
ul.keywords li,
ul.courses li {
margin: 0;
padding: 0;
font-size: .8rem;
text-transform: lowercase;
}
ul.keywords li::after,
ul.courses li::after {
padding: 0 0 0 .1rem;
content: " |";
}
ul.keywords::before,
ul.courses::before {
font-size: .8rem;
font-weight: 600;
}
ul.keywords::before {
content: "Skills acquired: ";
}
#skills .keywords::before {
content: '';
}
.section p {
margin: 0;
padding: 0;
}
ul.courses::before {
content: "Major courses: ";
}
ul.keywords li:last-of-type::after,
ul.courses li:last-of-type::after {
content: "";
}
.level em {
font-style: normal;
padding: .1em 0;
}
.level .bar {
display: none;
}
#profiles .item {
padding: 0;
}
.item.display {
display: block;
opacity: 1 !important;
}
}

View File

@ -30,6 +30,7 @@ import (
"io"
"jsonresume/model"
"path"
"strings"
"text/template"
)
@ -58,3 +59,63 @@ func (t *Theme) Register() error {
Themes[t.Name] = t
return nil
}
// Common functions
func IconClass(network string) string {
network = strings.ToLower(network)
switch network {
case "google-plus":
case "googleplus":
return "fa fa-google-plus"
case "flickr":
case "flicker":
return "fa fa-flickr"
case "dribbble":
case "dribble":
return "fa fa-dribbble"
case "codepen":
return "fa fa-codepen"
case "soundcloud":
return "fa fa-soundcloud"
case "reddit":
return "fa fa-reddit"
case "tumblr":
case "tumbler":
return "fa fa-tumblr"
case "stack-overflow":
case "stackoverflow":
return "fa fa-stack-overflow"
case "blog":
case "rss":
return "fa fa-rss"
case "gitlab":
return "fa fa-gitlab"
case "keybase":
return "fa fa-key"
default:
return "fa fa-" + network
}
return "fa fa-" + network
}
func FormatDateWork(date model.ResumeDate) string {
if date.IsZero() {
return "Present"
}
return fmt.Sprintf("%s %d", date.Month().String(), date.Year())
}
func FormatDateEdu(date model.ResumeDate) string {
if date.IsZero() {
return "Present"
}
return fmt.Sprintf("%d", date.Year())
}
func FormatDatePub(date model.ResumeDate) string {
if date.IsZero() {
return "Present"
}
return fmt.Sprintf("%d %s %d", date.Day(), date.Month().String(), date.Year())
}