├── actions ├── entrypoint.sh └── action.yml ├── .gitignore ├── .dockerignore ├── shell.nix ├── .docker └── resume.dockerfile ├── docker-compose.yml ├── ISSUE_TEMPLATE.md ├── pdc-links-target-blank.lua ├── flake.lock ├── .github └── workflows │ ├── main.yml │ └── docker-update.yml ├── LICENSE ├── flake.nix ├── Makefile ├── styles ├── chmduquesne.css └── chmduquesne.tex ├── README.md └── markdown └── resume.md /actions/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | sh -c "cd /home/app/resume && make pdf" 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.swo 3 | *.swp 4 | output/ 5 | result 6 | result-* 7 | .envrc 8 | .direnv 9 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | *.tuc 2 | *.log 3 | *.pdf 4 | *.html 5 | resume.tex 6 | *.swo 7 | *.swp 8 | *.docx 9 | *.rtf 10 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import { } }: 2 | with pkgs; 3 | mkShell { buildInputs = [ pandoc texlive.combined.scheme-context gnumake ]; } 4 | -------------------------------------------------------------------------------- /.docker/resume.dockerfile: -------------------------------------------------------------------------------- 1 | FROM pandoc/latex:2.9 2 | 3 | RUN apk add make texlive 4 | 5 | ENV TEXMF /usr/share/texmf-dist 6 | 7 | COPY actions/entrypoint.sh /entrypoint.sh 8 | -------------------------------------------------------------------------------- /actions/action.yml: -------------------------------------------------------------------------------- 1 | # action.yml 2 | name: 'Texlive Build' 3 | description: 'Build a document using texlive' 4 | runs: 5 | using: 'docker' 6 | image: 'docker://ghcr.io/mszep/pandoc_resume:master' 7 | entrypoint: '/entrypoint.sh' 8 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | 5 | resume-make: 6 | build: 7 | context: . 8 | dockerfile: ./.docker/resume.dockerfile 9 | container_name: resume-make 10 | entrypoint: /entrypoint.sh 11 | image: resume-make 12 | volumes: 13 | - .:/home/app/resume:z 14 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Expected Behavior 2 | 3 | ### Actual Behavior 4 | 5 | ### Steps to reproduce the behavior 6 | 7 | ### Versions 8 | 9 | Pandoc and context versions 10 | 11 | pandoc --version 12 | context --version 13 | 14 | OS information on non-Windows can use one of the following commands 15 | 16 | cat /etc/*-release 17 | lsb_release -a 18 | -------------------------------------------------------------------------------- /pdc-links-target-blank.lua: -------------------------------------------------------------------------------- 1 | -- Add target="_blank" attributes to all http links in a Pandoc document 2 | 3 | local function add_target_blank (link) 4 | if string.match(link.target, '^http') then -- here .target == href attribute 5 | link.attributes.target = '_blank' -- here .target == traget attribute 6 | end 7 | return link 8 | end 9 | 10 | -- remove lines 4 and 6 to add target="_blank" to all links, not just http(s) 11 | 12 | return { 13 | { Link = add_target_blank } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "nixpkgs": { 4 | "locked": { 5 | "lastModified": 1655269044, 6 | "narHash": "sha256-VscxTckDD3wSdXsJxkOrdtDo4h4nVD5GutWQmD2uMlM=", 7 | "owner": "nixos", 8 | "repo": "nixpkgs", 9 | "rev": "81ccb11016c0e333f6158ec6af965a47c37e5055", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "owner": "nixos", 14 | "repo": "nixpkgs", 15 | "type": "github" 16 | } 17 | }, 18 | "root": { 19 | "inputs": { 20 | "nixpkgs": "nixpkgs" 21 | } 22 | } 23 | }, 24 | "root": "root", 25 | "version": 7 26 | } 27 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: build-resume 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the master branch 8 | push: 9 | branches: [ master ] 10 | paths: 11 | - 'markdown/**' 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | jobs: 17 | build-resume: 18 | runs-on: ubuntu-latest 19 | steps: 20 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 21 | - uses: actions/checkout@v2 22 | 23 | - name: Test directory contents 24 | run: 'ls -al' 25 | 26 | - name: Build resume 27 | uses: ./actions 28 | 29 | - name: Upload a Build Artifact 30 | uses: actions/upload-artifact@v2.2.3 31 | with: 32 | # Artifact name 33 | name: Resume PDF # optional, default is artifact 34 | # A file, directory or wildcard pattern that describes what to upload 35 | path: output/*.pdf 36 | 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Mark Szepieniec 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { nixpkgs.url = "github:nixos/nixpkgs"; }; 3 | 4 | outputs = { self, nixpkgs }: 5 | let 6 | supportedSystems = 7 | let 8 | unsupportedSystems = [ 9 | # GHC not supported 10 | "armv5tel-linux" 11 | "armv6l-linux" 12 | "powerpc64le-linux" 13 | "riscv64-linux" 14 | 15 | # "error: attribute 'busybox' missing" when building 16 | # `bootstrap-tools` 17 | "mipsel-linux" 18 | ]; 19 | in nixpkgs.lib.subtractLists unsupportedSystems nixpkgs.lib.systems.flakeExposed; 20 | 21 | perSystem = nixpkgs.lib.genAttrs supportedSystems; 22 | pkgsFor = system: import nixpkgs { inherit system; }; 23 | 24 | buildResumeFor = system: 25 | let pkgs = pkgsFor system; 26 | in pkgs.runCommand "build-resume" { 27 | nativeBuildInputs = with pkgs; [ pandoc texlive.combined.scheme-context ]; 28 | } '' 29 | cd ${self} 30 | make OUT_DIR="$out" 31 | ''; 32 | in { 33 | packages = perSystem (system: 34 | let 35 | resume = buildResumeFor system; 36 | in 37 | { 38 | inherit resume; 39 | default = resume; 40 | }); 41 | 42 | devShells = perSystem (system: { 43 | default = import ./shell.nix { pkgs = pkgsFor system; }; 44 | }); 45 | 46 | devShell = perSystem (system: self.devShells.${system}.default); 47 | 48 | defaultPackage = perSystem (system: self.packages.${system}.default); 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | OUT_DIR=output 2 | IN_DIR=markdown 3 | STYLES_DIR=styles 4 | STYLE=chmduquesne 5 | 6 | all: html pdf docx rtf 7 | 8 | pdf: init 9 | for f in $(IN_DIR)/*.md; do \ 10 | FILE_NAME=`basename $$f | sed 's/.md//g'`; \ 11 | echo $$FILE_NAME.pdf; \ 12 | pandoc --standalone --template $(STYLES_DIR)/$(STYLE).tex \ 13 | --from markdown --to context \ 14 | --variable papersize=A4 \ 15 | --output $(OUT_DIR)/$$FILE_NAME.tex $$f > /dev/null; \ 16 | mtxrun --path=$(OUT_DIR) --result=$$FILE_NAME.pdf --script context $$FILE_NAME.tex > $(OUT_DIR)/context_$$FILE_NAME.log 2>&1; \ 17 | done 18 | 19 | html: init 20 | for f in $(IN_DIR)/*.md; do \ 21 | FILE_NAME=`basename $$f | sed 's/.md//g'`; \ 22 | echo $$FILE_NAME.html; \ 23 | pandoc --standalone --include-in-header $(STYLES_DIR)/$(STYLE).css \ 24 | --lua-filter=pdc-links-target-blank.lua \ 25 | --from markdown --to html \ 26 | --output $(OUT_DIR)/$$FILE_NAME.html $$f \ 27 | --metadata pagetitle=$$FILE_NAME;\ 28 | done 29 | 30 | docx: init 31 | for f in $(IN_DIR)/*.md; do \ 32 | FILE_NAME=`basename $$f | sed 's/.md//g'`; \ 33 | echo $$FILE_NAME.docx; \ 34 | pandoc --standalone $$SMART $$f --output $(OUT_DIR)/$$FILE_NAME.docx; \ 35 | done 36 | 37 | rtf: init 38 | for f in $(IN_DIR)/*.md; do \ 39 | FILE_NAME=`basename $$f | sed 's/.md//g'`; \ 40 | echo $$FILE_NAME.rtf; \ 41 | pandoc --standalone $$SMART $$f --output $(OUT_DIR)/$$FILE_NAME.rtf; \ 42 | done 43 | 44 | init: dir version 45 | 46 | dir: 47 | mkdir -p $(OUT_DIR) 48 | 49 | version: 50 | PANDOC_VERSION=`pandoc --version | head -1 | cut -d' ' -f2 | cut -d'.' -f1`; \ 51 | if [ "$$PANDOC_VERSION" -eq "2" ]; then \ 52 | SMART=-smart; \ 53 | else \ 54 | SMART=--smart; \ 55 | fi \ 56 | 57 | clean: 58 | rm -f $(OUT_DIR)/* 59 | -------------------------------------------------------------------------------- /.github/workflows/docker-update.yml: -------------------------------------------------------------------------------- 1 | # This workflow updates the docker container which has context and 2 | # pandoc installed, and on which the resume documents are built. The 3 | # workflow runs whenever the dockerfile is changed, and updates the 4 | # container image in the Github Packages registry. 5 | 6 | name: Publish Docker Image 7 | 8 | # Controls when the action will run. 9 | on: 10 | # Triggers the workflow on push events but only for the master branch 11 | push: 12 | branches: [ master ] 13 | paths-ignore: 14 | - 'markdown/**' 15 | 16 | # Allows you to run this workflow manually from the Actions tab 17 | workflow_dispatch: 18 | 19 | env: 20 | REGISTRY: ghcr.io 21 | IMAGE_NAME: ${{ github.repository }} 22 | 23 | jobs: 24 | push_to_registry: 25 | name: Push Docker image to GitHub Packages 26 | runs-on: ubuntu-latest 27 | permissions: 28 | packages: write 29 | contents: read 30 | steps: 31 | - name: Check out the repo 32 | uses: actions/checkout@v2 33 | 34 | - name: Log in to the Container registry 35 | uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 36 | with: 37 | registry: ${{ env.REGISTRY }} 38 | username: ${{ github.actor }} 39 | password: ${{ secrets.GITHUB_TOKEN }} 40 | 41 | - name: Extract metadata (tags, labels) for Docker 42 | id: meta 43 | uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 44 | with: 45 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 46 | 47 | - name: Build and Push to GitHub Packages 48 | uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc 49 | with: 50 | context: . 51 | file: .docker/resume.dockerfile 52 | push: true 53 | tags: ${{ steps.meta.outputs.tags }} 54 | labels: ${{ steps.meta.outputs.labels }} 55 | 56 | -------------------------------------------------------------------------------- /styles/chmduquesne.css: -------------------------------------------------------------------------------- 1 | 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The Markdown Resume 2 | =================== 3 | 4 | ### Instructions 5 | 6 | ```bash 7 | git clone https://github.com/mszep/pandoc_resume 8 | cd pandoc_resume 9 | vim markdown/resume.md # insert your own resume info 10 | ``` 11 | 12 | #### Local 13 | 14 | Make everything 15 | 16 | ```bash 17 | make 18 | ``` 19 | 20 | Make specifics 21 | 22 | ```bash 23 | make pdf 24 | make html 25 | ``` 26 | 27 | #### Dockerized 28 | 29 | Make everything 30 | 31 | ```bash 32 | docker-compose up -d 33 | ``` 34 | 35 | ### Requirements 36 | 37 | If not using `docker` then you will need the following dependencies. 38 | 39 | * ConTeXt 0.6x 40 | * pandoc 2.x 41 | * 1.x is deprecated 42 | 43 | Last tested on the above versions and that's not to say the later versions won't work. Please try to use the latest versions when possible. 44 | 45 | #### Debian / Ubuntu 46 | 47 | ```bash 48 | sudo apt install pandoc context 49 | ``` 50 | 51 | #### Fedora 52 | ```bash 53 | sudo dnf install pandoc texlive-collection-context 54 | ``` 55 | 56 | #### Arch 57 | ```bash 58 | sudo pacman -S pandoc texlive 59 | ``` 60 | 61 | #### OSX 62 | ```bash 63 | brew install pandoc 64 | brew install --cask mactex 65 | ``` 66 | 67 | Make sure to add the directory `/Library/TeX/texbin/` to your path or `context` and `mtxrun` will not be found. 68 | 69 | ``` 70 | export PATH=$PATH:/Library/TeX/texbin/ 71 | ``` 72 | 73 | #### Nix 74 | 75 | Make sure to enable flakes, see [this](https://nixos.wiki/wiki/Flakes). 76 | 77 | ```bash 78 | nix build 79 | ``` 80 | 81 | The built resume will end up in `./result`. 82 | 83 | ### Troubleshooting 84 | 85 | #### Get versions 86 | 87 | Check if the dependencies are up to date. 88 | 89 | ``` 90 | context --version 91 | pandoc --version 92 | ``` 93 | 94 | #### Cannot process lua 95 | Currently pandoc 1.x may be within your distro's repos and the latest version should be used. See the 96 | [pandoc releases](https://github.com/jgm/pandoc/releases) for your distro. 97 | 98 | e.g. for Debian / Ubuntu 99 | ``` 100 | wget https://github.com/jgm/pandoc/releases/download/2.2.1/pandoc-2.2.1-1-amd64.deb 101 | sudo dpkg -i pandoc-2.2.1-1-amd64.deb 102 | ``` 103 | 104 | #### Context executable cannot be found 105 | Some users have reported problems where their system does not properly find the ConTeXt 106 | executable, leading to errors like `Cannot find context.lua` or similar. It has been found 107 | that running `mtxrun --generate`, ([suggested on texlive-2011-context-problem]( 108 | https://tex.stackexchange.com/questions/53892/texlive-2011-context-problem)), can fix the 109 | issue. 110 | -------------------------------------------------------------------------------- /styles/chmduquesne.tex: -------------------------------------------------------------------------------- 1 | % Copyright 2013 Christophe-Marie Duquesne 2 | % Copyright 2014 Mark Szepieniec 3 | % 4 | % ConText style for making a resume with pandoc. Inspired by moderncv. 5 | % 6 | % This CSS document is delivered to you under the CC BY-SA 3.0 License. 7 | % https://creativecommons.org/licenses/by-sa/3.0/deed.en_US 8 | 9 | \startmode[*mkii] 10 | \enableregime[utf-8] 11 | \setupcolors[state=start] 12 | \stopmode 13 | $if(mainlang)$ 14 | \mainlanguage[$mainlang$] 15 | $endif$ 16 | 17 | \setupcolor[hex] 18 | \definecolor[titlegrey][h=757575] 19 | \definecolor[sectioncolor][h=397249] 20 | \definecolor[rulecolor][h=9cb770] 21 | 22 | % Enable hyperlinks 23 | \setupinteraction[state=start, color=sectioncolor] 24 | 25 | \setuppapersize [$if(papersize)$$papersize$$else$letter$endif$][$if(papersize)$$papersize$$else$letter$endif$] 26 | \setuplayout [width=middle, height=middle, 27 | backspace=20mm, cutspace=0mm, 28 | topspace=10mm, bottomspace=20mm, 29 | header=0mm, footer=0mm] 30 | 31 | %\setuppagenumbering[location={footer,center}] 32 | 33 | \setupbodyfont[11pt, helvetica] 34 | 35 | \setupwhitespace[medium] 36 | 37 | \setupblackrules[width=31mm, color=rulecolor] 38 | 39 | \setuphead[chapter] [style=\tfd] 40 | \setuphead[section] [style=\tfd\bf, color=titlegrey, align=middle] 41 | \setuphead[subsection] [style=\tfb\bf, color=sectioncolor, align=right, 42 | before={\leavevmode\blackrule\hspace}] 43 | \setuphead[subsubsection][style=\bf] 44 | 45 | $if(number-sections)$ 46 | $else$ 47 | \setuphead[chapter, section, subsection, subsubsection][number=no] 48 | $endif$ 49 | 50 | %\setupdescriptions[width=10mm] 51 | 52 | \definedescription 53 | [description] 54 | [headstyle=bold, style=normal, 55 | location=hanging, width=18mm, distance=14mm, margin=0cm] 56 | 57 | \setupitemize[autointro, packed] % prevent orphan list intro 58 | \setupitemize[indentnext=no] 59 | 60 | \defineitemgroup[enumerate] 61 | \setupenumerate[each][fit][itemalign=left,distance=.5em,style={\feature[+][default:tnum]}] 62 | 63 | \setupfloat[figure][default={here,nonumber}] 64 | \setupfloat[table][default={here,nonumber}] 65 | 66 | \setuptables[textwidth=max, HL=none] 67 | \setupxtable[frame=off,option={stretch,width}] 68 | 69 | \setupthinrules[width=15em] % width of horizontal rules 70 | 71 | \setupdelimitedtext 72 | [blockquote] 73 | [before={\setupalign[middle]}, 74 | indentnext=no, 75 | ] 76 | 77 | $if(toc)$ 78 | \setupcombinedlist[content][list={$placelist$}] 79 | 80 | $endif$ 81 | $for(header-includes)$ 82 | $header-includes$ 83 | $endfor$ 84 | 85 | \starttext 86 | $if(title)$ 87 | \startalignment[center] 88 | \blank[2*big] 89 | {\tfd $title$} 90 | $if(author)$ 91 | \blank[3*medium] 92 | {\tfa $for(author)$$author$$sep$\crlf $endfor$} 93 | $endif$ 94 | $if(date)$ 95 | \blank[2*medium] 96 | {\tfa $date$} 97 | $endif$ 98 | \blank[3*medium] 99 | \stopalignment 100 | $endif$ 101 | $for(include-before)$ 102 | $include-before$ 103 | $endfor$ 104 | $if(toc)$ 105 | \placecontent 106 | $endif$ 107 | 108 | $body$ 109 | 110 | $for(include-after)$ 111 | $include-after$ 112 | $endfor$ 113 | \stoptext 114 | -------------------------------------------------------------------------------- /markdown/resume.md: -------------------------------------------------------------------------------- 1 | Johnny Coder 2 | ============ 3 | 4 | ---- 5 | 6 | > In this style, the resume starts with a blockquote, where 7 | > you can briefly list your specialties, or include a salient 8 | > quote. Ending a line with a backslash forces a line break. 9 | 10 | ---- 11 | 12 | Education 13 | --------- 14 | 15 | 2010-2014 (expected) 16 | : **PhD, Computer Science**; Awesome University (MyTown) 17 | 18 | *Thesis title: Deep Learning Approaches to the Self-Awesomeness 19 | Estimation Problem* 20 | 21 | 2007-2010 22 | : **BSc, Computer Science and Electrical Engineering**; University of 23 | HomeTown (HomeTown) 24 | 25 | *Minor: Awesomeology* 26 | 27 | Experience 28 | ---------- 29 | 30 | **Your Most Recent Work Experience:** 31 | 32 | Short text containing the type of work done, results obtained, 33 | lessons learned and other remarks. Can also include lists and 34 | links: 35 | 36 | * First item 37 | 38 | * Item with [link](http://www.example.com). Links will work both in 39 | the html and pdf versions. 40 | 41 | **That Other Job You Had** 42 | 43 | Also with a short description. 44 | 45 | Technical Experience 46 | -------------------- 47 | 48 | My Cool Side Project 49 | : For items which don't have a clear time ordering, a definition 50 | list can be used to have named items. 51 | 52 | * These items can also contain lists, but you need to mind the 53 | indentation levels in the markdown source. 54 | * Second item. 55 | 56 | Open Source 57 | : List open source contributions here, perhaps placing emphasis on 58 | the project names, for example the **Linux Kernel**, where you 59 | implemented multithreading over a long weekend, or **node.js** 60 | (with [link](http://nodejs.org)) which was actually totally 61 | your idea... 62 | 63 | Programming Languages 64 | : **first-lang:** Here, we have an itemization, where we only want 65 | to add descriptions to the first few items, but still want to 66 | mention some others together at the end. A format that works well 67 | here is a description list where the first few items have their 68 | first word emphasized, and the last item contains the final few 69 | emphasized terms. Notice the reasonably nice page break in the pdf 70 | version, which wouldn't happen if we generated the pdf via html. 71 | 72 | : **second-lang:** Description of your experience with second-lang, 73 | perhaps again including a [link] [ref], this time placing the url 74 | reference elsewhere in the document to reduce clutter (see source 75 | file). 76 | 77 | : **obscure-but-impressive-lang:** We both know this one's pushing 78 | it. 79 | 80 | : Basic knowledge of **C**, **x86 assembly**, **forth**, **Common Lisp** 81 | 82 | [ref]: https://github.com/githubuser/superlongprojectname 83 | 84 | Extra Section, Call it Whatever You Want 85 | ---------------------------------------- 86 | 87 | * Human Languages: 88 | 89 | * English (native speaker) 90 | * ??? 91 | * This is what a nested list looks like. 92 | 93 | * Random tidbit 94 | 95 | * Other sort of impressive-sounding thing you did 96 | 97 | ---- 98 | 99 | > • +00 (0)00 000 0000 • XX years old\ 100 | > address - Mytown, Mycountry 101 | --------------------------------------------------------------------------------