jsonresume-theme-straightforward-fet-adapt 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Aaron Gershman (original work)
4
+ Copyright (c) 2026 Franco Trujillo (modifications and enhancements)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # jsonresume-theme-straightforward-fet-adapt
2
+
3
+ A straightforward [jsonresume](https://github.com/jsonresume) theme with adaptive layouts and enhanced link support.
4
+
5
+ **Note:** This is a fork of the original [jsonresume-theme-straightforward](https://github.com/slugstack/jsonresume-theme-straightforward) with modifications and enhancements.
6
+
7
+ ## Preview
8
+
9
+ ![Sample Resume](.img/new_straightforward_sample.png)
10
+
11
+ ## Changes from Original
12
+
13
+ ### Header/Basics Section
14
+
15
+ - Centered layout with name at the top
16
+ - Contact information (phone, email, social profiles) in a single centered line
17
+ - SVG icons for phone, email, LinkedIn, and GitHub
18
+ - Generic link icon (link-45deg.svg) for unrecognized networks with URLs
19
+ - Social profiles display actual URLs (e.g., `linkedin.com/in/username`) instead of platform names
20
+ - Profiles with empty or null URLs are automatically skipped
21
+ - Location only shows comma when city is present
22
+
23
+ ### Work Experience Section
24
+
25
+ - Adaptive two-line layout when highlights are present:
26
+ - Line 1: `Organization | Title`
27
+ - Line 2: `Date range`
28
+ - Compact one-line layout when no highlights: `Organization | Title Date`
29
+
30
+ ### Volunteer Section
31
+
32
+ - Same adaptive layout as Work section
33
+ - Two-line format with highlights, one-line without
34
+
35
+ ### Awards Section
36
+
37
+ - Adaptive layout based on highlights presence
38
+ - Two-line format: `Award Title | Awarder` on first line, `Date` on second
39
+ - One-line format: `Award Title, Awarder Date` on single line
40
+
41
+ ### Publications Section
42
+
43
+ - Adaptive layout based on highlights presence
44
+ - Two-line format: `Publication Name` on first line, `Date` on second
45
+ - One-line format: `Publication Name Date` on single line
46
+
47
+ ### Education Section
48
+
49
+ - Maintains original one-line format
50
+ - Displays: `Institution | Study Type - Area, GPA Date`
51
+
52
+ ### Print/PDF
53
+
54
+ - Job blocks avoid splitting when possible
55
+ - Orphan/widow control for better page breaks
56
+
57
+ ### Icon Support
58
+
59
+ - Supports custom SVG icons in the `icons/` folder
60
+ - Icons are inlined for portability
61
+
62
+ ## examples
63
+
64
+ - [as HTML (https://francoet.github.io/jsonresume-theme-straightforward-fet-adapt)](https://francoet.github.io/jsonresume-theme-straightforward-fet-adapt)
65
+ - [as PDF (docs/index.pdf)](docs/index.pdf)
66
+
67
+ ## usage
68
+
69
+ ```sh
70
+ npm install jsonresume-theme-straightforward-fet-adapt
71
+
72
+ resume export resume.pdf --format pdf --theme jsonresume-theme-straightforward-fet-adapt
73
+ resume export resume.html --format html --theme jsonresume-theme-straightforward-fet-adapt
74
+ ```
75
+
76
+ ## building local
77
+
78
+ ```sh
79
+ npm install
80
+ npm start
81
+ npm test
82
+
83
+ npm run export:html
84
+ ```
85
+
86
+ Note that running `npm run export:pdf` will result in a different binary every time it's run, even if the source hasn't changed. So it's not the most reliable indicator of differences.
package/index.js ADDED
@@ -0,0 +1,198 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const Handlebars = require("handlebars");
4
+
5
+ const extname = ".hbs";
6
+ const partialsDir = path.join(__dirname, "partials");
7
+
8
+ fs.readdirSync(partialsDir)
9
+ .filter((filename) => path.extname(filename) === extname)
10
+ .map((filename) => [
11
+ filename,
12
+ fs.readFileSync(path.join(partialsDir, filename), "utf8"),
13
+ ])
14
+ .forEach(([filename, template]) =>
15
+ Handlebars.registerPartial(path.basename(filename, extname), template)
16
+ );
17
+
18
+ // Handlebars.registerHelper('STRIP_PROTOCOL', urlStr => {
19
+ // const result = urlStr.replace(/(^\w+:|^)\/\//, '');
20
+ // return result;
21
+ // })
22
+
23
+ Handlebars.registerHelper("MONTH_YEAR", (dateString) =>
24
+ // https://dockyard.com/blog/2020/02/14/you-probably-don-t-need-moment-js-anymore
25
+ // https://stackoverflow.com/questions/5619202/parsing-a-string-to-a-date-in-javascript
26
+ new Date(dateString + "T00:00:00").toLocaleDateString("en-US", {
27
+ month: "short",
28
+ year: "numeric",
29
+ })
30
+ );
31
+
32
+ Handlebars.registerHelper(
33
+ "IF_DATES_HAVE_SAME_MONTH_AND_YEAR",
34
+ function (arg1, arg2) {
35
+ // prevents situation where we render same month/date combination
36
+ // such as "Sept. 2020 - Sept. 2020"
37
+ const d1 = new Date(arg1 + "T00:00:00");
38
+ const d2 = new Date(arg2 + "T00:00:00");
39
+ const matchingYear = d1.getFullYear() == d2.getFullYear();
40
+ const matchingMonth = d1.getMonth() == d2.getMonth();
41
+ return matchingYear && matchingMonth;
42
+ }
43
+ );
44
+
45
+ Handlebars.registerHelper("join", (arr, separator) =>
46
+ arr.join(typeof separator === "string" ? separator : ", ")
47
+ );
48
+
49
+ Handlebars.registerHelper("eq", (a, b) => a === b);
50
+
51
+ // Helper to load and inline SVG icons
52
+ Handlebars.registerHelper("icon", (iconName) => {
53
+ try {
54
+ const iconPath = path.join(__dirname, "icons", `${iconName}.svg`);
55
+ const svg = fs.readFileSync(iconPath, "utf-8");
56
+ return new Handlebars.SafeString(svg);
57
+ } catch (e) {
58
+ return "";
59
+ }
60
+ });
61
+
62
+ // Helper to strip protocol from URLs for cleaner display
63
+ Handlebars.registerHelper("STRIP_PROTOCOL", (urlStr) => {
64
+ const result = urlStr.replace(/(^\w+:|^)\/\//, "");
65
+ return result;
66
+ });
67
+
68
+ Handlebars.registerHelper("STATE_ABBREVIATION_TO_FULL_NAME", (state) => {
69
+ const stateList = {
70
+ AZ: "Arizona",
71
+ AL: "Alabama",
72
+ AK: "Alaska",
73
+ AR: "Arkansas",
74
+ CA: "California",
75
+ CO: "Colorado",
76
+ CT: "Connecticut",
77
+ DC: "District of Columbia",
78
+ DE: "Delaware",
79
+ FL: "Florida",
80
+ GA: "Georgia",
81
+ HI: "Hawaii",
82
+ ID: "Idaho",
83
+ IL: "Illinois",
84
+ IN: "Indiana",
85
+ IA: "Iowa",
86
+ KS: "Kansas",
87
+ KY: "Kentucky",
88
+ LA: "Louisiana",
89
+ ME: "Maine",
90
+ MD: "Maryland",
91
+ MA: "Massachusetts",
92
+ MI: "Michigan",
93
+ MN: "Minnesota",
94
+ MS: "Mississippi",
95
+ MO: "Missouri",
96
+ MT: "Montana",
97
+ NE: "Nebraska",
98
+ NV: "Nevada",
99
+ NH: "New Hampshire",
100
+ NJ: "New Jersey",
101
+ NM: "New Mexico",
102
+ NY: "New York",
103
+ NC: "North Carolina",
104
+ ND: "North Dakota",
105
+ OH: "Ohio",
106
+ OK: "Oklahoma",
107
+ OR: "Oregon",
108
+ PA: "Pennsylvania",
109
+ RI: "Rhode Island",
110
+ SC: "South Carolina",
111
+ SD: "South Dakota",
112
+ TN: "Tennessee",
113
+ TX: "Texas",
114
+ UT: "Utah",
115
+ VT: "Vermont",
116
+ VA: "Virginia",
117
+ WA: "Washington",
118
+ WV: "West Virginia",
119
+ WI: "Wisconsin",
120
+ WY: "Wyoming",
121
+ AS: "American Samoa",
122
+ GU: "Guam",
123
+ MP: "Northern Mariana Islands",
124
+ PR: "Puerto Rico",
125
+ VI: "U.S. Virgin Islands",
126
+ UM: "U.S. Minor Outlying Islands",
127
+ };
128
+ if (stateList[state] != null) {
129
+ return stateList[state];
130
+ }
131
+ return state;
132
+ });
133
+
134
+ Handlebars.registerHelper("STATE_NAME_TO_ABBREVIATION", (state) => {
135
+ const stateList = {
136
+ Arizona: "AZ",
137
+ Alabama: "AL",
138
+ Alaska: "AK",
139
+ Arkansas: "AR",
140
+ California: "CA",
141
+ Colorado: "CO",
142
+ Connecticut: "CT",
143
+ Delaware: "DE",
144
+ Florida: "FL",
145
+ Georgia: "GA",
146
+ Hawaii: "HI",
147
+ Idaho: "ID",
148
+ Illinois: "IL",
149
+ Indiana: "IN",
150
+ Iowa: "IA",
151
+ Kansas: "KS",
152
+ Kentucky: "KY",
153
+ Louisiana: "LA",
154
+ Maine: "ME",
155
+ Maryland: "MD",
156
+ Massachusetts: "MA",
157
+ Michigan: "MI",
158
+ Minnesota: "MN",
159
+ Mississippi: "MS",
160
+ Missouri: "MO",
161
+ Montana: "MT",
162
+ Nebraska: "NE",
163
+ Nevada: "NV",
164
+ "New Hampshire": "NH",
165
+ "New Jersey": "NJ",
166
+ "New Mexico": "NM",
167
+ "New York": "NY",
168
+ "North Carolina": "NC",
169
+ "North Dakota": "ND",
170
+ Ohio: "OH",
171
+ Oklahoma: "OK",
172
+ Oregon: "OR",
173
+ Pennsylvania: "PA",
174
+ "Rhode Island": "RI",
175
+ "South Carolina": "SC",
176
+ "South Dakota": "SD",
177
+ Tennessee: "TN",
178
+ Texas: "TX",
179
+ Utah: "UT",
180
+ Vermont: "VT",
181
+ Virginia: "VA",
182
+ Washington: "WA",
183
+ "West Virginia": "WV",
184
+ Wisconsin: "WI",
185
+ Wyoming: "WY",
186
+ };
187
+ if (stateList[state] != null) {
188
+ return stateList[state];
189
+ }
190
+ return state;
191
+ });
192
+
193
+ exports.render = (resume) => {
194
+ const css = fs.readFileSync(path.join(__dirname, "style.css"), "utf-8");
195
+ const template = fs.readFileSync(path.join(__dirname, "resume.hbs"), "utf-8");
196
+
197
+ return Handlebars.compile(template)({ css, resume });
198
+ };
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "jsonresume-theme-straightforward-fet-adapt",
3
+ "private": false,
4
+ "version": "1.1.0",
5
+ "description": "A straightforward jsonresume theme with adaptive layouts and enhanced link support",
6
+ "homepage": "https://github.com/FrancoETrujillo/jsonresume-theme-straightforward-fet-adapt",
7
+ "bugs": {
8
+ "url": "https://github.com/FrancoETrujillo/jsonresume-theme-straightforward-fet-adapt/issues"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/FrancoETrujillo/jsonresume-theme-straightforward-fet-adapt.git"
13
+ },
14
+ "license": "MIT",
15
+ "author": "Franco Trujillo",
16
+ "contributors": [
17
+ "Aaron Gershman (original author)"
18
+ ],
19
+ "keywords": [
20
+ "jsonresume",
21
+ "theme",
22
+ "straightforward",
23
+ "resume",
24
+ "cv"
25
+ ],
26
+ "files": [
27
+ "index.js",
28
+ "partials/*.hbs",
29
+ "resume.hbs",
30
+ "style.css"
31
+ ],
32
+ "scripts": {
33
+ "start": "resume serve --theme .",
34
+ "export": "npm-run-all export:*",
35
+ "export:html": "resume export docs/index.html --format html --theme .",
36
+ "export:pdf": "resume export docs/index.pdf --format pdf --theme .",
37
+ "lint": "npm-run-all lint:*",
38
+ "lint:eslint": "eslint .",
39
+ "lint:pa11y": "pa11y --reporter=cli $(pwd)/docs/index.html",
40
+ "test": "jest && npm run export:html && npm run lint"
41
+ },
42
+ "dependencies": {
43
+ "handlebars": "^4.7.6"
44
+ },
45
+ "devDependencies": {
46
+ "@types/jest": "^30.0.0",
47
+ "eslint": "^9.0.0",
48
+ "html-validate": "^10.0.0",
49
+ "jest": "^30.0.2",
50
+ "npm-run-all": "^4.1.5",
51
+ "pa11y": "^9.0.0",
52
+ "resume-cli": "^3.1.2"
53
+ }
54
+ }
@@ -0,0 +1,48 @@
1
+ {{#if resume.awards.length}}
2
+ <div id='awards' class='section-block'>
3
+ <div class='section-intro'>
4
+ <div class='section-name'>
5
+ <span>AWARDS</span>
6
+ </div>
7
+ <div class='section-intro-line'></div>
8
+ </div>
9
+ <div class='section-content'>
10
+ {{#each resume.awards}}
11
+ {{#if highlights.length}}
12
+ <div class='block-header'>
13
+ <div>
14
+ <span class='organization'>{{title}}</span>{{#if awarder}} | <span class='title'>{{awarder}}</span>{{/if}}
15
+ </div>
16
+ {{#if date}}
17
+ <div class='date'>
18
+ <time datetime="{{date}}">{{MONTH_YEAR date}}</time>
19
+ </div>
20
+ {{/if}}
21
+ </div>
22
+ {{else}}
23
+ <div class='block-header'>
24
+ <div>
25
+ <span class='title'>{{title}}{{#if awarder}}, {{awarder}}{{/if}}</span>
26
+ {{#if date}}
27
+ <span class='date'>
28
+ <time datetime="{{date}}">{{MONTH_YEAR date}}</time>
29
+ </span>
30
+ {{/if}}
31
+ </div>
32
+ </div>
33
+ {{/if}}
34
+ {{#if highlights.length}}
35
+ <ul class='highlights'>
36
+ {{#each highlights}}
37
+ <li>{{.}}</li>
38
+ {{/each}}
39
+ </ul>
40
+ {{/if}}
41
+ {{#unless @last}}
42
+ <div class='separator'></div>
43
+ {{/unless}}
44
+ {{/each}}
45
+ </div>
46
+ </div>
47
+ <div class='section-line'></div>
48
+ {{/if}}
@@ -0,0 +1,73 @@
1
+ {{#resume.basics}}
2
+ <div class="basics">
3
+ <div id="basics-left-content">
4
+ {{! note: this content should not appear or have any effect on styling, this is only to enable any automated content parsing }}
5
+ <div class="display-none">
6
+ {{#location}}
7
+ <span class="address">
8
+ {{address}}
9
+ {{city}}
10
+ {{region}}
11
+ {{postalCode}}
12
+ </span>
13
+ {{/location}}
14
+ {{#if phone}}
15
+ <span class="phone">
16
+ <a href="tel:{{phone}}">{{phone}}</a>
17
+ </span>
18
+ {{/if}}
19
+ </div>
20
+ </div>
21
+
22
+ <div id="basics-center-content">
23
+ <span class="name">{{name}}</span>
24
+ </div>
25
+
26
+ <div id="basics-right-content">
27
+ <div class="contact-block">
28
+ {{#if phone}}
29
+ <div>
30
+ <span class="phone">{{{icon "telephone-fill"}}}
31
+ <a href="tel:{{phone}}">{{phone}}</a></span>
32
+ </div>
33
+ <span class="divider">|</span>
34
+ {{/if}}
35
+ {{#if email}}
36
+ <div>
37
+ <span class="email">{{{icon "envelope"}}}
38
+ <a href="mailto:{{email}}">{{email}}</a></span>
39
+ </div>
40
+ {{/if}}
41
+ {{#each profiles}}
42
+ {{#if url}}
43
+ <span class="divider">|</span>
44
+ <div>
45
+ <span class="profile">
46
+ {{#if (eq network "LinkedIn")}}
47
+ {{{icon "linkedin"}}}
48
+ <a href="{{url}}">{{STRIP_PROTOCOL url}}</a>
49
+ {{else if (eq network "GitHub")}}
50
+ {{{icon "github"}}}
51
+ <a href="{{url}}">{{STRIP_PROTOCOL url}}</a>
52
+ {{else}}
53
+ {{{icon "link-45deg"}}}
54
+ <a href="{{url}}">{{STRIP_PROTOCOL url}}</a>
55
+ {{/if}}
56
+ </span>
57
+ </div>
58
+ {{/if}}
59
+ {{/each}}
60
+ </div>
61
+
62
+ {{! location and full address hidden for parsing }}
63
+ {{#location}}
64
+ <div class="display-none">
65
+ <span class="address">{{#if city}}{{city}}{{#if region}},
66
+ {{/if}}{{/if}}{{STATE_ABBREVIATION_TO_FULL_NAME region}}</span>
67
+ </div>
68
+ {{/location}}
69
+
70
+ </div>
71
+ </div>
72
+
73
+ {{/resume.basics}}
@@ -0,0 +1,33 @@
1
+ {{#if resume.education.length}}
2
+ <div id="education" class="section-block">
3
+ <div class="section-intro">
4
+ <div class="section-name">
5
+ <span>EDUCATION</span>
6
+ </div>
7
+ <div class="section-intro-line"></div>
8
+ </div>
9
+ <div class="section-content">
10
+ {{#each resume.education}}
11
+ <div class="block-header">
12
+ <span class="title">{{institution}}</span>
13
+ {{#if startDate}}
14
+ <span class="date">
15
+ {{#if startDate}}{{MONTH_YEAR startDate}}{{/if}}
16
+ &mdash;
17
+ {{#if endDate}}{{MONTH_YEAR endDate}}{{else}}Present{{/if}}
18
+ </span>
19
+ {{/if}}
20
+ <div class="">
21
+ {{#if studyType}}{{studyType}} {{/if}}
22
+ -
23
+ {{#if area}}{{area}}{{/if}}{{#if score}}, GPA: {{score}}{{/if}}
24
+ </div>
25
+ </div>
26
+ {{#unless @last}}
27
+ <div class="separator"></div>
28
+ {{/unless}}
29
+ {{/each}}
30
+ </div>
31
+ </div>
32
+ <div class="section-line"></div>
33
+ {{/if}}
@@ -0,0 +1,25 @@
1
+ {{#if resume.interests.length}}
2
+ <div id='interests' class='section-block'>
3
+ <div class='section-intro'>
4
+ <div class='section-name'>
5
+ <span>INTERESTS</span>
6
+ </div>
7
+ <div class='section-intro-line'></div>
8
+ </div>
9
+ <div class='section-content'>
10
+ <ul class='highlights'>
11
+ {{#each resume.interests}}
12
+ <li>
13
+ <span class='title'>{{name}}:</span>
14
+ {{#if keywords.length}}
15
+ {{#each keywords}}
16
+ <span>{{.}}</span>{{#unless @last}}, {{/unless}}
17
+ {{/each}}
18
+ {{/if}}
19
+ </li>
20
+ {{/each}}
21
+ </ul>
22
+ </div>
23
+ <div class='section-line'></div>
24
+ </div>
25
+ {{/if}}
@@ -0,0 +1,30 @@
1
+ {{#if resume.projects.length}}
2
+ <div id='projects' class='section-block'>
3
+ <div class='section-intro'>
4
+ <div class='section-name'>
5
+ <span>PROJECTS</span>
6
+ </div>
7
+ <div class='section-intro-line'></div>
8
+ </div>
9
+ <div class='section-content'>
10
+ <ul class='highlights'>
11
+ {{#each resume.projects}}
12
+ <li>
13
+ {{#if url}}
14
+ <span class='title'><a href="{{url}}">{{name}}</a>: </span>
15
+ {{else}}
16
+ <span class='title'>{{name}}: </span>
17
+ {{/if}}
18
+ {{#if highlights.length}}
19
+ {{#each highlights}}
20
+ {{!-- formatting is expecting resume.json highlights to not have end punctuation --}}
21
+ <span>{{.}}</span>.{{#unless @last}} {{/unless}}
22
+ {{/each}}
23
+ {{/if}}
24
+ </li>
25
+ {{/each}}
26
+ </ul>
27
+ </div>
28
+ </div>
29
+ <div class='section-line'></div>
30
+ {{/if}}
@@ -0,0 +1,51 @@
1
+ {{#if resume.publications.length}}
2
+ <div id='publications' class='section-block'>
3
+ <div class='section-intro'>
4
+ <div class='section-name'>
5
+ <span>PUBLICATIONS</span>
6
+ </div>
7
+ <div class='section-intro-line'></div>
8
+ </div>
9
+ <div class='section-content'>
10
+ {{#each resume.publications}}
11
+ {{#if highlights.length}}
12
+ <div class='block-header'>
13
+ <div>
14
+ <span class='organization'>{{name}}</span>
15
+ </div>
16
+ {{#if releaseDate}}
17
+ <div class='date'>
18
+ <time datetime="{{releaseDate}}">{{MONTH_YEAR releaseDate}}</time>
19
+ </div>
20
+ {{/if}}
21
+ </div>
22
+ {{else}}
23
+ <div class='block-header'>
24
+ <div>
25
+ <span class='title'>{{name}}</span>
26
+ {{#if releaseDate}}
27
+ <span class='date'>
28
+ <time datetime="{{releaseDate}}">{{MONTH_YEAR releaseDate}}</time>
29
+ </span>
30
+ {{/if}}
31
+ </div>
32
+ </div>
33
+ {{/if}}
34
+ {{#if website}}
35
+ <div class='website'><a href='{{website}}'>{{website}}</a></div>
36
+ {{/if}}
37
+ {{#if highlights.length}}
38
+ <ul class='highlights'>
39
+ {{#each highlights}}
40
+ <li>{{.}}</li>
41
+ {{/each}}
42
+ </ul>
43
+ {{/if}}
44
+ {{#unless @last}}
45
+ <div class='separator'></div>
46
+ {{/unless}}
47
+ {{/each}}
48
+ </div>
49
+ </div>
50
+ <div class='section-line'></div>
51
+ {{/if}}
@@ -0,0 +1,25 @@
1
+ {{#if resume.skills.length}}
2
+ <div id='skills' class='section-block'>
3
+ <div class='section-intro'>
4
+ <div class='section-name'>
5
+ <span>SKILLS AND TECH</span>
6
+ </div>
7
+ <div class='section-intro-line'></div>
8
+ </div>
9
+ <div class='section-content'>
10
+ <ul class='highlights'>
11
+ {{#each resume.skills}}
12
+ <li>
13
+ <span class='title'>{{name}}:</span>
14
+ {{#if keywords.length}}
15
+ {{#each keywords}}
16
+ <span>{{.}}</span>{{#unless @last}}, {{/unless}}{{#if @last}}.{{/if}}
17
+ {{/each}}
18
+ {{/if}}
19
+ </li>
20
+ {{/each}}
21
+ </ul>
22
+ </div>
23
+ </div>
24
+ <div class='section-line'></div>
25
+ {{/if}}
@@ -0,0 +1,14 @@
1
+ {{#if resume.basics.summary}}
2
+ <div id='summary-block' class='section-block'>
3
+ <div class='section-intro'>
4
+ <div class='section-name'>
5
+ <span>SUMMARY</span>
6
+ </div>
7
+ <div class='section-intro-line'></div>
8
+ </div>
9
+ <div class='section-content'>
10
+ <span>{{resume.basics.summary}}</span>
11
+ </div>
12
+ </div>
13
+ <div class='section-line'></div>
14
+ {{/if}}
@@ -0,0 +1,61 @@
1
+ {{#if resume.volunteer.length}}
2
+ <div id='volunteer' class='section-block'>
3
+ <div class='section-intro'>
4
+ <div class='section-name'>
5
+ <span>VOLUNTEERING</span>
6
+ </div>
7
+ <div class='section-intro-line'></div>
8
+ </div>
9
+ <div class='section-content'>
10
+ {{#each resume.volunteer}}
11
+ {{#if highlights.length}}
12
+ <div class='block-header'>
13
+ <div>
14
+ <span class='organization'>{{organization}}</span> | <span class='title'>{{position}}</span>
15
+ </div>
16
+ {{#if startDate}}
17
+ <div class='date'>
18
+ {{#if (IF_DATES_HAVE_SAME_MONTH_AND_YEAR startDate endDate)}}
19
+ {{MONTH_YEAR startDate}}
20
+ {{else}}
21
+ {{#if startDate}}{{MONTH_YEAR startDate}}{{/if}} &mdash;
22
+ {{#if endDate}}{{MONTH_YEAR endDate}}{{else}}Present{{/if}}
23
+ {{/if}}
24
+ </div>
25
+ {{/if}}
26
+ </div>
27
+ {{else}}
28
+ <div class='block-header'>
29
+ <div>
30
+ <span class='organization'>{{organization}}</span> | <span class='title'>{{position}}</span>
31
+ {{#if startDate}}
32
+ <span class='date'>
33
+ {{#if (IF_DATES_HAVE_SAME_MONTH_AND_YEAR startDate endDate)}}
34
+ {{MONTH_YEAR startDate}}
35
+ {{else}}
36
+ {{#if startDate}}{{MONTH_YEAR startDate}}{{/if}} &mdash;
37
+ {{#if endDate}}{{MONTH_YEAR endDate}}{{else}}Present{{/if}}
38
+ {{/if}}
39
+ </span>
40
+ {{/if}}
41
+ </div>
42
+ </div>
43
+ {{/if}}
44
+ {{#if website}}
45
+ <div class='website'><a href='{{website}}'>{{website}}</a></div>
46
+ {{/if}}
47
+ {{#if highlights.length}}
48
+ <ul class='highlights'>
49
+ {{#each highlights}}
50
+ <li>{{.}}</li>
51
+ {{/each}}
52
+ </ul>
53
+ {{/if}}
54
+ {{#unless @last}}
55
+ <div class='separator'></div>
56
+ {{/unless}}
57
+ {{/each}}
58
+ </div>
59
+ </div>
60
+ <div class='section-line'></div>
61
+ {{/if}}
@@ -0,0 +1,59 @@
1
+ {{#if resume.work.length}}
2
+ <div id='work-block' class='section-block'>
3
+ <div class='section-intro'>
4
+ <div class='section-name'>
5
+ <span>EXPERIENCE</span>
6
+ </div>
7
+ <div class='section-intro-line'></div>
8
+ </div>
9
+ <div class='section-content'>
10
+ {{#each resume.work}}
11
+ <div class='job-block'>
12
+ {{#if highlights.length}}
13
+ <div class='block-header'>
14
+ <div>
15
+ <span class='organization'>{{name}}</span> | <span class='title'>{{position}}</span>
16
+ </div>
17
+ <div class='date'>
18
+ <time datetime="{{startDate}}">{{MONTH_YEAR startDate}}</time> &mdash;
19
+ {{#if endDate}}<time datetime="{{endDate}}">{{MONTH_YEAR endDate}}</time>{{else}}Present{{/if}}
20
+ </div>
21
+ </div>
22
+ {{else}}
23
+ <div class='block-header'>
24
+ <div>
25
+ <span class='organization'>{{name}}</span> | <span class='title'>{{position}}</span>
26
+ <span class='date'>
27
+ <time datetime="{{startDate}}">{{MONTH_YEAR startDate}}</time> &mdash;
28
+ {{#if endDate}}<time datetime="{{endDate}}">{{MONTH_YEAR endDate}}</time>{{else}}Present{{/if}}
29
+ </span>
30
+ </div>
31
+ </div>
32
+ {{/if}}
33
+
34
+ <div class='display-none'>
35
+ {{!-- note: this is to enable any automated parsing of content --}}
36
+ {{#if location}}
37
+ <span class='location'>{{location}}</span>
38
+ {{/if}}
39
+ {{#if website}}
40
+ <span class='website'><a href='{{website}}'>{{website}}</a></span>
41
+ {{/if}}
42
+ </div>
43
+
44
+ {{#if highlights.length}}
45
+ <ul class='highlights'>
46
+ {{#each highlights}}
47
+ <li>{{.}}</li>
48
+ {{/each}}
49
+ </ul>
50
+ {{/if}}
51
+ {{#unless @last}}
52
+ <div class='separator'></div>
53
+ {{/unless}}
54
+ </div>
55
+ {{/each}}
56
+ </div>
57
+ </div>
58
+ <div class='section-line'></div>
59
+ {{/if}}
package/resume.hbs ADDED
@@ -0,0 +1,34 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset='utf-8'>
6
+ <title>{{resume.basics.name}}</title>
7
+ {{#if resume.basics.summary}}
8
+ <meta name="description" content='{{resume.basics.summary}}'>
9
+ {{else}}
10
+ <meta name="description" content='{{resume.basics.name}}'>
11
+ {{/if}}
12
+ <meta name='viewport' content='width=device-width, minimal-ui'>
13
+ <meta name='resume-version' content='{{resume.meta.version}}'>
14
+ <style>{{{css}}}</style>
15
+ </head>
16
+
17
+ <body>
18
+ <div id='wrapper'>
19
+ <div id='resume'>
20
+ {{> basics}}
21
+ {{> summary}}
22
+ {{> skills}}
23
+ {{> work}}
24
+ {{> volunteer}}
25
+ {{> projects}}
26
+ {{> education}}
27
+ {{> publications}}
28
+ {{> awards}}
29
+ {{> interests}}
30
+ </div>
31
+ </div>
32
+ </body>
33
+
34
+ </html>
package/style.css ADDED
@@ -0,0 +1,208 @@
1
+ body {
2
+ font-family: "Times New Roman", Times, sans-serif;
3
+ /* 13px to 15px looks good */
4
+ font-size: 15px;
5
+ /* 1.38, 1.4, or 1.5 looks good */
6
+ line-height: 1.4;
7
+ margin: 0 auto;
8
+ }
9
+
10
+ #wrapper {
11
+ margin: 0 auto;
12
+ max-width: 800px;
13
+ }
14
+
15
+ /* when generating the resume as a website or as headless, this will keep a nice readable margin in place */
16
+ #resume {
17
+ margin: 0.4in;
18
+ }
19
+
20
+ /* use-case is when a user generates their resume as a website, saves their website as a PDF, and uses their browser to manage the margins during save */
21
+ @media print {
22
+ #resume {
23
+ margin: 0;
24
+ }
25
+ }
26
+
27
+ ul {
28
+ margin-bottom: 0;
29
+ }
30
+
31
+ li {
32
+ margin-bottom: 2px;
33
+ }
34
+
35
+ a {
36
+ color: black;
37
+ /* it's less likely someone will click the links; removing underline to reduce noise */
38
+ text-decoration: none;
39
+ }
40
+
41
+ .display-none {
42
+ /* note: this is to enable any automated parsing of content */
43
+ display: none;
44
+ }
45
+
46
+ .basics {
47
+ display: block;
48
+ text-align: center;
49
+ }
50
+
51
+ #basics-center-content {
52
+ text-align: center;
53
+ font-size: 30px;
54
+ margin-bottom: 5px;
55
+ }
56
+
57
+ #basics-right-content {
58
+ text-align: center;
59
+ font-size: 13px;
60
+ margin-bottom: 15px;
61
+ }
62
+
63
+ #basics-left-content {
64
+ display: none;
65
+ }
66
+
67
+ .contact-block {
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ gap: 10px;
72
+ }
73
+
74
+ .contact-block > div {
75
+ display: inline;
76
+ }
77
+
78
+ .contact-block svg {
79
+ width: 14px;
80
+ height: 14px;
81
+ vertical-align: middle;
82
+ margin-right: 2px;
83
+ }
84
+
85
+ .basics .divider {
86
+ font-weight: bold;
87
+ margin-left: 5px;
88
+ margin-right: 5px;
89
+ }
90
+
91
+ .section-block {
92
+ display: block;
93
+ width: 100%;
94
+ }
95
+
96
+ .section-name {
97
+ color: #004687;
98
+ display: block;
99
+ font-weight: bold;
100
+ }
101
+
102
+ .section-line {
103
+ border-color: none;
104
+ border-style: hidden;
105
+ border-width: 1px;
106
+ margin-top: 10px;
107
+ margin-bottom: 5px;
108
+ border-color: #004687;
109
+ border-style: solid;
110
+ border-width: 1px;
111
+ margin-top: 0px;
112
+ margin-bottom: 5px;
113
+ }
114
+
115
+ #work-block .block-header,
116
+ #volunteer .block-header,
117
+ #awards .block-header,
118
+ #publications .block-header {
119
+ display: flex;
120
+ flex-wrap: wrap;
121
+ align-items: center;
122
+ justify-content: space-between;
123
+ }
124
+
125
+ #work-block .block-header > *,
126
+ #volunteer .block-header > *,
127
+ #awards .block-header > *,
128
+ #publications .block-header > * {
129
+ flex-grow: 1;
130
+ flex-shrink: 1;
131
+ flex-basis: 30%;
132
+ }
133
+
134
+ #work-block .block-header > div:first-child,
135
+ #volunteer .block-header > div:first-child,
136
+ #awards .block-header > div:first-child,
137
+ #publications .block-header > div:first-child {
138
+ flex-basis: 100%;
139
+ }
140
+
141
+ #work-block .block-header > div.date,
142
+ #volunteer .block-header > div.date,
143
+ #awards .block-header > div.date,
144
+ #publications .block-header > div.date {
145
+ flex-basis: 100%;
146
+ text-align: left;
147
+ }
148
+
149
+ .block-header .date {
150
+ font-weight: bold;
151
+ text-align: right;
152
+ }
153
+
154
+ .block-header .organization {
155
+ font-weight: bold;
156
+ text-align: left;
157
+ }
158
+
159
+ .block-header .title {
160
+ font-weight: bold;
161
+ text-align: center;
162
+ }
163
+
164
+ .section-content {
165
+ display: block;
166
+ }
167
+
168
+ .section-content ul {
169
+ padding-left: 20px;
170
+ margin-top: 3px;
171
+ list-style-type: circle;
172
+ }
173
+
174
+ .section-content .title {
175
+ font-weight: bold;
176
+ }
177
+
178
+ .section-content .date {
179
+ float: right;
180
+ }
181
+
182
+ .section-content .separator {
183
+ height: 7px;
184
+ }
185
+
186
+ .summary {
187
+ margin-top: 6px;
188
+ }
189
+
190
+ .job-block {
191
+ page-break-inside: avoid;
192
+ }
193
+
194
+ @media print {
195
+ .job-block {
196
+ margin-top: 10px;
197
+ }
198
+
199
+ .job-block:first-child {
200
+ margin-top: 0;
201
+ }
202
+
203
+ .section-content ul,
204
+ .section-content .highlights {
205
+ orphans: 2;
206
+ widows: 2;
207
+ }
208
+ }