kamisaku 0.3.2 → 0.3.4

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.
@@ -181,7 +181,7 @@
181
181
  <div class="skills">
182
182
  <% data[:skills].each do |skill| %>
183
183
  <div>
184
- <b><%= skill.dig :area %> </b>
184
+ <b><%= skill[:name] %> </b>
185
185
  <% skill.dig(:items).each do |item| %>
186
186
  • <%= item %>
187
187
  <% end %>
@@ -0,0 +1,546 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title><%= data[:profile][:name] %> - Resume</title>
7
+ <style>
8
+ /* Base print and preview styles */
9
+ @page {
10
+ margin: 0 auto;
11
+ padding: 0.5in;
12
+ size: A4;
13
+ }
14
+ @media screen {
15
+ body {
16
+ background: #e0e0e0;
17
+ }
18
+ .paper {
19
+ padding: 0.5in;
20
+ }
21
+ }
22
+ @media screen, print {
23
+ .paper {
24
+ background: white;
25
+ margin: 0 auto;
26
+ width: 210mm;
27
+ height: 100%;
28
+ }
29
+ }
30
+
31
+ /* Reset and base styles */
32
+ * {
33
+ margin: 0;
34
+ padding: 0;
35
+ box-sizing: border-box;
36
+ }
37
+
38
+ body {
39
+ font-family: 'Arial', sans-serif;
40
+ font-size: 11pt;
41
+ line-height: 1.4;
42
+ color: #333;
43
+ }
44
+
45
+ /* Main layout */
46
+ .resume-container {
47
+ display: flex;
48
+ gap: 20px;
49
+ height: 100%;
50
+ }
51
+
52
+ /* Left column - 35% width */
53
+ .left-column {
54
+ flex: 0 0 35%;
55
+ background-color: #f8f9fa;
56
+ padding: 20px;
57
+ border-radius: 5px;
58
+ }
59
+
60
+ /* Right column - 65% width */
61
+ .right-column {
62
+ flex: 1;
63
+ padding: 20px;
64
+ }
65
+
66
+ /* Header styles */
67
+ .profile-header {
68
+ margin-bottom: 30px;
69
+ }
70
+
71
+ .profile-name {
72
+ font-size: 28pt;
73
+ font-weight: bold;
74
+ color: #2c3e50;
75
+ line-height: 1.1;
76
+ margin-bottom: 8px;
77
+ }
78
+
79
+ .profile-title {
80
+ font-size: 14pt;
81
+ color: #7f8c8d;
82
+ font-weight: 300;
83
+ margin-bottom: 15px;
84
+ }
85
+
86
+ .profile-about {
87
+ font-size: 11pt;
88
+ line-height: 1.5;
89
+ text-align: justify;
90
+ }
91
+
92
+ /* Contact section */
93
+ .contact-section {
94
+ margin-bottom: 25px;
95
+ }
96
+
97
+ .contact-item {
98
+ display: flex;
99
+ align-items: center;
100
+ margin-bottom: 8px;
101
+ font-size: 10pt;
102
+ }
103
+
104
+ .contact-emoji {
105
+ width: 20px;
106
+ margin-right: 10px;
107
+ }
108
+
109
+ .contact-link {
110
+ color: #2980b9;
111
+ text-decoration: none;
112
+ }
113
+
114
+ .contact-link:hover {
115
+ text-decoration: underline;
116
+ }
117
+
118
+ /* Section headers */
119
+ .section-header {
120
+ font-size: 12pt;
121
+ font-weight: bold;
122
+ color: #2c3e50;
123
+ margin-bottom: 12px;
124
+ padding-bottom: 5px;
125
+ border-bottom: 2px solid #3498db;
126
+ text-transform: uppercase;
127
+ letter-spacing: 0.5px;
128
+ }
129
+
130
+ .left-section-header {
131
+ font-size: 11pt;
132
+ font-weight: bold;
133
+ color: #2c3e50;
134
+ margin-bottom: 10px;
135
+ text-transform: uppercase;
136
+ letter-spacing: 0.3px;
137
+ }
138
+
139
+ /* Skills section */
140
+ .skills-section {
141
+ margin-bottom: 25px;
142
+ }
143
+
144
+ .skill-group {
145
+ margin-bottom: 15px;
146
+ }
147
+
148
+ .skill-name {
149
+ font-weight: bold;
150
+ color: #2c3e50;
151
+ margin-bottom: 5px;
152
+ font-size: 10pt;
153
+ }
154
+
155
+ .skill-items {
156
+ list-style: none;
157
+ padding-left: 0;
158
+ }
159
+
160
+ .skill-item {
161
+ background-color: #ecf0f1;
162
+ padding: 3px 8px;
163
+ margin: 2px 0;
164
+ border-radius: 3px;
165
+ font-size: 9pt;
166
+ color: #34495e;
167
+ }
168
+
169
+ /* Experience section */
170
+ .experience-item, .education-item, .project-item {
171
+ margin-bottom: 20px;
172
+ border-left: 3px solid #3498db;
173
+ padding-left: 15px;
174
+ }
175
+
176
+ .item-header {
177
+ margin-bottom: 8px;
178
+ }
179
+
180
+ .item-title {
181
+ font-weight: bold;
182
+ font-size: 12pt;
183
+ color: #2c3e50;
184
+ }
185
+
186
+ .item-organization {
187
+ font-size: 11pt;
188
+ color: #7f8c8d;
189
+ font-style: italic;
190
+ }
191
+
192
+ .item-location {
193
+ font-size: 9pt;
194
+ color: #95a5a6;
195
+ }
196
+
197
+ .item-date {
198
+ font-size: 9pt;
199
+ color: #7f8c8d;
200
+ font-weight: 500;
201
+ margin-top: 3px;
202
+ }
203
+
204
+ .item-skills {
205
+ margin: 8px 0;
206
+ }
207
+
208
+ .item-skill-tag {
209
+ display: inline-block;
210
+ background-color: #e8f4fd;
211
+ color: #2980b9;
212
+ padding: 2px 6px;
213
+ margin: 2px 3px 2px 0;
214
+ border-radius: 3px;
215
+ font-size: 8pt;
216
+ font-weight: 500;
217
+ }
218
+
219
+ .achievements-list {
220
+ list-style: none;
221
+ padding-left: 0;
222
+ margin-top: 8px;
223
+ }
224
+
225
+ .achievement-item {
226
+ position: relative;
227
+ padding-left: 12px;
228
+ margin-bottom: 4px;
229
+ font-size: 10pt;
230
+ }
231
+
232
+ .achievement-item:before {
233
+ content: "•";
234
+ position: absolute;
235
+ left: 0;
236
+ color: #3498db;
237
+ font-weight: bold;
238
+ }
239
+
240
+ /* Languages section */
241
+ .languages-list {
242
+ list-style: none;
243
+ padding: 0;
244
+ }
245
+
246
+ .language-item {
247
+ background-color: #ecf0f1;
248
+ padding: 5px 10px;
249
+ margin: 3px 0;
250
+ border-radius: 3px;
251
+ font-size: 9pt;
252
+ color: #34495e;
253
+ }
254
+
255
+ /* Interests section */
256
+ .interests-list {
257
+ display: flex;
258
+ flex-wrap: wrap;
259
+ gap: 5px;
260
+ }
261
+
262
+ .interest-item {
263
+ background-color: #e8f6f3;
264
+ color: #16a085;
265
+ padding: 3px 8px;
266
+ border-radius: 3px;
267
+ font-size: 9pt;
268
+ }
269
+
270
+ /* Certifications and Awards */
271
+ .cert-item, .award-item {
272
+ margin-bottom: 12px;
273
+ padding: 8px;
274
+ background-color: #f8f9fa;
275
+ border-radius: 3px;
276
+ }
277
+
278
+ .cert-name, .award-title {
279
+ font-weight: bold;
280
+ color: #2c3e50;
281
+ font-size: 10pt;
282
+ }
283
+
284
+ .cert-issuer, .award-issuer {
285
+ color: #7f8c8d;
286
+ font-size: 9pt;
287
+ font-style: italic;
288
+ }
289
+
290
+ .cert-date, .award-date {
291
+ color: #95a5a6;
292
+ font-size: 8pt;
293
+ }
294
+
295
+ /* Print optimization */
296
+ @media print {
297
+ .paper {
298
+ box-shadow: none;
299
+ }
300
+
301
+ .contact-link {
302
+ color: #333 !important;
303
+ }
304
+ }
305
+ </style>
306
+ </head>
307
+ <body>
308
+ <div class="paper">
309
+ <div class="resume-container">
310
+ <!-- Left Column -->
311
+ <div class="left-column">
312
+ <!-- Contact Information -->
313
+ <% if data[:contact] %>
314
+ <div class="contact-section">
315
+ <div class="left-section-header">Contact</div>
316
+
317
+ <% if data[:contact][:email] %>
318
+ <div class="contact-item">
319
+ <span class="contact-emoji">📧</span>
320
+ <a href="mailto:<%= data[:contact][:email] %>" class="contact-link"><%= data[:contact][:email] %></a>
321
+ </div>
322
+ <% end %>
323
+
324
+ <% if data[:contact][:mobile] %>
325
+ <div class="contact-item">
326
+ <span class="contact-emoji">📱</span>
327
+ <%= data[:contact][:mobile] %>
328
+ </div>
329
+ <% end %>
330
+
331
+ <% if data[:contact][:linkedin] %>
332
+ <div class="contact-item">
333
+ <span class="contact-emoji">💼</span>
334
+ <a href="https://linkedin.com/in/<%= data[:contact][:linkedin] %>" class="contact-link">linkedin.com/in/<%= data[:contact][:linkedin] %></a>
335
+ </div>
336
+ <% end %>
337
+
338
+ <% if data[:contact][:github] %>
339
+ <div class="contact-item">
340
+ <span class="contact-emoji">🐙</span>
341
+ <a href="https://github.com/<%= data[:contact][:github] %>" class="contact-link">github.com/<%= data[:contact][:github] %></a>
342
+ </div>
343
+ <% end %>
344
+
345
+ <% if data[:contact][:location] %>
346
+ <div class="contact-item">
347
+ <span class="contact-emoji">📍</span>
348
+ <%= [data[:contact][:location][:city], data[:contact][:location][:country]].compact.join(', ') %>
349
+ </div>
350
+ <% end %>
351
+ </div>
352
+ <% end %>
353
+
354
+ <!-- Skills -->
355
+ <% if data[:skills] && data[:skills].any? %>
356
+ <div class="skills-section">
357
+ <div class="left-section-header">Skills</div>
358
+ <% data[:skills].each do |skill| %>
359
+ <div class="skill-group">
360
+ <div class="skill-name"><%= skill[:name] %></div>
361
+ <% if skill[:items] && skill[:items].any? %>
362
+ <ul class="skill-items">
363
+ <% skill[:items].each do |item| %>
364
+ <li class="skill-item"><%= item %></li>
365
+ <% end %>
366
+ </ul>
367
+ <% end %>
368
+ </div>
369
+ <% end %>
370
+ </div>
371
+ <% end %>
372
+
373
+ <!-- Languages -->
374
+ <% if data[:languages] && data[:languages].any? %>
375
+ <div class="languages-section">
376
+ <div class="left-section-header">Languages</div>
377
+ <ul class="languages-list">
378
+ <% data[:languages].each do |language| %>
379
+ <li class="language-item"><%= language[:name] %></li>
380
+ <% end %>
381
+ </ul>
382
+ </div>
383
+ <% end %>
384
+
385
+ <!-- Interests -->
386
+ <% if data[:interests] && data[:interests].any? %>
387
+ <div class="interests-section">
388
+ <div class="left-section-header">Interests</div>
389
+ <div class="interests-list">
390
+ <% data[:interests].each do |interest| %>
391
+ <span class="interest-item"><%= interest[:name] %></span>
392
+ <% end %>
393
+ </div>
394
+ </div>
395
+ <% end %>
396
+ </div>
397
+
398
+ <!-- Right Column -->
399
+ <div class="right-column">
400
+ <!-- Profile Header -->
401
+ <div class="profile-header">
402
+ <div class="profile-name"><%= data[:profile][:name] %></div>
403
+ <% if data[:profile][:title] %>
404
+ <div class="profile-title"><%= data[:profile][:title] %></div>
405
+ <% end %>
406
+ <% if data[:profile][:about] %>
407
+ <div class="profile-about"><%= data[:profile][:about] %></div>
408
+ <% end %>
409
+ </div>
410
+
411
+ <!-- Experience -->
412
+ <% if data[:experiences] && data[:experiences].any? %>
413
+ <div class="section-header">Experience</div>
414
+ <% data[:experiences].each do |exp| %>
415
+ <div class="experience-item">
416
+ <div class="item-header">
417
+ <div class="item-title"><%= exp[:title] %></div>
418
+ <div class="item-organization"><%= exp[:organisation] %></div>
419
+ <% if exp[:location] %>
420
+ <div class="item-location"><%= [exp[:location][:city], exp[:location][:country]].compact.join(', ') %></div>
421
+ <% end %>
422
+ <div class="item-date">
423
+ <%= "#{exp[:from][:month]}/#{exp[:from][:year]}" %>
424
+ -
425
+ <%= exp[:to] ? "#{exp[:to][:month]}/#{exp[:to][:year]}" : "Present" %>
426
+ </div>
427
+ </div>
428
+
429
+ <% if exp[:skills] && exp[:skills].any? %>
430
+ <div class="item-skills">
431
+ <% exp[:skills].each do |skill| %>
432
+ <span class="item-skill-tag"><%= skill %></span>
433
+ <% end %>
434
+ </div>
435
+ <% end %>
436
+
437
+ <% if exp[:achievements] && exp[:achievements].any? %>
438
+ <ul class="achievements-list">
439
+ <% exp[:achievements].each do |achievement| %>
440
+ <li class="achievement-item"><%= achievement %></li>
441
+ <% end %>
442
+ </ul>
443
+ <% end %>
444
+ </div>
445
+ <% end %>
446
+ <% end %>
447
+
448
+ <!-- Education -->
449
+ <% if data[:education] && data[:education].any? %>
450
+ <div class="section-header">Education</div>
451
+ <% data[:education].each do |edu| %>
452
+ <div class="education-item">
453
+ <div class="item-header">
454
+ <div class="item-title"><%= edu[:qualification] %><%= edu[:field] ? " in #{edu[:field]}" : "" %></div>
455
+ <div class="item-organization"><%= edu[:institute] %></div>
456
+ <% if edu[:location] %>
457
+ <div class="item-location"><%= [edu[:location][:city], edu[:location][:country]].compact.join(', ') %></div>
458
+ <% end %>
459
+ <% if edu[:from] %>
460
+ <div class="item-date">
461
+ <%= "#{edu[:from][:month]}/#{edu[:from][:year]}" %>
462
+ <% if edu[:to] %>
463
+ - <%= "#{edu[:to][:month]}/#{edu[:to][:year]}" %>
464
+ <% end %>
465
+ </div>
466
+ <% end %>
467
+ </div>
468
+
469
+ <% if edu[:achievements] && edu[:achievements].any? %>
470
+ <ul class="achievements-list">
471
+ <% edu[:achievements].each do |achievement| %>
472
+ <li class="achievement-item"><%= achievement %></li>
473
+ <% end %>
474
+ </ul>
475
+ <% end %>
476
+ </div>
477
+ <% end %>
478
+ <% end %>
479
+
480
+ <!-- Projects -->
481
+ <% if data[:projects] && data[:projects].any? %>
482
+ <div class="section-header">Projects</div>
483
+ <% data[:projects].each do |project| %>
484
+ <div class="project-item">
485
+ <div class="item-header">
486
+ <div class="item-title">
487
+ <%= project[:name] %>
488
+ <% if project[:link] %>
489
+ <a href="<%= project[:link] %>" class="contact-link" style="font-size: 9pt; margin-left: 5px;">[Link]</a>
490
+ <% end %>
491
+ </div>
492
+ <% if project[:description] %>
493
+ <div style="margin-top: 5px; font-size: 10pt;"><%= project[:description] %></div>
494
+ <% end %>
495
+ </div>
496
+
497
+ <% if project[:technologies] && project[:technologies].any? %>
498
+ <div class="item-skills">
499
+ <% project[:technologies].each do |tech| %>
500
+ <span class="item-skill-tag"><%= tech %></span>
501
+ <% end %>
502
+ </div>
503
+ <% end %>
504
+ </div>
505
+ <% end %>
506
+ <% end %>
507
+
508
+ <!-- Certifications -->
509
+ <% if data[:certifications] && data[:certifications].any? %>
510
+ <div class="section-header">Certifications</div>
511
+ <% data[:certifications].each do |cert| %>
512
+ <div class="cert-item">
513
+ <div class="cert-name"><%= cert[:name] %></div>
514
+ <% if cert[:issuer] %>
515
+ <div class="cert-issuer"><%= cert[:issuer] %></div>
516
+ <% end %>
517
+ <% if cert[:date] %>
518
+ <div class="cert-date"><%= "#{cert[:date][:day]}/#{cert[:date][:month]}/#{cert[:date][:year]}" %></div>
519
+ <% end %>
520
+ </div>
521
+ <% end %>
522
+ <% end %>
523
+
524
+ <!-- Awards -->
525
+ <% if data[:awards] && data[:awards].any? %>
526
+ <div class="section-header">Awards</div>
527
+ <% data[:awards].each do |award| %>
528
+ <div class="award-item">
529
+ <div class="award-title"><%= award[:title] %></div>
530
+ <% if award[:issuer] %>
531
+ <div class="award-issuer"><%= award[:issuer] %></div>
532
+ <% end %>
533
+ <% if award[:description] %>
534
+ <div style="margin-top: 5px; font-size: 10pt;"><%= award[:description] %></div>
535
+ <% end %>
536
+ <% if award[:date] %>
537
+ <div class="award-date"><%= "#{award[:date][:day]}/#{award[:date][:month]}/#{award[:date][:year]}" %></div>
538
+ <% end %>
539
+ </div>
540
+ <% end %>
541
+ <% end %>
542
+ </div>
543
+ </div>
544
+ </div>
545
+ </body>
546
+ </html>
@@ -0,0 +1,45 @@
1
+ require_relative "../lib/kamisaku"
2
+ require "fileutils"
3
+ require "optparse"
4
+
5
+ # Parse command line arguments
6
+ options = {}
7
+ OptionParser.new do |opts|
8
+ opts.banner = "Usage: #{$0} [options]"
9
+
10
+ opts.on("-t", "--template TEMPLATE", "Use specific template instead of all templates") do |template|
11
+ options[:template] = template
12
+ end
13
+
14
+ opts.on("-z", "--generate-html", "Generate HTML files") do
15
+ options[:write_to_html_file] = true
16
+ end
17
+
18
+ opts.on("-h", "--help", "Show this help message") do
19
+ puts opts
20
+ exit
21
+ end
22
+ end.parse!
23
+
24
+ example_yaml_fie = File.expand_path("../lib/schema/example.yml", __dir__)
25
+ yaml_str = File.read(example_yaml_fie)
26
+
27
+ # Use specified template or all templates
28
+ templates = options[:template] ? [options[:template]] : Kamisaku::TemplateHelpers::TEMPLATES
29
+
30
+ templates.each do |template|
31
+ template_dir = File.expand_path("../examples/#{template}", __dir__)
32
+ FileUtils.mkdir_p(template_dir)
33
+
34
+ pdf_file_path = File.expand_path("../examples/#{template}/example.pdf", __dir__)
35
+
36
+ content_hash = Kamisaku::Helpers.yaml_str_to_content_hash(yaml_str)
37
+ pdf = Kamisaku::PDF.new(content_hash:, template:)
38
+ puts "Building template #{template}"
39
+ pdf.write_to(pdf_file_path)
40
+
41
+ if options[:write_to_html_file]
42
+ html_location = File.expand_path("../examples/#{template}/example.html", __dir__)
43
+ pdf.write_to_html_file(html_location)
44
+ end
45
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kamisaku
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sinaru Gunawardena
@@ -25,10 +25,13 @@ files:
25
25
  - LICENSE.txt
26
26
  - README.md
27
27
  - Rakefile
28
- - examples/paper/john_doe.pdf
29
- - examples/paper/john_doe.yml
30
- - examples/sleek/john_doe.pdf
31
- - examples/sleek/john_doe.yml
28
+ - examples/chromatic/example.pdf
29
+ - examples/gradient/example.pdf
30
+ - examples/meridian/example.pdf
31
+ - examples/paper/example.pdf
32
+ - examples/prism/example.pdf
33
+ - examples/sleek/example.pdf
34
+ - examples/zenith/example.pdf
32
35
  - kamisaku.gemspec
33
36
  - kamisaku.png
34
37
  - lib/kamisaku.rb
@@ -42,10 +45,17 @@ files:
42
45
  - lib/kamisaku/pdf.rb
43
46
  - lib/kamisaku/template_helpers.rb
44
47
  - lib/kamisaku/version.rb
48
+ - lib/schema/example.yml
49
+ - lib/schema/schema.yml
50
+ - lib/templates/chromatic/template.html.erb
51
+ - lib/templates/gradient/template.html.erb
52
+ - lib/templates/meridian/template.html.erb
45
53
  - lib/templates/paper/template.html.erb
54
+ - lib/templates/prism/template.html.erb
46
55
  - lib/templates/sleek/template.html.erb
56
+ - lib/templates/zenith/template.html.erb
57
+ - scripts/rebuild_examples.rb
47
58
  - sig/kamisaku.rbs
48
- - template.yml
49
59
  homepage: https://github.com/sinaru/kamisaku
50
60
  licenses:
51
61
  - MIT
Binary file