From 1614f02e9b33e1a57303774a6ee0759fe211c0a0 Mon Sep 17 00:00:00 2001 From: dozens Date: Thu, 21 Dec 2023 15:23:57 -0700 Subject: [PATCH] Add mustache lambdas Now you can define lambdas in lambdas.js. In the build process, ed will creat the json for the view from the toml, and insert the lambdas to be fed to mustache to expand the templates to create the groff to create the pdf. See the examples in lambdas.js for guidance on writing lambdas. --- .gitignore | 2 - README.md | 4 +- example.pdf | Bin 18189 -> 18220 bytes justfile | 31 ++++---- lambdas.js | 27 +++++++ resume.template | 30 ++++---- view.js | 192 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 250 insertions(+), 36 deletions(-) delete mode 100644 .gitignore create mode 100644 lambdas.js create mode 100644 view.js diff --git a/.gitignore b/.gitignore deleted file mode 100644 index a3ed5cd..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -resume.toml -resume.pdf diff --git a/README.md b/README.md index a6b6bae..65a25e2 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ and then exported to pdf. ## You Will Need -1. GNU groff version 1.23.0: for typesetting and pdf output (with the ms macro package; it *should* be installed anywhere groff is installed) -2. mustache 4.2.0: for templates +1. groff 1.23.0: for typesetting and pdf output (with the ms macro package; it *should* be installed anywhere groff is installed) +2. mustache.js 4.2.0: for templates 3. taplo 0.8.1: toml toolkit. Provides conversion to JSON, formatting, and validation. 4. jq 1.6: json queries 5. (optional) just 1.14.0: just a command runner diff --git a/example.pdf b/example.pdf index 8c30ed9f1661a5734f39b3203b355e4448e1b6d9..9b8be2655fd9630709da78af254e2f032812db7b 100644 GIT binary patch delta 2075 zcmZXVdpHve8^#l1LuHZUkSOG|*=%!Yy<&>DNwLTzWh;j*N^2ch${~%JLs3L>%EBC) zLpG&I=GeiENJwEchuZ3OdcW_zzVEue%lG_sU%%(Rujl^nNoL5DF=UvfG#C=NcQ5cl zN1AIIWylJtF2HIxj}_>|1Bm zR6vYdx#yx_zV_5-G^niV_CWOc^PdZof^n{W$SxU`s-ZA ztT8(#z{oRKx0Z>^!{tp zoLis+seI6Px}=-o@t9!M$($mEUe~q$YN2fAi;;uJe!TOd!0;Qui0co6j>U!nL;6nv zlbA^TQK4-Wt$ZR_(X~W3y0cYQZ0PLgp}oXU>;N3 zbGLJAhQKebx{?V}Yb`(WJN$l1d?bFHQquRar}cfK#Yy=(e@S-)09@!~-Y+(|<&ZX# zUmGwlQ{kR?W=ZMj<{}2rVgWp)_+=F{bG0nykV77Ww&w<=Ri4@G>V0iWSDf1Wb33kH zT~9@vk+!jyqdGIM*=zV}TOThv>5BFPrtm{$vw`fis=Z<{l=}HdpLHm3=DJ)A#|QiQ zf|(KDEknh}dD}5#t1hFZHm#N-|1YJwk5*0yKHM6V`W9|t!8E;mADQe(MU56jV zi!-n~!|u7_$Sanrv9Fc-(imxHY2;n4HH`OWqBnh-d*`;Q8}ctU1S7k>qd(1=pYKXg z1Sk>(&4{plZ1+i7^#+}Xi0jTD)s&_&`KT=?G!;-3F}>VlV$Mi=pFfdL^vWy^Acza&qA9t!ka<1F{|$G@>9;x=9h>zNA{|5iUz>6 zw(!+x%VP1o-sMX&N*d2$7a8} zhMpCE7Wd;xqX~U)@$vcNTdg!*zf4mgcgyj_EM&+ckJjXdP9+epWQ8 zR(FSj!Ip*7gTxvDlhofq=mMaPf*;{Z|MvZpjXixbZ$kRgbomL?_)j zJ%?p^C9>VS#oSWIr zrovW+_UKvZ1p3!m$fMsSU}-y5O4AM=%`~XE{Yc`|CZj?c)4UyTcKFPu6z{i`3wic@ zrO3EmBDo;N&1c0tv8N7mOltS%pbvyluGSHEP?|1Q@~&U{n6gG2`f#s$8~?8b z2}QD&@R;2;TKaUVC!qjpDQ7m|TnQJ;?`B$xqB*k%0$#L5U9vzMG>wims$Am+>QI+f zlRXX1sTIyy=hEJE$a7tD3gpz(6FrfgXp5X^vKkf*RqsCAr*tNS0NT8W1)edQ<_H1c zgISeyN7*K$D&3!V)M<^6AaIT}?E9q0g4n28qn$`i_83_zE|egiss{?E7wiNqQ`V2f zM|`}f!7f}`rS&hf(y?L=%x*XWYtPHhM)Gv-p`t3abM{t2?S_dSM7sWkx9F?OYXxnl z4D@5+i=}pZ4m*(Haie!qj6cY+Uq&U=>N}L9F$tgU{gBf79ll>FrnEpBGY5Mviap1I zQI|)!&}=E%IBd1udxZJ%JqbpI7%Ub?#IM zF#Vc>w*nLbLBUYabfJR7e|3$HVuIs#7{b8%-(x^F0RAH&2wR9vdcBJs&DMI|%G$=p zdcEBm4uk$5LqM&e>$3!|LFvU+alM6AvOqz&3Xn$+Q8N^ XYX}O3Natc)fk+4nXl(4_fdT#vwVua9 delta 2027 zcmZXOdpOgJAIE>5l{=X<4ymm}7&*Iq?c!P#+A6uEDd{98mm^DtwJeuPhFa7}F6p?G zAtX96w>9^rlFf#>%#=k+MJ}D+^E=P;d!FCp_x|hsygu*u^Zsx$l`=AwZarckvFeVF z>d_Z31fTgsJ??%bsr!Nir_-#kw8ak}(>-)+T>cg(2*|2Izwy!T-hS@3F4!f-If)7g ze|!#|H_C1d+r>TwFH*8^N@#ACUP(%H`X-HPDO%XUXtCC8AE%sY)n-VoxNXe-;(EZC zozthxMg|%vM|@{8g?B-EEsV(5^sSS#VUu9T!u9SBldfHHMrEG-PtnUIh0&zkbWxmW z_=ogK{7v_d%I+#`)TDu`5OuQAJKZmXWunEGepk{r$-YEtW1|c2offn`o7+}*XoXSa zbyhV-_0|dH#!{p*DanqQZ7XBz>p!=8W3E@5>Q2|rtJZi0%{)E-gmDAX@4!`AO-?0_ z>wDgE?YzudL~NVxzDukOTe@c2n>QdE`iSE`R7yO;5%3(!vG$9a@!=s6b@?#sn6Uj| z6Zc?k35Q!Zts9nuMhDTnji4&&cyzL}OlhCi1QpNQcb5;|Pif|b@V*S|3|8@Fp|F>f zEuFxP&^`|r9Gr1uqB`4&mr;_DSA$=;U-4_#o{V?^D#JvpVoxxNoZVbkq>*GXO+8d4$ zEO15PAlx{zXnBW6_Q`JsPk|GT$VcSlBg%uY(iyGb1sx5)b}I{n!(==^0-xxirf+Up zaQt`hVUmneWj35o*2%-L%)C{#RXn{qh|*7>mlVxoCUs{mHxUk%B@gU5)gB-xY`jR-}a#JZ@y_-29z9 zNAIxx3crpy%6g$qn;wCVz7vyq*z_NPaWYRUL&iMvo20Msmpu;-!+5pww+3r&cd{eT zEpCoZtwi$ZpDSC5kW1#xUOtp!6QIePa6?j-8|kOpMK=MD6ofvj);(>m0ZvT2I`ASf zzU;BY6QVQH?W}a1*r-6IJEUG8f@EOMR~rhDLFv!Cl|dybUpfzi#1(1ck&o8=s02p{ z<85@4o7lg#_3HQX9DAUR(3_3A*If}u^X=EZmtmn+YOTRt$vk+aGn6Fk|6n+Kd|6^s zjai@|b0xp!1aEyc@5T#sFp~ThK~5jKoq7-sIKBQRDz$6BY`ZQNg$Q!+C#BJ_ zuYv8r`vUjoIsZbMgmq?iu2MW`_w-FkfaHA>qKC9c?9t!bcE+%3emwXsA_r2lyS_pY zyNwej;`9>gbyf#ZBi0jh@{UhY%>f;&MU_b+;cV=M&W?RM8077y6|md!KU0_6UJHZS zq@_gm!o)yptixn2USLdb3|^3rhF9w3topzZZe}SJ>VLU#4i>ku8+>>4;rHC6R}*hb_|!F3Sh5Cy;;d*apbPScL%2zs}~nSZbSy6!9NHBcba57$nvPhsqKjuw|g| z8%_u`3cE3mutDShk71Em}JgT`(sBheTfY9q73 cAR233-PH7ehpYO(0RgeA$N&HU diff --git a/justfile b/justfile index 3a40867..a6fe143 100644 --- a/justfile +++ b/justfile @@ -2,10 +2,6 @@ default: just --list --unsorted -# convert to json -json: - taplo get -f resume.toml -o json - # format toml fmt: taplo fmt resume.toml @@ -14,17 +10,18 @@ fmt: validate: taplo lint resume.toml -# make groff -groff: - just json | mustache - resume.template - -# make pdf +# create pdf pdf: - just groff | groff -ms -t -Tpdf > resume.pdf - -# example -example: - taplo get -f example.toml -o json \ - | mustache - resume.template \ - | groff -ms -t -Tpdf \ - > example.pdf + #!/usr/bin/env sh + ed< example.pdf diff --git a/lambdas.js b/lambdas.js new file mode 100644 index 0000000..d65b206 --- /dev/null +++ b/lambdas.js @@ -0,0 +1,27 @@ +bold: function() { + return function(text, render) { + return "" + render(text) + ""; + } +}, +join: function() { + return function(text, render) { + return render(text).split(',').join(', '); + } +}, +formatdate: function() { + return function(text, render) { + return new Date(render(text)).toLocaleDateString( + 'en-us', + { + year: 'numeric', + month: 'long', + day: 'numeric' + } + ); + } +}, +chicken: function() { + return function(text, render) { + return render(text).replace(/(.)(.)/g, (match) => match[0].toLowerCase() + match[1].toUpperCase()) + } +} diff --git a/resume.template b/resume.template index 640e51c..c7c8a7d 100644 --- a/resume.template +++ b/resume.template @@ -1,13 +1,15 @@ -.EH '''' -.OH '''' -.nr HM .5i -.nr FM .5i -.TS H +.EH '''' \" delete header (even pages) +.OH '''' \" delete header (odd pages) +.nr HM .5i \" tighter header margin +.nr FM .5i \" tighter footer margin +.nr PI 2n \" tighter paragraph indentation (for bullet lists) +.nr PD 0 \" tighter paragraph spacing +.TS H \" Table Start! center tab(;); cbx s c s c s -cfI s. +lfI s. .TH ./" ============ ./" == HEADER == @@ -29,7 +31,7 @@ T} ./" == WORK == ./" ========== .T& -lbv1 s +lbv2 s - - {{#work}} lb r @@ -39,18 +41,16 @@ l s {{/highlights}} {{/work}} l l. -Experience -.ds +{{#chicken}}Experience{{/chicken}} {{#work}} {{{name}}};{{{location}}} -{{{position}}};{{startDate}}-{{endDate}} +{{{position}}};{{#formatdate}}{{startDate}}{{/formatdate}}\*[-]{{#formatdate}}{{endDate}}{{/formatdate}} {{#highlights}} T{ .IP \(bu {{{.}}} T} {{/highlights}} -.de .sp 1 {{/work}} ; @@ -69,7 +69,7 @@ l s l s. Skills {{#skills}} -{{{name}}}: {{#keywords}} {{{.}}} {{/keywords}} +{{{name}}}: {{#join}} {{{keywords}}} {{/join}} {{/skills}} ; . @@ -87,7 +87,7 @@ l r l r. Awards {{#awards}} -{{title}}, {{awarder}};{{date}} +{{title}}, {{awarder}};{{#formatdate}}{{date}}{{/formatdate}} {{/awards}} ; . @@ -105,7 +105,7 @@ l r l l. Education {{#education}} -{{institution}}, {{area}};{{startDate}}-{{endDate}} +{{institution}}, {{area}};{{#formatdate}}{{startDate}}{{/formatdate}}\*[-]{{#formatdate}}{{endDate}}{{/formatdate}} {{/education}} ; . @@ -123,7 +123,7 @@ l s l s. Interests {{#interests}} -{{name}}: {{#keywords}} {{{.}}} {{/keywords}} +{{name}}: {{#join}} {{{keywords}}} {{/join}} {{/interests}} ; .TE diff --git a/view.js b/view.js new file mode 100644 index 0000000..9fd3934 --- /dev/null +++ b/view.js @@ -0,0 +1,192 @@ +module.exports = +{ + "$schema": "https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json", + "basics": { + "name": "Richard Hendriks", + "label": "Programmer", + "image": "", + "email": "richard.hendriks@mail.com", + "phone": "(912) 555-4321", + "url": "http://richardhendricks.example.com", + "summary": "Richard hails from Tulsa. He has earned degrees from the University of Oklahoma and Stanford. (Go Sooners and Cardinal!) Before starting Pied Piper, he worked for Hooli as a part time software developer. While his work focuses on applied information theory, mostly optimizing lossless compression schema of both the length-limited and adaptive variants, his non-work interests range widely, everything from quantum computing to chaos theory. He could tell you about it, but THAT would NOT be a \"length-limited\" conversation!", + "location": { + "address": "2712 Broadway St", + "postalCode": "CA 94115", + "city": "San Francisco", + "countryCode": "US", + "region": "California" + }, + "profiles": [ + { + "network": "Twitter", + "username": "neutralthoughts", + "url": "" + }, + { + "network": "SoundCloud", + "username": "dandymusicnl", + "url": "https://soundcloud.example.com/dandymusicnl" + } + ] + }, + "work": [ + { + "name": "Pied Piper", + "location": "Palo Alto, CA", + "description": "Awesome compression company", + "position": "CEO/President", + "url": "http://piedpiper.example.com", + "startDate": "2013-12-01", + "endDate": "2014-12-01", + "summary": "Pied Piper is a multi-platform technology based on a proprietary universal compression algorithm that has consistently fielded high Weisman Scores™ that are not merely competitive, but approach the theoretical limit of lossless compression.", + "highlights": [ + "Build an algorithm for artist to detect if their music was violating copy right infringement laws", + "Successfully won Techcrunch Disrupt", + "Optimized an algorithm that holds the current world record for Weisman Scores" + ] + } + ], + "volunteer": [ + { + "organization": "CoderDojo", + "position": "Teacher", + "url": "http://coderdojo.example.com/", + "startDate": "2012-01-01", + "endDate": "2013-01-01", + "summary": "Global movement of free coding clubs for young people.", + "highlights": [ + "Awarded 'Teacher of the Month'" + ] + } + ], + "education": [ + { + "institution": "University of Oklahoma", + "url": "https://www.ou.edu/", + "area": "Information Technology", + "studyType": "Bachelor", + "startDate": "2011-06-01", + "endDate": "2014-01-01", + "score": "4.0", + "courses": [ + "DB1101 - Basic SQL", + "CS2011 - Java Introduction" + ] + } + ], + "awards": [ + { + "title": "Digital Compression Pioneer Award", + "date": "2014-11-01", + "awarder": "Techcrunch", + "summary": "There is no spoon." + } + ], + "publications": [ + { + "name": "Video compression for 3d media", + "publisher": "Hooli", + "releaseDate": "2014-10-01", + "url": "http://en.wikipedia.org/wiki/Silicon_Valley_(TV_series)", + "summary": "Innovative middle-out compression algorithm that changes the way we store data." + } + ], + "skills": [ + { + "name": "Web Development", + "level": "Master", + "keywords": [ + "HTML", + "CSS", + "Javascript" + ] + }, + { + "name": "Compression", + "level": "Master", + "keywords": [ + "Mpeg", + "MP4", + "GIF" + ] + } + ], + "languages": [ + { + "language": "English", + "fluency": "Native speaker" + } + ], + "interests": [ + { + "name": "Wildlife", + "keywords": [ + "Ferrets", + "Unicorns" + ] + } + ], + "references": [ + { + "name": "Erlich Bachman", + "reference": "It is my pleasure to recommend Richard, his performance working as a consultant for Main St. Company proved that he will be a valuable addition to any company." + } + ], + "projects": [ + { + "name": "Miss Direction", + "description": "A mapping engine that misguides you", + "highlights": [ + "Won award at AIHacks 2016", + "Built by all women team of newbie programmers", + "Using modern technologies such as GoogleMaps, Chrome Extension and Javascript" + ], + "keywords": [ + "GoogleMaps", + "Chrome Extension", + "Javascript" + ], + "startDate": "2016-08-24", + "endDate": "2016-08-24", + "url": "missdirection.example.com", + "roles": [ + "Team lead", + "Designer" + ], + "entity": "Smoogle", + "type": "application" + } + ], + "meta": { + "canonical": "https://raw.githubusercontent.com/jsonresume/resume-schema/master/sample.resume.json", + "version": "v1.0.0", + "lastModified": "2017-12-24T15:53:00" + }, +bold: function() { + return function(text, render) { + return "" + render(text) + ""; + } +}, +join: function() { + return function(text, render) { + return render(text).split(',').join(', '); + } +}, +formatdate: function() { + return function(text, render) { + return new Date(render(text)).toLocaleDateString( + 'en-us', + { + year: 'numeric', + month: 'long', + day: 'numeric' + } + ); + } +}, +chicken: function() { + return function(text, render) { + return render(text).replace(/(.)(.)/g, (match) => match[0].toLowerCase() + match[1].toUpperCase()) + } +} +}