kamisaku 0.3.3 → 0.4.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +28 -64
  5. data/examples/birthday_invitation/dino/invitation.pdf +0 -0
  6. data/examples/resume/chromatic/example.pdf +0 -0
  7. data/examples/resume/gradient/example.pdf +0 -0
  8. data/examples/resume/meridian/example.pdf +0 -0
  9. data/examples/resume/paper/example.pdf +0 -0
  10. data/examples/resume/prism/example.pdf +0 -0
  11. data/examples/resume/sleek/example.pdf +0 -0
  12. data/examples/resume/zenith/example.pdf +0 -0
  13. data/lib/kamisaku/arg_parser.rb +4 -0
  14. data/lib/kamisaku/cli_runner.rb +2 -2
  15. data/lib/kamisaku/content_validators/base_content_validator.rb +14 -0
  16. data/lib/kamisaku/content_validators/birthday_invitation_content_validator.rb +218 -0
  17. data/lib/kamisaku/{content_validator.rb → content_validators/resume_content_validator.rb} +28 -11
  18. data/lib/kamisaku/html_builder.rb +4 -3
  19. data/lib/kamisaku/pdf.rb +17 -12
  20. data/lib/kamisaku/template_helpers.rb +0 -2
  21. data/lib/kamisaku/version.rb +1 -1
  22. data/lib/kamisaku.rb +4 -2
  23. data/lib/schema/birthday_invitation/example.yml +45 -0
  24. data/lib/schema/birthday_invitation/schema.yml +40 -0
  25. data/lib/schema/resume/example.yml +274 -0
  26. data/lib/schema/resume/schema.yml +112 -0
  27. data/lib/templates/birthday_invitation/dino/template.html.erb +486 -0
  28. data/lib/templates/resume/chromatic/template.html.erb +275 -0
  29. data/lib/templates/resume/gradient/template.html.erb +793 -0
  30. data/lib/templates/resume/meridian/template.html.erb +535 -0
  31. data/lib/templates/resume/paper/template.html.erb +525 -0
  32. data/lib/templates/resume/prism/template.html.erb +818 -0
  33. data/lib/templates/{sleek → resume/sleek}/template.html.erb +1 -1
  34. data/lib/templates/resume/zenith/template.html.erb +546 -0
  35. data/scripts/rebuild_examples.rb +45 -0
  36. metadata +25 -9
  37. data/examples/paper/john_doe.pdf +0 -0
  38. data/examples/paper/john_doe.yml +0 -157
  39. data/examples/sleek/john_doe.pdf +0 -0
  40. data/examples/sleek/john_doe.yml +0 -157
  41. data/lib/templates/paper/template.html.erb +0 -420
  42. data/template.yml +0 -64
@@ -0,0 +1,525 @@
1
+ <html>
2
+ <head>
3
+ <meta content="text/html; charset=UTF-8" http-equiv="content-type">
4
+ <style>
5
+
6
+ /*
7
+ print and print-preview styles.
8
+ To use:
9
+ <body>
10
+ <div class="paper">
11
+ All the template content should go here...
12
+ </div>
13
+ </body>
14
+ */
15
+ @page {
16
+ margin: 0 auto;
17
+ padding: 0.5in;
18
+ size: A4;
19
+ }
20
+ @media screen {
21
+ body {
22
+ background: #e0e0e0;
23
+ }
24
+
25
+ .paper {
26
+ padding: 0.5in;
27
+ }
28
+ }
29
+ @media screen, print {
30
+ .paper {
31
+ background: white;
32
+ margin: 0 auto;
33
+ width: 210mm;
34
+ height: 100%;
35
+ }
36
+ }
37
+
38
+ body {
39
+ font-family: "Cambria", serif;
40
+ color: #000;
41
+ font-size: 12pt;
42
+ }
43
+
44
+ /* latin */
45
+ @font-face {
46
+ font-family: 'Cambria';
47
+ font-style: normal;
48
+ font-weight: 400;
49
+ src: url(https://fonts.gstatic.com/l/font?kit=GFDqWAB9jnWLT-HIK7ILrphaOAw&skey=d4699178559bc4b0&v=v18) format('woff2');
50
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
51
+ }
52
+
53
+ /* latin */
54
+ @font-face {
55
+ font-family: 'Cambria';
56
+ font-style: normal;
57
+ font-weight: 700;
58
+ src: url(https://fonts.gstatic.com/l/font?kit=GFDvWAB9jnWLT-HIIwkuu7V4NSY7WWA&skey=5202a3b6f5388b49&v=v18) format('woff2');
59
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
60
+ }
61
+
62
+ /* cyrillic */
63
+ @font-face {
64
+ font-family: 'Garamond';
65
+ font-style: normal;
66
+ font-weight: 400;
67
+ src: url(https://fonts.gstatic.com/l/font?kit=XoHl2Y_-T6Oo88RDZSQOn9IDlDLo&skey=a3a4b3361b12223a&v=v18) format('woff2');
68
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
69
+ }
70
+
71
+ /* greek */
72
+ @font-face {
73
+ font-family: 'Garamond';
74
+ font-style: normal;
75
+ font-weight: 400;
76
+ src: url(https://fonts.gstatic.com/l/font?kit=XoHl2Y_-T6Oo88RDZSQJn9IDlDLo&skey=a3a4b3361b12223a&v=v18) format('woff2');
77
+ unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
78
+ }
79
+
80
+ /* latin-ext */
81
+ @font-face {
82
+ font-family: 'Garamond';
83
+ font-style: normal;
84
+ font-weight: 400;
85
+ src: url(https://fonts.gstatic.com/l/font?kit=XoHl2Y_-T6Oo88RDZSQEn9IDlDLo&skey=a3a4b3361b12223a&v=v18) format('woff2');
86
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
87
+ }
88
+
89
+ /* latin */
90
+ @font-face {
91
+ font-family: 'Garamond';
92
+ font-style: normal;
93
+ font-weight: 400;
94
+ src: url(https://fonts.gstatic.com/l/font?kit=XoHl2Y_-T6Oo88RDZSQKn9IDlDLo&skey=a3a4b3361b12223a&v=v18) format('woff2');
95
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
96
+ }
97
+
98
+ /* cyrillic */
99
+ @font-face {
100
+ font-family: 'Garamond';
101
+ font-style: normal;
102
+ font-weight: 700;
103
+ src: url(https://fonts.gstatic.com/l/font?kit=XoHi2Y_-T6Oo88RDZSyxuscqtj_C8ibe&skey=66cb3cbedfd2039d&v=v18) format('woff2');
104
+ unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
105
+ }
106
+
107
+ /* greek */
108
+ @font-face {
109
+ font-family: 'Garamond';
110
+ font-style: normal;
111
+ font-weight: 700;
112
+ src: url(https://fonts.gstatic.com/l/font?kit=XoHi2Y_-T6Oo88RDZSyxuscttj_C8ibe&skey=66cb3cbedfd2039d&v=v18) format('woff2');
113
+ unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
114
+ }
115
+
116
+ /* latin-ext */
117
+ @font-face {
118
+ font-family: 'Garamond';
119
+ font-style: normal;
120
+ font-weight: 700;
121
+ src: url(https://fonts.gstatic.com/l/font?kit=XoHi2Y_-T6Oo88RDZSyxuscgtj_C8ibe&skey=66cb3cbedfd2039d&v=v18) format('woff2');
122
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
123
+ }
124
+
125
+ /* latin */
126
+ @font-face {
127
+ font-family: 'Garamond';
128
+ font-style: normal;
129
+ font-weight: 700;
130
+ src: url(https://fonts.gstatic.com/l/font?kit=XoHi2Y_-T6Oo88RDZSyxuscutj_C8ibe&skey=66cb3cbedfd2039d&v=v18) format('woff2');
131
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
132
+ }
133
+
134
+ a {
135
+ color: #000000;
136
+ }
137
+
138
+ a:link {
139
+ text-decoration: none;
140
+ }
141
+
142
+ a:visited {
143
+ text-decoration: none;
144
+ }
145
+
146
+ a:hover {
147
+ text-decoration: none;
148
+ }
149
+
150
+ a:active {
151
+ text-decoration: none;
152
+ }
153
+
154
+ .bottom-ruler {
155
+ border-bottom-color: #000000;
156
+ border-bottom-width: 0.8pt;
157
+ padding-bottom: 2pt;
158
+ border-bottom-style: solid;
159
+ }
160
+
161
+ .upcase {
162
+ text-transform: uppercase;
163
+ }
164
+
165
+ .flex {
166
+ display: flex;
167
+ }
168
+
169
+ .flex-grow {
170
+ flex-grow: 1;
171
+ }
172
+
173
+ .flex-col {
174
+ flex-direction: column;
175
+ }
176
+
177
+ .sb {
178
+ justify-content: space-between;
179
+ }
180
+
181
+ .nowrap {
182
+ white-space: nowrap;
183
+ }
184
+
185
+ .contact-section {
186
+ .name {
187
+ font-size: 24pt;
188
+ font-weight: 700;
189
+ font-family: "Garamond";
190
+ }
191
+
192
+ .contact {
193
+ font-size: 14pt;
194
+ font-weight: 400;
195
+ font-family: "Garamond";
196
+ text-align: center;
197
+ padding-top: 6pt;
198
+ padding-bottom: 6pt;
199
+ }
200
+
201
+ span {
202
+ white-space: nowrap;
203
+ }
204
+ }
205
+
206
+ .summary {
207
+ margin-top: 12pt;
208
+
209
+ .section-title {
210
+ font-weight: bold;
211
+ margin-bottom: 12pt;
212
+ }
213
+
214
+ .about {
215
+ color: #000000;
216
+ font-weight: 400;
217
+ text-decoration: none;
218
+ vertical-align: baseline;
219
+ font-size: 12pt;
220
+ font-family: "Garamond";
221
+ font-style: normal;
222
+ text-align: justify;
223
+ }
224
+
225
+ }
226
+
227
+ .work-experience {
228
+ margin-top: 12pt;
229
+
230
+ .section-title {
231
+ font-weight: bold;
232
+ }
233
+
234
+ .experience {
235
+ margin-top: 12pt;
236
+
237
+ .organisation-name, .time-period {
238
+ font-weight: 700;
239
+ font-family: "Garamond";
240
+ }
241
+
242
+ .achievements {
243
+ .achievement-item {
244
+ color: #000000;
245
+ font-weight: 400;
246
+ text-decoration: none;
247
+ vertical-align: baseline;
248
+ font-size: 12pt;
249
+ font-family: "Garamond";
250
+ font-style: normal;
251
+ text-align: justify;
252
+ }
253
+ }
254
+
255
+ .job-title {
256
+ font-style: italic;
257
+ }
258
+
259
+ .job-title, .job-location {
260
+ font-weight: 400;
261
+ font-family: "Garamond";
262
+ }
263
+ }
264
+ }
265
+
266
+ .education {
267
+ margin-top: 12pt;
268
+
269
+ .section-title {
270
+ font-weight: bold;
271
+ }
272
+
273
+ .education-item {
274
+ margin-top: 12pt;
275
+
276
+ .institute-name, .time-period {
277
+ font-weight: 700;
278
+ font-family: "Garamond";
279
+ }
280
+
281
+ .qualification {
282
+ font-style: italic;
283
+ }
284
+
285
+ .qualification, .education-location {
286
+ font-weight: 400;
287
+ font-family: "Garamond";
288
+ }
289
+
290
+ .achievements {
291
+ .achievement-item {
292
+ color: #000000;
293
+ font-weight: 400;
294
+ text-decoration: none;
295
+ vertical-align: baseline;
296
+ font-size: 12pt;
297
+ font-family: "Garamond";
298
+ font-style: normal;
299
+ text-align: justify;
300
+ }
301
+ }
302
+ }
303
+ }
304
+
305
+ .projects {
306
+ margin-top: 12pt;
307
+ color: #000000;
308
+ font-weight: 400;
309
+ text-decoration: none;
310
+ vertical-align: baseline;
311
+ font-size: 12pt;
312
+ font-family: "Garamond";
313
+
314
+ .section-title {
315
+ font-weight: bold;
316
+ }
317
+
318
+ .project {
319
+ margin-top: 12pt;
320
+
321
+ .project-name {
322
+ font-weight: 700;
323
+ font-family: "Garamond";
324
+ }
325
+
326
+ .project-description, .technologies {
327
+ font-style: normal;
328
+ padding-top: 2pt;
329
+ }
330
+
331
+ .link {
332
+ padding-top: 6pt;
333
+ }
334
+ }
335
+ }
336
+
337
+ .generic-section {
338
+ margin-top: 12pt;
339
+
340
+ .section-title {
341
+ font-weight: bold;
342
+ margin-bottom: 12pt;
343
+ }
344
+
345
+ ul {
346
+ padding-left: 0;
347
+ list-style-type: none;
348
+ }
349
+
350
+ .item {
351
+ margin-top: 2pt;
352
+ color: #000000;
353
+ font-weight: 400;
354
+ text-decoration: none;
355
+ vertical-align: baseline;
356
+ font-size: 12pt;
357
+ font-family: "Garamond";
358
+ }
359
+ }
360
+ </style>
361
+ </head>
362
+ <div class="paper">
363
+ <% if (profile = data[:profile]) %>
364
+ <div class="bottom-ruler contact-section">
365
+ <div class="name bottom-ruler"><%= profile.dig(:name) %></div>
366
+ <% if (contact = data[:contact]) %>
367
+ <div class="contact">
368
+ <% if (email = contact[:email]) %>
369
+ <span> • <a href="mailto:<%= email %>"><%= email %></a></span>
370
+ <% end %>
371
+
372
+ <% if (mobile = contact[:mobile]) %>
373
+ <span> • <a href="tel:<%= mobile %>"><%= mobile %></a></span>
374
+ <% end %>
375
+
376
+ <% city = contact.dig(:location, :city); country = contact.dig(:location, :country) %>
377
+ <% if city || country %>
378
+ <span class="location"> • <%= city ? "#{city}, " : nil %><%= country ? country : nil %></span>
379
+ <% end %>
380
+
381
+ <% if (website = contact[:website]) %>
382
+ <span> • <a href="<%= website %>"><%= website %></a></span>
383
+ <% end %>
384
+
385
+ <% if (github = contact[:github]) %>
386
+ <span> • <a href="https://github.com/<%= github %>">github.com/<%= github %></a></span>
387
+ <% end %>
388
+
389
+ <% if (linkedin = contact[:linkedin]) %>
390
+ <span> • <a href="https://linkedin.com/in/<%= linkedin %>">linkedin.com/in/<%= linkedin %></a></span>
391
+ <% end %>
392
+ </div>
393
+ <% end %>
394
+ </div>
395
+ <div class="summary">
396
+ <div class="upcase bottom-ruler section-title">Summary</div>
397
+ <div class="about"><%= profile[:about] %></div>
398
+ </div>
399
+ <% end %>
400
+
401
+ <% if (experiences = data[:experiences]) %>
402
+ <div class="work-experience">
403
+ <div class="upcase bottom-ruler section-title">Work Experience</div>
404
+ <% experiences.each do |experience| %>
405
+ <div class="experience">
406
+ <div class="flex flex-grow sb">
407
+ <div class="organisation-name"><%= experience[:organisation] %></div>
408
+ <div class="time-period">
409
+ <%= "#{month_name experience.dig(:from, :month)} #{experience.dig(:from, :year)}" %> -
410
+ <%= experience[:to] ? "#{month_name experience.dig(:to, :month)} #{experience.dig(:to, :year)}" : "Present" %>
411
+ </div>
412
+ </div>
413
+
414
+ <div class="flex flex-grow sb">
415
+ <div class="job-title"><%= experience[:title] %></div>
416
+ <div class="job-location">
417
+ <%= "#{experience.dig(:location, :city)}, #{experience.dig(:location, :country)}" %>
418
+ </div>
419
+ </div>
420
+
421
+ <% if (achievements = experience[:achievements]) %>
422
+ <ul class="achievements">
423
+ <% achievements.each do |achievement| %>
424
+ <li class="achievement-item"><%= achievement %></li>
425
+ <% end %>
426
+ </ul>
427
+ <% end %>
428
+ </div>
429
+ <% end %>
430
+ </div>
431
+ <% end %>
432
+
433
+ <% if (education_list = data[:education]) %>
434
+ <div class="education">
435
+ <div class="upcase bottom-ruler section-title">Education</div>
436
+ <% education_list.each do |education| %>
437
+ <div class="education-item">
438
+ <div class="flex flex-grow sb">
439
+ <div class="institute-name">
440
+ <%= education[:institute] %>
441
+ </div>
442
+ <div class="time-period">
443
+ <%= education.dig(:from) ? "#{month_name education.dig(:from, :month)} #{education.dig(:from, :year)} - " : "" %>
444
+ <%= education.dig(:to) ? "#{month_name education.dig(:to, :month)} #{education.dig(:to, :year)}" : "Present" %>
445
+ </div>
446
+ </div>
447
+
448
+ <div class="flex flex-grow sb">
449
+ <div class="qualification"><%= education[:qualification] %></div>
450
+ <div class="education-location">
451
+ <%= "#{education.dig(:location, :city)}, #{education.dig(:location, :country)}".strip %>
452
+ </div>
453
+ </div>
454
+
455
+ <% if (achievements = education[:achievements]) %>
456
+ <ul class="achievements">
457
+ <% achievements.each do |achievement| %>
458
+ <li class="achievement-item"><%= achievement %></li>
459
+ <% end %>
460
+ </ul>
461
+ <% end %>
462
+ </div>
463
+ <% end %>
464
+ </div>
465
+ <% end %>
466
+
467
+ <% if (projects = (data[:projects])) %>
468
+ <div class="projects">
469
+ <div class="upcase bottom-ruler section-title">Projects</div>
470
+ <% projects.each do |project| %>
471
+ <div class="project">
472
+ <div class="project-name"><%= project[:name] %></div>
473
+
474
+ <% if project[:description] %>
475
+ <div class="project-description"><%= project[:description] %></div>
476
+ <% end %>
477
+
478
+ <div>
479
+ <% if (technologies = project[:technologies]) %>
480
+ <div class="technologies"><b>Technologies: </b><%= technologies.join(', ') %></div>
481
+ <% end %>
482
+
483
+ <% if (project_link = project[:link]) %>
484
+ <div class="link">
485
+ <a src="<%= project_link %>"><%= project_link %></a>
486
+ </div>
487
+ <% end %>
488
+ </div>
489
+ <% end %>
490
+ </div>
491
+ </div>
492
+ <% end %>
493
+
494
+ <% if (generic_sections = data.slice(:skills, :interests).compact) %>
495
+ <% show_subtitle = generic_sections.keys.size > 1 %>
496
+ <div class="generic-section">
497
+ <div class="upcase bottom-ruler section-title"><%= generic_sections.keys.map(&:capitalize).join(', ') %></div>
498
+ <ul>
499
+ <% if (skills = generic_sections[:skills]) %>
500
+ <li class="item">
501
+ <% if show_subtitle %>
502
+ <b>Skills: </b>
503
+ <% end %>
504
+ <% skills.map { it[:name] }.each do |skill| %>
505
+ <span class="nowrap"> • <%= skill%></span>
506
+ <% end %>
507
+ </li>
508
+ <% end %>
509
+
510
+ <% if (interests = generic_sections[:interests]) %>
511
+ <li class="item">
512
+ <% if show_subtitle %>
513
+ <b>Interests: </b>
514
+ <% end %>
515
+ <% interests.map { it[:name] }.each do |interest| %>
516
+ <span class="nowrap"> • <%= interest%></span>
517
+ <% end %>
518
+ </li>
519
+ <% end %>
520
+ </ul>
521
+ </div>
522
+ <% end %>
523
+ </div>
524
+ </body>
525
+ </html>