diff --git a/layouts/shortcodes/agent-memory-demo.html b/layouts/shortcodes/agent-memory-demo.html index 825bc24604..3e9c9546d0 100644 --- a/layouts/shortcodes/agent-memory-demo.html +++ b/layouts/shortcodes/agent-memory-demo.html @@ -20,11 +20,12 @@ {{- /* ?v= is a hash of the file, so a reload never runs a stale cached copy. */ -}} {{- $v := dict -}} -{{- range slice "css/context-retriever-demo.css" "css/agent-memory-demo.css" "js/agent-memory-demo.js" -}} +{{- range slice "css/context-retriever-demo.css" "css/agent-memory-demo.css" "js/demo-highlight.js" "js/agent-memory-demo.js" -}} {{- $v = merge $v (dict . (substr (md5 (os.ReadFile (print "static/" .))) 0 10)) -}} {{- end }} +
INDEXMISSING option, so the database must run Redis 7.4 or later. " +
"Tag fields used for access control, which this demo doesn't include, also get INDEXEMPTY. The index names are illustrative."));
p.appendChild(idx);
@@ -678,7 +678,12 @@
var right = panels.model.querySelector(".rcr-tools");
if (right) { renderTools(right); right.classList.remove("rcr-flash"); void right.offsetWidth; right.classList.add("rcr-flash"); }
var beh = panels.model.querySelector(".rcr-behind pre");
- if (beh) beh.textContent = indexCommands(state.model, state.surface).join("\n\n") || "No indexed fields, so no index is created.";
+ if (beh) beh.innerHTML = indexHtml();
+ }
+ /* The FT.CREATE commands behind the tools, highlighted, or why there are none. */
+ function indexHtml() {
+ var cmds = indexCommands(state.model, state.surface);
+ return cmds.length ? window.DemoHL.redis(cmds.join("\n\n")) : esc("No indexed fields, so no index is created.");
}
function entityCard(ent) {
@@ -909,7 +914,7 @@
body.appendChild(el("pre", "rcr-code rcr-code-sm", jsonHtml(failed ? res : c.result)));
var cd = el("details", "rcr-curl");
cd.appendChild(el("summary", "", "Run this call yourself with curl"));
- cd.appendChild(el("pre", "rcr-code rcr-code-sm", esc(curlFor(c.name, c.args, c.id))));
+ cd.appendChild(el("pre", "rcr-code rcr-code-sm", window.DemoHL.shell(curlFor(c.name, c.args, c.id))));
body.appendChild(cd);
d.appendChild(body);
return d;
diff --git a/static/js/demo-highlight.js b/static/js/demo-highlight.js
new file mode 100644
index 0000000000..e6cf3135a3
--- /dev/null
+++ b/static/js/demo-highlight.js
@@ -0,0 +1,170 @@
+/* =========================================================================
+ Syntax highlighting for the scripted demos' code blocks
+ Dependency-free and shared: each demo's shortcode loads this before the
+ demo itself. Every function takes text exactly as a demo shows it and
+ returns it escaped, with spans the shared stylesheet colors. Redis commands
+ are colored the way Redis Insight's Workbench colors them, and the other
+ languages follow the same roles:
+ hl-cmd a command or language keyword, such as FT.SEARCH, curl, or import
+ hl-kw an option, such as SCHEMA or -H
+ hl-key an index name or URL
+ hl-field an @field
+ hl-query a query, quotes and all
+ hl-op a comparison or logical operator in a query; YAML list dashes
+ hl-fn a function in a query, such as ismissing
+ hl-str a string
+ hl-num a number
+ hl-com a comment
+ hl-faint framing that isn't the point: reply index numbers, (integer),
+ line continuations, and " + esc(sqlOf(s)) + ""; }, runStatement));
+ function (s) { return "" + window.DemoHL.sql(sqlOf(s)) + ""; }, runStatement));
var ran = st.ran.map(function (k) { return byKey(STATEMENTS, k); });
if (ran.length) p.appendChild(changesCard(ctx, ran, STATEMENTS.length));
p.appendChild(grid(sourceCard(ctx), redisCard(ctx)));
@@ -961,7 +961,7 @@
var start = /^transform:/.test(line) ? 1 : /^ key:/.test(line) ? 2 : 0;
if (start) block = start;
else if (/^output:/.test(line)) block = 0;
- html += '' + (start ? '' + start + "" : "") + esc(line) + "";
+ html += '' + (start ? '' + start + "" : "") + window.DemoHL.yaml(line) + "";
});
/* YAML depends on indentation, so lines never wrap: the file scrolls
sideways instead, and the body spans the widest line so the
diff --git a/static/js/redisvl-demo.js b/static/js/redisvl-demo.js
index abe493df5e..e5afa05519 100644
--- a/static/js/redisvl-demo.js
+++ b/static/js/redisvl-demo.js
@@ -175,12 +175,13 @@
var m = line.match(/^ - name: (\S+)/);
if (m) cur = m[1];
else if (!/^ {4}/.test(line)) cur = null;
- return used.indexOf(cur) >= 0 ? '' + esc(line) + "" : esc(line);
+ var html = window.DemoHL.yaml(line);
+ return used.indexOf(cur) >= 0 ? '' + html + "" : html;
}).join("\n");
}
- /* Code with "restaurants.yaml" as a link to the schema. */
+ /* The Python, highlighted, with "restaurants.yaml" as a link to the schema. */
function withYamlLink(text) {
- return esc(text).replace(/"restaurants\.yaml"/g, '');
+ return window.DemoHL.python(text).replace(/"restaurants\.yaml"/g, '');
}
/* --------------------------------------------------------------- the widget */
@@ -382,7 +383,7 @@
card.appendChild(head);
var used = fieldsUsed(q, built);
if (st.view !== "data") {
- var pre = el("pre", "rcr-code rvd-pre", st.view === "python" ? withYamlLink(pythonFor(q, built)) : st.view === "redis" ? esc(commandFor(built)) : schemaHtml(used));
+ var pre = el("pre", "rcr-code rvd-pre", st.view === "python" ? withYamlLink(pythonFor(q, built)) : st.view === "redis" ? window.DemoHL.redis(commandFor(built)) : schemaHtml(used));
pre.addEventListener("click", function (e) { if (e.target.closest(".rvd-yaml")) { st.view = "schema"; render(); } });
card.appendChild(pre);
}
diff --git a/static/js/search-demo.js b/static/js/search-demo.js
index f0539f0316..07fa0eca7a 100644
--- a/static/js/search-demo.js
+++ b/static/js/search-demo.js
@@ -155,6 +155,10 @@
}
function cmdline(argv) { return argv.map(function (a, i) { return token(argv, i); }).join(" "); }
+ /* Syntax highlighting comes from demo-highlight.js, which the shortcode loads first. */
+ function hl(argv, i) { return window.DemoHL.arg(argv, i, token(argv, i)); }
+ function hlReply(text) { return window.DemoHL.reply(text); }
+
/* ------------------------------------------------ step 3: filter and sort */
function filterQuery(f) {
@@ -416,7 +420,7 @@
/* A transcript line: the prompt, the command, and its reply. */
function line(argv, reply) {
- return '> ' + cmdHtml(argv) + "\n" + esc(reply);
+ return '> ' + cmdHtml(argv) + "\n" + hlReply(reply);
}
/* A key as written and as read back, exactly as redis-cli prints it. */
function docBox(key) {
@@ -445,7 +449,7 @@
box.appendChild(el("div", "rsi-createhead", "The index, part by part"));
lines.forEach(function (l) {
var toks = [];
- for (var j = l.from; j <= l.to; j++) toks.push(esc(token(argv, j)));
+ for (var j = l.from; j <= l.to; j++) toks.push(hl(argv, j));
box.appendChild(el("div", "rsi-cline", '' + toks.join(" ") + '' + l.note + ""));
});
var foot = el("div", "rcr-faint rsi-createcap", "One part per line here. In redis-cli, it's a single line. "), copy = el("button", "rsi-copy", "Copy as one line");
@@ -491,7 +495,7 @@
function outputBlock(c) {
var box = el("div", "rsi-create rsi-output");
box.appendChild(el("div", "rsi-createhead", "The output"));
- box.appendChild(el("pre", "rcr-code rsq-pre rsq-cmdline", esc(c.reply.replace(/\n$/, ""))));
+ box.appendChild(el("pre", "rcr-code rsq-pre rsq-cmdline", hlReply(c.reply.replace(/\n$/, ""))));
box.appendChild(el("div", "rcr-faint rsi-createcap", esc("Exactly what redis-cli prints." +
(st.tab === "text" ? " The tags around matched words come from HIGHLIGHT." : ""))));
return box;
@@ -506,7 +510,7 @@
}
function cmdHtml(argv) {
var m = marks(argv);
- return argv.map(function (a, i) { var t = esc(token(argv, i)); return m[i] ? '' + t + "" : t; }).join(" ");
+ return argv.map(function (a, i) { var t = hl(argv, i); return m[i] ? '' + t + "" : t; }).join(" ");
}
render();
diff --git a/static/js/search-index-demo.js b/static/js/search-index-demo.js
index ef66dd3cd3..7d06d7f24b 100644
--- a/static/js/search-index-demo.js
+++ b/static/js/search-index-demo.js
@@ -233,6 +233,10 @@
}
function cmdline(argv) { return argv.map(function (a, i) { return token(argv, i); }).join(" "); }
+ /* Syntax highlighting comes from demo-highlight.js, which the shortcode loads first. */
+ function hl(argv, i) { return window.DemoHL.arg(argv, i, token(argv, i)); }
+ function hlReply(text) { return window.DemoHL.reply(text); }
+
/* --------------------------------------------------------------- the widget */
var STEPS = [
@@ -529,7 +533,7 @@
/* A transcript line: the prompt, the command, and, when asked, its reply. */
function line(argv, reply, withReply) {
- return '> ' + cmdHtml(argv) + "\n" + (withReply ? esc(reply) : "");
+ return '> ' + cmdHtml(argv) + "\n" + (withReply ? hlReply(reply) : "");
}
/* A key as written and as read back, exactly as redis-cli prints it. */
function docBox(key) {
@@ -567,7 +571,7 @@
box.appendChild(el("div", "rsi-createhead", "The index, part by part"));
lines.forEach(function (l) {
var toks = [];
- for (var j = l.from; j <= l.to; j++) { var t = esc(token(argv, j)); toks.push(m[j] ? '' + t + "" : t); }
+ for (var j = l.from; j <= l.to; j++) { var t = hl(argv, j); toks.push(m[j] ? '' + t + "" : t); }
box.appendChild(el("div", "rsi-cline", '' + toks.join(" ") + '' + l.note + ""));
});
var foot = el("div", "rcr-faint rsi-createcap", "One part per line here. In redis-cli, it's a single line. "), copy = el("button", "rsi-copy", "Copy as one line");
@@ -609,7 +613,7 @@
function outputBlock(c) {
var box = el("div", "rsi-create rsi-output"), cap = "Exactly what redis-cli prints.";
box.appendChild(el("div", "rsi-createhead", "The output"));
- box.appendChild(el("pre", "rcr-code rsq-pre rsq-cmdline" + (c.error ? " is-err" : ""), esc(c.reply.replace(/\n$/, "")))); // an error reply in red
+ box.appendChild(el("pre", "rcr-code rsq-pre rsq-cmdline" + (c.error ? " is-err" : ""), hlReply(c.reply.replace(/\n$/, "")))); // an error reply in red
if (c.query[0] === "FT.INFO") cap += " Sizes, timings, and counters vary from server to server.";
else if (st.tab === "keys") cap += " The keys come back in Redis's own order.";
box.appendChild(el("div", "rcr-faint rsi-createcap", cap));
@@ -630,7 +634,7 @@
}
function cmdHtml(argv) {
var m = marks(argv);
- return argv.map(function (a, i) { var t = esc(token(argv, i)); return m[i] ? '' + t + "" : t; }).join(" ");
+ return argv.map(function (a, i) { var t = hl(argv, i); return m[i] ? '' + t + "" : t; }).join(" ");
}
render();
}