HTML, CSS, JavaScript

HTML, CSS, JavaScript#

Inline document#

The {exec} html directive allows displaying a complete HTML document as an <iframe>. The <iframe> defaults to a 16/9 aspect ratio, but its size can be adjusted with :output-style:.

Console output generated by. console methods is displayed in a console output block. Its size can be controlled with :console-style:.

 1<!DOCTYPE html>
 2<html lang="en">
 3<head>
 4  <title>This is the page title (counter: 0)</title>
 5  <style>
 6    img.logo { float: right; min-width: 20px; min-height: 20px; }
 7    h1 { margin: 0; font-size: 3rem; }
 8    span > a { color: red; }
 9  </style>
10</head>
11<body>
12  <img src="/_static/logo.svg" class="logo">
13  <h1 id="top">Hello, </h1>
14  <p class="toc">
15    Go to <a href="#sect-1">section 1</a>, <a href="#sect-2">section 2</a>,
16  </p>
17  <br><br><br><br>
18
19  <h2 id="sect-1">Section 1</h2>
20  <p>This is section 1. Go back to the <a href="#top">top</a>.</p>
21  <h2 id="sect-2">Section 2</h2>
22  <p>This is section 2. Go back to the <a href="#top">top</a>.</p>
23  <h2 id="sect-3">Section 3</h2>
24  <p>This is section 3. Go back to the <a href="#top">top</a>.</p>
25  <h2 id="sect-4">Section 4</h2>
26  <p>This is section 4. Go back to the <a href="#top">top</a>.</p>
27
28  <script>
29document.addEventListener('DOMContentLoaded', () => {
30  document.querySelector('h1').appendChild(document.createTextNode('world!'));
31  const n = document.createElement('span');
32  n.innerHTML = `\
33<a href="#sect-3">section 3</a> or <a href="#sect-4">section 4</a>.`;
34  document.querySelector('p.toc').appendChild(n);
35});
36let counter = 0;
37setInterval(() => {
38  document.title = document.title.replace(/\d+/, ++counter);
39}, 1000);
40
41console.log("log");
42console.debug("debug");
43console.info("info");
44console.warn("Warn");
45console.error("Error");
46console.log('\n');
47console.log();
48console.log(undefined, null, 42, 12.45, "A % string %% value %%%", {a: 1, b: 2},
49            [1, 2, 3, 4]);
50console.log(document.querySelector('title'));
51console.log("A % string %% on %%% its %%%% own");
52console.log("Objects: %o %O %o %O", {a: 1}, {a: 1}, [1, 2], [1, 2]);
53console.log("Integers: %d %i %d %d %d", 1.2, 1.2, -7.8, "-7.8a", "a");
54console.log("Strings: %s %s %s %s", "abc", 12.34, {a: 1}, [1, 2]);
55console.log("Floats: %f %f %f", 12.34, "-12.34a", "a");
56console.log("Styles: %cred %cgreen %cblue",
57            'color: red', 'color: green', 'color: blue');
58console.log("Prefix & suffix: %% %% %d %d %d %d", 1, 2);
59(async () => { throw new Error("Async boom!"); })();
60throw new Error("Boom!");
61  </script>
62  <script>*Invalid JavaScript*</script>
63</body>
64</html>

Partial content#

Browsers are smart enough to render <iframe> tags with partial content correctly. So an {exec} html block can specify just an HTML snippet, and optionally styles (with a <style> element):

1<style>h1 { margin: 0; font-size: 5rem; }</style>
2<h1>Hello, world!</h1>

Or scripts (with a <script> element):

1Please click <button>here</button>
2<script>
3let clicks = 0;
4document.querySelector('button')
5  .addEventListener('click', () => {
6    document.title = `Clicks: ${++clicks}`;
7    console.log(`Clicks: ${clicks}`);
8  });
9</script>

Web application#

Markdown already allows adding arbitrary HTML. Page-specific stylesheets and scripts can be added with the styles and scripts keys of the document metadata.

Please click (clicks: 0)