├── src ├── slides │ ├── revealjs │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── lib │ │ │ └── js │ │ │ │ ├── html5shiv.js │ │ │ │ ├── classList.js │ │ │ │ └── head.min.js │ │ ├── plugin │ │ │ ├── print-pdf │ │ │ │ └── print-pdf.js │ │ │ ├── math │ │ │ │ └── math.js │ │ │ └── notes │ │ │ │ ├── notes.js │ │ │ │ └── notes.html │ │ ├── LICENSE │ │ ├── css │ │ │ ├── print │ │ │ │ ├── pdf.css │ │ │ │ └── paper.css │ │ │ └── reveal.min.css │ │ └── js │ │ │ └── reveal.min.js │ ├── img │ │ ├── facts.jpg │ │ ├── image.jpg │ │ ├── bezier.jpg │ │ ├── impact.jpg │ │ ├── motion.jpg │ │ ├── number-8.jpg │ │ ├── projection.jpg │ │ ├── de-casteljau.jpg │ │ └── starting-point.jpg │ └── index.md └── uk │ └── co │ └── tombooth │ └── pollock.cljs ├── .gitignore ├── README.md ├── web └── index.html ├── project.clj ├── update_gh_pages.sh ├── tools ├── clojure-to-markdown.py ├── pandoc-template.html └── pandoc-template-slides.html └── LICENSE /src/slides/revealjs/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .svn 3 | log/*.log 4 | tmp/** 5 | node_modules/ 6 | .sass-cache -------------------------------------------------------------------------------- /src/slides/img/facts.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombooth/painting-in-clojure/HEAD/src/slides/img/facts.jpg -------------------------------------------------------------------------------- /src/slides/img/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombooth/painting-in-clojure/HEAD/src/slides/img/image.jpg -------------------------------------------------------------------------------- /src/slides/img/bezier.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombooth/painting-in-clojure/HEAD/src/slides/img/bezier.jpg -------------------------------------------------------------------------------- /src/slides/img/impact.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombooth/painting-in-clojure/HEAD/src/slides/img/impact.jpg -------------------------------------------------------------------------------- /src/slides/img/motion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombooth/painting-in-clojure/HEAD/src/slides/img/motion.jpg -------------------------------------------------------------------------------- /src/slides/img/number-8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombooth/painting-in-clojure/HEAD/src/slides/img/number-8.jpg -------------------------------------------------------------------------------- /src/slides/img/projection.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombooth/painting-in-clojure/HEAD/src/slides/img/projection.jpg -------------------------------------------------------------------------------- /src/slides/img/de-casteljau.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombooth/painting-in-clojure/HEAD/src/slides/img/de-casteljau.jpg -------------------------------------------------------------------------------- /src/slides/revealjs/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.8 4 | before_script: 5 | - npm install -g grunt-cli -------------------------------------------------------------------------------- /src/slides/img/starting-point.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombooth/painting-in-clojure/HEAD/src/slides/img/starting-point.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | /web/js/main.js 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Painting in Clojure 2 | 3 | Explore clojure by building a digital Jackson Pollock 4 | 5 | ## Usage 6 | 7 | ``` 8 | $ lein cljsbuild once 9 | $ open web/index.html 10 | ``` 11 | 12 | ## License 13 | 14 | Copyright © 2014 Tom Booth 15 | 16 | MIT License 17 | -------------------------------------------------------------------------------- /src/slides/revealjs/lib/js/html5shiv.js: -------------------------------------------------------------------------------- 1 | document.createElement('header'); 2 | document.createElement('nav'); 3 | document.createElement('section'); 4 | document.createElement('article'); 5 | document.createElement('aside'); 6 | document.createElement('footer'); 7 | document.createElement('hgroup'); -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pollock 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject painting-by-clojure "0.1.0-SNAPSHOT" 2 | :description "A digital Jackson Pollock" 3 | :url "https://github.com/tombooth/painting-by-clojure" 4 | :license {:name "MIT License" 5 | :url "http://opensource.org/licenses/MIT"} 6 | :dependencies [[org.clojure/clojure "1.6.0"] 7 | [quil "2.2.0"] 8 | [org.clojure/clojurescript "0.0-2268"]] 9 | :plugins [[lein-cljsbuild "1.0.3"]] 10 | :hooks [leiningen.cljsbuild] 11 | :cljsbuild 12 | {:builds [{:source-paths ["src"] 13 | :compiler 14 | {:output-to "web/js/main.js" 15 | :externs ["externs/processing-externs.js"] 16 | :optimizations :whitespace 17 | :pretty-print true}}]}) 18 | -------------------------------------------------------------------------------- /update_gh_pages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | mkdir .working 6 | 7 | cat src/uk/co/tombooth/pollock.cljs | python tools/clojure-to-markdown.py > .working/out.md 8 | pandoc --mathjax --template=tools/pandoc-template.html -s .working/out.md | sed -E 's/([^<]*)<\/span>/\1<\/a>/g' > .working/index.html 9 | cp -r web/js .working/ 10 | 11 | mkdir .working/slides 12 | cp -r src/slides/img .working/slides/ 13 | cp -r src/slides/revealjs .working/slides/ 14 | pandoc --template=tools/pandoc-template-slides.html -t revealjs -s src/slides/index.md -o .working/slides/index.html 15 | 16 | git checkout gh-pages 17 | 18 | cp .working/index.html index.html 19 | cp -r .working/slides . 20 | cp -r .working/js . 21 | 22 | git add index.html 23 | git add js 24 | git add slides 25 | git commit -m "Update homepage" || true 26 | 27 | git checkout master 28 | 29 | rm -rf .working 30 | -------------------------------------------------------------------------------- /src/slides/revealjs/plugin/print-pdf/print-pdf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * phantomjs script for printing presentations to PDF. 3 | * 4 | * Example: 5 | * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf 6 | * 7 | * By Manuel Bieh (https://github.com/manuelbieh) 8 | */ 9 | 10 | // html2pdf.js 11 | var page = new WebPage(); 12 | var system = require( 'system' ); 13 | 14 | page.viewportSize = { 15 | width: 1024, 16 | height: 768 17 | }; 18 | 19 | page.paperSize = { 20 | format: 'letter', 21 | orientation: 'landscape', 22 | margin: { 23 | left: '0', 24 | right: '0', 25 | top: '0', 26 | bottom: '0' 27 | } 28 | }; 29 | 30 | var revealFile = system.args[1] || 'index.html?print-pdf'; 31 | var slideFile = system.args[2] || 'slides.pdf'; 32 | 33 | if( slideFile.match( /\.pdf$/gi ) === null ) { 34 | slideFile += '.pdf'; 35 | } 36 | 37 | console.log( 'Printing PDF...' ); 38 | 39 | page.open( revealFile, function( status ) { 40 | console.log( 'Printed succesfully' ); 41 | page.render( slideFile ); 42 | phantom.exit(); 43 | } ); 44 | 45 | -------------------------------------------------------------------------------- /tools/clojure-to-markdown.py: -------------------------------------------------------------------------------- 1 | import re 2 | import sys 3 | 4 | 5 | whitespace_re = re.compile('^\s') 6 | 7 | PRELUDE = 0 8 | COMMENT = 1 9 | SEXP = 2 10 | 11 | 12 | def main(): 13 | state = PRELUDE 14 | out = [] 15 | 16 | for line in sys.stdin: 17 | if line[0] == ';': 18 | if state == SEXP: 19 | sys.stdout.write('```\n\n\n') 20 | 21 | sys.stdout.write(line[3:] if len(line) > 3 else '\n') 22 | state = COMMENT 23 | elif line[0] == '(': 24 | if state != PRELUDE: 25 | if state != SEXP: 26 | sys.stdout.write('\n\n``` {.clojure}\n') 27 | sys.stdout.write(line) 28 | state = SEXP 29 | elif whitespace_re.match(line[0]): 30 | if state == SEXP: 31 | sys.stdout.write(line) 32 | elif state == COMMENT: 33 | sys.stdout.write('\n') 34 | else: 35 | sys.stderr.write('Unknown line: {}'.format(line)) 36 | 37 | if state == SEXP: 38 | sys.stdout.write('```\n') 39 | 40 | 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Thomas Booth 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/slides/revealjs/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Hakim El Hattab, http://hakim.se 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /src/slides/revealjs/lib/js/classList.js: -------------------------------------------------------------------------------- 1 | /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/ 2 | if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p 3 | 4 | 5 | 6 | 7 | $if(title)$$title$ - $endif$Tom Booth 8 | 11 | 12 | 13 | 14 | 15 |
16 |

$title$by Tom Booth

17 |
18 |
19 | $body$ 20 |
21 | 24 | 25 | 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/slides/revealjs/plugin/math/math.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A plugin which enables rendering of math equations inside 3 | * of reveal.js slides. Essentially a thin wrapper for MathJax. 4 | * 5 | * @author Hakim El Hattab 6 | */ 7 | var RevealMath = window.RevealMath || (function(){ 8 | 9 | var options = Reveal.getConfig().math || {}; 10 | options.mathjax = options.mathjax || 'http://cdn.mathjax.org/mathjax/latest/MathJax.js'; 11 | options.config = options.config || 'TeX-AMS_HTML-full'; 12 | 13 | loadScript( options.mathjax + '?config=' + options.config, function() { 14 | 15 | MathJax.Hub.Config({ 16 | messageStyle: 'none', 17 | tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] }, 18 | skipStartupTypeset: true 19 | }); 20 | 21 | // Typeset followed by an immediate reveal.js layout since 22 | // the typesetting process could affect slide height 23 | MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] ); 24 | MathJax.Hub.Queue( Reveal.layout ); 25 | 26 | // Reprocess equations in slides when they turn visible 27 | Reveal.addEventListener( 'slidechanged', function( event ) { 28 | 29 | MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] ); 30 | 31 | } ); 32 | 33 | } ); 34 | 35 | function loadScript( url, callback ) { 36 | 37 | var head = document.querySelector( 'head' ); 38 | var script = document.createElement( 'script' ); 39 | script.type = 'text/javascript'; 40 | script.src = url; 41 | 42 | // Wrapper for callback to make sure it only fires once 43 | var finish = function() { 44 | if( typeof callback === 'function' ) { 45 | callback.call(); 46 | callback = null; 47 | } 48 | } 49 | 50 | script.onload = finish; 51 | 52 | // IE 53 | script.onreadystatechange = function() { 54 | if ( this.readyState === 'loaded' ) { 55 | finish(); 56 | } 57 | } 58 | 59 | // Normal browsers 60 | head.appendChild( script ); 61 | 62 | } 63 | 64 | })(); 65 | -------------------------------------------------------------------------------- /src/slides/revealjs/plugin/notes/notes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Handles opening of and synchronization with the reveal.js 3 | * notes window. 4 | */ 5 | var RevealNotes = (function() { 6 | 7 | function openNotes() { 8 | var jsFileLocation = document.querySelector('script[src$="notes.js"]').src; // this js file path 9 | jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, ''); // the js folder path 10 | var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' ); 11 | 12 | // Fires when slide is changed 13 | Reveal.addEventListener( 'slidechanged', post ); 14 | 15 | // Fires when a fragment is shown 16 | Reveal.addEventListener( 'fragmentshown', post ); 17 | 18 | // Fires when a fragment is hidden 19 | Reveal.addEventListener( 'fragmenthidden', post ); 20 | 21 | /** 22 | * Posts the current slide data to the notes window 23 | */ 24 | function post() { 25 | var slideElement = Reveal.getCurrentSlide(), 26 | slideIndices = Reveal.getIndices(), 27 | messageData; 28 | 29 | var notes = slideElement.querySelector( 'aside.notes' ), 30 | nextindexh, 31 | nextindexv; 32 | 33 | if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) { 34 | nextindexh = slideIndices.h; 35 | nextindexv = slideIndices.v + 1; 36 | } else { 37 | nextindexh = slideIndices.h + 1; 38 | nextindexv = 0; 39 | } 40 | 41 | messageData = { 42 | notes : notes ? notes.innerHTML : '', 43 | indexh : slideIndices.h, 44 | indexv : slideIndices.v, 45 | indexf : slideIndices.f, 46 | nextindexh : nextindexh, 47 | nextindexv : nextindexv, 48 | markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false 49 | }; 50 | 51 | notesPopup.postMessage( JSON.stringify( messageData ), '*' ); 52 | } 53 | 54 | // Navigate to the current slide when the notes are loaded 55 | notesPopup.addEventListener( 'load', function( event ) { 56 | post(); 57 | }, false ); 58 | } 59 | 60 | // If the there's a 'notes' query set, open directly 61 | if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) { 62 | openNotes(); 63 | } 64 | 65 | // Open the notes when the 's' key is hit 66 | document.addEventListener( 'keydown', function( event ) { 67 | // Disregard the event if the target is editable or a 68 | // modifier is present 69 | if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return; 70 | 71 | if( event.keyCode === 83 ) { 72 | event.preventDefault(); 73 | openNotes(); 74 | } 75 | }, false ); 76 | 77 | return { open: openNotes }; 78 | })(); 79 | -------------------------------------------------------------------------------- /tools/pandoc-template-slides.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 25 | 28 | 29 | 30 |
31 |
32 | $body$ 33 |
34 |
35 | 36 | 37 | 54 | 55 | 56 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/slides/revealjs/lib/js/head.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | Head JS The only script in your 3 | Copyright Tero Piirainen (tipiirai) 4 | License MIT / http://bit.ly/mit-license 5 | Version 0.96 6 | 7 | http://headjs.com 8 | */(function(a){function z(){d||(d=!0,s(e,function(a){p(a)}))}function y(c,d){var e=a.createElement("script");e.type="text/"+(c.type||"javascript"),e.src=c.src||c,e.async=!1,e.onreadystatechange=e.onload=function(){var a=e.readyState;!d.done&&(!a||/loaded|complete/.test(a))&&(d.done=!0,d())},(a.body||b).appendChild(e)}function x(a,b){if(a.state==o)return b&&b();if(a.state==n)return k.ready(a.name,b);if(a.state==m)return a.onpreload.push(function(){x(a,b)});a.state=n,y(a.url,function(){a.state=o,b&&b(),s(g[a.name],function(a){p(a)}),u()&&d&&s(g.ALL,function(a){p(a)})})}function w(a,b){a.state===undefined&&(a.state=m,a.onpreload=[],y({src:a.url,type:"cache"},function(){v(a)}))}function v(a){a.state=l,s(a.onpreload,function(a){a.call()})}function u(a){a=a||h;var b;for(var c in a){if(a.hasOwnProperty(c)&&a[c].state!=o)return!1;b=!0}return b}function t(a){return Object.prototype.toString.call(a)=="[object Function]"}function s(a,b){if(!!a){typeof a=="object"&&(a=[].slice.call(a));for(var c=0;c