forked from jsidrach/resume-generator
/
main.go
173 lines (149 loc) · 4.1 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/caitlinelfring/go-env-default"
"github.com/caitlinelfring/resume-generator/pdf"
yaml "gopkg.in/yaml.v2"
)
func main() {
var err error
// Flags
var resumePath = flag.String("resume", "example.yaml", "Path to the resume YAML file")
flag.Parse()
// Load resume
r, err := loadResume(*resumePath)
if err != nil {
log.Fatal(err)
}
r.ResumeName = strings.TrimSuffix(*resumePath, filepath.Ext(*resumePath))
// Templates extensions
// There must exist a template named TemplatesPath+Extension for each extension
var templatesExtensions = []Exporter{HTML, MD, TXT, JSON, XML}
// Save resume using the templates
for _, exporter := range templatesExtensions {
var filename string
filename, err = exporter.SaveAs(r)
if err != nil {
log.Printf("Unable to export as %s: %s", filename, err)
} else {
log.Printf("Exported to %s", (filename))
}
}
// Save resume as PDF
err = pdf.SaveHTMLAsPDF("output/" + r.ResumeName + ".html")
if err != nil {
log.Fatal(err)
}
}
//
// Resume structure
//
// Resume format
type Resume struct {
ResumeName string `json:"-"`
Name string `json:",omitempty"`
Title string `json:",omitempty"`
Contact Contact `json:",omitempty"`
Summary string `json:",omitempty"`
Sections []Section `json:",omitempty"`
}
// Contact section
type Contact struct {
Phone string `json:",omitempty"`
Address string `json:",omitempty"`
Email string `json:",omitempty"`
Webpage Link `json:",omitempty"`
Linkedin Link `json:",omitempty"`
Github Link `json:",omitempty"`
}
// Link to URL
type Link struct {
Name string `json:",omitempty"`
URL string `json:",omitempty"`
}
// Section of the resume
type Section struct {
Name string `json:",omitempty"`
Entries []Entry `json:",omitempty"`
}
// Entry of a section
type Entry struct {
What string `json:",omitempty"`
URL string `json:",omitempty"`
Where string `json:",omitempty"`
When string `json:",omitempty"`
Location string `json:",omitempty"`
Description string `json:",omitempty"`
Details []string `json:",omitempty"`
}
//
// Load from YAML
//
func loadResume(yamlPath string) (*Resume, error) {
yamlFile, err := ioutil.ReadFile(yamlPath)
if err != nil {
return nil, fmt.Errorf("Open input YAML (%s) failed\n%s", yamlPath, err)
}
resume := Resume{}
err = yaml.Unmarshal(yamlFile, &resume)
if err != nil {
return nil, fmt.Errorf("Read input YAML (%s) failed\n%s", yamlPath, err)
}
return &resume, nil
}
//
// Export to file
//
var HTML = DefaultExporter{".html"}
var XML = DefaultExporter{".xml"}
var TXT = DefaultExporter{".txt"}
var MD = DefaultExporter{".md"}
var JSON = JSONExporter{}
type Exporter interface {
SaveAs(r *Resume) (filename string, err error)
}
type DefaultExporter struct {
Extension string
}
type JSONExporter struct{}
func (j JSONExporter) SaveAs(r *Resume) (outputPath string, err error) {
outputPath = "output/" + r.ResumeName + ".json"
outputFile, err := os.Create(outputPath)
if err != nil {
return "", fmt.Errorf("Open output file (%s) failed\n%s", outputPath, err)
}
defer outputFile.Close()
output, err := json.MarshalIndent(r, "", " ")
if err != nil {
return "", fmt.Errorf("Write output file (%s) failed\n%s", outputPath, err)
}
outputFile.Write(output)
return
}
var TemplateRoot = env.GetDefault("TEMPLATE_ROOT", "templates")
func (d DefaultExporter) SaveAs(r *Resume) (outputPath string, err error) {
templatePath := TemplateRoot + "/tmpl" + d.Extension
outputPath = "output/" + r.ResumeName + d.Extension
tmpl, err := template.ParseFiles(templatePath)
if err != nil {
return "", fmt.Errorf("Parse template file (%s) failed\n%s", templatePath, err)
}
outputFile, err := os.Create(outputPath)
if err != nil {
return "", fmt.Errorf("Open output file (%s) failed\n%s", outputPath, err)
}
defer outputFile.Close()
err = tmpl.Execute(outputFile, *r)
if err != nil {
return "", fmt.Errorf("Execute template (%s) failed\n%s", templatePath, err)
}
return
}