From 53aacbe1b0270357e2bc97205d74e4a5353889f1 Mon Sep 17 00:00:00 2001 From: Arnaud Ysmal Date: Tue, 8 May 2018 15:23:46 +0200 Subject: [PATCH] Add stackoverflow theme --- README.md | 1 + cli/resume.go | 1 + model/json.go | 2 + themes/kendall/kendall.go | 71 +-- themes/stackoverflow/resume.template | 500 +++++++++++++++++ themes/stackoverflow/stackoverflow.go | 62 +++ themes/stackoverflow/style.css | 771 ++++++++++++++++++++++++++ themes/theme.go | 61 ++ 8 files changed, 1402 insertions(+), 67 deletions(-) create mode 100644 themes/stackoverflow/resume.template create mode 100644 themes/stackoverflow/stackoverflow.go create mode 100755 themes/stackoverflow/style.css diff --git a/README.md b/README.md index 3d78821..3b7d627 100644 --- a/README.md +++ b/README.md @@ -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 .` diff --git a/cli/resume.go b/cli/resume.go index 384b37a..ef71c07 100644 --- a/cli/resume.go +++ b/cli/resume.go @@ -35,6 +35,7 @@ import ( "jsonresume/themes" _ "jsonresume/themes/kendall" _ "jsonresume/themes/kendallfr" + _ "jsonresume/themes/stackoverflow" ) func main() { diff --git a/model/json.go b/model/json.go index 1693cc4..7eb6e87 100644 --- a/model/json.go +++ b/model/json.go @@ -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. diff --git a/themes/kendall/kendall.go b/themes/kendall/kendall.go index f0b976b..ba5b8a5 100644 --- a/themes/kendall/kendall.go +++ b/themes/kendall/kendall.go @@ -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()) -} diff --git a/themes/stackoverflow/resume.template b/themes/stackoverflow/resume.template new file mode 100644 index 0000000..3d4c121 --- /dev/null +++ b/themes/stackoverflow/resume.template @@ -0,0 +1,500 @@ + + + + + + Resume of {{.Basic.Name}} + + + + + + +
+ + + {{if .Basic.Summary}} +
+
+
{{.Basic.Summary}}
+
+
+ {{- end}} +{{if .Skills}} +
+
+

Skills

+
+
+ {{range .Skills}} +
+ {{if .Name}}

{{.Name}}

{{end}} + {{if .Level}}
{{.Level}}
{{end}} + {{if .Keywords -}} +
    + {{range .Keywords}}
  • {{.}}
  • {{end}} +
+ {{- end}} +
+ {{- end}} +
+
+{{- end}} +{{if .Work}} +
+
+

Work Experience ({{len .Work}})

+
+ +
+ {{range $index, $w := .Work}} +
+ {{if $w.Name}} + + {{if eq $index 0}} + + {{else}} + + {{- end}} + + +
+ {{if $w.Position}} +
{{$w.Position}}
+ {{- end}} +
{{$w.Name}}
+
+ {{formatDateWork $w.StartDate}} + - {{formatDateWork $w.EndDate}} +
+
+ {{- end}} + + {{if $w.WorkLocation}} + + + {{if $w.WorkLocation}} + {{$w.WorkLocation}}, + {{- end}} + + {{end}} + {{if $w.URL}} + + {{$w.URL}} + {{- end}} + {{if $w.Keywords -}} +
    + {{range $w.Keywords}}
  • {{.}}
  • {{end}} +
+ {{- end}} +
+ {{if $w.Summary}}

{{$w.Summary}}

{{end}} + {{if $w.Highlights -}} +
    + {{range $w.Highlights}}
  • {{.}}
  • {{end}} +
{{end}} +
+
+ {{end}} +
+
+{{- end}} +{{if .Projects}} +
+
+

Projects ({{len .Projects}})

+
+
+ {{range $index, $p := .Projects}} +
+ {{if eq $index 0}} + + {{else}} + + {{- end}} + + + {{if $p.Name}} +
+ {{if $p.Name}} +
{{$p.Name}}
+ {{- end}} + {{if $p.StartDate}} +
+ {{formatDateWork $p.StartDate}} + - {{formatDateWork $p.EndDate}} +
+ {{- end}} +
+ {{- end}} + {{if $p.URL}} + + {{$p.URL}} + + {{- end}} + {{if $p.Keywords}} +
    + {{range $p.Keywords}} +
  • {{.}}
  • + {{end}} +
+ {{- end}} +
+ {{if $p.Description}}

{{$p.Description}}

{{end}} + {{if $p.Highlights}}
    {{range $p.Highlights}}
  • {{.}}
  • {{end}}
{{end}} +
+
+ {{- end}} +
+
+{{- end}} +{{if .Volunteer}} +
+
+

Volunteer

+
+
+ {{range $index, $v := .Volunteer}} +
+ {{if $v.Organization}} + + {{if eq $index 0}} + + {{else}} + + {{- end}} + + +
+
+ {{if $v.Position}}
{{$v.Position}}
{{end}} +
+ {{$v.Organization}} +
+
+
+ {{if $v.StartDate}}{{formatDateWork $v.StartDate}}{{- end}} + - {{formatDateWork $v.EndDate}} +
+
+ {{- end}} + {{if $v.URL}} + + {{- end}} + {{if $v.Keywords}}
    {{range $v.Keywords}}
  • {{.}}
  • {{end}}
{{end}} +
+

+ {{if $v.Summary}}

{{$v.Summary}}

{{end}} + {{if $v.Highlights}} +
    + {{range $v.Highlights}}
  • {{.}}

  • {{end}} +
+ {{- end}} +
+
+ {{end}} +
+
+{{- end}} + +{{if .Education}} +
+
+

Education ({{len .Education}})

+
+ +
+ {{range $index, $e := .Education}} +
+ {{if eq $index 0}} + + {{else}} + + {{- end}} + +
+
+ {{if $e.StudyType}}
{{$e.StudyType}}
{{end}} + {{if $e.Area}}
{{$e.Area}}
{{end}} + {{if $e.Institution}}
{{$e.Institution}}
{{end}} +
+
+ {{if $e.StartDate}}{{formatDateEdu $e.StartDate}}{{end}} + - {{formatDateEdu $e.EndDate}} +
+
+ + {{if $e.Courses}} +
    + {{range $e.Courses}}
  • {{.}}
  • {{end}} +
+ {{- end}} + +
+ {{if $e.GPA}} +
+ Grade: {{$e.GPA}} +
+ {{- end}} +
+
+ {{- end}} +
+
+{{- end}} +{{if .Awards}} +
+
+

Awards

+
+
+ {{range $index, $a := .Awards}} +
+ {{if eq $index 0}} + + {{else}} + + {{- end}} + + +
+
+ {{if $a.Title}} +
+ {{$a.Title}} +
+ {{- end}} + {{if $a.Awarder}} +
+ {{$a.Awarder}} +
+ {{- end}} +
+ {{if $a.Date}} +
+ {{formatDatePub $a.Date}} +
+ {{- end}} +
+ +
+ {{if $a.Summary}} +
+

{{$a.Summary}}

+
+ {{- end}} +
+
+ {{- end}} +
+
+{{- end}} +{{if .Publications}} +
+
+

Publications

+
+
+ {{range $index, $p := .Publications}} +
+ {{if eq $index 0}} + + {{else}} + + {{- end}} + + +
+
+ {{if $p.Name}} + + {{if $p.URL}} + + {{$p.Name}} + + {{else}} + {{$p.Name}} + {{- end}} + + {{- end}} + {{if $p.Publisher}} + + in {{$p.Publisher}} + + {{- end}} +
+ {{if $p.ReleaseDate}} + + {{formatDatePub $p.ReleaseDate}} + + {{- end}} +
+ +
+ {{if $p.Summary}} +
+

{{$p.Summary}}

+
+ {{- end}} +
+
+ {{end}} +
+
+{{- end}} +{{if .Languages}} +
+
+

Languages

+
+
+ {{range .Languages}} +
+ {{if .Language}} +

+ {{.Language}} +

+ {{- end}} +
+ {{if .Fluency}} +
+ {{.Fluency}} +
+
+ {{- end}} +
+
+ {{end}} +
+
+{{- end}} +{{if .Interests}} +
+
+

Interests

+
+
+ {{range .Interests}} +
+ {{if .Name}} +

+ {{.Name}} +

+ {{- end}} + {{if .Keywords}} +
    + {{range .Keywords}} +
  • {{.}}
  • + {{- end}} +
+ {{- end}} +
+ {{end}} +
+
+{{- end}} + +{{if .References}} +
+
+

References

+
+
+ {{range .References}} +
+ {{if .Reference}} +
+ “ {{.Reference}} ” +
+ {{- end}} + {{if .Name}} +
+ {{.Name}} +
+ {{- end}} +
+ {{end}} +
+
+{{- end}} + + + diff --git a/themes/stackoverflow/stackoverflow.go b/themes/stackoverflow/stackoverflow.go new file mode 100644 index 0000000..cd90b8f --- /dev/null +++ b/themes/stackoverflow/stackoverflow.go @@ -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) +} diff --git a/themes/stackoverflow/style.css b/themes/stackoverflow/style.css new file mode 100755 index 0000000..e89e828 --- /dev/null +++ b/themes/stackoverflow/style.css @@ -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; + } +} diff --git a/themes/theme.go b/themes/theme.go index f3d66b9..e19e173 100644 --- a/themes/theme.go +++ b/themes/theme.go @@ -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()) +}