Browse code
chore: misc
fiddlerwoaroof authored on 19/08/2020 06:16:20
Showing 2 changed files
Showing 2 changed files
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,154 @@ |
1 |
+\documentclass[margin]{res} |
|
2 |
+ |
|
3 |
+% Default font is the helvetica postscript font |
|
4 |
+\usepackage{polyglossia} |
|
5 |
+\usepackage{fontspec} |
|
6 |
+\usepackage{url} |
|
7 |
+\usepackage{hyperref} |
|
8 |
+\usepackage{hyphenat} |
|
9 |
+ |
|
10 |
+\setdefaultlanguage{english} |
|
11 |
+ |
|
12 |
+\setmainfont{Alegreya-Regular.otf}[ |
|
13 |
+ BoldFont=Alegreya-Bold.otf, |
|
14 |
+ ItalicFont=Alegreya-Italic.otf, |
|
15 |
+ BoldItalicFont=Alegreya-BoldItalic.otf, |
|
16 |
+ SmallCapsFont=AlegreyaSC-Bold.otf |
|
17 |
+] |
|
18 |
+ |
|
19 |
+\setsansfont{AlegreyaSans-Regular.otf}[ |
|
20 |
+ BoldFont=AlegreyaSans-Bold.otf, |
|
21 |
+ ItalicFont=AlegreyaSans-Italic.otf, |
|
22 |
+ BoldItalicFont=AlegreyaSans-BoldItalic.otf, |
|
23 |
+ SmallCapsFont=AlegreyaSansSC-Bold.otf |
|
24 |
+] |
|
25 |
+ |
|
26 |
+\setmonofont{SourceCodePro-Regular.otf} |
|
27 |
+ |
|
28 |
+% Increase text height |
|
29 |
+\textheight=700pt |
|
30 |
+\parskip=8pt |
|
31 |
+ |
|
32 |
+\begin{document} |
|
33 |
+ |
|
34 |
+%------------------------------------------------------------------------------- |
|
35 |
+% NAME AND ADDRESS SECTION |
|
36 |
+%------------------------------------------------------------------------------- |
|
37 |
+\name{\Huge{\textsc{Edward Langley}}} |
|
38 |
+ |
|
39 |
+ |
|
40 |
+\address{\textbf{Email:} edward@elangley.org \\ \textbf{Phone:} (832) 585--2660} |
|
41 |
+\address{3090 Channel Dr. \#210\\ Ventura, CA 93003} |
|
42 |
+ |
|
43 |
+\begin{resume} |
|
44 |
+ |
|
45 |
+%------------------------------------------------------------------------------- |
|
46 |
+% PROJECTS SECTION |
|
47 |
+%------------------------------------------------------------------------------- |
|
48 |
+ \section{\textbf{\textsc{Skills}}} |
|
49 |
+ |
|
50 |
+\par Designing and implementing applications using a variety of programming paradigms and languages. |
|
51 |
+ |
|
52 |
+\par Producing web applications using a variety of server-side and client-side frameworks. |
|
53 |
+ |
|
54 |
+\par Maintaining web servers and relating servies such as PHP-FPM and uWSGI.\@ |
|
55 |
+ |
|
56 |
+\par Administering networks and implementing remote access via OpenVPN, OpenSSH and VNC.\@ |
|
57 |
+ |
|
58 |
+\par Configuring and maintaining email servers and spam filtering. |
|
59 |
+ |
|
60 |
+\par Administering a variety of Linux distributions and other Unices |
|
61 |
+ |
|
62 |
+%------------------------------------------------------------------------------- |
|
63 |
+ |
|
64 |
+%------------------------------------------------------------------------------- |
|
65 |
+% COMPUTER SKILLS SECTION |
|
66 |
+%------------------------------------------------------------------------------- |
|
67 |
+\section{\textbf{\textsc{Technologies}}} |
|
68 |
+ |
|
69 |
+\par Python, Clojure, JavaScript, |
|
70 |
+ TypeScript, PHP, Ruby, Haskell, SQL, |
|
71 |
+ \nohyphens{Common\penalty10000\ Lisp}, |
|
72 |
+ \texttt{\LaTeX{}}, PostScript |
|
73 |
+ |
|
74 |
+\par HTML, CSS (Sass, Bootstrap, Susy grids), VueJS, |
|
75 |
+ Drupal, Symfony2, Apache, Nginx, PHP-FPM, uWSGI |
|
76 |
+ |
|
77 |
+\par MySQL, PostgreSQL, Interbase/Firebird, BerkeleyDB, Redis |
|
78 |
+ |
|
79 |
+\par Postfix, Sendmail, Dovecot, OpenDKIM, DSPAM, Roundcube |
|
80 |
+ |
|
81 |
+\par Vi/Vim, Emacs, VirtualBox, OpenVPN, NFS, Samba |
|
82 |
+ |
|
83 |
+\par Unix, Linux, FreeBSD, Sol\-aris (SmartOS), Mac OSX, AWS (EC2, S3, RDS, Route53) |
|
84 |
+ |
|
85 |
+%------------------------------------------------------------------------------- |
|
86 |
+ |
|
87 |
+%------------------------------------------------------------------------------- |
|
88 |
+% EXPERIENCE SECTION |
|
89 |
+%------------------------------------------------------------------------------- |
|
90 |
+% Modify the format of each position |
|
91 |
+\begin{format} |
|
92 |
+\title{l}\employer{r}\\ |
|
93 |
+\dates{l}\location{r}\\ |
|
94 |
+\body\\ |
|
95 |
+\end{format} |
|
96 |
+%------------------------------------------------------------------------------- |
|
97 |
+ |
|
98 |
+\section{\textbf{\textsc{Experience}}} |
|
99 |
+\employer{Independent Consultant} |
|
100 |
+\location{Ventura, CA} |
|
101 |
+\dates{2014--present} |
|
102 |
+\title{\textbf{Programmer}} |
|
103 |
+\begin{position} |
|
104 |
+ Developed a web interface for managing a router. |
|
105 |
+ |
|
106 |
+ Researched and developed an interface for the bro intrusion detection system. |
|
107 |
+ |
|
108 |
+ Produced a theme for an e-commerce site and developed a deployment |
|
109 |
+ strategy for updates to the site. Implemented and themed a new |
|
110 |
+ e-commerce platform. |
|
111 |
+\end{position} |
|
112 |
+ |
|
113 |
+\employer{NCMI, Baylor College of Medicine} |
|
114 |
+\location{Houston, TX} |
|
115 |
+\dates{2007--2012} |
|
116 |
+\title{\textbf{Python Programmer}} |
|
117 |
+\begin{position} |
|
118 |
+Built a web framework for EMEN2, a document-oriented database for recording scientific experiments. |
|
119 |
+Improved EMEN2's reliability and performance by debugging and fixing memory leaks and taking advantage of |
|
120 |
+Berkeley DB's transactional storage. Implemented the JSON-RPC 2.0 protocol |
|
121 |
+(\url{https://www.github.com/NCMI/jsonrpc}). Prototyped OpenID authentication. Managed migration to |
|
122 |
+EMEN2. |
|
123 |
+\end{position} |
|
124 |
+ |
|
125 |
+\employer{Desktop Assistance, L.P.} |
|
126 |
+\location{Houston, TX} |
|
127 |
+\dates{2004} |
|
128 |
+\title{\textbf{IT Assistant}} |
|
129 |
+\begin{position} |
|
130 |
+Installed and configured Linux desktops and servers. Built a Linux distribution |
|
131 |
+based on Fedora Cores 1 and 2 for internal use. Researched, installed and configured |
|
132 |
+a variety of server applications including: databases, Apache, Squid, Samba, NFS.\@ |
|
133 |
+\end{position} |
|
134 |
+%------------------------------------------------------------------------------- |
|
135 |
+\section{\textbf{\textsc{Publications}}} |
|
136 |
+ |
|
137 |
+\par |
|
138 |
+Rees, I., Langley, E., Chiu, W., \& Ludtke, S.J. (2013). {\em EMEN2: an object oriented database and electronic lab notebook.\/} Microsc Microanal 19, 1--10 |
|
139 |
+ |
|
140 |
+ |
|
141 |
+%------------------------------------------------------------------------------- |
|
142 |
+% EDUCATION SECTION |
|
143 |
+%------------------------------------------------------------------------------- |
|
144 |
+\section{\textbf{\textsc{Education}}} |
|
145 |
+\textbf{Thomas Aquinas College}, Santa Paula, CA\\ |
|
146 |
+{\sl Bachelor of Arts}, Liberal Arts, 2012\hfill GPA:\ 3.96 |
|
147 |
+\\ |
|
148 |
+\textbf{The Catholic University of America}, Washington, DC\\ |
|
149 |
+{\sl Ph.D Student}, Philosophy, 2012--2015\hfill GPA:\ 3.84 |
|
150 |
+%------------------------------------------------------------------------------- |
|
151 |
+ |
|
152 |
+ |
|
153 |
+\end{resume} |
|
154 |
+\end{document} |
0 | 155 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,450 @@ |
1 |
+(in-package :cl-user) |
|
2 |
+ |
|
3 |
+(defpackage :resume-dl |
|
4 |
+ (:use :cl :anaphora :alexandria :serapeum :fw.lu)) |
|
5 |
+(in-package :resume-dl) |
|
6 |
+ |
|
7 |
+(defclass section () |
|
8 |
+ ((subsections :initarg :subsections :reader subsections))) |
|
9 |
+(defclass subsection () |
|
10 |
+ ((items :initarg :items :reader items))) |
|
11 |
+ |
|
12 |
+(defclass address () |
|
13 |
+ ((street :initarg :street :reader street) |
|
14 |
+ (city :initarg :city :reader city) |
|
15 |
+ (state :initarg :state :reader state) |
|
16 |
+ (zipcode :initarg :zipcode :reader zipcode))) |
|
17 |
+ |
|
18 |
+(defun make-address (&rest r &key street city state zipcode) |
|
19 |
+ (declare (ignore street city state zipcode)) |
|
20 |
+ (apply #'make-instance 'address r)) |
|
21 |
+ |
|
22 |
+(defclass person () |
|
23 |
+ ((name :initarg :name :reader name) |
|
24 |
+ (email :initarg :email :reader email) |
|
25 |
+ (phone :initarg :phone :reader phone) |
|
26 |
+ (address :initarg :address :reader address))) |
|
27 |
+ |
|
28 |
+(defun make-person (&rest r &key name email phone address) |
|
29 |
+ (declare (ignore name email phone)) |
|
30 |
+ (apply #'make-instance 'person (list* :address (apply #'make-address address) |
|
31 |
+ r))) |
|
32 |
+ |
|
33 |
+(defclass skill-section (section) |
|
34 |
+ ()) |
|
35 |
+ |
|
36 |
+(defclass skill () |
|
37 |
+ ((description :initarg :description :reader description))) |
|
38 |
+ |
|
39 |
+(defmacro make-skills (&body r) |
|
40 |
+ `(make-instance 'skill-section |
|
41 |
+ :subsections (list ,@(loop for (key value) in r |
|
42 |
+ when (eq key :skill) |
|
43 |
+ collect `(make-instance 'skill :description ,value))))) |
|
44 |
+ |
|
45 |
+(defclass technology-section (section) |
|
46 |
+ ()) |
|
47 |
+ |
|
48 |
+(defclass technology () |
|
49 |
+ ((name :initarg :name :reader name) |
|
50 |
+ (subordinates :initarg :subordinates :reader subordinates))) |
|
51 |
+ |
|
52 |
+(defmacro make-technologies (&rest r) |
|
53 |
+ `(labels ((:technology (name &rest subordinates) |
|
54 |
+ (make-instance 'technology :name name :subordinates (copy-seq subordinates))) |
|
55 |
+ (:group (&rest technologies) |
|
56 |
+ (make-instance 'subsection |
|
57 |
+ :items (copy-seq technologies)))) |
|
58 |
+ (make-instance 'technology-section |
|
59 |
+ :subsections (list ,@(loop for (key . value) in r |
|
60 |
+ collect `(,key ,@value)))))) |
|
61 |
+ |
|
62 |
+(defclass employment-section (section) |
|
63 |
+ ()) |
|
64 |
+ |
|
65 |
+(defclass employer () |
|
66 |
+ ((name :initarg :name :reader name) |
|
67 |
+ (location :initarg :location :reader location) |
|
68 |
+ (dates :initarg :dates :reader dates) |
|
69 |
+ (title :initarg :title :reader title) |
|
70 |
+ (description :initarg :description :reader description))) |
|
71 |
+ |
|
72 |
+(defmacro make-employment (&rest r) |
|
73 |
+ `(labels ((:employer (name &rest r &key location dates title description) |
|
74 |
+ (declare (ignore location dates title description)) |
|
75 |
+ (apply #'make-instance 'employer :name name r))) |
|
76 |
+ (make-instance 'employment-section |
|
77 |
+ :subsections (list ,@(loop for (key . value) in r |
|
78 |
+ collect `(,key ,@value)))))) |
|
79 |
+ |
|
80 |
+(defclass education-section (section) |
|
81 |
+ ()) |
|
82 |
+ |
|
83 |
+(defclass school () |
|
84 |
+ ((name :initarg :name :reader name) |
|
85 |
+ (location :initarg :location :reader location) |
|
86 |
+ (degree :initarg :degree :reader degree) |
|
87 |
+ (graduation-date :initarg :graduation-date :reader graduation-date) |
|
88 |
+ (gpa :initarg :gpa :reader gpa))) |
|
89 |
+ |
|
90 |
+(defmacro make-education (&rest r) |
|
91 |
+ `(labels ((:school (name &rest r &key location degree graduation-date gpa) |
|
92 |
+ (declare (ignore location degree graduation-date gpa)) |
|
93 |
+ (apply #'make-instance 'school :name name r))) |
|
94 |
+ (make-instance 'education-section |
|
95 |
+ :subsections (list ,@(loop for (key . value) in r |
|
96 |
+ collect `(,key ,@value)))))) |
|
97 |
+ |
|
98 |
+(defclass resume () |
|
99 |
+ ((person :initarg :person :reader person) |
|
100 |
+ (sections :initarg :sections :reader sections) |
|
101 |
+ (skills :initarg :skills :reader skills) |
|
102 |
+ (technologies :initarg :technologies :reader technologies) |
|
103 |
+ (employment :initarg :employment :reader employment) |
|
104 |
+ (education :initarg :education :reader education))) |
|
105 |
+ |
|
106 |
+(defun make-resume (&rest r &key person skills technologies employment education) |
|
107 |
+ (declare (ignore person skills technologies employment education)) |
|
108 |
+ (apply #'make-instance 'resume r)) |
|
109 |
+ |
|
110 |
+(defmacro define-resume (place &body body) |
|
111 |
+ (let ((person (assoc :person body)) |
|
112 |
+ (skills (assoc :skills body)) |
|
113 |
+ (technologies (assoc :technologies body)) |
|
114 |
+ (employment (assoc :employment body)) |
|
115 |
+ (education (assoc :education body))) |
|
116 |
+ (let ((definer (etypecase place |
|
117 |
+ (symbol 'defparameter) |
|
118 |
+ (list 'setf)))) |
|
119 |
+ `(,definer ,place |
|
120 |
+ (make-resume ,@(when person |
|
121 |
+ `(:person (make-person ,@(cdr person)))) |
|
122 |
+ ,@(when skills |
|
123 |
+ `(:skills (make-skills ,@(cdr skills)))) |
|
124 |
+ ,@(when technologies |
|
125 |
+ `(:technologies (make-technologies ,@(cdr technologies)))) |
|
126 |
+ ,@(when employment |
|
127 |
+ `(:employment (make-employment ,@(cdr employment)))) |
|
128 |
+ ,@(when education |
|
129 |
+ `(:education (make-education ,@(cdr education))))))))) |
|
130 |
+ |
|
131 |
+ |
|
132 |
+ |
|
133 |
+(defgeneric format-object (object) |
|
134 |
+ (:documentation "Format an object")) |
|
135 |
+ |
|
136 |
+(defgeneric format-section (root section) |
|
137 |
+ (:documentation "Format a section")) |
|
138 |
+ |
|
139 |
+(defparameter *output-stream* (make-synonym-stream '*standard-output*)) |
|
140 |
+(defgeneric format-subsection (root section subsection) |
|
141 |
+ (:documentation "Format a subsection")) |
|
142 |
+ |
|
143 |
+(defgeneric format-item (root section subsection item) |
|
144 |
+ (:documentation "Format an item")) |
|
145 |
+ |
|
146 |
+(defclass font () |
|
147 |
+ ((basename :initarg :basename :reader basename :initform (error "need a basename")) |
|
148 |
+ (role :initarg :role :reader font-role :initform "main") |
|
149 |
+ (extension :initarg :extension :reader extension :initform "otf") |
|
150 |
+ (formats :initarg :formats :reader formats :initform '(:bold :italic :bold-italic :small-cap)) |
|
151 |
+ (regular :initarg :regular :reader regular) |
|
152 |
+ (bold :initarg :bold :reader bold) |
|
153 |
+ (italic :initarg :italic :reader italic) |
|
154 |
+ (bold-italic :initarg :bold-italic :reader bold-italic) |
|
155 |
+ (small-cap :initarg :small-cap :reader small-cap))) |
|
156 |
+ |
|
157 |
+(defmethod initialize-instance :after ((instance font) |
|
158 |
+ &key |
|
159 |
+ (regular (string-join (list (basename instance) |
|
160 |
+ "-Regular"))) |
|
161 |
+ (bold (string-join (list (basename instance) |
|
162 |
+ "-Bold"))) |
|
163 |
+ (italic (string-join (list (basename instance) |
|
164 |
+ "-Italic"))) |
|
165 |
+ (bold-italic (string-join (list (basename instance) |
|
166 |
+ "-BoldItalic"))) |
|
167 |
+ (small-cap (string-join (list (basename instance) |
|
168 |
+ "-SmallCaps")))) |
|
169 |
+ (setf (slot-value instance 'bold) bold |
|
170 |
+ (slot-value instance 'regular) regular |
|
171 |
+ (slot-value instance 'italic) italic |
|
172 |
+ (slot-value instance 'bold-italic) bold-italic |
|
173 |
+ (slot-value instance 'small-cap) small-cap)) |
|
174 |
+ |
|
175 |
+(defgeneric get-font-spec (font kind) |
|
176 |
+ (:method :around ((font font) kind) |
|
177 |
+ (format nil "~a.~a" |
|
178 |
+ (call-next-method) |
|
179 |
+ (extension font))) |
|
180 |
+ (:method ((font font) (kind (eql :regular))) |
|
181 |
+ (regular font)) |
|
182 |
+ (:method ((font font) (kind (eql :bold))) |
|
183 |
+ (bold font)) |
|
184 |
+ (:method ((font font) (kind (eql :italic))) |
|
185 |
+ (italic font)) |
|
186 |
+ (:method ((font font) (kind (eql :bold-italic))) |
|
187 |
+ (bold-italic font)) |
|
188 |
+ (:method ((font font) (kind (eql :small-cap))) |
|
189 |
+ (small-cap font))) |
|
190 |
+ |
|
191 |
+(defmethod format-object ((font font)) |
|
192 |
+ (format *output-stream* "~&\\set~afont{~a}~@[[~%~{~4t~{~a~^=~}~^,~%~}~%]~]~%" |
|
193 |
+ (font-role font) |
|
194 |
+ (get-font-spec font :regular) |
|
195 |
+ (loop for format in (formats font) |
|
196 |
+ collect (list (ecase format |
|
197 |
+ (:bold "BoldFont") |
|
198 |
+ (:italic "ItalicFont") |
|
199 |
+ (:bold-italic "BoldItalicFont") |
|
200 |
+ (:small-cap "SmallCapsFont")) |
|
201 |
+ (get-font-spec font format))))) |
|
202 |
+ |
|
203 |
+ |
|
204 |
+(defclass latex-doc () |
|
205 |
+ ((body :initarg :body :reader body))) |
|
206 |
+ |
|
207 |
+(defgeneric document-class (latex-doc) |
|
208 |
+ (:method ((latex-doc latex-doc)) |
|
209 |
+ (values "res" |
|
210 |
+ (list "margin")))) |
|
211 |
+ |
|
212 |
+(defgeneric packages (latex-doc) |
|
213 |
+ (:method ((latex-doc latex-doc)) |
|
214 |
+ (list "polyglossia" |
|
215 |
+ "fontspec" |
|
216 |
+ "url" |
|
217 |
+ "hyperref" |
|
218 |
+ "hyphenat"))) |
|
219 |
+ |
|
220 |
+(defgeneric main-font (doc) |
|
221 |
+ (:method ((doc latex-doc)) |
|
222 |
+ (make-instance 'font |
|
223 |
+ :basename "Alegreya" |
|
224 |
+ :small-cap "AlegreyaSC-Bold"))) |
|
225 |
+ |
|
226 |
+(defgeneric sans-font (doc) |
|
227 |
+ (:method ((doc latex-doc)) |
|
228 |
+ (make-instance 'font |
|
229 |
+ :role "sans" |
|
230 |
+ :basename "AlegreyaSans" |
|
231 |
+ :small-cap "AlegreyaSansSC-Bold"))) |
|
232 |
+ |
|
233 |
+(defgeneric mono-font (doc) |
|
234 |
+ (:method ((doc latex-doc)) |
|
235 |
+ (make-instance 'font |
|
236 |
+ :role "mono" |
|
237 |
+ :formats '() |
|
238 |
+ :basename "SourceCodePro" |
|
239 |
+ :small-cap "AlegreyaSansSC-Bold"))) |
|
240 |
+ |
|
241 |
+(defgeneric document-language (doc) |
|
242 |
+ (:method ((doc latex-doc)) |
|
243 |
+ "english")) |
|
244 |
+ |
|
245 |
+(defgeneric header (doc) |
|
246 |
+ (:method ((doc latex-doc)) |
|
247 |
+ "\\textheight=700pt |
|
248 |
+\\parskip=8pt")) |
|
249 |
+ |
|
250 |
+(defmethod format-object ((doc latex-doc)) |
|
251 |
+ (multiple-value-bind (doc-class class-options) (document-class doc) |
|
252 |
+ (format *output-stream* "~&\\documentclass[~{~a~^,~}]{~a}~2&~{\\usepackage{~a}~%~}~2&\\setdefaultlanguage{~a}" |
|
253 |
+ class-options doc-class |
|
254 |
+ (packages doc) |
|
255 |
+ (document-language doc))) |
|
256 |
+ (format-object (main-font doc)) |
|
257 |
+ (format-object (sans-font doc)) |
|
258 |
+ (format-object (mono-font doc)) |
|
259 |
+ (format *output-stream* "~2&~a~2&\\begin{document}~%" |
|
260 |
+ (header doc)) |
|
261 |
+ (format-object (body doc)) |
|
262 |
+ (format *output-stream* "~&\\end{document}~%")) |
|
263 |
+ |
|
264 |
+(defmethod format-object ((object resume)) |
|
265 |
+ (fresh-line *output-stream*) |
|
266 |
+ (format-section object (person object)) |
|
267 |
+ (fresh-line *output-stream*) |
|
268 |
+ (format *output-stream* "\\begin{resume}~%") |
|
269 |
+ (terpri *output-stream*) |
|
270 |
+ (format-section object (skills object)) |
|
271 |
+ (fresh-line *output-stream*) |
|
272 |
+ (terpri *output-stream*) |
|
273 |
+ (format-section object (technologies object)) |
|
274 |
+ (fresh-line *output-stream*) |
|
275 |
+ (terpri *output-stream*) |
|
276 |
+ (format-section object (employment object)) |
|
277 |
+ (fresh-line *output-stream*) |
|
278 |
+ (terpri *output-stream*) |
|
279 |
+ (format-section object (education object)) |
|
280 |
+ (fresh-line *output-stream*) |
|
281 |
+ (format *output-stream* "\\end{resume}~%")) |
|
282 |
+ |
|
283 |
+(defmethod format-section :after ((object resume) section) |
|
284 |
+ (format *output-stream* "\\bigskip{}")) |
|
285 |
+ |
|
286 |
+(defmethod format-section :before ((object resume) (section education-section)) |
|
287 |
+ (format *output-stream* "\\vfill{}")) |
|
288 |
+ |
|
289 |
+(defmethod format-section ((object resume) (person person)) |
|
290 |
+ (format *output-stream* "~&\\name{\\Huge{\\textsc{~a}}} |
|
291 |
+\\address{\\textbf{Email:} ~a \\\\ \\textbf{Phone:} ~a}~%" |
|
292 |
+ (name person) |
|
293 |
+ (email person) |
|
294 |
+ (phone person)) |
|
295 |
+ (format-subsection object person (address person)) |
|
296 |
+ (fresh-line *output-stream*)) |
|
297 |
+ |
|
298 |
+(defmethod format-subsection ((object resume) (person person) (address address)) |
|
299 |
+ (let ((street (street address))) |
|
300 |
+ (format *output-stream* "~&\\address{~a ~a ~a \\\\ ~a, ~a ~a}~%" |
|
301 |
+ (getf street :number) |
|
302 |
+ (getf street :street) |
|
303 |
+ (string-replace-all "#" "\\#" (getf street :apartment)) |
|
304 |
+ (city address) |
|
305 |
+ (state address) |
|
306 |
+ (zipcode address)))) |
|
307 |
+ |
|
308 |
+(defmethod format-section ((object resume) (section skill-section)) |
|
309 |
+ (format *output-stream* "~&\\section{\\textbf{\\textsc{Skills}}}~2%") |
|
310 |
+ (mapcar (op (format-subsection object section _) |
|
311 |
+ (fresh-line *output-stream*) |
|
312 |
+ (terpri *output-stream*)) |
|
313 |
+ (subsections section))) |
|
314 |
+ |
|
315 |
+(defmethod format-subsection ((object resume) (section skill-section) (subsection skill)) |
|
316 |
+ (format *output-stream* "~&\\par ~a~%" (description subsection))) |
|
317 |
+ |
|
318 |
+ |
|
319 |
+(defmethod format-section ((object resume) (section technology-section)) |
|
320 |
+ (format *output-stream* "\\section{\\textbf{\\textsc{Technologies}}}~2%") |
|
321 |
+ (mapcar (op (format-subsection object section _)) |
|
322 |
+ (subsections section))) |
|
323 |
+ |
|
324 |
+(defmethod format-subsection ((object resume) (section technology-section) (subsection subsection)) |
|
325 |
+ (declare (optimize (debug 3))) |
|
326 |
+ (format *output-stream* "~&\\par ") |
|
327 |
+ (loop for (technology . rest) on (items subsection) |
|
328 |
+ do (format-item object section subsection technology) |
|
329 |
+ when rest |
|
330 |
+ do (princ ", " *output-stream*)) |
|
331 |
+ (fresh-line *output-stream*) |
|
332 |
+ (terpri *output-stream*)) |
|
333 |
+ |
|
334 |
+(defmethod format-item ((object resume) (section technology-section) subsection (item technology)) |
|
335 |
+ (princ (name item) *output-stream*) |
|
336 |
+ (when (subordinates item) |
|
337 |
+ (format *output-stream* " (~{~a~^, ~})" (subordinates item)))) |
|
338 |
+ |
|
339 |
+(defmethod format-section ((object resume) (section employment-section)) |
|
340 |
+ (format *output-stream* "~&\\section{\\textbf{\\textsc{Experience}}}~2%") |
|
341 |
+ (loop for subsection in (subsections section) |
|
342 |
+ do (format-subsection object section subsection))) |
|
343 |
+ |
|
344 |
+(defmethod format-subsection ((object resume) (section employment-section) (subsection employer)) |
|
345 |
+ (flet ((:formatter (format &rest args) (apply #'format *output-stream* format args))) |
|
346 |
+ (with-accessors #.(mapcar (op (list _1 _1)) '(name location dates title description)) subsection |
|
347 |
+ (:formatter "~&\\employer{~a}~%" name) |
|
348 |
+ ;(:formatter "~&\\location{~a}~%" location) |
|
349 |
+ (typecase dates |
|
350 |
+ (cons (:formatter "~&\\dates{~a (~a~@[--~a~])}~%" location (car dates) |
|
351 |
+ (case (cdr dates) |
|
352 |
+ (:now "Present") |
|
353 |
+ (t (cdr dates))))) |
|
354 |
+ (integer (:formatter "~&\\dates{~a, (~a)}~%" location dates))) |
|
355 |
+ ;(:formatter "~&\\title{\\textbf{~a}}~%" title) |
|
356 |
+ (:formatter "~&\\begin{position}~%~a~&\\end{position}~%" description)))) |
|
357 |
+ |
|
358 |
+(defmethod format-section ((object resume) (section education-section)) |
|
359 |
+ (format *output-stream* "\\section{\\textbf{\\textsc{Education}}}~2%") |
|
360 |
+ (loop for subsection in (subsections section) |
|
361 |
+ do (format-subsection object section subsection))) |
|
362 |
+ |
|
363 |
+(defmethod format-subsection ((object resume) (section education-section) (subsection school)) |
|
364 |
+ (with-accessors* (name location degree graduation-date) subsection |
|
365 |
+ (format *output-stream* "~a, ~a\\hfill{\\sl ~a}, ~a, ~a\\\\~%" |
|
366 |
+ name location |
|
367 |
+ (car degree) |
|
368 |
+ (cdr degree) |
|
369 |
+ graduation-date))) |
|
370 |
+ |
|
371 |
+(define-resume *resume* |
|
372 |
+ (:person :name "Edward Langley" |
|
373 |
+ :email "edward@elangley.org" |
|
374 |
+ :phone "(832) 585-2660" |
|
375 |
+ :address '(:street (:number "3090" :street "Channel Dr." :apartment "#210") |
|
376 |
+ :city "Ventura" |
|
377 |
+ :state "CA" |
|
378 |
+ :zipcode "93003")) |
|
379 |
+ (:skills (:skill "Designing and implementing applications using a variety of programming paradigms and languages.") |
|
380 |
+ (:skill "Developing web applications using a variety of server-side and client-side frameworks") |
|
381 |
+ (:skill "Deploying and maintaining web applications on nginx using FastCGI") |
|
382 |
+ (:skill "Administering and configuring Linux, FreeBSD and Solaris")) |
|
383 |
+ (:technologies (:group (:technology "Haskell") |
|
384 |
+ (:technology "Clojure") |
|
385 |
+ (:technology "SQL") |
|
386 |
+ (:technology "Python") |
|
387 |
+ (:technology "Common Lisp") |
|
388 |
+ (:technology "Javascript") |
|
389 |
+ (:technology "PHP") |
|
390 |
+ (:technology "Postscript")) |
|
391 |
+ (:group (:technology "HTML") |
|
392 |
+ (:technology "CSS" |
|
393 |
+ "Sass" |
|
394 |
+ "Bootstrap" |
|
395 |
+ "Susy grids") |
|
396 |
+ (:technology "VueJS") |
|
397 |
+ (:technology "Apache") |
|
398 |
+ (:technology "Nginx") |
|
399 |
+ (:technology "PHP-FPM") |
|
400 |
+ (:technology "uWSGI")) |
|
401 |
+ (:group (:technology "MySQL") |
|
402 |
+ (:technology "PostgreSQL") |
|
403 |
+ (:technology "Redis") |
|
404 |
+ (:technology "BerkeleyDB")) |
|
405 |
+ (:group (:technology "Linux") |
|
406 |
+ (:technology "FreeBSD") |
|
407 |
+ (:technology "Solaris") |
|
408 |
+ (:technology "Mac OSX") |
|
409 |
+ (:technology "AWS" "EC2" "S3" "RDS" "Route53"))) |
|
410 |
+ (:employment (:employer "Independent Consultant" |
|
411 |
+ :location "Ventura, CA" |
|
412 |
+ :dates '(2014 . :now) |
|
413 |
+ :title "Programmer" |
|
414 |
+ :description "Developed a web interface for managing a router including interfaces for |
|
415 |
+ various system services such as the bro intrusion detection system. |
|
416 |
+ |
|
417 |
+ Themed an e-commerce site, developed a deployment strategy and managed updates to the site. |
|
418 |
+ Implemented and themed a new e-commerce platform. |
|
419 |
+ |
|
420 |
+ Developed a tool to track my time and automatically upload it to my invoicing service.") |
|
421 |
+ (:employer "NCMI, Baylor College of Medicine" |
|
422 |
+ :location "Houston, TX" |
|
423 |
+ :dates '(2007 . 2012) |
|
424 |
+ :title "Python Programmer" |
|
425 |
+ :description "Built a web framework for EMEN2, a document-oriented database for recording |
|
426 |
+ scientific experiments. |
|
427 |
+ |
|
428 |
+ Improved EMEN2's reliability and performance by debugging and fixing memory leaks and taking |
|
429 |
+ advantage of Berkeley DB's transactional storage. |
|
430 |
+ |
|
431 |
+ Managed the migration of another lab's data from EMEN1 to EMEN2 and built a conversion tool |
|
432 |
+ that allowed the user to add new rules for correcting invalid data without restarting the |
|
433 |
+ conversion process.") |
|
434 |
+ (:employer "Desktop Assistance, L.P." |
|
435 |
+ :location "Houston, TX" |
|
436 |
+ :dates 2004 |
|
437 |
+ :title "IT Assistant" |
|
438 |
+ :description "Installed and configured Linux desktops and serves. Build a Fedora derivative |
|
439 |
+ for internal use. Researched, installed and configured a variety of services including: |
|
440 |
+ databases, Apache, Squid, Samba and NFS.")) |
|
441 |
+ (:education (:school "Thomas Aquinas College" |
|
442 |
+ :location "Santa Paula, CA" |
|
443 |
+ :degree '("B.A." . "Liberal Arts") |
|
444 |
+ :graduation-date "2012" |
|
445 |
+ :gpa 3.96) |
|
446 |
+ (:school "The Catholic University of America" |
|
447 |
+ :location "Washington, DC" |
|
448 |
+ :degree '("Ph.D student" . "Philosophy") |
|
449 |
+ :graduation-date "2015" |
|
450 |
+ :gpa 3.84))) |