Rewrite previous resume in Typst
This commit is contained in:
		
							parent
							
								
									63aee0dc7b
								
							
						
					
					
						commit
						c175bdb709
					
				
					 3 changed files with 526 additions and 0 deletions
				
			
		
							
								
								
									
										9
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | # My resume | ||||||
|  | 
 | ||||||
|  | ## How to generate using Guix | ||||||
|  | 
 | ||||||
|  | 1. Install `just` (and optionally `bat`) by adding to your Guix Home configuration or running `guix install just bat`. | ||||||
|  | 
 | ||||||
|  | 2. To verify the commands `just` will run on your system, run `bat ./Justfile` (or `cat ./Justfile`). | ||||||
|  | 
 | ||||||
|  | 3. Run `just` to generate `./out/resume.pdf`. Run `just run` to generate then open `./out/resume.pdf`. Run `just dev` to open a shell environment with `typst` and the required font. | ||||||
							
								
								
									
										144
									
								
								src/main.typ
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								src/main.typ
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,144 @@ | ||||||
|  | #{ | ||||||
|  |   import "resume_page.typ": resume_page | ||||||
|  | 
 | ||||||
|  |   let config = ( | ||||||
|  |     identity: ( | ||||||
|  |       name: "Ethan Reece", | ||||||
|  |       email: "contact@ethanreece.com", | ||||||
|  |       phone: "(208) 515-2094", | ||||||
|  |       location: "Richardson, TX", | ||||||
|  |       website: "https://ethanreece.com/" | ||||||
|  |     ), | ||||||
|  |     skills: ( | ||||||
|  |       ( | ||||||
|  |         title: "DevOps and System Administration", | ||||||
|  |         items: ( | ||||||
|  |           "Linux", | ||||||
|  |           "Git", | ||||||
|  |           "GitHub Actions", | ||||||
|  |           "Docker", | ||||||
|  |           "Guix", | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |       ( | ||||||
|  |         title: "Programming Languages", | ||||||
|  |         items: ( | ||||||
|  |           "JavaScript", | ||||||
|  |           "C#", | ||||||
|  |           "Java", | ||||||
|  |           "C", | ||||||
|  |           "C++", | ||||||
|  |           "Guile", | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |       ( | ||||||
|  |         title: "Layout and Web Development", | ||||||
|  |         items: ( | ||||||
|  |           "HTML", | ||||||
|  |           "CSS", | ||||||
|  |           "React", | ||||||
|  |           "ASP.NET", | ||||||
|  |           "Express.js", | ||||||
|  |           "Astro", | ||||||
|  |           "Typst", | ||||||
|  |         ), | ||||||
|  |       ),  | ||||||
|  |     ), | ||||||
|  |     education: ( | ||||||
|  |       ( | ||||||
|  |         title: "The University of Texas at Dallas", | ||||||
|  |         degree: "Bachelor of Science in Computer Science", | ||||||
|  |         graduation: "May 2026", | ||||||
|  |         gpa: "Current GPA: 3.764", | ||||||
|  |         coursework: ( | ||||||
|  |           "Probability and Statistics for CS", | ||||||
|  |           "Data Structures and Algorithms", | ||||||
|  |           "Software Engineering", | ||||||
|  |           "C/C++ Programming in UNIX", | ||||||
|  |           "Computer Architecture", | ||||||
|  |           "Discrete Mathematics II", | ||||||
|  |         ), | ||||||
|  |         highlights: ( | ||||||
|  |           "Collegium V Honors Program", | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|  |     work_experience: ( | ||||||
|  |       ( | ||||||
|  |         title: "Scrumfish Software", | ||||||
|  |         location: "Nampa, ID", | ||||||
|  |         timeframe: "June – August (2022, 2023)", | ||||||
|  |         role: "Software Engineering Intern", | ||||||
|  |         skills: ( | ||||||
|  |           "C#/ASP.NET", | ||||||
|  |           "JavaScript/React", | ||||||
|  |           "Microsoft SQL Server", | ||||||
|  |           "GitHub", | ||||||
|  |         ), | ||||||
|  |         highlights: ( | ||||||
|  |           "Developed ASP.NET APIs for data management, multifactor authentication, and document conversion.", | ||||||
|  |           "Created a React-based UI for a book critique platform, supporting document viewing, sharing, and annotation.", | ||||||
|  |           "Automated the update of email templates in the database using SQL and PowerShell scripts.", | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |       ( | ||||||
|  |         title: "R-Technics", | ||||||
|  |         location: "Boise, ID", | ||||||
|  |         timeframe: "June – August (2022, 2023)", | ||||||
|  |         role: "Software Engineering Intern", | ||||||
|  |         skills: ( | ||||||
|  |           "Azure", | ||||||
|  |           "Windows Server", | ||||||
|  |           "Docker", | ||||||
|  |           "C#/ASP.NET", | ||||||
|  |         ), | ||||||
|  |         highlights: ( | ||||||
|  |           "Supported server maintenance through update research, implementation, and monitoring.", | ||||||
|  |           "Developed a C# program to fetch song lyrics and metadata from an API, later integrated into the main product.", | ||||||
|  |           "Enhanced a server application with Docker and Linux support; established an Azure DevOps pipeline for build automation.", | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|  |     professional_development: ( | ||||||
|  |       ( | ||||||
|  |         title: "Personal Server Administration", | ||||||
|  |         timeframe: "2020 – Present", | ||||||
|  |         role: "Hobby", | ||||||
|  |         skills: ( | ||||||
|  |           "Linux", | ||||||
|  |           "Docker", | ||||||
|  |           "Guix/Guile", | ||||||
|  |           "Git", | ||||||
|  |           "Proxmox", | ||||||
|  |           "Google Cloud", | ||||||
|  |         ), | ||||||
|  |         highlights: ( | ||||||
|  |           "Manage a physical server using Proxmox, Debian VMs, and Docker for several applications.", | ||||||
|  |           "Migrate new applications to Guix to utilize declarative configuration for reduced state, fine-grained system control, and increased resource efficiency.", | ||||||
|  |           "Implement a VPN via Google Cloud Compute Engine to navigate CGNAT limitations.", | ||||||
|  |           "Host various services including Forgejo, TrueNAS, Nextcloud, and Vaultwarden.", | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |       ( | ||||||
|  |         title: "Cybersecurity Courses", | ||||||
|  |         timeframe: "February 2023 – November 2023", | ||||||
|  |         role: "CodePath CYB101, CYB102", | ||||||
|  |         skills: ( | ||||||
|  |           "Linux", | ||||||
|  |         ), | ||||||
|  |         highlights: ( | ||||||
|  |           "Gained knowledge in cybersecurity tools and defense strategies.", | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|  |   ) | ||||||
|  |    | ||||||
|  |   set document( | ||||||
|  |     title: "Resume", | ||||||
|  |     author: config.identity.name, | ||||||
|  |     keywords: "resume", | ||||||
|  |     date: none, | ||||||
|  |   ) | ||||||
|  |    | ||||||
|  |   resume_page(..config) | ||||||
|  | } | ||||||
							
								
								
									
										373
									
								
								src/resume_page.typ
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										373
									
								
								src/resume_page.typ
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,373 @@ | ||||||
|  | #let resume_page( | ||||||
|  |   identity: ( | ||||||
|  |     name: "", | ||||||
|  |     email: "", | ||||||
|  |     phone: "", | ||||||
|  |     location: "", | ||||||
|  |     website: "", | ||||||
|  |   ), | ||||||
|  |   skills: ( | ||||||
|  |     ( | ||||||
|  |       title: "", | ||||||
|  |       items: (""), | ||||||
|  |     ), | ||||||
|  |   ), | ||||||
|  |   education: ( | ||||||
|  |     ( | ||||||
|  |       title: "", | ||||||
|  |       degree: "", | ||||||
|  |       graduation: "", | ||||||
|  |       gpa: "", | ||||||
|  |       coursework: (""), | ||||||
|  |       highlights: (""), | ||||||
|  |     ), | ||||||
|  |   ), | ||||||
|  |   work_experience: ( | ||||||
|  |     ( | ||||||
|  |       title: "", | ||||||
|  |       location: "", | ||||||
|  |       timeframe: "", | ||||||
|  |       role: "", | ||||||
|  |       skills: (""), | ||||||
|  |       highlights: (""), | ||||||
|  |     ), | ||||||
|  |   ), | ||||||
|  |   professional_development: ( | ||||||
|  |     ( | ||||||
|  |       title: "", | ||||||
|  |       timeframe: "", | ||||||
|  |       role: "", | ||||||
|  |       skills: (""), | ||||||
|  |       highlights: (""), | ||||||
|  |     ), | ||||||
|  |   ), | ||||||
|  | ) = { | ||||||
|  |   let _block( | ||||||
|  |     below: 0em, | ||||||
|  |     width: 100%, | ||||||
|  |     padding: ( | ||||||
|  |       top: 0em, | ||||||
|  |       right: 0em, | ||||||
|  |       bottom: 0em, | ||||||
|  |       left: 0em, | ||||||
|  |     ), | ||||||
|  |     body | ||||||
|  |   ) = block( | ||||||
|  |     below: below, | ||||||
|  |     width: width, | ||||||
|  |     align( | ||||||
|  |       top + left, | ||||||
|  |       pad( | ||||||
|  |         ..padding, | ||||||
|  |         body | ||||||
|  |       ) | ||||||
|  |     ) | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let _text( | ||||||
|  |     font: "Inter", | ||||||
|  |     size: 10pt, | ||||||
|  |     weight: "regular", | ||||||
|  |     block: ( | ||||||
|  |       below: 0em, | ||||||
|  |       width: 100%, | ||||||
|  |       padding: ( | ||||||
|  |         top: 0em, | ||||||
|  |         right: 0em, | ||||||
|  |         bottom: 0em, | ||||||
|  |         left: 0em, | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|  |     body | ||||||
|  |   ) = text( | ||||||
|  |     font: font, | ||||||
|  |     size: size, | ||||||
|  |     weight: weight, | ||||||
|  |     _block( | ||||||
|  |       ..block, | ||||||
|  |       body | ||||||
|  |     ) | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let _heading(title: "") = _text( | ||||||
|  |     size: 13pt, | ||||||
|  |     block: (below: .95em), | ||||||
|  |     heading( | ||||||
|  |       _text( | ||||||
|  |         size: 13pt, | ||||||
|  |         weight: "bold", | ||||||
|  |         title | ||||||
|  |       ) | ||||||
|  |     ) | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let section_base( | ||||||
|  |     title: "", | ||||||
|  |     body | ||||||
|  |   ) = _text( | ||||||
|  |     block: (below: 2.5em), | ||||||
|  |     { | ||||||
|  |       _heading(title: title) | ||||||
|  |       _text( | ||||||
|  |         block: ( | ||||||
|  |           padding: (left: 1em), | ||||||
|  |         ), | ||||||
|  |         body | ||||||
|  |       ) | ||||||
|  |     } | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let section_item( | ||||||
|  |     title: "", | ||||||
|  |     subtitle: "", | ||||||
|  |     role: "", | ||||||
|  |     timeframe: "", | ||||||
|  |     skills: (""), | ||||||
|  |     highlights: (""), | ||||||
|  |   ) = _text( | ||||||
|  |     block: (below: 1.5em), | ||||||
|  |     { | ||||||
|  |       _text( | ||||||
|  |         block: (below: 0.95em), | ||||||
|  |         grid( | ||||||
|  |           columns: (40%, 60%), | ||||||
|  |           rows: 2, | ||||||
|  |           gutter: 0.75em, | ||||||
|  |           align: ( | ||||||
|  |             left, | ||||||
|  |             right, | ||||||
|  |           ), | ||||||
|  |           grid( | ||||||
|  |             columns: 2, | ||||||
|  |             gutter: 1.5em, | ||||||
|  |             align: bottom, | ||||||
|  |             text( | ||||||
|  |               weight: "semibold", | ||||||
|  |               title | ||||||
|  |             ), | ||||||
|  |             text( | ||||||
|  |               size: 9pt, | ||||||
|  |               weight: "extralight", | ||||||
|  |               subtitle | ||||||
|  |             ) | ||||||
|  |           ), | ||||||
|  |           text( | ||||||
|  |             weight: "regular", | ||||||
|  |             timeframe | ||||||
|  |           ), | ||||||
|  |           text( | ||||||
|  |             weight: "light", | ||||||
|  |             size: 9.5pt, | ||||||
|  |             role | ||||||
|  |           ), | ||||||
|  |           text( | ||||||
|  |             weight: "light", | ||||||
|  |             size: 9.5pt, | ||||||
|  |             skills.join(", "), | ||||||
|  |           ), | ||||||
|  |         ) | ||||||
|  |       ) | ||||||
|  |       _text( | ||||||
|  |         block: ( | ||||||
|  |           padding: (left: 2em), | ||||||
|  |         ), | ||||||
|  |         for highlight in highlights { | ||||||
|  |           _text( | ||||||
|  |             block: (below: 1em), | ||||||
|  |             par( | ||||||
|  |               justify: true, | ||||||
|  |               highlight | ||||||
|  |             ) | ||||||
|  |           ) | ||||||
|  |         } | ||||||
|  |       ) | ||||||
|  |     } | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let section( | ||||||
|  |     title: "", | ||||||
|  |     items: ( | ||||||
|  |       ( | ||||||
|  |         title: "", | ||||||
|  |         subtitle: "", | ||||||
|  |         role: "", | ||||||
|  |         timeframe: "", | ||||||
|  |         skills: (""), | ||||||
|  |         highlights: (""), | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|  |   ) = section_base( | ||||||
|  |     title: title, | ||||||
|  |     for item in items { | ||||||
|  |       section_item(..item) | ||||||
|  |     } | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let title_block(title: "") = _text( | ||||||
|  |     size: 28pt, | ||||||
|  |     block: (below: 0.60em), | ||||||
|  |     weight: "extrabold", | ||||||
|  |     align( | ||||||
|  |       center, | ||||||
|  |       title | ||||||
|  |     ) | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let contact_info_block( | ||||||
|  |     email: "", | ||||||
|  |     phone: "", | ||||||
|  |     location: "", | ||||||
|  |     website: "", | ||||||
|  |   ) = _text( | ||||||
|  |     size: 10.5pt, | ||||||
|  |     block: (below: 2.75em), | ||||||
|  |     weight: "medium", | ||||||
|  |     align( | ||||||
|  |       center, | ||||||
|  |       grid( | ||||||
|  |         columns: 4, | ||||||
|  |         rows: 1, | ||||||
|  |         gutter: 4em, | ||||||
|  |         email, | ||||||
|  |         phone, | ||||||
|  |         location, | ||||||
|  |         website, | ||||||
|  |       ) | ||||||
|  |     ) | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let skills_block( | ||||||
|  |     skills: ( | ||||||
|  |       ( | ||||||
|  |         title: "", | ||||||
|  |         items: (""), | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|  |   ) = section_base( | ||||||
|  |     title: "Skills", | ||||||
|  |     _text( | ||||||
|  |       grid( | ||||||
|  |         columns: (33%, 67%), | ||||||
|  |         gutter: 1em, | ||||||
|  |         ..for skill in skills { | ||||||
|  |           ( | ||||||
|  |             _text( | ||||||
|  |               weight: "semibold", | ||||||
|  |               skill.title | ||||||
|  |             ), | ||||||
|  |             skill.items.join(", "), | ||||||
|  |           ) | ||||||
|  |         } | ||||||
|  |       ) | ||||||
|  |     ) | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let education_block( | ||||||
|  |     education: ( | ||||||
|  |       ( | ||||||
|  |         title: "", | ||||||
|  |         degree: "", | ||||||
|  |         graduation: "", | ||||||
|  |         gpa: "", | ||||||
|  |         coursework: (""), | ||||||
|  |         highlights: (""), | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|  |   ) = section( | ||||||
|  |     title: "Education", | ||||||
|  |     items: education.map(school => ( | ||||||
|  |       title: school.title, | ||||||
|  |       role: school.degree, | ||||||
|  |       timeframe: school.graduation, | ||||||
|  |       skills: ( | ||||||
|  |         school.gpa, | ||||||
|  |       ), | ||||||
|  |       highlights: ( | ||||||
|  |         ..school.highlights, | ||||||
|  |         { | ||||||
|  |           _text( | ||||||
|  |             weight: "medium", | ||||||
|  |             block: ( | ||||||
|  |               below: 0.75em, | ||||||
|  |             ), | ||||||
|  |             "Relevant Coursework" | ||||||
|  |           ) | ||||||
|  |           _text( | ||||||
|  |             size: 9.5pt, | ||||||
|  |             block: ( | ||||||
|  |               padding: ( | ||||||
|  |                 left: 2em, | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |             school.coursework.join(", ") | ||||||
|  |           ) | ||||||
|  |         } | ||||||
|  |       ), | ||||||
|  |     )) | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let work_experience_block( | ||||||
|  |     work_experience: ( | ||||||
|  |       ( | ||||||
|  |         title: "", | ||||||
|  |         location: "", | ||||||
|  |         timeframe: "", | ||||||
|  |         role: "", | ||||||
|  |         skills: (""), | ||||||
|  |         highlights: (""), | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|  |   ) = section( | ||||||
|  |     title: "Work Experience", | ||||||
|  |     items: work_experience.map(company => ( | ||||||
|  |       title: company.title, | ||||||
|  |       subtitle: company.location, | ||||||
|  |       timeframe: company.timeframe, | ||||||
|  |       role: company.role, | ||||||
|  |       skills: company.skills, | ||||||
|  |       highlights: company.highlights, | ||||||
|  |     )), | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   let professional_development_block( | ||||||
|  |     professional_development: ( | ||||||
|  |       ( | ||||||
|  |         title: "", | ||||||
|  |         timeframe: "", | ||||||
|  |         role: "", | ||||||
|  |         skills: (""), | ||||||
|  |         highlights: (""), | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|  |   ) = section( | ||||||
|  |     title: "Professional Development", | ||||||
|  |     items: professional_development.map(item => ( | ||||||
|  |       title: item.title, | ||||||
|  |       timeframe: item.timeframe, | ||||||
|  |       role: item.role, | ||||||
|  |       skills: item.skills, | ||||||
|  |       highlights: item.highlights, | ||||||
|  |     )), | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   page( | ||||||
|  |     paper: "us-letter", | ||||||
|  |     margin: ( | ||||||
|  |       x: 0.5in, | ||||||
|  |       y: 0.4in, | ||||||
|  |     ), | ||||||
|  |     { | ||||||
|  |       title_block(title: identity.name) | ||||||
|  |       contact_info_block( | ||||||
|  |         email: identity.email, | ||||||
|  |         phone: identity.phone, | ||||||
|  |         location: identity.location, | ||||||
|  |         website: identity.website, | ||||||
|  |       ) | ||||||
|  |       skills_block(skills: skills) | ||||||
|  |       education_block(education: education) | ||||||
|  |       work_experience_block(work_experience: work_experience) | ||||||
|  |       professional_development_block(professional_development: professional_development) | ||||||
|  |     } | ||||||
|  |   ) | ||||||
|  | } | ||||||
		Reference in a new issue