├── .gitignore ├── letter ├── graphics │ └── bids-logo.png ├── Makefile ├── letterhead.tex ├── letter.md ├── template.tex └── README.md ├── report ├── static │ ├── header.tex │ ├── default.yml │ ├── tufte-template.tex │ └── ieee-with-url.csl ├── bibliography.bib ├── Makefile ├── report.md ├── diagram.svg └── bin │ └── pandocCommentFilter.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /letter/graphics/bids-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BIDS/pandoc-templates/HEAD/letter/graphics/bids-logo.png -------------------------------------------------------------------------------- /report/static/header.tex: -------------------------------------------------------------------------------- 1 | \usepackage{titlesec} 2 | \titleformat*{\subsection}{\large\itshape} 3 | % \bfseries to make bold 4 | % \normalsize is, well, normal size; then there's \large \Large \LARGE \small 5 | % families: \rmfamily \sffamily \ttfamily 6 | 7 | \usepackage{tabularx} 8 | \usepackage{booktabs} 9 | -------------------------------------------------------------------------------- /report/static/default.yml: -------------------------------------------------------------------------------- 1 | --- 2 | #fontfamily: utopia 3 | # See also http://pandoc.org/MANUAL.html#templates (search for fontfamily) 4 | # utopia, bookman, mathpazo (Palatino), arev (Arev Sans), fouriernc, times, libertine, lmodern 5 | documentclass: tufte-handout 6 | fontfamily: mathpazo 7 | mainfont: Palatino 8 | monofont: Menlo 9 | fontsize: 10pt 10 | newtxmathoptions: 11 | - cmintegrals 12 | - cmbraces 13 | linkcolor: RoyalBlue 14 | urlcolor: RoyalBlue 15 | toccolor: RoyalBlue 16 | --- 17 | -------------------------------------------------------------------------------- /report/bibliography.bib: -------------------------------------------------------------------------------- 1 | @article{scikit-image, 2 | title = {scikit-image: image processing in {P}ython}, 3 | author = {van der Walt, {S}t\'efan and {S}ch\"onberger, {J}ohannes {L}. and 4 | {Nunez-Iglesias}, {J}uan and {B}oulogne, {F}ran\c{c}ois and {W}arner, 5 | {J}oshua {D}. and {Y}ager, {N}eil and {G}ouillart, {E}mmanuelle and 6 | {Y}u, {T}ony and the scikit-image contributors}, 7 | year = {2014}, 8 | month = {6}, 9 | keywords = {Image processing, Reproducible research, Education, 10 | Visualization, Open source, Python, Scientific programming}, 11 | volume = {2}, 12 | pages = {e453}, 13 | journal = {PeerJ}, 14 | issn = {2167-8359}, 15 | url = {http://dx.doi.org/10.7717/peerj.453}, 16 | doi = {10.7717/peerj.453} 17 | } 18 | -------------------------------------------------------------------------------- /letter/Makefile: -------------------------------------------------------------------------------- 1 | build_dir := build 2 | excluded := README.md 3 | 4 | sources := $(filter-out $(excluded),$(wildcard *.md)) 5 | letters = $(addprefix $(build_dir)/,$(sources:.md=.pdf)) 6 | 7 | .PHONY: default 8 | default: $(letters) 9 | 10 | $(build_dir)/: 11 | mkdir -p $@ 12 | 13 | $(build_dir)/letterhead.pdf: letterhead.tex | $(build_dir)/ 14 | cp letterhead.tex $(build_dir) 15 | cd $(build_dir) && xelatex $< 16 | 17 | $(letters): $(build_dir)/%.pdf : %.md | $(build_dir)/letterhead.pdf template.tex 18 | # See https://pandoc.org/MANUAL.html#extensions for a list of extensions 19 | pandoc --pdf-engine=xelatex \ 20 | --template template.tex \ 21 | -s -o $@ $< 22 | 23 | # Add the build directory as an order only prerequisite 24 | $(foreach letter,$(letters),$(eval $(letter): | $(dir $(report)))) 25 | 26 | clean: $(build_dir) 27 | rm -rf $(build_dir) 28 | -------------------------------------------------------------------------------- /letter/letterhead.tex: -------------------------------------------------------------------------------- 1 | \documentclass[letterpaper]{minimal} 2 | \usepackage[paperwidth=14in,paperheight=5in,top=15mm,left=35mm,right=50mm]{geometry} 3 | \usepackage{graphicx} 4 | \usepackage{fontspec} 5 | \setmainfont[ 6 | Mapping=tex-text, 7 | ]{TeX Gyre Adventor} 8 | \defaultfontfeatures{Scale=MatchLowercase} 9 | \usepackage{xcolor} 10 | \definecolor{bidsblue}{RGB}{0, 50, 98} 11 | \renewcommand\normalsize{\fontsize{15pt}{20pt}\selectfont} 12 | 13 | \begin{document} 14 | \begin{minipage}{\textwidth} 15 | \begin{minipage}{0.4\textwidth} 16 | \includegraphics[width=76mm]{../graphics/bids-logo.png} 17 | \end{minipage} 18 | \hfill 19 | \begin{minipage}{0.6\textwidth}\raggedleft 20 | \vspace{0.5in} 21 | \textcolor{bidsblue}{ 22 | \noindent Berkeley Institute for Data Science\\ 23 | \textsc{UNIVERSITY OF CALIFORNIA, BERKELEY}\\ 24 | 190 Doe Library\\ 25 | Berkeley, CA 94720\\ 26 | http://bids.berkeley.edu}% 27 | \end{minipage} 28 | \begin{minipage}{\textwidth} 29 | \vspace{7.5mm} 30 | \hspace{2mm}\rule{\textwidth}{0.4pt} 31 | \end{minipage} 32 | \end{minipage} 33 | \end{document} 34 | -------------------------------------------------------------------------------- /letter/letter.md: -------------------------------------------------------------------------------- 1 | --- 2 | subject: Once in a galaxy far far away 3 | author: Ada Twist 4 | endnote: | 5 | \vspace{5mm} 6 | Co-signed: 7 | 8 | Prof. A 9 | 10 | Mr. B 11 | 12 | Director. C 13 | #city: Naumburg 14 | #from: 15 | #- Artillerieregiment, 8. Batt. 16 | #- Nordstraße 15, Naumburg 17 | to: 18 | - Carl Freiherr von Gersdorff 19 | - Stresow-Kaserne I 20 | - Grenadierstraße 13–16 21 | - 13597 Spandau 22 | 23 | # Settings 24 | 25 | # These fonts require texlive-fonts-extra 26 | mainfont: Caladea 27 | altfont: Carlito 28 | 29 | # Alternative fonts: 30 | 31 | #mainfont: TeX Gyre Pagella 32 | #altfont: TeX Gyre Heros 33 | 34 | monofont: Courier 35 | lang: en-US 36 | fontsize: 12pt 37 | geometry: letterpaper, left=25mm, right=25mm, top=50mm, bottom=25mm 38 | letterhead: true 39 | customdate: 2018-11-30 40 | --- 41 | 42 | To whom it may concern, 43 | 44 | This is a letter, and in it I have what I want to say. But I surely 45 | cannot say it before it has been written, and it is thus that I now 46 | find myself with pen in hand, approaching this paper. 47 | 48 | That said, time is no-one's friend, and therefore I must unfortunately 49 | depart before having shared that which I came to say; which, although 50 | undoubtedly of utmost importance, will have to wait for another day. 51 | 52 | Best regards, 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BIDS Pandoc Templates 2 | 3 | You need [Pandoc](https://pandoc.org/installing.html) and LaTeX 4 | installed. If you want to compile SVG diagrams, you'll also need 5 | Inkscape. 6 | 7 | ## Report 8 | 9 | Change into `report` and type `make`. The result is in 10 | `build/report.pdf`. 11 | 12 | Here is [an example build](https://github.com/BIDS/pandoc-report/blob/build/build/report.pdf). 13 | 14 | The report is derived 15 | from [this template](https://github.com/jez/pandoc-starter) which is 16 | [MIT licensed](https://jez.io/MIT-LICENSE.txt). 17 | 18 | ### Adding your own report 19 | 20 | Copy `report.md` to `my_report.md` (or whatever you want to call it). 21 | The `make` command will now also produce your report in 22 | `build/my_report.pdf`. 23 | 24 | ### Vector graphics 25 | 26 | All `.svg` images (Inkscape graphics) gets converted to PNG files in 27 | the `build/` folder. Those images can then be used in the document, 28 | e.g. 29 | 30 | ``` 31 | ![My Image Description](build/my_image.png) 32 | ``` 33 | 34 | ## Letter 35 | 36 | The letter template works very much like the report. Any custom 37 | adjustments can be made to `static/tufte_template.tex`. It is derived 38 | from [this template](https://github.com/mrzool/letter-boilerplate) 39 | which is [MIT licensed](https://opensource.org/licenses/MIT). 40 | -------------------------------------------------------------------------------- /report/Makefile: -------------------------------------------------------------------------------- 1 | build_dir := build 2 | excluded := README.md 3 | sources := $(filter-out $(excluded),$(wildcard *.md)) 4 | reports = $(addprefix $(build_dir)/,$(sources:.md=.pdf)) 5 | vector_images = $(wildcard *.svg) 6 | images := $(addprefix $(build_dir)/,$(vector_images:.svg=.png)) 7 | static := static 8 | bin := bin 9 | metadata := $(static)/default.yml 10 | 11 | # Look up your bibliography style at https://www.zotero.org/styles 12 | # Download the CSL file to the static directory and modify `bibstyle` 13 | # below 14 | bibstyle := ieee-with-url.csl 15 | 16 | .PHONY: default 17 | default: $(reports) 18 | 19 | $(build_dir)/: 20 | mkdir -p $@ 21 | 22 | $(reports): $(build_dir)/%.pdf : %.md | $(images) 23 | # See https://pandoc.org/MANUAL.html#extensions for a list of extensions 24 | # To disable TOC comment out --toc 25 | # To disable Bibliography comment the line containing pandoc-citeproc 26 | pandoc $(metadata) \ 27 | --from markdown+implicit_figures \ 28 | --template $(static)/tufte-template.tex \ 29 | --filter $(bin)/pandocCommentFilter.py \ 30 | --include-in-header $(static)/header.tex \ 31 | --toc \ 32 | --filter pandoc-citeproc --csl $(static)/$(bibstyle) \ 33 | -s -o $@ $< 34 | 35 | $(images): $(build_dir)/%.png : %.svg 36 | -inkscape --export-png=$@ --export-dpi=300 $< 37 | 38 | # Add the build directory as an order only prerequisite 39 | $(foreach report,$(reports),$(eval $(report): | $(dir $(report)))) 40 | $(foreach image,$(images),$(eval $(image): | $(dir $(image)))) 41 | 42 | clean: $(build_dir) 43 | rm -rf $(build_dir) 44 | -------------------------------------------------------------------------------- /report/report.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The Title of My Report 3 | author: "Author One, Author Two, Author Three" 4 | date: Berkeley Institute for Data Science (BIDS) \newline \vspace{-.15cm} University of California, Berkeley \newline October 2018 5 | draft: true 6 | bibliography: bibliography.bib 7 | abstract: | 8 | Any LaTeX can go here; this is the summary of the document. 9 | 10 | --- 11 | 12 | # Some section 13 | 14 | The content of some section. And you can use raw LaTeX too if you 15 | need. You can add **margin notes**.\marginnote{This is a margin note.} 16 | 17 | You can also make footnotes, that appear in the margin[^my_footnote]. 18 | 19 | Sometimes there's something to fix, so [add a fixme note for 20 | that]{.fixme}. Otherwise, a [comment might do]{.comment}. 21 | 22 | From your bibliography, you can cite papers [@scikit-image]. You can 23 | change the citation style 24 | by [downloading another style](https://www.zotero.org/styles?q=ieee) 25 | and then modifying the Makefile to use that style file. 26 | 27 | [^my_footnote]: And this is the text of my footnote. It can have 28 | [links to important pages](https://github.com/bids/fellows/wiki). 29 | 30 | ## And then a subsection {#with-an-anchor-if-you-need-to-refer-to-it} 31 | 32 | In the [subsection](#with-an-anchor-if-you-need-to-refer-to-it) it is 33 | written that... 34 | 35 | Pandoc Markdown supports various forms of tables. Like this one: 36 | 37 | | Table | Header | 38 | |-------|--------| 39 | | 4.00 | 5.00 | 40 | 41 | You should also take a look at the manual 42 | for [Tufte LaTeX](https://ctan.org/pkg/tufte-latex?lang=en), because 43 | you can use raw LaTeX with any of the instructions described within. 44 | 45 | Finally, you can also switch the document format to any class of your 46 | choice, but you will also have to modify the `Makefile` to remove the 47 | Tufte style there. 48 | 49 | # A beautiful diagram 50 | 51 | Here is a beautiful diagram. 52 | 53 | ![](build/diagram.png){ width=30% } 54 | 55 | Which can also be rendered as a captioned figure: 56 | 57 | ![My Beautiful Diagram](build/diagram.png){ width=30% } 58 | 59 | # Some source code 60 | 61 | ```python 62 | def foo(bar): 63 | return bar + 1 64 | ``` 65 | 66 | # Bibliography 67 | 68 | -------------------------------------------------------------------------------- /report/diagram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 25 | 29 | 33 | 34 | 43 | 44 | 66 | 68 | 69 | 71 | image/svg+xml 72 | 74 | 75 | 76 | 77 | 78 | 83 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /letter/template.tex: -------------------------------------------------------------------------------- 1 | %!TEX TS-program = xelatex 2 | %!TEX encoding = UTF-8 Unicode 3 | 4 | \documentclass[$fontsize$,letterpaper]{article} 5 | \usepackage{fontspec} 6 | 7 | % LAYOUT 8 | %-------------------------------- 9 | \usepackage{geometry} 10 | \geometry{$geometry$} 11 | 12 | % No page numbers 13 | \pagenumbering{gobble} 14 | 15 | % Left align 16 | \usepackage[document]{ragged2e} 17 | 18 | % Trim excessive whitespace before lists 19 | \usepackage{enumitem} 20 | \setlist{nolistsep} 21 | 22 | $if(letterhead)$ 23 | \usepackage{wallpaper} 24 | % \ThisULCornerWallPaper{1}{letterhead-front.pdf} % Uncomment to include a different letterhead on the first page 25 | \ThisULCornerWallPaper{1}{build/letterhead.pdf} 26 | $endif$ 27 | 28 | % LANGUAGE 29 | %-------------------------------- 30 | $if(lang)$ 31 | \usepackage{polyglossia} 32 | \setmainlanguage{$lang$} 33 | $endif$ 34 | 35 | % TYPOGRAPHY 36 | %-------------------------------- 37 | \usepackage{xunicode} 38 | \usepackage{xltxtra} 39 | \usepackage[protrusion=true,final]{microtype} 40 | 41 | % converts LaTeX specials (quotes, dashes etc.) to Unicode 42 | \defaultfontfeatures{ 43 | Mapping=tex-text, 44 | Scale=MatchLowercase 45 | } 46 | \setromanfont [Ligatures={Common}, Numbers={OldStyle}, Scale=1.05]{$mainfont$} 47 | \setsansfont[Scale=0.9]{$altfont$} 48 | \setmonofont[Scale=0.8]{$monofont$} 49 | 50 | % Set paragraph break 51 | \setlength{\parskip}{1em} 52 | 53 | % Custom ampersand 54 | \newcommand{\amper}{{\fontspec[Scale=.95]{$mainfont$}\selectfont\itshape\&}} 55 | 56 | $if(mainfont)$ 57 | \setmainfont{$mainfont$} 58 | $endif$ 59 | $if(altfont)$ 60 | \setsansfont{$altfont$} 61 | $endif$ 62 | 63 | % Command required by how Pandoc handles the list conversion 64 | \providecommand{\tightlist}{% 65 | \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} 66 | 67 | % PDF SETUP 68 | %-------------------------------- 69 | \usepackage[xetex, bookmarks, colorlinks, breaklinks]{hyperref} 70 | \hypersetup 71 | { 72 | pdfauthor={$author$}, 73 | pdfsubject={$subject$}, 74 | pdftitle={$subject$}, 75 | colorlinks,breaklinks, 76 | filecolor=black, 77 | urlcolor=[rgb]{0.117,0.682,0.858}, 78 | linkcolor=[rgb]{0.117,0.682,0.858}, 79 | linkcolor=[rgb]{0.117,0.682,0.858}, 80 | citecolor=[rgb]{0.117,0.682,0.858} 81 | } 82 | 83 | % To display custom date in the example 84 | $if(customdate)$ 85 | \usepackage[$lang$]{datetime2} 86 | \DTMsavedate{customdate}{$customdate$} 87 | $endif$ 88 | 89 | % DOCUMENT 90 | %-------------------------------- 91 | \begin{document} 92 | 93 | \begin{minipage}{\textwidth} 94 | \normalsize \sffamily% 95 | \vspace{10mm}% 96 | $for(to)$ 97 | $to$\\ 98 | $endfor$ 99 | \end{minipage} 100 | 101 | \rmfamily 102 | \begin{flushright} 103 | $if(city)$city, $endif$$if(customdate)$\DTMusedate{customdate}$else$\today$endif$ 104 | \end{flushright} 105 | 106 | \vspace{1em} 107 | 108 | $if(subject)$ 109 | \textbf{$subject$} 110 | $endif$ 111 | 112 | \vspace{1em} 113 | 114 | $body$ 115 | 116 | \IfFileExists{graphics/signature.pdf} 117 | { 118 | \includegraphics[height=5.5\baselineskip]{graphics/signature.pdf} \par 119 | } 120 | { 121 | \vspace{2.5\baselineskip} 122 | } 123 | $author$ 124 | 125 | $endnote$ 126 | 127 | \end{document} 128 | -------------------------------------------------------------------------------- /letter/README.md: -------------------------------------------------------------------------------- 1 | Originally from https://github.com/mrzool/letter-boilerplate 2 | 3 | Heavily modified by @stefanv to reproduce the BIDS letterhead. 4 | 5 | # Letter Boilerplate 6 | 7 | A boilerplate to quickly and painlessly generate high-quality letters through LaTeX. 8 | 9 | Why settle for MS Word when you can get the job done using your text editor? 10 | 11 | ![preview](preview.jpg) 12 | 13 | ## Dependencies 14 | 15 | 1. LaTeX with the following extra packages: `fontspec` `geometry` `ragged2e` `enumitem` `xunicode` `xltxtra` `hyperref` `polyglossia` `footmisc` (also, `datetime2` plus its language modules if you want to use a custom date, see below in the settings section) 16 | 2. [Pandoc](http://pandoc.org/), the universal document converter. 17 | 18 | To install LaTeX on Mac OS X, I recommend getting the smaller version BasicTeX from [here](https://tug.org/mactex/morepackages.html) and installing the additional packages with `tlmgr` afterwards. Same goes for Linux: install `texlive-base` with your package manager and add the needed additional packages later. 19 | 20 | To install pandoc on Mac OS X, run `brew install pandoc`. To install it on Linux, refer to the [official docs](http://pandoc.org/installing.html). 21 | 22 | ## Getting started 23 | 24 | 1. Open `letter.md` and fill the YAML frontmatter with your details, your recipient's details, optional subject line, and the desired settings. 25 | 2. Write your letter in markdown below. 26 | 3. Run `make` to compile the PDF. 27 | 28 | If a file named `signature.pdf` is present in the directory, the boilerplate will automatically print it after the letter's body as a final touch. Follow [this method](http://tex.stackexchange.com/a/32940/82423) to import your own signature. 29 | 30 | **Note**: this template needs to be compiled with XeTeX. 31 | 32 | ### Note for Windows users 33 | 34 | Although I didn't test it, you can probably use this on Windows, too. Both [Pandoc](http://pandoc.org/installing.html) and LaTeX can be installed on Windows (I recommend [MiKTeX](http://miktex.org/) for that) and you should be able to run makefiles on Windows through [Cygwin](https://www.cygwin.com/). If that's too much hassle, this command should do the trick in Powershell: 35 | 36 | pandoc letter.md -o output.pdf --template=template.tex --pdf-engine=xelatex 37 | 38 | ## Available settings 39 | 40 | - **`subject`**: The letter's subject (optional) 41 | - **`mainfont`**: Hoefler Text is the default, but every font installed on your system should work out of the box (thanks, XeTeX!) 42 | - **`altfont`**: Used to render the recipient address so that it stands out from the rest of the letter. 43 | - **`fontsize`**: Possible values here are 10pt, 11pt and 12pt. 44 | - **`lang`**: Sets the main language through the `polyglossia` package. This is important for proper hyphenation and date format. 45 | - **`geometry`**: A string that sets the margins through `geometry`. Read [this](https://www.sharelatex.com/learn/Page_size_and_margins) to learn how this package works. 46 | - **`letterhead`**: include custom letterhead in the PDF (see below). 47 | - **`customdate`**: Allows you to specify a custom date in the format YYYY-MM-DD in case you need to pre/postdate your letter. *Caveat*: Requires `datetime2` along with its language module (ex: if `lang` is set to `german` do `tlmgr install datetime2 datetime2-german`) 48 | 49 | ## Custom letterhead 50 | 51 | If you have already designed your own letterhead and want to use it with this template, including it should be easy enough. Set the `letterhead` option to `true` to activate the `wallpaper` package in the template. `wallpaper` will look for a file named `letterhead.pdf` in the project root folder and print it on the PDF before compiling the document. Change the fonts to match the ones in your letterhead, adjust the margins with `geometry` and you should be all set. 52 | 53 | ## Recommended readings 54 | 55 | - [Typesetting Automation](http://mrzool.cc/writing/typesetting-automation/), my article about this project with in-depth instructions and some suggestions for an ideal workflow. 56 | - [The Beauty of LaTeX](http://nitens.org/taraborelli/latex) by Dario Taraborelli 57 | - [Letterhead advices](http://practicaltypography.com/letterhead.html) from Butterick's Practical Typography 58 | - [Multichannel Text Processing](https://ia.net/topics/multichannel-text-processing/) by iA 59 | - [Why Microsoft Word must Die](http://www.antipope.org/charlie/blog-static/2013/10/why-microsoft-word-must-die.html) by Charlie Stross 60 | - [Word Processors: Stupid and Inefficient](http://ricardo.ecn.wfu.edu/~cottrell/wp.html) by Allin Cottrell 61 | - [Proprietary Binary Data Formats: Just Say No!](http://www.podval.org/~sds/data.html) by Sam Steingold 62 | - [Sustainable Authorship in Plain Text using Pandoc and Markdown](http://programminghistorian.org/lessons/sustainable-authorship-in-plain-text-using-pandoc-and-markdown) by Dennis Tenen and Grant Wythoff 63 | 64 | ## Resources 65 | 66 | - Refer to [pandoc's documentation](http://pandoc.org/MANUAL.html#templates) to learn more about how templates work. 67 | - If you're not familiar with the YAML syntax, [here](http://learnxinyminutes.com/docs/yaml/)'s a good overview. 68 | - If you want to edit the template but LaTeX scares you, these [docs](https://www.sharelatex.com/learn/Main_Page) put together by ShareLaTeX cover most of the basics and are surprisingly kind to the beginner. 69 | - Odds are your question already has an answer on [TeX Stack Exchange](https://www.sharelatex.com/learn/Main_Page). Also, pretty friendly crowd in there. 70 | - Need to fax that letter? Check out [Phaxio](https://www.phaxio.com/) and learn how to send your faxes from the command line with a simple API call. 71 | 72 | ## See also 73 | 74 | - [invoice-boilerplate](https://github.com/mrzool/invoice-boilerplate) — Simple automated LaTeX invoicing system 75 | - [cv-boilerplate](https://github.com/mrzool/cv-boilerplate) — Easing the process of building and maintaining a CV using LaTeX 76 | 77 | ## License 78 | 79 | [MIT](https://opensource.org/licenses/MIT) 80 | -------------------------------------------------------------------------------- /report/static/tufte-template.tex: -------------------------------------------------------------------------------- 1 | \documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$babel-lang$,$endif$$if(papersize)$$papersize$paper,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$} 2 | $if(beamerarticle)$ 3 | \usepackage{beamerarticle} % needs to be loaded first 4 | $endif$ 5 | $if(fontfamily)$ 6 | \usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$} 7 | $else$ 8 | \usepackage{lmodern} 9 | $endif$ 10 | $if(linestretch)$ 11 | \usepackage{setspace} 12 | \setstretch{$linestretch$} 13 | $endif$ 14 | \usepackage{amssymb,amsmath} 15 | \usepackage{ifxetex,ifluatex} 16 | \usepackage{fixltx2e} % provides \textsubscript 17 | \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex 18 | \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc} 19 | \usepackage[utf8]{inputenc} 20 | $if(euro)$ 21 | \usepackage{eurosym} 22 | $endif$ 23 | \else % if luatex or xelatex 24 | \ifxetex 25 | \else 26 | \usepackage{fontspec} 27 | \fi 28 | \defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase} 29 | $for(fontfamilies)$ 30 | \newfontfamily{$fontfamilies.name$}[$fontfamilies.options$]{$fontfamilies.font$} 31 | $endfor$ 32 | $if(euro)$ 33 | \newcommand{\euro}{€} 34 | $endif$ 35 | $if(mainfont)$ 36 | \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$} 37 | $endif$ 38 | $if(sansfont)$ 39 | \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$} 40 | $endif$ 41 | $if(monofont)$ 42 | \setmonofont[Mapping=tex-ansi$if(monofontoptions)$,$for(monofontoptions)$$monofontoptions$$sep$,$endfor$$endif$]{$monofont$} 43 | $endif$ 44 | $if(mathfont)$ 45 | \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} 46 | $endif$ 47 | $if(CJKmainfont)$ 48 | \usepackage{xeCJK} 49 | \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} 50 | $endif$ 51 | \fi 52 | % use upquote if available, for straight quotes in verbatim environments 53 | \IfFileExists{upquote.sty}{\usepackage{upquote}}{} 54 | % use microtype if available 55 | \IfFileExists{microtype.sty}{% 56 | \usepackage{microtype} 57 | \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts 58 | }{} 59 | $if(geometry)$ 60 | \usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} 61 | $endif$ 62 | $if(colorlinks)$ 63 | \PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref 64 | $endif$ 65 | \hypersetup{ 66 | $if(title-meta)$ 67 | pdftitle={$title-meta$}, 68 | $endif$ 69 | $if(author-meta)$ 70 | pdfauthor={$author-meta$}, 71 | $endif$ 72 | $if(keywords)$ 73 | pdfkeywords={$for(keywords)$$keywords$$sep$; $endfor$}, 74 | $endif$ 75 | $if(colorlinks)$ 76 | colorlinks=true, 77 | linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$, 78 | citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$, 79 | urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$, 80 | $else$ 81 | pdfborder={0 0 0}, 82 | $endif$ 83 | breaklinks=true} 84 | \urlstyle{same} % don't use monospace font for urls 85 | $if(lang)$ 86 | \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex 87 | \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} 88 | $if(babel-newcommands)$ 89 | $babel-newcommands$ 90 | $endif$ 91 | \else 92 | \usepackage{polyglossia} 93 | \setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$} 94 | $for(polyglossia-otherlangs)$ 95 | \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$} 96 | $endfor$ 97 | \fi 98 | $endif$ 99 | $if(natbib)$ 100 | \usepackage{natbib} 101 | \bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$} 102 | $endif$ 103 | $if(biblatex)$ 104 | \usepackage[$if(biblio-style)$style=$biblio-style$,$endif$$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$]{biblatex} 105 | $for(bibliography)$ 106 | \addbibresource{$bibliography$} 107 | $endfor$ 108 | $endif$ 109 | $if(listings)$ 110 | \usepackage{listings} 111 | $endif$ 112 | $if(lhs)$ 113 | \lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} 114 | $endif$ 115 | $if(highlighting-macros)$ 116 | $highlighting-macros$ 117 | $endif$ 118 | $if(verbatim-in-note)$ 119 | \usepackage{fancyvrb} 120 | \VerbatimFootnotes % allows verbatim text in footnotes 121 | $endif$ 122 | $if(tables)$ 123 | \usepackage{longtable,booktabs} 124 | % Fix footnotes in tables (requires footnote package) 125 | \IfFileExists{footnote.sty}{\usepackage{footnote}\makesavenoteenv{long table}}{} 126 | $endif$ 127 | $if(graphics)$ 128 | \usepackage{graphicx,grffile} 129 | \makeatletter 130 | \def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} 131 | \def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} 132 | \makeatother 133 | % Scale images if necessary, so that they will not overflow the page 134 | % margins by default, and it is still possible to overwrite the defaults 135 | % using explicit options in \includegraphics[width, height, ...]{} 136 | \setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} 137 | $endif$ 138 | $if(links-as-notes)$ 139 | % Make links footnotes instead of hotlinks: 140 | \renewcommand{\href}[2]{#2\footnote{\url{#1}}} 141 | $endif$ 142 | $if(strikeout)$ 143 | \usepackage[normalem]{ulem} 144 | % avoid problems with \sout in headers with hyperref: 145 | \pdfstringdefDisableCommands{\renewcommand{\sout}{}} 146 | $endif$ 147 | $if(indent)$ 148 | $else$ 149 | \IfFileExists{parskip.sty}{% 150 | \usepackage{parskip} 151 | }{% else 152 | \setlength{\parindent}{0pt} 153 | \setlength{\parskip}{6pt plus 2pt minus 1pt} 154 | } 155 | $endif$ 156 | \setlength{\emergencystretch}{3em} % prevent overfull lines 157 | \providecommand{\tightlist}{% 158 | \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} 159 | $if(numbersections)$ 160 | \setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$} 161 | $else$ 162 | \setcounter{secnumdepth}{0} 163 | $endif$ 164 | $if(subparagraph)$ 165 | $else$ 166 | % Redefines (sub)paragraphs to behave more like sections 167 | \ifx\paragraph\undefined\else 168 | \let\oldparagraph\paragraph 169 | \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}} 170 | \fi 171 | \ifx\subparagraph\undefined\else 172 | \let\oldsubparagraph\subparagraph 173 | \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}} 174 | \fi 175 | $endif$ 176 | $if(dir)$ 177 | \ifxetex 178 | % load bidi as late as possible as it modifies e.g. graphicx 179 | $if(latex-dir-rtl)$ 180 | \usepackage[RTLdocument]{bidi} 181 | $else$ 182 | \usepackage{bidi} 183 | $endif$ 184 | \fi 185 | \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex 186 | \TeXXeTstate=1 187 | \newcommand{\RL}[1]{\beginR #1\endR} 188 | \newcommand{\LR}[1]{\beginL #1\endL} 189 | \newenvironment{RTL}{\beginR}{\endR} 190 | \newenvironment{LTR}{\beginL}{\endL} 191 | \fi 192 | $endif$ 193 | 194 | % set default figure placement to htbp 195 | \makeatletter 196 | \def\fps@figure{htbp} 197 | \makeatother 198 | 199 | $for(header-includes)$ 200 | $header-includes$ 201 | $endfor$ 202 | 203 | $if(title)$ 204 | \title{$title$$if(thanks)$\thanks{$thanks$}$endif$} 205 | $endif$ 206 | $if(subtitle)$ 207 | \providecommand{\subtitle}[1]{} 208 | \subtitle{$subtitle$} 209 | $endif$ 210 | $if(author)$ 211 | \author{$for(author)$$author$$sep$ \and $endfor$} 212 | $endif$ 213 | $if(institute)$ 214 | \providecommand{\institute}[1]{} 215 | \institute{$for(institute)$$institute$$sep$ \and $endfor$} 216 | $endif$ 217 | \date{$date$} 218 | 219 | \begin{document} 220 | $if(title)$ 221 | \maketitle 222 | $endif$ 223 | $if(abstract)$ 224 | \begin{abstract} 225 | $abstract$ 226 | \end{abstract} 227 | $endif$ 228 | 229 | $for(include-before)$ 230 | $include-before$ 231 | 232 | $endfor$ 233 | $if(toc)$ 234 | { 235 | $if(colorlinks)$ 236 | \hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$black$endif$} 237 | $endif$ 238 | \setcounter{tocdepth}{$toc-depth$} 239 | \tableofcontents 240 | } 241 | $endif$ 242 | $if(lot)$ 243 | \listoftables 244 | $endif$ 245 | $if(lof)$ 246 | \listoffigures 247 | $endif$ 248 | $body$ 249 | 250 | $if(natbib)$ 251 | $if(bibliography)$ 252 | $if(biblio-title)$ 253 | $if(book-class)$ 254 | \renewcommand\bibname{$biblio-title$} 255 | $else$ 256 | \renewcommand\refname{$biblio-title$} 257 | $endif$ 258 | $endif$ 259 | \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} 260 | 261 | $endif$ 262 | $endif$ 263 | $if(biblatex)$ 264 | \printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ 265 | 266 | $endif$ 267 | $for(include-after)$ 268 | $include-after$ 269 | 270 | $endfor$ 271 | \end{document} 272 | -------------------------------------------------------------------------------- /report/static/ieee-with-url.csl: -------------------------------------------------------------------------------- 1 | 2 | 341 | -------------------------------------------------------------------------------- /report/bin/pandocCommentFilter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | From https://github.com/bwhelm/Pandoc-Comment-Filter 5 | """ 6 | 7 | """ 8 | Pandoc filter to extend pandoc's markdown to incorporate comment features and 9 | other things I find useful. With `draft: true` in the YAML header, comments and 10 | margin notes are displayed in red, and text that is highlighted or flagged with 11 | `fixme` is marked up in the output. With `draft: false` in the YAML header, 12 | comments and margin notes are not displayed at all, and highlightings and 13 | `fixme` mark ups are suppressed (though the text is displayed). Also provided 14 | are markup conventions for cross-references, index entries, and TikZ figures. 15 | 16 | Copyright (C) 2017 Bennett Helm 17 | 18 | This program is free software: you can redistribute it and/or modify 19 | it under the terms of the GNU General Public License as published by 20 | the Free Software Foundation, either version 3 of the License, or 21 | (at your option) any later version. 22 | This program is distributed in the hope that it will be useful, 23 | but WITHOUT ANY WARRANTY; without even the implied warranty of 24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 | GNU General Public License for more details. 26 | You should have received a copy of the GNU General Public License 27 | along with this program. If not, see . 28 | 29 | 30 | # Syntax Extensions 31 | 32 | ## Block-Level Items: 33 | 34 | ``: begin comment block 35 | ``: end comment block 36 | `
`: begin centering 37 | `
`: end centering 38 | ``: begin frame box 39 | ``: end frame box 40 | ``: begin speaker notes (for revealjs) 41 | ``: end speaker notes 42 | 43 | 44 | ## Inline Items: Two Styles 45 | 46 | 1. Tag-style: 47 | - ``: begin commenting 48 | - ``: end commenting 49 | - ``: begin highlighting (note that this requires that 50 | `soul.sty` be loaded in LaTeX) 51 | - ``: end highlighting 52 | - ``: begin FixMe margin note (and highlighting) 53 | - ``: end FixMe margin note (and highlighting) 54 | - ``: begin margin note 55 | - ``: end margin note 56 | - ``: begin small caps style 57 | - ``: end small caps style 58 | 59 | 2. Span-style: 60 | 61 | - `[...]{.comment}`: make `...` be a comment 62 | - `[...]{.highlight}`: make `...` be highlighted (note that this requires 63 | that `soul.sty` be loaded in LaTeX) 64 | - `[...]{.fixme}`: make `...` be a FixMe margin note (with 65 | highlighting) 66 | - `[...]{.margin}`: make `...` be a margin note 67 | - `[...]{.smcaps}`: make `...` be in small caps 68 | 69 | 70 | ## Other Items: 71 | 72 | 1. Tag-style (pre pandoc2): 73 | - `< `: (at begining of line) do not indent paragraph 74 | (after quotation block or lists, e.g.) 75 | - ``: create a label 76 | - ``: create a reference 77 | - ``: create a page reference 78 | - ``: create LaTeX index mark (`\\index{text-for-index}`) 79 | 80 | 2. Span-style (pandoc2 and later): 81 | - `< `: (at begining of line) do not indent paragraph 82 | (after quotation block or lists, e.g.) 83 | - `[LABEL]{.l}`: create a label 84 | - `[LABEL]{.r}`: create a reference 85 | - `[LABEL]{.rp}`: create a page reference 86 | - `[text-for-index]{.i}`: create LaTeX index (`\\index{text-for-index}`) 87 | 88 | 89 | ## Images: Allow for tikZ figures in code blocks. They should have the 90 | following format: 91 | 92 | ~~~ {#tikz caption='My *great* caption' id='fig:id' 93 | tikzlibrary='items,to,go,in,\\usetikzlibrary{}'} 94 | 95 | [LaTeX code] 96 | 97 | ~~~ 98 | 99 | Note that the caption can be formatted text in markdown. 100 | 101 | """ 102 | 103 | 104 | from pandocfilters import json, sys, walk, elt, stringify,\ 105 | RawInline, Para, Plain, Image, Str 106 | from os import path, mkdir, chdir, getcwd 107 | from shutil import copyfile, rmtree 108 | from sys import getfilesystemencoding, stderr 109 | from subprocess import call, Popen, PIPE 110 | from hashlib import sha1 111 | 112 | IMAGE_PATH = path.expanduser('~/tmp/pandoc/Figures') 113 | DEFAULT_FONT = 'fbb' 114 | INLINE_TAG_STACK = [] 115 | BLOCK_COMMENT = False 116 | INLINE_COMMENT = False 117 | INLINE_MARGIN = False 118 | INLINE_HIGHLIGHT = False 119 | INLINE_FONT_COLOR_STACK = ['black'] 120 | USED_BOX = False 121 | DRAFT = False 122 | 123 | COLORS = { 124 | '': 'cyan', 125 | '': 'cyan', 126 | '': 'yellow', 127 | '': 'black', 128 | '': 'red' 129 | } 130 | 131 | # HTML style for margin notes 132 | MARGIN_STYLE = 'max-width:20%; border: 1px solid black;' + \ 133 | 'padding: 1ex; margin: 1ex; float:right; font-size: small;' 134 | 135 | LATEX_TEXT = { 136 | '': '\\color{{{}}}{{}}'.format(COLORS['']), 137 | '': '\\color{black}{}', 138 | '': '\\medskip\\begin{mdframed}', 139 | '': '\\end{mdframed}\\medskip{}', 140 | '': '\\textcolor{{{}}}{{'.format(COLORS['']), 141 | '': '}', 142 | '': '\\hl{', 143 | '': '}', 144 | '': 145 | '\\marginpar{{\\begin{{flushleft}}\\scriptsize{{\\textcolor{{{}}}{{' 146 | .format(COLORS['']), 147 | '': '}}\\end{flushleft}}', 148 | '': '\\marginpar{{\\scriptsize{{\\textcolor{{{}}}' 149 | .format(COLORS['']) + 150 | '{{Fix this!}}}}}}\\textcolor{{{}}}{{' 151 | .format(COLORS['']), 152 | '': '}', 153 | '
': '\\begin{center}', 154 | '
': '\\end{center}', 155 | # Note: treat just like 156 | '': '\\textcolor{{{}}}{{'.format(COLORS['']), 157 | '': '}', 158 | '': '\\textsc{', 159 | '': '}' 160 | } 161 | HTML_TEXT = { 162 | '': '
'.format(COLORS['']), 163 | '': '
', 164 | '': ''.format(COLORS['']), 165 | '': '', 166 | '': '', 167 | '': '', 168 | '': '' 169 | .format(COLORS[''], MARGIN_STYLE), 170 | '': '', 171 | '': 'Fix this!' 172 | .format(COLORS[''], MARGIN_STYLE) 173 | + ''.format(COLORS['']), 174 | '': '', 175 | '
': '
', 176 | '
': '', 177 | '': '
', 178 | '': '
', 179 | # Note: treat just like 180 | '': '
'.format(COLORS['']), 181 | '': '
', 182 | '': '', 183 | '': '' 184 | } 185 | REVEALJS_TEXT = { 186 | '': '
'.format(COLORS['']), 187 | '': '
', 188 | '': ''.format(COLORS['']), 189 | '': '', 190 | '': '', 191 | '': '', 192 | '': '' 193 | .format(COLORS[''], MARGIN_STYLE), 194 | '': '', 195 | '': 'Fix this!' 196 | .format(COLORS[''], MARGIN_STYLE) 197 | + ''.format(COLORS['']), 198 | '': '', 199 | '
': '
', 200 | '
': '', 201 | '': '
', 202 | '': '
', 203 | '': '', 205 | '': '', 206 | '': '' 207 | } 208 | DOCX_TEXT = { 209 | '': '', 210 | '': '', 211 | '': '', 212 | '': '', 213 | '': '', 214 | '': '', 215 | '': '', 216 | '': '', 217 | '': '', 218 | '': '', 219 | '
': '', 220 | '
': '', 221 | '': '', 222 | '': '', 223 | '': '', 224 | '': '', 225 | '': '', 226 | '': '' 227 | } 228 | 229 | 230 | def debug(text): 231 | stderr.write("*****\n" + str(text) + "\n*****\n") 232 | 233 | 234 | def my_sha1(x): 235 | return sha1(x.encode(getfilesystemencoding())).hexdigest() 236 | 237 | 238 | def tikz2image(tikz, filetype, outfile): 239 | from tempfile import mkdtemp 240 | tmpdir = mkdtemp() 241 | olddir = getcwd() 242 | chdir(tmpdir) 243 | f = open('tikz.tex', 'w') 244 | f.write(tikz) 245 | f.close() 246 | call(['pdflatex', 'tikz.tex'], stdout=stderr) 247 | chdir(olddir) 248 | if filetype == '.pdf': 249 | copyfile(path.join(tmpdir, 'tikz.pdf'), outfile + filetype) 250 | else: 251 | call(['convert', '-density', '300', path.join(tmpdir, 'tikz.pdf'), 252 | '-quality', '100', outfile + filetype]) 253 | rmtree(tmpdir) 254 | 255 | 256 | def toFormat(string, fromThis, toThis): 257 | # Process string through pandoc to get formatted JSON string. 258 | p1 = Popen(['echo'] + string.split(), stdout=PIPE) 259 | p2 = Popen(['pandoc', '-f', fromThis, '-t', toThis], stdin=p1.stdout, 260 | stdout=PIPE) 261 | p1.stdout.close() 262 | return p2.communicate()[0].decode('utf-8').strip('\n') 263 | 264 | 265 | def latex(text): 266 | return RawInline('latex', text) 267 | 268 | 269 | def html(text): 270 | return RawInline('html', text) 271 | 272 | 273 | def docx(text): 274 | return RawInline('openxml', text) 275 | 276 | 277 | def handle_comments(key, value, docFormat, meta): 278 | global INLINE_TAG_STACK, BLOCK_COMMENT, INLINE_COMMENT, INLINE_MARGIN,\ 279 | INLINE_HIGHLIGHT, INLINE_FONT_COLOR_STACK, USED_BOX, DRAFT 280 | 281 | # If translating to markdown, leave everything alone. 282 | if docFormat == 'markdown': 283 | return 284 | 285 | # Check to see if we're starting or closing a Block element 286 | if key == 'RawBlock' or (key == 'Para' and len(value) == 1 and 287 | value[0]['t'] == 'Str'): 288 | if key == 'RawBlock': 289 | elementFormat, tag = value 290 | if elementFormat != 'html': 291 | return 292 | tag = tag.lower() 293 | else: 294 | tag = value[0]['c'] 295 | 296 | if not DRAFT: 297 | if BLOCK_COMMENT: # Need to suppress output 298 | if tag == '': 299 | BLOCK_COMMENT = False 300 | return [] 301 | 302 | # Not currently suppressing output ... 303 | 304 | if tag in ['', '', '
', '']: 305 | if tag == '': 306 | BLOCK_COMMENT = True 307 | if not DRAFT: 308 | return [] 309 | INLINE_FONT_COLOR_STACK.append(COLORS[tag]) 310 | elif tag == '': 311 | USED_BOX = True 312 | if docFormat in ['latex', 'beamer']: 313 | return Para([latex(LATEX_TEXT[tag])]) 314 | elif docFormat in ['html', 'html5']: 315 | return Plain([html(HTML_TEXT[tag])]) 316 | elif docFormat == 'revealjs': 317 | return Plain([html(REVEALJS_TEXT[tag])]) 318 | else: 319 | return 320 | elif tag in ['', '', '
', '']: 321 | if INLINE_TAG_STACK: 322 | debug('Need to close all inline elements before closing ' 323 | + 'block elements!\n\n{}\n\nbefore\n\n{}\n\n' 324 | .format(str(INLINE_TAG_STACK), tag)) 325 | exit(1) 326 | if tag == '': 327 | BLOCK_COMMENT = False 328 | if not DRAFT: 329 | return [] 330 | INLINE_FONT_COLOR_STACK.pop() 331 | if docFormat in ['latex', 'beamer']: 332 | return Para([latex(LATEX_TEXT[tag])]) 333 | elif docFormat in ['html', 'html5']: 334 | return Plain([html(HTML_TEXT[tag])]) 335 | elif docFormat == 'revealjs': 336 | return Plain([html(REVEALJS_TEXT[tag])]) 337 | else: 338 | return 339 | # else: 340 | # return # TODO Is this the right thing to do? 341 | 342 | if not DRAFT and BLOCK_COMMENT: 343 | return [] # Need to suppress output 344 | 345 | elif key == 'Span': 346 | [itemID, classes, keyValues], content = value 347 | if "comment" in classes: 348 | if DRAFT: 349 | if docFormat in ['latex', 'beamer']: 350 | newContent = walk(content, handle_comments, docFormat, 351 | meta) 352 | return [latex(LATEX_TEXT[""])] + newContent +\ 353 | [latex(LATEX_TEXT[""])] 354 | elif docFormat in ['html', 'html5']: 355 | newContent = walk(content, handle_comments, docFormat, 356 | meta) 357 | return [html(HTML_TEXT[""])] + newContent +\ 358 | [html(HTML_TEXT[""])] 359 | elif docFormat == 'revealjs': 360 | newContent = walk(content, handle_comments, docFormat, 361 | meta) 362 | return [html(REVEALJS_TEXT[""])] + newContent +\ 363 | [html(REVEALJS_TEXT[""])] 364 | elif docFormat == 'docx': 365 | newContent = walk(content, handle_comments, docFormat, 366 | meta) 367 | return [docx(DOCX_TEXT[""])] + newContent +\ 368 | [docx(DOCX_TEXT[""])] 369 | else: 370 | return content 371 | else: 372 | return [] 373 | elif "margin" in classes: 374 | if DRAFT: 375 | if docFormat in ['latex', 'beamer']: 376 | newContent = walk(content, handle_comments, docFormat, 377 | meta) 378 | return [latex(LATEX_TEXT[""])] + newContent +\ 379 | [latex(LATEX_TEXT[""])] 380 | elif docFormat in ['html', 'html5']: 381 | newContent = walk(content, handle_comments, docFormat, 382 | meta) 383 | return [html(HTML_TEXT[""])] + newContent +\ 384 | [html(HTML_TEXT[""])] 385 | elif docFormat == 'revealjs': 386 | newContent = walk(content, handle_comments, docFormat, 387 | meta) 388 | return [html(REVEALJS_TEXT[""])] + newContent +\ 389 | [html(REVEALJS_TEXT[""])] 390 | else: 391 | # return content 392 | return [] 393 | else: 394 | return [] 395 | elif "fixme" in classes: 396 | if DRAFT: 397 | if docFormat in ['latex', 'beamer']: 398 | newContent = walk(content, handle_comments, docFormat, 399 | meta) 400 | return [latex(LATEX_TEXT[""])] + newContent +\ 401 | [latex(LATEX_TEXT[""])] 402 | elif docFormat in ['html', 'html5']: 403 | newContent = walk(content, handle_comments, docFormat, 404 | meta) 405 | return [html(HTML_TEXT[""])] + newContent +\ 406 | [html(HTML_TEXT[""])] 407 | elif docFormat == 'revealjs': 408 | newContent = walk(content, handle_comments, docFormat, 409 | meta) 410 | return [html(REVEALJS_TEXT[""])] + newContent +\ 411 | [html(REVEALJS_TEXT[""])] 412 | elif docFormat == 'docx': 413 | newContent = walk(content, handle_comments, docFormat, 414 | meta) 415 | return [docx(DOCX_TEXT[""])] + newContent +\ 416 | [docx(DOCX_TEXT[""])] 417 | else: 418 | return content 419 | else: 420 | return content 421 | elif "highlight" in classes: 422 | if DRAFT: 423 | if docFormat in ['latex', 'beamer']: 424 | # Note: Because of limitations of highlighting in LaTeX, 425 | # can't nest any comments inside here: will get LaTeX 426 | # error. 427 | newContent = walk(content, handle_comments, docFormat, 428 | meta) 429 | return [latex(LATEX_TEXT[""])] + newContent +\ 430 | [latex(LATEX_TEXT[""])] 431 | elif docFormat in ['html', 'html5']: 432 | newContent = walk(content, handle_comments, docFormat, 433 | meta) 434 | return [html(HTML_TEXT[""])] + newContent +\ 435 | [html(HTML_TEXT[""])] 436 | elif docFormat == 'revealjs': 437 | newContent = walk(content, handle_comments, docFormat, 438 | meta) 439 | return [html(REVEALJS_TEXT[""])] + newContent +\ 440 | [html(REVEALJS_TEXT[""])] 441 | elif docFormat == 'docx': 442 | newContent = walk(content, handle_comments, docFormat, 443 | meta) 444 | return [docx(DOCX_TEXT[""])] + newContent +\ 445 | [docx(DOCX_TEXT[""])] 446 | else: 447 | return content 448 | else: 449 | return content 450 | elif "smcaps" in classes: 451 | # Always show this---don't worry about draft status! 452 | if docFormat in ['latex', 'beamer']: 453 | newContent = walk(content, handle_comments, docFormat, meta) 454 | return [latex(LATEX_TEXT[""])] + newContent +\ 455 | [latex(LATEX_TEXT[""])] 456 | elif docFormat in ['html', 'html5']: 457 | newContent = walk(content, handle_comments, docFormat, meta) 458 | return [html(HTML_TEXT[""])] + newContent +\ 459 | [html(HTML_TEXT[""])] 460 | elif docFormat == 'revealjs': 461 | newContent = walk(content, handle_comments, docFormat, meta) 462 | return [html(REVEALJS_TEXT[""])] + newContent +\ 463 | [html(REVEALJS_TEXT[""])] 464 | elif docFormat == 'docx': 465 | return docx(DOCX_TEXT[tag]) 466 | else: 467 | # FIXME: I should run this through a filter that capitalizes 468 | # all strings in `content`. 469 | return content 470 | 471 | # Alternate way of marking index entries that's required by pandoc2. 472 | elif "i" in classes: # Index 473 | if docFormat == 'latex': # (This is senseless in beamer.) 474 | return latex(u'\\index{{{}}}'.format(stringify(content))) 475 | else: 476 | return [] 477 | 478 | elif "l" in classes: # Label 479 | if docFormat in ['latex', 'beamer']: 480 | return latex(u'\\label{{{}}}'.format(stringify(content))) 481 | # return latex('\\label{{{}}}'.format(tag[3:-1])) 482 | elif docFormat in ['html', 'html5']: 483 | return html(u''.format(stringify(content))) 484 | # return html(''.format(tag[3:-1])) 485 | else: 486 | return [] 487 | 488 | elif "r" in classes: # Reference 489 | if docFormat in ['latex', 'beamer']: 490 | return latex(u'\\cref{{{}}}'.format(stringify(content))) 491 | # return latex('\\cref{{{}}}'.format(tag[3:-1])) 492 | elif docFormat in ['html', 'html5']: 493 | return html(u'here' 494 | .format(stringify(content))) 495 | # return html('here'.format(tag[3:-1])) 496 | else: 497 | return [] 498 | 499 | elif "rp" in classes: # Page reference 500 | if docFormat in ['latex', 'beamer']: 501 | return latex(u'\\cpageref{{{}}}'.format(stringify(content))) 502 | # return latex('\\cpageref{{{}}}'.format(tag[4:-1])) 503 | elif docFormat in ['html', 'html5']: 504 | return html(u'here' 505 | .format(stringify(content))) 506 | # return html('here'.format(tag[4:-1])) 507 | else: 508 | return [] 509 | 510 | # Then check to see if we're changing INLINE_TAG_STACK... 511 | elif key == 'RawInline': 512 | elementFormat, tag = value 513 | if elementFormat != 'html': 514 | return 515 | 516 | # Check to see if need to suppress output. We do this only for 517 | # `` and `` tags; with `` and `` 518 | # tags, we merely suppress the tag. 519 | if not DRAFT: 520 | if tag == '': 521 | INLINE_COMMENT = True 522 | return [] 523 | elif tag == '': 524 | INLINE_MARGIN = True 525 | return [] 526 | elif INLINE_COMMENT: # Need to suppress output 527 | if tag == '': 528 | INLINE_COMMENT = False 529 | return [] 530 | elif INLINE_MARGIN: # Need to suppress output 531 | if tag == '': 532 | INLINE_MARGIN = False 533 | return [] 534 | elif tag in ['', '', '', 535 | '
']: 536 | return [] # Suppress the tag (but not the subsequent text) 537 | 538 | # Not currently suppressing output.... 539 | 540 | if tag in ['', '', '', '', 541 | '', '', '', '']: 542 | # LaTeX gets treated differently than HTML 543 | if docFormat in ['latex', 'beamer', 'docx']: 544 | preText = '' 545 | postText = '' 546 | # Cannot change COLORS within highlighting in LaTeX (but 547 | # don't do anything when closing the highlight tag!) 548 | if INLINE_HIGHLIGHT and tag != '': 549 | if docFormat in ['latex', 'beamer']: 550 | preText = LATEX_TEXT[''] 551 | postText = LATEX_TEXT[''] 552 | elif docFormat == 'docx': 553 | preText = DOCX_TEXT[''] 554 | postText = DOCX_TEXT[''] 555 | if tag in ['', '', '', 556 | '']: # If any opening tag 557 | if tag == '': 558 | INLINE_COMMENT = True 559 | INLINE_FONT_COLOR_STACK.append(COLORS[tag]) 560 | elif tag == '': 561 | INLINE_FONT_COLOR_STACK.append(COLORS[tag]) 562 | elif tag == '': 563 | INLINE_MARGIN = True 564 | INLINE_FONT_COLOR_STACK.append(COLORS[tag]) 565 | elif tag == '': 566 | INLINE_HIGHLIGHT = True 567 | INLINE_FONT_COLOR_STACK.append( 568 | INLINE_FONT_COLOR_STACK[-1]) 569 | INLINE_TAG_STACK.append(tag) 570 | if docFormat in ['latex', 'beamer']: 571 | return latex(preText + LATEX_TEXT[tag] + postText) 572 | elif docFormat == 'docx': 573 | return docx(preText + DOCX_TEXT[tag] + postText) 574 | elif tag in ['', '', '', 575 | '']: 576 | if tag == '
': 577 | INLINE_COMMENT = False 578 | elif tag == '': 579 | pass 580 | elif tag == '': 581 | INLINE_MARGIN = False 582 | elif tag == '': 583 | INLINE_HIGHLIGHT = False 584 | INLINE_FONT_COLOR_STACK.pop() 585 | previousColor = INLINE_FONT_COLOR_STACK[-1] 586 | currentInlineStatus = INLINE_TAG_STACK.pop() 587 | if currentInlineStatus[1:] == tag[2:]: 588 | # matching opening tag 589 | if docFormat in ['latex', 'beamer']: 590 | return latex('{}{}\\color{{{}}}{{}}{}'.format( 591 | preText, LATEX_TEXT[tag], previousColor, 592 | postText)) 593 | elif docFormat == 'docx': 594 | return docx(preText + DOCX_TEXT[tag] + postText) 595 | else: 596 | debug('Closing tag ({}) does not match opening tag ' 597 | + '({}).\n\n'.format(tag, currentInlineStatus)) 598 | exit(1) 599 | else: # Some docFormat other than LaTeX/beamer 600 | if tag in ['', '', '', 601 | '']: 602 | if tag == '': 603 | INLINE_HIGHLIGHT = True 604 | INLINE_TAG_STACK.append(tag) 605 | else: 606 | if tag == '': 607 | INLINE_HIGHLIGHT = False 608 | INLINE_TAG_STACK.pop() 609 | if docFormat in ['html', 'html5']: 610 | return html(HTML_TEXT[tag]) 611 | elif docFormat == 'revealjs': 612 | return html(REVEALJS_TEXT[tag]) 613 | else: 614 | return [] 615 | 616 | elif tag in ['', '']: 617 | if tag == '': 618 | INLINE_TAG_STACK.append(tag) 619 | else: 620 | INLINE_TAG_STACK.pop() 621 | if docFormat in ['latex', 'beamer']: 622 | return latex(LATEX_TEXT[tag]) 623 | elif docFormat in ['html', 'html5']: 624 | return html(HTML_TEXT[tag]) 625 | elif docFormat == 'revealjs': 626 | return html(REVEALJS_TEXT[tag]) 627 | elif docFormat == 'docx': 628 | return docx(DOCX_TEXT[tag]) 629 | else: 630 | return [] 631 | 632 | elif tag.startswith(''): # Index 633 | if docFormat == 'latex': # (This is senseless in beamer.) 634 | return latex('\\index{{{}}}'.format(tag[3:-1])) 635 | else: 636 | return [] 637 | 638 | elif tag.startswith(''): 639 | # My definition of a label 640 | if docFormat in ['latex', 'beamer']: 641 | return latex('\\label{{{}}}'.format(tag[3:-1])) 642 | elif docFormat in ['html', 'html5']: 643 | return html(''.format(tag[3:-1])) 644 | 645 | elif tag.startswith(''): 646 | # My definition of a reference 647 | if docFormat in ['latex', 'beamer']: 648 | return latex('\\cref{{{}}}'.format(tag[3:-1])) 649 | elif docFormat in ['html', 'html5']: 650 | return html('here'.format(tag[3:-1])) 651 | 652 | elif tag.startswith(''): 653 | # My definition of a page reference 654 | if docFormat in ['latex', 'beamer']: 655 | return latex('\\cpageref{{{}}}'.format(tag[4:-1])) 656 | elif docFormat in ['html', 'html5']: 657 | return html('here'.format(tag[4:-1])) 658 | 659 | elif not DRAFT and (INLINE_COMMENT or INLINE_MARGIN): 660 | # Suppress all output 661 | return [] 662 | 663 | # Check some cases at beginnings of paragraphs 664 | elif key == 'Para': 665 | try: 666 | # If translating to LaTeX, beginning a paragraph with '< ' 667 | # will cause '\noindent{}' to be output first. 668 | if value[0]['t'] == 'Str' and value[0]['c'] == '<' \ 669 | and value[1]['t'] == 'Space': 670 | if docFormat in ['latex', 'beamer']: 671 | return Para([latex('\\noindent{}')] + value[2:]) 672 | elif docFormat in ['html', 'html5']: 673 | return Para([html('
')] + 674 | value[2:] + [html('
')]) 675 | else: 676 | return Para(value[2:]) 677 | 678 | else: 679 | return # Normal paragraph, not affected by this filter 680 | 681 | except: 682 | return # May happen if the paragraph is empty. 683 | 684 | # Check for tikz CodeBlock. If it exists, try typesetting figure 685 | elif key == 'CodeBlock': 686 | (id, classes, attributes), code = value 687 | if 'tikz' in classes or '\\begin{tikzpicture}' in code: 688 | if 'fontfamily' in meta: 689 | font = meta['fontfamily']['c'][0]['c'] 690 | else: 691 | font = DEFAULT_FONT 692 | outfile = path.join(IMAGE_PATH, my_sha1(code + font)) 693 | filetype = '.pdf' if docFormat in ['latex', 'beamer'] else '.png' 694 | sourceFile = outfile + filetype 695 | caption = '' 696 | library = '' 697 | for a, b in attributes: 698 | if a == 'caption': 699 | caption = b 700 | elif a == 'tikzlibrary': 701 | library = b 702 | if not path.isfile(sourceFile): 703 | try: 704 | mkdir(IMAGE_PATH) 705 | debug('Created directory {}\n\n'.format(IMAGE_PATH)) 706 | except OSError: 707 | pass 708 | codeHeader = '\\documentclass{{standalone}}\n' + \ 709 | '\\usepackage{{{}}}\n' + \ 710 | '\\usepackage{{tikz}}\n'.format(font) 711 | if library: 712 | codeHeader += '\\usetikzlibrary{{{}}}\n'.format(library) 713 | codeHeader += '\\begin{document}\n' 714 | codeFooter = '\n\\end{document}\n' 715 | tikz2image(codeHeader + code + codeFooter, filetype, 716 | outfile) 717 | debug('Created image {}\n\n'.format(sourceFile)) 718 | if caption: 719 | # Need to run this through pandoc to get JSON 720 | # representation so that captions can be docFormatted text. 721 | jsonString = toFormat(caption, 'markdown', 'json') 722 | if "blocks" in jsonString: 723 | formattedCaption = eval(jsonString)["blocks"][0]['c'] 724 | else: # old API 725 | formattedCaption = eval(jsonString)[1][0]['c'] 726 | else: 727 | formattedCaption = [Str('')] 728 | return Para([Image((id, classes, attributes), formattedCaption, 729 | [sourceFile, caption])]) 730 | else: # CodeBlock, but not tikZ 731 | return 732 | 733 | else: # Not text this filter modifies.... 734 | return 735 | 736 | 737 | def main(): 738 | # This grabs the output of `pandoc` as json file, retrieves `metadata` to 739 | # check for draft status, and runs the document through `handle_comments`. 740 | # Then adds any needed entries to `metadata` and passes the output back out 741 | # to `pandoc`. This code is modeled after 742 | # . 743 | global DRAFT 744 | document = json.loads(sys.stdin.read()) 745 | if len(sys.argv) > 1: 746 | format = sys.argv[1] 747 | else: 748 | format = '' 749 | 750 | if 'meta' in document: # new API 751 | metadata = document['meta'] 752 | elif document[0]: # old API 753 | metadata = document[0]['unMeta'] 754 | 755 | if 'draft' in metadata: 756 | DRAFT = metadata['draft']['c'] 757 | else: 758 | DRAFT = False 759 | 760 | newDocument = document 761 | newDocument = walk(newDocument, handle_comments, format, metadata) 762 | 763 | # Need to ensure the LaTeX/beamer template knows if `mdframed` package is 764 | # required (when `` has been used). 765 | if (format == 'latex' or format == 'beamer') and USED_BOX: 766 | MetaList = elt('MetaList', 1) 767 | MetaInlines = elt('MetaInlines', 1) 768 | rawinlines = [MetaInlines([RawInline('tex', 769 | '\\RequirePackage{mdframed}')])] 770 | if 'header-includes' in metadata: 771 | headerIncludes = metadata['header-includes'] 772 | if headerIncludes['t'] == 'MetaList': 773 | rawinlines += headerIncludes['c'] 774 | else: # headerIncludes['t'] == 'MetaInlines' 775 | rawinlines += [headerIncludes] 776 | metadata['header-includes'] = MetaList(rawinlines) 777 | newDocument['meta'] = metadata 778 | 779 | json.dump(newDocument, sys.stdout) 780 | 781 | 782 | if __name__ == '__main__': 783 | main() 784 | --------------------------------------------------------------------------------