├── source-code ├── project │ ├── build.properties │ └── Dependencies.scala ├── src │ └── main │ │ └── scala │ │ └── de │ │ └── codecentric │ │ └── HelloWorld.scala └── build.sbt ├── snippets ├── Addr ├── snippet-type.snippet ├── build-shebang.snippet ├── extraction.snippet ├── shake-main.snippet ├── travis.snippet ├── graphviz-rule.snippet ├── latexmk-rule.snippet ├── parse-latex.snippet ├── pdf-rule.snippet ├── download-images.snippet ├── Snippet ├── haskell-snippet-rule.snippet ├── haskell-snippet-type.snippet ├── outer-pdf-rule.snippet └── outer-haskell-snippet-rule.snippet ├── ditaa ├── diagram-all.ditaa ├── workflow.ditaa ├── workflow.dhall └── presentations.ditaa ├── font_non_cc.tex ├── static-images └── cc-logo.png ├── images ├── maintain-make.src ├── xkcd-automation.src ├── xkcd-salt.src └── horror.src ├── .gitignore ├── graphviz ├── rules.dot └── rules-big.dot ├── dhall └── example.dhall ├── .idea └── vcs.xml ├── beamerthemecodecentric.sty ├── static-source ├── simple-shell.nix └── long-travis-ci.yml ├── font_cc.tex ├── README.md ├── beamerouterthemecodecentric.sty ├── beamerinnerthemecodecentric.sty ├── .travis.yml ├── shell.nix ├── beamerfontthemecodecentric.sty ├── beamercolorthemecodecentric.sty ├── Build.hs └── slides.tex /source-code/project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.1.1 2 | -------------------------------------------------------------------------------- /snippets/Addr: -------------------------------------------------------------------------------- 1 | constructors < Search : { term : Text} | Start : {} | End : {} > -------------------------------------------------------------------------------- /ditaa/diagram-all.ditaa: -------------------------------------------------------------------------------- 1 | +------+ 2 | | | 3 | | Idea | 4 | | | 5 | +------+ -------------------------------------------------------------------------------- /font_non_cc.tex: -------------------------------------------------------------------------------- 1 | \setmainfont{Nunito} 2 | \setsansfont{Nunito Sans} 3 | \setmonofont{Ubuntu Mono} -------------------------------------------------------------------------------- /static-images/cc-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/markus1189/how-this-presentation/HEAD/static-images/cc-logo.png -------------------------------------------------------------------------------- /images/maintain-make.src: -------------------------------------------------------------------------------- 1 | { 2 | url = "http://bit.ly/maintain-make-jpg", 3 | transformations = ["-resize 1101"] 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | auto/ 2 | /missfont.log 3 | /report.html 4 | /report.json 5 | result/ 6 | /_region_.tex 7 | /cc-font.nix 8 | .shake/ 9 | -------------------------------------------------------------------------------- /images/xkcd-automation.src: -------------------------------------------------------------------------------- 1 | { 2 | url = "https://imgs.xkcd.com/comics/automation.png", 3 | transformations = ([] : List Text) 4 | } 5 | -------------------------------------------------------------------------------- /images/xkcd-salt.src: -------------------------------------------------------------------------------- 1 | { 2 | url = "https://imgs.xkcd.com/comics/the_general_problem.png", 3 | transformations = ([] : List Text) 4 | } 5 | -------------------------------------------------------------------------------- /graphviz/rules.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | "slides.pdf" -> "slides.tex"; 3 | "slides.pdf" -> "font.tex"; 4 | "slides.pdf" -> "theme.tex"; 5 | } -------------------------------------------------------------------------------- /source-code/src/main/scala/de/codecentric/HelloWorld.scala: -------------------------------------------------------------------------------- 1 | package de.codecentric 2 | 3 | object Main extends App { 4 | println("Hello World") 5 | } 6 | -------------------------------------------------------------------------------- /source-code/project/Dependencies.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | 3 | object Dependencies { 4 | lazy val scalaTest = "org.scalatest" %% "scalatest" % "3.0.5" 5 | } 6 | -------------------------------------------------------------------------------- /snippets/snippet-type.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "snippets/Snippet", 3 | snippetStart = (./Addr).Start {=}, 4 | snippetEnd = (./Addr).End {=} 5 | } : ./Snippet -------------------------------------------------------------------------------- /images/horror.src: -------------------------------------------------------------------------------- 1 | { 2 | url = "https://78.media.tumblr.com/8f727e47681d04068b9039699f6ff763/tumblr_o9yb5yQXGX1ugyavxo1_1280.jpg", 3 | transformations = ["-resize 1101"] 4 | } 5 | -------------------------------------------------------------------------------- /dhall/example.dhall: -------------------------------------------------------------------------------- 1 | { a = 2 | 42 3 | , b = 4 | [] : Optional Natural 5 | , c = -- comments are possible 6 | { c1 = "foo" : Text, c2 = "bar", c3 = [ 1, 3, 3, 7 ] } 7 | } 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /snippets/build-shebang.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Start {=}, 4 | snippetEnd = (./Addr).Search { term = "{-# LANGUAGE TypeFamilies #-}"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/extraction.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:extraction"}, 4 | snippetEnd = (./Addr).Search { term = "--end"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/shake-main.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:shake main"}, 4 | snippetEnd = (./Addr).Search { term = "--end"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/travis.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = ".travis.yml", 3 | snippetStart = (./Addr).Search { term = "#snippet:travis yml"}, 4 | snippetEnd = (./Addr).Search { term = "#end" } 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/graphviz-rule.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:graphviz rule"}, 4 | snippetEnd = (./Addr).Search { term = "--end"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/latexmk-rule.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:latexmk rule"}, 4 | snippetEnd = (./Addr).Search { term = "--end"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/parse-latex.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:parse latex"}, 4 | snippetEnd = (./Addr).Search { term = "--end"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/pdf-rule.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:pdf rule"}, 4 | snippetEnd = (./Addr).Search { term = "--end:pdf rule"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/download-images.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:download-images"}, 4 | snippetEnd = (./Addr).Search { term = "--end"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/Snippet: -------------------------------------------------------------------------------- 1 | { snippetFile : 2 | Text 3 | , snippetStart : 4 | < Search : { term : Text } | End : {} | Start : {} > 5 | , snippetEnd : 6 | < Search : { term : Text } | End : {} | Start : {} > 7 | } 8 | -------------------------------------------------------------------------------- /snippets/haskell-snippet-rule.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:hs snippet rule"}, 4 | snippetEnd = (./Addr).Search { term = "--end"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/haskell-snippet-type.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:haskell snippet type"}, 4 | snippetEnd = (./Addr).Search { term = "--end"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /snippets/outer-pdf-rule.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:outer pdf rule"}, 4 | snippetEnd = (./Addr).Search { term = "--end:outer pdf rule"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /beamerthemecodecentric.sty: -------------------------------------------------------------------------------- 1 | \mode 2 | 3 | \useoutertheme[subsection=false]{miniframes} 4 | \useoutertheme{codecentric} 5 | \useinnertheme{codecentric} 6 | \usecolortheme{codecentric} 7 | 8 | \mode 9 | 10 | -------------------------------------------------------------------------------- /snippets/outer-haskell-snippet-rule.snippet: -------------------------------------------------------------------------------- 1 | { 2 | snippetFile = "Build.hs", 3 | snippetStart = (./Addr).Search { term = "--snippet:outer hs snippet rule"}, 4 | snippetEnd = (./Addr).Search { term = "--end:outer hs snippet rule"} 5 | } : ./Snippet -------------------------------------------------------------------------------- /static-source/simple-shell.nix: -------------------------------------------------------------------------------- 1 | with import {}; 2 | 3 | mkShell { 4 | buildInputs = [ 5 | (texlive.combine { 6 | inherit (texlive) 7 | beamer; 8 | }) 9 | pythonPackages.pygments 10 | graphviz 11 | imagemagick 12 | (ghc.withPackages (p: with p; [shake dhall])) 13 | ]; 14 | } 15 | -------------------------------------------------------------------------------- /font_cc.tex: -------------------------------------------------------------------------------- 1 | \setmainfont[ 2 | BoldFont={Panton Bold}, 3 | ItalicFont={Panton Regular Italic}, 4 | BoldItalicFont={Panton Bold Italic} 5 | ]{Panton} 6 | \setsansfont[ 7 | BoldFont={Panton Bold}, 8 | ItalicFont={Panton Regular Italic}, 9 | BoldItalicFont={Panton Bold Italic} 10 | ]{Panton} 11 | \setmonofont{Ubuntu Mono} 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Declarative Presentation Made Easy 2 | 3 | [![Build Status](https://travis-ci.org/markus1189/how-this-presentation.svg?branch=master)](https://travis-ci.org/markus1189/how-this-presentation) 4 | 5 | This presentation uses Travis to build the pdf continually: Find the pdf here: [link](https://github.com/markus1189/how-this-presentation/raw/pdf/result/slides.pdf) 6 | -------------------------------------------------------------------------------- /source-code/build.sbt: -------------------------------------------------------------------------------- 1 | import Dependencies._ 2 | 3 | lazy val root = (project in file(".")). 4 | settings( 5 | inThisBuild(List( 6 | organization := "de.codecentric", 7 | scalaVersion := "2.12.4", 8 | version := "0.1.0" 9 | )), 10 | name := "free-all-the-things", 11 | addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.6"), 12 | scalacOptions ++= Seq("-feature", "-language:higherKinds", "-language:implicitConversions") 13 | ) 14 | -------------------------------------------------------------------------------- /ditaa/workflow.ditaa: -------------------------------------------------------------------------------- 1 | +---------------+ +---------------+ +---------------+ 2 | | | | | | | 3 | | Edit/Modify | Step 1 | Generate | Step 2 | Include the | 4 | | +---------> +---------> | 5 | | Graphviz | | Image | | Image | 6 | | | | | | | 7 | +-------^-------+ +---------------+ +-------+-------+ 8 | | | 9 | | | 10 | +---------------------------------------------------+ -------------------------------------------------------------------------------- /graphviz/rules-big.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | "want" [shape=box]; 3 | 4 | "want" -> "slides.pdf"; 5 | "slides.pdf" -> "slides.tex" [ label = "compile" ]; 6 | "slides.pdf" -> "font.tex"; 7 | "slides.pdf" -> "theme.tex"; 8 | 9 | "slides.tex" -> "snippets/pdf-rule.hs" [ label = "check,format" ]; 10 | "snippets/pdf-rule.hs" -> "snippets/pdf-rule.snippet" [ label = "extract" ]; 11 | 12 | "slides.tex" -> "graphviz/rules.png"; 13 | "graphviz/rules.png" -> "graphviz/rules.dot" [label = "dot" ]; 14 | 15 | "slides.tex" -> "ditaa/flow.png"; 16 | "ditaa/flow.png" -> "ditaa/flow.ditaa" [label = "ditaa"]; 17 | 18 | "slides.tex" -> "images/image.jpg"; 19 | "images/image.jpg" -> "images/image.src" [label = "download"]; 20 | } -------------------------------------------------------------------------------- /ditaa/workflow.dhall: -------------------------------------------------------------------------------- 1 | let template = \(c : Text) -> '' 2 | +---------------+ +---------------+ +---------------+ 3 | | | | | | | 4 | | Edit/Modify | Step 1 | Generate | Step 2 | Include the | 5 | | +---------> ${c} +---------> | 6 | | Graphviz | | Image | | Image | 7 | | | | | | | 8 | +-------^-------+ +---------------+ +-------+-------+ 9 | | | 10 | | | 11 | +---------------------------------------------------+ 12 | '' 13 | in [template "cBLU", template "cRED"] -------------------------------------------------------------------------------- /beamerouterthemecodecentric.sty: -------------------------------------------------------------------------------- 1 | \defbeamertemplate*{footline}{} 2 | { 3 | \leavevmode% 4 | \hbox{% 5 | \begin{beamercolorbox}[wd=.31\paperwidth,ht=2.25ex,dp=1ex,center]{author in head/foot}% 6 | \usebeamerfont{author in head/foot}\insertshortauthor\expandafter\beamer@ifempty\expandafter{\beamer@shortinstitute}{}{~~(\insertshortinstitute)} 7 | \end{beamercolorbox}% 8 | \hfill 9 | \begin{beamercolorbox}[wd=.31\paperwidth,ht=2.25ex,dp=-2ex,center]{date in head/foot}% 10 | LambdaConf 2018 11 | \end{beamercolorbox}% 12 | \hspace{2ex} 13 | \hfill 14 | \begin{beamercolorbox}[wd=.32\paperwidth,ht=2.25ex,dp=1ex,center]{title in head/foot}% 15 | \usebeamerfont{title in head/foot}\insertshorttitle{} 16 | \end{beamercolorbox}% 17 | \begin{beamercolorbox}[wd=.06\paperwidth,ht=2.25ex,dp=1ex,left]{date in head/foot}% 18 | \insertframenumber{}\hspace{2ex} 19 | \end{beamercolorbox} 20 | }% 21 | \vskip0pt% 22 | } 23 | 24 | \setbeamertemplate{navigation symbols}{} 25 | 26 | \mode% 27 | 28 | -------------------------------------------------------------------------------- /ditaa/presentations.ditaa: -------------------------------------------------------------------------------- 1 | +-------------------+ +-------------------+ +-------------------+ 2 | | | | | | | 3 | | Call for Papers | OK | Think about a | OK | Get Accepted | 4 | | cBLU +---->| cBLU +---->| cBLU | 5 | | opens | | good topic | | (yeah) | 6 | | | | | | | 7 | +-------------------+ +-------------------+ +---------+---------+ 8 | | 9 | +---------------------------------------------+ | 10 | | | | 11 | | cPNK | BUT ALSO | 12 | | Actually write the presentation... |<--------------+ 13 | | | 14 | | | 15 | +---------------------------------------------+ -------------------------------------------------------------------------------- /beamerinnerthemecodecentric.sty: -------------------------------------------------------------------------------- 1 | \mode 2 | 3 | \defbeamertemplate*{title page}{} 4 | { 5 | \vfill 6 | \begingroup 7 | \centering 8 | \begin{beamercolorbox}[sep=8pt,center]{title} 9 | \usebeamerfont{title}\inserttitle\text{}\par% 10 | \ifx\insertsubtitle\@empty% 11 | \else% 12 | \vskip0.25em% 13 | {\usebeamerfont{subtitle}\usebeamercolor[fg]{subtitle}\insertsubtitle\par}% 14 | \fi% 15 | \end{beamercolorbox}% 16 | \vskip1em\par 17 | \begin{beamercolorbox}[sep=8pt,center]{author} 18 | \usebeamerfont{author}\insertauthor{} 19 | \end{beamercolorbox} 20 | \begin{beamercolorbox}[sep=8pt,center]{institute} 21 | \usebeamerfont{institute}\insertinstitute{} 22 | \end{beamercolorbox} 23 | % \begin{beamercolorbox}[sep=8pt,center]{date} 24 | % \usebeamerfont{date}\insertdate{} 25 | % \end{beamercolorbox}\vskip0.5em 26 | {\usebeamercolor[fg]{titlegraphic}\inserttitlegraphic\par} 27 | \endgroup 28 | \vfill 29 | \vspace*{-15mm} 30 | } 31 | 32 | \setbeamertemplate{items}[circle] 33 | 34 | \setbeamertemplate{blocks}[rounded] 35 | 36 | \setbeamertemplate{sections/subsections in toc}[default] 37 | 38 | \setbeamertemplate{caption}{\raggedright\insertcaption\par} 39 | 40 | \mode% 41 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | #snippet:travis yml 2 | language: 3 | - nix 4 | 5 | script: 6 | - "./Build.hs" 7 | #end 8 | 9 | after_success: 10 | - test "$TRAVIS_BRANCH" = "master" 11 | - git config --global user.email "travis-ci@travis.org" 12 | - git config --global user.name "Travis CI" 13 | - git checkout -b pdf 14 | - git add -f result/slides.pdf 15 | - git commit -m "$(date --iso-8601) @ $(git rev-list --max-count=1 --abbrev-commit $TRAVIS_BRANCH)" -m "[skip ci]" 16 | - git tag -f -a -m "Compilation on $(date --iso-8601) of commit $(git rev-list --max-count=1 --abbrev-commit $TRAVIS_BRANCH)" "pdf-$TRAVIS_BRANCH-$(git rev-list --max-count=1 --abbrev-commit $TRAVIS_BRANCH)" 17 | - git push --tags --force-with-lease https://markus1189:$GITHUB_API_KEY@github.com/markus1189/how-this-presentation pdf 18 | 19 | env: 20 | secure: "GEkc6/hgFnSLiflHkkRWTFil7CZrai76Ua0QmMfGOJZRbi7FMMXpT59WKiXO6GX5RR0QWNQNiHRrDmmGTI6BQyrM5G+Q7qPKc2tO4XO0MQbRYzuHStfolaQ0/dpQ34htDoIZ9e3DnurUrGsr1XSeMsD/rzCHtj5ZHuaqWv6YL1/DsZB0JCvkG22Plho0sVHNRheb9oj4vnbNsMcqyrZ9I9hqkGG2JT+4NiXUIrD/iN5XgDiSavDypzKNZNnpGjQoIzcFP4haR+75kpBmEX6W60c49s6WTRgAu6/DFp5BuOSoubpq7WGDEg7DI9rqcqDo1V024zAbxbDd/5hfIyv/2IOkoXscxfSYkVx3LKtsECAXr37bDiDkWgUHpQRuAjleqDRrTQQP5xMk6LeE1eFaA9keX7ugFnVHJpztnCad9C5jaSOtSqCXzO9V3XW1rUUnseIVpFzZUsWndDmU3U/oTe5+KDWxLdXrOcLImWKA1KFLlwXaZO5jO1pF+MfKi8oVayUfuygMOixTl/2GZD52AuzYDCaYhmk6GxJ9zgU7/HHwlo5BndM9it9KsHiHc56h+P2tOXkwtixVwhJlq/CmKUed1DjI7BydfaCBsTOjxRsNXZTGqu09u+aoB/KQkrYgh0BlR4pN7QY7Bg/bZ+U5dEAtxZTrJUn6gnz83CfYTyU=" 21 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import {} 2 | , useCodecentricFont ? false 3 | }: with pkgs; 4 | 5 | let 6 | codecentricFont = import ./cc-font.nix { inherit pkgs; }; 7 | #snippet:ghc packages 8 | ghcPackages = ghc.withPackages (p: with p; 9 | [ 10 | bytestring 11 | dhall 12 | hlint 13 | hindent 14 | HaTeX 15 | lens 16 | pandoc 17 | shake 18 | split 19 | text 20 | wreq 21 | ] 22 | ); 23 | #end 24 | latexPackages = texlive.combine { 25 | inherit (texlive) 26 | animate 27 | babel 28 | beamer 29 | chngcntr 30 | cleveref 31 | enumitem 32 | environ 33 | etoolbox 34 | excludeonly 35 | fancyvrb 36 | fvextra 37 | float 38 | framed 39 | ifplatform 40 | lineno 41 | listings 42 | mdframed 43 | media9 44 | microtype 45 | minted 46 | needspace 47 | ocgx2 48 | pgf 49 | scheme-medium 50 | tcolorbox 51 | textpos 52 | todonotes 53 | trimspaces 54 | upquote 55 | xcolor 56 | xstring 57 | ; 58 | }; 59 | #snippet:python packages 60 | pyPackages = with pythonPackages; [ pygments pillow ]; 61 | #end 62 | in 63 | mkShell { 64 | FONTCONFIG_FILE = makeFontsConf { fontDirectories = [ google-fonts ubuntu_font_family ] ++ (if useCodecentricFont then [codecentricFont] else []); }; 65 | 66 | buildInputs = [ 67 | coreutils 68 | dhall-json 69 | ditaa 70 | fontconfig 71 | eject 72 | ghcPackages 73 | graphviz 74 | imagemagick 75 | jq 76 | latexPackages 77 | sbt 78 | scalafmt 79 | scala 80 | unzip 81 | which 82 | ] ++ pyPackages; 83 | 84 | USE_CC_FONT = lib.boolToString useCodecentricFont; 85 | } 86 | -------------------------------------------------------------------------------- /beamerfontthemecodecentric.sty: -------------------------------------------------------------------------------- 1 | % Copyright 2007 by Till Tantau 2 | % Copyright 2012,2015 by Vedran Mileti\'c, Joseph Wright 3 | % 4 | % This file may be distributed and/or modified 5 | % 6 | % 1. under the LaTeX Project Public License and/or 7 | % 2. under the GNU Public License. 8 | % 9 | % See the file doc/licenses/LICENSE for more details. 10 | 11 | \mode 12 | 13 | \setbeamerfont{normal text}{} % ignored currently 14 | \setbeamerfont{alerted text}{} 15 | \setbeamerfont{example text}{} 16 | 17 | \setbeamerfont{structure}{} 18 | \setbeamerfont{tiny structure}{size=\tiny} 19 | 20 | \setbeamerfont{title}{size=\Large,parent=structure} 21 | \setbeamerfont{title in head/foot}{} 22 | \setbeamerfont{title in sidebar}{size=\tiny} 23 | 24 | \setbeamerfont{subtitle}{size=\normalsize,parent=title} 25 | 26 | \setbeamerfont{author}{} 27 | \setbeamerfont{author in head/foot}{} 28 | \setbeamerfont{author in sidebar}{size=\tiny} 29 | 30 | \setbeamerfont{institute}{size=\scriptsize} 31 | \setbeamerfont{institute in head/foot}{} 32 | \setbeamerfont{institute in sidebar}{} 33 | 34 | \setbeamerfont{date}{} 35 | \setbeamerfont{date in head/foot}{} 36 | \setbeamerfont{date in sidebar}{} 37 | 38 | \setbeamerfont{part name}{size=\LARGE} 39 | \setbeamerfont{part title}{size=\LARGE,parent=title} 40 | 41 | \setbeamerfont{section name}{size=\Large} 42 | \setbeamerfont{section title}{size=\Large,parent=title} 43 | 44 | \setbeamerfont{section in toc}{parent=structure} 45 | \setbeamerfont{section in toc shaded}{parent=section in toc} 46 | \setbeamerfont{section in head/foot}{} 47 | \setbeamerfont{section in sidebar}{size=\tiny} 48 | \setbeamerfont{section number projected}{size=\small,parent={section in toc,projected text}} 49 | 50 | \setbeamerfont{subsection name}{size=\large} 51 | \setbeamerfont{subsection title}{size=\large,parent=title} 52 | 53 | \setbeamerfont{subsection in toc}{} 54 | \setbeamerfont{subsection in toc shaded}{parent=subsection in toc} 55 | \setbeamerfont{subsection in head/foot}{} 56 | \setbeamerfont{subsection in sidebar}{} 57 | 58 | \setbeamerfont{subsubsection in toc}{size=\footnotesize} 59 | \setbeamerfont{subsubsection in toc shaded}{parent=subsubsection in toc} 60 | \setbeamerfont{subsubsection in head/foot}{} 61 | \setbeamerfont{subsubsection in sidebar}{} 62 | 63 | \setbeamerfont{headline}{parent={tiny structure}} 64 | \setbeamerfont{footline}{parent={tiny structure}} 65 | 66 | \setbeamerfont{sidebar}{size=\Tiny,parent={tiny structure}} 67 | \setbeamerfont{sidebar left}{parent=sidebar} 68 | \setbeamerfont{sidebar right}{parent=sidebar} 69 | 70 | \setbeamerfont{frametitle}{parent=structure,size=\Large} 71 | \setbeamerfont{framesubtitle}{parent=frametitle,size=\footnotesize} 72 | 73 | \setbeamerfont{caption}{size=\small} 74 | \setbeamerfont{caption name}{parent={structure,caption}} 75 | 76 | \setbeamerfont{button}{size=\tiny} 77 | 78 | \setbeamerfont{block body}{} 79 | \setbeamerfont{block body alerted}{} 80 | \setbeamerfont{block body example}{} 81 | \setbeamerfont{block title}{size=\large,parent={structure,block body}} 82 | \setbeamerfont{block title alerted}{parent={block title,alerted text}} 83 | \setbeamerfont{block title example}{parent={block title,example text}} 84 | 85 | \setbeamerfont{item}{parent=structure} 86 | \setbeamerfont{subitem}{parent=item} 87 | \setbeamerfont{subsubitem}{parent=subitem} 88 | 89 | \setbeamerfont{item projected}{size=\tiny,parent={item,projected text}} 90 | \setbeamerfont{subitem projected}{parent=item projected} 91 | \setbeamerfont{subsubitem projected}{parent=subitem projected} 92 | 93 | \setbeamerfont{itemize item}{parent=item} 94 | \setbeamerfont{itemize subitem}{parent=subitem} 95 | \setbeamerfont{itemize subsubitem}{parent=subsubitem} 96 | 97 | \setbeamerfont{enumerate item}{parent=item} 98 | \setbeamerfont{enumerate subitem}{parent=subitem} 99 | \setbeamerfont{enumerate subsubitem}{parent=subsubitem} 100 | 101 | \setbeamerfont{itemize/enumerate body}{} 102 | \setbeamerfont{itemize/enumerate subbody}{size=\small} 103 | \setbeamerfont{itemize/enumerate subsubbody}{size=\footnotesize} 104 | 105 | 106 | \setbeamerfont{description item}{parent=item} 107 | 108 | \setbeamerfont{projected text}{parent={tiny structure}} 109 | 110 | \setbeamerfont{abstract}{size=\small} 111 | \setbeamerfont{abstract title}{parent={abstract,structure},size=\normalsize} 112 | 113 | \setbeamerfont{verse}{family=\rmfamily,shape=\itshape} 114 | 115 | \setbeamerfont{quotation}{shape=\itshape} 116 | \setbeamerfont{quote}{parent=quotation} 117 | 118 | \setbeamerfont{note page}{size=\small} 119 | \setbeamerfont{note title}{parent=note page} 120 | \setbeamerfont{note date}{size=\footnotesize} 121 | 122 | \mode 123 | 124 | -------------------------------------------------------------------------------- /static-source/long-travis-ci.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | language: haskell 4 | 5 | cache: 6 | directories: 7 | - ~/.stack 8 | 9 | branches: 10 | except: 11 | - pdf 12 | 13 | before_install: 14 | - wget -q -O- http://download.fpcomplete.com/ubuntu/fpco.key | sudo apt-key add - 15 | - echo 'deb http://download.fpcomplete.com/ubuntu/precise stable main' | sudo tee /etc/apt/sources.list.d/fpco.list 16 | - sudo apt-get update 17 | 18 | - sudo apt-get install -qq -y stack 19 | - stack --version 20 | 21 | - sudo apt-get install -qq -y texlive-base texlive-fonts-recommended texlive-latex-extra texlive-latex-recommended texlive-math-extra texlive-fonts-extra python-pygments cm-super cm-super-x11 imagemagick 22 | - latex --version 23 | 24 | - sudo apt-get install -qq -y python-pip 25 | - pip --version 26 | 27 | - wget 'http://downloads.typesafe.com/scala/2.11.7/scala-2.11.7.tgz' && tar xzf scala-2.11.7.tgz && export PATH="$(pwd)/scala-2.11.7/bin:$PATH" 28 | - scala -version 29 | 30 | - sudo apt-get install -qq -y fort77 libblas3gf libblas-doc libblas-dev liblapack3gf liblapack-doc liblapack-dev 31 | - sudo apt-get build-dep -qq -y r-base r-base-dev 32 | 33 | # May result in error during R ./configure 34 | # checking whether mixed C/Fortran code can be run... configure: WARNING: cannot run mixed C/Fortran code 35 | # configure: error: Maybe check LDFLAGS for paths to Fortran libraries? 36 | - sudo mv /usr/lib/libf2c.so /usr/lib/libf2c.so_backup 37 | - sudo ln -s /usr/lib/libf2c.a /usr/lib/libf2c.so 38 | 39 | - wget 'https://cran.r-project.org/src/base/R-3/R-3.1.3.tar.gz' && tar xzf R-3.1.3.tar.gz 40 | - (cd R-3.1.3 && ./configure --with-blas --with-lapack --prefix=/usr/local && make) 41 | - export PATH="$(pwd)/R-3.1.3/bin:$PATH" 42 | - R --version 43 | - R --slave --no-save -f R/install-packages.R 44 | 45 | - sudo pip install --upgrade pygments 46 | - pygmentize -V 47 | 48 | install: 49 | - mkdir -p "$HOME/texmf/tex/latex" 50 | - (cd "$HOME/texmf/tex/latex" && wget -O lineno.zip "http://mirrors.ctan.org/macros/latex/contrib/lineno.zip" && unzip lineno.zip) 51 | - texhash "$HOME/texmf" 52 | - (cd "$HOME/texmf/tex/latex" && wget -O minted.zip "http://mirrors.ctan.org/macros/latex/contrib/minted.zip" && unzip minted.zip && latex -shell-escape -interaction nonstopmode minted.ins) 53 | 54 | # setup $HOME/bin 55 | - mkdir -p "$HOME/bin" 56 | - export PATH="$HOME/bin:$PATH" 57 | 58 | # install latexmk 59 | - (mkdir -p "install-latexmk" && 60 | cd "install-latexmk" && 61 | wget -O latexmk.zip "http://mirrors.ctan.org/support/latexmk.zip" && 62 | unzip latexmk.zip && 63 | cp latexmk/latexmk.pl "$HOME/bin/latexmk" && 64 | chmod +x "$HOME/bin/latexmk") 65 | - latexmk -version 66 | 67 | # install custom design and fonts 68 | - wget -O some-design.zip 'http://some-custom-design_1.0.20140928.zip' 69 | - unzip some-design -d "$HOME/" 70 | - wget -O some-other-design.zip 'http://some-other-custom-design_0.0.20140703.zip' 71 | - unzip some-other-design.zip -d "$HOME/" 72 | - unzip some-fonts.zip -d "$HOME/" 73 | 74 | - (wget -O excludeonly.zip "http://mirrors.ctan.org/macros/latex/contrib/excludeonly.zip" && unzip excludeonly.zip -d "$HOME/texmf/tex/latex") 75 | - (wget -O cleveref.zip "http://mirrors.ctan.org/macros/latex/contrib/cleveref.zip" && unzip cleveref.zip -d "$HOME/texmf/tex/latex") 76 | - (wget -O microtype.zip "http://mirrors.ctan.org/macros/latex/contrib/microtype.zip" && unzip microtype.zip -d "$HOME/texmf/tex/latex/") 77 | 78 | - mkdir -p "$HOME/.texmf-var" 79 | - mkdir -p "$HOME/.texmf-config/updmap.d" 80 | 81 | - mv -v "$HOME/texmf/updmap.d" "$HOME/.texmf-config/" 82 | - cat "$HOME/.texmf-config/updmap.d/20tex-fonts.cfg" 83 | - sed -i -e '/DebPkgProvided/d' "$HOME/.texmf-config/updmap.d/20tex-fonts.cfg" 84 | - texhash "$HOME/texmf" 85 | 86 | - update-updmap || echo update-updmap failed 87 | - updmap || echo updmap failed 88 | 89 | # Diagnosis 90 | - updmap --listmaps 91 | - updmap --listmaps | egrep "^Map[[:blank:]]*5" || echo nop 92 | - kpsewhich --all updmap.cfg 93 | 94 | - stack setup 95 | - stack build hlint 96 | 97 | script: 98 | - stack build 99 | - stack exec thesis 100 | 101 | after_failure: 102 | - ls -1lhA 103 | - cat thesis.log 104 | - cat thesis.blg 105 | - cat presentation/final/final.log 106 | 107 | after_success: 108 | - git config --global user.email "travis-ci@travis.org" 109 | - git config --global user.name "Travis CI" 110 | - git checkout -b pdf 111 | - git add -f thesis.pdf 112 | - git add -f presentation/final/final.pdf 113 | - git commit -m "$(date --iso-8601) @ $(git rev-list --max-count=1 --abbrev-commit $TRAVIS_BRANCH)" -m "[skip ci]" 114 | - git tag -f -a -m "Compilation on $(date --iso-8601) of commit $(git rev-list --max-count=1 --abbrev-commit $TRAVIS_BRANCH)" "pdf-$TRAVIS_BRANCH-$(git rev-list --max-count=1 --abbrev-commit $TRAVIS_BRANCH)" 115 | - git push --tags -f origin pdf 116 | -------------------------------------------------------------------------------- /beamercolorthemecodecentric.sty: -------------------------------------------------------------------------------- 1 | % Copyright 2007 by Till Tantau 2 | % Copyright 2012,2015 by Vedran Mileti\'c, Joseph Wright 3 | % 4 | % This file may be distributed and/or modified 5 | % 6 | % 1. under the LaTeX Project Public License and/or 7 | % 2. under the GNU Public License. 8 | % 9 | % See the file doc/licenses/LICENSE for more details. 10 | 11 | \mode 12 | 13 | % http://cc-style-guide.businesscatalyst.com/web-colors.html 14 | \definecolor{beamer@codeblue}{RGB}{0,174,210} 15 | \definecolor{beamer@centricgreen}{RGB}{66,211,165} 16 | \definecolor{beamer@ccdarkgreen}{RGB}{22,89,76} 17 | \definecolor{beamer@ccdarkblue}{RGB}{0,68,82} 18 | 19 | \setbeamercolor{normal text}{fg=black,bg=white} 20 | \setbeamercolor{alerted text}{fg=red} 21 | \setbeamercolor{example text}{fg=green!50!black} 22 | 23 | \setbeamercolor{structure}{fg=black} 24 | 25 | \setbeamercolor{background canvas}{bg=white!90} 26 | \setbeamercolor{background}{parent=background canvas} 27 | 28 | \setbeamercolor{palette primary}{fg=beamer@codeblue} 29 | \setbeamercolor{palette secondary}{fg=beamer@codeblue} 30 | \setbeamercolor{palette tertiary}{fg=beamer@centricgreen} 31 | \setbeamercolor{palette quaternary}{fg=beamer@centricgreen} 32 | 33 | \setbeamercolor{palette sidebar primary}{use=normal text,fg=normal text.fg} 34 | \setbeamercolor{palette sidebar secondary}{use=structure,fg=structure.fg} 35 | \setbeamercolor{palette sidebar tertiary}{use=normal text,fg=normal text.fg} 36 | \setbeamercolor{palette sidebar quaternary}{use=structure,fg=structure.fg} 37 | 38 | \setbeamercolor{math text}{} 39 | \setbeamercolor{math text inlined}{parent=math text} 40 | \setbeamercolor{math text displayed}{parent=math text} 41 | 42 | \setbeamercolor{normal text in math text}{} 43 | 44 | \setbeamercolor{local structure}{parent=structure} 45 | 46 | \setbeamercolor{titlelike}{parent=structure} 47 | 48 | \setbeamercolor{title}{fg=black} 49 | \setbeamercolor{title in head/foot}{fg=beamer@codeblue, parent=palette quaternary} 50 | \setbeamercolor{title in sidebar}{parent=palette sidebar quaternary} 51 | 52 | \setbeamercolor{subtitle}{parent=title} 53 | 54 | \setbeamercolor{author}{fg=black} 55 | \setbeamercolor{author in head/foot}{parent=palette primary} 56 | \setbeamercolor{author in sidebar}{use=palette sidebar tertiary,fg=palette sidebar tertiary.fg} 57 | 58 | \setbeamercolor{institute}{} 59 | \setbeamercolor{institute in head/foot}{parent=palette tertiary} 60 | \setbeamercolor{institute in sidebar}{use=palette sidebar tertiary,fg=palette sidebar tertiary.fg} 61 | 62 | \setbeamercolor{date}{fg=black} 63 | \setbeamercolor{date in head/foot}{parent=palette secondary} 64 | \setbeamercolor{date in sidebar}{fg=black, use=palette sidebar tertiary,fg=palette sidebar tertiary.fg} 65 | 66 | \setbeamercolor{titlegraphic}{} 67 | 68 | \setbeamercolor{part name}{} 69 | \setbeamercolor{part title}{parent=titlelike} 70 | 71 | \setbeamercolor{section name}{} 72 | \setbeamercolor{section title}{parent=titlelike} 73 | 74 | \setbeamercolor{section in toc}{parent=structure} 75 | \setbeamercolor{section in toc shaded}{parent=section in toc} 76 | \setbeamercolor{section in head/foot}{parent=palette tertiary} 77 | \setbeamercolor{section in sidebar}{parent=palette sidebar secondary} 78 | \setbeamercolor{section in sidebar shaded}{use=section in sidebar,fg=section in sidebar.fg!40!bg} 79 | \setbeamercolor{section number projected}{parent=item projected} 80 | 81 | \setbeamercolor{subsection name}{} 82 | \setbeamercolor{subsection title}{parent=titlelike} 83 | 84 | \setbeamercolor{subsection in toc}{} 85 | \setbeamercolor{subsection in toc shaded}{parent=subsection in toc} 86 | \setbeamercolor{subsection in head/foot}{parent=palette secondary} 87 | \setbeamercolor{subsection in sidebar}{parent=palette sidebar primary} 88 | \setbeamercolor{subsection in sidebar shaded}{use=subsection in sidebar,fg=subsection in sidebar.fg!40!bg} 89 | \setbeamercolor{subsection number projected}{parent={subitem projected}} 90 | 91 | \setbeamercolor{subsubsection in toc}{parent=subsection in toc} 92 | \setbeamercolor{subsubsection in toc shaded}{parent=subsubsection in toc} 93 | \setbeamercolor{subsubsection in head/foot}{parent=subsection in head/foot} 94 | \setbeamercolor{subsubsection in sidebar}{parent=subsection in sidebar} 95 | \setbeamercolor{subsubsection in sidebar shaded}{parent=subsection in sidebar shaded} 96 | \setbeamercolor{subsubsection number projected}{parent=subsubitem projected} 97 | 98 | \setbeamercolor{headline}{} 99 | \setbeamercolor{footline}{} 100 | 101 | \setbeamercolor{sidebar}{} 102 | \setbeamercolor{sidebar left}{parent=sidebar} 103 | \setbeamercolor{sidebar right}{parent=sidebar} 104 | 105 | \setbeamercolor{logo}{parent=palette secondary} 106 | 107 | \setbeamercolor{frametitle}{parent=titlelike} 108 | \setbeamercolor{framesubtitle}{parent=frametitle} 109 | 110 | \setbeamercolor{frametitle right}{parent=frametitle} 111 | 112 | \setbeamercolor{caption}{} 113 | \setbeamercolor{caption name}{parent=structure} 114 | 115 | \setbeamercolor{button}{use=local structure,bg=local structure.fg!50!bg,fg=white} 116 | \setbeamercolor{button border}{use=button,fg=button.bg} 117 | \setbeamercolor{navigation symbols}{use=structure,fg=structure.fg!40!bg} 118 | \setbeamercolor{navigation symbols dimmed}{use=structure,fg=structure.fg!20!bg} 119 | \setbeamercolor{mini frame}{parent=section in head/foot} 120 | 121 | \setbeamercolor{block body}{fg=beamer@centricgreen} 122 | \setbeamercolor{block body alerted}{fg=red!60} 123 | \setbeamercolor{block body example}{} 124 | \setbeamercolor{block title}{parent=structure} 125 | \setbeamercolor{block title alerted}{parent=alerted text} 126 | \setbeamercolor{block title example}{parent=example text} 127 | 128 | \setbeamercolor{item}{parent=local structure} 129 | \setbeamercolor{subitem}{parent=item} 130 | \setbeamercolor{subsubitem}{parent=subitem} 131 | 132 | \setbeamercolor{item projected}{parent=item,use=item,fg=white,bg=item.fg} 133 | \setbeamercolor{subitem projected}{parent=item projected} 134 | \setbeamercolor{subsubitem projected}{parent=subitem projected} 135 | 136 | \setbeamercolor{enumerate item}{parent=item} 137 | \setbeamercolor{enumerate subitem}{parent=subitem} 138 | \setbeamercolor{enumerate subsubitem}{parent=subsubitem} 139 | 140 | \setbeamercolor{itemize item}{fg=beamer@codeblue} 141 | \setbeamercolor{itemize subitem}{parent=subitem} 142 | \setbeamercolor{itemize subsubitem}{parent=subsubitem} 143 | 144 | \setbeamercolor{itemize/enumerate body}{} 145 | \setbeamercolor{itemize/enumerate subbody}{} 146 | \setbeamercolor{itemize/enumerate subsubbody}{} 147 | 148 | \setbeamercolor{description item}{parent=item} 149 | 150 | \setbeamercolor{bibliography item}{parent=item} 151 | 152 | \setbeamercolor{bibliography entry author}{use=structure,fg=structure.fg} 153 | \setbeamercolor{bibliography entry title}{use=normal text,fg=normal text.fg} 154 | \setbeamercolor{bibliography entry location}{use=structure,fg=structure.fg!65!bg} 155 | \setbeamercolor{bibliography entry note}{use=structure,fg=structure.fg!65!bg} 156 | 157 | \setbeamercolor{separation line}{} 158 | 159 | \setbeamercolor{upper separation line head}{parent=separation line} 160 | \setbeamercolor{middle separation line head}{parent=separation line} 161 | \setbeamercolor{lower separation line head}{parent=separation line} 162 | 163 | \setbeamercolor{upper separation line foot}{parent=separation line} 164 | \setbeamercolor{middle separation line foot}{parent=separation line} 165 | \setbeamercolor{lower separation line foot}{parent=separation line} 166 | 167 | \setbeamercolor{abstract}{} 168 | \setbeamercolor{abstract title}{parent=structure} 169 | 170 | \setbeamercolor{verse}{} 171 | 172 | \setbeamercolor{quotation}{} 173 | \setbeamercolor{quote}{parent=quotation} 174 | 175 | \setbeamercolor{page number in head/foot}{fg=fg!50!bg} 176 | 177 | \setbeamercolor{qed symbol}{parent=structure} 178 | 179 | \setbeamercolor{note page}{bg=white!90!black, fg=black} 180 | \setbeamercolor{note title}{bg=white!80!black, fg=black} 181 | \setbeamercolor{note date}{parent=note title} 182 | 183 | \mode 184 | 185 | -------------------------------------------------------------------------------- /Build.hs: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell shell.nix -i "runhaskell --ghc-arg=-threaded --ghc-arg=-Wall" 3 | #! nix-shell --pure 4 | {-# LANGUAGE TypeFamilies #-} 5 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 6 | {-# LANGUAGE DeriveGeneric #-} 7 | {-# LANGUAGE ViewPatterns #-} 8 | 9 | module Main where 10 | 11 | import Control.Lens.Operators ((^.)) 12 | import Control.Monad (void) 13 | import Control.Monad.IO.Class (MonadIO) 14 | import qualified Data.ByteString.Lazy as BL 15 | import Data.Foldable (for_) 16 | import Data.List (isPrefixOf) 17 | import Data.Maybe (mapMaybe) 18 | import Data.Monoid ((<>)) 19 | import qualified Data.Text as T 20 | import qualified Data.Text as TS 21 | import qualified Data.Text.Lazy as TL 22 | import Development.Shake 23 | import Development.Shake.Classes 24 | import Development.Shake.FilePath 25 | import qualified Dhall as D 26 | import qualified Network.Wreq as Wreq 27 | import System.Directory (createDirectoryIfMissing, copyFile) 28 | import qualified System.IO as IO 29 | import Text.LaTeX 30 | import Text.LaTeX.Base.Parser 31 | import Text.LaTeX.Base.Syntax 32 | 33 | cmdOpts :: [CmdOption] 34 | cmdOpts = [WithStdout True, EchoStdout False, EchoStderr False, Stdin ""] 35 | 36 | data Addr = Start | Search { term :: Text} | End deriving (Show, D.Generic) 37 | instance D.Interpret Addr 38 | 39 | data ImageSrc = ImageSrc { url :: Text, transformations :: [Text] } deriving (Show, D.Generic) 40 | instance D.Interpret ImageSrc 41 | 42 | --snippet:haskell snippet type 43 | data SnippetSrc = SnippetSrc { snippetFile :: Text, snippetStart :: Addr, snippetEnd :: Addr } deriving (Show, D.Generic) 44 | instance D.Interpret SnippetSrc 45 | --end 46 | 47 | newtype ScalaOptions = ScalaOptions () deriving (Show,Typeable,Eq,Hashable,Binary,NFData) 48 | type instance RuleResult ScalaOptions = [String] 49 | 50 | newtype ScalafmtOptions = ScalafmtOptions () deriving (Show,Typeable,Eq,Hashable,Binary,NFData) 51 | type instance RuleResult ScalafmtOptions = [String] 52 | 53 | newtype HindentOptions = HindentOptions () deriving (Show,Typeable,Eq,Hashable,Binary,NFData) 54 | type instance RuleResult HindentOptions = [String] 55 | 56 | newtype DitaaOptions = DitaaOptions () deriving (Show,Typeable,Eq,Hashable,Binary,NFData) 57 | type instance RuleResult DitaaOptions = [String] 58 | 59 | newtype GraphvizOptions = GraphvizOptions () deriving (Show,Typeable,Eq,Hashable,Binary,NFData) 60 | type instance RuleResult GraphvizOptions = [String] 61 | 62 | --snippet:shake main 63 | theMain :: IO () 64 | theMain = shakeArgs shakeOptions (want [buildDir "slides.pdf"]) 65 | --end 66 | 67 | main :: IO () 68 | main = runShakeBuild 69 | 70 | buildDir :: FilePath 71 | buildDir = "result" 72 | 73 | myShakeOptions :: ShakeOptions 74 | myShakeOptions = shakeOptions { shakeLint = Just LintBasic 75 | , shakeReport = ["report.html", "report.json"] 76 | , shakeThreads = 0 77 | , shakeColor = True 78 | } 79 | 80 | runShakeBuild :: IO () 81 | runShakeBuild = shakeArgs myShakeOptions $ do 82 | downloadResource <- addResource 83 | addOracles 84 | sbtCompile <- addProjectCompiler 85 | wantTargets 86 | phonyCommands 87 | rules sbtCompile downloadResource 88 | 89 | wantTargets :: Rules () 90 | wantTargets = do 91 | want [buildDir "slides.pdf"] 92 | 93 | phonyCommands :: Rules () 94 | phonyCommands = do 95 | phony "clean" (removeFilesAfter buildDir ["//*"]) 96 | 97 | addResource :: Rules Resource 98 | addResource = newResource "Download" 10 99 | 100 | addOracles :: Rules () 101 | addOracles = do 102 | _ <- addOracle $ \(ScalaOptions _) -> return ["-Ystop-after:namer" 103 | ,"-feature" 104 | ,"-deprecation" 105 | ,"-language:higherKinds" 106 | ,"-Xlint" 107 | ,"-nocompdaemon" 108 | ] 109 | _ <- addOracle $ \(ScalafmtOptions _) -> return ["--non-interactive" 110 | ,"--quiet" 111 | ,"--no-stderr" 112 | ,"--stdout" 113 | ,"--config-str" 114 | ,"maxColumn = 55" 115 | ] 116 | _ <- addOracle $ \(HindentOptions _) -> return ["--line-length", "55"] 117 | _ <- addOracle $ \(DitaaOptions _) -> return ["--scale" 118 | ,"4" 119 | ,"--overwrite" 120 | ] 121 | _ <- addOracle $ \(GraphvizOptions _) -> return ["-Tpng" 122 | ,"-Gdpi=300" 123 | ] 124 | return () 125 | 126 | addProjectCompiler :: Rules (() -> Action ()) 127 | addProjectCompiler = newCache $ \() -> cmd_ [Cwd "source-code"] "sbt" ["compile"] 128 | 129 | includedFont :: FilePath 130 | includedFont = buildDir "font.tex" 131 | 132 | beamerThemes :: [FilePath] 133 | beamerThemes = map (buildDir ) ["beamercolorthemecodecentric.sty" 134 | ,"beamerfontthemecodecentric.sty" 135 | ,"beamerinnerthemecodecentric.sty" 136 | ,"beamerouterthemecodecentric.sty" 137 | ,"beamerthemecodecentric.sty" 138 | ] 139 | 140 | createByCopy :: FilePath -> Rules () 141 | createByCopy ptrn = buildDir ptrn %> \out -> copyFileChanged (dropDirectory1 out) out 142 | 143 | rules :: (() -> Action ()) -> Resource -> Rules () 144 | rules sbtCompile downloadResource = do 145 | --snippet:outer pdf rule 146 | --snippet:pdf rule 147 | buildDir "slides.pdf" %> \out -> do 148 | let inp = out -<.> "tex" 149 | need (inp : includedFont : beamerThemes) 150 | latexmk inp 151 | --end:pdf rule 152 | --end:outer pdf rule 153 | 154 | buildDir "font.tex" %> \_ -> dumpFontFile 155 | 156 | buildDir "*.tex" %> \out -> do 157 | let inp = dropDirectory1 out 158 | needsCode <- codeDeps inp 159 | needsGraphics <- graphicDeps inp 160 | need (inp : needsCode ++ needsGraphics) 161 | chktex inp 162 | liftIO (copyFile inp out) 163 | 164 | createByCopy "*.sty" 165 | 166 | alternatives $ do 167 | 168 | buildDir "snippets" "*.scala" %> \out -> do 169 | _ <- sbtCompile () 170 | handleSnippet out $ \file -> do 171 | checkScala file 172 | scalafmt out 173 | 174 | --snippet:outer hs snippet rule 175 | --snippet:hs snippet rule 176 | buildDir "snippets" "*.hs" %> \out -> do 177 | snip <- extractSnippet (dropDirectory1 $ out -<.> "snippet") 178 | withTempFile $ \temp -> do 179 | liftIO (writeFile temp snip) 180 | hlint temp 181 | hindent temp 182 | content <- liftIO (readFile temp) 183 | writeFileChanged out content 184 | --end 185 | --end:outer hs snippet rule 186 | 187 | buildDir "snippets" "*.hs_noformat" %> \out -> do 188 | handleSnippet out hlint 189 | 190 | buildDir "snippets" "*.yml" %> \out -> do 191 | handleSnippet out (void . return) 192 | 193 | buildDir "snippets" "*.snippet" %> \out -> do 194 | let inp = dropDirectory1 out 195 | formatted <- dhallFormat inp 196 | writeFileChanged out formatted 197 | 198 | buildDir "snippets" "*" %> \out -> do 199 | handleSnippet out $ \file -> do 200 | formatted <- dhallFormat file 201 | writeFileChanged out formatted 202 | 203 | buildDir "ditaa/*.png" %> \out -> do 204 | let inp = dropDirectory1 out -<.> "ditaa" 205 | need [inp] 206 | ditaa inp out 207 | 208 | createByCopy "ditaa/*.ditaa" 209 | 210 | createByCopy "dhall/*.dhall" 211 | 212 | buildDir "dhall/*.json" %> \out -> do 213 | let inp = dropDirectory1 out -<.> "dhall" 214 | json <- dhallToJson inp 215 | result <- jqPretty json 216 | writeFileChanged out result 217 | 218 | buildDir "dhall/*.yaml" %> \out -> do 219 | let inp = dropDirectory1 out -<.> "dhall" 220 | yaml <- dhallToYaml inp 221 | writeFileChanged out yaml 222 | 223 | --snippet:graphviz rule 224 | buildDir "graphviz/*.png" %> \out -> do 225 | let inp = dropDirectory1 out -<.> "dot" 226 | need [inp] 227 | graphviz inp out 228 | --end 229 | 230 | createByCopy "graphviz/*.dot" 231 | 232 | buildDir "static-images/*" %> \out -> do 233 | let inp = dropDirectory1 out 234 | copyFileChanged inp out 235 | 236 | alternatives $ do 237 | buildDir "static-source/*.png" %> \out -> do 238 | let inp = dropExtension (dropDirectory1 out) 239 | need [inp] 240 | cmd [Stdin ""] ("pygmentize" :: String) ["-Ofont_name=Ubuntu Mono", "-o", out, inp] 241 | 242 | buildDir "static-source/*" %> \out -> do 243 | let inp = dropDirectory1 out 244 | copyFileChanged inp out 245 | 246 | --snippet:download-images 247 | [ buildDir "images/*" <.> ext | ext <- [ "jpg", "png", "gif" ] ] |%> \out -> do 248 | let inp = dropDirectory1 $ out -<.> "src" 249 | need [inp] 250 | ImageSrc uri ts <- traced "image-src" (readDhall inp) 251 | download downloadResource (TS.unpack uri) out 252 | for_ ts $ unit . applyTransformation out 253 | --end 254 | 255 | createByCopy "images/*.src" 256 | 257 | dhallFormat :: FilePath -> Action String 258 | dhallFormat inp = do 259 | Stdout out <- cmd (FileStdin inp : cmdOpts) "dhall-format" 260 | return out 261 | 262 | jqPretty :: String -> Action String 263 | jqPretty inp = do 264 | Stdout out <- cmd (Stdin inp : cmdOpts) "jq" ["."] 265 | return out 266 | 267 | dhallToJson :: FilePath -> Action String 268 | dhallToJson inp = do 269 | Stdout out <- cmd (FileStdin inp : cmdOpts) "dhall-to-json" 270 | return out 271 | 272 | dhallToYaml :: FilePath -> Action String 273 | dhallToYaml inp = do 274 | Stdout out <- cmd (FileStdin inp : cmdOpts) "dhall-to-yaml" 275 | return out 276 | 277 | chktex :: FilePath -> Action () 278 | chktex inp = cmd cmdOpts "chktex" inp 279 | 280 | hlint :: FilePath -> Action () 281 | hlint inp = do 282 | cmd cmdOpts "hlint" inp 283 | 284 | graphviz :: FilePath -> FilePath -> Action () 285 | graphviz inp out = do 286 | opts <- askOracle (GraphvizOptions ()) 287 | cmd cmdOpts "dot" (opts ++ ["-o", out, inp]) 288 | 289 | ditaa :: FilePath -> FilePath -> Action () 290 | ditaa inp outp = do 291 | opts <- askOracle (DitaaOptions ()) 292 | cmd cmdOpts "ditaa" ([inp, outp] ++ opts) 293 | 294 | --snippet:latexmk rule 295 | latexmk :: FilePath -> Action () 296 | latexmk inp = cmd (Cwd (takeDirectory inp) : cmdOpts) 297 | "latexmk" 298 | ["-g", "-shell-escape", "-pdfxe", dropDirectory1 inp] 299 | --end 300 | 301 | checkScala :: FilePath -> Action () 302 | checkScala inp = do 303 | opts <- askOracle (ScalaOptions ()) 304 | cmd "scala" (opts ++ [inp]) 305 | 306 | hindent :: FilePath -> Action () 307 | hindent inp = do 308 | opts <- askOracle (HindentOptions ()) 309 | cmd "hindent" (opts ++ [inp]) 310 | 311 | scalafmt :: FilePath -> Action () 312 | scalafmt inp = do 313 | opts <- askOracle (ScalafmtOptions ()) 314 | contents <- liftIO (IO.readFile inp) 315 | withTempFile $ \temp -> do 316 | let wrapped = unlines $ "object ObjForScalafmt {" : lines contents ++ ["}"] 317 | liftIO $ IO.writeFile temp wrapped 318 | Stdout stdout <- cmd [EchoStdout False, EchoStderr False] "scalafmt" (opts ++ [temp]) 319 | let output = unlines (init (drop 1 (lines stdout))) 320 | liftIO $ IO.writeFile inp output 321 | 322 | dumpFontFile :: Action () 323 | dumpFontFile = do 324 | putQuiet ("Dumping font file to " ++ (buildDir "font.tex")) 325 | -- Guaranteed to be present via `shell.nix`, although this couples shake and nix... 326 | 327 | Just useCodecentricFont <- getEnv "USE_CC_FONT" 328 | let filename = if useCodecentricFont == "true" then "font_cc.tex" else "font_non_cc.tex" 329 | outname = (buildDir "font.tex") 330 | copyFile' filename outname 331 | 332 | cmdArgs :: TeXArg -> Maybe Text 333 | cmdArgs (FixArg (TeXRaw arg)) = Just arg 334 | cmdArgs _ = Nothing 335 | 336 | --snippet:parse latex 337 | commandDeps :: [String] -> FilePath -> Action [[FilePath]] 338 | commandDeps cmds file = do 339 | etex <- liftIO (parseLaTeXFile file) 340 | case etex of 341 | Left err -> error ("Parsing of file " <> file <> " failed: " <> show err) 342 | Right t -> do 343 | let result = map (map T.unpack . mapMaybe cmdArgs . snd) . 344 | matchCommand (`elem` cmds) $ 345 | t 346 | return result 347 | --end 348 | 349 | graphicDeps :: FilePath -> Action [FilePath] 350 | graphicDeps file = map ((buildDir ) . concat) <$> commandDeps ["includegraphics"] file 351 | 352 | codeDeps :: FilePath -> Action [FilePath] 353 | codeDeps file = map (buildDir ) . concatMap (drop 1) <$> commandDeps ["inputminted"] file 354 | 355 | --snippet:extraction 356 | extractSnippet :: FilePath -> Action String 357 | extractSnippet file = do 358 | putQuiet ("Extracting from " <> file) 359 | need [file] 360 | SnippetSrc (T.unpack -> sourceFile) startSearch endSearch <- readDhall file 361 | lns <- readFileLines sourceFile 362 | let result = findSnippet startSearch endSearch lns 363 | if null result 364 | then error ("Empty snippet for:\n" <> file <> ":0:") 365 | else return (unlines result) 366 | --end 367 | 368 | findSnippet :: Addr -> Addr -> [String] -> [String] 369 | findSnippet (Search (T.unpack -> startString)) (Search (T.unpack -> endString)) lns = 370 | drop 1 371 | . takeWhile (not . (endString `isPrefixOf`) . dropWhile (== ' ')) 372 | . dropWhile (not . (startString `isPrefixOf`) . dropWhile (== ' ')) 373 | $ lns 374 | findSnippet (Search (T.unpack -> startString)) End lns = 375 | drop 1 . dropWhile (not . (startString `isPrefixOf`) . dropWhile (== ' ')) $ lns 376 | findSnippet Start (Search (T.unpack -> endString)) lns = 377 | takeWhile (not . (endString `isPrefixOf`) . dropWhile (== ' ')) lns 378 | findSnippet Start End lns = lns 379 | findSnippet s e _ = error $ "invalid combination of addresses: " ++ show (s,e) 380 | 381 | handleSnippet :: FilePath -> (FilePath -> Action ()) -> Action () 382 | handleSnippet out act = do 383 | snip <- extractSnippet (dropDirectory1 $ out -<.> "snippet") 384 | withTempFile $ \temp -> do 385 | liftIO (writeFile temp snip) 386 | act temp 387 | content <- liftIO (readFile temp) 388 | writeFileChanged out content 389 | 390 | download :: Resource -> String -> FilePath -> Action () 391 | download res uri target = withResource res 1 $ traced "download" $ do 392 | createDirectoryIfMissing True (takeDirectory target) 393 | r <- Wreq.get uri 394 | BL.writeFile target (r ^. Wreq.responseBody) 395 | 396 | readDhall :: (D.Interpret a, MonadIO m) => String -> m a 397 | readDhall p = liftIO $ D.input D.auto (TL.pack $ "./" <> p) 398 | 399 | applyTransformation :: String -> Text -> Action () 400 | applyTransformation out t = cmd [Stdin ""] "convert" (words (TS.unpack t) ++ [out, out]) 401 | -------------------------------------------------------------------------------- /slides.tex: -------------------------------------------------------------------------------- 1 | \documentclass{beamer} 2 | 3 | % Must be loaded first 4 | \usepackage{tikz} 5 | 6 | \usepackage[utf8]{inputenc} 7 | \usepackage{textpos} 8 | 9 | % Font configuration 10 | \usepackage{fontspec} 11 | 12 | \input{font.tex} 13 | 14 | % Tikz for beautiful drawings 15 | \usetikzlibrary{mindmap,backgrounds} 16 | \usetikzlibrary{arrows.meta,arrows} 17 | \usetikzlibrary{shapes.geometric} 18 | 19 | % Minted configuration for source code highlighting 20 | \usepackage{minted} 21 | \setminted{highlightcolor=black!5, linenos} 22 | \setminted{style=perldoc} 23 | 24 | \usepackage[listings, minted]{tcolorbox} 25 | \tcbset{left=6mm} 26 | 27 | % Use the include theme 28 | \usetheme{codecentric} 29 | 30 | % Metadata 31 | \title{How This Presentation Was Made} 32 | \author{Markus Hauck @markus1189} 33 | 34 | \newcommand{\overview}{% 35 | \begin{center} 36 | \resizebox{0.7\textwidth}{!}{ 37 | \begin{tikzpicture} 38 | \path[small mindmap, concept color=beamer@codeblue, 39 | level 1 concept/.append style={every child/.style={concept color=beamer@centricgreen}}, 40 | level 2 concept/.append style={every child/.style={concept color=beamer@centricgreen!50}} 41 | ] 42 | node[concept] {Presentation} 43 | [clockwise from=0] 44 | child { 45 | node[concept] (images) {Images} 46 | [clockwise from=90] 47 | child { node[concept] (algo) {Download} } 48 | child { node[concept] {graphviz} } 49 | child { node[concept] {ditaa} } 50 | child { node[concept] {plantuml} } 51 | } 52 | child { 53 | node[concept] (code) {Code} 54 | [clockwise from=-90] 55 | child { node[concept] {Extract} } 56 | child { node[concept] {Inline} } 57 | } 58 | child { 59 | node[concept] (build) {Build} 60 | [clockwise from=-120] 61 | child { node[concept] {PDF} } 62 | child { node[concept] {Depen-\\dencies} } 63 | child { node[concept] {CI} } 64 | } 65 | child { 66 | node[concept] (tools) {Tools} 67 | [clockwise from=135] 68 | child { node[concept] {Dhall} } 69 | child { node[concept] {Shake} } 70 | child { node[concept] {Nix} } 71 | } 72 | 73 | node [annotation, xshift=2cm, yshift=-10mm] (annot) at (code.east) {\setsansfont{Caveat} \large Should compile } 74 | node [annotation, xshift=2cm, yshift=-10mm] (annot2) at (build.east) {\setsansfont{Caveat} \large Simple } 75 | node [annotation, xshift=-10mm, yshift=8mm] (annot3) at (images.north) {\setsansfont{Caveat} \large Generated} 76 | node [annotation] (annot4) at (tools.west) {\setsansfont{Caveat} \large Fun} 77 | ; 78 | 79 | \begin{pgfonlayer}{background} 80 | \draw[draw=black, thick, shorten <=1mm, shorten >=1mm, -{Stealth[length=3mm, open, round]}] (annot) -- (code); 81 | \draw[draw=black, thick, shorten <=1mm, shorten >=1mm, -{Stealth[length=3mm, open, round]}] (annot2) -- (build); 82 | \draw[draw=black, thick, shorten <=1mm, shorten >=1mm, -{Stealth[length=3mm, open, round]}] (1.8,1.5) -- (images); 83 | \draw[draw=black, thick, shorten <=1mm, shorten >=1mm, -{Stealth[length=3mm, open, round]}] (-3.7,2) -- (tools); 84 | \end{pgfonlayer} 85 | \end{tikzpicture} 86 | } 87 | \end{center} 88 | } 89 | 90 | % The presentation content 91 | \begin{document} 92 | 93 | \begin{frame}[noframenumbering,plain] 94 | \titlepage{} 95 | \end{frame} 96 | 97 | \section{Introduction}\label{sec:introduction} 98 | 99 | \begin{frame} 100 | \frametitle{Presentations} 101 | \begin{center} 102 | \includegraphics[width=\textwidth]{ditaa/presentations.png} 103 | \end{center} 104 | \end{frame} 105 | 106 | \begin{frame} 107 | \frametitle{Some Problems} 108 | \begin{itemize} 109 | \item powerpoint/keynote/google slides/\ldots{} 110 | \item but you can't use \texttt{git} 111 | \item pandoc / LaTeX / \ldots{} 112 | \item how to include code and pictures? 113 | \end{itemize} 114 | \end{frame} 115 | 116 | \begin{frame} 117 | \frametitle{How It All Started} 118 | \begin{itemize} 119 | \item fighting with graphical editor instead of content 120 | \item so, switch to something that is text based 121 | \item but: how to handle generated pictures 122 | \item but: how to handle code 123 | \end{itemize} 124 | \end{frame} 125 | 126 | \begin{frame} 127 | \frametitle{In A Nutshell} 128 | \begin{center} 129 | \includegraphics[width=0.8\textwidth]{images/xkcd-salt.png}\\ 130 | XKCD 974 131 | \end{center} 132 | \end{frame} 133 | 134 | \begin{frame} 135 | \frametitle{In A Nutshell} 136 | \begin{center} 137 | \includegraphics[width=0.5\textwidth]{images/xkcd-automation.png}\\ 138 | XKCD 1319 139 | \end{center} 140 | \end{frame} 141 | 142 | \begin{frame} 143 | \frametitle{Used Tools Overview} 144 | \begin{itemize} 145 | \item Nix for system dependencies + build env 146 | \item Shake to write a custom build system 147 | \item Dhall for ``configuration'' 148 | \item LaTeX for slides 149 | \item ditaa, graphviz 150 | \end{itemize} 151 | \end{frame} 152 | 153 | \begin{frame} 154 | \frametitle{Wish List} 155 | \begin{itemize} 156 | \item version control: use git to track changes 157 | \item reproducible: same description for CI and local machine 158 | \item single step: \textbf{one} command to build presentation 159 | \item declarative: generate from description 160 | \item checked: source code compiles 161 | \item minimal: only re-build what changed 162 | \end{itemize} 163 | \end{frame} 164 | 165 | \begin{frame} 166 | \frametitle{Overview} 167 | \overview{} 168 | \end{frame} 169 | 170 | \begin{frame} 171 | \frametitle{Goal} 172 | \begin{itemize} 173 | \item I love theoretical talks about concepts 174 | \item it's also fun to \textbf{reap some benefits} 175 | \item apply FP to your presentation 176 | \item as much as possible: description only + build 177 | \end{itemize} 178 | \end{frame} 179 | 180 | \section{Shake} 181 | 182 | \begin{frame} 183 | \frametitle{Tool: Shake} 184 | \begin{itemize} 185 | \item \url{shakebuild.com/manual} 186 | \item Shake is a Haskell \textbf{library} for writing build systems 187 | \item ``just'' a library, rest is up to you 188 | \item \texttt{Shake} vs \texttt{make} is like \texttt{Monad} vs \texttt{Applicative} 189 | \item integrates well with other libraries and system tools 190 | \end{itemize} 191 | \end{frame} 192 | 193 | \begin{frame} 194 | \frametitle{Shake \textemdash{} Usage} 195 | \begin{itemize} 196 | \item specify rules to create output from some input 197 | \item avoid rebuilds of unchanged things 198 | \item call the shake build from your \texttt{main} 199 | \end{itemize} 200 | \begin{center} 201 | \inputminted[autogobble]{haskell}{snippets/shake-main.hs} 202 | \end{center} 203 | \end{frame} 204 | 205 | \begin{frame}[fragile] 206 | \frametitle{Shake Rules} 207 | \begin{minted}{haskell} 208 | -- +---------------- file pattern to match 209 | -- | 210 | -- | +-------- target path to create 211 | -- | | 212 | -- v v 213 | pattern %> \out -> do 214 | action1 -- <--\ 215 | action2 -- <---+- Actions to build 'out' 216 | action3 -- <--/ 217 | \end{minted} 218 | \end{frame} 219 | 220 | \begin{frame}[fragile] 221 | \frametitle{Shake Rules} 222 | \begin{minted}{haskell} 223 | "*.txt" %> \out -> do 224 | putNormal "Debug" 225 | cmd "touch" [out] 226 | \end{minted} 227 | \end{frame} 228 | 229 | \begin{frame}[fragile] 230 | \frametitle{Shake Rules} 231 | \inputminted[autogobble]{haskell}{snippets/pdf-rule.hs} 232 | \inputminted[autogobble]{haskell}{snippets/latexmk-rule.hs} 233 | \end{frame} 234 | 235 | \begin{frame} 236 | \frametitle{Shake Rules} 237 | \begin{center} 238 | \includegraphics[width=0.8\textwidth]{graphviz/rules.png} 239 | \end{center} 240 | \end{frame} 241 | 242 | \begin{frame} 243 | \frametitle{Shake} 244 | \begin{itemize} 245 | \item general idea: express any dependencies via Shake rules 246 | \item let shake figure out what needs rebuilding 247 | \item ensures minimal rebuilds 248 | \item you don't have to worry 249 | \end{itemize} 250 | \end{frame} 251 | 252 | \begin{frame} 253 | \frametitle{Shake} 254 | \begin{itemize} 255 | \item quick status: use haskell library shake 256 | \item get a ``build system'' for your presentation 257 | \item next: source code 258 | \end{itemize} 259 | \end{frame} 260 | 261 | \section{Source Code} 262 | 263 | \begin{frame} 264 | \frametitle{Editing Code} 265 | \begin{itemize} 266 | \item Step 1: Implement your code in a normal project 267 | \item Step 2: Wild Copy And Paste Into Presentation 268 | \item Step 3: Reformat To Fit Slide 269 | \item Step 4: Change Original Source Code 270 | \item Step 5: Wild Editing Of Code on Slides 271 | \item Step 6: Notice something doesn't make sense 272 | \end{itemize} 273 | \end{frame} 274 | 275 | \begin{frame}[fragile] 276 | \frametitle{Extract Code} 277 | \begin{itemize} 278 | \item totally broken: copy \& paste 279 | \item little better: extract based on lines, still bad 280 | \item after edit / formatting / \ldots they change 281 | \item not what we want 282 | \end{itemize} 283 | \end{frame} 284 | 285 | \begin{frame} 286 | \frametitle{Editing Code} 287 | \begin{itemize} 288 | \item idea: extract source code directly from actual project 289 | \item use comments to delimit ``snippets'' 290 | \item write code to extract everything in between 291 | \end{itemize} 292 | \end{frame} 293 | 294 | \begin{frame} 295 | \frametitle{Editing Code} 296 | \begin{itemize} 297 | \item add comments in the code 298 | \item write a small ``snippet'' file 299 | \item let shake automatically extract snippets 300 | \item include code snippets in presentation 301 | \end{itemize} 302 | \end{frame} 303 | 304 | \begin{frame} 305 | \frametitle{Annotating Code for Snippets (META)} 306 | \begin{center} 307 | \inputminted[autogobble]{haskell}{snippets/outer-pdf-rule.hs} 308 | \end{center} 309 | \end{frame} 310 | 311 | \begin{frame} 312 | \frametitle{Intermezzo: Dhall} 313 | \begin{quote} 314 | A configuration language guaranteed to terminate 315 | \end{quote} 316 | \begin{itemize} 317 | \item think: lambda calculus for config 318 | \item not turing-complete on purpose 319 | \item subset can be converted to JSON and YAML 320 | \item has \textbf{types}!!!11 321 | \item can be mapped directly into Haskell types 322 | \end{itemize} 323 | \end{frame} 324 | 325 | \begin{frame} 326 | \frametitle{Dhall Example} 327 | \inputminted[autogobble]{haskell}{dhall/example.dhall} 328 | \end{frame} 329 | 330 | \begin{frame} 331 | \frametitle{Dhall Features} 332 | \begin{itemize} 333 | \item booleans/integer/naturals 334 | \item optional values 335 | \item lists 336 | \item records 337 | \item functions 338 | \item strings + interpolation 339 | \item unions 340 | \item imports 341 | \item \ldots{} 342 | \end{itemize} 343 | \end{frame} 344 | 345 | \begin{frame} 346 | \frametitle{Dhall To JSON} 347 | \inputminted[autogobble]{json}{dhall/example.json} 348 | \end{frame} 349 | 350 | \begin{frame} 351 | \frametitle{Dhall To YAML} 352 | \inputminted[autogobble]{yaml}{dhall/example.yaml} 353 | \end{frame} 354 | 355 | \begin{frame} 356 | \frametitle{Snippet Files \textemdash{} Type} 357 | \begin{center} 358 | \inputminted{text}{snippets/snippet-type.dhall} 359 | \end{center} 360 | \end{frame} 361 | 362 | \begin{frame} 363 | \frametitle{Snippet Files \textemdash{} Haskell} 364 | \inputminted{haskell}{snippets/haskell-snippet-type.hs} 365 | \end{frame} 366 | 367 | \begin{frame} 368 | \frametitle{Snippet Files \textemdash{} Example} 369 | \begin{center} 370 | \inputminted{text}{snippets/snippet-type.snippet} 371 | \end{center} 372 | \end{frame} 373 | 374 | \begin{frame} 375 | \frametitle{Snippet Files \textemdash{} Example} 376 | \begin{center} 377 | \inputminted{text}{snippets/pdf-rule.snippet} 378 | \end{center} 379 | \end{frame} 380 | 381 | \begin{frame} 382 | \frametitle{Snippet Files \textemdash{} Extraction} 383 | \inputminted{haskell}{snippets/extraction.hs} 384 | \end{frame} 385 | 386 | \begin{frame} 387 | \frametitle{Extracting Code} 388 | \begin{itemize} 389 | \item will always be up to date with the compiling source (yay) 390 | \item but we also have to format and maybe check again 391 | \end{itemize} 392 | \end{frame} 393 | 394 | \begin{frame} 395 | \frametitle{Checking Code} 396 | \begin{itemize} 397 | \item let's tackle checking first 398 | \item lots of times: broken code snippets that don't compile 399 | \item style errors you would notice in your actual setup 400 | \item after extracting a snippet into an includable file 401 | \item run linter/compiler/\ldots 402 | \item fail building presentation if the command fails 403 | \end{itemize} 404 | \end{frame} 405 | 406 | \begin{frame} 407 | \frametitle{Checking Code} 408 | \begin{itemize} 409 | \item haskell with hindent + hlint 410 | \item scala with sbt and scalafmt 411 | \item actually any programming language and linter 412 | \end{itemize} 413 | \end{frame} 414 | 415 | \begin{frame} 416 | \frametitle{Formatting Code} 417 | \begin{itemize} 418 | \item just another step like linting 419 | \item run formatter of choice on the source file 420 | \item e.g.\ format to a width of 55 chars 421 | \end{itemize} 422 | \end{frame} 423 | 424 | \begin{frame} 425 | \frametitle{Snippet Rule \textemdash{} Broken Formatting} 426 | \begin{center} 427 | \inputminted[autogobble, highlightlines={3}]{haskell}{snippets/outer-haskell-snippet-rule.hs_noformat} 428 | \end{center} 429 | \end{frame} 430 | 431 | \begin{frame} 432 | \frametitle{Snippet Rule \textemdash{} After Auto-Formatting} 433 | \begin{center} 434 | \inputminted[autogobble, highlightlines={2-4}]{haskell}{snippets/haskell-snippet-rule.hs} 435 | \end{center} 436 | \end{frame} 437 | 438 | \begin{frame} 439 | \frametitle{Snippets \textemdash{} Summary} 440 | \begin{itemize} 441 | \item automatic snippet extraction, robust 442 | \item snippets compile 443 | \item snippets are formatted 444 | \item no worries over broken code 445 | \item confidence in examples 446 | \end{itemize} 447 | \end{frame} 448 | 449 | \section{Pictures} 450 | 451 | \begin{frame} 452 | \frametitle{Pictures} 453 | \begin{itemize} 454 | \item scenario 1: search on the web and download 455 | \begin{itemize} 456 | \item but you will forget from where 457 | \item resize and rotate are manual steps 458 | \item you have to store them in git 459 | \end{itemize} 460 | \item scenario 2: generated from description 461 | \begin{itemize} 462 | \item graphviz graphs 463 | \item ditaa diagrams 464 | \item plantuml diagrams 465 | \item and more\ldots{} 466 | \end{itemize} 467 | \end{itemize} 468 | \end{frame} 469 | 470 | \begin{frame} 471 | \frametitle{Downloading Pictures} 472 | \begin{center} 473 | \includegraphics[width=0.7\textwidth]{images/maintain-make.jpg} 474 | \end{center} 475 | {\small{Picture: me having to do too many manual steps}} 476 | \end{frame} 477 | 478 | \begin{frame} 479 | \frametitle{Downloading Pictures} 480 | \begin{itemize} 481 | \item use Haskell and Shake to download on demand 482 | \item download of the file from the internet 483 | \item file that describes from where plus transformations 484 | \item transformations performed by imagemagick 485 | \end{itemize} 486 | \end{frame} 487 | 488 | \begin{frame} 489 | \frametitle{Downloading Pictures} 490 | \begin{center} 491 | \includegraphics[width=0.4\textwidth]{images/maintain-make.jpg} 492 | \inputminted{text}{images/maintain-make.src} 493 | \end{center} 494 | \end{frame} 495 | 496 | \begin{frame} 497 | \frametitle{Downloading Pictures} 498 | \begin{center} 499 | \inputminted{haskell}{snippets/download-images.hs} 500 | \end{center} 501 | \end{frame} 502 | 503 | \begin{frame} 504 | \frametitle{Generating Pictures} 505 | \begin{itemize} 506 | \item second scenario: picture is generated 507 | \item there is a file that describes it + tool to render 508 | \item Steps: 509 | \begin{itemize} 510 | \item write the description file 511 | \item generate graphic 512 | \item include in presentation 513 | \item change description 514 | \item generate graphic 515 | \item include in presentation 516 | \item change description again\ldots{} 517 | \end{itemize} 518 | \end{itemize} 519 | \end{frame} 520 | 521 | \begin{frame} 522 | \frametitle{Shake It} 523 | \begin{itemize} 524 | \item express the dependency as a shake rule 525 | \end{itemize} 526 | \inputminted{haskell}{snippets/graphviz-rule.hs} 527 | \end{frame} 528 | 529 | \begin{frame} 530 | \frametitle{Everything As A Rule} 531 | \begin{center} 532 | \includegraphics[width=\textwidth]{graphviz/rules-big.png} 533 | \end{center} 534 | \end{frame} 535 | 536 | \begin{frame} 537 | \frametitle{Getting Dependencies} 538 | \begin{itemize} 539 | \item the missing piece: how to ``discover'' dependencies? 540 | \item all of hackage is available 541 | \item parse LaTeX via HaTeX (this time) 542 | \item use the pandoc library 543 | \item \ldots whatever you need 544 | \end{itemize} 545 | \end{frame} 546 | 547 | \begin{frame} 548 | \frametitle{Extraction from LaTeX} 549 | \inputminted{haskell}{snippets/parse-latex.hs} 550 | \end{frame} 551 | 552 | \section{Continuous Integration} 553 | 554 | \begin{frame} 555 | \frametitle{Develop Environment and CI} 556 | \begin{itemize} 557 | \item we freely mixed stuff and used lots of tools 558 | \begin{itemize} 559 | \item haskell + libraries 560 | \item imagemagick 561 | \item graphviz 562 | \item ditaa 563 | \item LaTeX plus packages and special font 564 | \item scala, sbt, scalafmt 565 | \end{itemize} 566 | \end{itemize} 567 | \end{frame} 568 | 569 | \begin{frame} 570 | \frametitle{Travis} 571 | \begin{itemize} 572 | \item let's get it working on travis 573 | \item (how hard can it be?!) 574 | \end{itemize} 575 | \end{frame} 576 | 577 | \begin{frame} 578 | \frametitle{Continuous Integration via Travis} 579 | \inputminted[linenos=false, fontsize=\tiny, lastline=31]{yaml}{static-source/long-travis-ci.yml} 580 | \end{frame} 581 | 582 | \begin{frame} 583 | \frametitle{Continuous Integration via Travis} 584 | \inputminted[linenos=false, fontsize=\tiny, firstline=31, lastline=60]{yaml}{static-source/long-travis-ci.yml} 585 | \end{frame} 586 | 587 | \begin{frame} 588 | \frametitle{Continuous Integration via Travis} 589 | \inputminted[linenos=false, fontsize=\tiny, firstline=61, lastline=90]{yaml}{static-source/long-travis-ci.yml} 590 | \end{frame} 591 | 592 | \begin{frame} 593 | \frametitle{Continuous Integration via Travis} 594 | \inputminted[linenos=false, fontsize=\tiny, firstline=91, lastline=120]{yaml}{static-source/long-travis-ci.yml} 595 | \end{frame} 596 | 597 | \begin{frame} 598 | \frametitle{Continuous Integration Madness} 599 | \begin{itemize} 600 | \item it's huge and a mess, good luck maintaining this 601 | \item OS specific, your own setup vs travis 602 | \item not reproducible at all 603 | \item very brittle 604 | \end{itemize} 605 | \end{frame} 606 | 607 | \begin{frame} 608 | \frametitle{The One Command Lie} 609 | \begin{itemize} 610 | \item you just have to run this \textbf{one} command 611 | \item it's mostly a lie 612 | \item with nix, you can \textit{actually} achieve that! 613 | \item perfect: use it in ``.travis.yml'' as well as every pc 614 | \end{itemize} 615 | \end{frame} 616 | 617 | \begin{frame} 618 | \frametitle{Nix} 619 | \begin{itemize} 620 | \item \url{https://nixos.org/nix/} 621 | \end{itemize} 622 | \begin{quote} 623 | Nix is a powerful package manager for Linux and other Unix systems that makes package management reliable and reproducible. 624 | \end{quote} 625 | \end{frame} 626 | 627 | \begin{frame} 628 | \frametitle{Continuous Integration Made Easy} 629 | \inputminted{yaml}{snippets/travis.yml} 630 | \end{frame} 631 | 632 | \begin{frame} 633 | \frametitle{Executing Our Shake Build} 634 | \inputminted[breaklines]{yaml}{snippets/build-shebang.hs} 635 | \end{frame} 636 | 637 | \begin{frame} 638 | \frametitle{The Nix File (Simplified)} 639 | \inputminted{nix}{static-source/simple-shell.nix} 640 | \end{frame} 641 | 642 | \section{Conclusion}\label{sec:conclusion} 643 | 644 | \begin{frame} 645 | \frametitle{Only LaTeX} 646 | \begin{itemize} 647 | \item all of this is not specific to LaTeX 648 | \item other: pandoc, reveal.js, \ldots{} 649 | \item e.g.\ download reveal.js automatically 650 | \item use pandoc to analyze the markdown 651 | \end{itemize} 652 | \end{frame} 653 | 654 | \begin{frame} 655 | \frametitle{I Want To Use This} 656 | \begin{itemize} 657 | \item github.com/markus1189/how-this-presentation 658 | \item you need \texttt{Nix}, but that's it 659 | \end{itemize} 660 | \end{frame} 661 | 662 | \begin{frame} 663 | \begin{center} 664 | \Huge 665 | Thanks for your attention 666 | \end{center} 667 | \begin{center} 668 | \Huge 669 | Markus Hauck (@markus1189) 670 | \end{center} 671 | \end{frame} 672 | 673 | \begin{frame} 674 | \overview{} 675 | \end{frame} 676 | 677 | \appendix{} 678 | 679 | \section*{Bonus}\label{sec:bonus} 680 | 681 | \end{document} 682 | --------------------------------------------------------------------------------