(load "../utils/list2html.lisp") (defun date (start end) (format nil "~A/~A" start end)) (defun gpa (gpa bounds) (format nil "~A/~A" gpa bounds)) (defun education (&key school location start end degree majorgpa totalgpa) (let ((locationtext (format nil "~A: ~A - ~A" location start end)) (majortext (format nil "~A Major GPA" majorgpa)) (totaltext (format nil "~A Total GPA" totalgpa))) `((h1 "Education") (hr :align "left") (div :style-float "right" ,locationtext (br) ,degree (br) ,majortext (br) ,totaltext) ,school (div :style-clear "both")))) (defun skills (skill-list) `((h1 "Relevant Skills") (hr :align "left") (table ,@(mapit `(tr :valign "top" (td ,(handle-desc-element (car it))) (td :width "50%" ,@(if (listp (cadr it)) (mapit `(,it (br)) (cadr it)) (list (cadr it))))) skill-list)))) (defun handle-desc-list (list) `(ul ,@(mapit `(li ,(handle-desc-element it)) list))) (defun handle-paragraph-element (p-elem) (cond ((stringp p-elem) p-elem) ((and (listp p-elem) (eql (car p-elem) 'bold)) `(span :style-font-weight "bold" ,(cadr p-elem))) ((and (listp p-elem) (eql (car p-elem) 'invisible)) `(span :style-color "white" ,(cadr p-elem))))) (defun handle-paragraph (paragraph) (mapcar #'handle-paragraph-element paragraph)) (defun handle-desc-element (desc-element) (cond ((stringp desc-element) desc-element) ((and (listp desc-element) (eql 'list (car desc-element))) (handle-desc-list (cdr desc-element))) ((listp desc-element) (handle-paragraph desc-element)))) (defun print-description (description) (mapcar #'handle-desc-element description)) (defun pos (&key position start end description one-line) `(div (span :style-font-weight "bold" ,position) " (" ,start " - " ,(or end "Present") ")" ,(if one-line (print-description description) `(div :style-margin-left 20 ,(print-description description))))) (defun all-work (work) `((h1 "Work Experience") (hr :align "left") ,@work)) (defun work (&key company positions) `(div (h2 ,company) (div :style-margin-left 20 ,@positions) (br))) (defun all-oss (oss-projs) `((h1 "Open Source Projects") (hr :align "left") ,@oss-projs)) (defun oss-proj (&key project project-desc project-website role start end) `(div (h2 ,project " (" ,project-website ")") (div :style-margin-left "20px" (span :style-font-weight "bold" ,role) " (" ,start " - " ,(or end "Present") ")" (div :style-margin-left "20px" ,(print-description project-desc))))) (defun build-css () '((body nil :font-size "73%") (table nil :font-size "100%") (hr nil :width "60%") (p nil :margin-top 0 :margin-bottom 0) (ul nil :margin-top 0 :margin-bottom 0) (h1 nil :font-size "120%" :margin-top 0) (h2 nil :font-size "110%" :margin-top 0 :margin-bottom 0))) (defun resume (&key name email phone addr1 addr2 education skills work oss) `(html (head (title ,name) (style ,(build-css))) (body (div :style-width "8.5in" (center (span :style-font-weight "bold" ,(format nil "~:@(~A~)" name))) (div :style-float "right" :style-text-align "right" ,addr1 (br) ,addr2) (div ,email (br) ,phone) (br) ,education (br) ,skills (br) ,(all-work work) ,(all-oss oss))))) (defun dump-to-html (resume-file out-file) (with-open-file (out out-file :direction :output :if-exists :supersede) (with-open-file (in resume-file) (format out "~A" (list-to-html-pretty (eval (read in)))))))