diff --git a/config.toml b/config.toml index 7854e90..ad2ff3f 100644 --- a/config.toml +++ b/config.toml @@ -28,6 +28,10 @@ external_links_target_blank = true [markdown.highlighting] style = "class" theme = "github-light" +# Register an "output" language so ```output fenced blocks keep a +# data-lang="output" attribute we can target with CSS (see sass/style.scss). +# The grammar itself does no highlighting; it just marks the text as plain. +extra_grammars = ["grammars/output.json"] [search] include_title = true diff --git a/content/generators/install/index.md b/content/generators/install/index.md index 109b192..95e424e 100644 --- a/content/generators/install/index.md +++ b/content/generators/install/index.md @@ -31,19 +31,16 @@ These steps use Docker to run the Shinzo Generator client. To build the Generato docker pull ghcr.io/shinzonetwork/shinzo-generator-client:ethereum-mainnet-latest ``` - {% output() %} -``` + ```output standard: Pulling from shinzonetwork/shinzo-generator-client 2521f1b70bf8: Pull complete 2c845527b24c: Pull complete [...] - + Digest: sha256:a272b09607e6f3f07399d72d019f058919ba2854469835b80478fd75799fa0fd Status: Downloaded newer image for ghcr.io/shinzonetwork/shinzo-generator-client:ethereum-mainnet-latest - -``` -{% end %} + ``` 1. Gather your Geth node's: @@ -73,8 +70,7 @@ These steps use Docker to run the Shinzo Generator client. To build the Generato You should see the Generator client connect to Geth and start collecting and committing blocks: -{% output() %} -``` +```output 2026-05-11T10:59:54.762Z INFO Committed block 25071330 (ID: bae-235bbc36-32ff-5fb0-8361-6c4dc3d6aeb9) 2026-05-11T10:59:54.902Z DEBUG HTTP response: 200 OK (Content-Length: ) 2026-05-11T10:59:54.902Z DEBUG HTTP request successful, status: 200 OK @@ -84,17 +80,14 @@ You should see the Generator client connect to Geth and start collecting and com 2026-05-11T10:59:55.409Z DEBUG HTTP response: 200 OK (Content-Length: ) 2026-05-11T10:59:55.409Z DEBUG HTTP request successful, status: 200 OK ``` -{% end %} Eventually your Generator client will catch up with the validator node and start waiting for new blocks rather than pulling historical data: -{% output() %} -``` +```output 2026-05-11T11:05:09.338Z DEBUG HTTP response: 200 OK (Content-Length: ) 2026-05-11T11:05:09.338Z DEBUG HTTP request successful, status: 200 OK 2026-05-11T11:05:09.338Z INFO Block 25071451 not available yet, waiting... ``` -{% end %} ### Registration diff --git a/content/guides/operator-quickstart/index.md b/content/guides/operator-quickstart/index.md index 205aa2c..91d893e 100644 --- a/content/guides/operator-quickstart/index.md +++ b/content/guides/operator-quickstart/index.md @@ -100,8 +100,7 @@ Both come from the Generator client's `/health` endpoint once it finishes starti curl -s http://localhost:8080/health | jq '.p2p.self' ``` -{% output() %} -``` +```output { "id": "12D3KooWK8zmiDmX91PwDV1PsqtgA1UUDuuyipVBVPEjrvwgoFJH", "addresses": [ @@ -111,7 +110,6 @@ curl -s http://localhost:8080/health | jq '.p2p.self' "public_key": "8a7f061eeaaec8b8130ce4b9d6e519bbe76b9a4bc038b7e6743a773ad3915e02" } ``` -{% end %} `id` is the Generator client's libp2p Peer ID, derived from its keyring secret. It's stable across restarts as long as the secret stays the same. @@ -130,11 +128,9 @@ BOOTSTRAP_PEER="/ip4/${INDEXER_IP}/tcp/9171/p2p/${PEER_ID}" echo "$BOOTSTRAP_PEER" ``` -{% output() %} -``` +```output /ip4/172.17.0.2/tcp/9171/p2p/12D3KooWK8zmiDmX91PwDV1PsqtgA1UUDuuyipVBVPEjrvwgoFJH ``` -{% end %} `BOOTSTRAP_PEER` is a libp2p multiaddr that essentially says _"speak IPv4 to this address on this TCP port, then handshake with this Peer ID."_ If the Peer ID doesn't match, the Host client refuses the connection. This is what makes the connection authenticated end to end. @@ -204,8 +200,7 @@ The Host client's `/health` lists the peers it's connected to. Once the Generato curl -s http://localhost:8081/health | jq '{status, current_block, p2p: {self: .p2p.self.id, peers: [.p2p.peers[].id]}}' ``` -{% output() %} -``` +```output { "status": "healthy", "current_block": 25303386, @@ -217,7 +212,6 @@ curl -s http://localhost:8081/health | jq '{status, current_block, p2p: {self: . } } ``` -{% end %} Check the Generator client's side too. Its peer list should now contain the Host client: @@ -225,13 +219,11 @@ Check the Generator client's side too. Its peer list should now contain the Host curl -s http://localhost:8080/health | jq '[.p2p.peers[].id]' ``` -{% output() %} -``` +```output [ "12D3KooWK76zTyFW73BSwoQRkuM45Aky7SNSCQGkzjGvxGy8Y76Z" ] ``` -{% end %} If both list each other, libp2p is connected and DefraDB is replicating between them! Data from the Generator client lands in the Host client within a few seconds. @@ -246,8 +238,7 @@ curl -s -X POST http://localhost:9182/api/v0/graphql \ | jq ``` -{% output() %} -``` +```output { "data": { "Ethereum__Mainnet__Log": [ @@ -265,7 +256,6 @@ curl -s -X POST http://localhost:9182/api/v0/graphql \ } } ``` -{% end %} The rows that come back were originally just logs on Ethereum, then pulled in by the Generator client over the Geth WebSocket, signed, gossiped over libp2p to the Host client, and are now being served back to you over GraphQL. More queries are on the [Host examples](/hosts/examples) page. diff --git a/grammars/output.json b/grammars/output.json new file mode 100644 index 0000000..dbe81a8 --- /dev/null +++ b/grammars/output.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "scopeName": "text.output", + "name": "output", + "patterns": [{ "include": "#main" }], + "repository": { + "main": { + "match": ".*", + "name": "text.output" + } + } +} diff --git a/sass/style.scss b/sass/style.scss index 469e850..c7489aa 100644 --- a/sass/style.scss +++ b/sass/style.scss @@ -759,15 +759,15 @@ pre { } /* ─── Output code blocks (```output) ─────────────────────────────────── */ -.code-output { +// Rendered by Zola as
...). The "output"
+// language is registered via extra_grammars (grammars/output.json) so Zola
+// keeps the data-lang attribute instead of folding it to "plain".
+.markdown pre:has(code[data-lang="output"]) {
position: relative;
- margin: 0 0 1rem;
-
- pre {
- background: color-mix(in srgb, var(--code-background) 80%, black);
- }
+ background: color-mix(in srgb, var(--code-background) 80%, black);
- &__label {
+ &::before {
+ content: "output";
position: absolute;
top: 0;
right: 0;
@@ -784,6 +784,28 @@ pre {
}
}
+/* Collapse the gap between a code block and an immediately following output
+ block so they read as a single stacked unit. Handles both the raw
+ + case (before JS runs) and the .code-block-wrapper case (after
+ copy-code.js wraps the preceding ). Output blocks preceded by anything
+ else (a , a heading, etc.) keep their normal top margin. */
+
+// Raw
directly followed by an output (no-JS / same-structure).
+.markdown pre:has(+ pre > code[data-lang="output"]) {
+ margin-bottom: 0;
+}
+.markdown pre + pre:has(code[data-lang="output"]) {
+ margin-top: 0;
+}
+
+// Wrapped code block followed by an output (post-JS).
+.markdown .code-block-wrapper:has(+ pre > code[data-lang="output"]) pre {
+ margin-bottom: 0;
+}
+.markdown .code-block-wrapper + pre:has(code[data-lang="output"]) {
+ margin-top: 0;
+}
+
/* ─── Changelog ──────────────────────────────────────────────────────── */
.changelog {
h2 {
diff --git a/static/js/copy-code.js b/static/js/copy-code.js
index de27f53..4831230 100644
--- a/static/js/copy-code.js
+++ b/static/js/copy-code.js
@@ -68,11 +68,12 @@
}
function init() {
- // All code blocks inside rendered markdown, excluding those inside an
- // output block (.code-output) which intentionally have no copy button.
+ // All code blocks inside rendered markdown, excluding output blocks
+ // (code[data-lang="output"]) which intentionally have no copy button.
var pres = document.querySelectorAll(".markdown pre");
Array.prototype.forEach.call(pres, function (pre) {
- if (pre.closest(".code-output")) return;
+ var code = pre.querySelector("code");
+ if (code && code.getAttribute("data-lang") === "output") return;
if (pre.closest(".mermaid-container")) return;
addButton(pre);
});
diff --git a/templates/shortcodes/output.html b/templates/shortcodes/output.html
deleted file mode 100644
index a44631e..0000000
--- a/templates/shortcodes/output.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{# Output code block (formerly ```output). Renders darker, with an "output" label. #}
-
- output
-{{ body | markdown | safe }}
-