diff --git a/cli/resume.go b/cli/resume.go
index e214e88..42efcca 100644
--- a/cli/resume.go
+++ b/cli/resume.go
@@ -35,6 +35,7 @@ import (
"jsonresume/themes"
_ "jsonresume/themes/kendall"
_ "jsonresume/themes/stackoverflow"
+ _ "jsonresume/themes/tex"
)
func main() {
diff --git a/generate.sh b/generate.sh
new file mode 100755
index 0000000..9413e58
--- /dev/null
+++ b/generate.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+go-bindata -pkg kendall -o themes/kendall/kendall-assets.go themes/kendall/{resume.template,style.css,print.css}
+go-bindata -pkg stackoverflow -o themes/stackoverflow/stackoverflow-assets.go themes/stackoverflow/{resume.template,style.css}
+go-bindata -pkg tex -o themes/tex/tex-assets.go themes/tex/resume_template.tex
diff --git a/model/json.go b/model/json.go
index 1661b0d..7c86efe 100644
--- a/model/json.go
+++ b/model/json.go
@@ -28,12 +28,15 @@ package model
import (
"encoding/json"
"io/ioutil"
+ "regexp"
"strings"
"time"
)
const ISO8601DateLayout = "2006-01-02"
+var MarkdownURLRegexp = regexp.MustCompile(`\[([^]]*)\]\((http[^)]*)\)`)
+
type ResumeDate struct {
time.Time
}
diff --git a/themes/kendall/kendall.go b/themes/kendall/kendall.go
index 77459c0..40d09a6 100644
--- a/themes/kendall/kendall.go
+++ b/themes/kendall/kendall.go
@@ -26,6 +26,7 @@
package kendall
import (
+ "jsonresume/model"
"jsonresume/themes"
"path"
"text/template"
@@ -44,6 +45,7 @@ var Theme = themes.Theme{
Functions: template.FuncMap{
"css": getCSS,
"printcss": getPrintCSS,
+ "md2html": md2html,
},
}
@@ -62,3 +64,7 @@ func getPrintCSS() string {
r, _ := Asset(path.Join(packageDirectory, fileCSSPrint))
return string(r)
}
+
+func md2html(s string) string {
+ return model.MarkdownURLRegexp.ReplaceAllString(s, `$1`)
+}
diff --git a/themes/kendall/resume.template b/themes/kendall/resume.template
index 1be4a9b..20b0928 100644
--- a/themes/kendall/resume.template
+++ b/themes/kendall/resume.template
@@ -125,10 +125,10 @@
{{range .Highlights -}}
-
- {{.Title}}
+ {{md2html .Title}}
{{if .Items -}}
- {{range .Items}}- {{.}}
{{end}}
+ {{range .Items}}- {{md2html .}}
{{end}}
{{- end}}
diff --git a/themes/stackoverflow/resume.template b/themes/stackoverflow/resume.template
index b2318b3..24e746c 100644
--- a/themes/stackoverflow/resume.template
+++ b/themes/stackoverflow/resume.template
@@ -266,10 +266,10 @@
{{if $v.Highlights}}
{{range $v.Highlights -}}
- - {{.Title}}
+
- {{md2html .Title}}
{{if .Items -}}
- {{range .Items}}- {{.}}
{{end}}
+ {{range .Items}}- {{md2html .}}
{{end}}
{{- end}}
diff --git a/themes/stackoverflow/stackoverflow.go b/themes/stackoverflow/stackoverflow.go
index 5b86e3c..097af80 100644
--- a/themes/stackoverflow/stackoverflow.go
+++ b/themes/stackoverflow/stackoverflow.go
@@ -26,6 +26,7 @@
package stackoverflow
import (
+ "jsonresume/model"
"jsonresume/themes"
"path"
"strings"
@@ -44,6 +45,7 @@ var Theme = themes.Theme{
Functions: template.FuncMap{
"css": getCSS,
"tolower": strings.ToLower,
+ "md2html": md2html,
},
}
@@ -57,3 +59,7 @@ func getCSS() string {
r, _ := Asset(path.Join(packageDirectory, fileCSS))
return string(r)
}
+
+func md2html(s string) string {
+ return model.MarkdownURLRegexp.ReplaceAllString(s, `$1`)
+}
diff --git a/themes/tex/resume_template.tex b/themes/tex/resume_template.tex
new file mode 100644
index 0000000..e225d20
--- /dev/null
+++ b/themes/tex/resume_template.tex
@@ -0,0 +1,93 @@
+\documentclass[a4paper,10pt]{article}
+\usepackage{parskip}
+\usepackage[cm]{fullpage}
+\usepackage{titlesec}
+\usepackage{array}
+\usepackage[hidelinks]{hyperref}
+\titleformat{\section}{\Large\scshape\raggedright}{}{0em}{}[\titlerule]
+\titlespacing{\section}{0pt}{3pt}{3pt}
+\addtolength{\textheight}{3cm}
+\pagestyle{empty}
+\begin{document}
+\par{\centering {\Large {{.Basic.Name -}} }\par}
+\par{\centering {\large {{.Basic.Label -}} }\par}
+\par{\centering
+{{.Basic.Location.Address}}\\
+{{.Basic.Location.PostalCode}} {{.Basic.Location.City}}\\
+{{.Basic.Location.CountryCode}}\\
+{{.Basic.Phone}}\\
+{{.Basic.Email}}\\
+\href{ {{- .Basic.URL -}} }{ {{- .Basic.URL -}} }
+\par}
+{{if .Skills -}}
+\section{ {{- .Lang.Skills -}} }
+\renewcommand{\arraystretch}{0.5}
+\begin{tabular}{>{\centering}p{2.5cm}|p{14.8cm}}
+{{range .Skills -}}
+ {{- .Name}}&{{if gt (len .Name) 10}}\vspace*{\stretch{1}}{{end -}}
+ {{- range $i, $k := .Keywords}}{{if eq $i 0}}{{$k}}{{else}}, {{$k}}{{end}}{{end -}}
+ {{- if gt (len .Name) 10}}\vspace*{\stretch{1}} {{end}}\\
+\multicolumn{2}{c}{} \\
+{{end -}}
+\end{tabular}
+\renewcommand{\arraystretch}{1}
+{{- end}}
+{{if .Languages -}}
+\begin{tabular}{>{\centering}p{2.5cm}|p{14.8cm}}
+{{.Lang.Languages}}&
+ {{- range $i, $l := .Languages -}}
+ {{- if gt $i 0}}, {{end -}}
+ {{- .Language}} ({{.Fluency}})
+ {{- end -}}\\
+\multicolumn{2}{c}{} \\
+\end{tabular}
+{{- end}}
+
+{{if .Work -}}
+\section{ {{- .Lang.WorkExperience -}} }
+\begin{tabular}{>{\centering}p{2.5cm}|p{14.8cm}}
+{{range .Work -}}
+{{formatDateMY .EndDate}}&\textbf{ {{- .Name -}} }, \textbf{ {{- .Position -}} }{{if .Location}}, {{md2tex .Location}}{{end}}\\
+{{formatDateMY .StartDate -}}
+{{range $i, $h := .Highlights -}}
+&\textbf{--} {{$h.Title}}\\
+{{range $h.Items -}}
+&\hspace{0.5cm}\textbf{\labelitemiv} {{.}}\\
+{{end -}}
+{{end -}}
+\multicolumn{2}{c}{} \\
+{{end -}}
+\end{tabular}
+{{- end}}
+
+{{if .Education -}}
+\section{ {{- .Lang.Education -}} }
+\begin{tabular}{>{\centering}p{2.5cm}|p{14.8cm}}
+{{range $i, $e := .Education -}}
+{{if gt $i 0}}\muticolumn{2}{c}{} \\{{end -}}
+{{formatDateY $e.StartDate}} - {{formatDateY $e.EndDate}}&{{$e.StudyType}} {{$.Lang.In}} {{$e.Area}} {{$.Lang.At}} {{md2tex $e.Institution}}\\
+{{end -}}
+\end{tabular}
+{{- end}}
+
+{{if .Volunteer -}}
+\section{ {{- .Lang.Volunteer -}} }
+\begin{tabular}{>{\centering}p{2.3cm}|p{15cm}}
+{{range $i, $v := .Volunteer -}}
+{{if gt $i 0}}\multicolumn{2}{c}{} \\{{end -}}
+{{if $v.URL -}}
+\href{ {{- $v.URL -}} }{ {{- $v.Organization -}} }&{{$v.Position}}\\
+{{- else -}}
+{{$v.Organization}}&{{$v.Position}}\\
+{{- end}}
+{{range $j, $h := $v.Highlights -}}
+{{if gt $j 0}}& \\{{end -}}
+&\textbf{--} {{md2tex .Title}}\\
+{{range .Items -}}
+&\hspace{0.5cm}\textbf{\labelitemiv} {{.}}\\
+{{end -}}
+{{end}}
+{{- end -}}
+\end{tabular}
+{{- end}}
+\end{document}
diff --git a/themes/tex/tex.go b/themes/tex/tex.go
new file mode 100644
index 0000000..a79bfcc
--- /dev/null
+++ b/themes/tex/tex.go
@@ -0,0 +1,152 @@
+/*
+ * 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 tex
+
+import (
+ "jsonresume/model"
+ "jsonresume/themes"
+ "path"
+ "strings"
+ "text/template"
+)
+
+const (
+ packageDirectory = "themes/tex"
+ fileTemplate = "resume_template.tex"
+)
+
+var Theme = themes.Theme{
+ Name: "tex",
+ Directory: packageDirectory,
+ Functions: template.FuncMap{"md2tex": md2tex},
+}
+
+func init() {
+ t, _ := Asset(path.Join(packageDirectory, fileTemplate))
+ Theme.Template = string(t)
+ (&Theme).Register()
+}
+
+type replacement struct {
+ o string
+ n string
+}
+
+var latexAccents = []replacement{
+ {"\\", "\\\\"},
+ {"{", "\\{"},
+ {"}", "\\}"},
+
+ {"à", "\\`a"},
+ {"è", "\\`e"},
+ {"ì", "\\`\\i"},
+ {"ò", "\\`o"},
+ {"ù", "\\`u"},
+ {"ỳ", "\\`y"},
+ {"À", "\\`A"},
+ {"È", "\\`E"},
+ {"Ì", "\\`\\I"},
+ {"Ò", "\\`O"},
+ {"Ù", "\\`U"},
+ {"Ỳ", "\\`Y"},
+ {"á", "\\'a"},
+ {"é", "\\'e"},
+ {"í", "\\'\\i"},
+ {"ó", "\\'o"},
+ {"ú", "\\'u"},
+ {"ý", "\\'y"},
+ {"Á", "\\'A"},
+ {"É", "\\'E"},
+ {"Í", "\\'\\I"},
+ {"Ó", "\\'O"},
+ {"Ú", "\\'U"},
+ {"Ý", "\\'Y"},
+ {"â", "\\^a"},
+ {"ê", "\\^e"},
+ {"î", "\\^\\i"},
+ {"ô", "\\^o"},
+ {"û", "\\^u"},
+ {"ŷ", "\\^y"},
+ {"Â", "\\^A"},
+ {"Ê", "\\^E"},
+ {"Î", "\\^\\I"},
+ {"Ô", "\\^O"},
+ {"Û", "\\^U"},
+ {"Ŷ", "\\^Y"},
+ {"ä", "\\\"a"},
+ {"ë", "\\\"e"},
+ {"ï", "\\\"\\i"},
+ {"ö", "\\\"o"},
+ {"ü", "\\\"u"},
+ {"ÿ", "\\\"y"},
+ {"Ä", "\\\"A"},
+ {"Ë", "\\\"E"},
+ {"Ï", "\\\"\\I"},
+ {"Ö", "\\\"O"},
+ {"Ü", "\\\"U"},
+ {"Ÿ", "\\\"Y"},
+ {"ç", "\\c{c}"},
+ {"Ç", "\\c{C}"},
+ {"œ", "\\oe{}"},
+ {"Œ", "{\\OE}"},
+ {"æ", "{\\ae}"},
+ {"Æ", "{\\AE}"},
+ {"å", "{\\aa}"},
+ {"Å", "{\\AA}"},
+ {"–", "--"},
+ {"—", "---"},
+ {"ø", "{\\o}"},
+ {"Ø", "{\\O}"},
+ {"ß", "{\\ss}"},
+ {"¡", "{!`}"},
+ {"¿", "{?`}"},
+ {"~", "\\~"},
+ {"&", "\\&"},
+ {"$", "\\$"},
+ {"%", "\\%"},
+ {"#", "\\#"},
+ {"_", "\\_"},
+ {"≥", "$\\ge$"},
+ {"≤", "$\\le$"},
+ {"≠", "$\\neq$"},
+ {"ı", "{\\i}"},
+ {"µ", "$\\mu$"},
+ {"°", "$\\deg$"},
+ {"‘", "`"},
+ {"’", "'"},
+ {"“", "``"},
+ {"”", "''"},
+ {"‚", ","},
+ {"„", ",,"},
+}
+
+func md2tex(s string) string {
+ for _, r := range latexAccents {
+ s = strings.Replace(s, r.o, r.n, -1)
+ }
+
+ return model.MarkdownURLRegexp.ReplaceAllString(s, `\href{$2}{$1}`)
+}
diff --git a/themes/theme.go b/themes/theme.go
index 372c2b9..363916d 100644
--- a/themes/theme.go
+++ b/themes/theme.go
@@ -48,6 +48,8 @@ type LangString struct {
Interests string
References string
Projects string
+ In string
+ At string
}
type Theme struct {
@@ -73,6 +75,8 @@ var Langs = map[string]LangString{
Interests: "Interests",
References: "References",
Projects: "Projects",
+ In: "in",
+ At: "at",
},
}
var CommonFuncs = map[string]template.FuncMap{
@@ -189,6 +193,8 @@ func setupFrenchTranslation() {
Interests: "Intérêts",
References: "Références",
Projects: "Projets",
+ In: "en",
+ At: "à",
}
CommonFuncs["fr"] = template.FuncMap{
"iconClass": iconClass,