- Notifications
You must be signed in to change notification settings - Fork148
Klipse is a JavaScript plugin for embedding interactive code snippets in tech blogs.
License
viebel/klipse
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Klipse is a JavaScript plugin for embedding interactive code snippets in tech blogs. See examples athttps://blog.klipse.tech/
Technically, Klipse is a small piece of JavaScript code that evaluates code snippets in the browser and it is pluggable on any web page.
If you like this stuff, please consider a (small donation) onPatreon.
The klipse plugin is aJavaScript
tag (see detailsbelow) that transforms static code snippets of an html page into live and interactive snippets:
- Live: The code is executed in your browser
- Interactive: You can modify the code and it is evaluated as you type
The code evaluation is done in the browser: no server is involved at all!
With the klipse plugin, the code is evaluated as you type...
Here is alive demo of the embedding of klipse in a web page.
JavaScript | Ruby |
---|---|
![]() | ![]() |
PHP | Clojure |
---|---|
![]() | ![]() |
- #"https://github.com/thejameskyle/pretty-format">pretty-format
The code editing inside the interactive snippets is powered byCodeMirror.
- #"http://blog.klipse.tech/javascript/2016/06/20/blog-javascript.html" rel="nofollow">A new way of blogging about JavaScript
- Ruby:A new way of blogging about ruby
- Clojure[Script]:How to klipsify a clojure[script] blog post
In order to integrate the klipse plugin on a blog, library documentation or any other web page, you have to follow 3 simple steps.
Make sure you have
<!DOCTYPE html>
at the top of your html file and<meta charset="utf-8">
right after your<head>
(It is required in order to display properly the CodeMirror elements used by Klipse.)Add css and custom configuration somewhere in the page (it could be in the
<head>
or in the<body>
)before the<script>
element of step #3.The selector keys are per language (see below for a list of supported languages) and the value are the CSS selector of the elements that you want to klipsify.
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_eval_js:'.language-klipse-eval-js',// css selector for the html elements you want to klipsify};</script>
- Add the
JavaScript
tag at theend of the body tag :
For Clojure:
<scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin/js/klipse_plugin.js"></script></body>
For other languages:
<scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script></body>
Here is aninteractive guide of the klipse snippets.
If you want to host Klipse JavaScript tag from your own server, seeHost Klipse Locally.
If you want to use an older version of Klipse, seeUse Older Versions.
Here is thefull interactive guide of the klipseJavaScript
snippets.
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_eval_js:'.language-klipse-eval-js',// css selector for the html elements you want to klipsify};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
Here is ajsfiddle with Klipse plugin for JavaScript.And here are detailed explanations abouta JavaScript live code editor in a blog post.
Pay attention: for Clojure interactive snippets, you must use thenon-minified version of klipse as for the moment, self-host cljs doesn't support advanced compilation!
Here is thefull interactive guide of the klipseclojure
snippets.
You can manipulate the DOM inside KLIPSE: here is atutorial.
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector:'.language-klipse'// css selector for the html elements you want to klipsify};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin/js/klipse_plugin.js"></script>
If you want to integrate Klipse inside a Clojurescript project, it is recommended to consume Klipse as a Clojurescript library like any other Clojurescript lib, just like this.
Inside your code you have to require two namespaces and call a function:
(nsmy.project (:require [klipse.run.plugin.plugin];; this namespace initializes Klipse. We require it for its side effects [klipse.plugin:as klipse-plugin]))(klipse-plugin/init #js {:selector".language-klipse":selector_reagent".language-reagent"})
Here is an example of atiny reagent demo project that integrates Klipse as a Clojurescript library.
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_eval_python_client:'.language-klipse-python',// css selector for the html elements you want to klipsify};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_pyodide:'.language-klipse-pyodide',// css selector for the html elements you want to klipsify};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_eval_ruby:'.language-klipse-eval-ruby',// css selector for the html elements you want to klipsify};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/lua.css"><script>window.klipse_settings={selector_lua:'.language-klipse-lua',// css selector for the html elements you want to klipsify};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_golang:'.language-klipse-go, // css selector for the html elements you want to klipsify};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_eval_scheme:'.language-klipse-eval-scheme',// css selector for the html elements you want to klipsify};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
Prolog code snippets are separated into two kinds:
- Rules
- Queries
In the query, you must omit the?-
characters.
SeeA new way of blogging about Prolog for a full example and guide.
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/prolog.css"><script>window.klipse_settings={selector_prolog_rules:'.language-prolog-rules',// css selector for the html elements that contain prolog rulesselector_prolog_query:'.language-prolog-query',// css selector for the html elements that contain prolog queries};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js?v=7.7.1-a"></script>
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_eval_clisp:'.language-klipse-eval-clisp',// css selector for the html elements you want to klipsify};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_eval_ocaml:'.language-klipse-ocaml',// selector for ocaml evaluation snippetsselector_transpile_ocaml:'.language-transpile-ocaml'// selector for ocaml transpilation snippets};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
Note: Code Snippets in Reason version 3 will automagically be upgraded to latest Reason version once a new version of Reason is released.
We have 4 kinds of ReasonML snippets:
- Code Evaluation
- Transpilation to JavaScript
- Transpilation to Ocaml
- Transpilation from Ocaml
Here is the JavaScript tag that you need to setup for embedding ReasonML snippets on your page:
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_transpile_reason_3:'.language-transpile-reason',// selector for reason transpilation snippetsselector_transpile_reason_3_to_ocaml:'.language-transpile-reason-to-ocaml',// selector for reason transpilation into ocaml snippetsselector_eval_reason_3:'.language-klipse-reason',// selector for reason evaluation snippetsselector_ocaml_to_reason:'.language-klipse-ocaml-to-reason'// selector for ocaml to reason snippets};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_transpile_reason:'.language-transpile-reason',// selector for reason transpilation snippetsselector_transpile_reason_to_ocaml:'.language-transpile-reason-to-ocaml',// selector for reason transpilation into ocaml snippetsselector_eval_reason:'.language-klipse-reason'// selector for reason evaluation snippets};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/sql.css"><script>window.klipse_settings={selector_sql:'.sql',};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
<linkrel="stylesheet"type="text/css"href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"><script>window.klipse_settings={selector_eval_php:'.language-klipse-eval-php',// css selector for the html elements you want to klipsify};</script><scriptsrc="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"></script>
If your site runs underhttps
, you need to load the klipse plugin fromhttps://storage.googleapis.com/app.klipse.tech
instead ofhttp://app.klipse.tech
.
The reason is that the klipse plugin is hosted onGoogle Cloud Storage and for the momentSSL is not supported for custom domains.
The klipse plugin is configurable both at the level of the page and at the level of the snippet.
Here are the settings for the klipse plugin a page level:
window.klipse_settings={eval_idle_msec:20,// idle time in msec before the snippet is evaluatedselector:'.language-klipse',// selector for Clojure evaluation snippetsselector_js:'.language-klipse-js',// selector for Clojure transpilation snippetsselector_reagent:'.language-reagent',// selector for reagent snippetsselector_google_charts:'.language-google-charts'// selector for Google charts snippetsselector_oblivion:'.language-oblivion'// selector for oblivion snippetsselector_eval_js:'.language-klipse-eval-js',// selector for JavaScript evaluation snippetsselector_eval_ruby:'.language-klipse-eval-ruby',// selector for Ruby evaluation snippetsselector_lua:'.language-klipse-lua',// selector for lua evaluation snippetsselector_es2017:'.language-klipse-es2017',// selector for EcmaScript 2017 evaluation snippetsselector_jsx:'.language-klipse-jsx',// selector for JSX evaluation snippetsselector_transpile_jsx:'.language-transpile-jsx',// selector for JSX transpilation snippetsselector_render_jsx:'.language-render-jsx',// selector for JSX rendering snippetsselector_react:'.language-react',// selector for React snippetsselector_eval_php:'.language-klipse-eval-php',// selector for PHP evaluation snippetsselector_eval_markdown:'.language-klipse-markdown',// selector for Markdown transpilation snippetsselector_render_hiccup:'.render-hiccup',// selector for Hiccup rendering snippetsselector_transpile_hiccup:'.transpile-hiccup',// selector for Hiccup transpiling snippetsselector_eval_lambdaway:'.language-klipse-lambdaway',// selector for lambdaway transpilation snippetsselector_eval_python_client:'.language-klipse-python',// selector for Python evaluation snippetsselector_eval_cpp:'.language-klipse-cpp',// selector for cpp evaluationselector_eval_html:'.language-klipse-html',// selector for Html evaluation snippetsselector_sql:'.language-klipse-sql',// selector for sqlite evaluation snippetsselector_eval_scheme:'.language-klipse-scheme',// selector for Scheme evaluation snippetsselector_brainfuck:'.language-klipse-brainfuck',// selector for Brainfuck snippetsselector_eval_ocaml:'.language-klipse-ocaml',// selector for Ocaml evaluation snippetsselector_transpile_ocaml:'.language-transpile-ocaml',// selector for Ocaml transpilation snippetsselector_transpile_reason_3:'.language-transpile-reason',// selector for Reason transpilation snippetsselector_transpile_reason_3_to_ocaml:'.language-transpile-reason-to-ocaml',// selector for Reason transpilation into ocaml snippetsselector_eval_reason_3:'.language-klipse-reason',// selector for Reason evaluation snippetsselector_ocaml_to_reason:'.language-klipse-ocaml-to-reason'// selector for Ocaml to reason snippetscached_ns_root:'/my-root',// the root of Clojure cached namespace, default: https://viebel.github.io/cljs-analysis-cache/cache/clojure_cached_macro_ns_regexp:/reagent.*/,// the regexp for Clojure macro namespaces that are cachedclojure_cached_ns_regexp:/reagent.*/,// the regexp for clojure namespaces that are cachedcodemirror_root:'/my-codemirror-root',// the root of Codemirror filesscripts_root:'/my-scripts-root',// the root of scripts files (e.g pretty_format.js, opal.js ...)re_evaluate_all_snippets_on_change:false,// Whether all snippets should be reevaluated when any one snippet is edited, since snippets might depend on each othereditor_type:'code-mirror',//the type of the editor for Klipse results (the element where the evaluation of the snippet is displayed). Allowed values:// "code-mirror": The input editor is codemirror. The output editor is codemirror// "html": The input editor is codemirror. The output editor is html// "dom": The input editor is plain text. The output editor is plain text};
Additionally, you can configure CodeMirror input (snippet source code) and output (snippet evaluation) by settingcodemirror_options_in
andcodemirror_options_out
:
Currently, we support all the settingsCodeMirror Configuration settings and part of theAddons settings:matchBrackets
andautoCloseBrackets
.
For instance, you can modify theindentUnit
,lineWrapping
,lineNumbers
andautoCloseBrackets
like this:
window.klipse_settings={codemirror_options_in:{indentUnit:8,lineWrapping:true,lineNumbers:true,autoCloseBrackets:true},codemirror_options_out:{lineWrapping:true,lineNumbers:true}}
print_length
: (default 1000) max number of items in collections to display - useful to prevent browser stuck when evaluating infinite sequences like(range)
beautify_strings
: (default false) when evaluation result is a string - display the "interior" of the string without escaping the quotes.
The following attributes can be added to the DOM element of the snippet:
data-eval-idle-msec
: (default 20) idle time in msec before the snippet is evaluateddata-loop-msec
: (defaultundefined
) the code is run in a loop everydata-loop-msec
msecdata-preamble
: (default""
) A string containing Clojurescript source code that should be run before the contents of this snippet, eg "(reset! canvas-id :canvas-2)". Useful for hiding implementation details from readers in blog posts, like e.g. setting acanvas-id
atom to:canvas-2
, or for performing any other setup operations that need to be done on a per-snippet basisdata-editor-type
: (default"code-mirror"
) the type of the editor for the klipse result (the element where the evaluation of the snippet is displayed). Allowed values:** "code-mirror": The input editor is codemirror. The output editor is codemirror** "html": The input editor is codemirror. The output editor is html** "dom": The input editor is plain text. The output editor is plain text
data-external-libs
: comma separated list of JavaScript libraries to load before snippet evaluationdata-async-code
: (defaultfalse
) whentrue
, asynchronous calls toconsole.log
append their result to the result cell
Here is alive demo of the different snippet level configuration options.
The following data attributes are supported on a klipse snippet DOM element:
data-static-fns
: (defaultfalse
) set to true for usingstatic dispatchdata-external-libs
: comma separated list of github repositories to resolve dependencies: you need to provide the full list of dependencies (including the dependencies of dependencies recursively). See for instanceLambda Calculus with clojure and Klipsedata-print-length
: (default 1000) max number of items in collections to display - useful to prevent browser stuck when evaluating infinite sequences like(range)
data-beautify-strings
: (default false) when evaluation result is a string - display the "interior" of the string without escaping the quotes.data-verbose
: (default false) passed to bootstrappedeval
andcompile
:verbose
optsdata-max-eval-duration
: (default 1000) max number of milliseconds the snippet code is allowed to run synchronously before being interrupted.data-compile-display-guard
: (default false) when true, display the anti-starvation code inside result of compilation
The Klipse plugin can be easily styled with CSS, which can be applied both to the Klipse plugin's own elements, and to the CodeMirror editor's elements. Much of the styling you'll apply will be to CodeMirror, as it contains all the CSS classes to style the code itself. Surrounding CodeMirror is the Klipse plugin, the styles of which control the plugin's borders, and the executed code's output.
Each klipse snippet is associated with 4 HTML elements:
- The klipse snippet itself: it has the class
klipse-snippet
. - The result: it has the class
klipse-result
. - A container: it has the class
klipse-container
and is accessible inside the klipse snippet through the global variableklipse_container
(the global variable is dynamically bound to the correct klipse container). - A separator: it has the class
klipse-separator
.
You can change the theme of the CodeMirror editor simply by modifying itsCSS. If you don't want to create your own theme, Farhad Gayour has an awesomelist of ready-made themes you can select from. Have a look at the different themes by selecting them from the drop-down. Once you've found one you like, head to thetheme repo to copy the CSS, paste it into a CSS file, and link to it from the HTML page containing your Klipse plugin.
To change the style of the Klipse plugin's borders and the console output, you'll need to add a few extra style rules to your CSS file. These are:
.CodeMirror
- modify the plugin's borders and CodeMirror's containingdiv
.CodeMirror:last-child::before
- modify the console's title (i.e. the bit that saysOutput:).CodeMirror:last-child
- modify the console area (i.e. the area beneathOutput:)
You can see an example of styling Klipse indemos/styling
. And here is alive demo
You can build interactive slides by integrating Klipse withReveal.js using thistemplate for reveal.js and Klipse.
Here are a couple of examples of blogs using the klipse plugin:
- Clojure:Procedural Dungeon Generation: A Drunkard's Walk in ClojureScript
- Python:Drawing fractals with a turtle
- Clojure:Island Generator
- ClojureScript transpiled:blog.ducky.io - More about protocols in ClojureScript
- Ruby:jessewaites.com - interactive ruby snippets
- Clojure:z.caudate.me - live documentation with klipse
- Ruby, Javascript, Clojure:blog.klipse.tech
- Prolog:A new way of blogging about Prolog
- Clojure documentation:Anonymous functions in clojure
- #"http://untangled.io/in-depth-es6-destructuring-with-assembled-avengers/" rel="nofollow">Untangled.io - Advanced ES6 destructuring techniques with live examples
- Clojure:Klipse for Kids: A fun way to learn computer programming
- JavaScriptImmutable.js: An Introduction with examples written for humans
- Clojure:Yet another scheme dialect written in Clojure and ClojureScript
- #"http://calmm-js.github.io/partial.lenses/" rel="nofollow">Try Partial Lenses with KLIPSE
- #"https://clause.js.org" rel="nofollow">Clause.js, a JavaScript contract system, documentation created with klipse
- Clojure: Reagent deep dive part1234
- ClojureScript:Visualising Bézier Curves
- Clojure:core.async fun tutorial
- ClojureScript:reagent and reframe playground
- #"https://e-zchai.firebaseapp.com/" rel="nofollow">chai unit tests playground
- Clojure:polynomial macro
- Prolog: A scientific paper withinteractive code snippets: [Continuous Reasoning for Managing Next-Gen Distributed Applications] (http://eptcs.web.cse.unsw.edu.au/paper.cgi?ICLP2020.22.pdf)
Ask us any question about the klipse plugin (integration, feature requests...) on
Each code snippet is wrapped into a CodeMirror editor.
The CodeMirror editors are accessible via the JavaScript global variable:klipse_editors
.This is an array that contains the CodeMirror editors wrapping the original code snippets. For instance, you can modify the content of the code snippeti
by calling:klipse_editors[i].setValue('let a = 1');
Here is ajsfiddle that shows it in action.
The evaluation of each snippet is also wrapped into a CodeMirror editor.The CodeMirror editors that wrapped results are accessible via the JavaScript global variable:klipse_results
.This is an array that contains the CodeMirror editors wrapping the results of the evaluation of the code snippets.For instance, you can read the content of the code snippeti
by calling:klipse_results[i].getValue();
Here is ajsfiddle that shows it in action.
Since version6.8.0
, Klipse is published onnpm. Therefore you can access the klipse files of a specific version fromunpkg - a cdn for stuff that is published tonpm
.
For instance, The urls are for the version6.8.0
are:
- JavaScript minified:https://unpkg.com/klipse@6.8.0/dist/klipse_plugin.min.js
- JavaScript non-minified:https://unpkg.com/klipse@6.8.0/dist/klipse_plugin.min.js
- Css:https://unpkg.com/klipse@6.8.0/dist/codemirror.css
You can download klipse withnpm
orbower
.
In order to serve Klipse from your own server, you have to:
- Include in your page all the assets that you need from the
dist
folder:codemirror.css
,klipse_plugin.js
orklipse_plugin.min.js
,javascript.inc.js
(CodeMirror JavaScript addon),pretty_format.js
(JavaScript beautifier) - set
klipse_settings.no_dynamic_scripts=true;
If you need more assets that are usually dynamically loaded by klipse, please download them manually.
Here is theinformation about the Klipse app
The Web REPL is live athttp://app.klipse.tech
Here isthe manual for the KLIPSE web repl.
Languages supported in the REPL:Clojure
andClojureScript
.
If you like this stuff, please consider a (small donation) onPatreon.
See theLICENSE file for license rights and limitations (GNU General Public License v3.0).
About
Klipse is a JavaScript plugin for embedding interactive code snippets in tech blogs.