Smartdown is intended to serve a broad audience, enabling the teaching and explanation of many different subjects. Some of these subjects such as Computer Science and Programming and Linguistics demand the ability to express, share, explain and execute code. Smartdown embraces this idea by making it easy to play code fragments of various forms into the document.
Currently, only Javascript is supported within Smartdown, although it is trivial to build upon this to support per-document embedded languages.
This Javascript integration will evolve to be safer and more convenient. Currently, Smartdown variables are strings, and must be converted. The reactivity in Smartdown is currently not as good as it could be, so an explicit call to smartdown.setVariable()
is required to trigger other cells and playables to update.
In the same way that Smartdown accommodates a diversity of playable languages, including GraphViz, Mermaid, and other DSLs (Domain-specific Languages), it can and eventually will include a diversity of executable languages via a playable plugin mechanism. Right now, though, Javascript is the primary scripting language for Smartdown.
This example is totally useless. Every time you play the script, it increments a Smartdown variable named COUNTER
which is displayed here:
- Counter
Hint: Click Stop
and Play
repeatedly to see what's going on
var counter = env.COUNTER || 0;
++counter;
smartdown.setVariable('COUNTER', counter, 'integer');
Every playable is assigned a <div>
sandbox within which it can display its content. This is used (for example) in a D3 playable which will render an SVG in the playable's <div>
. The following example will adjust the size, border and background of the playable's <div>
via the use of this.div
, which points to the DOM element and permit normal DOM manipulation.
var playableDiv = this.div;
playableDiv.style.width = '80%';
playableDiv.style.margin = 'auto';
playableDiv.style.padding = '20px';
playableDiv.style.border = '5px solid purple';
playableDiv.style.background='lightgreen';
playableDiv.innerHTML = '<h1>Hello World</h1>';
I'm looking for better ways to report per-playable errors and per-playable logging output. I've added an experimental per-playable console UI, which is hidden by default. If output is written to the playable's console, a Console
toggle button will be displayed above the content of the console.
The this.log()
function, when invoked within a playable, will output to the playable's console.
this.log('Hello World from this Playable!');
as in the following playable:
this.log('Hello World from this Playable!');
const log = this.log;
this.dependOn.MyVariableA = function() {
log('MyVariableA changed to: ', env.MyVariableA);
};
this.dependOn.MyVariableB = function() {
log('MyVariableB changed to: ', env.MyVariableB);
};
MyVariableA MyVariableB
const log = this.log;
this.dependOn.MyVariableA = () => {
log('MyVariableA changed to: ', env.MyVariableA);
};
this.dependOn.MyVariableB = () => {
log('MyVariableB changed to: ', env.MyVariableB);
};
const log = this.log;
this.dependOn = ['MyVariableX', 'MyVariableY'];
this.depend = () => {
log('MyVariableX changed to: ', env.MyVariableX);
log('MyVariableY changed to: ', env.MyVariableY);
};
MyVariableX MyVariableY
const log = this.log;
this.dependOn = ['MyVariableX', 'MyVariableY'];
this.depend = () => {
log('MyVariableX changed to: ', env.MyVariableX);
log('MyVariableY changed to: ', env.MyVariableY);
};
There should be NO blue progress bar below; otherwise, we have a bug
const log = this.log;
smartdown.setVariable('Preset', 1);
this.dependOn = ['Preset'];
this.depend = () => {
log('Preset changed to: ', env.Preset);
};
As of Smartdown v1.024, there is an optional this.sizeChanged()
handler available to Javascript playable authors. Here, we'll create a this.sizeChanged()
handler to detect playable size changes to our playable, and to reflect these by changing the content of the playable.
var that = this;
var playableDiv = this.div;
playableDiv.style.border = '5px solid magenta';
playableDiv.style.background='lightblue';
this.sizeChanged = function() {
playableDiv.innerHTML =
`
<div style="padding:20px;">
<h6>width: ${playableDiv.offsetWidth}</h6>
<h6>height: ${playableDiv.offsetHeight}</h6>
</div>
`;
};
that.sizeChanged();
setTimeout(function() {
that.sizeChanged();
}, 0);
Smartdown by default wraps its playables in an async
function, so that authors can assume that await
will work properly in their playable. (This is all NYI as of SD 1.0.24).
For this example, we'll use the Fetch API to retrieve an example JSON file (the Smartdown package.json
in this case), and to parse and display this file in a cell.
Because the Fetch API uses Promises, we can use the async/await syntactic sugar to easily manage asynchronous tasks without the requirement of nesting continuations.
Prior to Smartdown 1.0.25, it was possible to use await
by wrapping your playable code explcitly with an anonymous async
function.
(async () => {
const response = await fetch('https://unpkg.com/smartdown/package.json');
const myJson = await response.json();
smartdown.setVariable('PackageExplicit', myJson);
})();
package.json via anonymous async
Smartdown 1.0.25 now wraps the playable's code in an implicit async
function, which removes the need for an explicit wrapper.
const response = await fetch('https://unpkg.com/smartdown/package.json');
const myJson = await response.json();
smartdown.setVariable('Package', myJson);
package.json via implicit async
Back to Home