Public
Edited
Oct 17, 2022
1 fork
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
example.container
Insert cell
example = {
// Note that any newlines in the raw HTML will be converted to
// lines in the editor. The same will happen to leading
// spaces so keep that in mind!
const container = html`<div style="font-size:16pt" id="editor">/* Hello Observable! */

${initial_code}</div>`;

const editor = aceJS.edit(container, {
minLines: 7,
maxLines: 9000,
theme: "ace/theme/monokai",
mode: "ace/mode/javascript"
});

// The text extraction is most easily done with a callback and
// a mutable cell, as shown here, but see the up linked
// documentation for more complex examples.
editor.session.on('change', () => {mutable text = editor.getValue()})
mutable text = editor.getValue()
return { editor, container };
}
Insert cell
/*
IMPORTANT: DON'T use the mutable `text` cell here!
That would be a circular definition that isn't caught
by Observable and cause an infinite loop

In other words: the initial text should be a separate,
independent string value from the extracted text!
*/
initial_code = `function foo(items) {
var x = "All this is syntax highlighted";
return x;
}`
Insert cell
mutable text = initial_code
Insert cell
Insert cell
// convenience function to instantiate
function ace(textOrDiv, containerStyle, aceConfig){
// if not a string or undefined, assume object with fontSize and/or height
if (typeof containerStyle !== 'string') {
if (!containerStyle) containerStyle = {};
if (!containerStyle.fontSize) containerStyle.fontSize = "1em";
containerStyle = `font-size:${containerStyle.fontSize};`
}
if (textOrDiv === undefined || typeof textOrDiv === 'string') {
textOrDiv = html`<div style="${containerStyle}">${textOrDiv || ""}</div>`
} else {
textOrDiv.style = containerStyle;
}
const editor = aceJS.edit(textOrDiv, Object.assign({
minLines: 7,
maxLines: 9000,
theme: "ace/theme/monokai",
mode: "ace/mode/javascript"
}, aceConfig));
return {editor, view: textOrDiv};
}
Insert cell
Insert cell
exampleReadOnly.view
Insert cell
exampleReadOnly = ace(`const example1 = \` This is a read-only editor field!
For when you just want to show some code (but if that is all
that you need please just use MarkDown's built-in syntax
highligher for that - even minified Ace is 370 KiB).

Note that the editor window height will default to seven lines
unless you set it manually, which we also do here for
demonstration purposes, alongside custom fonts\`;
`, {fontSize: "1.2em"}, {readOnly: true})
Insert cell
Insert cell
liveMarkdown = md`${exampleLiveMarkdown}`
Insert cell
viewof exampleLiveMarkdown = {
const defaultLiveMarkdownText = `## Extracting text on every keystroke

The cell that is rendered by this bit of markdown will update
with every change to the text field.

[Test to see if markdown highlighting works as expected](#liveMarkdown)`
// Instantiating the editor
const {editor, view} = ace(defaultLiveMarkdownText, undefined, {mode: "ace/mode/markdown"});

// initial value for viewof
view.value = editor.getValue();

// Setting up the callback that reacts to the changes
editor.on('change', () => {view.value = editor.getValue()})
return view;
}
Insert cell
Insert cell
html`${exampleShiftEnterValue}`
Insert cell
viewof exampleShiftEnter = {
// This string will be parsed as HTML, so to embed HTML requires using &lt; &gt;
const defaultShiftEnterText = `&lt;h2&gt;Setting Up Key Commands&lt;/h2&gt;
&lt;p&gt;This editor follows Observable style &lt;i&gt;"Run on &lt;kbd&gt;Shift&lt;/kbd&gt; +
&lt;kbd>Enter&lt;/kbd&gt;"&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Since &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd>Enter&lt;/kbd&gt; is kinda hard to accomplish in
mobile environments, there's a button too. However, it seems to mess up the
focussing behavior of Observable a bit at the moment&lt;/p&gt;`
const {editor, view} = ace(defaultShiftEnterText, undefined, {mode: "ace/mode/html"});

// For some reason I don't understand the `wrapper.value`
// approach from above resulted incorrect behavior.
// A mutable cell works as expected though.
mutable exampleShiftEnterValue = editor.getValue();
// Add callback for Shift-Enter command
editor.commands.addCommand({
name: 'Observablish',
bindKey: {win: 'Shift-Enter', mac: 'Shift-Enter', linux: 'Shift-Enter'},
exec: (editor) => {
mutable exampleShiftEnterValue = editor.getValue();
},
readOnly: true // false if this command should not apply in readOnly mode
});

const refresh = html`<button style="margin:0;padding:0;position:absolute;top:0;right:0;min-width:2em;">▶</button>`
const wrapper = html`<div>${view}${refresh}</div>`
refresh.onclick = () => { mutable exampleShiftEnterValue = editor.getValue() };

return wrapper;
}
Insert cell
mutable exampleShiftEnterValue = ""
Insert cell
Insert cell
aceJS = require('ace-builds@1.12.0/src-min-noconflict/ace.js').catch(() => window["ace"])
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more