working on documentation and more API functions
This commit is contained in:
@@ -38,6 +38,7 @@ RENDER(Request& context)
|
||||
<? render_card("dtree.uce", "DTree", "Dynamic hierarchical data tree"); ?>
|
||||
<? render_card("json.uce", "JSON", "Parse and encode JSON data"); ?>
|
||||
<? render_card("preprocessor-comments.uce", "Preprocessor Comments", "Regression coverage for comment parsing in templates"); ?>
|
||||
<? render_card("regex.uce", "Regular Expressions", "PCRE2 matching, captures, replacement, and splitting"); ?>
|
||||
<? render_card("string.uce", "String", "String operations"); ?>
|
||||
<? render_card("str_replace.uce", "String Replace", "Search and replace in strings"); ?>
|
||||
<? render_card("utf8.uce", "UTF-8", "Unicode string handling"); ?>
|
||||
@@ -61,6 +62,7 @@ RENDER(Request& context)
|
||||
<div class="grid-heading">Advanced</div>
|
||||
<? render_card("call_file.uce", "unit_call()", "Dynamic file inclusion"); ?>
|
||||
<? render_card("components.uce", "Components", "Reusable component system"); ?>
|
||||
<? render_card("once-init.uce", "ONCE / INIT", "Unit lifecycle hooks for worker load and request entry"); ?>
|
||||
<? render_card("markdown.uce", "Markdown", "Markdown parsing with components"); ?>
|
||||
<? render_card("script.uce", "Script", "UCE script integration"); ?>
|
||||
<? render_card("websockets.ws.uce", "WebSockets", "Real-time WebSocket chat"); ?>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
static s64 demo_worker_init_count = 0;
|
||||
static s64 demo_component_hits = 0;
|
||||
|
||||
INIT(Request& context)
|
||||
{
|
||||
(void)context;
|
||||
demo_worker_init_count += 1;
|
||||
}
|
||||
|
||||
ONCE(Request& context)
|
||||
{
|
||||
context.call["once_hits"] = context.call["once_hits"].to_s64() + 1;
|
||||
}
|
||||
|
||||
COMPONENT:PROBE(Request& context)
|
||||
{
|
||||
demo_component_hits += 1;
|
||||
|
||||
<>
|
||||
<div class="banner">
|
||||
<strong><?= context.props["label"].to_string() ?></strong>
|
||||
<div>worker INIT count for this loaded unit: <?= (u64)demo_worker_init_count ?></div>
|
||||
<div>request ONCE count for this request: <?= context.call["once_hits"].to_u64() ?></div>
|
||||
<div>component handler calls served by this worker copy: <?= (u64)demo_component_hits ?></div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
RENDER(Request& context)
|
||||
{
|
||||
DTree first;
|
||||
first["label"] = "First component call";
|
||||
|
||||
DTree second;
|
||||
second["label"] = "Second component call in the same request";
|
||||
|
||||
DTree third;
|
||||
third["label"] = "Third component call through unit_call(\"COMPONENT:PROBE\")";
|
||||
|
||||
<><html>
|
||||
<link rel="stylesheet" href='style.css?v=<?= time() ?>'></link>
|
||||
<h1>
|
||||
<a href="index.uce">UCE Test</a>:
|
||||
ONCE() and INIT()
|
||||
</h1>
|
||||
<p>
|
||||
This page calls the same named component twice. `ONCE()` should only run once for the request, while `INIT()` should stay stable for the currently loaded worker copy.
|
||||
</p>
|
||||
<?: component(":PROBE", first, context) ?>
|
||||
<?: component(":PROBE", second, context) ?>
|
||||
<? unit_call("once-init.uce", "COMPONENT:PROBE", &third); ?>
|
||||
</html></>
|
||||
}
|
||||
@@ -11,6 +11,7 @@ RENDER(Request& context)
|
||||
</h1>
|
||||
|
||||
<p>This page exists to prove the template parser ignores quotes and template markers that appear inside C++ comments.</p>
|
||||
<p>It also renders a literal raw-string terminator sequence safely: <code>)"</code>.</p>
|
||||
|
||||
<?
|
||||
// Regression: this comment's apostrophe must not swallow the later ?> marker.
|
||||
@@ -36,4 +37,4 @@ RENDER(Request& context)
|
||||
<pre><?= var_dump(context.params) ?></pre>
|
||||
</details>
|
||||
</>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
|
||||
#include "demo_guard.h"
|
||||
|
||||
void regex_row(String label, String result, String expect)
|
||||
{
|
||||
bool pass = (result == expect);
|
||||
<><tr>
|
||||
<td class="test-label"><?= label ?></td>
|
||||
<td class="test-result"><code><?= result ?></code></td>
|
||||
<td class="test-status <?= pass ? "pass" : "fail" ?>"><?= pass ? "pass" : "expected: " + expect ?></td>
|
||||
</tr></>
|
||||
}
|
||||
|
||||
void regex_bool_row(String label, bool result, bool expect)
|
||||
{
|
||||
regex_row(label, result ? "true" : "false", expect ? "true" : "false");
|
||||
}
|
||||
|
||||
RENDER(Request& context)
|
||||
{
|
||||
String text = "Contact ops@example.test or tag #uce, #docs, and café.";
|
||||
DTree first_email = regex_search("(?<user>[A-Za-z0-9._%+-]+)@(?<host>[A-Za-z0-9.-]+)", text);
|
||||
DTree tags = regex_search_all("#(?<tag>[A-Za-z0-9_]+)", text);
|
||||
StringList pieces = regex_split("\\s*,\\s*", "uce, components, markdown");
|
||||
|
||||
<>
|
||||
<link rel="stylesheet" href='style.css'></link>
|
||||
<style>
|
||||
table.tests { width: 100%; border-collapse: collapse; margin-bottom: 8px; }
|
||||
table.tests td { padding: 6px 12px; border-bottom: 1px solid rgba(255,255,255,0.06); font-family: var(--font-mono); font-size: 0.88rem; }
|
||||
.test-label { color: var(--text-dim); white-space: nowrap; width: 1%; }
|
||||
.test-result code { background: var(--bg-code); padding: 2px 8px; border-radius: 4px; }
|
||||
.test-status.pass { color: #6f6; width: 1%; }
|
||||
.test-status.fail { color: #f66; }
|
||||
</style>
|
||||
<h1>
|
||||
<a href="index.uce">UCE Test</a>:
|
||||
Regular Expressions
|
||||
</h1>
|
||||
|
||||
<p>UCE regex functions use PCRE2 and return ordinary UCE strings, lists, and DTree values.</p>
|
||||
<p>sample = <code><?= text ?></code></p>
|
||||
|
||||
<h2>Validation And Search</h2>
|
||||
<table class="tests"><?
|
||||
regex_bool_row("regex_match(\"[A-Z][a-z]+\", \"Alice\")", regex_match("[A-Z][a-z]+", "Alice"), true);
|
||||
regex_bool_row("regex_match(\"[A-Z][a-z]+\", \"Alice!\")", regex_match("[A-Z][a-z]+", "Alice!"), false);
|
||||
regex_bool_row("regex_search(\"example\", text)[\"matched\"]", first_email["matched"].to_bool(), true);
|
||||
regex_row("first_email[\"match\"]", first_email["match"].to_string(), "ops@example.test");
|
||||
regex_row("first_email[\"named\"][\"user\"]", first_email["named"]["user"].to_string(), "ops");
|
||||
regex_row("first_email[\"named\"][\"host\"]", first_email["named"]["host"].to_string(), "example.test");
|
||||
regex_bool_row("regex_match(\"\\\\p{L}+\", \"café\")", regex_match("\\p{L}+", "café"), true);
|
||||
?></table>
|
||||
|
||||
<h2>All Matches</h2>
|
||||
<table class="tests"><?
|
||||
regex_row("regex_search_all hashtags count", tags["count"].to_string(), "2.000000");
|
||||
regex_row("first hashtag", tags["matches"]["0"]["named"]["tag"].to_string(), "uce");
|
||||
regex_row("second hashtag", tags["matches"]["1"]["named"]["tag"].to_string(), "docs");
|
||||
?></table>
|
||||
|
||||
<h2>Replace And Split</h2>
|
||||
<table class="tests"><?
|
||||
regex_row("regex_replace(\"#([A-Za-z0-9_]+)\", \"<tag>$1</tag>\", \"#uce\")", regex_replace("#([A-Za-z0-9_]+)", "<tag>$1</tag>", "#uce"), "<tag>uce</tag>");
|
||||
regex_row("join(regex_split(\"\\\\s*,\\\\s*\", ...), \"|\")", join(pieces, "|"), "uce|components|markdown");
|
||||
regex_row("case-insensitive flag", regex_search("uce", "Hello UCE", "i")["match"].to_string(), "UCE");
|
||||
?></table>
|
||||
|
||||
<h2>Structured Result</h2>
|
||||
<pre><?= json_encode(first_email) ?></pre>
|
||||
|
||||
<p><a href="../doc/index.uce?p=regex_search">Read the regex API documentation</a></p>
|
||||
</>
|
||||
}
|
||||
Reference in New Issue
Block a user