├── .gitignore ├── .travis.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Makefile ├── README.adoc ├── bb.sh ├── build.sh ├── deploy.sh ├── docs ├── advanced-topics.adoc ├── clojure │ ├── 0-introduction.adoc │ ├── 1-ecosystem.adoc │ ├── 10-databases.adoc │ ├── 11-spec.adoc │ ├── 12-macros.adoc │ ├── 13-further-reading.adoc │ ├── 2-syntax.adoc │ ├── 3-functions.adoc │ ├── 4-testing.adoc │ ├── 5-control-flow.adoc │ ├── 6-functional-programming.adoc │ ├── 7-java-interop.adoc │ ├── 8-concurrency.adoc │ ├── 9-polymorphism.adoc │ ├── docinfo-footer.html │ ├── docinfo-header.html │ ├── docinfo.html │ └── slide.attrs ├── docinfo-footer.html ├── docinfo-header.html ├── docinfo.html ├── functions.adoc ├── getting-help.adoc ├── img ├── index.adoc ├── manual.adoc ├── setup.adoc └── talk.adoc ├── examples ├── aot │ ├── README.adoc │ ├── little-aot │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── project.clj │ │ └── src │ │ │ └── little_aot │ │ │ ├── bootstrap.clj │ │ │ ├── core.clj │ │ │ └── dont_aot_me.clj │ ├── no-aot │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── project.clj │ │ ├── src │ │ │ └── no_aot │ │ │ │ └── core.clj │ │ └── test │ │ │ └── no_aot │ │ │ └── core_test.clj │ └── too-much-aot │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── project.clj │ │ └── src │ │ └── too_much_aot │ │ ├── core.clj │ │ └── dont_aot_me.clj ├── communicating-services │ ├── Makefile │ ├── customer-data-service │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── Makefile │ │ ├── README.md │ │ ├── project.clj │ │ ├── src │ │ │ └── customer_data_service │ │ │ │ ├── db.clj │ │ │ │ └── handler.clj │ │ └── test │ │ │ └── customer_data_service │ │ │ └── handler_test.clj │ ├── docker-compose-prod.yml │ ├── docker-compose.yml │ ├── insurance-policy-application-processor │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── project.clj │ │ ├── src │ │ │ └── insurance_policy_application_processor │ │ │ │ └── core.clj │ │ └── test │ │ │ └── insurance_policy_application_processor │ │ │ └── core_test.clj │ └── insurance-policy-service │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── Makefile │ │ ├── README.md │ │ ├── project.clj │ │ ├── src │ │ └── insurance_policy_service │ │ │ ├── db.clj │ │ │ └── handler.clj │ │ └── test │ │ └── insurance_policy_service │ │ └── handler_test.clj ├── jenkins-build-server │ ├── Dockerfile │ ├── Makefile │ └── README.adoc └── parsing-with-spec │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── data │ └── insurance_policy_applications.txt │ ├── project.clj │ ├── src │ └── parsing_with_spec │ │ └── core.clj │ └── test │ └── parsing_with_spec │ ├── core_test.clj │ └── generated_test.clj ├── site ├── forum.html ├── img │ ├── art1.jpg │ ├── clojure-logo-icon-32.png │ ├── clojure-logo.png │ ├── control.jpg │ ├── corgi.jpg │ ├── database.jpg │ ├── ecosystem.jpg │ ├── functional.jpg │ ├── functions.jpg │ ├── further-reading.jpg │ ├── interop.jpg │ ├── macros.jpg │ ├── parallel.jpg │ ├── spec.jpg │ ├── syntax.png │ ├── talk │ │ ├── clojure-jobs.png │ │ ├── corgi-asleep-at-vet.jpg │ │ ├── corgi-challenge.jpg │ │ ├── corgi-developer.jpg │ │ ├── corgi-encounter.jpg │ │ ├── corgi-herding-ducks.jpg │ │ ├── corgi-hoodie.jpg │ │ ├── corgi-in-crate.jpg │ │ ├── corgi-lights.png │ │ ├── corgi-on-field.jpg │ │ ├── corgi-rope.jpg │ │ ├── corgi-student.png │ │ ├── corgi-team.jpg │ │ ├── corgi-training.jpeg │ │ ├── corgi-training.jpg │ │ ├── corgi-waiting.jpg │ │ ├── corgi-weird.jpeg │ │ ├── idea-asciidoctor.png │ │ ├── most-used-jvm.jpg │ │ ├── popularity.png │ │ └── suiteness.png │ ├── testing.jpg │ └── types.jpg ├── reveal.js │ ├── .gitignore │ ├── .travis.yml │ ├── CONTRIBUTING.md │ ├── Gruntfile.js │ ├── LICENSE │ ├── README.md │ ├── bower.json │ ├── css │ │ ├── print │ │ │ ├── paper.css │ │ │ └── pdf.css │ │ ├── reveal.css │ │ ├── reveal.scss │ │ └── theme │ │ │ ├── README.md │ │ │ ├── beige.css │ │ │ ├── black.css │ │ │ ├── blood.css │ │ │ ├── league.css │ │ │ ├── moon.css │ │ │ ├── night.css │ │ │ ├── serif.css │ │ │ ├── simple.css │ │ │ ├── sky.css │ │ │ ├── solarized.css │ │ │ ├── source │ │ │ ├── beige.scss │ │ │ ├── black.scss │ │ │ ├── blood.scss │ │ │ ├── league.scss │ │ │ ├── moon.scss │ │ │ ├── night.scss │ │ │ ├── serif.scss │ │ │ ├── simple.scss │ │ │ ├── sky.scss │ │ │ ├── solarized.scss │ │ │ └── white.scss │ │ │ ├── template │ │ │ ├── mixins.scss │ │ │ ├── settings.scss │ │ │ └── theme.scss │ │ │ └── white.css │ ├── demo.html │ ├── index.html │ ├── js │ │ └── reveal.js │ ├── lib │ │ ├── css │ │ │ └── zenburn.css │ │ ├── font │ │ │ ├── league-gothic │ │ │ │ ├── LICENSE │ │ │ │ ├── league-gothic.css │ │ │ │ ├── league-gothic.eot │ │ │ │ ├── league-gothic.ttf │ │ │ │ └── league-gothic.woff │ │ │ └── source-sans-pro │ │ │ │ ├── LICENSE │ │ │ │ ├── source-sans-pro-italic.eot │ │ │ │ ├── source-sans-pro-italic.ttf │ │ │ │ ├── source-sans-pro-italic.woff │ │ │ │ ├── source-sans-pro-regular.eot │ │ │ │ ├── source-sans-pro-regular.ttf │ │ │ │ ├── source-sans-pro-regular.woff │ │ │ │ ├── source-sans-pro-semibold.eot │ │ │ │ ├── source-sans-pro-semibold.ttf │ │ │ │ ├── source-sans-pro-semibold.woff │ │ │ │ ├── source-sans-pro-semibolditalic.eot │ │ │ │ ├── source-sans-pro-semibolditalic.ttf │ │ │ │ ├── source-sans-pro-semibolditalic.woff │ │ │ │ └── source-sans-pro.css │ │ └── js │ │ │ ├── classList.js │ │ │ ├── head.min.js │ │ │ └── html5shiv.js │ ├── package.json │ ├── plugin │ │ ├── highlight │ │ │ └── highlight.js │ │ ├── markdown │ │ │ ├── example.html │ │ │ ├── example.md │ │ │ ├── markdown.js │ │ │ └── marked.js │ │ ├── math │ │ │ └── math.js │ │ ├── multiplex │ │ │ ├── client.js │ │ │ ├── index.js │ │ │ ├── master.js │ │ │ └── package.json │ │ ├── notes-server │ │ │ ├── client.js │ │ │ ├── index.js │ │ │ └── notes.html │ │ ├── notes │ │ │ ├── notes.html │ │ │ └── notes.js │ │ ├── print-pdf │ │ │ └── print-pdf.js │ │ ├── search │ │ │ └── search.js │ │ └── zoom-js │ │ │ └── zoom.js │ └── test │ │ ├── examples │ │ ├── assets │ │ │ ├── image1.png │ │ │ └── image2.png │ │ ├── barebones.html │ │ ├── embedded-media.html │ │ ├── math.html │ │ ├── slide-backgrounds.html │ │ └── slide-transitions.html │ │ ├── qunit-1.12.0.css │ │ ├── qunit-1.12.0.js │ │ ├── simple.md │ │ ├── test-markdown-element-attributes.html │ │ ├── test-markdown-element-attributes.js │ │ ├── test-markdown-external.html │ │ ├── test-markdown-external.js │ │ ├── test-markdown-options.html │ │ ├── test-markdown-options.js │ │ ├── test-markdown-slide-attributes.html │ │ ├── test-markdown-slide-attributes.js │ │ ├── test-markdown.html │ │ ├── test-markdown.js │ │ ├── test-pdf.html │ │ ├── test-pdf.js │ │ ├── test.html │ │ └── test.js └── slides.css └── watch.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle/ 2 | site/*.html 3 | site/*.pdf 4 | site/clojure 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | services: 4 | - docker 5 | 6 | before_install: 7 | - docker pull asciidoctor/docker-asciidoctor 8 | 9 | script: 10 | - docker run -v $TRAVIS_BUILD_DIR:/documents/ --name asciidoc-to-html asciidoctor/docker-asciidoctor /documents/build.sh 11 | 12 | after_error: 13 | - docker logs asciidoc-to-html 14 | 15 | after_failure: 16 | - docker logs asciidoc-to-html 17 | 18 | deploy: 19 | provider: pages 20 | local-dir: site 21 | target-branch: gh-pages 22 | skip-cleanup: true 23 | github-token: $GITHUB_TOKEN 24 | on: 25 | branch: master 26 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gem 'concurrent-ruby' 6 | gem 'asciidoctor' 7 | gem 'asciidoctor-revealjs' 8 | gem 'asciidoctor-pdf' 9 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | Ascii85 (1.0.3) 5 | addressable (2.8.0) 6 | public_suffix (>= 2.0.2, < 5.0) 7 | afm (0.2.2) 8 | asciidoctor (1.5.8) 9 | asciidoctor-pdf (1.5.0.alpha.16) 10 | asciidoctor (>= 1.5.0) 11 | prawn (>= 1.3.0, < 2.3.0) 12 | prawn-icon (= 1.3.0) 13 | prawn-svg (>= 0.21.0, < 0.28.0) 14 | prawn-table (= 0.2.2) 15 | prawn-templates (>= 0.0.3, <= 0.1.1) 16 | safe_yaml (~> 1.0.4) 17 | thread_safe (~> 0.3.6) 18 | treetop (= 1.5.3) 19 | asciidoctor-revealjs (1.1.3) 20 | asciidoctor (~> 1.5.6) 21 | thread_safe (~> 0.3.5) 22 | concurrent-ruby (1.0.5) 23 | css_parser (1.6.0) 24 | addressable 25 | hashery (2.1.2) 26 | pdf-core (0.7.0) 27 | pdf-reader (2.1.0) 28 | Ascii85 (~> 1.0.0) 29 | afm (~> 0.2.1) 30 | hashery (~> 2.0) 31 | ruby-rc4 32 | ttfunk 33 | polyglot (0.3.5) 34 | prawn (2.2.2) 35 | pdf-core (~> 0.7.0) 36 | ttfunk (~> 1.5) 37 | prawn-icon (1.3.0) 38 | prawn (>= 1.1.0, < 3.0.0) 39 | prawn-svg (0.27.1) 40 | css_parser (~> 1.3) 41 | prawn (>= 0.11.1, < 3) 42 | prawn-table (0.2.2) 43 | prawn (>= 1.3.0, < 3.0.0) 44 | prawn-templates (0.1.1) 45 | pdf-reader (~> 2.0) 46 | prawn (~> 2.2) 47 | public_suffix (4.0.6) 48 | ruby-rc4 (0.1.5) 49 | safe_yaml (1.0.4) 50 | thread_safe (0.3.6) 51 | treetop (1.5.3) 52 | polyglot (~> 0.3) 53 | ttfunk (1.5.1) 54 | 55 | PLATFORMS 56 | ruby 57 | 58 | DEPENDENCIES 59 | asciidoctor 60 | asciidoctor-pdf 61 | asciidoctor-revealjs 62 | concurrent-ruby 63 | 64 | BUNDLED WITH 65 | 1.16.1 66 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SOURCES := $(wildcard docs/*.adoc) 2 | HTML := $(patsubst docs/%.adoc, site/%.html, $(SOURCES)) 3 | PDF := $(patsubst docs/%.adoc, site/%.pdf, $(SOURCES)) 4 | CLOJURE_COURSE_SOURCES := $(wildcard docs/clojure/*.adoc) 5 | CLOJURE_COURSE := $(patsubst docs/clojure/%.adoc, site/clojure/%.html, $(CLOJURE_COURSE_SOURCES)) 6 | 7 | .PHONY: all clean setup 8 | 9 | all: setup $(HTML) $(PDF) $(CLOJURE_COURSE) 10 | 11 | clean: 12 | rm site/*.html site/*.pdf site/clojure/*.html 13 | 14 | setup: .bundle 15 | 16 | .bundle: 17 | bundle --path=.bundle/gems --binstubs=.bundle/.bin 18 | 19 | site/clojure/%.html: docs/clojure/%.adoc 20 | bundle exec asciidoctor-revealjs --destination-dir=site/clojure $< 21 | 22 | site/%.html: docs/%.adoc 23 | bundle exec asciidoctor --destination-dir=site $< 24 | 25 | site/%.pdf: docs/%.adoc 26 | bundle exec asciidoctor-pdf --destination-dir=site $< 27 | 28 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Enterprise Clojure Training 2 | 3 | > "Clojure is serious business!" -- Timothy Pratley 4 | 5 | A Clojure training course for Developers and Senior Developers working on Enterprise software. 6 | 7 | Please visit the https://timothypratley.github.io/enterprise-clojure-training[Website] to see the precompiled course material. 8 | 9 | A list of companies and individuals offering Clojure training is here https://clojure.org/community/training[this page]. 10 | 11 | 12 | == Rationale 13 | 14 | Clojure has been in the "adopt" zone of the Thoughtworks tech radar since 2014. 15 | But companies face the challenge of how to prepare their staff to be productive using Clojure. 16 | Creating a structured enterprise style course material will enable more people to offer Clojure courses suitable for companies wanting to adopt Clojure. 17 | 18 | 19 | == Usage 20 | 21 | Slides have https://github.com/hakimel/reveal.js/wiki/Keyboard-Shortcuts[Keyboard shortcuts]. 22 | 23 | 24 | == Contributing 25 | 26 | If you have suggestions on how to improve this course, I would love to hear them. 27 | Issues welcome. Pull requests welcome. 28 | 29 | 30 | == Developing 31 | 32 | The manual and slides source material are under the `docs` directory. 33 | The material is written in asciidoc (.adoc) format, which gets compiled to HTML and PDF. 34 | They are built to HTML and PDF using https://asciidoctor.org[Asciidoctor], and output to the `site` directory. 35 | Refer to the https://asciidoctor.org/docs/asciidoc-writers-guide[Writer's Guide] for syntax. 36 | Asciidoctor provides excellent document producing features and allows slides to be generated as RevealJS slideshows. 37 | 38 | When editing the material, there are many live preview tools to chooose from https://asciidoctor.org/docs/editing-asciidoc-with-live-preview[here]. 39 | I use the IntelliJ plugin as it is simple to install and works well. 40 | There is also a `./watch.sh` command to build when the source file changes. 41 | The Web (Epiphany) browser reloads from disk when the HTML file changes. 42 | 43 | 44 | === Building 45 | 46 | The easiest way to build is to run 47 | 48 | ./bb.sh 49 | 50 | This script relies on bundler (See The Ruby way for more info). 51 | It will install dependencies and build the documents into html/pdf. 52 | 53 | 54 | === With installed CLI tools. 55 | 56 | You can install asciidoctor, asciidoctor-pdf, and ascidoctor-revealjs locally and run 57 | 58 | ./build.sh 59 | 60 | But installing these tools is a bit of a pain... so two ways to get the dependencies are provided: 61 | 62 | 63 | ==== The Ruby way 64 | 65 | Requires https://www.ruby-lang.org/en/documentation/installation[Ruby]. 66 | 67 | You don't need to install Asciidoctor. 68 | Asciidoctor is a dependency specified in the Gemfile. 69 | However you will need Ruby and Bundler to pull down the Asciidoctor and RevealJS plugin dependencies. 70 | 71 | Requires Bundler: 72 | 73 | gem install bundler 74 | 75 | Pull the dependencies: 76 | 77 | bundle --path=.bundle/gems --binstubs=.bundle/.bin 78 | 79 | Now you can call the build script: 80 | 81 | bundle exec ./build.sh 82 | 83 | The `./bb.sh` just does these two steps for you. 84 | 85 | 86 | === Rebuild on file modified 87 | 88 | To have the build watch for file changes and rebuild automatically: 89 | 90 | ./watch.sh 91 | 92 | You need `entr` (Event Notify Test Runner) installed for watch to work, I highly recomend it. 93 | 94 | brew install entr 95 | 96 | Or 97 | 98 | apt install entr 99 | 100 | 101 | ==== The Docker way 102 | 103 | Alternatively, if you prefer pulling a Docker image over installing dependencies: 104 | 105 | docker run -v $(pwd):/documents/ asciidoctor/docker-asciidoctor /documents/build.sh 106 | 107 | 108 | == Deploying 109 | 110 | TravisCI automatically deploys the latest version to https://timothypratley.github.io/enterprise-clojure-training[GitHub Pages]. 111 | image:https://travis-ci.org/timothypratley/enterprise-clojure-training.svg?branch=master[Build Status, link=https://travis-ci.org/timothypratley/enterprise-clojure-training] 112 | 113 | Manual deployment: 114 | 115 | ./deploy.sh 116 | -------------------------------------------------------------------------------- /bb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # get dependencies 5 | if [ ! -d .bundle ]; then 6 | bundle --path=.bundle/gems --binstubs=.bundle/.bin 7 | fi 8 | 9 | # build with dependencies 10 | bundle exec ./build.sh 11 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | FLAGS=--destination-dir=site 4 | 5 | asciidoctor ${FLAGS} docs/index.adoc docs/manual.adoc docs/getting-help.adoc docs/setup.adoc 6 | asciidoctor-pdf ${FLAGS} docs/manual.adoc 7 | asciidoctor-revealjs ${FLAGS} docs/advanced-topics.adoc docs/advanced-topics.adoc docs/talk.adoc 8 | asciidoctor-revealjs --destination-dir=site/clojure docs/clojure/*.adoc 9 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | cd $(dirname $0) 4 | ./build.sh 5 | cd site 6 | git init 7 | git add . 8 | git commit -m "Deploy to GitHub Pages" 9 | git push --force --quiet "git@github.com:timothypratley/enterprise-clojure-training.git" master:gh-pages 10 | rm -fr .git 11 | echo "Deployed to https://timothypratley.github.io/enterprise-clojure-training" 12 | -------------------------------------------------------------------------------- /docs/clojure/0-introduction.adoc: -------------------------------------------------------------------------------- 1 | = Enterprise Clojure Training 2 | :copyright: Timothy Pratley 3 | :license: Eclipse Public License http://www.eclipse.org/legal/epl-v10.html 4 | include::slide.attrs[] 5 | 6 | 7 | [state=title] 8 | == Enterprise Clojure Training 9 | 10 | image:../img/corgi.jpg[] 11 | 12 | 13 | [state=title] 14 | == Contents 15 | 16 | [cols=4] 17 | |=== 18 | |link:1-ecosystem.html[Ecosystem] 19 | |link:2-syntax.html[Syntax] 20 | |link:3-functions.html[Functions] 21 | |link:4-testing.html[Testing] 22 | |link:5-control-flow.html[Control Flow] 23 | |link:6-functional-programming.html[Functional Programming] 24 | |link:7-java-interop.html[Java Interop] 25 | |link:8-concurrency.html[Concurrency] 26 | |link:9-polymorphism.html[Polymorphism] 27 | |link:10-databases[Databases] 28 | |link:11-spec.html[Spec] 29 | |link:12-macros.html[Macros] 30 | |link:13-further-reading.html[Further reading] 31 | | 32 | | 33 | | 34 | |=== 35 | 36 | 37 | [state=title] 38 | == Introductions 39 | 40 | image:../img/art1.jpg[] 41 | 42 | [state=title] 43 | == Clojure 44 | 45 | image:../img/clojure-logo.png[] 46 | 47 | "What language is it that meets all the criteria? What language would I choose if I had to choose today? Probably Clojure!" 48 | -- Robert Martin 49 | 50 | 51 | == Clojure 52 | 53 | * Data 54 | * Functions 55 | * A tool for thought 56 | * Getting stuff done 57 | 58 | 59 | == End Introduction 60 | 61 | link:0-introduction.html#contents[Contents] 62 | 63 | link:2-syntax.html[Next Topic: 1 - Ecosystem] 64 | -------------------------------------------------------------------------------- /docs/clojure/1-ecosystem.adoc: -------------------------------------------------------------------------------- 1 | = Enterprise Clojure Training 2 | :copyright: Timothy Pratley 3 | :license: Eclipse Public License http://www.eclipse.org/legal/epl-v10.html 4 | include::slide.attrs[] 5 | 6 | 7 | [state=title] 8 | == 1. The Clojure Ecosystem 9 | 10 | image:../img/ecosystem.jpg[] 11 | 12 | "Integrity is an ecosystem." 13 | -- Michael Leunig 14 | 15 | [NOTE.speaker] 16 | -- 17 | Benefits of embracing the JVM as a host 18 | -- 19 | 20 | 21 | == Dependencies 22 | 23 | * Libraries are plain old jars 24 | * Clojure is itself a jar 25 | * Clojure can make direct use of other jars 26 | * Easy to deploy 27 | * Leiningen 28 | 29 | 30 | == Leiningen 31 | 32 | lein new training 33 | cd training 34 | tree 35 | cat project.clj 36 | cat src/training/core.clj 37 | 38 | 39 | == tree 40 | 41 | . 42 | ├── CHANGELOG.md 43 | ├── doc 44 | │   └── intro.md 45 | ├── LICENSE 46 | ├── project.clj 47 | ├── README.md 48 | ├── resources 49 | ├── src 50 | │   └── training 51 | │   └── core.clj 52 | └── test 53 | └── training 54 | └── core_test.clj 55 | 56 | 57 | == project.clj 58 | 59 | [source, clojure] 60 | (defproject training "0.1.0-SNAPSHOT" 61 | :description "FIXME: write description" 62 | :url "http://example.com/FIXME" 63 | :license 64 | {:name "Eclipse Public License" 65 | :url "http://www.eclipse.org/legal/epl-v10.html"} 66 | :dependencies [[org.clojure/clojure "1.8.0"]]) 67 | 68 | 69 | == src/training/core.clj 70 | 71 | [source, clojure] 72 | ---- 73 | (ns training.core) 74 | 75 | (defn foo 76 | "I don't do a whole lot." 77 | [x] 78 | (println x "Hello, World!")) 79 | ---- 80 | 81 | 82 | == The Read Eval Print Loop (REPL) 83 | 84 | [source, console] 85 | $ lein repl 86 | 87 | We type in an expression: 88 | 89 | [source, clojure] 90 | (+ 1 2) 91 | 92 | Clojure returns a result: 93 | 94 | [source, clojure] 95 | => 3 96 | 97 | NOTE: `=>` means evaluates to 98 | 99 | 100 | [NOTE.speaker] 101 | -- 102 | * evaluates 103 | * compiles 104 | * change program definitions on the fly 105 | * try things 106 | * answer questions 107 | -- 108 | 109 | 110 | == Editor setup 111 | 112 | * IntelliJ IDEA + Cursive 113 | * Wide range of editor support options 114 | 115 | [NOTE.speaker] 116 | -- 117 | * https://www.jetbrains.com/idea 118 | * https://cursive-ide.com 119 | * Focus on Clojure first, editors later 120 | -- 121 | 122 | 123 | == Exercises 124 | 125 | See manual end of section 1 126 | 127 | 128 | == Answers a 129 | 130 | [source.eval-clojure, clojure] 131 | (+ 2 3) 132 | ;=> 5 133 | 134 | [source.eval-clojure, clojure] 135 | (* 31 79) 136 | ;=> 2449 137 | 138 | [source.eval-clojure, clojure] 139 | (/ 10 2) 140 | ;=> 5 141 | 142 | [source.eval-clojure, clojure] 143 | (/ 2 10) 144 | ;=> 1/5 145 | 146 | 147 | == Answers b 148 | 149 | [source.eval-clojure, clojure] 150 | (+ 1 2 3) 151 | ;=> 6 152 | 153 | [.eval-clojure] 154 | (println "hello world") 155 | ;=> "hello world" 156 | 157 | [source.eval-clojure, clojure] 158 | (* 5 4 3 2 1) 159 | ;=> 120 160 | 161 | == End Ecosystem 162 | 163 | link:0-introduction.html#contents[Contents] 164 | 165 | link:2-syntax.html[Next Topic: 2 - Syntax] 166 | -------------------------------------------------------------------------------- /docs/clojure/10-databases.adoc: -------------------------------------------------------------------------------- 1 | = Enterprise Clojure Training 2 | :copyright: Timothy Pratley 3 | :license: Eclipse Public License http://www.eclipse.org/legal/epl-v10.html 4 | include::slide.attrs[] 5 | 6 | 7 | [state=title] 8 | == 10. Interacting with a Database 9 | 10 | image:../img/database.jpg[] 11 | 12 | "You can have data without information, but you cannot have information without data." 13 | -- Daniel Keys Moran 14 | 15 | 16 | == clojure.java.jdbc 17 | 18 | $ lein new messenger 19 | 20 | `project.clj` dependencies: 21 | 22 | [org.clojure/java.jdbc "0.7.5"] 23 | [hsqldb/hsqldb "1.8.0.10"] 24 | 25 | NOTE: we need the driver we plan to use to connect to a database 26 | 27 | 28 | == Connecting 29 | 30 | Require `jdbc` and configure a db connection url 31 | 32 | (ns messenger.core 33 | (:require [clojure.java.jdbc :as jdbc])) 34 | 35 | (def db "jdbc:hsqldb:mem:testdb") 36 | 37 | 38 | == Inserting 39 | 40 | Create a table called testing 41 | 42 | (jdbc/execute! db 43 | "create table messages (message varchar(1024))") 44 | 45 | Insert some rows 46 | 47 | (jdbc/insert-multi! db :messages 48 | [{:message "Hello World"} 49 | {:message "How now?"}]) 50 | 51 | 52 | == Querying 53 | 54 | (jdbc/query db ["select * from messages"]) 55 | => ({:message "Hello World"} 56 | {:message "How now?"}) 57 | 58 | 59 | == Deleting 60 | 61 | To selectively delete some data: 62 | 63 | (jdbc/delete! db :messages ["message like '%World%'"]) 64 | (jdbc/query db ["select * from messages"]) 65 | => ({:message "How now?"}) 66 | 67 | Now there is only one row remaining 68 | 69 | 70 | == insert-multi! 71 | 72 | (jdbc/insert-multi! db :messages 73 | [{:message "Nobody panic!!!"} 74 | {:message "What in the world?"} 75 | {:message "All is well."}]) 76 | 77 | 78 | == Parameterized query 79 | 80 | (defn search [s] 81 | (jdbc/query db 82 | ["select * from messages where message like ?" s])) 83 | 84 | (search "%How%") 85 | => ({:message "How now?"}) 86 | 87 | * String concatenation is susceptible to SQL injection 88 | * Parameters are not part of the query; cannot perform SQL from malicious input 89 | 90 | 91 | == Starting fresh 92 | 93 | If you want to redo any steps, remember that you can always drop the table and start again 94 | 95 | (jdbc/execute! db "drop table messages") 96 | 97 | 98 | == Solutions for SQL management 99 | 100 | HoneySQL can be used to build SQL statements from data structures. 101 | 102 | [NOTE.speaker] 103 | -- 104 | * https://github.com/jkk/honeysql 105 | * Useful to programmatically combine clauses to produce a final SQL statement 106 | * For example, user can check a checkbox to enable an additional clause in a search 107 | * Convenient to use Clojure's capabilities for manipulating data structures 108 | * If you do not need to do manipulation, I recommend using string SQL queries 109 | * It's easier to run string SQL interactively from a prompt 110 | -- 111 | 112 | 113 | == Exercises 114 | 115 | See manual end of section 11 116 | 117 | 118 | == Answers 119 | 120 | (ns messenger.core 121 | (:require [clojure.java.jdbc :as jdbc])) 122 | 123 | (def db "jdbc:hsqldb:mem:testdb") 124 | 125 | (jdbc/execute! db 126 | "create table person (id bigint, name varchar(1024))") 127 | (jdbc/execute! db 128 | "create table policy (id bigint, name varchar(1024))") 129 | (jdbc/execute! db 130 | "create table person_policy 131 | (person_id bigint, policy_id bigint)") 132 | 133 | 134 | == Answers 135 | 136 | (jdbc/insert-multi! db :person 137 | [{:id 1 :name "Sally"} 138 | {:id 2 :name "Billy"}]) 139 | (jdbc/insert-multi! db :policy 140 | [{:id 1 :name "Corgi Cover"} 141 | {:id 2 :name "Poodle Protection"}]) 142 | (jdbc/insert-multi! db :person_policy 143 | [{:person_id 1 :policy_id 1} 144 | {:person_id 1 :policy_id 2} 145 | {:person_id 2 :policy_id 1}]) 146 | 147 | 148 | == Answers 149 | 150 | (defn find-policies [person-name] 151 | (jdbc/query db ["select a.name from policy a 152 | inner join person_policy b on a.id = b.policy_id 153 | inner join person c on b.person_id = c.id 154 | where c.name = ?" 155 | person-name])) 156 | 157 | (find-policies "Sally") 158 | => ({:name "Corgi Cover"} {:name "Poodle Protection"}) 159 | (find-policies "Jane") 160 | => () 161 | (find-policies "Billy") 162 | => ({:name "Corgi Cover"}) 163 | 164 | 165 | == Challenge 4: Corgi Cover Database 166 | 167 | Sending files around is proving to be problematic. Sometimes applications are lost or the results of the eligibility check are not communicated back to the customer. You have been tasked with creating a central source of truth that can be queried as to what applications have been submitted and processed. 168 | 169 | 170 | == Part 1: Set up the schema 171 | 172 | Using the database of your choice, set up an initial database for the Corgi Cover project. In the code, connect to the database and create the initial table required. You can use whatever schema you like, but the first requirement is to store the applications with exactly the same data as was retrieved from the file format in Challenge 2. 173 | 174 | 175 | == Part 2: Populate the data 176 | 177 | Modify the code to store the applications as they are processed, and the result of the eligibility check. 178 | 179 | 180 | == Part 3: Write a spec 181 | 182 | Ensure that all records processed from the files meets your expectations for required fields. Write a spec that explicitly defines what should be in the applications. Validate the spec on the incoming records. 183 | 184 | 185 | == Part 4: Extending to Poodle Protection 186 | 187 | Insuricorp is about to launch a new policy called “Poodle Protection”. Soon they will be processing applications with completely new rules. Set up a multimethod to handle “Poodle Protection” applications differently from “Corgi Cover” applications. For now the only difference with the rules from “Corgi Cover” is that “Poodle Protection” is available in different states: California (CA), Florida (FL), Wyoming (WY), and Hawaii (HI). 188 | 189 | 190 | == End Databases 191 | 192 | link:0-introduction.html#contents[Contents] 193 | 194 | link:11-spec.html[Next Topic: 11 - Spec] 195 | -------------------------------------------------------------------------------- /docs/clojure/13-further-reading.adoc: -------------------------------------------------------------------------------- 1 | = Enterprise Clojure Training 2 | :copyright: Timothy Pratley 3 | :license: Eclipse Public License http://www.eclipse.org/legal/epl-v10.html 4 | include::slide.attrs[] 5 | 6 | 7 | [state=title] 8 | == 13. Further reading 9 | 10 | image:../img/further-reading.jpg[] 11 | 12 | "You can never get a cup of tea large enough or a book long enough to suit me." 13 | -- C.S. Lewis 14 | 15 | 16 | == Further reading 17 | 18 | Further exercises: https://www.4clojure.com/ 19 | 20 | Clojure for Java Programmers - Rich Hickey 21 | 22 | * Part 1: https://www.youtube.com/watch?v=P76Vbsk_3J0 23 | * Part 2: https://www.youtube.com/watch?v=hb3rurFxrZ8 24 | 25 | [NOTE.speaker] 26 | -- 27 | * Writing Clojure code requires more thinking and less typing than other languages 28 | * Don't feel frustrated if the code comes slowly at first 29 | * Being a great programmer requires thinking 30 | * You will only reach your true potential expressing code in ways that empower you rather than constrain you 31 | -- 32 | 33 | 34 | == Best practices 35 | 36 | * Write tests 37 | * Write expectation strings for tests 38 | * Use lein-test-refresh 39 | * Keep functions short and focused 40 | - Extract sub functions 41 | - Compose functions 42 | 43 | 44 | == Best practices 45 | 46 | * Keep namespaces short and focused 47 | - Extract related functions into new namespaces 48 | - Write doc-strings for namespaces 49 | * Write doc-strings for functions 50 | * Write doc-strings for defs when appropriate 51 | * Follow the Clojure style guide 52 | 53 | 54 | == Tips 55 | 56 | * Build bottom up 57 | * Start with data 58 | * Create functions to operated on that data 59 | * Eastwood can give hints on better expressions 60 | * Read source code (Clojure, libraries, open source projects) 61 | 62 | 63 | == Tips 64 | 65 | * Most problems can be solved with a function 66 | * Scientific method: 67 | - Think of things that could possibly be wrong 68 | - Isolate a small test case 69 | - Test one hypothesis at a time 70 | * Finding Clojure libraries https://www.clojure-toolbox.com/ 71 | 72 | 73 | == Workflow 74 | 75 | * Editor + Test refresh + REPL 76 | * Reading stacktraces 77 | ** Try line 1 78 | ** Scan down for your namespace 79 | * Small functions 80 | * Test as you go 81 | * Print things 82 | * Test assumptions/hypothesis 83 | 84 | 85 | == Editor customization 86 | 87 | * After you feel comfortable with Clojure 88 | * Paredit 89 | * Parinfer 90 | * Send file to REPL 91 | * Send form to REPL 92 | 93 | 94 | == Learn the many Clojure functions 95 | 96 | * Set aside some recuring time to bite of bits of the API 97 | * Clojure word of the day: https://clojure.me 98 | 99 | 100 | == Read Clojure code 101 | 102 | * Clojure source 103 | * Clojure libraries 104 | * Open source projects 105 | * Check the source on anything new you use 106 | 107 | 108 | == Style guide 109 | 110 | https://github.com/bbatsov/clojure-style-guide 111 | 112 | 113 | == Eastwood 114 | 115 | Produces suggestions on how to write idiomatic Clojure 116 | 117 | `$HOME/.lein/profiles.clj` 118 | 119 | {:user {:plugins [[jonase/eastwood "0.2.5"]]}} 120 | 121 | $ lein eastwood 122 | 123 | 124 | == Get help 125 | 126 | * REPL can answer most questions 127 | * StackOverflow.com #clojure 128 | * Create minimal examples 129 | * Clojure mailing list https://groups.google.com/forum/#!forum/clojure 130 | * ClojureVerse https://clojureverse.org 131 | * Clojurians Slack http://clojurians.net 132 | 133 | 134 | == Practice 135 | 136 | * Challenges 1-4 137 | * Small projects 138 | * 4Clojure problems http://www.4clojure.com 139 | * Project Euler https://projecteuler.net 140 | * Katas 141 | 142 | 143 | [state=title] 144 | == Thank you 145 | 146 | timothypratley@gmail.com 147 | 148 | https://timothypratley.blogspot.com 149 | 150 | @timothypratley 151 | 152 | 153 | == End Further Reading 154 | 155 | link:0-introduction.html#contents[Contents] 156 | -------------------------------------------------------------------------------- /docs/clojure/5-control-flow.adoc: -------------------------------------------------------------------------------- 1 | = Enterprise Clojure Training 2 | :copyright: Timothy Pratley 3 | :license: Eclipse Public License http://www.eclipse.org/legal/epl-v10.html 4 | include::slide.attrs[] 5 | 6 | 7 | [state=title] 8 | == 5. Control Flow 9 | 10 | image:../img/control.jpg[] 11 | 12 | "Control your own destiny or someone else will." 13 | -- Jack Welch 14 | 15 | 16 | == Conditionals: if 17 | 18 | [source.eval-clojure, clojure] 19 | (if (pos? 1) 20 | "one is positive" 21 | "or is it?") 22 | ;=> "one is positive" 23 | 24 | * Chooses between two options 25 | * Returns a result 26 | * Only one branch is evaluated 27 | * A function call evaluates all arguments 28 | 29 | 30 | == Truthiness 31 | 32 | * Booleans: `true` and `false` 33 | * `nil` means nothing and is considered false in logical tests 34 | * Anything else is truthy 35 | 36 | [source.eval-clojure, clojure] 37 | (if 5 38 | "it's five!" 39 | "no problem") 40 | ;=> "it's five!" 41 | 42 | 43 | == Use do to group multiple statements 44 | 45 | [source.eval-clojure, clojure] 46 | (if (pos? 1) 47 | (do (prn "hi") 48 | "one is positive") 49 | "or is it?") 50 | ;;; "hi" 51 | ;=> "one is positive" 52 | 53 | 54 | == Conditionals: when 55 | 56 | [source.eval-clojure, clojure] 57 | (when (pos? 1) 58 | (prn "multiple expressions allowed") 59 | :ok) 60 | ;;; multiple expressions allowed 61 | ;=> :ok 62 | 63 | * When test fails, nothing is evaluated 64 | * When test passes, the entire body is evaluated 65 | * Returns the last expression as a result 66 | 67 | 68 | == Conditionals: cond 69 | 70 | [source.eval-clojure, clojure] 71 | (def x {:cake 1}) 72 | (cond (= x 1) "one" 73 | (= x :cake) "the cake is a lie" 74 | (map? x) "it's a map!" 75 | :else "not sure what it is") 76 | ;=> "it's a map!" 77 | 78 | * Multiple branches 79 | * `:else` is not special, keywords are truthy 80 | * See also `condp` and `case` 81 | 82 | 83 | == Conditionals are special forms 84 | 85 | Built in primitives, not functions 86 | 87 | `def`, `let`, `quote` and `fn` are special forms 88 | 89 | Arguments are not evaluated 90 | 91 | [source.eval-clojure, clojure] 92 | (if (= 1 2) 93 | (prn "a") 94 | (prn "b")) 95 | ;;; "b" 96 | ;=> nil 97 | 98 | 99 | == Reminder: functions evaluate all arguments 100 | 101 | [source.eval-clojure, clojure] 102 | (defn if-fn [condition a b] 103 | (if condition a b)) 104 | (if-fn (= 1 2) 105 | (prn "a") 106 | (prn "b")) 107 | ;;; a 108 | ;;; b 109 | ;=> nil 110 | 111 | 112 | == Macros are also special 113 | 114 | `or` is a macro 115 | 116 | [source.eval-clojure, clojure] 117 | (or true (println "Hello")) 118 | ;=> true 119 | 120 | Arguments are not evaluated 121 | 122 | Macros are used to implement and extend Clojure syntax 123 | 124 | 125 | == Macros replace forms at compile time 126 | 127 | (or true false) 128 | 129 | Expands to: 130 | 131 | (let [a true] 132 | (if a 133 | a 134 | (let [b false] 135 | (if b 136 | b))))) 137 | 138 | 139 | == Macros and special forms are not functions 140 | 141 | [source.eval-clojure, clojure] 142 | (apply or [true false true]) 143 | ;;; CompilerException: Can't take value of a macro 144 | 145 | 146 | [source.eval-clojure, clojure] 147 | (apply if [true :a :b]) 148 | ;;; CompilerException: Unable to resolve symbol: if 149 | 150 | WARNING: Macros cannot be passed as arguments to functions 151 | 152 | 153 | == Identifying special forms and macros 154 | 155 | * Remember the special forms: 156 | `if`, `do`, `let`, `quote`, `var`, `fn`, `loop`, `recur`, `throw`, `try` 157 | * Control flow forms: `cond`, `or`, `and`, `when` 158 | * Navigate to source: `def`, `defn`, `defmacro` 159 | * See `:macro` in Metadata 160 | * Documentation 161 | 162 | NOTE: Writing macros is covered later in the course 163 | 164 | 165 | == Recursion 166 | 167 | (defn sum-up [coll result] 168 | (if (empty? coll) 169 | result 170 | (sum-up (rest coll) 171 | (+ result (first coll))))) 172 | 173 | Functions that invoke themselves are recursive 174 | 175 | 176 | == Tail Call Optimization 177 | 178 | Recursion without consuming the stack 179 | 180 | (defn sum-up-with-recur [coll result] 181 | (if (empty? coll) 182 | result 183 | (recur (rest coll) (+ result (first coll))))) 184 | 185 | * Recur can only occur where a function returns 186 | * Current frame will return the result of the next call 187 | * No further calculations needed 188 | * Current frame can be released 189 | 190 | 191 | == Loops 192 | 193 | (loop [a 0 194 | b 1] 195 | (if (< b 1000) 196 | (recur b (+ a b)) 197 | a)) 198 | 199 | * Loop establishes bindings 200 | * Allows recur to the start of the loop 201 | 202 | 203 | == Exception handling 204 | 205 | Special forms `try` `catch` `finally` and `throw` 206 | 207 | (try 208 | (inc "cat") 209 | (catch Exception e 210 | (println "cat cannot be incremented")) 211 | (finally 212 | (println "always")) 213 | 214 | 215 | == Exercises 216 | 217 | See manual end of section 5 218 | 219 | 220 | == Answers 221 | 222 | (def grade [score] 223 | (cond (>= score 90) "A" 224 | (>= score 80) "B" 225 | (>= score 70) "C" 226 | (>= score 60) "D" 227 | :else "F")) 228 | 229 | (deftest grade-test 230 | (is (= "B" (grade 85)))) 231 | 232 | 233 | == Answers 234 | 235 | (defn factorial [n] 236 | (loop [acc 1 237 | x n] 238 | (if (<= x 1) 239 | acc 240 | (recur (* acc x) (dec x))))) 241 | 242 | (deftest factorial-test 243 | (is (= 120 (factorial 5)))) 244 | 245 | 246 | == Answers 247 | 248 | (defn factorial2 249 | ([n] (factorial2 1 n)) 250 | ([acc n] 251 | (if (<= n 1) 252 | acc 253 | (recur (* acc n) (dec n))))) 254 | 255 | (deftest factorial2-test 256 | (is (= 120 (factorial2 5)))) 257 | 258 | 259 | == Answers 260 | 261 | (defn fib [limit] 262 | (loop [a 1 263 | b 1] 264 | (if (>= b limit) 265 | a 266 | (recur b (+ a b))))) 267 | 268 | (deftest fib-test 269 | (is (= 89 (fib 100)))) 270 | 271 | 272 | == End Control Flow 273 | 274 | link:0-introduction.html#contents[Contents] 275 | 276 | link:6-functional-programming.html[Next Topic: 6 - Functional Programming] 277 | -------------------------------------------------------------------------------- /docs/clojure/7-java-interop.adoc: -------------------------------------------------------------------------------- 1 | = Enterprise Clojure Training 2 | :copyright: Timothy Pratley 3 | :license: Eclipse Public License http://www.eclipse.org/legal/epl-v10.html 4 | include::slide.attrs[] 5 | 6 | 7 | [state=title] 8 | == 7. Java Interop 9 | 10 | image:../img/interop.jpg[] 11 | 12 | "Sitting in my favorite coffeehouse with a new notebook and a hot cup of java is my idea of Heaven." 13 | -- Libba Bray 14 | 15 | 16 | == Clojure syntax for Java constructors 17 | 18 | (ns training.core 19 | (:import (java.util Date))) 20 | 21 | (Date.) 22 | (Date. 2018 02 17) 23 | 24 | Which is equivalent to the less used variant: 25 | 26 | (new Date) 27 | (new Date 2018 02 17) 28 | 29 | 30 | == Calling methods on a Java object 31 | 32 | (.length "hello world") 33 | (.isDirectory (java.io.File. "my-dir")) 34 | 35 | Equivalent to the less used variant: 36 | 37 | (. "hello world" length) 38 | (. (java.io.File. "my-dir") isDirectory) 39 | 40 | 41 | == Static and inner 42 | 43 | Java static method calls: 44 | 45 | (Math/pow 1 2) 46 | (.print System/out "hi") 47 | 48 | Inner classes: 49 | 50 | java.nio.channels.FileChannel$MapMode/READ_ONLY 51 | 52 | 53 | == Initializing objects with doto 54 | 55 | (ns training.core 56 | (:import (java.util HashMap))) 57 | (doto (HashMap.) 58 | (.put "a" 1) 59 | (.put "b" 2)) 60 | => {"a" 1, "b" 2} 61 | 62 | We get the constructed object, with side-effects applied 63 | 64 | 65 | == reify 66 | 67 | `reify` creates an object that conforms to an interface: 68 | 69 | (.listFiles (java.io.File. ".") 70 | (reify 71 | java.io.FileFilter 72 | (accept [this f] 73 | (.isDirectory f)))) 74 | 75 | Notice that we did not define a class? 76 | 77 | 78 | == gen-class and proxy 79 | 80 | `gen-class` creates a class. 81 | 82 | `proxy` extends a concrete superclass. 83 | 84 | Rarely needed, refer to manual. 85 | 86 | 87 | == Including Java classes in Clojure projects 88 | 89 | You can define Java classes in Java in a separate directory and add 90 | 91 | :java-source-paths ["java-src"] 92 | 93 | To your `project.clj` file 94 | 95 | lein compile 96 | 97 | Java code in that directory will be usable from Clojure 98 | 99 | 100 | == End Java Interop 101 | 102 | link:0-introduction.html#contents[Contents] 103 | 104 | link:8-concurrency.html[Next Topic: 8 - Concurrency] 105 | -------------------------------------------------------------------------------- /docs/clojure/docinfo-footer.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /docs/clojure/docinfo-header.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/clojure/docinfo.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/clojure/slide.attrs: -------------------------------------------------------------------------------- 1 | :customcss: ../slides.css 2 | :revealjs_theme: simple 3 | :revealjs_center: false 4 | :revealjs_controls: false 5 | :revealjs_transition: none 6 | :revealjs_history: true 7 | :revealjs_minScale: 1.0 8 | :revealjs_maxScale: 1.0 9 | :revealjsdir: ../reveal.js 10 | :docinfo: shared 11 | :notitle: 12 | :icons: font 13 | -------------------------------------------------------------------------------- /docs/docinfo-footer.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /docs/docinfo-header.html: -------------------------------------------------------------------------------- 1 | docinfo.html -------------------------------------------------------------------------------- /docs/docinfo.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/getting-help.adoc: -------------------------------------------------------------------------------- 1 | = Getting Help 2 | 3 | * A REPL can answer most questions :) 4 | * https://stackoverflow.com/questions/tagged/clojure[StackOverflow #clojure] 5 | * https://clojureverse.org[ClojureVerse] 6 | * https://groups.google.com/forum/#!forum/clojure[Clojure mailing list] 7 | * http://clojurians.net[Clojurians Slack] 8 | * https://timothypratley.github.io/enterprise-clojure-training/forum[Enterprise Clojure Training Forum] 9 | * Create minimal examples to illustrate your question and you'll get better responses 10 | * Email me timothypratley@gmail.com; I want to hear from you! 11 | -------------------------------------------------------------------------------- /docs/img: -------------------------------------------------------------------------------- 1 | ../site/img/ -------------------------------------------------------------------------------- /docs/index.adoc: -------------------------------------------------------------------------------- 1 | = Enterprise Clojure Training 2 | :docinfo: shared 3 | 4 | "Clojure is serious business!" 5 | -- Timothy Pratley 6 | 7 | This is a Clojure training course for Developers and Senior Developers working on enterprise software. 8 | 9 | * link:manual.html[Manual HTML] 10 | * link:manual.pdf[Manual PDF] 11 | * link:clojure/0-introduction.html[Course Slides] 12 | * link:advanced-topics.html[Advanced topics slides] 13 | * https://github.com/timothypratley/enterprise-clojure-training/tree/master/examples[Examples source code] 14 | * https://github.com/timothypratley/enterprise-clojure-training[Course Github] 15 | * link:getting-help.html[Getting help] 16 | 17 | image:img/corgi.jpg[Corgi] 18 | -------------------------------------------------------------------------------- /examples/aot/README.adoc: -------------------------------------------------------------------------------- 1 | WAR files for web applications and JAR files for command-line or custom server or background processes. 2 | The default behaviour of Leingingen is to compile the entry points and all related code. 3 | This can cause inconsistent and undesirable Clojure behavior, 4 | and is also somewhat slow and often unnecessary otherwise. 5 | There are ways to avoid AOT. 6 | -------------------------------------------------------------------------------- /examples/aot/little-aot/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | -------------------------------------------------------------------------------- /examples/aot/little-aot/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | lein uberjar 3 | java -jar ./target/little-aot-0.1.0-SNAPSHOT-standalone.jar 4 | -------------------------------------------------------------------------------- /examples/aot/little-aot/README.md: -------------------------------------------------------------------------------- 1 | # little-aot 2 | 3 | A Clojure library designed to ... well, that part is up to you. 4 | 5 | ## Usage 6 | 7 | FIXME 8 | 9 | ## License 10 | 11 | Copyright © 2018 FIXME 12 | 13 | Distributed under the Eclipse Public License either version 1.0 or (at 14 | your option) any later version. 15 | -------------------------------------------------------------------------------- /examples/aot/little-aot/project.clj: -------------------------------------------------------------------------------- 1 | (defproject little-aot "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :main little-aot.bootstrap 7 | :aot [little-aot.bootstrap] 8 | :dependencies [[org.clojure/clojure "1.8.0"]]) 9 | -------------------------------------------------------------------------------- /examples/aot/little-aot/src/little_aot/bootstrap.clj: -------------------------------------------------------------------------------- 1 | (ns little-aot.bootstrap 2 | (:gen-class)) 3 | 4 | (defn -main [& args] 5 | (require (symbol "little-aot.core")) 6 | ((resolve (symbol "little-aot.core" "-main")))) 7 | -------------------------------------------------------------------------------- /examples/aot/little-aot/src/little_aot/core.clj: -------------------------------------------------------------------------------- 1 | (ns little-aot.core 2 | (:require [little-aot.dont-aot-me])) 3 | 4 | (defn -main [& args] 5 | (println "Hello, World!")) 6 | -------------------------------------------------------------------------------- /examples/aot/little-aot/src/little_aot/dont_aot_me.clj: -------------------------------------------------------------------------------- 1 | (ns little-aot.dont-aot-me) 2 | 3 | (println "This should be printed at runtime, not during compile") 4 | -------------------------------------------------------------------------------- /examples/aot/no-aot/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | -------------------------------------------------------------------------------- /examples/aot/no-aot/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). 3 | 4 | ## [Unreleased] 5 | ### Changed 6 | - Add a new arity to `make-widget-async` to provide a different widget shape. 7 | 8 | ## [0.1.1] - 2018-04-18 9 | ### Changed 10 | - Documentation on how to make the widgets. 11 | 12 | ### Removed 13 | - `make-widget-sync` - we're all async, all the time. 14 | 15 | ### Fixed 16 | - Fixed widget maker to keep working when daylight savings switches over. 17 | 18 | ## 0.1.0 - 2018-04-18 19 | ### Added 20 | - Files from the new template. 21 | - Widget maker public API - `make-widget-sync`. 22 | 23 | [Unreleased]: https://github.com/your-name/no-aot/compare/0.1.1...HEAD 24 | [0.1.1]: https://github.com/your-name/no-aot/compare/0.1.0...0.1.1 25 | -------------------------------------------------------------------------------- /examples/aot/no-aot/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | lein uberjar 3 | java -cp ./target/no-aot-0.1.0-SNAPSHOT-standalone.jar clojure.main -m no-aot.core 4 | -------------------------------------------------------------------------------- /examples/aot/no-aot/README.md: -------------------------------------------------------------------------------- 1 | # no-aot 2 | 3 | A Clojure library designed to ... well, that part is up to you. 4 | 5 | ## Usage 6 | 7 | FIXME 8 | 9 | ## License 10 | 11 | Copyright © 2018 FIXME 12 | 13 | Distributed under the Eclipse Public License either version 1.0 or (at 14 | your option) any later version. 15 | -------------------------------------------------------------------------------- /examples/aot/no-aot/project.clj: -------------------------------------------------------------------------------- 1 | (defproject no-aot "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :dependencies [[org.clojure/clojure "1.8.0"]]) 7 | -------------------------------------------------------------------------------- /examples/aot/no-aot/src/no_aot/core.clj: -------------------------------------------------------------------------------- 1 | (ns no-aot.core) 2 | 3 | (defn -main [& args] 4 | (println "Hello, World!")) 5 | -------------------------------------------------------------------------------- /examples/aot/no-aot/test/no_aot/core_test.clj: -------------------------------------------------------------------------------- 1 | (ns no-aot.core-test 2 | (:require [clojure.test :refer :all] 3 | [no-aot.core :refer :all])) 4 | 5 | -------------------------------------------------------------------------------- /examples/aot/too-much-aot/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | -------------------------------------------------------------------------------- /examples/aot/too-much-aot/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | lein uberjar 3 | java -jar ./target/too-much-aot-0.1.0-SNAPSHOT-standalone.jar 4 | -------------------------------------------------------------------------------- /examples/aot/too-much-aot/README.md: -------------------------------------------------------------------------------- 1 | # little-aot 2 | 3 | A Clojure library designed to ... well, that part is up to you. 4 | 5 | ## Usage 6 | 7 | FIXME 8 | 9 | ## License 10 | 11 | Copyright © 2018 FIXME 12 | 13 | Distributed under the Eclipse Public License either version 1.0 or (at 14 | your option) any later version. 15 | -------------------------------------------------------------------------------- /examples/aot/too-much-aot/project.clj: -------------------------------------------------------------------------------- 1 | (defproject too-much-aot "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :main too-much-aot.core 7 | :aot [too-much-aot.core] 8 | :dependencies [[org.clojure/clojure "1.8.0"]]) 9 | -------------------------------------------------------------------------------- /examples/aot/too-much-aot/src/too_much_aot/core.clj: -------------------------------------------------------------------------------- 1 | (ns too-much-aot.core 2 | (:require [too-much-aot.dont-aot-me]) 3 | (:gen-class)) 4 | 5 | (defn -main [& args] 6 | (println "Hello, World!")) 7 | -------------------------------------------------------------------------------- /examples/aot/too-much-aot/src/too_much_aot/dont_aot_me.clj: -------------------------------------------------------------------------------- 1 | (ns too-much-aot.dont-aot-me) 2 | 3 | (println "This should be printed at runtime, not during compile") 4 | -------------------------------------------------------------------------------- /examples/communicating-services/Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | cd customer-data-service && $(MAKE) 3 | cd insurance-policy-service && $(MAKE) 4 | cd insurance-policy-application-processor && $(MAKE) 5 | 6 | up: 7 | docker-compose up -d && docker-compose logs -f 8 | 9 | up-prod: 10 | docker-compose -f docker-compose-prod.yml up -d && docker-compose logs -f 11 | 12 | stop: 13 | docker-compose stop 14 | -------------------------------------------------------------------------------- /examples/communicating-services/customer-data-service/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /lib 3 | /classes 4 | /checkouts 5 | pom.xml 6 | pom.xml.asc 7 | *.jar 8 | *.class 9 | /.lein-* 10 | /.nrepl-port 11 | -------------------------------------------------------------------------------- /examples/communicating-services/customer-data-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | RUN mkdir -p /app 3 | COPY ./target/*standalone.jar /app 4 | WORKDIR /app 5 | CMD ["/bin/sh", "-c", "java -jar /app/*standalone.jar"] 6 | -------------------------------------------------------------------------------- /examples/communicating-services/customer-data-service/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | lein ring uberjar 3 | docker build -t customer-data-service . 4 | -------------------------------------------------------------------------------- /examples/communicating-services/customer-data-service/README.md: -------------------------------------------------------------------------------- 1 | # customer-data-service 2 | 3 | FIXME 4 | 5 | ## Prerequisites 6 | 7 | You will need [Leiningen][] 2.0.0 or above installed. 8 | 9 | [leiningen]: https://github.com/technomancy/leiningen 10 | 11 | ## Running 12 | 13 | To start a web server for the application, run: 14 | 15 | lein ring server 16 | 17 | ## License 18 | 19 | Copyright © 2018 FIXME 20 | -------------------------------------------------------------------------------- /examples/communicating-services/customer-data-service/project.clj: -------------------------------------------------------------------------------- 1 | (defproject customer-data-service "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :min-lein-version "2.0.0" 5 | :dependencies [[org.clojure/clojure "1.8.0"] 6 | [compojure "1.5.1"] 7 | [ring/ring-defaults "0.2.1"]] 8 | :plugins [[lein-ring "0.9.7"]] 9 | :ring {:handler customer-data-service.handler/app} 10 | :profiles 11 | {:dev {:dependencies [[javax.servlet/servlet-api "2.5"] 12 | [ring/ring-mock "0.3.0"]]}}) 13 | -------------------------------------------------------------------------------- /examples/communicating-services/customer-data-service/src/customer_data_service/db.clj: -------------------------------------------------------------------------------- 1 | (ns customer-data-service.db 2 | (:require [clojure.string :as str])) 3 | 4 | (defonce backend (atom {1 {:name "Chloe"}})) 5 | 6 | (defn find-by-id [id] 7 | (get @backend id)) 8 | 9 | (defn find-by-name [s] 10 | (vec 11 | (for [[k v] @backend 12 | :when (str/includes? 13 | (some-> v (:name) (str/lower-case)) 14 | (str/lower-case s))] 15 | v))) 16 | -------------------------------------------------------------------------------- /examples/communicating-services/customer-data-service/src/customer_data_service/handler.clj: -------------------------------------------------------------------------------- 1 | (ns customer-data-service.handler 2 | (:require [compojure.core :refer :all] 3 | [compojure.route :as route] 4 | [ring.middleware.defaults :refer [wrap-defaults site-defaults]] 5 | [customer-data-service.db :as db] 6 | [ring.util.response :as response])) 7 | 8 | (defroutes app-routes 9 | (GET "/status" [] 10 | (response/response "Customer data service is running")) 11 | (GET "/customer/:id" [id] 12 | (response/response (db/find-by-id id))) 13 | (GET "/find-by-name/:customer-name" [customer-name] 14 | (response/response (db/find-by-name customer-name))) 15 | (route/not-found "Not Found")) 16 | 17 | (def app 18 | (wrap-defaults app-routes site-defaults)) 19 | -------------------------------------------------------------------------------- /examples/communicating-services/customer-data-service/test/customer_data_service/handler_test.clj: -------------------------------------------------------------------------------- 1 | (ns customer-data-service.handler-test 2 | (:require [clojure.test :refer :all] 3 | [ring.mock.request :as mock] 4 | [customer-data-service.handler :refer :all])) 5 | 6 | (deftest test-app 7 | (testing "main route" 8 | (let [response (app (mock/request :get "/"))] 9 | (is (= (:status response) 200)) 10 | (is (= (:body response) "Hello World")))) 11 | 12 | (testing "not-found route" 13 | (let [response (app (mock/request :get "/invalid"))] 14 | (is (= (:status response) 404))))) 15 | -------------------------------------------------------------------------------- /examples/communicating-services/docker-compose-prod.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | customer-data-service: 4 | image: customer-data-service 5 | ports: 6 | - "3031:3000" 7 | insurance-policy-service: 8 | image: insurance-policy-service 9 | ports: 10 | - "3032:3000" 11 | insurance-policy-application-processor: 12 | image: insurance-policy-application-processor 13 | links: 14 | - customer-data-service 15 | - insurance-policy-service 16 | -------------------------------------------------------------------------------- /examples/communicating-services/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | customer-data-service: 4 | image: clojure:alpine 5 | working_dir: /app 6 | volumes: 7 | - ./customer-data-service:/app 8 | - ~/.m2:/root/.m2 9 | - ~/.lein:/root/.lein 10 | command: lein ring server-headless 11 | ports: 12 | - "3031:3000" 13 | insurance-policy-service: 14 | image: clojure:alpine 15 | working_dir: /app 16 | volumes: 17 | - ./insurance-policy-service:/app 18 | - ~/.m2:/root/.m2 19 | - ~/.lein:/root/.lein 20 | command: lein ring server-headless 21 | ports: 22 | - "3032:3000" 23 | insurance-policy-application-processor: 24 | image: clojure:alpine 25 | working_dir: /app 26 | volumes: 27 | - ./insurance-policy-application-processor:/app 28 | - ~/.m2:/root/.m2 29 | - ~/.lein:/root/.lein 30 | command: lein run 31 | links: 32 | - customer-data-service 33 | - insurance-policy-service 34 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-application-processor/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-application-processor/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | RUN mkdir -p /app 3 | COPY ./target/*standalone.jar /app 4 | WORKDIR /app 5 | CMD ["/bin/sh", "-c", "java -jar /app/*standalone.jar"] 6 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-application-processor/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | lein uberjar 3 | docker build -t insurance-policy-application-processor . 4 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-application-processor/README.md: -------------------------------------------------------------------------------- 1 | # insurance-policy-application-processor 2 | 3 | A Clojure library designed to ... well, that part is up to you. 4 | 5 | ## Usage 6 | 7 | FIXME 8 | 9 | ## License 10 | 11 | Copyright © 2018 FIXME 12 | 13 | Distributed under the Eclipse Public License either version 1.0 or (at 14 | your option) any later version. 15 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-application-processor/project.clj: -------------------------------------------------------------------------------- 1 | (defproject insurance-policy-application-processor "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :main insurance-policy-application-processor.core 7 | :aot [insurance-policy-application-processor.core] 8 | :dependencies [[org.clojure/clojure "1.8.0"] 9 | [clj-http "3.8.0"]]) 10 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-application-processor/src/insurance_policy_application_processor/core.clj: -------------------------------------------------------------------------------- 1 | (ns insurance-policy-application-processor.core 2 | (:require [clj-http.client :as client]) 3 | (:gen-class)) 4 | 5 | (defn fetch-customer [id] 6 | (client/get (str "http://customer-data-service:3000/customer/" id))) 7 | 8 | (defn -main [& args] 9 | (println "Starting Insurance Policy Application Processor...") 10 | (Thread/sleep 5000) 11 | (prn (fetch-customer "1")) 12 | (println "Done.")) 13 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-application-processor/test/insurance_policy_application_processor/core_test.clj: -------------------------------------------------------------------------------- 1 | (ns insurance-policy-application-processor.core-test 2 | (:require [clojure.test :refer :all] 3 | [insurance-policy-application-processor.core :refer :all])) 4 | 5 | (deftest a-test 6 | (testing "FIXME, I fail." 7 | (is (= 0 1)))) 8 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-service/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /lib 3 | /classes 4 | /checkouts 5 | pom.xml 6 | pom.xml.asc 7 | *.jar 8 | *.class 9 | /.lein-* 10 | /.nrepl-port 11 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | RUN mkdir -p /app 3 | COPY ./target/*standalone.jar /app 4 | WORKDIR /app 5 | CMD ["/bin/sh", "-c", "java -jar /app/*standalone.jar"] 6 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-service/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | lein ring uberjar 3 | docker build -t insurance-policy-service . 4 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-service/README.md: -------------------------------------------------------------------------------- 1 | # insurance-policy-service 2 | 3 | FIXME 4 | 5 | ## Prerequisites 6 | 7 | You will need [Leiningen][] 2.0.0 or above installed. 8 | 9 | [leiningen]: https://github.com/technomancy/leiningen 10 | 11 | ## Running 12 | 13 | To start a web server for the application, run: 14 | 15 | lein ring server 16 | 17 | ## License 18 | 19 | Copyright © 2018 FIXME 20 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-service/project.clj: -------------------------------------------------------------------------------- 1 | (defproject insurance-policy-service "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :min-lein-version "2.0.0" 5 | :dependencies [[org.clojure/clojure "1.8.0"] 6 | [compojure "1.5.1"] 7 | [ring/ring-defaults "0.2.1"]] 8 | :plugins [[lein-ring "0.9.7"]] 9 | :ring {:handler insurance-policy-service.handler/app} 10 | :profiles 11 | {:dev {:dependencies [[javax.servlet/servlet-api "2.5"] 12 | [ring/ring-mock "0.3.0"]]}}) 13 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-service/src/insurance_policy_service/db.clj: -------------------------------------------------------------------------------- 1 | (ns insurance-policy-service.db) 2 | 3 | (defonce backend (atom {:corgi-cover {:id :corgi-cover 4 | :name "Corgi Cover"} 5 | :poodle-protection {:id :poodle-protection 6 | :name "Poodle Protection"}})) 7 | 8 | (defn find-all [] 9 | @backend) 10 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-service/src/insurance_policy_service/handler.clj: -------------------------------------------------------------------------------- 1 | (ns insurance-policy-service.handler 2 | (:require [compojure.core :refer :all] 3 | [compojure.route :as route] 4 | [ring.middleware.defaults :refer [wrap-defaults site-defaults]] 5 | [ring.util.response :as response] 6 | [insurance-policy-service.db :as db])) 7 | 8 | (defroutes app-routes 9 | (GET "/status" [] 10 | (response/response "Insurance policy service is running!!!!")) 11 | (GET "/policies" [] 12 | (response/response 13 | (str (db/find-all)))) 14 | (route/not-found "Not Found")) 15 | 16 | (def app 17 | (wrap-defaults app-routes site-defaults)) 18 | -------------------------------------------------------------------------------- /examples/communicating-services/insurance-policy-service/test/insurance_policy_service/handler_test.clj: -------------------------------------------------------------------------------- 1 | (ns insurance-policy-service.handler-test 2 | (:require [clojure.test :refer :all] 3 | [ring.mock.request :as mock] 4 | [insurance-policy-service.handler :refer :all])) 5 | 6 | (deftest test-app 7 | (testing "main route" 8 | (let [response (app (mock/request :get "/"))] 9 | (is (= (:status response) 200)) 10 | (is (= (:body response) "Hello World")))) 11 | 12 | (testing "not-found route" 13 | (let [response (app (mock/request :get "/invalid"))] 14 | (is (= (:status response) 404))))) 15 | -------------------------------------------------------------------------------- /examples/jenkins-build-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jenkins/jenkins:lts 2 | USER root 3 | RUN wget --directory-prefix /usr/local/bin/ https://raw.github.com/technomancy/leiningen/stable/bin/lein 4 | RUN chmod +x /usr/local/bin/lein 5 | USER jenkins 6 | -------------------------------------------------------------------------------- /examples/jenkins-build-server/Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | docker build -t lein-jenkins . 3 | 4 | run: 5 | docker run -p 8080:8080 -p 50000:50000 -v jenkins_home:/var/jenkins_home lein-jenkins 6 | 7 | clean: 8 | docker rm -v lein-jenkins 9 | -------------------------------------------------------------------------------- /examples/jenkins-build-server/README.adoc: -------------------------------------------------------------------------------- 1 | = Jenkins build server 2 | :copyright: Timothy Pratley 3 | :license: Eclipse Public License http://www.eclipse.org/legal/epl-v10.html 4 | :backend: slidy 5 | :max-width: 45em 6 | 7 | This guide assumes you have already created a project to build and deploy. 8 | We will start with the `parsing-with-spec` example project provided in this repository. 9 | Jenkins is presented because it is free and well documented. 10 | The steps in this guide can be adapted to other build tools and services. 11 | 12 | 13 | == Overview 14 | 15 | * How Clojure projects are built and executed locally 16 | * How to set up a build server to automate test/build/deploy 17 | 18 | 19 | == Building and Executing Clojure projects 20 | 21 | lein run 22 | 23 | lein uberjar 24 | 25 | java -jar myapp.jar 26 | 27 | lein ring uberjar 28 | 29 | lein install 30 | 31 | lein deploy 32 | 33 | 34 | == lein run 35 | 36 | * Easy to execute 37 | * May need to pull dependencies 38 | 39 | 40 | == lein uberjar 41 | 42 | * Your application and all dependencies in a single JAR file 43 | * Easy to deploy 44 | * Easy to execute 45 | * Versioned 46 | * Preservable 47 | 48 | 49 | == java -jar myapp.jar 50 | 51 | * Executes an uberjar 52 | * Define a main entrypoint in project.clj 53 | 54 | :main myapp.core 55 | 56 | src/myapp/core.clj 57 | 58 | (ns myapp.core) 59 | (defn -main [& args] ...) 60 | 61 | * Alternatively, specify an entrypoint from the commandline 62 | 63 | java -jar myapp.jar -m myapp.core/-main 64 | 65 | == lein ring uberjar 66 | 67 | Sets up a main entry point to start the webservice 68 | 69 | Equivalent to 70 | 71 | (ns myapp.core) 72 | (defn -main [& args] 73 | (run-jetty handler {:port 3000})) 74 | 75 | 76 | == lein install 77 | 78 | * Builds an uberjar and puts it in your local Maven repository `~/.m2` 79 | * Useful for testing library snapshots and building from source 80 | * Does not publish your artifact 81 | 82 | 83 | == lein deploy 84 | 85 | * Publishes your artifact to a repository 86 | * Repositories can be 87 | - public (Clojars, Maven Central) 88 | - private (Hosted/S3/Self managed) 89 | * https://github.com/technomancy/leiningen/blob/master/doc/DEPLOY.md 90 | * Easy... if you have a repository... 91 | * Not the same as deploying your application! 92 | 93 | 94 | == Where to publish artifacts to? 95 | 96 | * Amazon S3 is a low-maintenance choice: 97 | - https://github.com/s3-wagon-private/s3-wagon-private 98 | * Artifactory/Nexus/Archiva 99 | * Deps: https://www.deps.co/ 100 | * Remeber to include a `repositories` section in your project.clj 101 | - To publish to a private repository 102 | - To pull dependencies from a private repository 103 | 104 | :repositories [["private" {:url "s3p://mybucket/releases/" :no-auth true}]] 105 | 106 | 107 | == Deploying a Clojure application 108 | 109 | * Build an uberjar (or Docker container) 110 | * Get the artifact to the host server 111 | * Run it 112 | 113 | 114 | == Implementation details are driven by architecture 115 | 116 | * Tomcat? Drop a WAR in a folder 117 | * AWS Elastic Beanstalk? Roll out a new docker container 118 | * AWS Lambda? Upload a new JAR 119 | * Kubernetes? Roll out a new docker container 120 | * Heroku? Deploy from git 121 | 122 | 123 | == Creating a build server overview 124 | 125 | * Install Jenkins 126 | * Install Leiningen 127 | * Add a build 128 | 129 | 130 | == What is Docker? 131 | 132 | * Virtualization 133 | * Dockerfile specifies a parent and setup tasks 134 | * Building starts with an image and runs the setup tasks, creates a container 135 | * Run a container and it behaves like a stand alone computer 136 | 137 | 138 | == Handy Docker commands 139 | 140 | * `docker build -t .` to create a container from a Dockerfile 141 | * `docker run ` to run it 142 | * `docker ps` to see running containers 143 | * `docker exec -ti bash` to get a shell in a running container 144 | * `docker stop ` to stop it 145 | 146 | 147 | == Creating a Jenkins server inside a Docker container 148 | 149 | * Install docker 150 | * Create a Dockerfile to extend the base Jenkins image 151 | - see examples/jenkins-build-server/Dockerfile 152 | - https://github.com/jenkinsci/docker/blob/master/README.md 153 | - add steps to install Leiningen 154 | * Create a Makefile or similar to automate tasks 155 | - see examples/jenkins-build-server/Makefile 156 | - `make run` to start the server 157 | * Open the UI: http://localhost:8080/ 158 | * Enter password from console log 159 | * Install suggested plugins 160 | * Create admin user 161 | 162 | 163 | == What to build? 164 | 165 | * An uberjar 166 | * Docker image 167 | 168 | 169 | == Set up Job 170 | 171 | * Choose Freestyle project 172 | * Configure source code management 173 | - parsing-with-spec is a subdirectory of the enterprise-clojure repository 174 | - `sparse checkout path` only gets a subdirectory 175 | * Under "Build", add build steps, shell command 176 | - `cd examples/parsing-with-spec && lein test` 177 | - `cd examples/parsing-with-spec && lein install` 178 | - or docker build 179 | - don't need to change directory if project is in root 180 | * Save 181 | * Build now 182 | * Check the console logs 183 | - tests passed 184 | - jar created 185 | 186 | 187 | == Versioning 188 | 189 | 190 | == Running the built artifacts 191 | 192 | * `java -jar myapp.jar` 193 | * Use environment variables to behave differently 194 | * Can extend a prebuilt docker image (or roll your own) 195 | 196 | 197 | == Building multiple services 198 | 199 | * Set up jobs for each project 200 | 201 | 202 | == Set up another triggered Job to deploy to CI 203 | 204 | * If the build succeeds, deploy 205 | -------------------------------------------------------------------------------- /examples/parsing-with-spec/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .hgignore 11 | .hg/ 12 | -------------------------------------------------------------------------------- /examples/parsing-with-spec/README.md: -------------------------------------------------------------------------------- 1 | # parsing-with-spec 2 | 3 | Demonstrates how to validate data and conform multiple possible matching specifications. 4 | 5 | ## Usage 6 | 7 | `lein test` 8 | 9 | ## License 10 | 11 | Copyright © 2018 Timothy Pratley 12 | 13 | Distributed under the Eclipse Public License either version 1.0 or (at 14 | your option) any later version. 15 | -------------------------------------------------------------------------------- /examples/parsing-with-spec/data/insurance_policy_applications.txt: -------------------------------------------------------------------------------- 1 | name,state,corgi-count,existing-policy-count,poodle-count 2 | Chloe,IL,1,0,1 3 | Ethan,IL,4,2,2 4 | Annabelle,WY,19,0,0 5 | Logan,WA,2,1,0 6 | Tiffany,TAS,2,1,0 7 | Wendy,WY,0,1,4 8 | -------------------------------------------------------------------------------- /examples/parsing-with-spec/project.clj: -------------------------------------------------------------------------------- 1 | (defproject parsing-with-spec "0.1.0-SNAPSHOT" 2 | :description "Example of parsing with spec" 3 | :url "https://github.com/timothypratley/enterprise-clojure-training/examples/parsing-with-spec" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :dependencies [[org.clojure/clojure "1.9.0"] 7 | [org.clojure/data.csv "0.1.4"] 8 | [org.clojure/test.check "0.9.0"] 9 | [expound "0.5.0"]] 10 | :aot [parsing-with-spec.core] 11 | :main parsing-with-spec.core) 12 | -------------------------------------------------------------------------------- /examples/parsing-with-spec/src/parsing_with_spec/core.clj: -------------------------------------------------------------------------------- 1 | (ns parsing-with-spec.core 2 | (:gen-class) 3 | (:require [clojure.data.csv :as csv] 4 | [clojure.java.io :as io] 5 | [clojure.spec.alpha :as s] 6 | [expound.alpha :as e])) 7 | 8 | ;; Specs 9 | 10 | ;; Insurance policy shared fields 11 | 12 | (s/def :mega-corp/name string?) 13 | (s/def :mega-corp/policy-count int?) 14 | 15 | 16 | ;; The "Corgi Cover" policy is only available in certain USA states 17 | 18 | (s/def :corgi-cover/state #{"IL" "WA" "NY" "CO"}) 19 | (s/def :corgi-cover/corgi-count pos-int?) 20 | 21 | (s/def :mega-corp/corgi-cover 22 | (s/keys :req-un [:mega-corp/name 23 | :corgi-cover/state 24 | :corgi-cover/corgi-count])) 25 | 26 | ;; The "Poodle Protection" policy is only available in some other set of USA states 27 | 28 | (s/def :poodle-protection/state #{"CA" "FL" "WY" "HI"}) 29 | (s/def :poodle-protection/poodle-count pos-int?) 30 | 31 | (s/def :mega-corp/poodle-protection 32 | (s/keys :req-un [:mega-corp/name 33 | :poodle-protection/state 34 | :poodle-protection/poodle-count])) 35 | 36 | 37 | ;; "Poodle Protection Platinum" is available to people with 3 or more Poodles. 38 | 39 | (s/def :poodle-protection-platinum/poodle-count (s/and pos-int? #(<= 3 %))) 40 | 41 | (s/def :mega-corp/poodle-protection-platinum 42 | (s/keys :req-un [:mega-corp/name 43 | :poodle-protection/state 44 | :poodle-protection-platinum/poodle-count])) 45 | 46 | 47 | ;; All insurance policies 48 | 49 | (s/def :mega-corp/insurance-policy 50 | (s/or :mega-corp/corgi-cover :mega-corp/corgi-cover 51 | :mega-corp/poodle-protection :mega-corp/poodle-protection 52 | :mega-corp/poodle-protection-platinum :mega-corp/poodle-protection-platinum)) 53 | 54 | 55 | (defn process-applications [valid invalid policy-applications] 56 | (doseq [a policy-applications] 57 | (if (s/valid? :mega-corp/insurance-policy a) 58 | (valid a) 59 | (invalid a)))) 60 | 61 | 62 | ;; Data shaping 63 | 64 | (defn parse-int [s] 65 | (try 66 | (Integer/parseInt s) 67 | (catch Exception ex 0))) 68 | 69 | (defn mapize [csv-rows] 70 | (let [[header & lines] csv-rows 71 | ks (for [field header] 72 | (keyword field))] 73 | (for [line lines] 74 | (-> (zipmap ks line) 75 | (update :corgi-count parse-int) 76 | (update :policy-count parse-int) 77 | (update :poodle-count parse-int))))) 78 | 79 | (defn process-applications-file [valid invalid filename] 80 | (with-open [r (io/reader filename)] 81 | (->> (csv/read-csv r) 82 | (mapize) 83 | (process-applications valid invalid)))) 84 | 85 | (defn valid [application] 86 | (let [[policy-type {:keys [poodle-protection/poodle-count 87 | policy-count]}] 88 | (s/conform :mega-corp/insurance-policy application)] 89 | ;; this passes unit tests, but what if the the policy-count was 0? 90 | ;; see generative tests 91 | (when (= policy-type :mega-corp/poodle-protection) 92 | (println "Poodle to policy ratio:" (/ poodle-count policy-count))) 93 | 94 | ;; write to accepted log 95 | (println "VALID:" policy-type application))) 96 | 97 | (s/fdef valid :args (s/cat :application :mega-corp/insurance-policy)) 98 | 99 | (defn invalid [application] 100 | ;; write to discard log 101 | (println "INVALID:" application) 102 | ;;(s/explain ::policy-application application) 103 | (e/expound :mega-corp/insurance-policy application)) 104 | 105 | (defn -main [& args] 106 | (println "Starting file processing...") 107 | (let [filename (or (first args) "data/insurance_policy_applications.txt")] 108 | (process-applications-file valid invalid filename)) 109 | (println "Done.")) 110 | -------------------------------------------------------------------------------- /examples/parsing-with-spec/test/parsing_with_spec/core_test.clj: -------------------------------------------------------------------------------- 1 | (ns parsing-with-spec.core-test 2 | (:require [clojure.test :refer :all] 3 | [parsing-with-spec.core :as p] 4 | [clojure.spec.alpha :as s] 5 | [expound.alpha :as e])) 6 | 7 | (def good 8 | {:name "Chloe" 9 | :state "WA" 10 | :corgi-count 1 11 | :policy-count 1}) 12 | 13 | (def bad 14 | {:name "Chloe" 15 | :state "TAS" 16 | :corgi-count 1 17 | :policy-count 1}) 18 | 19 | (deftest test-validation 20 | (is (not (s/valid? :mega-corp/corgi-cover bad)) 21 | "TAS is not be a valid state for corgi-cover") 22 | (is (s/valid? :mega-corp/insurance-policy good) 23 | (e/expound-str :mega-corp/insurance-policy good)) 24 | (is (not (s/valid? :mega-corp/insurance-policy bad)) 25 | "TAS is not a valid state for any policy")) 26 | 27 | (deftest test-validation-handling 28 | (let [insurance-policy-applications [good bad] 29 | valid-count (atom 0) 30 | invalid-count (atom 0) 31 | valid (fn [x] 32 | (swap! valid-count inc)) 33 | invalid (fn [x] 34 | (swap! invalid-count inc))] 35 | (p/process-applications valid invalid insurance-policy-applications) 36 | (is (= 1 @valid-count)) 37 | (is (= 1 @invalid-count)))) 38 | 39 | (deftest a-test 40 | (let [valid-names (atom #{}) 41 | invalid-names (atom #{}) 42 | valid (fn [x] 43 | (swap! valid-names conj (:name x))) 44 | invalid (fn [x] 45 | ;;(e/expound :mega-corp/insurance-policy x) 46 | (swap! invalid-names conj (:name x)))] 47 | (p/process-applications-file valid invalid "data/insurance_policy_applications.txt") 48 | (is (= #{"Tiffany" "Annabelle"} 49 | @invalid-names)) 50 | (is (= #{"Wendy" "Ethan" "Chloe" "Logan"} 51 | @valid-names)))) 52 | 53 | -------------------------------------------------------------------------------- /examples/parsing-with-spec/test/parsing_with_spec/generated_test.clj: -------------------------------------------------------------------------------- 1 | (ns parsing-with-spec.generated-test 2 | (:require [clojure.test :refer :all] 3 | [clojure.spec.alpha :as s] 4 | [clojure.spec.test.alpha :as stest] 5 | [clojure.spec.gen.alpha :as gen] 6 | [parsing-with-spec.core :refer [valid]])) 7 | 8 | ;; get some test data 9 | #_(prn (gen/sample (s/gen :mega-corp/insurance-policy))) 10 | 11 | ;; check that the function works for all valid inputs 12 | ;; ... finds a bug! :) 13 | ;; ... gives the shortest reproduction input 14 | #_ 15 | (with-redefs [println (constantly nil)] 16 | (prn (stest/check `valid))) 17 | 18 | -------------------------------------------------------------------------------- /site/forum.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |
9 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /site/img/art1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/art1.jpg -------------------------------------------------------------------------------- /site/img/clojure-logo-icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/clojure-logo-icon-32.png -------------------------------------------------------------------------------- /site/img/clojure-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/clojure-logo.png -------------------------------------------------------------------------------- /site/img/control.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/control.jpg -------------------------------------------------------------------------------- /site/img/corgi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/corgi.jpg -------------------------------------------------------------------------------- /site/img/database.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/database.jpg -------------------------------------------------------------------------------- /site/img/ecosystem.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/ecosystem.jpg -------------------------------------------------------------------------------- /site/img/functional.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/functional.jpg -------------------------------------------------------------------------------- /site/img/functions.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/functions.jpg -------------------------------------------------------------------------------- /site/img/further-reading.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/further-reading.jpg -------------------------------------------------------------------------------- /site/img/interop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/interop.jpg -------------------------------------------------------------------------------- /site/img/macros.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/macros.jpg -------------------------------------------------------------------------------- /site/img/parallel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/parallel.jpg -------------------------------------------------------------------------------- /site/img/spec.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/spec.jpg -------------------------------------------------------------------------------- /site/img/syntax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/syntax.png -------------------------------------------------------------------------------- /site/img/talk/clojure-jobs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/clojure-jobs.png -------------------------------------------------------------------------------- /site/img/talk/corgi-asleep-at-vet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-asleep-at-vet.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-challenge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-challenge.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-developer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-developer.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-encounter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-encounter.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-herding-ducks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-herding-ducks.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-hoodie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-hoodie.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-in-crate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-in-crate.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-lights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-lights.png -------------------------------------------------------------------------------- /site/img/talk/corgi-on-field.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-on-field.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-rope.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-rope.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-student.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-student.png -------------------------------------------------------------------------------- /site/img/talk/corgi-team.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-team.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-training.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-training.jpeg -------------------------------------------------------------------------------- /site/img/talk/corgi-training.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-training.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-waiting.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-waiting.jpg -------------------------------------------------------------------------------- /site/img/talk/corgi-weird.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/corgi-weird.jpeg -------------------------------------------------------------------------------- /site/img/talk/idea-asciidoctor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/idea-asciidoctor.png -------------------------------------------------------------------------------- /site/img/talk/most-used-jvm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/most-used-jvm.jpg -------------------------------------------------------------------------------- /site/img/talk/popularity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/popularity.png -------------------------------------------------------------------------------- /site/img/talk/suiteness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/talk/suiteness.png -------------------------------------------------------------------------------- /site/img/testing.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/testing.jpg -------------------------------------------------------------------------------- /site/img/types.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/img/types.jpg -------------------------------------------------------------------------------- /site/reveal.js/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | *.iws 4 | *.eml 5 | out/ 6 | .DS_Store 7 | .svn 8 | log/*.log 9 | tmp/** 10 | node_modules/ 11 | .sass-cache 12 | css/reveal.min.css 13 | js/reveal.min.js -------------------------------------------------------------------------------- /site/reveal.js/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 4 4 | before_script: 5 | - npm install -g grunt-cli 6 | after_script: 7 | - grunt retire 8 | -------------------------------------------------------------------------------- /site/reveal.js/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**. 4 | 5 | 6 | ### Personal Support 7 | If you have personal support or setup questions the best place to ask those are [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js). 8 | 9 | 10 | ### Bug Reports 11 | When reporting a bug make sure to include information about which browser and operating system you are on as well as the necessary steps to reproduce the issue. If possible please include a link to a sample presentation where the bug can be tested. 12 | 13 | 14 | ### Pull Requests 15 | - Should follow the coding style of the file you work in, most importantly: 16 | - Tabs to indent 17 | - Single-quoted strings 18 | - Should be made towards the **dev branch** 19 | - Should be submitted from a feature/topic branch (not your master) 20 | 21 | 22 | ### Plugins 23 | Please do not submit plugins as pull requests. They should be maintained in their own separate repository. More information here: https://github.com/hakimel/reveal.js/wiki/Plugin-Guidelines 24 | -------------------------------------------------------------------------------- /site/reveal.js/Gruntfile.js: -------------------------------------------------------------------------------- 1 | /* global module:false */ 2 | module.exports = function(grunt) { 3 | var port = grunt.option('port') || 8000; 4 | var root = grunt.option('root') || '.'; 5 | 6 | if (!Array.isArray(root)) root = [root]; 7 | 8 | // Project configuration 9 | grunt.initConfig({ 10 | pkg: grunt.file.readJSON('package.json'), 11 | meta: { 12 | banner: 13 | '/*!\n' + 14 | ' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' + 15 | ' * http://revealjs.com\n' + 16 | ' * MIT licensed\n' + 17 | ' *\n' + 18 | ' * Copyright (C) 2017 Hakim El Hattab, http://hakim.se\n' + 19 | ' */' 20 | }, 21 | 22 | qunit: { 23 | files: [ 'test/*.html' ] 24 | }, 25 | 26 | uglify: { 27 | options: { 28 | banner: '<%= meta.banner %>\n', 29 | screwIE8: false 30 | }, 31 | build: { 32 | src: 'js/reveal.js', 33 | dest: 'js/reveal.min.js' 34 | } 35 | }, 36 | 37 | sass: { 38 | core: { 39 | src: 'css/reveal.scss', 40 | dest: 'css/reveal.css' 41 | }, 42 | themes: { 43 | expand: true, 44 | cwd: 'css/theme/source', 45 | src: ['*.sass', '*.scss'], 46 | dest: 'css/theme', 47 | ext: '.css' 48 | } 49 | }, 50 | 51 | autoprefixer: { 52 | core: { 53 | src: 'css/reveal.css' 54 | } 55 | }, 56 | 57 | cssmin: { 58 | options: { 59 | compatibility: 'ie9' 60 | }, 61 | compress: { 62 | src: 'css/reveal.css', 63 | dest: 'css/reveal.min.css' 64 | } 65 | }, 66 | 67 | jshint: { 68 | options: { 69 | curly: false, 70 | eqeqeq: true, 71 | immed: true, 72 | esnext: true, 73 | latedef: 'nofunc', 74 | newcap: true, 75 | noarg: true, 76 | sub: true, 77 | undef: true, 78 | eqnull: true, 79 | browser: true, 80 | expr: true, 81 | globals: { 82 | head: false, 83 | module: false, 84 | console: false, 85 | unescape: false, 86 | define: false, 87 | exports: false 88 | } 89 | }, 90 | files: [ 'Gruntfile.js', 'js/reveal.js' ] 91 | }, 92 | 93 | connect: { 94 | server: { 95 | options: { 96 | port: port, 97 | base: root, 98 | livereload: true, 99 | open: true, 100 | useAvailablePort: true 101 | } 102 | } 103 | }, 104 | 105 | zip: { 106 | bundle: { 107 | src: [ 108 | 'index.html', 109 | 'css/**', 110 | 'js/**', 111 | 'lib/**', 112 | 'images/**', 113 | 'plugin/**', 114 | '**.md' 115 | ], 116 | dest: 'reveal-js-presentation.zip' 117 | } 118 | }, 119 | 120 | watch: { 121 | js: { 122 | files: [ 'Gruntfile.js', 'js/reveal.js' ], 123 | tasks: 'js' 124 | }, 125 | theme: { 126 | files: [ 127 | 'css/theme/source/*.sass', 128 | 'css/theme/source/*.scss', 129 | 'css/theme/template/*.sass', 130 | 'css/theme/template/*.scss' 131 | ], 132 | tasks: 'css-themes' 133 | }, 134 | css: { 135 | files: [ 'css/reveal.scss' ], 136 | tasks: 'css-core' 137 | }, 138 | html: { 139 | files: root.map(path => path + '/*.html') 140 | }, 141 | markdown: { 142 | files: root.map(path => path + '/*.md') 143 | }, 144 | options: { 145 | livereload: true 146 | } 147 | }, 148 | 149 | retire: { 150 | js: [ 'js/reveal.js', 'lib/js/*.js', 'plugin/**/*.js' ], 151 | node: [ '.' ] 152 | } 153 | 154 | }); 155 | 156 | // Dependencies 157 | grunt.loadNpmTasks( 'grunt-contrib-connect' ); 158 | grunt.loadNpmTasks( 'grunt-contrib-cssmin' ); 159 | grunt.loadNpmTasks( 'grunt-contrib-jshint' ); 160 | grunt.loadNpmTasks( 'grunt-contrib-qunit' ); 161 | grunt.loadNpmTasks( 'grunt-contrib-uglify' ); 162 | grunt.loadNpmTasks( 'grunt-contrib-watch' ); 163 | grunt.loadNpmTasks( 'grunt-autoprefixer' ); 164 | grunt.loadNpmTasks( 'grunt-retire' ); 165 | grunt.loadNpmTasks( 'grunt-sass' ); 166 | grunt.loadNpmTasks( 'grunt-zip' ); 167 | 168 | // Default task 169 | grunt.registerTask( 'default', [ 'css', 'js' ] ); 170 | 171 | // JS task 172 | grunt.registerTask( 'js', [ 'jshint', 'uglify', 'qunit' ] ); 173 | 174 | // Theme CSS 175 | grunt.registerTask( 'css-themes', [ 'sass:themes' ] ); 176 | 177 | // Core framework CSS 178 | grunt.registerTask( 'css-core', [ 'sass:core', 'autoprefixer', 'cssmin' ] ); 179 | 180 | // All CSS 181 | grunt.registerTask( 'css', [ 'sass', 'autoprefixer', 'cssmin' ] ); 182 | 183 | // Package presentation to archive 184 | grunt.registerTask( 'package', [ 'default', 'zip' ] ); 185 | 186 | // Serve presentation locally 187 | grunt.registerTask( 'serve', [ 'connect', 'watch' ] ); 188 | 189 | // Run tests 190 | grunt.registerTask( 'test', [ 'jshint', 'qunit' ] ); 191 | 192 | }; 193 | -------------------------------------------------------------------------------- /site/reveal.js/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2017 Hakim El Hattab, http://hakim.se, and reveal.js contributors 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. -------------------------------------------------------------------------------- /site/reveal.js/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reveal.js", 3 | "version": "3.6.0", 4 | "main": [ 5 | "js/reveal.js", 6 | "css/reveal.css" 7 | ], 8 | "homepage": "http://revealjs.com", 9 | "license": "MIT", 10 | "description": "The HTML Presentation Framework", 11 | "authors": [ 12 | "Hakim El Hattab " 13 | ], 14 | "dependencies": { 15 | "headjs": "~1.0.3" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git://github.com/hakimel/reveal.js.git" 20 | }, 21 | "ignore": [ 22 | "**/.*", 23 | "node_modules", 24 | "bower_components", 25 | "test" 26 | ] 27 | } -------------------------------------------------------------------------------- /site/reveal.js/css/print/paper.css: -------------------------------------------------------------------------------- 1 | /* Default Print Stylesheet Template 2 | by Rob Glazebrook of CSSnewbie.com 3 | Last Updated: June 4, 2008 4 | 5 | Feel free (nay, compelled) to edit, append, and 6 | manipulate this file as you see fit. */ 7 | 8 | 9 | @media print { 10 | 11 | /* SECTION 1: Set default width, margin, float, and 12 | background. This prevents elements from extending 13 | beyond the edge of the printed page, and prevents 14 | unnecessary background images from printing */ 15 | html { 16 | background: #fff; 17 | width: auto; 18 | height: auto; 19 | overflow: visible; 20 | } 21 | body { 22 | background: #fff; 23 | font-size: 20pt; 24 | width: auto; 25 | height: auto; 26 | border: 0; 27 | margin: 0 5%; 28 | padding: 0; 29 | overflow: visible; 30 | float: none !important; 31 | } 32 | 33 | /* SECTION 2: Remove any elements not needed in print. 34 | This would include navigation, ads, sidebars, etc. */ 35 | .nestedarrow, 36 | .controls, 37 | .fork-reveal, 38 | .share-reveal, 39 | .state-background, 40 | .reveal .progress, 41 | .reveal .backgrounds, 42 | .reveal .slide-number { 43 | display: none !important; 44 | } 45 | 46 | /* SECTION 3: Set body font face, size, and color. 47 | Consider using a serif font for readability. */ 48 | body, p, td, li, div { 49 | font-size: 20pt!important; 50 | font-family: Georgia, "Times New Roman", Times, serif !important; 51 | color: #000; 52 | } 53 | 54 | /* SECTION 4: Set heading font face, sizes, and color. 55 | Differentiate your headings from your body text. 56 | Perhaps use a large sans-serif for distinction. */ 57 | h1,h2,h3,h4,h5,h6 { 58 | color: #000!important; 59 | height: auto; 60 | line-height: normal; 61 | font-family: Georgia, "Times New Roman", Times, serif !important; 62 | text-shadow: 0 0 0 #000 !important; 63 | text-align: left; 64 | letter-spacing: normal; 65 | } 66 | /* Need to reduce the size of the fonts for printing */ 67 | h1 { font-size: 28pt !important; } 68 | h2 { font-size: 24pt !important; } 69 | h3 { font-size: 22pt !important; } 70 | h4 { font-size: 22pt !important; font-variant: small-caps; } 71 | h5 { font-size: 21pt !important; } 72 | h6 { font-size: 20pt !important; font-style: italic; } 73 | 74 | /* SECTION 5: Make hyperlinks more usable. 75 | Ensure links are underlined, and consider appending 76 | the URL to the end of the link for usability. */ 77 | a:link, 78 | a:visited { 79 | color: #000 !important; 80 | font-weight: bold; 81 | text-decoration: underline; 82 | } 83 | /* 84 | .reveal a:link:after, 85 | .reveal a:visited:after { 86 | content: " (" attr(href) ") "; 87 | color: #222 !important; 88 | font-size: 90%; 89 | } 90 | */ 91 | 92 | 93 | /* SECTION 6: more reveal.js specific additions by @skypanther */ 94 | ul, ol, div, p { 95 | visibility: visible; 96 | position: static; 97 | width: auto; 98 | height: auto; 99 | display: block; 100 | overflow: visible; 101 | margin: 0; 102 | text-align: left !important; 103 | } 104 | .reveal pre, 105 | .reveal table { 106 | margin-left: 0; 107 | margin-right: 0; 108 | } 109 | .reveal pre code { 110 | padding: 20px; 111 | border: 1px solid #ddd; 112 | } 113 | .reveal blockquote { 114 | margin: 20px 0; 115 | } 116 | .reveal .slides { 117 | position: static !important; 118 | width: auto !important; 119 | height: auto !important; 120 | 121 | left: 0 !important; 122 | top: 0 !important; 123 | margin-left: 0 !important; 124 | margin-top: 0 !important; 125 | padding: 0 !important; 126 | zoom: 1 !important; 127 | 128 | overflow: visible !important; 129 | display: block !important; 130 | 131 | text-align: left !important; 132 | -webkit-perspective: none; 133 | -moz-perspective: none; 134 | -ms-perspective: none; 135 | perspective: none; 136 | 137 | -webkit-perspective-origin: 50% 50%; 138 | -moz-perspective-origin: 50% 50%; 139 | -ms-perspective-origin: 50% 50%; 140 | perspective-origin: 50% 50%; 141 | } 142 | .reveal .slides section { 143 | visibility: visible !important; 144 | position: static !important; 145 | width: auto !important; 146 | height: auto !important; 147 | display: block !important; 148 | overflow: visible !important; 149 | 150 | left: 0 !important; 151 | top: 0 !important; 152 | margin-left: 0 !important; 153 | margin-top: 0 !important; 154 | padding: 60px 20px !important; 155 | z-index: auto !important; 156 | 157 | opacity: 1 !important; 158 | 159 | page-break-after: always !important; 160 | 161 | -webkit-transform-style: flat !important; 162 | -moz-transform-style: flat !important; 163 | -ms-transform-style: flat !important; 164 | transform-style: flat !important; 165 | 166 | -webkit-transform: none !important; 167 | -moz-transform: none !important; 168 | -ms-transform: none !important; 169 | transform: none !important; 170 | 171 | -webkit-transition: none !important; 172 | -moz-transition: none !important; 173 | -ms-transition: none !important; 174 | transition: none !important; 175 | } 176 | .reveal .slides section.stack { 177 | padding: 0 !important; 178 | } 179 | .reveal section:last-of-type { 180 | page-break-after: avoid !important; 181 | } 182 | .reveal section .fragment { 183 | opacity: 1 !important; 184 | visibility: visible !important; 185 | 186 | -webkit-transform: none !important; 187 | -moz-transform: none !important; 188 | -ms-transform: none !important; 189 | transform: none !important; 190 | } 191 | .reveal section img { 192 | display: block; 193 | margin: 15px 0px; 194 | background: rgba(255,255,255,1); 195 | border: 1px solid #666; 196 | box-shadow: none; 197 | } 198 | 199 | .reveal section small { 200 | font-size: 0.8em; 201 | } 202 | 203 | } 204 | -------------------------------------------------------------------------------- /site/reveal.js/css/print/pdf.css: -------------------------------------------------------------------------------- 1 | /** 2 | * This stylesheet is used to print reveal.js 3 | * presentations to PDF. 4 | * 5 | * https://github.com/hakimel/reveal.js#pdf-export 6 | */ 7 | 8 | * { 9 | -webkit-print-color-adjust: exact; 10 | } 11 | 12 | body { 13 | margin: 0 auto !important; 14 | border: 0; 15 | padding: 0; 16 | float: none !important; 17 | overflow: visible; 18 | } 19 | 20 | html { 21 | width: 100%; 22 | height: 100%; 23 | overflow: visible; 24 | } 25 | 26 | /* Remove any elements not needed in print. */ 27 | .nestedarrow, 28 | .reveal .controls, 29 | .reveal .progress, 30 | .reveal .playback, 31 | .reveal.overview, 32 | .fork-reveal, 33 | .share-reveal, 34 | .state-background { 35 | display: none !important; 36 | } 37 | 38 | h1, h2, h3, h4, h5, h6 { 39 | text-shadow: 0 0 0 #000 !important; 40 | } 41 | 42 | .reveal pre code { 43 | overflow: hidden !important; 44 | font-family: Courier, 'Courier New', monospace !important; 45 | } 46 | 47 | ul, ol, div, p { 48 | visibility: visible; 49 | position: static; 50 | width: auto; 51 | height: auto; 52 | display: block; 53 | overflow: visible; 54 | margin: auto; 55 | } 56 | .reveal { 57 | width: auto !important; 58 | height: auto !important; 59 | overflow: hidden !important; 60 | } 61 | .reveal .slides { 62 | position: static; 63 | width: 100% !important; 64 | height: auto !important; 65 | zoom: 1 !important; 66 | 67 | left: auto; 68 | top: auto; 69 | margin: 0 !important; 70 | padding: 0 !important; 71 | 72 | overflow: visible; 73 | display: block; 74 | 75 | -webkit-perspective: none; 76 | -moz-perspective: none; 77 | -ms-perspective: none; 78 | perspective: none; 79 | 80 | -webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */ 81 | -moz-perspective-origin: 50% 50%; 82 | -ms-perspective-origin: 50% 50%; 83 | perspective-origin: 50% 50%; 84 | } 85 | 86 | .reveal .slides .pdf-page { 87 | position: relative; 88 | overflow: hidden; 89 | z-index: 1; 90 | 91 | page-break-after: always; 92 | } 93 | 94 | .reveal .slides section { 95 | visibility: visible !important; 96 | display: block !important; 97 | position: absolute !important; 98 | 99 | margin: 0 !important; 100 | padding: 0 !important; 101 | box-sizing: border-box !important; 102 | min-height: 1px; 103 | 104 | opacity: 1 !important; 105 | 106 | -webkit-transform-style: flat !important; 107 | -moz-transform-style: flat !important; 108 | -ms-transform-style: flat !important; 109 | transform-style: flat !important; 110 | 111 | -webkit-transform: none !important; 112 | -moz-transform: none !important; 113 | -ms-transform: none !important; 114 | transform: none !important; 115 | } 116 | 117 | .reveal section.stack { 118 | position: relative !important; 119 | margin: 0 !important; 120 | padding: 0 !important; 121 | page-break-after: avoid !important; 122 | height: auto !important; 123 | min-height: auto !important; 124 | } 125 | 126 | .reveal img { 127 | box-shadow: none; 128 | } 129 | 130 | .reveal .roll { 131 | overflow: visible; 132 | line-height: 1em; 133 | } 134 | 135 | /* Slide backgrounds are placed inside of their slide when exporting to PDF */ 136 | .reveal .slide-background { 137 | display: block !important; 138 | position: absolute; 139 | top: 0; 140 | left: 0; 141 | width: 100%; 142 | height: 100%; 143 | z-index: auto !important; 144 | } 145 | 146 | /* Display slide speaker notes when 'showNotes' is enabled */ 147 | .reveal.show-notes { 148 | max-width: none; 149 | max-height: none; 150 | } 151 | .reveal .speaker-notes-pdf { 152 | display: block; 153 | width: 100%; 154 | height: auto; 155 | max-height: none; 156 | top: auto; 157 | right: auto; 158 | bottom: auto; 159 | left: auto; 160 | z-index: 100; 161 | } 162 | 163 | /* Layout option which makes notes appear on a separate page */ 164 | .reveal .speaker-notes-pdf[data-layout="separate-page"] { 165 | position: relative; 166 | color: inherit; 167 | background-color: transparent; 168 | padding: 20px; 169 | page-break-after: always; 170 | border: 0; 171 | } 172 | 173 | /* Display slide numbers when 'slideNumber' is enabled */ 174 | .reveal .slide-number-pdf { 175 | display: block; 176 | position: absolute; 177 | font-size: 14px; 178 | } 179 | -------------------------------------------------------------------------------- /site/reveal.js/css/theme/README.md: -------------------------------------------------------------------------------- 1 | ## Dependencies 2 | 3 | Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Make sure that you have the reveal.js development environment including the Grunt dependencies installed before proceeding: https://github.com/hakimel/reveal.js#full-setup 4 | 5 | ## Creating a Theme 6 | 7 | To create your own theme, start by duplicating a ```.scss``` file in [/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source). It will be automatically compiled by Grunt from Sass to CSS (see the [Gruntfile](https://github.com/hakimel/reveal.js/blob/master/Gruntfile.js)) when you run `grunt css-themes`. 8 | 9 | Each theme file does four things in the following order: 10 | 11 | 1. **Include [/css/theme/template/mixins.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/mixins.scss)** 12 | Shared utility functions. 13 | 14 | 2. **Include [/css/theme/template/settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)** 15 | Declares a set of custom variables that the template file (step 4) expects. Can be overridden in step 3. 16 | 17 | 3. **Override** 18 | This is where you override the default theme. Either by specifying variables (see [settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss) for reference) or by adding any selectors and styles you please. 19 | 20 | 4. **Include [/css/theme/template/theme.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/theme.scss)** 21 | The template theme file which will generate final CSS output based on the currently defined variables. 22 | -------------------------------------------------------------------------------- /site/reveal.js/css/theme/night.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Black theme for reveal.js. 3 | * 4 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 5 | */ 6 | @import url(https://fonts.googleapis.com/css?family=Montserrat:700); 7 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic); 8 | /********************************************* 9 | * GLOBAL STYLES 10 | *********************************************/ 11 | body { 12 | background: #111; 13 | background-color: #111; } 14 | 15 | .reveal { 16 | font-family: "Open Sans", sans-serif; 17 | font-size: 40px; 18 | font-weight: normal; 19 | color: #eee; } 20 | 21 | ::selection { 22 | color: #fff; 23 | background: #e7ad52; 24 | text-shadow: none; } 25 | 26 | ::-moz-selection { 27 | color: #fff; 28 | background: #e7ad52; 29 | text-shadow: none; } 30 | 31 | .reveal .slides > section, 32 | .reveal .slides > section > section { 33 | line-height: 1.3; 34 | font-weight: inherit; } 35 | 36 | /********************************************* 37 | * HEADERS 38 | *********************************************/ 39 | .reveal h1, 40 | .reveal h2, 41 | .reveal h3, 42 | .reveal h4, 43 | .reveal h5, 44 | .reveal h6 { 45 | margin: 0 0 20px 0; 46 | color: #eee; 47 | font-family: "Montserrat", Impact, sans-serif; 48 | font-weight: normal; 49 | line-height: 1.2; 50 | letter-spacing: -0.03em; 51 | text-transform: none; 52 | text-shadow: none; 53 | word-wrap: break-word; } 54 | 55 | .reveal h1 { 56 | font-size: 3.77em; } 57 | 58 | .reveal h2 { 59 | font-size: 2.11em; } 60 | 61 | .reveal h3 { 62 | font-size: 1.55em; } 63 | 64 | .reveal h4 { 65 | font-size: 1em; } 66 | 67 | .reveal h1 { 68 | text-shadow: none; } 69 | 70 | /********************************************* 71 | * OTHER 72 | *********************************************/ 73 | .reveal p { 74 | margin: 20px 0; 75 | line-height: 1.3; } 76 | 77 | /* Ensure certain elements are never larger than the slide itself */ 78 | .reveal img, 79 | .reveal video, 80 | .reveal iframe { 81 | max-width: 95%; 82 | max-height: 95%; } 83 | 84 | .reveal strong, 85 | .reveal b { 86 | font-weight: bold; } 87 | 88 | .reveal em { 89 | font-style: italic; } 90 | 91 | .reveal ol, 92 | .reveal dl, 93 | .reveal ul { 94 | display: inline-block; 95 | text-align: left; 96 | margin: 0 0 0 1em; } 97 | 98 | .reveal ol { 99 | list-style-type: decimal; } 100 | 101 | .reveal ul { 102 | list-style-type: disc; } 103 | 104 | .reveal ul ul { 105 | list-style-type: square; } 106 | 107 | .reveal ul ul ul { 108 | list-style-type: circle; } 109 | 110 | .reveal ul ul, 111 | .reveal ul ol, 112 | .reveal ol ol, 113 | .reveal ol ul { 114 | display: block; 115 | margin-left: 40px; } 116 | 117 | .reveal dt { 118 | font-weight: bold; } 119 | 120 | .reveal dd { 121 | margin-left: 40px; } 122 | 123 | .reveal blockquote { 124 | display: block; 125 | position: relative; 126 | width: 70%; 127 | margin: 20px auto; 128 | padding: 5px; 129 | font-style: italic; 130 | background: rgba(255, 255, 255, 0.05); 131 | box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); } 132 | 133 | .reveal blockquote p:first-child, 134 | .reveal blockquote p:last-child { 135 | display: inline-block; } 136 | 137 | .reveal q { 138 | font-style: italic; } 139 | 140 | .reveal pre { 141 | display: block; 142 | position: relative; 143 | width: 90%; 144 | margin: 20px auto; 145 | text-align: left; 146 | font-size: 0.55em; 147 | font-family: monospace; 148 | line-height: 1.2em; 149 | word-wrap: break-word; 150 | box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); } 151 | 152 | .reveal code { 153 | font-family: monospace; 154 | text-transform: none; } 155 | 156 | .reveal pre code { 157 | display: block; 158 | padding: 5px; 159 | overflow: auto; 160 | max-height: 400px; 161 | word-wrap: normal; } 162 | 163 | .reveal table { 164 | margin: auto; 165 | border-collapse: collapse; 166 | border-spacing: 0; } 167 | 168 | .reveal table th { 169 | font-weight: bold; } 170 | 171 | .reveal table th, 172 | .reveal table td { 173 | text-align: left; 174 | padding: 0.2em 0.5em 0.2em 0.5em; 175 | border-bottom: 1px solid; } 176 | 177 | .reveal table th[align="center"], 178 | .reveal table td[align="center"] { 179 | text-align: center; } 180 | 181 | .reveal table th[align="right"], 182 | .reveal table td[align="right"] { 183 | text-align: right; } 184 | 185 | .reveal table tbody tr:last-child th, 186 | .reveal table tbody tr:last-child td { 187 | border-bottom: none; } 188 | 189 | .reveal sup { 190 | vertical-align: super; } 191 | 192 | .reveal sub { 193 | vertical-align: sub; } 194 | 195 | .reveal small { 196 | display: inline-block; 197 | font-size: 0.6em; 198 | line-height: 1.2em; 199 | vertical-align: top; } 200 | 201 | .reveal small * { 202 | vertical-align: top; } 203 | 204 | /********************************************* 205 | * LINKS 206 | *********************************************/ 207 | .reveal a { 208 | color: #e7ad52; 209 | text-decoration: none; 210 | -webkit-transition: color .15s ease; 211 | -moz-transition: color .15s ease; 212 | transition: color .15s ease; } 213 | 214 | .reveal a:hover { 215 | color: #f3d7ac; 216 | text-shadow: none; 217 | border: none; } 218 | 219 | .reveal .roll span:after { 220 | color: #fff; 221 | background: #d08a1d; } 222 | 223 | /********************************************* 224 | * IMAGES 225 | *********************************************/ 226 | .reveal section img { 227 | margin: 15px 0px; 228 | background: rgba(255, 255, 255, 0.12); 229 | border: 4px solid #eee; 230 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } 231 | 232 | .reveal section img.plain { 233 | border: 0; 234 | box-shadow: none; } 235 | 236 | .reveal a img { 237 | -webkit-transition: all .15s linear; 238 | -moz-transition: all .15s linear; 239 | transition: all .15s linear; } 240 | 241 | .reveal a:hover img { 242 | background: rgba(255, 255, 255, 0.2); 243 | border-color: #e7ad52; 244 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } 245 | 246 | /********************************************* 247 | * NAVIGATION CONTROLS 248 | *********************************************/ 249 | .reveal .controls { 250 | color: #e7ad52; } 251 | 252 | /********************************************* 253 | * PROGRESS BAR 254 | *********************************************/ 255 | .reveal .progress { 256 | background: rgba(0, 0, 0, 0.2); 257 | color: #e7ad52; } 258 | 259 | .reveal .progress span { 260 | -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 261 | -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 262 | transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); } 263 | -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/beige.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Beige theme for reveal.js. 3 | * 4 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | 8 | // Default mixins and settings ----------------- 9 | @import "../template/mixins"; 10 | @import "../template/settings"; 11 | // --------------------------------------------- 12 | 13 | 14 | 15 | // Include theme-specific fonts 16 | @import url(../../lib/font/league-gothic/league-gothic.css); 17 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 18 | 19 | 20 | // Override theme settings (see ../template/settings.scss) 21 | $mainColor: #333; 22 | $headingColor: #333; 23 | $headingTextShadow: none; 24 | $backgroundColor: #f7f3de; 25 | $linkColor: #8b743d; 26 | $linkColorHover: lighten( $linkColor, 20% ); 27 | $selectionBackgroundColor: rgba(79, 64, 28, 0.99); 28 | $heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); 29 | 30 | // Background generator 31 | @mixin bodyBackground() { 32 | @include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) ); 33 | } 34 | 35 | 36 | 37 | // Theme template ------------------------------ 38 | @import "../template/theme"; 39 | // --------------------------------------------- -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/black.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Black theme for reveal.js. This is the opposite of the 'white' theme. 3 | * 4 | * By Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | 8 | // Default mixins and settings ----------------- 9 | @import "../template/mixins"; 10 | @import "../template/settings"; 11 | // --------------------------------------------- 12 | 13 | 14 | // Include theme-specific fonts 15 | @import url(../../lib/font/source-sans-pro/source-sans-pro.css); 16 | 17 | 18 | // Override theme settings (see ../template/settings.scss) 19 | $backgroundColor: #222; 20 | 21 | $mainColor: #fff; 22 | $headingColor: #fff; 23 | 24 | $mainFontSize: 42px; 25 | $mainFont: 'Source Sans Pro', Helvetica, sans-serif; 26 | $headingFont: 'Source Sans Pro', Helvetica, sans-serif; 27 | $headingTextShadow: none; 28 | $headingLetterSpacing: normal; 29 | $headingTextTransform: uppercase; 30 | $headingFontWeight: 600; 31 | $linkColor: #42affa; 32 | $linkColorHover: lighten( $linkColor, 15% ); 33 | $selectionBackgroundColor: lighten( $linkColor, 25% ); 34 | 35 | $heading1Size: 2.5em; 36 | $heading2Size: 1.6em; 37 | $heading3Size: 1.3em; 38 | $heading4Size: 1.0em; 39 | 40 | section.has-light-background { 41 | &, h1, h2, h3, h4, h5, h6 { 42 | color: #222; 43 | } 44 | } 45 | 46 | 47 | // Theme template ------------------------------ 48 | @import "../template/theme"; 49 | // --------------------------------------------- -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/blood.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Blood theme for reveal.js 3 | * Author: Walther http://github.com/Walther 4 | * 5 | * Designed to be used with highlight.js theme 6 | * "monokai_sublime.css" available from 7 | * https://github.com/isagalaev/highlight.js/ 8 | * 9 | * For other themes, change $codeBackground accordingly. 10 | * 11 | */ 12 | 13 | // Default mixins and settings ----------------- 14 | @import "../template/mixins"; 15 | @import "../template/settings"; 16 | // --------------------------------------------- 17 | 18 | // Include theme-specific fonts 19 | 20 | @import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic); 21 | 22 | // Colors used in the theme 23 | $blood: #a23; 24 | $coal: #222; 25 | $codeBackground: #23241f; 26 | 27 | $backgroundColor: $coal; 28 | 29 | // Main text 30 | $mainFont: Ubuntu, 'sans-serif'; 31 | $mainColor: #eee; 32 | 33 | // Headings 34 | $headingFont: Ubuntu, 'sans-serif'; 35 | $headingTextShadow: 2px 2px 2px $coal; 36 | 37 | // h1 shadow, borrowed humbly from 38 | // (c) Default theme by Hakim El Hattab 39 | $heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); 40 | 41 | // Links 42 | $linkColor: $blood; 43 | $linkColorHover: lighten( $linkColor, 20% ); 44 | 45 | // Text selection 46 | $selectionBackgroundColor: $blood; 47 | $selectionColor: #fff; 48 | 49 | 50 | // Theme template ------------------------------ 51 | @import "../template/theme"; 52 | // --------------------------------------------- 53 | 54 | // some overrides after theme template import 55 | 56 | .reveal p { 57 | font-weight: 300; 58 | text-shadow: 1px 1px $coal; 59 | } 60 | 61 | .reveal h1, 62 | .reveal h2, 63 | .reveal h3, 64 | .reveal h4, 65 | .reveal h5, 66 | .reveal h6 { 67 | font-weight: 700; 68 | } 69 | 70 | .reveal p code { 71 | background-color: $codeBackground; 72 | display: inline-block; 73 | border-radius: 7px; 74 | } 75 | 76 | .reveal small code { 77 | vertical-align: baseline; 78 | } -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/league.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * League theme for reveal.js. 3 | * 4 | * This was the default theme pre-3.0.0. 5 | * 6 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 7 | */ 8 | 9 | 10 | // Default mixins and settings ----------------- 11 | @import "../template/mixins"; 12 | @import "../template/settings"; 13 | // --------------------------------------------- 14 | 15 | 16 | 17 | // Include theme-specific fonts 18 | @import url(../../lib/font/league-gothic/league-gothic.css); 19 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 20 | 21 | // Override theme settings (see ../template/settings.scss) 22 | $headingTextShadow: 0px 0px 6px rgba(0,0,0,0.2); 23 | $heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15); 24 | 25 | // Background generator 26 | @mixin bodyBackground() { 27 | @include radial-gradient( rgba(28,30,32,1), rgba(85,90,95,1) ); 28 | } 29 | 30 | 31 | 32 | // Theme template ------------------------------ 33 | @import "../template/theme"; 34 | // --------------------------------------------- -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/moon.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Solarized Dark theme for reveal.js. 3 | * Author: Achim Staebler 4 | */ 5 | 6 | 7 | // Default mixins and settings ----------------- 8 | @import "../template/mixins"; 9 | @import "../template/settings"; 10 | // --------------------------------------------- 11 | 12 | 13 | 14 | // Include theme-specific fonts 15 | @import url(../../lib/font/league-gothic/league-gothic.css); 16 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 17 | 18 | /** 19 | * Solarized colors by Ethan Schoonover 20 | */ 21 | html * { 22 | color-profile: sRGB; 23 | rendering-intent: auto; 24 | } 25 | 26 | // Solarized colors 27 | $base03: #002b36; 28 | $base02: #073642; 29 | $base01: #586e75; 30 | $base00: #657b83; 31 | $base0: #839496; 32 | $base1: #93a1a1; 33 | $base2: #eee8d5; 34 | $base3: #fdf6e3; 35 | $yellow: #b58900; 36 | $orange: #cb4b16; 37 | $red: #dc322f; 38 | $magenta: #d33682; 39 | $violet: #6c71c4; 40 | $blue: #268bd2; 41 | $cyan: #2aa198; 42 | $green: #859900; 43 | 44 | // Override theme settings (see ../template/settings.scss) 45 | $mainColor: $base1; 46 | $headingColor: $base2; 47 | $headingTextShadow: none; 48 | $backgroundColor: $base03; 49 | $linkColor: $blue; 50 | $linkColorHover: lighten( $linkColor, 20% ); 51 | $selectionBackgroundColor: $magenta; 52 | 53 | 54 | 55 | // Theme template ------------------------------ 56 | @import "../template/theme"; 57 | // --------------------------------------------- 58 | -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/night.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Black theme for reveal.js. 3 | * 4 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | 8 | // Default mixins and settings ----------------- 9 | @import "../template/mixins"; 10 | @import "../template/settings"; 11 | // --------------------------------------------- 12 | 13 | 14 | // Include theme-specific fonts 15 | @import url(https://fonts.googleapis.com/css?family=Montserrat:700); 16 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic); 17 | 18 | 19 | // Override theme settings (see ../template/settings.scss) 20 | $backgroundColor: #111; 21 | 22 | $mainFont: 'Open Sans', sans-serif; 23 | $linkColor: #e7ad52; 24 | $linkColorHover: lighten( $linkColor, 20% ); 25 | $headingFont: 'Montserrat', Impact, sans-serif; 26 | $headingTextShadow: none; 27 | $headingLetterSpacing: -0.03em; 28 | $headingTextTransform: none; 29 | $selectionBackgroundColor: #e7ad52; 30 | 31 | 32 | // Theme template ------------------------------ 33 | @import "../template/theme"; 34 | // --------------------------------------------- -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/serif.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple theme for reveal.js presentations, similar 3 | * to the default theme. The accent color is brown. 4 | * 5 | * This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed. 6 | */ 7 | 8 | 9 | // Default mixins and settings ----------------- 10 | @import "../template/mixins"; 11 | @import "../template/settings"; 12 | // --------------------------------------------- 13 | 14 | 15 | 16 | // Override theme settings (see ../template/settings.scss) 17 | $mainFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; 18 | $mainColor: #000; 19 | $headingFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; 20 | $headingColor: #383D3D; 21 | $headingTextShadow: none; 22 | $headingTextTransform: none; 23 | $backgroundColor: #F0F1EB; 24 | $linkColor: #51483D; 25 | $linkColorHover: lighten( $linkColor, 20% ); 26 | $selectionBackgroundColor: #26351C; 27 | 28 | .reveal a { 29 | line-height: 1.3em; 30 | } 31 | 32 | 33 | // Theme template ------------------------------ 34 | @import "../template/theme"; 35 | // --------------------------------------------- 36 | -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/simple.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple theme for reveal.js presentations, similar 3 | * to the default theme. The accent color is darkblue. 4 | * 5 | * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. 6 | * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 7 | */ 8 | 9 | 10 | // Default mixins and settings ----------------- 11 | @import "../template/mixins"; 12 | @import "../template/settings"; 13 | // --------------------------------------------- 14 | 15 | 16 | 17 | // Include theme-specific fonts 18 | @import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700); 19 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 20 | 21 | 22 | // Override theme settings (see ../template/settings.scss) 23 | $mainFont: 'Lato', sans-serif; 24 | $mainColor: #000; 25 | $headingFont: 'News Cycle', Impact, sans-serif; 26 | $headingColor: #000; 27 | $headingTextShadow: none; 28 | $headingTextTransform: none; 29 | $backgroundColor: #fff; 30 | $linkColor: #00008B; 31 | $linkColorHover: lighten( $linkColor, 20% ); 32 | $selectionBackgroundColor: rgba(0, 0, 0, 0.99); 33 | 34 | section.has-dark-background { 35 | &, h1, h2, h3, h4, h5, h6 { 36 | color: #fff; 37 | } 38 | } 39 | 40 | 41 | // Theme template ------------------------------ 42 | @import "../template/theme"; 43 | // --------------------------------------------- -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/sky.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Sky theme for reveal.js. 3 | * 4 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | 8 | // Default mixins and settings ----------------- 9 | @import "../template/mixins"; 10 | @import "../template/settings"; 11 | // --------------------------------------------- 12 | 13 | 14 | 15 | // Include theme-specific fonts 16 | @import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic); 17 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700); 18 | 19 | 20 | // Override theme settings (see ../template/settings.scss) 21 | $mainFont: 'Open Sans', sans-serif; 22 | $mainColor: #333; 23 | $headingFont: 'Quicksand', sans-serif; 24 | $headingColor: #333; 25 | $headingLetterSpacing: -0.08em; 26 | $headingTextShadow: none; 27 | $backgroundColor: #f7fbfc; 28 | $linkColor: #3b759e; 29 | $linkColorHover: lighten( $linkColor, 20% ); 30 | $selectionBackgroundColor: #134674; 31 | 32 | // Fix links so they are not cut off 33 | .reveal a { 34 | line-height: 1.3em; 35 | } 36 | 37 | // Background generator 38 | @mixin bodyBackground() { 39 | @include radial-gradient( #add9e4, #f7fbfc ); 40 | } 41 | 42 | 43 | 44 | // Theme template ------------------------------ 45 | @import "../template/theme"; 46 | // --------------------------------------------- 47 | -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/solarized.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Solarized Light theme for reveal.js. 3 | * Author: Achim Staebler 4 | */ 5 | 6 | 7 | // Default mixins and settings ----------------- 8 | @import "../template/mixins"; 9 | @import "../template/settings"; 10 | // --------------------------------------------- 11 | 12 | 13 | 14 | // Include theme-specific fonts 15 | @import url(../../lib/font/league-gothic/league-gothic.css); 16 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 17 | 18 | 19 | /** 20 | * Solarized colors by Ethan Schoonover 21 | */ 22 | html * { 23 | color-profile: sRGB; 24 | rendering-intent: auto; 25 | } 26 | 27 | // Solarized colors 28 | $base03: #002b36; 29 | $base02: #073642; 30 | $base01: #586e75; 31 | $base00: #657b83; 32 | $base0: #839496; 33 | $base1: #93a1a1; 34 | $base2: #eee8d5; 35 | $base3: #fdf6e3; 36 | $yellow: #b58900; 37 | $orange: #cb4b16; 38 | $red: #dc322f; 39 | $magenta: #d33682; 40 | $violet: #6c71c4; 41 | $blue: #268bd2; 42 | $cyan: #2aa198; 43 | $green: #859900; 44 | 45 | // Override theme settings (see ../template/settings.scss) 46 | $mainColor: $base00; 47 | $headingColor: $base01; 48 | $headingTextShadow: none; 49 | $backgroundColor: $base3; 50 | $linkColor: $blue; 51 | $linkColorHover: lighten( $linkColor, 20% ); 52 | $selectionBackgroundColor: $magenta; 53 | 54 | // Background generator 55 | // @mixin bodyBackground() { 56 | // @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) ); 57 | // } 58 | 59 | 60 | 61 | // Theme template ------------------------------ 62 | @import "../template/theme"; 63 | // --------------------------------------------- 64 | -------------------------------------------------------------------------------- /site/reveal.js/css/theme/source/white.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * White theme for reveal.js. This is the opposite of the 'black' theme. 3 | * 4 | * By Hakim El Hattab, http://hakim.se 5 | */ 6 | 7 | 8 | // Default mixins and settings ----------------- 9 | @import "../template/mixins"; 10 | @import "../template/settings"; 11 | // --------------------------------------------- 12 | 13 | 14 | // Include theme-specific fonts 15 | @import url(../../lib/font/source-sans-pro/source-sans-pro.css); 16 | 17 | 18 | // Override theme settings (see ../template/settings.scss) 19 | $backgroundColor: #fff; 20 | 21 | $mainColor: #222; 22 | $headingColor: #222; 23 | 24 | $mainFontSize: 42px; 25 | $mainFont: 'Source Sans Pro', Helvetica, sans-serif; 26 | $headingFont: 'Source Sans Pro', Helvetica, sans-serif; 27 | $headingTextShadow: none; 28 | $headingLetterSpacing: normal; 29 | $headingTextTransform: uppercase; 30 | $headingFontWeight: 600; 31 | $linkColor: #2a76dd; 32 | $linkColorHover: lighten( $linkColor, 15% ); 33 | $selectionBackgroundColor: lighten( $linkColor, 25% ); 34 | 35 | $heading1Size: 2.5em; 36 | $heading2Size: 1.6em; 37 | $heading3Size: 1.3em; 38 | $heading4Size: 1.0em; 39 | 40 | section.has-dark-background { 41 | &, h1, h2, h3, h4, h5, h6 { 42 | color: #fff; 43 | } 44 | } 45 | 46 | 47 | // Theme template ------------------------------ 48 | @import "../template/theme"; 49 | // --------------------------------------------- -------------------------------------------------------------------------------- /site/reveal.js/css/theme/template/mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin vertical-gradient( $top, $bottom ) { 2 | background: $top; 3 | background: -moz-linear-gradient( top, $top 0%, $bottom 100% ); 4 | background: -webkit-gradient( linear, left top, left bottom, color-stop(0%,$top), color-stop(100%,$bottom) ); 5 | background: -webkit-linear-gradient( top, $top 0%, $bottom 100% ); 6 | background: -o-linear-gradient( top, $top 0%, $bottom 100% ); 7 | background: -ms-linear-gradient( top, $top 0%, $bottom 100% ); 8 | background: linear-gradient( top, $top 0%, $bottom 100% ); 9 | } 10 | 11 | @mixin horizontal-gradient( $top, $bottom ) { 12 | background: $top; 13 | background: -moz-linear-gradient( left, $top 0%, $bottom 100% ); 14 | background: -webkit-gradient( linear, left top, right top, color-stop(0%,$top), color-stop(100%,$bottom) ); 15 | background: -webkit-linear-gradient( left, $top 0%, $bottom 100% ); 16 | background: -o-linear-gradient( left, $top 0%, $bottom 100% ); 17 | background: -ms-linear-gradient( left, $top 0%, $bottom 100% ); 18 | background: linear-gradient( left, $top 0%, $bottom 100% ); 19 | } 20 | 21 | @mixin radial-gradient( $outer, $inner, $type: circle ) { 22 | background: $outer; 23 | background: -moz-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); 24 | background: -webkit-gradient( radial, center center, 0px, center center, 100%, color-stop(0%,$inner), color-stop(100%,$outer) ); 25 | background: -webkit-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); 26 | background: -o-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); 27 | background: -ms-radial-gradient( center, $type cover, $inner 0%, $outer 100% ); 28 | background: radial-gradient( center, $type cover, $inner 0%, $outer 100% ); 29 | } -------------------------------------------------------------------------------- /site/reveal.js/css/theme/template/settings.scss: -------------------------------------------------------------------------------- 1 | // Base settings for all themes that can optionally be 2 | // overridden by the super-theme 3 | 4 | // Background of the presentation 5 | $backgroundColor: #2b2b2b; 6 | 7 | // Primary/body text 8 | $mainFont: 'Lato', sans-serif; 9 | $mainFontSize: 40px; 10 | $mainColor: #eee; 11 | 12 | // Vertical spacing between blocks of text 13 | $blockMargin: 20px; 14 | 15 | // Headings 16 | $headingMargin: 0 0 $blockMargin 0; 17 | $headingFont: 'League Gothic', Impact, sans-serif; 18 | $headingColor: #eee; 19 | $headingLineHeight: 1.2; 20 | $headingLetterSpacing: normal; 21 | $headingTextTransform: uppercase; 22 | $headingTextShadow: none; 23 | $headingFontWeight: normal; 24 | $heading1TextShadow: $headingTextShadow; 25 | 26 | $heading1Size: 3.77em; 27 | $heading2Size: 2.11em; 28 | $heading3Size: 1.55em; 29 | $heading4Size: 1.00em; 30 | 31 | // Links and actions 32 | $linkColor: #13DAEC; 33 | $linkColorHover: lighten( $linkColor, 20% ); 34 | 35 | // Text selection 36 | $selectionBackgroundColor: #FF5E99; 37 | $selectionColor: #fff; 38 | 39 | // Generates the presentation background, can be overridden 40 | // to return a background image or gradient 41 | @mixin bodyBackground() { 42 | background: $backgroundColor; 43 | } -------------------------------------------------------------------------------- /site/reveal.js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 23 | 24 | 25 |
26 |
27 |
Slide 1
28 |
Slide 2
29 |
30 |
31 | 32 | 33 | 34 | 35 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /site/reveal.js/lib/css/zenburn.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Zenburn style from voldmar.ru (c) Vladimir Epifanov 4 | based on dark.css by Ivan Sagalaev 5 | 6 | */ 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | background: #3f3f3f; 13 | color: #dcdcdc; 14 | } 15 | 16 | .hljs-keyword, 17 | .hljs-selector-tag, 18 | .hljs-tag { 19 | color: #e3ceab; 20 | } 21 | 22 | .hljs-template-tag { 23 | color: #dcdcdc; 24 | } 25 | 26 | .hljs-number { 27 | color: #8cd0d3; 28 | } 29 | 30 | .hljs-variable, 31 | .hljs-template-variable, 32 | .hljs-attribute { 33 | color: #efdcbc; 34 | } 35 | 36 | .hljs-literal { 37 | color: #efefaf; 38 | } 39 | 40 | .hljs-subst { 41 | color: #8f8f8f; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-name, 46 | .hljs-selector-id, 47 | .hljs-selector-class, 48 | .hljs-section, 49 | .hljs-type { 50 | color: #efef8f; 51 | } 52 | 53 | .hljs-symbol, 54 | .hljs-bullet, 55 | .hljs-link { 56 | color: #dca3a3; 57 | } 58 | 59 | .hljs-deletion, 60 | .hljs-string, 61 | .hljs-built_in, 62 | .hljs-builtin-name { 63 | color: #cc9393; 64 | } 65 | 66 | .hljs-addition, 67 | .hljs-comment, 68 | .hljs-quote, 69 | .hljs-meta { 70 | color: #7f9f7f; 71 | } 72 | 73 | 74 | .hljs-emphasis { 75 | font-style: italic; 76 | } 77 | 78 | .hljs-strong { 79 | font-weight: bold; 80 | } 81 | -------------------------------------------------------------------------------- /site/reveal.js/lib/font/league-gothic/LICENSE: -------------------------------------------------------------------------------- 1 | SIL Open Font License (OFL) 2 | http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL 3 | -------------------------------------------------------------------------------- /site/reveal.js/lib/font/league-gothic/league-gothic.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'League Gothic'; 3 | src: url('league-gothic.eot'); 4 | src: url('league-gothic.eot?#iefix') format('embedded-opentype'), 5 | url('league-gothic.woff') format('woff'), 6 | url('league-gothic.ttf') format('truetype'); 7 | 8 | font-weight: normal; 9 | font-style: normal; 10 | } -------------------------------------------------------------------------------- /site/reveal.js/lib/font/league-gothic/league-gothic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/league-gothic/league-gothic.eot -------------------------------------------------------------------------------- /site/reveal.js/lib/font/league-gothic/league-gothic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/league-gothic/league-gothic.ttf -------------------------------------------------------------------------------- /site/reveal.js/lib/font/league-gothic/league-gothic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/league-gothic/league-gothic.woff -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/LICENSE: -------------------------------------------------------------------------------- 1 | SIL Open Font License 2 | 3 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. 4 | 5 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 6 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL 7 | 8 | —————————————————————————————- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | —————————————————————————————- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. 14 | 15 | The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. 16 | 17 | DEFINITIONS 18 | “Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. 19 | 20 | “Reserved Font Name” refers to any names specified as such after the copyright statement(s). 21 | 22 | “Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s). 23 | 24 | “Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. 25 | 26 | “Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. 27 | 28 | PERMISSION & CONDITIONS 29 | Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 30 | 31 | 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 32 | 33 | 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 34 | 35 | 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 36 | 37 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 38 | 39 | 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. 40 | 41 | TERMINATION 42 | This license becomes null and void if any of the above conditions are not met. 43 | 44 | DISCLAIMER 45 | THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.eot -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.ttf -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.woff -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.eot -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.ttf -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.woff -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.eot -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.ttf -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.woff -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.eot -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.ttf -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.woff -------------------------------------------------------------------------------- /site/reveal.js/lib/font/source-sans-pro/source-sans-pro.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Source Sans Pro'; 3 | src: url('source-sans-pro-regular.eot'); 4 | src: url('source-sans-pro-regular.eot?#iefix') format('embedded-opentype'), 5 | url('source-sans-pro-regular.woff') format('woff'), 6 | url('source-sans-pro-regular.ttf') format('truetype'); 7 | font-weight: normal; 8 | font-style: normal; 9 | } 10 | 11 | @font-face { 12 | font-family: 'Source Sans Pro'; 13 | src: url('source-sans-pro-italic.eot'); 14 | src: url('source-sans-pro-italic.eot?#iefix') format('embedded-opentype'), 15 | url('source-sans-pro-italic.woff') format('woff'), 16 | url('source-sans-pro-italic.ttf') format('truetype'); 17 | font-weight: normal; 18 | font-style: italic; 19 | } 20 | 21 | @font-face { 22 | font-family: 'Source Sans Pro'; 23 | src: url('source-sans-pro-semibold.eot'); 24 | src: url('source-sans-pro-semibold.eot?#iefix') format('embedded-opentype'), 25 | url('source-sans-pro-semibold.woff') format('woff'), 26 | url('source-sans-pro-semibold.ttf') format('truetype'); 27 | font-weight: 600; 28 | font-style: normal; 29 | } 30 | 31 | @font-face { 32 | font-family: 'Source Sans Pro'; 33 | src: url('source-sans-pro-semibolditalic.eot'); 34 | src: url('source-sans-pro-semibolditalic.eot?#iefix') format('embedded-opentype'), 35 | url('source-sans-pro-semibolditalic.woff') format('woff'), 36 | url('source-sans-pro-semibolditalic.ttf') format('truetype'); 37 | font-weight: 600; 38 | font-style: italic; 39 | } -------------------------------------------------------------------------------- /site/reveal.js/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=4.0.0" 24 | }, 25 | "devDependencies": { 26 | "express": "^4.15.2", 27 | "grunt": "^1.0.1", 28 | "grunt-autoprefixer": "^3.0.4", 29 | "grunt-cli": "^1.2.0", 30 | "grunt-contrib-connect": "^1.0.2", 31 | "grunt-contrib-cssmin": "^2.1.0", 32 | "grunt-contrib-jshint": "^1.1.0", 33 | "grunt-contrib-qunit": "~1.2.0", 34 | "grunt-contrib-uglify": "^2.3.0", 35 | "grunt-contrib-watch": "^1.0.0", 36 | "grunt-sass": "^2.0.0", 37 | "grunt-retire": "^1.0.7", 38 | "grunt-zip": "~0.17.1", 39 | "mustache": "^2.3.0", 40 | "socket.io": "^1.7.3" 41 | }, 42 | "license": "MIT" 43 | } 44 | -------------------------------------------------------------------------------- /site/reveal.js/plugin/markdown/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Markdown Demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 | 21 | 22 |
23 | 24 | 25 |
26 | 36 |
37 | 38 | 39 |
40 | 54 |
55 | 56 | 57 |
58 | 69 |
70 | 71 | 72 |
73 | 77 |
78 | 79 | 80 |
81 | 86 |
87 | 88 | 89 |
90 | 100 |
101 | 102 |
103 |
104 | 105 | 106 | 107 | 108 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /site/reveal.js/plugin/markdown/example.md: -------------------------------------------------------------------------------- 1 | # Markdown Demo 2 | 3 | 4 | 5 | ## External 1.1 6 | 7 | Content 1.1 8 | 9 | Note: This will only appear in the speaker notes window. 10 | 11 | 12 | ## External 1.2 13 | 14 | Content 1.2 15 | 16 | 17 | 18 | ## External 2 19 | 20 | Content 2.1 21 | 22 | 23 | 24 | ## External 3.1 25 | 26 | Content 3.1 27 | 28 | 29 | ## External 3.2 30 | 31 | Content 3.2 32 | -------------------------------------------------------------------------------- /site/reveal.js/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 || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/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: { 18 | inlineMath: [['$','$'],['\\(','\\)']] , 19 | skipTags: ['script','noscript','style','textarea','pre'] 20 | }, 21 | skipStartupTypeset: true 22 | }); 23 | 24 | // Typeset followed by an immediate reveal.js layout since 25 | // the typesetting process could affect slide height 26 | MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] ); 27 | MathJax.Hub.Queue( Reveal.layout ); 28 | 29 | // Reprocess equations in slides when they turn visible 30 | Reveal.addEventListener( 'slidechanged', function( event ) { 31 | 32 | MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] ); 33 | 34 | } ); 35 | 36 | } ); 37 | 38 | function loadScript( url, callback ) { 39 | 40 | var head = document.querySelector( 'head' ); 41 | var script = document.createElement( 'script' ); 42 | script.type = 'text/javascript'; 43 | script.src = url; 44 | 45 | // Wrapper for callback to make sure it only fires once 46 | var finish = function() { 47 | if( typeof callback === 'function' ) { 48 | callback.call(); 49 | callback = null; 50 | } 51 | } 52 | 53 | script.onload = finish; 54 | 55 | // IE 56 | script.onreadystatechange = function() { 57 | if ( this.readyState === 'loaded' ) { 58 | finish(); 59 | } 60 | } 61 | 62 | // Normal browsers 63 | head.appendChild( script ); 64 | 65 | } 66 | 67 | })(); 68 | -------------------------------------------------------------------------------- /site/reveal.js/plugin/multiplex/client.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var multiplex = Reveal.getConfig().multiplex; 3 | var socketId = multiplex.id; 4 | var socket = io.connect(multiplex.url); 5 | 6 | socket.on(multiplex.id, function(data) { 7 | // ignore data from sockets that aren't ours 8 | if (data.socketId !== socketId) { return; } 9 | if( window.location.host === 'localhost:1947' ) return; 10 | 11 | Reveal.setState(data.state); 12 | }); 13 | }()); 14 | -------------------------------------------------------------------------------- /site/reveal.js/plugin/multiplex/index.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var express = require('express'); 3 | var fs = require('fs'); 4 | var io = require('socket.io'); 5 | var crypto = require('crypto'); 6 | 7 | var app = express(); 8 | var staticDir = express.static; 9 | var server = http.createServer(app); 10 | 11 | io = io(server); 12 | 13 | var opts = { 14 | port: process.env.PORT || 1948, 15 | baseDir : __dirname + '/../../' 16 | }; 17 | 18 | io.on( 'connection', function( socket ) { 19 | socket.on('multiplex-statechanged', function(data) { 20 | if (typeof data.secret == 'undefined' || data.secret == null || data.secret === '') return; 21 | if (createHash(data.secret) === data.socketId) { 22 | data.secret = null; 23 | socket.broadcast.emit(data.socketId, data); 24 | }; 25 | }); 26 | }); 27 | 28 | [ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) { 29 | app.use('/' + dir, staticDir(opts.baseDir + dir)); 30 | }); 31 | 32 | app.get("/", function(req, res) { 33 | res.writeHead(200, {'Content-Type': 'text/html'}); 34 | 35 | var stream = fs.createReadStream(opts.baseDir + '/index.html'); 36 | stream.on('error', function( error ) { 37 | res.write('

reveal.js multiplex server.

Generate token'); 38 | res.end(); 39 | }); 40 | stream.on('readable', function() { 41 | stream.pipe(res); 42 | }); 43 | }); 44 | 45 | app.get("/token", function(req,res) { 46 | var ts = new Date().getTime(); 47 | var rand = Math.floor(Math.random()*9999999); 48 | var secret = ts.toString() + rand.toString(); 49 | res.send({secret: secret, socketId: createHash(secret)}); 50 | }); 51 | 52 | var createHash = function(secret) { 53 | var cipher = crypto.createCipher('blowfish', secret); 54 | return(cipher.final('hex')); 55 | }; 56 | 57 | // Actually listen 58 | server.listen( opts.port || null ); 59 | 60 | var brown = '\033[33m', 61 | green = '\033[32m', 62 | reset = '\033[0m'; 63 | 64 | console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset ); -------------------------------------------------------------------------------- /site/reveal.js/plugin/multiplex/master.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // Don't emit events from inside of notes windows 4 | if ( window.location.search.match( /receiver/gi ) ) { return; } 5 | 6 | var multiplex = Reveal.getConfig().multiplex; 7 | 8 | var socket = io.connect( multiplex.url ); 9 | 10 | function post() { 11 | 12 | var messageData = { 13 | state: Reveal.getState(), 14 | secret: multiplex.secret, 15 | socketId: multiplex.id 16 | }; 17 | 18 | socket.emit( 'multiplex-statechanged', messageData ); 19 | 20 | }; 21 | 22 | // post once the page is loaded, so the client follows also on "open URL". 23 | window.addEventListener( 'load', post ); 24 | 25 | // Monitor events that trigger a change in state 26 | Reveal.addEventListener( 'slidechanged', post ); 27 | Reveal.addEventListener( 'fragmentshown', post ); 28 | Reveal.addEventListener( 'fragmenthidden', post ); 29 | Reveal.addEventListener( 'overviewhidden', post ); 30 | Reveal.addEventListener( 'overviewshown', post ); 31 | Reveal.addEventListener( 'paused', post ); 32 | Reveal.addEventListener( 'resumed', post ); 33 | 34 | }()); 35 | -------------------------------------------------------------------------------- /site/reveal.js/plugin/multiplex/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reveal-js-multiplex", 3 | "version": "1.0.0", 4 | "description": "reveal.js multiplex server", 5 | "homepage": "http://revealjs.com", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "engines": { 10 | "node": "~4.1.1" 11 | }, 12 | "dependencies": { 13 | "express": "~4.13.3", 14 | "grunt-cli": "~0.1.13", 15 | "mustache": "~2.2.1", 16 | "socket.io": "~1.3.7" 17 | }, 18 | "license": "MIT" 19 | } 20 | -------------------------------------------------------------------------------- /site/reveal.js/plugin/notes-server/client.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // don't emit events from inside the previews themselves 4 | if( window.location.search.match( /receiver/gi ) ) { return; } 5 | 6 | var socket = io.connect( window.location.origin ), 7 | socketId = Math.random().toString().slice( 2 ); 8 | 9 | console.log( 'View slide notes at ' + window.location.origin + '/notes/' + socketId ); 10 | 11 | window.open( window.location.origin + '/notes/' + socketId, 'notes-' + socketId ); 12 | 13 | /** 14 | * Posts the current slide data to the notes window 15 | */ 16 | function post() { 17 | 18 | var slideElement = Reveal.getCurrentSlide(), 19 | notesElement = slideElement.querySelector( 'aside.notes' ); 20 | 21 | var messageData = { 22 | notes: '', 23 | markdown: false, 24 | socketId: socketId, 25 | state: Reveal.getState() 26 | }; 27 | 28 | // Look for notes defined in a slide attribute 29 | if( slideElement.hasAttribute( 'data-notes' ) ) { 30 | messageData.notes = slideElement.getAttribute( 'data-notes' ); 31 | } 32 | 33 | // Look for notes defined in an aside element 34 | if( notesElement ) { 35 | messageData.notes = notesElement.innerHTML; 36 | messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string'; 37 | } 38 | 39 | socket.emit( 'statechanged', messageData ); 40 | 41 | } 42 | 43 | // When a new notes window connects, post our current state 44 | socket.on( 'new-subscriber', function( data ) { 45 | post(); 46 | } ); 47 | 48 | // When the state changes from inside of the speaker view 49 | socket.on( 'statechanged-speaker', function( data ) { 50 | Reveal.setState( data.state ); 51 | } ); 52 | 53 | // Monitor events that trigger a change in state 54 | Reveal.addEventListener( 'slidechanged', post ); 55 | Reveal.addEventListener( 'fragmentshown', post ); 56 | Reveal.addEventListener( 'fragmenthidden', post ); 57 | Reveal.addEventListener( 'overviewhidden', post ); 58 | Reveal.addEventListener( 'overviewshown', post ); 59 | Reveal.addEventListener( 'paused', post ); 60 | Reveal.addEventListener( 'resumed', post ); 61 | 62 | // Post the initial state 63 | post(); 64 | 65 | }()); 66 | -------------------------------------------------------------------------------- /site/reveal.js/plugin/notes-server/index.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var express = require('express'); 3 | var fs = require('fs'); 4 | var io = require('socket.io'); 5 | var Mustache = require('mustache'); 6 | 7 | var app = express(); 8 | var staticDir = express.static; 9 | var server = http.createServer(app); 10 | 11 | io = io(server); 12 | 13 | var opts = { 14 | port : 1947, 15 | baseDir : __dirname + '/../../' 16 | }; 17 | 18 | io.on( 'connection', function( socket ) { 19 | 20 | socket.on( 'new-subscriber', function( data ) { 21 | socket.broadcast.emit( 'new-subscriber', data ); 22 | }); 23 | 24 | socket.on( 'statechanged', function( data ) { 25 | delete data.state.overview; 26 | socket.broadcast.emit( 'statechanged', data ); 27 | }); 28 | 29 | socket.on( 'statechanged-speaker', function( data ) { 30 | delete data.state.overview; 31 | socket.broadcast.emit( 'statechanged-speaker', data ); 32 | }); 33 | 34 | }); 35 | 36 | [ 'css', 'js', 'images', 'plugin', 'lib' ].forEach( function( dir ) { 37 | app.use( '/' + dir, staticDir( opts.baseDir + dir ) ); 38 | }); 39 | 40 | app.get('/', function( req, res ) { 41 | 42 | res.writeHead( 200, { 'Content-Type': 'text/html' } ); 43 | fs.createReadStream( opts.baseDir + '/index.html' ).pipe( res ); 44 | 45 | }); 46 | 47 | app.get( '/notes/:socketId', function( req, res ) { 48 | 49 | fs.readFile( opts.baseDir + 'plugin/notes-server/notes.html', function( err, data ) { 50 | res.send( Mustache.to_html( data.toString(), { 51 | socketId : req.params.socketId 52 | })); 53 | }); 54 | 55 | }); 56 | 57 | // Actually listen 58 | server.listen( opts.port || null ); 59 | 60 | var brown = '\033[33m', 61 | green = '\033[32m', 62 | reset = '\033[0m'; 63 | 64 | var slidesLocation = 'http://localhost' + ( opts.port ? ( ':' + opts.port ) : '' ); 65 | 66 | console.log( brown + 'reveal.js - Speaker Notes' + reset ); 67 | console.log( '1. Open the slides at ' + green + slidesLocation + reset ); 68 | console.log( '2. Click on the link in your JS console to go to the notes page' ); 69 | console.log( '3. Advance through your slides and your notes will advance automatically' ); 70 | -------------------------------------------------------------------------------- /site/reveal.js/plugin/notes/notes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Handles opening of and synchronization with the reveal.js 3 | * notes window. 4 | * 5 | * Handshake process: 6 | * 1. This window posts 'connect' to notes window 7 | * - Includes URL of presentation to show 8 | * 2. Notes window responds with 'connected' when it is available 9 | * 3. This window proceeds to send the current presentation state 10 | * to the notes window 11 | */ 12 | var RevealNotes = (function() { 13 | 14 | function openNotes( notesFilePath ) { 15 | 16 | if( !notesFilePath ) { 17 | var jsFileLocation = document.querySelector('script[src$="notes.js"]').src; // this js file path 18 | jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, ''); // the js folder path 19 | notesFilePath = jsFileLocation + 'notes.html'; 20 | } 21 | 22 | var notesPopup = window.open( notesFilePath, 'reveal.js - Notes', 'width=1100,height=700' ); 23 | 24 | // Allow popup window access to Reveal API 25 | notesPopup.Reveal = this.Reveal; 26 | 27 | /** 28 | * Connect to the notes window through a postmessage handshake. 29 | * Using postmessage enables us to work in situations where the 30 | * origins differ, such as a presentation being opened from the 31 | * file system. 32 | */ 33 | function connect() { 34 | // Keep trying to connect until we get a 'connected' message back 35 | var connectInterval = setInterval( function() { 36 | notesPopup.postMessage( JSON.stringify( { 37 | namespace: 'reveal-notes', 38 | type: 'connect', 39 | url: window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search, 40 | state: Reveal.getState() 41 | } ), '*' ); 42 | }, 500 ); 43 | 44 | window.addEventListener( 'message', function( event ) { 45 | var data = JSON.parse( event.data ); 46 | if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) { 47 | clearInterval( connectInterval ); 48 | onConnected(); 49 | } 50 | } ); 51 | } 52 | 53 | /** 54 | * Posts the current slide data to the notes window 55 | */ 56 | function post( event ) { 57 | 58 | var slideElement = Reveal.getCurrentSlide(), 59 | notesElement = slideElement.querySelector( 'aside.notes' ), 60 | fragmentElement = slideElement.querySelector( '.current-fragment' ); 61 | 62 | var messageData = { 63 | namespace: 'reveal-notes', 64 | type: 'state', 65 | notes: '', 66 | markdown: false, 67 | whitespace: 'normal', 68 | state: Reveal.getState() 69 | }; 70 | 71 | // Look for notes defined in a slide attribute 72 | if( slideElement.hasAttribute( 'data-notes' ) ) { 73 | messageData.notes = slideElement.getAttribute( 'data-notes' ); 74 | messageData.whitespace = 'pre-wrap'; 75 | } 76 | 77 | // Look for notes defined in a fragment 78 | if( fragmentElement ) { 79 | var fragmentNotes = fragmentElement.querySelector( 'aside.notes' ); 80 | if( fragmentNotes ) { 81 | notesElement = fragmentNotes; 82 | } 83 | else if( fragmentElement.hasAttribute( 'data-notes' ) ) { 84 | messageData.notes = fragmentElement.getAttribute( 'data-notes' ); 85 | messageData.whitespace = 'pre-wrap'; 86 | 87 | // In case there are slide notes 88 | notesElement = null; 89 | } 90 | } 91 | 92 | // Look for notes defined in an aside element 93 | if( notesElement ) { 94 | messageData.notes = notesElement.innerHTML; 95 | messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string'; 96 | } 97 | 98 | notesPopup.postMessage( JSON.stringify( messageData ), '*' ); 99 | 100 | } 101 | 102 | /** 103 | * Called once we have established a connection to the notes 104 | * window. 105 | */ 106 | function onConnected() { 107 | 108 | // Monitor events that trigger a change in state 109 | Reveal.addEventListener( 'slidechanged', post ); 110 | Reveal.addEventListener( 'fragmentshown', post ); 111 | Reveal.addEventListener( 'fragmenthidden', post ); 112 | Reveal.addEventListener( 'overviewhidden', post ); 113 | Reveal.addEventListener( 'overviewshown', post ); 114 | Reveal.addEventListener( 'paused', post ); 115 | Reveal.addEventListener( 'resumed', post ); 116 | 117 | // Post the initial state 118 | post(); 119 | 120 | } 121 | 122 | connect(); 123 | 124 | } 125 | 126 | if( !/receiver/i.test( window.location.search ) ) { 127 | 128 | // If the there's a 'notes' query set, open directly 129 | if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) { 130 | openNotes(); 131 | } 132 | 133 | // Open the notes when the 's' key is hit 134 | document.addEventListener( 'keydown', function( event ) { 135 | // Disregard the event if the target is editable or a 136 | // modifier is present 137 | if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return; 138 | 139 | // Disregard the event if keyboard is disabled 140 | if ( Reveal.getConfig().keyboard === false ) return; 141 | 142 | if( event.keyCode === 83 ) { 143 | event.preventDefault(); 144 | openNotes(); 145 | } 146 | }, false ); 147 | 148 | // Show our keyboard shortcut in the reveal.js help overlay 149 | if( window.Reveal ) Reveal.registerKeyboardShortcut( 'S', 'Speaker notes view' ); 150 | 151 | } 152 | 153 | return { open: openNotes }; 154 | 155 | })(); 156 | -------------------------------------------------------------------------------- /site/reveal.js/plugin/print-pdf/print-pdf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * phantomjs script for printing presentations to PDF. 3 | * 4 | * Example: 5 | * phantomjs print-pdf.js "http://revealjs.com?print-pdf" reveal-demo.pdf 6 | * 7 | * @author Manuel Bieh (https://github.com/manuelbieh) 8 | * @author Hakim El Hattab (https://github.com/hakimel) 9 | * @author Manuel Riezebosch (https://github.com/riezebosch) 10 | */ 11 | 12 | // html2pdf.js 13 | var system = require( 'system' ); 14 | 15 | var probePage = new WebPage(); 16 | var printPage = new WebPage(); 17 | 18 | var inputFile = system.args[1] || 'index.html?print-pdf'; 19 | var outputFile = system.args[2] || 'slides.pdf'; 20 | 21 | if( outputFile.match( /\.pdf$/gi ) === null ) { 22 | outputFile += '.pdf'; 23 | } 24 | 25 | console.log( 'Export PDF: Reading reveal.js config [1/4]' ); 26 | 27 | probePage.open( inputFile, function( status ) { 28 | 29 | console.log( 'Export PDF: Preparing print layout [2/4]' ); 30 | 31 | var config = probePage.evaluate( function() { 32 | return Reveal.getConfig(); 33 | } ); 34 | 35 | if( config ) { 36 | 37 | printPage.paperSize = { 38 | width: Math.floor( config.width * ( 1 + config.margin ) ), 39 | height: Math.floor( config.height * ( 1 + config.margin ) ), 40 | border: 0 41 | }; 42 | 43 | printPage.open( inputFile, function( status ) { 44 | console.log( 'Export PDF: Preparing pdf [3/4]') 45 | printPage.evaluate(function() { 46 | Reveal.isReady() ? window.callPhantom() : Reveal.addEventListener( 'pdf-ready', window.callPhantom ); 47 | }); 48 | } ); 49 | 50 | printPage.onCallback = function(data) { 51 | // For some reason we need to "jump the queue" for syntax highlighting to work. 52 | // See: http://stackoverflow.com/a/3580132/129269 53 | setTimeout(function() { 54 | console.log( 'Export PDF: Writing file [4/4]' ); 55 | printPage.render( outputFile ); 56 | console.log( 'Export PDF: Finished successfully!' ); 57 | phantom.exit(); 58 | }, 0); 59 | }; 60 | } 61 | else { 62 | 63 | console.log( 'Export PDF: Unable to read reveal.js config. Make sure the input address points to a reveal.js page.' ); 64 | phantom.exit(1); 65 | 66 | } 67 | } ); 68 | 69 | 70 | -------------------------------------------------------------------------------- /site/reveal.js/test/examples/assets/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/test/examples/assets/image1.png -------------------------------------------------------------------------------- /site/reveal.js/test/examples/assets/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timothypratley/enterprise-clojure-training/3acf1a47e0de714215a76d75138c0de178259750/site/reveal.js/test/examples/assets/image2.png -------------------------------------------------------------------------------- /site/reveal.js/test/examples/barebones.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Barebones 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 |
17 | 18 |
19 |

Barebones Presentation

20 |

This example contains the bare minimum includes and markup required to run a reveal.js presentation.

21 |
22 | 23 |
24 |

No Theme

25 |

There's no theme included, so it will fall back on browser defaults.

26 |
27 | 28 |
29 | 30 |
31 | 32 | 33 | 34 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /site/reveal.js/test/examples/embedded-media.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Embedded Media 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 | 21 |
22 |

Embedded Media Test

23 |
24 | 25 |
26 | 27 |
28 | 29 |
30 |

Empty Slide

31 |
32 | 33 |
34 | 35 |
36 | 37 | 38 | 39 | 40 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /site/reveal.js/test/examples/math.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Math Plugin 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 | 21 |
22 |

reveal.js Math Plugin

23 |

A thin wrapper for MathJax

24 |
25 | 26 |
27 |

The Lorenz Equations

28 | 29 | \[\begin{aligned} 30 | \dot{x} & = \sigma(y-x) \\ 31 | \dot{y} & = \rho x - y - xz \\ 32 | \dot{z} & = -\beta z + xy 33 | \end{aligned} \] 34 |
35 | 36 |
37 |

The Cauchy-Schwarz Inequality

38 | 39 | 42 |
43 | 44 |
45 |

A Cross Product Formula

46 | 47 | \[\mathbf{V}_1 \times \mathbf{V}_2 = \begin{vmatrix} 48 | \mathbf{i} & \mathbf{j} & \mathbf{k} \\ 49 | \frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\ 50 | \frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0 51 | \end{vmatrix} \] 52 |
53 | 54 |
55 |

The probability of getting \(k\) heads when flipping \(n\) coins is

56 | 57 | \[P(E) = {n \choose k} p^k (1-p)^{ n-k} \] 58 |
59 | 60 |
61 |

An Identity of Ramanujan

62 | 63 | \[ \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 64 | 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} 65 | {1+\frac{e^{-8\pi}} {1+\ldots} } } } \] 66 |
67 | 68 |
69 |

A Rogers-Ramanujan Identity

70 | 71 | \[ 1 + \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots = 72 | \prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}\] 73 |
74 | 75 |
76 |

Maxwell’s Equations

77 | 78 | \[ \begin{aligned} 79 | \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\ \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\ 80 | \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\ 81 | \nabla \cdot \vec{\mathbf{B}} & = 0 \end{aligned} 82 | \] 83 |
84 | 85 |
86 |
87 |

The Lorenz Equations

88 | 89 |
90 | \[\begin{aligned} 91 | \dot{x} & = \sigma(y-x) \\ 92 | \dot{y} & = \rho x - y - xz \\ 93 | \dot{z} & = -\beta z + xy 94 | \end{aligned} \] 95 |
96 |
97 | 98 |
99 |

The Cauchy-Schwarz Inequality

100 | 101 |
102 | \[ \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) \] 103 |
104 |
105 | 106 |
107 |

A Cross Product Formula

108 | 109 |
110 | \[\mathbf{V}_1 \times \mathbf{V}_2 = \begin{vmatrix} 111 | \mathbf{i} & \mathbf{j} & \mathbf{k} \\ 112 | \frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\ 113 | \frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0 114 | \end{vmatrix} \] 115 |
116 |
117 | 118 |
119 |

The probability of getting \(k\) heads when flipping \(n\) coins is

120 | 121 |
122 | \[P(E) = {n \choose k} p^k (1-p)^{ n-k} \] 123 |
124 |
125 | 126 |
127 |

An Identity of Ramanujan

128 | 129 |
130 | \[ \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 131 | 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} 132 | {1+\frac{e^{-8\pi}} {1+\ldots} } } } \] 133 |
134 |
135 | 136 |
137 |

A Rogers-Ramanujan Identity

138 | 139 |
140 | \[ 1 + \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots = 141 | \prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}\] 142 |
143 |
144 | 145 |
146 |

Maxwell’s Equations

147 | 148 |
149 | \[ \begin{aligned} 150 | \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\ \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\ 151 | \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\ 152 | \nabla \cdot \vec{\mathbf{B}} & = 0 \end{aligned} 153 | \] 154 |
155 |
156 |
157 | 158 |
159 | 160 |
161 | 162 | 163 | 164 | 165 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /site/reveal.js/test/examples/slide-backgrounds.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Slide Backgrounds 8 | 9 | 10 | 11 | 12 | 13 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |
32 |

data-background: #00ffff

33 |
34 | 35 |
36 |

data-background: #bb00bb

37 |
38 | 39 |
40 |

data-background: lightblue

41 |
42 | 43 |
44 |
45 |

data-background: #ff0000

46 |
47 |
48 |

data-background: rgba(0, 0, 0, 0.2)

49 |
50 |
51 |

data-background: salmon

52 |
53 |
54 | 55 |
56 |
57 |

Background applied to stack

58 |
59 |
60 |

Background applied to stack

61 |
62 |
63 |

Background applied to slide inside of stack

64 |
65 |
66 | 67 |
68 |

Background image

69 |
70 | 71 |
72 |
73 |

Background image

74 |
75 |
76 |

Background image

77 |
78 |
79 | 80 |
81 |

Background image

82 |
data-background-size="100px" data-background-repeat="repeat" data-background-color="#111"
83 |
84 | 85 |
86 |

Same background twice (1/2)

87 |
88 |
89 |

Same background twice (2/2)

90 |
91 | 92 |
93 |

Video background

94 |
95 | 96 |
97 |

Iframe background

98 |
99 | 100 |
101 |
102 |

Same background twice vertical (1/2)

103 |
104 |
105 |

Same background twice vertical (2/2)

106 |
107 |
108 | 109 |
110 |

Same background from horizontal to vertical (1/3)

111 |
112 |
113 |
114 |

Same background from horizontal to vertical (2/3)

115 |
116 |
117 |

Same background from horizontal to vertical (3/3)

118 |
119 |
120 | 121 |
122 | 123 |
124 | 125 | 126 | 127 | 128 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /site/reveal.js/test/examples/slide-transitions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Slide Transitions 8 | 9 | 10 | 11 | 21 | 22 | 23 | 24 | 25 |
26 | 27 |
28 | 29 |
30 |

Default

31 |
32 | 33 |
34 |

Default

35 |
36 | 37 |
38 |

data-transition: zoom

39 |
40 | 41 |
42 |

data-transition: zoom-in fade-out

43 |
44 | 45 |
46 |

Default

47 |
48 | 49 |
50 |

data-transition: convex

51 |
52 | 53 |
54 |

data-transition: convex-in concave-out

55 |
56 | 57 |
58 |
59 |

Default

60 |
61 |
62 |

data-transition: concave

63 |
64 |
65 |

data-transition: convex-in fade-out

66 |
67 |
68 |

Default

69 |
70 |
71 | 72 |
73 |

data-transition: none

74 |
75 | 76 |
77 |

Default

78 |
79 | 80 |
81 | 82 |
83 | 84 | 85 | 86 | 87 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /site/reveal.js/test/qunit-1.12.0.css: -------------------------------------------------------------------------------- 1 | /** 2 | * QUnit v1.12.0 - A JavaScript Unit Testing Framework 3 | * 4 | * http://qunitjs.com 5 | * 6 | * Copyright 2012 jQuery Foundation and other contributors 7 | * Released under the MIT license. 8 | * http://jquery.org/license 9 | */ 10 | 11 | /** Font Family and Sizes */ 12 | 13 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { 14 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; 15 | } 16 | 17 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } 18 | #qunit-tests { font-size: smaller; } 19 | 20 | 21 | /** Resets */ 22 | 23 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { 24 | margin: 0; 25 | padding: 0; 26 | } 27 | 28 | 29 | /** Header */ 30 | 31 | #qunit-header { 32 | padding: 0.5em 0 0.5em 1em; 33 | 34 | color: #8699a4; 35 | background-color: #0d3349; 36 | 37 | font-size: 1.5em; 38 | line-height: 1em; 39 | font-weight: normal; 40 | 41 | border-radius: 5px 5px 0 0; 42 | -moz-border-radius: 5px 5px 0 0; 43 | -webkit-border-top-right-radius: 5px; 44 | -webkit-border-top-left-radius: 5px; 45 | } 46 | 47 | #qunit-header a { 48 | text-decoration: none; 49 | color: #c2ccd1; 50 | } 51 | 52 | #qunit-header a:hover, 53 | #qunit-header a:focus { 54 | color: #fff; 55 | } 56 | 57 | #qunit-testrunner-toolbar label { 58 | display: inline-block; 59 | padding: 0 .5em 0 .1em; 60 | } 61 | 62 | #qunit-banner { 63 | height: 5px; 64 | } 65 | 66 | #qunit-testrunner-toolbar { 67 | padding: 0.5em 0 0.5em 2em; 68 | color: #5E740B; 69 | background-color: #eee; 70 | overflow: hidden; 71 | } 72 | 73 | #qunit-userAgent { 74 | padding: 0.5em 0 0.5em 2.5em; 75 | background-color: #2b81af; 76 | color: #fff; 77 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; 78 | } 79 | 80 | #qunit-modulefilter-container { 81 | float: right; 82 | } 83 | 84 | /** Tests: Pass/Fail */ 85 | 86 | #qunit-tests { 87 | list-style-position: inside; 88 | } 89 | 90 | #qunit-tests li { 91 | padding: 0.4em 0.5em 0.4em 2.5em; 92 | border-bottom: 1px solid #fff; 93 | list-style-position: inside; 94 | } 95 | 96 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { 97 | display: none; 98 | } 99 | 100 | #qunit-tests li strong { 101 | cursor: pointer; 102 | } 103 | 104 | #qunit-tests li a { 105 | padding: 0.5em; 106 | color: #c2ccd1; 107 | text-decoration: none; 108 | } 109 | #qunit-tests li a:hover, 110 | #qunit-tests li a:focus { 111 | color: #000; 112 | } 113 | 114 | #qunit-tests li .runtime { 115 | float: right; 116 | font-size: smaller; 117 | } 118 | 119 | .qunit-assert-list { 120 | margin-top: 0.5em; 121 | padding: 0.5em; 122 | 123 | background-color: #fff; 124 | 125 | border-radius: 5px; 126 | -moz-border-radius: 5px; 127 | -webkit-border-radius: 5px; 128 | } 129 | 130 | .qunit-collapsed { 131 | display: none; 132 | } 133 | 134 | #qunit-tests table { 135 | border-collapse: collapse; 136 | margin-top: .2em; 137 | } 138 | 139 | #qunit-tests th { 140 | text-align: right; 141 | vertical-align: top; 142 | padding: 0 .5em 0 0; 143 | } 144 | 145 | #qunit-tests td { 146 | vertical-align: top; 147 | } 148 | 149 | #qunit-tests pre { 150 | margin: 0; 151 | white-space: pre-wrap; 152 | word-wrap: break-word; 153 | } 154 | 155 | #qunit-tests del { 156 | background-color: #e0f2be; 157 | color: #374e0c; 158 | text-decoration: none; 159 | } 160 | 161 | #qunit-tests ins { 162 | background-color: #ffcaca; 163 | color: #500; 164 | text-decoration: none; 165 | } 166 | 167 | /*** Test Counts */ 168 | 169 | #qunit-tests b.counts { color: black; } 170 | #qunit-tests b.passed { color: #5E740B; } 171 | #qunit-tests b.failed { color: #710909; } 172 | 173 | #qunit-tests li li { 174 | padding: 5px; 175 | background-color: #fff; 176 | border-bottom: none; 177 | list-style-position: inside; 178 | } 179 | 180 | /*** Passing Styles */ 181 | 182 | #qunit-tests li li.pass { 183 | color: #3c510c; 184 | background-color: #fff; 185 | border-left: 10px solid #C6E746; 186 | } 187 | 188 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } 189 | #qunit-tests .pass .test-name { color: #366097; } 190 | 191 | #qunit-tests .pass .test-actual, 192 | #qunit-tests .pass .test-expected { color: #999999; } 193 | 194 | #qunit-banner.qunit-pass { background-color: #C6E746; } 195 | 196 | /*** Failing Styles */ 197 | 198 | #qunit-tests li li.fail { 199 | color: #710909; 200 | background-color: #fff; 201 | border-left: 10px solid #EE5757; 202 | white-space: pre; 203 | } 204 | 205 | #qunit-tests > li:last-child { 206 | border-radius: 0 0 5px 5px; 207 | -moz-border-radius: 0 0 5px 5px; 208 | -webkit-border-bottom-right-radius: 5px; 209 | -webkit-border-bottom-left-radius: 5px; 210 | } 211 | 212 | #qunit-tests .fail { color: #000000; background-color: #EE5757; } 213 | #qunit-tests .fail .test-name, 214 | #qunit-tests .fail .module-name { color: #000000; } 215 | 216 | #qunit-tests .fail .test-actual { color: #EE5757; } 217 | #qunit-tests .fail .test-expected { color: green; } 218 | 219 | #qunit-banner.qunit-fail { background-color: #EE5757; } 220 | 221 | 222 | /** Result */ 223 | 224 | #qunit-testresult { 225 | padding: 0.5em 0.5em 0.5em 2.5em; 226 | 227 | color: #2b81af; 228 | background-color: #D2E0E6; 229 | 230 | border-bottom: 1px solid white; 231 | } 232 | #qunit-testresult .module-name { 233 | font-weight: bold; 234 | } 235 | 236 | /** Fixture */ 237 | 238 | #qunit-fixture { 239 | position: absolute; 240 | top: -10000px; 241 | left: -10000px; 242 | width: 1000px; 243 | height: 1000px; 244 | } -------------------------------------------------------------------------------- /site/reveal.js/test/simple.md: -------------------------------------------------------------------------------- 1 | ## Slide 1.1 2 | 3 | ```js 4 | var a = 1; 5 | ``` 6 | 7 | 8 | ## Slide 1.2 9 | 10 | 11 | 12 | ## Slide 2 13 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-markdown-element-attributes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Test Markdown Element Attributes 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-markdown-element-attributes.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | Reveal.addEventListener( 'ready', function() { 4 | 5 | QUnit.module( 'Markdown' ); 6 | 7 | test( 'Vertical separator', function() { 8 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' ); 9 | }); 10 | 11 | 12 | test( 'Attributes on element header in vertical slides', function() { 13 | strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' ); 14 | strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' ); 15 | }); 16 | 17 | test( 'Attributes on element paragraphs in vertical slides', function() { 18 | strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' ); 19 | }); 20 | 21 | test( 'Attributes on element list items in vertical slides', function() { 22 | strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.grow' ).length, 3, 'found a vertical slide with three list items with class fragment.grow' ); 23 | }); 24 | 25 | test( 'Attributes on element paragraphs in horizontal slides', function() { 26 | strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' ); 27 | }); 28 | test( 'Attributes on element list items in horizontal slides', function() { 29 | strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' ); 30 | }); 31 | test( 'Attributes on element list items in horizontal slides', function() { 32 | strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' ); 33 | }); 34 | 35 | test( 'Attributes on elements in vertical slides with default element attribute separator', function() { 36 | strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' ); 37 | }); 38 | 39 | test( 'Attributes on elements in single slides with default element attribute separator', function() { 40 | strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' ); 41 | }); 42 | 43 | } ); 44 | 45 | Reveal.initialize(); 46 | 47 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-markdown-external.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Test Markdown 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-markdown-external.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | Reveal.addEventListener( 'ready', function() { 4 | 5 | QUnit.module( 'Markdown' ); 6 | 7 | test( 'Vertical separator', function() { 8 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' ); 9 | }); 10 | 11 | test( 'Horizontal separator', function() { 12 | strictEqual( document.querySelectorAll( '.reveal .slides>section' ).length, 2, 'found two slides' ); 13 | }); 14 | 15 | test( 'Language highlighter', function() { 16 | strictEqual( document.querySelectorAll( '.hljs-keyword' ).length, 1, 'got rendered highlight tag.' ); 17 | strictEqual( document.querySelector( '.hljs-keyword' ).innerHTML, 'var', 'the same keyword: var.' ); 18 | }); 19 | 20 | 21 | } ); 22 | 23 | Reveal.initialize(); 24 | 25 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-markdown-options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Test Markdown Options 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-markdown-options.js: -------------------------------------------------------------------------------- 1 | Reveal.addEventListener( 'ready', function() { 2 | 3 | QUnit.module( 'Markdown' ); 4 | 5 | test( 'Options are set', function() { 6 | strictEqual( marked.defaults.smartypants, true ); 7 | }); 8 | 9 | test( 'Smart quotes are activated', function() { 10 | var text = document.querySelector( '.reveal .slides>section>p' ).textContent; 11 | 12 | strictEqual( /['"]/.test( text ), false ); 13 | strictEqual( /[“”‘’]/.test( text ), true ); 14 | }); 15 | 16 | } ); 17 | 18 | Reveal.initialize({ 19 | dependencies: [ 20 | { src: '../plugin/markdown/marked.js' }, 21 | { src: '../plugin/markdown/markdown.js' }, 22 | ], 23 | markdown: { 24 | smartypants: true 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-markdown-slide-attributes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Test Markdown Attributes 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-markdown-slide-attributes.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | Reveal.addEventListener( 'ready', function() { 4 | 5 | QUnit.module( 'Markdown' ); 6 | 7 | test( 'Vertical separator', function() { 8 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 6, 'found six vertical slides' ); 9 | }); 10 | 11 | test( 'Id on slide', function() { 12 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section#slide2' ).length, 1, 'found one slide with id slide2' ); 13 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section a[href="#/slide2"]' ).length, 1, 'found one slide with a link to slide2' ); 14 | }); 15 | 16 | test( 'data-background attributes', function() { 17 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A0C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' ); 18 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#ff0000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' ); 19 | strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C6916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' ); 20 | }); 21 | 22 | test( 'data-transition attributes', function() { 23 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="zoom"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' ); 24 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="fade"]' ).length, 1, 'found one vertical slide with data-transition="fade"' ); 25 | strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="zoom"]' ).length, 1, 'found one slide with data-transition="zoom"' ); 26 | }); 27 | 28 | test( 'data-background attributes with default separator', function() { 29 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#A7C66B"]' ).length, 1, 'found one vertical slide with data-background="#A0C66B"' ); 30 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-background="#f70000"]' ).length, 1, 'found one vertical slide with data-background="#ff0000"' ); 31 | strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#C7916B"]' ).length, 1, 'found one slide with data-background="#C6916B"' ); 32 | }); 33 | 34 | test( 'data-transition attributes with default separator', function() { 35 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="concave"]' ).length, 1, 'found one vertical slide with data-transition="zoom"' ); 36 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section[data-transition="page"]' ).length, 1, 'found one vertical slide with data-transition="fade"' ); 37 | strictEqual( document.querySelectorAll( '.reveal .slides section [data-transition="concave"]' ).length, 1, 'found one slide with data-transition="zoom"' ); 38 | }); 39 | 40 | test( 'data-transition attributes with inline content', function() { 41 | strictEqual( document.querySelectorAll( '.reveal .slides>section[data-background="#ff0000"]' ).length, 3, 'found three horizontal slides with data-background="#ff0000"' ); 42 | }); 43 | 44 | } ); 45 | 46 | Reveal.initialize(); 47 | 48 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-markdown.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Test Markdown 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-markdown.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | Reveal.addEventListener( 'ready', function() { 4 | 5 | QUnit.module( 'Markdown' ); 6 | 7 | test( 'Vertical separator', function() { 8 | strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' ); 9 | }); 10 | 11 | 12 | } ); 13 | 14 | Reveal.initialize(); 15 | 16 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-pdf.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Test PDF exports 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 | 19 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /site/reveal.js/test/test-pdf.js: -------------------------------------------------------------------------------- 1 | 2 | Reveal.addEventListener( 'ready', function() { 3 | 4 | // Only one test for now, we're mainly ensuring that there 5 | // are no execution errors when running PDF mode 6 | 7 | test( 'Reveal.isReady', function() { 8 | strictEqual( Reveal.isReady(), true, 'returns true' ); 9 | }); 10 | 11 | 12 | } ); 13 | 14 | Reveal.initialize({ pdf: true }); 15 | 16 | -------------------------------------------------------------------------------- /site/reveal.js/test/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Tests 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /site/slides.css: -------------------------------------------------------------------------------- 1 | .reveal h2, th { 2 | font-size: 1.5em; 3 | padding-bottom: 0.5em; 4 | color: #66AF40; 5 | } 6 | 7 | .reveal pre { 8 | font-size: 0.8em; 9 | box-shadow: none; 10 | padding: 0.1em; 11 | background-color: #F8F8F8; 12 | } 13 | 14 | .reveal section { 15 | font-size: 1.0em; 16 | color: #5B80D4; 17 | /* allow vertical scrolling in slides */ 18 | max-height: 100%; 19 | overflow-y: auto; 20 | } 21 | 22 | .reveal section img { 23 | margin: 0; 24 | border: 10px solid #66AF40; 25 | height: 300px; 26 | } 27 | 28 | .reveal section p, h1, h2, div { 29 | text-align: left; 30 | } 31 | 32 | .slides { 33 | width: 90% !important; 34 | } 35 | 36 | html.title body { 37 | background: linear-gradient(to bottom left, #91B3FB, #92DA55); 38 | } 39 | 40 | .small { 41 | font-size: 0.8em !important; 42 | } 43 | 44 | .klipse-snippet { 45 | border: solid #92DA55 1px !important; 46 | } 47 | 48 | .klipse-result { 49 | border: solid #91B3FB 1px !important; 50 | } 51 | 52 | code { 53 | background-color: #F8F8F8; 54 | font-family: 'FiraCode', monospace !important; 55 | } 56 | 57 | .CodeMirror { 58 | font-family: 'FiraCode', monospace !important; 59 | font-size: 0.8em !important; 60 | } 61 | 62 | .CodeMirror-cursor { 63 | border-left: 1px solid black !important; 64 | } 65 | 66 | .CodeMirror-scroll { 67 | padding-bottom: 30px !important; 68 | margin-bottom: -30px !important; 69 | } 70 | -------------------------------------------------------------------------------- /watch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find docs | entr -s "make" 4 | --------------------------------------------------------------------------------