Arrow Playground is now available

Arrow Playground is now available

As you know Arrow is an open source library that’s packed with data types and type classes that empower pure functional programming in Kotlin. But, did you know you can embed Arrow snippets into any page? And even execute them? 😏

Arrow Playground is a JavaScript library that creates Kotlin-aware, including Arrow, editors capable of running code from HTML block elements. This is a fork of the original Kotlin Playground work done by the JetBrains team.

Installation and usage

Automatic initialization

You can load Arrow Playground from the UNPKG content delivery network, insert a <script> element into your page, and specify what elements should be converted in a data-selector attribute.

<script src="https://unpkg.com/arrow-playground@1" data-selector=".kotlin-code"></script>

The result of this action can be seen on this very page. As this site is already using Arrow Playground, the following block of Kotlin code:

import arrow.*
import arrow.core.*

fun main(args: Array<String>) {
  val someValue: Option<String> = Some("I am wrapped in something")
  println(someValue)
  // Some(I am wrapped in something)
}

Turns into:

import arrow.*
import arrow.core.*

fun main(args: Array<String>) {
  val someValue: Option<String> = Some("I am wrapped in something")
  println(someValue)
  // Some(I am wrapped in something)
}

Through the use of the custom data-selector attribute you can set the elements that will be applied with the Playground. You can use any valid DOM selector:

  • An element tag, for example code
  • A class selector, like .kotlin-code
  • An identifier, such as #my-unique-id-selector
  • An attribute, as [data-attribute="value"]
Manual initialization

If you want to initiate Arrow Playground manually, you can separate the process of fetching the library and the code conversion itself. To accomplish this, simply omit the data-selector attribute and use a second <script> element like this:

<script src="https://unpkg.com/arrow-playground@1"></script>

<script>
document.addEventListener('DOMContentLoaded', function() {
  ArrowPlayground('.kotlin-code-selector');
});
</script>

You can also overwrite the server where the code is being sent to be compiled and analyzed (this could be valuable, for example, if you host a server instance that includes your own Kotlin libraries outside of Arrow). This can be accomplished by setting the data-server attribute, like this:

<script src="https://unpkg.com/arrow-playground@1"
        data-selector="code"
        data-server="https://my-arrow-playground-server">
</script>

To host your own server, please review forking and/or cloning the Try Arrow server repository.

Serve your own Arrow Playground instance

Instead of using a CDN, you can also generate the library through the proper npm script (npm run build), then host it, and use it with the same process we’ve illustrated previously.

<script src="https://my-own-server/arrow-playground.js" data-selector="code"></script>

Arrow Playground is published in the NPM registry, so if you use a node.js based build environment, you can install arrow-playground as you usually do with dependencies - through npm.

NPM version

npm install arrow-playground -S

And then just use it in your code:

// ES5
var playground = require('arrow-playground');

document.addEventListener('DOMContentLoaded', function() {
  playground('code'); // attach to all <code> elements
});


// ES6
import playground from 'arrow-playground';

document.addEventListener('DOMContentLoaded', () => {
  playground('code'); // attach to all <code> elements
});
Jekyll environment

It’s possible that you want to embed Arrow code snippets in a Jekyll based website. As Jekyll uses Kramdown as its default Markdown parser, here are a few tips to integrate Arrow Playground with this stack.

<script src="https://unpkg.com/arrow-playground@1" data-selector=".language-kotlin"></script>
{: data-executable="true" data-theme="darcula"}
```kotlin
import arrow.*
import arrow.core.*

fun main(args: Array<String>) {
  val someValue: Option<String> = Some("I am wrapped in something")
  println(someValue)
  // Some(I am wrapped in something)
}
```

Processing triple backticks fenced code blocks will surround the snippet into <pre> and <code> elements, adding a class with the specified language. In this case, it’s language-kotlin so you can take advantage of using it as your selector. To add attributes to the blocks, you can use the Kramdown IAL syntax. Let’s dive deeper into the attributes to customize your Arrow Playground snippets!

Customizing editors

Use some of the following attributes on the editors to adjust their behavior:

  • data-executable: Not just highlighting, you can make the code snippets runnable and editable by using the data-executable attribute.

  • theme="arrow|idea|darcula|default": Some highlighting themes to use, we’ll have a rundown of them later in the post.

  • autocomplete="true|false": Get completion on every key press. If false => Press ctrl-space to activate autocompletion. Defaults to false.

  • indent="4": How many spaces a block should be indented. Defaults to 4.

  • lines="true|false": Whether to show line numbers to the left of the editor. Defaults to false.

  • from="5" to="10: Create a part of code. Example from line 5 to line 10.

  • match-brackets="true|false"": Determines whether brackets are matched whenever the cursor is moved next to a bracket. Defaults to true.

Additionally, you can make a section of code read-only by placing it between //sampleStart and //sampleEnd markers. The code outside of those markers will be hidden by default, with possibility of showing it by clicking a button. If you want to completely hide a section, just set the attribute folded-button to false value.

<code data-executable="true">
import arrow.*
import arrow.core.*

fun main(args: Array<String>) {
  //sampleStart
  val someValue: Option<String> = Some("I am wrapped in something")
  println(someValue)
  //sampleEnd
  // Some(I am wrapped in something)
}
</code>
import arrow.*
import arrow.core.*

fun main(args: Array<String>) {
  //sampleStart
  val someValue: Option<String> = Some("I am wrapped in something")
  println(someValue)
  //sampleEnd
  // Some(I am wrapped in something)
}
<code data-executable="true" folded-button="false">
import arrow.*
import arrow.core.*

fun main(args: Array<String>) {
  //sampleStart
  val someValue: Option<String> = Some("I am wrapped in something")
  println(someValue)
  //sampleEnd
  // Some(I am wrapped in something)
</code>
import arrow.*
import arrow.core.*

fun main(args: Array<String>) {
  //sampleStart
  val someValue: Option<String> = Some("I am wrapped in something")
  println(someValue)
  //sampleEnd
  // Some(I am wrapped in something)
}

Themes

If you don’t specify it, the highlighting theme will follow Arrow library color scheme, but you can change it using the theme attribute.

For example, this would be CodeMirror’s default theme:

<code theme="default"></code>
import arrow.*
import arrow.core.*

fun main(args: Array<String>) {
  val someValue: Option<String> = Some("I am wrapped in something")
  println(someValue)
  // Some(I am wrapped in something)
}

Or you can go with the dark theme, darcula:

<code theme="darcula"></code>
import arrow.*
import arrow.core.*

fun main(args: Array<String>) {
  val someValue: Option<String> = Some("I am wrapped in something")
  println(someValue)
  // Some(I am wrapped in something)
}

Events

You can leverage some of the Arrow Playground emitted events. You would use it like this:

function onChange(code) {
  console.log("Editor code was changed:\n" + code);
}

const options = {
  onChange: onChange(code),
};

playground('.selector', options)

Events description:

  • onChange(code) — fires every time the content of the editor is changed. Debounce time: 0.5s. code — current playground code.

  • onCloseConsole — is called after the console’s closed.

  • onOpenConsole — is called after the console’s opened.

  • getInstance(instance) - gets the playground state API, where you can find some useful data:

instance.state      // playground attributes, dependencies and etc.
instance.nodes      // playground NodeElement.
instance.codemirror // editor specification.
instance.execute()  // function for executing code snippet programmatically.
instance.getCode()  // function for getting the code from the snippet.

Supported keyboard shortcuts

  • Ctrl+Space — code completion
  • Ctrl+F9 / Cmd+R — execute snippet
  • Ctrl+/ — comment code
  • Ctrl+Alt+L / Cmd+Alt+L — format code
  • Shift+Tab — decrease indent

For the complete list of options and examples, please check out the project’s website and repository:

Ensure the success of your project

47 Degrees can work with you to help manage the risks of technology evolution, develop a team of top-tier engaged developers, improve productivity, lower maintenance cost, increase hardware utilization, and improve product quality; all while using the best technologies.