{"id":29894150,"url":"https://github.com/juxt/qcon2014","last_synced_at":"2025-08-01T04:45:24.432Z","repository":{"id":14683449,"uuid":"17402805","full_name":"juxt/qcon2014","owner":"juxt","description":null,"archived":false,"fork":false,"pushed_at":"2014-03-09T09:32:32.000Z","size":970,"stargazers_count":26,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-29T14:45:00.939Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/juxt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-03-04T13:31:46.000Z","updated_at":"2022-07-02T22:26:54.000Z","dependencies_parsed_at":"2022-09-23T22:12:30.327Z","dependency_job_id":null,"html_url":"https://github.com/juxt/qcon2014","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/juxt/qcon2014","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juxt%2Fqcon2014","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juxt%2Fqcon2014/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juxt%2Fqcon2014/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juxt%2Fqcon2014/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/juxt","download_url":"https://codeload.github.com/juxt/qcon2014/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juxt%2Fqcon2014/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268171716,"owners_count":24207417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-01T04:45:22.213Z","updated_at":"2025-08-01T04:45:24.394Z","avatar_url":"https://github.com/juxt.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# QCon slides\n\nAn [Om](https://github.com/swannodette/om)-powered HTML slide-deck, by Malcolm Sparks.\n\n## Discussion\n\nThere are numerous HTML-based tools out there\n([reveal.js](http://lab.hakim.se/reveal-js/#/),\n[slidy](http://www.w3.org/Talks/Tools/Slidy2/Overview.html#%281%29),\n[impress.js](http://bartaz.github.io/impress.js/#/bored),\n[deck.js](http://imakewebthings.com/deck.js/), etc..) for building\nslide-based presentations for conference talks, etc.\n\nBut I find they have a number of disadvantages, at least for me :\n\n1. You usually have to write your slides in raw HTML. This feels cumbersome when you're used to writing LISP s-expressions with paredit.\n\n2. If you want to build in more interactivity, you have to be proficient in JavaScript.\n\nIn March 2014 I gave a presentation at QCon in London for which I built\na slide-deck in [Om](https://github.com/swannodette/om).\n\nIf you're reading this on an old-style computer with a keyboard then you\ncan view it here http://qcon.juxt.pro/index.html. Use the left/right\narrow keys.\n\n![slide-19](slide-19.png)\n\nOn this slide (slide 19) you can click in the black box and on the `\u003e!`\nand `\u003c!` symbols, and there are other interactive slides following this\nto help explain some [core.async](https://github.com/clojure/core.async)\nconcepts with some visualisations.\n\nYou write your slides in EDN. For most slides, you can use simple conventions like this :\n\n```clojure\n{:title \"Hello\"\n :bullets [\"Point 1\" \"Point 2\" \"Point 3\"]}\n```\n\nYou can add a `:custom` key which references a _custom slide_, which is an Om component.\n\n```clojure\n(defn go-block-slide [data owner opts]\n...\n)\n\n{:subtitle \"go blocks\"\n             :custom go-block-slide\n             :code {:source \"qcon.examples/demo-go-loop\"\n                    :lang :clojure\n                    }\n             :opts {:width 600 :height 600\n                    :circles 7\n                    :radius 60 :font-size \"40pt\"}}\n```\n\nOm seems ideal for slide-decks. Om's component modularity protects the\nindependence of individual custom slides, so they can be transferred to\nother decks easily. I've found that, as a Clojure developer, building\nslides this way has been much easier than building them with JavaScript.\n\nOm is also great for SVG interactivity. Firstly, React supports SVG\nnodes as well as HTML ones, so you get both the convenience of rending a\ndiagram in [immediate mode](http://en.wikipedia.org/wiki/Immediate_mode)\nwithout sacrificing performance. Using ClojureScript and go-blocks wins\nhands-down against\n[standard SVG animation](http://www.w3.org/TR/SVG/animate.html)\ntechniques.\n\nIf anyone would like to re-use some or all of this code for an upcoming\ntalk or presentation, please feel free to use anything here if it\nhelps. If there is enough interest, we could separate the common\nfunctions into a small library.\n\n## Getting started\n\n```\nmkdir om-slides-example\ncd om-slides-example\ngit clone https://github.com/juxt/qcon2014\ngit clone https://github.com/juxt/jig\ncd jig\ngit checkout 2.0.3\n```\n\nMake a Jig config file at `$HOME/.jig/config.clj`, with the following contents.\n\n\n```clojure\n#=(eval\n   (-\u003e (clojure.core/read-string (slurp \"/home/malcolm/src/om-slides-example/qcon2014/config.clj\"))\n       ))\n```\n\nImportant: Replace the path\n`/home/malcolm/src/om-slides-example/qcon2014/config.clj` with the\nlocation of the qcon `config.clj` file you've cloned.\n\nFrom the jig directory :-\n\n```\nlein repl\nJig user\u003e (go)\nJig user\u003e (reset)\nJig user\u003e (reset)\n\n```\n\nNow open a browser at `localhost:8000`.\n\nDo a `(reset)` every time you change a file and Jig will recompile the\nmodified clojurescript and reload the modified clojure.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuxt%2Fqcon2014","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuxt%2Fqcon2014","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuxt%2Fqcon2014/lists"}