changing doc format and HTML literals

This commit is contained in:
Udo 2026-04-22 01:56:46 +00:00
parent 8223dcc6b3
commit f7b066b374
123 changed files with 1917 additions and 1611 deletions

View File

@ -1,7 +1,132 @@
struct DocPage {
String title;
String content;
StringList sig_lines;
StringList param_lines;
StringList see_lines;
};
String doc_default_title(String page)
{
String page_title = page;
if(page_title.length() > 1 && page_title[1] == '_')
nibble(page_title, "_");
return(page_title);
}
String doc_markdown_inline(String text)
{
text = trim(text);
if(text == "")
return("");
String html = markdown_to_html(text);
if(html.length() >= 7 && html.substr(0, 3) == "<p>" && html.substr(html.length() - 4) == "</p>")
return(html.substr(3, html.length() - 7));
return(html);
}
String doc_legacy_heading(String section)
{
if(section == "desc")
return("");
if(section == "related")
return("## PHP & JS Equivalents");
return("## " + section);
}
DocPage load_doc_page(String page)
{
DocPage result;
StringList lines = split(file_get_contents("pages/" + page + ".txt"), "\n");
String current_section = "";
bool content_mode = false;
StringList content_lines;
for(auto line : lines)
{
if(!content_mode && line != "" && line.substr(0, 1) == ":")
{
String section = trim(line.substr(1));
if(section == "title" || section == "sig" || section == "params" || section == "see")
{
current_section = section;
continue;
}
if(section == "content")
{
content_mode = true;
current_section = "content";
continue;
}
current_section = "legacy";
String heading = doc_legacy_heading(section);
if(heading != "")
{
if(content_lines.size() > 0 && content_lines.back() != "")
content_lines.push_back("");
content_lines.push_back(heading);
content_lines.push_back("");
}
continue;
}
if(current_section == "title")
{
if(result.title != "")
result.title += "\n";
result.title += line;
}
else if(current_section == "sig")
{
result.sig_lines.push_back(line);
}
else if(current_section == "params")
{
result.param_lines.push_back(line);
}
else if(current_section == "see")
{
if(trim(line) != "")
result.see_lines.push_back(trim(line));
}
else
{
content_lines.push_back(line);
}
}
result.content = join(content_lines, "\n");
result.title = trim(result.title);
return(result);
}
void render_doc_params(StringList param_lines)
{
if(param_lines.size() == 0)
return;
<><div class="doc-section params">
<h3>Parameters</h3><?
for(auto line : param_lines)
{
if(trim(line) == "")
continue;
String name = trim(nibble(line, ":"));
String value = trim(line);
?><div><b><?= name ?></b><?
if(value != "")
{
?> : <?: doc_markdown_inline(value) ?><?
}
?></div><?
}
?></div></>
}
void render_see_section(String name)
{
StringList lines = split(file_get_contents("areas/"+name+".txt"), "\n");
StringList lines = split(file_get_contents("areas/" + name + ".txt"), "\n");
s32 idx = 0;
for(auto line : lines)
{
@ -18,13 +143,40 @@ void render_see_section(String name)
<></ul></div></>
}
void render_doc_see_links(StringList see_lines)
{
if(see_lines.size() == 0)
return;
<><h3 class="sidebar-subhead">Related</h3>
<?
for(auto sl : see_lines)
{
if(sl[0] == '>')
{
render_see_section(sl.substr(1));
}
else
{
?><div><a href="index.uce?p=<?= trim(sl) ?>"><?= trim(sl) ?><span class="dim">()</span></a></div><?
}
}
?>
</>
}
RENDER(Request& context)
{
String page = first(context.get["p"], "index");
String page_title = page;
nibble(page_title, "_");
DocPage doc_page;
String page_title = doc_default_title(page);
if(page != "index")
{
doc_page = load_doc_page(page);
if(doc_page.title != "")
page_title = doc_page.title;
}
<><html>
<head>
@ -143,135 +295,35 @@ RENDER(Request& context)
}
else
{
auto doc = split(file_get_contents("pages/"+page+".txt"), "\n");
// Pre-extract sidebar-only sections so the article body stays focused.
StringList equiv_lines;
StringList see_lines;
String sidebar_section = "";
for(auto s : doc)
{
if(s != "" && s.substr(0, 1) == ":")
{
sidebar_section = s.substr(1);
}
else if(sidebar_section == "related" && s != "")
{
equiv_lines.push_back(s);
}
else if(sidebar_section == "see" && s != "")
{
see_lines.push_back(s);
}
}
String detail_class = "detail-layout";
if(equiv_lines.size() == 0 && see_lines.size() == 0) detail_class += " no-sidebar";
if(doc_page.see_lines.size() == 0)
detail_class += " no-sidebar";
?><div class="<?= detail_class ?>">
<article class="doc-detail"><?
String layout_class = "text";
u32 line_idx = 0;
bool section_hidden = false;
for(auto s : doc)
if(doc_page.sig_lines.size() > 0)
{
line_idx++;
if(s == "")
{
}
else if(s.substr(0, 1) == ":")
{
String new_class = s.substr(1);
// Close previous section's div if it was rendered
if(line_idx > 1 && !section_hidden)
{
?></div><?
}
section_hidden = (new_class == "related" || new_class == "see");
layout_class = new_class;
if(!section_hidden)
{
?><div class="doc-section <?= layout_class ?>"><?
if(layout_class == "params")
{
?><h3>Parameters</h3><?
}
else if(layout_class == "sig")
{
?><h3>Signature</h3><?
}
else if(layout_class == "pre")
{
layout_class = "sig";
}
else if(layout_class == "desc")
{
?><h3>Description</h3><?
}
else
{
?><h3><?= layout_class ?></h3><?
}
}
}
else if(!section_hidden)
{
if(s.substr(0, 1) == "-")
{
nibble(s, "-");
?><li><?= (s) ?></li><?
}
else if(layout_class == "sig")
{
?><pre><? print(s); ?></pre><?
}
else if(layout_class == "params")
{
?><div><b><?= trim(nibble(s, ":")) ?></b> : <?= trim(s) ?></div><?
}
else
{
?><div><?: markdown_to_html(s) ?></div><?
}
}
?><div class="doc-section sig">
<h3>Signature</h3>
<pre><? print(join(doc_page.sig_lines, "\n")); ?></pre>
</div><?
}
if(line_idx > 0 && !section_hidden)
render_doc_params(doc_page.param_lines);
if(trim(doc_page.content) != "")
{
?></div><?
?><div class="doc-section content"><?: markdown_to_html(doc_page.content) ?></div><?
}
?></article><?
if(equiv_lines.size() > 0 || see_lines.size() > 0)
if(doc_page.see_lines.size() > 0)
{
?><aside class="detail-sidebar">
<div class="sidebar-card"><?
if(equiv_lines.size() > 0)
{
?><h3>PHP &amp; JS Equivalents</h3><?
for(auto rl : equiv_lines)
{
?><div><?: markdown_to_html(rl) ?></div><?
}
}
if(see_lines.size() > 0)
{
?><h3 class="sidebar-subhead">Related</h3><?
for(auto sl : see_lines)
{
if(sl[0] == '>')
{
render_see_section(sl.substr(1));
}
else
{
?><div><a href="index.uce?p=<?= trim(sl) ?>"><?= trim(sl) ?><span class="dim">()</span></a></div><?
}
}
}
render_doc_see_links(doc_page.see_lines);
?></div>
</aside><?
}
@ -282,5 +334,4 @@ RENDER(Request& context)
?>
</body>
</html></>
}

View File

@ -1,111 +1,136 @@
:sig
:title
DTree
:desc
Dynamic tree/container type used throughout UCE for structured data.
:Overview
`DTree` is UCE's general-purpose structured value type.
This is the runtime's default container for nested data such as configuration trees, call payloads, decoded JSON, connection state, and metadata returned by runtime helpers.
:Value Kinds
- `DTree` can hold:
- `String`
- `f64`
- `bool`
- pointer
- nested map of child `DTree` values (map-shaped `DTree` values can be used to represent list-like data when the keys are numeric strings in sequence)
:Used in
`context.var`
`context.cfg`
`context.call`
`context.connection`
`json_decode()` results
`unit_call()` return values
`unit_info()`
:Reading Values
`["key"]` accesses or creates a child node.
`.has("key")` checks whether a child exists without creating it.
`.key("key")` returns a child pointer when it already exists.
`.get_or_create("key")` returns a child pointer and creates it when missing.
`.get_by_path("a/b/c")` traverses nested children without creating missing keys.
`.to_string()` reads scalar content as text.
`.to_s64()`, `.to_u64()`, and `.to_f64()` perform best-effort numeric conversion.
`.to_bool()` performs best-effort boolean conversion.
`.to_stringmap()` converts a map-shaped tree into `StringMap`.
`operator[]` creates missing entries, just like `std::map`.
`.has()` and `.key()` are the non-mutating lookup helpers.
`.get_by_path()` is the non-creating traversal helper.
`.json_decode()` currently stores JSON numbers as string-valued `DTree` nodes, so typed numeric conversion is the normal way to consume those values.
References are dereferenced automatically in most normal reads.
:Conversion Rules
Scalar-looking strings are trimmed before numeric and boolean parsing.
`.to_bool()` understands common textual forms such as `true`, `false`, `yes`, `no`, `1`, and `0`.
`bool` values convert numerically to `1` / `0`.
Pointer values convert numerically when read as numbers.
Single-value maps can act as scalar wrappers for numeric and boolean conversion.
Invalid numeric input falls back to `0`.
`.to_stringmap()` converts map children key-by-key using each child's `to_string()`.
:Writing Values
`.set(String)`
`.set(f64)`
`.set_bool(bool)`
`.set(StringMap)`
`.set_array()`
`.push(...)`
`.pop()`
`.remove(key)`
`.clear()`
Use `.set_array()` when you want list-style behavior with `push()` / `pop()`.
:Inspection Helpers
`.has(key)`
`.key(key)`
`.get_or_create(key)`
`.get_type_name()`
`.is_array()`
`.is_list()`
`.to_json()`
:each()
`each(std::function<void (DTree t, String key)> f)` iterates over the current tree value.
For map-shaped `DTree` values, the callback is invoked once for each child entry and receives:
`t` as the child value
`key` as the child key
For non-map values, `each()` still invokes the callback once:
`t` is the current value
`key` is an empty string
Typical usage:
`context.var["items"].each([&](DTree item, String key) { print(key, ": ", item.to_string(), "\n"); });`
:Examples
`String theme = context.cfg.get_by_path("theme/key").to_string()`
`u64 compiled_mtime = unit_info("test/hello.uce")["compiled_mtime"].to_u64()`
`bool dark_mode = context.call["dark_mode"].to_bool()`
`if(DTree* user = payload.key("user")) { print(user->to_json()); }`
`payload.get_or_create("headers")->get_or_create("Content-Type")->set("text/plain")`
`StringMap headers = payload["headers"].to_stringmap()`
:related
**PHP:** Nested associative arrays, `stdClass`, decoded JSON trees, and helper accessors for deep array paths.
**JavaScript / Node.js:** Plain objects, arrays, `Map`, and JSON-shaped data passed between handlers.
:sig
DTree
:see
>types
get_by_path
json_decode
:content
`DTree` is UCE's general-purpose structured value type. It is the runtime's default container for nested data such as configuration trees, call payloads, decoded JSON, connection state, and metadata returned by runtime helpers.
## Value Kinds
`DTree` can hold:
- `String`
- `f64`
- `bool`
- pointer values
- nested child `DTree` values in a map-shaped container
Map-shaped `DTree` values can also represent list-like data when their keys are numeric strings in sequence.
## Where It Appears
You will encounter `DTree` throughout the runtime, especially in:
- `context.var`
- `context.cfg`
- `context.call`
- `context.connection`
- `json_decode()` results
- `unit_call()` return values
- `unit_info()`
## Reading Values
- `["key"]` accesses or creates a child node.
- `.has("key")` checks whether a child exists without creating it.
- `.key("key")` returns a child pointer when it already exists.
- `.get_or_create("key")` returns a child pointer and creates it when missing.
- `.get_by_path("a/b/c")` traverses nested children without creating missing keys.
- `.to_string()` reads scalar content as text.
- `.to_s64()`, `.to_u64()`, and `.to_f64()` perform best-effort numeric conversion.
- `.to_bool()` performs best-effort boolean conversion.
- `.to_stringmap()` converts a map-shaped tree into `StringMap`.
`operator[]` creates missing entries, just like `std::map`. `.has()` and `.key()` are the non-mutating lookup helpers, and `.get_by_path()` is the non-creating traversal helper.
`json_decode()` currently stores JSON numbers as string-valued `DTree` nodes, so typed numeric conversion is the normal way to consume those values.
References are dereferenced automatically in most normal reads.
## Conversion Rules
- Scalar-looking strings are trimmed before numeric and boolean parsing.
- `.to_bool()` understands common textual forms such as `true`, `false`, `yes`, `no`, `1`, and `0`.
- `bool` values convert numerically to `1` and `0`.
- Pointer values convert numerically when read as numbers.
- Single-value maps can act as scalar wrappers for numeric and boolean conversion.
- Invalid numeric input falls back to `0`.
- `.to_stringmap()` converts map children key-by-key using each child's `to_string()`.
## Writing Values
Common mutating helpers include:
- `.set(String)`
- `.set(f64)`
- `.set_bool(bool)`
- `.set(StringMap)`
- `.set_array()`
- `.push(...)`
- `.pop()`
- `.remove(key)`
- `.clear()`
Use `.set_array()` when you want list-style behavior with `push()` and `pop()`.
## Inspection Helpers
Useful inspection helpers include:
- `.has(key)`
- `.key(key)`
- `.get_or_create(key)`
- `.get_type_name()`
- `.is_array()`
- `.is_list()`
- `.to_json()`
## each()
`each(std::function<void (DTree t, String key)> f)` iterates over the current tree value.
For map-shaped `DTree` values, the callback runs once per child entry and receives:
- `t` as the child value
- `key` as the child key
For non-map values, `each()` still invokes the callback once:
- `t` is the current value
- `key` is an empty string
```cpp
context.var["items"].each([&](DTree item, String key) {
print(key, ": ", item.to_string(), "\n");
});
```
## Examples
```cpp
String theme = context.cfg.get_by_path("theme/key").to_string();
u64 compiled_mtime = unit_info("test/hello.uce")["compiled_mtime"].to_u64();
bool dark_mode = context.call["dark_mode"].to_bool();
if(DTree* user = payload.key("user")) {
print(user->to_json());
}
payload.get_or_create("headers")->get_or_create("Content-Type")->set("text/plain");
StringMap headers = payload["headers"].to_stringmap();
```
## Related Concepts
- PHP: nested associative arrays, `stdClass`, decoded JSON trees, and helper accessors for deep array paths
- JavaScript / Node.js: plain objects, arrays, `Map`, and JSON-shaped data passed between handlers

View File

@ -1,75 +1,56 @@
:title
Request
:sig
Request& context;
:ServerState* server
Contains the current server state
:StringMap params
All FastCGI server parameters
:StringMap get
The current request's GET variables
:StringMap post
The current request's POST variables
:StringMap cookies
Cookies that have been transmitted by the browser
:StringMap session
The current session
:String session_id
ID of the session cookie
:String session_name
Name of the session cookie
:DTree var
Variable user-defined data
:DTree cfg
Request-local configuration tree. Apps can keep structured configuration here and traverse it with `context.cfg.get_by_path("path/to/value")`.
:DTree call
Invocation or message-local structured data
:DTree connection
Broker-owned per-WebSocket-connection state. Inside `WS(Request& context)`, updates to this tree persist for the lifetime of that socket connection.
:std::vector<UploadedFile> uploaded_files
Files that have been uploaded in the current request
:StringMap header
Headers to be sent back to the browser
:StringList set_cookies;
Cookies that should be sent back to the browser
:context.set_status(s32 code[, String reason])
Sets the HTTP status line and updates `context.flags.status`. When `reason` is omitted, UCE uses a built-in standard reason phrase for common status codes.
:u64 random_seed
The current request's "random" noise generator seed
:u64 random_index
The current request's "random" noise generator index position
:bool flags.log_request
Whether the request should be logged
:Stats
u32 stats.bytes_written
f64 stats.time_init
f64 stats.time_start
f64 stats.time_end
:unit_render(String file_name, [Request& context])
Invokes another UCE file using the current or supplied request context
:see
>types
:related
**PHP:** `$_SERVER`, `$_GET`, `$_POST`, `$_COOKIE`, `$_SESSION`, `header()`, and `http_response_code()`
**JavaScript / Node.js:** Express `req` and `res`, Fetch `Request`, `Headers`, cookies or session middleware, and per-connection state in WebSocket handlers
:content
`Request& context` is the request-local state object passed into UCE handlers. It carries incoming request data, response state, runtime metadata, and helper trees such as `context.cfg`, `context.var`, and `context.call`.
## Core Fields
- `ServerState* server`: current server state
- `StringMap params`: FastCGI server parameters
- `StringMap get`: current request GET variables
- `StringMap post`: current request POST variables
- `StringMap cookies`: cookies sent by the browser
- `StringMap session`: current session data
- `String session_id`: session cookie ID
- `String session_name`: session cookie name
- `DTree var`: user-defined request-local data
- `DTree cfg`: request-local configuration tree
- `DTree call`: invocation or message-local structured data
- `DTree connection`: broker-owned WebSocket connection state that persists across `WS(Request& context)` calls for the same socket
- `std::vector<UploadedFile> uploaded_files`: files uploaded in the current request
- `StringMap header`: headers to send back to the browser
- `StringList set_cookies`: cookies queued for the response
- `u64 random_seed`: current request noise seed
- `u64 random_index`: current request noise index position
## Response Control
`context.set_status(s32 code[, String reason])` sets the HTTP status line and updates `context.flags.status`. When `reason` is omitted, UCE uses a built-in standard reason phrase for common status codes.
## Flags And Stats
- `bool flags.log_request`: controls whether the request should be logged
- `u32 stats.bytes_written`
- `f64 stats.time_init`
- `f64 stats.time_start`
- `f64 stats.time_end`
## Common Usage Notes
- `context.cfg` is the usual place for structured configuration. Use `context.cfg.get_by_path("path/to/value")` for deep reads.
- `context.call` carries invocation data for component calls, unit calls, and WebSocket messages.
- `context.connection` is only meaningful for WebSocket traffic and persists for the lifetime of the connection.
`unit_render(String file_name, [Request& context])` invokes another UCE file using the current or supplied request context.
## Related Concepts
- PHP: `$_SERVER`, `$_GET`, `$_POST`, `$_COOKIE`, `$_SESSION`, `header()`, and `http_response_code()`
- JavaScript / Node.js: Express `req` and `res`, Fetch `Request`, `Headers`, cookies or session middleware, and per-connection state in WebSocket handlers

View File

@ -1,10 +1,21 @@
:title
COMPONENT
:sig
COMPONENT(Request& context)
:desc
:see
>component
>component_render
>1_RENDER
>1_WS
:content
Defines the default component entrypoint for the current `.uce` file.
`component()` and `component_render()` invoke `COMPONENT(Request& context)` by default. Named component entrypoints use `COMPONENT:NAME(Request& context)`.
`component()` and `component_render()` call `COMPONENT(Request& context)` by default. Named component entrypoints use `COMPONENT:NAME(Request& context)`.
## Why It Exists
This keeps page rendering and component rendering separate:
@ -18,23 +29,21 @@ Inside component handlers, props arrive through `context.call`.
When you call `component(":NAME", props, context)` or `component_render(":NAME", props, context)`, the runtime resolves `:NAME` against the current `.uce` file instead of requiring the file name again.
Examples:
`COMPONENT(Request& context)`
`{`
` &lt;&gt;&lt;section&gt;&lt;?: component(":BODY", context.call, context) ?&gt;&lt;/section&gt;&lt;/&gt;`
`}`
## Example
`COMPONENT:BODY(Request& context)`
`{`
` &lt;&gt;&lt;p&gt;&lt;?= context.call["body"] ?&gt;&lt;/p&gt;&lt;/&gt;`
`}`
```cpp
COMPONENT(Request& context)
{
<><section><?: component(":BODY", context.call, context) ?></section></>
}
:see
>component
>component_render
>1_RENDER
>1_WS
COMPONENT:BODY(Request& context)
{
<><p><?= context.call["body"] ?></p></>
}
```
:related
**PHP:** View partials, reusable include files, small template helpers, and server-side component-like rendering patterns
**JavaScript / Node.js:** Reusable component functions, React or Vue components, and server-rendered partials
## Related Concepts
- PHP: view partials, reusable include files, small template helpers, and server-side component-like rendering patterns
- JavaScript / Node.js: reusable component functions, React or Vue components, and server-rendered partials

View File

@ -1,11 +1,19 @@
:title
RENDER
:sig
RENDER(Request& context)
:desc
:see
>ob
:content
Defines the main HTTP render handler for the current `.uce` page.
When a page is requested over HTTP, the runtime loads the target file and calls its `RENDER(Request& context)` function.
## Entry Point Behavior
The default page entrypoint is always the plain `RENDER(Request& context)` handler.
Reusable component handlers now live on `COMPONENT(Request& context)` and `COMPONENT:NAME(Request& context)`. The component helpers call those handlers, not `RENDER()`.
@ -16,11 +24,15 @@ For a normal direct page request, `context.call` starts empty.
If the page is invoked from another UCE file via `unit_render(file_name, context)`, the callee receives that same `context`.
Pages intended to serve WebSocket traffic may expose both `RENDER(Request& context)` and `WS(Request& context)`. Files may also define `COMPONENT()` handlers when they intentionally need both page and component behavior in one unit. In that case `RENDER(Request& context)` serves the direct HTTP response, `WS(Request& context)` handles subsequent WebSocket messages, and `COMPONENT()` remains available only through the component helpers.
Pages intended to serve WebSocket traffic may expose both `RENDER(Request& context)` and `WS(Request& context)`. Files may also define `COMPONENT()` handlers when they intentionally need both page and component behavior in one unit.
:see
>ob
In that case:
:related
**PHP:** Front controller entrypoints, template files, `include`, `require`, and route handlers that write the HTTP response
**JavaScript / Node.js:** Express or Fastify route handlers, page controller functions, and SSR entrypoints that build a response
- `RENDER(Request& context)` serves the direct HTTP response
- `WS(Request& context)` handles later WebSocket messages
- `COMPONENT()` remains available only through the component helpers
## Related Concepts
- PHP: front controller entrypoints, template files, `include`, `require`, and route handlers that write the HTTP response
- JavaScript / Node.js: Express or Fastify route handlers, page controller functions, and SSR entrypoints that build a response

View File

@ -1,15 +1,25 @@
:title
WS
:sig
WS(Request& context)
:desc
:see
>websocket
:content
Defines the WebSocket message handler for the current `.ws.uce` page.
The same page may expose both `RENDER(Request& context)` and `WS(Request& context)`. `RENDER(Request& context)` serves the initial HTTP response, while `WS(Request& context)` is called whenever a complete WebSocket message arrives for that page.
UCE reassembles fragmented messages before calling `WS(Request& context)`. Text and binary frames are both delivered. Use `context.call`, `context.connection`, `ws_opcode()`, and `ws_is_binary()` to inspect the current message.
## Connection State
`context.connection` is a broker-owned `DTree` for the current socket. It starts empty for a new client and persists across later `WS(Request& context)` calls on that same connection.
## Message Data
The current message data is available in `context.call`:
- `context.call["message"]`: current message payload
@ -18,9 +28,7 @@ The current message data is available in `context.call`:
- `context.call["opcode"]`: WebSocket opcode of the current message
- `context.call["document_uri"]`: request URI of the current endpoint
:related
**PHP:** Ratchet `onMessage`, Workerman WebSocket handlers, or lower-level callbacks around accepted socket connections.
**JavaScript / Node.js:** Browser `WebSocket` `message` handlers and Node `ws` server `connection` and `message` callbacks.
## Related Concepts
:see
>websocket
- PHP: Ratchet `onMessage`, Workerman WebSocket handlers, or lower-level callbacks around accepted socket connections
- JavaScript / Node.js: browser `WebSocket` `message` handlers and Node `ws` server `connection` and `message` callbacks

View File

@ -1,12 +1,23 @@
:title
C++ Preprocessor
:sig
UCE source preprocessing
:desc
:see
load
unit_render
unit_call
0_context
1_COMPONENT
:content
UCE runs a small custom source-to-source preprocessor before Clang sees a `.uce` or `.ws.uce` file.
The implementation lives in `src/lib/compiler.cpp`. It does not try to parse all of C++. Instead, it performs a narrow character-wise rewrite that understands UCE literal blocks, inline code islands, `#load`, and `EXPORT` harvesting, then writes a generated `.cpp` file and compiles that file into a shared object.
:Syntax
## Syntax
- `<> ... </>` enters literal-output mode.
- Inside a literal block, `<? ... ?>` emits raw C++.
- Inside a literal block, `<?= expression ?>` emits `print(html_escape(expression));`.
@ -16,13 +27,14 @@ The implementation lives in `src/lib/compiler.cpp`. It does not try to parse all
- `COMPONENT:NAME(Request& context)` is rewritten by the custom pass into an exported named component handler.
- `EXPORT` is also a normal C++ macro, but the custom pass additionally records exported declarations for metadata.
:Pipeline
## Pipeline
- The generated file starts by including `COMPILER_SYS_PATH/src/lib/uce_lib.h`.
- It then inlines the configured setup template from `SETUP_TEMPLATE` (by default `scripts/setup.h.template`), which defines the internal hook `__uce_set_current_request(Request*)`.
- It inserts `#line 1` before page code so compiler diagnostics point back to the original `.uce` file.
- Each literal block is rewritten into one or more `print(R"( ... )");` calls.
- `<? ... ?>` temporarily breaks out of literal printing, emits the enclosed C++ unchanged, then resumes literal output.
- `<?= ... ?>` becomes `print(html_escape(...));`. The runtime currently provides `html_escape()` overloads for `String`, `u64`, and `f64`.
- `<?= ... ?>` becomes `print(html_escape(...));`.
- `<?: ... ?>` becomes `print(...);` and is intended for trusted markup or already-escaped content.
- `#load "file.uce"` is replaced with a generated C++ `#include` that points at the loaded unit's preprocessed `.cpp` file under `BIN_DIRECTORY`.
- Lines beginning with `EXPORT` are scanned so their declarations can be written to a sibling `.exports.txt` file.
@ -31,53 +43,74 @@ The implementation lives in `src/lib/compiler.cpp`. It does not try to parse all
- The final generated source is written to `BIN_DIRECTORY + src_path + "/" + source_file + ".cpp"`.
- `scripts/compile` then compiles that generated `.cpp` into `source_file + ".so"` with `clang++ -shared -std=c++20 ...`.
:GeneratedFiles
- Source file: `/some/path/page.uce`
- Generated C++: `BIN_DIRECTORY/some/path/page.uce.cpp`
- Shared object: `BIN_DIRECTORY/some/path/page.uce.so`
- Export list: `BIN_DIRECTORY/some/path/page.uce.exports.txt`
## Generated Files
:Example
Example 1: literal output with escaped data
`RENDER(Request& context)`
`{`
` &lt;&gt;&lt;h1&gt;&lt;?= context.params["DOCUMENT_URI"] ?&gt;&lt;/h1&gt;&lt;/&gt;`
`}`
For a source file like `/some/path/page.uce`, the preprocessor produces:
- generated C++: `BIN_DIRECTORY/some/path/page.uce.cpp`
- shared object: `BIN_DIRECTORY/some/path/page.uce.so`
- export list: `BIN_DIRECTORY/some/path/page.uce.exports.txt`
## Examples
Literal output with escaped data:
```cpp
RENDER(Request& context)
{
<><h1><?= context.params["DOCUMENT_URI"] ?></h1></>
}
```
Roughly becomes:
`print(R"(&lt;h1&gt;)");`
`print(html_escape(context.params["DOCUMENT_URI"]));`
`print(R"(&lt;/h1&gt;)");`
Example 1b: literal output with trusted unescaped markup
`RENDER(Request& context)`
`{`
` &lt;&gt;&lt;div class="panel"&gt;&lt;?: component("components/card", context.call, context) ?&gt;&lt;/div&gt;&lt;/&gt;`
`}`
```cpp
print(R"(<h1>)");
print(html_escape(context.params["DOCUMENT_URI"]));
print(R"(</h1>)");
```
Literal output with trusted unescaped markup:
```cpp
RENDER(Request& context)
{
<><div class="panel"><?: component("components/card", context.call, context) ?></div></>
}
```
Roughly becomes:
`print(R"(&lt;div class="panel"&gt;)");`
`print(component("components/card", context.call, context));`
`print(R"(&lt;/div&gt;)");`
Example 2: compile-time composition
`#load "partials/nav.uce"`
`RENDER(Request& context)`
`{`
` &lt;&gt;&lt;body&gt;...&lt;/body&gt;&lt;/&gt;`
`}`
```cpp
print(R"(<div class="panel">)");
print(component("components/card", context.call, context));
print(R"(</div>)");
```
Compile-time composition:
```cpp
#load "partials/nav.uce"
RENDER(Request& context)
{
<><body>...</body></>
}
```
The loaded file is resolved relative to the current source file unless the path is already absolute.
:Rules
## Rules
- Literal mode starts only on the exact token `<>`.
- Literal mode ends only on the exact token `</>`.
- `#load` is recognized only when the current line starts with `#load ` at column 1.
- `EXPORT` harvesting likewise only triggers when the current line starts with `EXPORT` at column 1 and is followed by whitespace.
- `EXPORT` harvesting only triggers when the current line starts with `EXPORT` at column 1 and is followed by whitespace.
- Relative `#load` paths are expanded against the including unit's source directory.
- `unit_render()` and `unit_call()` are runtime APIs; `#load` is a compile-time include/composition feature.
- `unit_render()` and `unit_call()` are runtime APIs. `#load` is a compile-time composition feature.
## Limitations
:Limitations
- This pass is character-wise, not a full parser.
- Outside literal blocks it only tracks double-quoted C++ strings while deciding whether `<>` should open literal mode.
- It does not understand comments, raw string literals, templates, or general C++ token structure.
@ -86,18 +119,13 @@ The loaded file is resolved relative to the current source file unless the path
- Because literal output is emitted as a C++ raw string literal `R"( ... )"`, literal content must not contain the exact terminator sequence `)"` or the generated C++ will break.
- `#load` depends on the target unit's generated `.cpp` existing and being compilable. If the target cannot be preprocessed or compiled correctly, the including file will fail to compile as well.
:Debugging
- When a page is compiled, inspect the generated file under `BIN_DIRECTORY` first. That file shows the exact C++ produced by the UCE preprocessor.
## Debugging
- Inspect the generated file under `BIN_DIRECTORY` first. That file shows the exact C++ produced by the UCE preprocessor.
- Compiler errors usually point back to the `.uce` source because the preprocessor inserts `#line 1`, but the generated `.cpp` is still the best place to inspect expansion problems.
- If a `#load` include looks wrong, check the current file's directory, the configured `BIN_DIRECTORY`, and whether the loaded page already produced its own generated `.cpp`.
:see
load
unit_render
unit_call
0_context
1_COMPONENT
## Related Concepts
:related
**PHP:** Template tags like `<?php ... ?>`, `<?= ... ?>`, output buffering, and compile-time include patterns
**JavaScript / Node.js:** JSX transforms, tagged templates, server-side rendering pipelines, and build-time HTML generation
- PHP: template tags like `<?php ... ?>`, `<?= ... ?>`, output buffering, and compile-time include patterns
- JavaScript / Node.js: JSX transforms, tagged templates, server-side rendering pipelines, and build-time HTML generation

View File

@ -1,7 +1,10 @@
:sig
String
:desc
:see
>types
:content
Primary string type used throughout UCE.
`String` is an alias for `std::string`.
@ -12,9 +15,7 @@ Because it is backed by `std::string`, it is binary-safe and may also contain ra
For UTF-8-aware splitting, use helpers such as `split_utf8()` instead of assuming one byte equals one character.
:see
>types
## Related Concepts
:related
**PHP:** Native PHP strings with helpers such as `substr()`, `trim()`, `explode()`, and `implode()`
**JavaScript / Node.js:** JavaScript `string` values with methods such as `slice()`, `trim()`, `split()`, and `join()`
- PHP: native PHP strings with helpers such as `substr()`, `trim()`, `explode()`, and `implode()`
- JavaScript / Node.js: JavaScript `string` values with methods such as `slice()`, `trim()`, `split()`, and `join()`

View File

@ -1,26 +1,30 @@
:sig
StringMap
:desc
Associative container mapping `String` keys to `String` values.
`StringMap` is an alias for `std::map<String, String>`.
It is commonly used for:
`context.params`
`context.get`
`context.post`
`context.cookies`
`context.session`
`context.header`
Because it uses `std::map`, `map["key"]` will create an empty entry when that key does not already exist.
Related helpers such as `parse_query()` and `encode_query()` convert between query strings and `StringMap` values.
:see
>types
:related
**PHP:** Associative arrays keyed by string, especially request bags like `$_GET` and `$_SERVER`
**JavaScript / Node.js:** Plain objects, dictionaries, `Map`, and header or query objects in web frameworks
:content
Associative container mapping `String` keys to `String` values.
`StringMap` is an alias for `std::map<String, String>`.
## Common Uses
`StringMap` commonly appears in:
- `context.params`
- `context.get`
- `context.post`
- `context.cookies`
- `context.session`
- `context.header`
Because it uses `std::map`, `map["key"]` will create an empty entry when that key does not already exist.
Helpers such as `parse_query()` and `encode_query()` convert between query strings and `StringMap` values.
## Related Concepts
- PHP: associative arrays keyed by string, especially request bags like `$_GET` and `$_SERVER`
- JavaScript / Node.js: plain objects, dictionaries, `Map`, and header or query objects in web frameworks

View File

@ -7,18 +7,19 @@ a : left-hand source map or tree
b : right-hand source map or tree
return value : merged result
:desc
:see
>types
:content
Merges two maps or trees using PHP-like merge behavior.
For `StringMap`, keys from `b` overwrite keys from `a`.
For `DTree`, string keys from `b` overwrite keys from `a`. Numeric keys are appended and reindexed when either side behaves like a list.
This helper is intended as the closest UCE equivalent to PHP `array_merge()` for common request, config, and JSON-shaped data.
This helper is the closest UCE equivalent to PHP `array_merge()` for common request, config, and JSON-shaped data.
:see
>types
## Related Concepts
:related
**PHP:** `array_merge()`
**JavaScript / Node.js:** Object spread, `Object.assign()`, or array concatenation depending on whether the data is map-like or list-like
- PHP: `array_merge()`
- JavaScript / Node.js: object spread, `Object.assign()`, or array concatenation depending on whether the data is map-like or list-like

View File

@ -5,14 +5,15 @@ String ascii_safe_name(String raw)
raw : input string to normalize
return value : ASCII-safe identifier made from letters, digits, and underscores
:desc
Builds a conservative identifier by keeping ASCII letters, digits, and underscores and dropping other characters.
This is useful when turning user- or config-provided names into handler suffixes, DOM-safe variable stems, or CSS/JS hook names.
:see
>string
:related
**PHP:** Slug or safe-filename helpers built with `preg_replace()` and transliteration utilities
**JavaScript / Node.js:** Regex-based slugify or safe-name helpers used for URLs and filenames
:content
Builds a conservative identifier by keeping ASCII letters, digits, and underscores and dropping other characters.
This is useful when turning user- or config-provided names into handler suffixes, DOM-safe variable stems, or CSS and JS hook names.
## Related Concepts
- PHP: slug or safe-filename helpers built with `preg_replace()` and transliteration utilities
- JavaScript / Node.js: regex-based slugify or safe-name helpers used for URLs and filenames

View File

@ -5,12 +5,13 @@ String basename(String fn)
fn : raw filename
return value : the file's name
:desc
Isolates the file name component from a path/file name.
:see
>sys
:related
**PHP:** `basename()`
**JavaScript / Node.js:** Node `path.basename()`
:content
Isolates the file name component from a path or file name.
## Related Concepts
- PHP: `basename()`
- JavaScript / Node.js: Node `path.basename()`

View File

@ -1,34 +1,42 @@
:sig
String component(String name, [DTree props], [Request& context])
:desc
:see
>ob
:content
Renders another `.uce` file as a component and returns the captured output as a `String`.
`component()` resolves the target file relative to the current page and also tries the `components/` prefix automatically, mirroring the shorthand used by the web app starter example project.
`component()` resolves the target file relative to the current page and also tries the `components/` prefix automatically, mirroring the shorthand used by the starter example project.
Component props are passed in `context.call`.
Because `<?= ... ?>` HTML-escapes its value, embed component markup with `<?: component(...) ?>`, `print(component(...))`, or use `component_render(...)` for direct output.
## Named Components
When `name` contains a colon, such as `components/card:BODY`, the part after the colon selects a named component handler exported from the component file through `COMPONENT:BODY(Request& context)`.
The default handler is `COMPONENT(Request& context)`.
When `name` starts with a colon, such as `:BODY`, the target resolves against the current `.uce` file so component files can call their own named handlers without repeating the file name.
Resolution order is:
exact file name
exact file name with `.uce`
the same two forms under `components/`
## Resolution Order
Example:
`DTree props;`
`props["title"] = "Status";`
`&lt;&gt;&lt;?: component("workspace/panel", props, context) ?&gt;&lt;/&gt;`
- exact file name
- exact file name with `.uce`
- the same two forms under `components/`
:see
>ob
## Example
:related
**PHP:** Reusable template partials or helper-rendered view fragments returned as strings
**JavaScript / Node.js:** Component render helpers, especially patterns that return markup as a string
```cpp
DTree props;
props["title"] = "Status";
<><?: component("workspace/panel", props, context) ?></>
```
## Related Concepts
- PHP: reusable template partials or helper-rendered view fragments returned as strings
- JavaScript / Node.js: component render helpers, especially patterns that return markup as a string

View File

@ -1,7 +1,10 @@
:sig
bool component_exists(String name)
:desc
:see
>ob
:content
Checks whether a component file can be resolved from the current page context.
Resolution tries the exact name first and then the `components/` shorthand form.
@ -10,9 +13,7 @@ If `name` contains a colon, only the file portion is used for existence checks.
This is useful when a page wants to render an optional component if it is present without hard-failing when it is missing.
:see
>ob
## Related Concepts
:related
**PHP:** `function_exists()`, `class_exists()`, or file-existence checks before including a partial
**JavaScript / Node.js:** Module existence checks, dynamic import guards, or registry lookups for named components
- PHP: `function_exists()`, `class_exists()`, or file-existence checks before including a partial
- JavaScript / Node.js: module existence checks, dynamic import guards, or registry lookups for named components

View File

@ -1,7 +1,10 @@
:sig
void component_render(String name, [DTree props], [Request& context])
:desc
:see
>ob
:content
Renders another `.uce` file as a component and writes the result directly to the current output buffer.
This is the direct-output counterpart to `component()`.
@ -12,14 +15,16 @@ When `name` starts with `:`, the runtime resolves that named handler against the
Use `component_render()` when you want to write component output directly from C++ code instead of capturing it as a `String`.
Example:
`DTree props;`
`props["body"] = "Hello";`
`component_render("components/card:BODY", props, context);`
## Example
:see
>ob
```cpp
DTree props;
props["body"] = "Hello";
:related
**PHP:** Rendering a partial directly into the current output buffer rather than returning a string
**JavaScript / Node.js:** Direct `res.write()`-style partial rendering or imperative component mount helpers
component_render("components/card:BODY", props, context);
```
## Related Concepts
- PHP: rendering a partial directly into the current output buffer rather than returning a string
- JavaScript / Node.js: direct `res.write()`-style partial rendering or imperative component mount helpers

View File

@ -1,7 +1,10 @@
:sig
String component_resolve(String name)
:desc
:see
>ob
:content
Resolves a component name to the concrete `.uce` file path that will be loaded.
Resolution tries the exact file name first, then the same name with `.uce` appended, and then the same two forms under the `components/` prefix.
@ -10,9 +13,7 @@ If `name` contains a colon, only the file portion is used for resolution.
This is primarily a debugging helper so you can see which concrete file a shorthand component name maps to.
:see
>ob
## Related Concepts
:related
**PHP:** Resolving include paths or view names to a concrete template file before rendering
**JavaScript / Node.js:** Resolving module paths, alias-based imports, or component registry entries
- PHP: resolving include paths or view names to a concrete template file before rendering
- JavaScript / Node.js: resolving module paths, alias-based imports, or component registry entries

View File

@ -4,12 +4,13 @@ String concat(...vals)
:params
...val : one or more values that should be concatenated
:desc
Returns a string with all the parameters concatenated into one.
:see
>string
:related
**PHP:** String concatenation with `.` or helpers like `implode()`
**JavaScript / Node.js:** String concatenation with `+`, template literals, or `Array.prototype.join()`
:content
Returns a string with all parameters concatenated into one result.
## Related Concepts
- PHP: string concatenation with `.` or helpers like `implode()`
- JavaScript / Node.js: string concatenation with `+`, template literals, or `Array.prototype.join()`

View File

@ -6,14 +6,15 @@ haystack : string to search in
needle : substring to look for
return value : `true` when `needle` appears in `haystack`, otherwise `false`
:desc
:see
>string
:content
Returns whether `haystack` contains `needle`.
An empty `needle` always returns `true`.
:see
>string
## Related Concepts
:related
**PHP:** `str_contains()`
**JavaScript / Node.js:** `String.prototype.includes()`
- PHP: `str_contains()`
- JavaScript / Node.js: `String.prototype.includes()`

View File

@ -4,12 +4,13 @@ String cwd_get()
:params
return value : the current working directory
:desc
Returns the current working directory.
:see
>sys
:related
**PHP:** `getcwd()`
**JavaScript / Node.js:** Node `process.cwd()`
:content
Returns the current working directory.
## Related Concepts
- PHP: `getcwd()`
- JavaScript / Node.js: Node `process.cwd()`

View File

@ -4,12 +4,13 @@ void cwd_set(String path)
:params
path : the new working directory
:desc
Sets a new working directory.
:see
>sys
:related
**PHP:** `chdir()`
**JavaScript / Node.js:** Node `process.chdir()`
:content
Sets a new working directory.
## Related Concepts
- PHP: `chdir()`
- JavaScript / Node.js: Node `process.chdir()`

View File

@ -5,12 +5,13 @@ String dirname(String fn)
fn : raw filename
return value : the directory's name
:desc
Isolates the directory name component from a path/file name.
:see
>sys
:related
**PHP:** `dirname()`
**JavaScript / Node.js:** Node `path.dirname()`
:content
Isolates the directory component from a path or file name.
## Related Concepts
- PHP: `dirname()`
- JavaScript / Node.js: Node `path.dirname()`

View File

@ -6,12 +6,15 @@ from : minimum value
to : maximum value
return value : a noise value between 'from' and 'to'
:desc
This function works exactly like generate_float(), but context.random_index is used for the 'index' value and context.random_seed is used for the seed. After this function has been called, the context.random_index is increased by one. At the start of every request, context.random_seed is automatically populated with a new seed value.
:see
>noise
:related
**PHP:** `random_int()`, `mt_rand()`, and custom numeric random helpers
**JavaScript / Node.js:** `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges
:content
Works like `generate_float()`, but uses `context.random_index` for the index value and `context.random_seed` for the seed.
After each call, `context.random_index` is increased by one. At the start of every request, `context.random_seed` is automatically populated with a new seed value.
## Related Concepts
- PHP: `random_int()`, `mt_rand()`, and custom numeric random helpers
- JavaScript / Node.js: `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges

View File

@ -6,12 +6,15 @@ from : minimum value
to : maximum value
return value : a noise value between 'from' and 'to'
:desc
This function works exactly like generate_int(), but context.random_index is used for the 'index' value and context.random_seed is used for the seed. After this function has been called, the context.random_index is increased by one. At the start of every request, context.random_seed is automatically populated with a new seed value.
:see
>noise
:related
**PHP:** `random_int()`, `mt_rand()`, and custom numeric random helpers
**JavaScript / Node.js:** `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges
:content
Works like `generate_int()`, but uses `context.random_index` for the index value and `context.random_seed` for the seed.
After each call, `context.random_index` is increased by one. At the start of every request, `context.random_seed` is automatically populated with a new seed value.
## Related Concepts
- PHP: `random_int()`, `mt_rand()`, and custom numeric random helpers
- JavaScript / Node.js: `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges

View File

@ -5,12 +5,13 @@ String encode_query(StringMap map)
q : StringMap containing URL parameters to be encoded
return value : a string with the encoded parameters
:desc
Encodes a StringMap containing URL parameters into a single String.
:see
>uri
:related
**PHP:** `http_build_query()`
**JavaScript / Node.js:** `URLSearchParams` and `toString()`
:content
Encodes a `StringMap` of URL parameters into a single query-string `String`.
## Related Concepts
- PHP: `http_build_query()`
- JavaScript / Node.js: `URLSearchParams` and `toString()`

View File

@ -6,12 +6,13 @@ path : a relative path
relative_to_path : optional, expand relative to this path (if not given, the current path is used)
return value : expanded version of the 'path'
:desc
Converts a relative path name into an absolute path, using the current working directory as a base.
:see
>sys
:related
**PHP:** `realpath()` and application-specific path normalization helpers
**JavaScript / Node.js:** Node `path.resolve()` and `path.normalize()`
:content
Converts a relative path name into an absolute path, using the current working directory as a base when `relative_to_path` is not provided.
## Related Concepts
- PHP: `realpath()` and application-specific path normalization helpers
- JavaScript / Node.js: Node `path.resolve()` and `path.normalize()`

View File

@ -5,12 +5,13 @@ void file_append(String file_name, ...val)
file_name : file name of file that should be written to
...val : one or more values that should be written into the file
:desc
Opens or creates a given file and appends data to it.
:see
>sys
:related
**PHP:** `file_put_contents($file, $data, FILE_APPEND)`
**JavaScript / Node.js:** Node `fs.appendFileSync()` or `fs.promises.appendFile()`
:content
Opens or creates a file and appends data to it.
## Related Concepts
- PHP: `file_put_contents($file, $data, FILE_APPEND)`
- JavaScript / Node.js: Node `fs.appendFileSync()` or `fs.promises.appendFile()`

View File

@ -5,12 +5,13 @@ bool file_exists(String path)
path : the path name to be checked
return value : true if the file exists
:desc
Checks whether the file or path specified by 'path' exists.
:see
>sys
:related
**PHP:** `file_exists()` or `is_file()`
**JavaScript / Node.js:** Node `fs.existsSync()` or `fs.stat()`
:content
Checks whether the file or path specified by `path` exists.
## Related Concepts
- PHP: `file_exists()` or `is_file()`
- JavaScript / Node.js: Node `fs.existsSync()` or `fs.stat()`

View File

@ -5,12 +5,15 @@ String file_get_contents(String file_name)
file_name : file name of file that should be read
return value : String containing the file's contents
:desc
Reads the file identified by 'file_name' and returns it as a String. If the file cannot be read, this function will return an empty string.
:see
>sys
:related
**PHP:** `file_get_contents()`
**JavaScript / Node.js:** Node `fs.readFileSync()` or `fs.promises.readFile()`
:content
Reads the file identified by `file_name` and returns it as a `String`.
If the file cannot be read, this function returns an empty string.
## Related Concepts
- PHP: `file_get_contents()`
- JavaScript / Node.js: Node `fs.readFileSync()` or `fs.promises.readFile()`

View File

@ -5,13 +5,14 @@ time_t file_mtime(String file_name)
file_name : name of the file
return value : Unix time stamp of the file's last modification
:desc
Retrieves the last modification date of 'file_name' as a Unix timestamp.
:see
>sys
>time
:related
**PHP:** `filemtime()`
**JavaScript / Node.js:** Node `fs.statSync().mtimeMs` or `fs.promises.stat()`
:content
Retrieves the last modification date of `file_name` as a Unix timestamp.
## Related Concepts
- PHP: `filemtime()`
- JavaScript / Node.js: Node `fs.statSync().mtimeMs` or `fs.promises.stat()`

View File

@ -6,12 +6,13 @@ file_name : file name of file that should be written
content : content that should be written
return value : true if write was successful
:desc
Writes the String 'content' into a file identified by 'file_name'. Any pre-existing content of the file will be overwritten.
:see
>sys
:related
**PHP:** `file_put_contents()`
**JavaScript / Node.js:** Node `fs.writeFileSync()` or `fs.promises.writeFile()`
:content
Writes `content` into the file identified by `file_name`, overwriting any pre-existing content.
## Related Concepts
- PHP: `file_put_contents()`
- JavaScript / Node.js: Node `fs.writeFileSync()` or `fs.promises.writeFile()`

View File

@ -4,12 +4,13 @@ void file_unlink(String file_name)
:params
file_name : name of the file
:desc
Deletes the file identified by `file_name`.
:see
>sys
:related
**PHP:** `unlink()`
**JavaScript / Node.js:** Node `fs.unlinkSync()` or `fs.promises.unlink()`
:content
Deletes the file identified by `file_name`.
## Related Concepts
- PHP: `unlink()`
- JavaScript / Node.js: Node `fs.unlinkSync()` or `fs.promises.unlink()`

View File

@ -7,12 +7,13 @@ items : list of items to be filtered
f : a function that decides which items should be in the new list
return value : a new list
:desc
Returns a list containing the members of 'items' for which 'f' returned boolean true.
:see
>string
:related
**PHP:** `array_filter()` for arrays or custom predicate-based filtering over strings and collections
**JavaScript / Node.js:** `Array.prototype.filter()` and custom predicate helpers
:content
Returns a new list containing the members of `items` for which `f` returned `true`.
## Related Concepts
- PHP: `array_filter()` for arrays or custom predicate-based filtering over strings and collections
- JavaScript / Node.js: `Array.prototype.filter()` and custom predicate helpers

View File

@ -5,12 +5,15 @@ String first(String... args)
args : a variable number of String arguments
return value : first of the 'args' that was not empty.
:desc
Given a variable number of String parameters, the first() function returns the first of these parameters that was not empty. Leading and trailing whitespace characters are not considered, resulting in a string that contains only whitespace characters being considered empty.
:see
>string
:related
**PHP:** Null-coalescing patterns like `$a ?? $b`, fallback helpers, or `reset()` for arrays
**JavaScript / Node.js:** `??`, `||`, and small fallback helper functions
:content
Returns the first non-empty string from the provided arguments.
Leading and trailing whitespace are ignored when checking emptiness, so a string containing only whitespace counts as empty.
## Related Concepts
- PHP: null-coalescing patterns like `$a ?? $b`, fallback helpers, or `reset()` for arrays
- JavaScript / Node.js: `??`, `||`, and small fallback helper functions

View File

@ -5,10 +5,12 @@ f64 float_val(String s)
s : string to be converted
return value : a f64 containing the number (0 if no number could be identified).
:desc
Extracts a floating point number from a String.
:content
Extracts a floating point number from a `String`.
If no usable number can be identified, the result is `0`.
:related
**PHP:** `floatval()`
**JavaScript / Node.js:** `Number()` or `parseFloat()`
## Related Concepts
- PHP: `floatval()`
- JavaScript / Node.js: `Number()` or `parseFloat()`

View File

@ -8,13 +8,13 @@ index : index position to generate number from
seed : seed position to generate number from (defaults to 0)
return value : noise value
:desc
Generates a noise value between 'from' and 'to', given the 'index' and 'seed' numbers.
:see
>noise
:related
**PHP:** `random_int()`, `mt_rand()`, and custom numeric random helpers
**JavaScript / Node.js:** `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges
:content
Generates a deterministic noise value between `from` and `to` for the given `index` and `seed`.
## Related Concepts
- PHP: `random_int()`, `mt_rand()`, and custom numeric random helpers
- JavaScript / Node.js: `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges

View File

@ -8,13 +8,13 @@ index : index position to generate number from
seed : seed position to generate number from (defaults to 0)
return value : noise value
:desc
Generates a noise value between 'from' and 'to', given the 'index' and 'seed' numbers.
:see
>noise
:related
**PHP:** `random_int()`, `mt_rand()`, and custom numeric random helpers
**JavaScript / Node.js:** `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges
:content
Generates a deterministic noise value between `from` and `to` for the given `index` and `seed`.
## Related Concepts
- PHP: `random_int()`, `mt_rand()`, and custom numeric random helpers
- JavaScript / Node.js: `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges

View File

@ -6,12 +6,13 @@ index : index position
seed : seed set (defaults to 0)
return value : a noise value from 0 to 1
:desc
Generates a noise value in the range from 0 to 1 for the given 'index' and 'seed' values.
:see
>noise
:related
**PHP:** There is no built-in PHP equivalent; this is closest to userland noise or deterministic pseudo-random helpers
**JavaScript / Node.js:** There is no built-in browser equivalent; closest matches are userland noise libraries or deterministic PRNG helpers
:content
Generates a deterministic noise value in the range from `0` to `1` for the given `index` and `seed`.
## Related Concepts
- PHP: no built-in equivalent; closest matches are userland noise or deterministic pseudo-random helpers
- JavaScript / Node.js: no built-in browser equivalent; closest matches are userland noise libraries or deterministic PRNG helpers

View File

@ -6,12 +6,13 @@ index : index position
seed : seed set (defaults to 0)
return value : a noise value given the 'index' and 'seed' values.
:desc
Generates a noise value for the given 'index' and 'seed' values.
:see
>noise
:related
**PHP:** There is no built-in PHP equivalent; this is closest to userland noise or deterministic pseudo-random helpers
**JavaScript / Node.js:** There is no built-in browser equivalent; closest matches are userland noise libraries or deterministic PRNG helpers
:content
Generates a deterministic 32-bit noise value for the given `index` and `seed`.
## Related Concepts
- PHP: no built-in equivalent; closest matches are userland noise or deterministic pseudo-random helpers
- JavaScript / Node.js: no built-in browser equivalent; closest matches are userland noise libraries or deterministic PRNG helpers

View File

@ -6,12 +6,13 @@ index : index position
seed : seed set (defaults to 0)
return value : a noise value given the 'index' and 'seed' values.
:desc
Generates a noise value for the given 'index' and 'seed' values.
:see
>noise
:related
**PHP:** There is no built-in PHP equivalent; this is closest to userland noise or deterministic pseudo-random helpers
**JavaScript / Node.js:** There is no built-in browser equivalent; closest matches are userland noise libraries or deterministic PRNG helpers
:content
Generates a deterministic 64-bit-indexed noise value for the given `index` and `seed`.
## Related Concepts
- PHP: no built-in equivalent; closest matches are userland noise or deterministic pseudo-random helpers
- JavaScript / Node.js: no built-in browser equivalent; closest matches are userland noise libraries or deterministic PRNG helpers

View File

@ -6,12 +6,15 @@ s : data to be hashed
as_binary : when set to false, returns hash in hexadecimal notation (defaults to false)
return value : the resulting hash value
:desc
Returns the sha1 hash of 's'.
:see
>noise
:related
**PHP:** `sha1()`
**JavaScript / Node.js:** Node `crypto.createHash("sha1")` or browser `SubtleCrypto` wrappers
:content
Returns the SHA-1 hash of `s`.
When `as_binary` is `false`, the hash is returned as hexadecimal text. When it is `true`, the raw binary hash bytes are returned.
## Related Concepts
- PHP: `sha1()`
- JavaScript / Node.js: Node `crypto.createHash("sha1")` or browser `SubtleCrypto` wrappers

View File

@ -6,19 +6,23 @@ path : slash-delimited path to traverse
delim : optional path separator
return value : the resolved child node, or an empty `DTree` when the path cannot be followed
:desc
Traverses a nested `DTree` without creating missing keys.
Empty path segments are ignored, so leading and trailing `/` characters are harmless. If any intermediate node is not a map or a segment is missing, `get_by_path()` returns an empty `DTree`.
Typical usage:
`context.cfg.get_by_path("theme/options/portal-dark/label").to_string()`
:see
DTree
0_context
>types
:related
**PHP:** Deep array access helpers for associative arrays, decoded JSON, or configuration trees
**JavaScript / Node.js:** Optional chaining like `obj?.a?.b`, lodash `get`, or small path-walking helpers
:content
Traverses a nested `DTree` without creating missing keys.
Empty path segments are ignored, so leading and trailing `/` characters are harmless. If any intermediate node is not a map or a segment is missing, `get_by_path()` returns an empty `DTree`.
## Example
```cpp
context.cfg.get_by_path("theme/options/portal-dark/label").to_string()
```
## Related Concepts
- PHP: deep array access helpers for associative arrays, decoded JSON, or configuration trees
- JavaScript / Node.js: optional chaining like `obj?.a?.b`, lodash `get`, or small path-walking helpers

View File

@ -5,13 +5,15 @@ String html_escape(String s)
s : string to be escaped
return value : an HTML-safe escaped version of 's'
:desc
Returns a version of the input string where the following characters have been replace by HTML entities:
- & → &amp
- < → lt;
- > → &gt;
- " → &quot;
:content
Returns a version of the input string where special HTML characters are replaced by entities:
:related
**PHP:** `htmlspecialchars()` or `htmlentities()`
**JavaScript / Node.js:** Safe text insertion via `textContent` or server-side HTML escaping libraries
- `&` becomes `&amp;`
- `<` becomes `&lt;`
- `>` becomes `&gt;`
- `"` becomes `&quot;`
## Related Concepts
- PHP: `htmlspecialchars()` or `htmlentities()`
- JavaScript / Node.js: safe text insertion via `textContent` or server-side HTML escaping libraries

View File

@ -6,10 +6,12 @@ s : string to be converted
base : number system base (default 10)
return value : a u64 containing the number (0 if no number could be identified).
:desc
Extracts an integer from a String.
:content
Extracts an integer value from `s`.
The `base` argument controls which number system is used while parsing. If no usable number can be identified, the function returns `0`.
:related
**PHP:** `intval()`
**JavaScript / Node.js:** `Number()` or `parseInt()`
Related:
- PHP: `intval()`
- JavaScript / Node.js: `Number()` or `parseInt()`

View File

@ -6,12 +6,15 @@ l : list of strings to be joined
delim : delimiter (defaults to newline character)
return value : a string containing items joined by 'delim'
:desc
Joins the items contained in 'l' into a single String.
:see
>string
:related
**PHP:** `implode()`
**JavaScript / Node.js:** `Array.prototype.join()`
:content
Joins all strings in `l` into a single `String`.
The delimiter is inserted between items. If `delim` is omitted, the default separator is a newline character.
Related:
- PHP: `implode()`
- JavaScript / Node.js: `Array.prototype.join()`

View File

@ -5,20 +5,6 @@ DTree json_decode(String s)
s : string containing JSON data
return value : a DTree object containing the deserialized JSON data
:desc
Deserializes 's' into a DTree structure.
The returned structure is usually consumed through `DTree` accessors such as:
- `tree["key"].to_string()`
- `tree["count"].to_u64()`
- `tree["enabled"].to_bool()`
Current runtime note:
- JSON objects and arrays become map-shaped `DTree` values
- JSON booleans become native `bool` `DTree` values
- JSON strings become native `String` `DTree` values
- JSON numbers currently deserialize as string-valued `DTree` nodes, so typed conversions like `to_f64()` and `to_u64()` are the normal way to read numeric content
:see
DTree
json_encode
@ -26,6 +12,23 @@ to_bool
to_f64
to_u64
:related
**PHP:** `json_decode()`
**JavaScript / Node.js:** `JSON.parse()`
:content
Deserializes `s` into a `DTree` structure.
The returned structure is usually consumed through `DTree` accessors such as:
- `tree["key"].to_string()`
- `tree["count"].to_u64()`
- `tree["enabled"].to_bool()`
Current runtime behavior:
- JSON objects and arrays become map-shaped `DTree` values.
- JSON booleans become native `bool` `DTree` values.
- JSON strings become native `String` `DTree` values.
- JSON numbers currently deserialize as string-valued `DTree` nodes, so typed conversions such as `to_f64()` and `to_u64()` are the normal way to read numeric content.
Related:
- PHP: `json_decode()`
- JavaScript / Node.js: `JSON.parse()`

View File

@ -7,13 +7,14 @@ s : string to encode as a JSON string literal
t : DTree object to be serialized
return value : string containing the JSON result
:desc
:content
Serializes either a `String` or a `DTree` into JSON notation.
When passed a `String`, `json_encode()` returns a quoted and escaped JSON string literal.
When passed a `DTree`, scalar values are serialized directly and nested map values are emitted as JSON objects.
:related
**PHP:** `json_encode()`
**JavaScript / Node.js:** `JSON.stringify()`
Related:
- PHP: `json_encode()`
- JavaScript / Node.js: `JSON.stringify()`

View File

@ -4,12 +4,19 @@
:params
file name : name of an UCE file that should be included
:desc
Includes another UCE file
:see
>ob
:related
**PHP:** `include`, `require`, and config-loader patterns that resolve and import another file
**JavaScript / Node.js:** `import()`, `require()`, or file-loader helpers that resolve modules at runtime
:content
Includes another UCE file.
Use `#load` when you want the current file to pull in declarations or reusable content from another UCE source file.
```uce
#load "myfile.uce"
```
Related:
- PHP: `include`, `require`, and config-loader patterns that resolve and import another file
- JavaScript / Node.js: `import()`, `require()`, or file-loader helpers that resolve modules at runtime

View File

@ -5,12 +5,15 @@ StringList ls(String path)
path : a filesystem path
return value : list of directory entries
:desc
Returns a list of files and subdirectories within the given 'path'.
:see
>sys
:related
**PHP:** `scandir()`, `glob()`, or `DirectoryIterator`
**JavaScript / Node.js:** Node `fs.readdirSync()` or `fs.promises.readdir()`
:content
Returns a list of files and subdirectories within `path`.
This is a simple directory listing helper for filesystem-oriented tasks.
Related:
- PHP: `scandir()`, `glob()`, or `DirectoryIterator`
- JavaScript / Node.js: Node `fs.readdirSync()` or `fs.promises.readdir()`

View File

@ -7,11 +7,19 @@ src : markdown source text
options : optional markdown options tree
return value : a `DTree` document AST
:desc
:see
markdown_to_html
component
component_render
json_encode
DTree
:content
Parses Markdown source into a structured `DTree` document tree.
The parser targets a practical GitHub-flavored subset by default:
- ATX headings (`#`)
- ATX headings with `#`
- setext headings
- paragraphs
- blockquotes
@ -20,62 +28,57 @@ The parser targets a practical GitHub-flavored subset by default:
- fenced code blocks
- tables
- horizontal rules
- emphasis / strong / strikethrough
- emphasis, strong, and strikethrough
- links, images, autolinks, and code spans
- `:::` directive blocks for component-based extensions
The returned AST uses `type` plus node-specific fields such as `level`, `text`, `lang`, `href`, `src`, `name`, `argument`, `attrs`, and `children`.
Top-level documents use:
`type = "document"`
`children = [...]`
```text
type = "document"
children = [...]
```
Common block nodes:
`heading`
`paragraph`
`blockquote`
`list`
`list_item`
`code_block`
`table`
`directive`
`hr`
- `heading`
- `paragraph`
- `blockquote`
- `list`
- `list_item`
- `code_block`
- `table`
- `directive`
- `hr`
Common inline nodes:
`text`
`code`
`strong`
`em`
`strike`
`link`
`image`
`raw_html`
:Example
`DTree options = json_decode("{\"components\":{\":::warning\":\"components/markdown/warning\"}}");`
`DTree ast = markdown_to_ast(file_get_contents("README.md"), options);`
`print(json_encode(ast));`
- `text`
- `code`
- `strong`
- `em`
- `strike`
- `link`
- `image`
- `raw_html`
:Options
`options["gfm"]`
Enables GitHub-style extras such as tables, task lists, strikethrough, and bare-URL autolinks.
Defaults to true.
Example:
`options["allow_html"]`
Allows raw HTML passthrough nodes to be captured and rendered.
Defaults to false.
```uce
DTree options = json_decode("{\"components\":{\":::warning\":\"components/markdown/warning\"}}");
DTree ast = markdown_to_ast(file_get_contents("README.md"), options);
print(json_encode(ast));
```
`options["components"]`
Component hook map used later by `markdown_to_html()`.
The parser preserves directive data needed by those hooks.
Options:
:see
markdown_to_html
component
component_render
json_encode
DTree
- `options["gfm"]` enables GitHub-style extras such as tables, task lists, strikethrough, and bare-URL autolinks. Defaults to `true`.
- `options["allow_html"]` allows raw HTML passthrough nodes to be captured and rendered. Defaults to `false`.
- `options["components"]` provides the component hook map later used by `markdown_to_html()`. The parser preserves directive data needed by those hooks.
:related
**PHP:** CommonMark or Parsedown parsing pipelines that expose a syntax tree or token stream
**JavaScript / Node.js:** `remark`, `micromark`, or `markdown-it` token streams and AST-like structures
Related:
- PHP: CommonMark or Parsedown parsing pipelines that expose a syntax tree or token stream
- JavaScript / Node.js: `remark`, `micromark`, or `markdown-it` token streams and AST-like structures

View File

@ -7,7 +7,14 @@ src : markdown source text
options : optional markdown options tree
return value : rendered HTML string
:desc
:see
markdown_to_ast
component
component_render
json_decode
String
:content
Renders Markdown source into HTML and returns the generated markup as a `String`.
`markdown_to_html()` does not write to the output stream directly. This keeps it aligned with the UCE naming convention where `render_*` names are reserved for direct-output helpers.
@ -16,14 +23,18 @@ Because the return value is HTML markup, embed it with `<?: markdown_to_html(...
By default the function aims at a practical GitHub-flavored Markdown target, including tables, task lists, fenced code blocks, autolinks, and strikethrough.
:Example
`DTree options;`
`options["components"][":::warning"] = "components/markdown/warning";`
`options["components"]["node.code_block"] = "components/markdown/code_block";`
`String html = markdown_to_html(file_get_contents("guide.md"), options);`
`print(html);`
Example:
```uce
DTree options;
options["components"][":::warning"] = "components/markdown/warning";
options["components"]["node.code_block"] = "components/markdown/code_block";
String html = markdown_to_html(file_get_contents("guide.md"), options);
print(html);
```
Supported syntax:
:SupportedSyntax
- headings with `#` or setext underlines
- paragraphs
- ordered and unordered lists
@ -32,73 +43,69 @@ By default the function aims at a practical GitHub-flavored Markdown target, inc
- fenced code blocks
- horizontal rules
- tables
- inline emphasis, strong, strikethrough, code spans
- inline emphasis, strong, strikethrough, and code spans
- links, images, and bare `http://` / `https://` URLs
- `:::name ... :::` directive blocks
:Options
`options["gfm"]`
Defaults to true.
Turns on GitHub-style extras such as tables, task lists, autolinks, and strikethrough.
Options:
`options["allow_html"]`
Defaults to false.
When true, raw HTML blocks and inline tags may pass through as `raw_html` nodes instead of being escaped as plain text.
- `options["gfm"]` defaults to `true` and turns on GitHub-style extras such as tables, task lists, autolinks, and strikethrough.
- `options["allow_html"]` defaults to `false`. When true, raw HTML blocks and inline tags may pass through as `raw_html` nodes instead of being escaped as plain text.
- `options["components"]` declares renderer extension points using normal UCE components.
`options["components"]`
Declares renderer extension points using normal UCE components.
Directive hook example:
Exact directive hooks:
`options["components"][":::warning"] = "components/markdown/warning"`
This hook is selected for `:::warning ... :::` blocks.
```uce
options["components"][":::warning"] = "components/markdown/warning";
```
Generic node hooks:
`options["components"]["node.code_block"] = "components/markdown/code_block"`
`options["components"]["node.table"] = "components/markdown/table"`
`options["components"]["node.link"] = "components/markdown/link"`
`options["components"]["node.directive"] = "components/markdown/directive"`
Generic node hook examples:
```uce
options["components"]["node.code_block"] = "components/markdown/code_block";
options["components"]["node.table"] = "components/markdown/table";
options["components"]["node.link"] = "components/markdown/link";
options["components"]["node.directive"] = "components/markdown/directive";
```
If both an exact directive hook and a generic `node.directive` hook exist, the exact directive hook wins.
:ComponentProps
When a markdown hook component is called, its props arrive in `context.call`.
Useful fields include:
`context.call["hook"]` : matched hook key such as `:::warning` or `node.code_block`
`context.call["target"]` : resolved component target name
`context.call["default_html"]` : renderer output without the hook
`context.call["children_html"]` : already-rendered child HTML
`context.call["node"]` : full AST node
`context.call["type"]` : node type
`context.call["name"]` : directive name when applicable
`context.call["argument"]` : directive remainder after the name
`context.call["text"]` : source text for nodes such as `code_block`
`context.call["lang"]` : fenced code language
`context.call["href"]` / `context.call["src"]` / `context.call["title"]`
`context.call["options"]` : full markdown options tree
This lets a component either replace the HTML completely or wrap `default_html` / `children_html`.
- `context.call["hook"]` for the matched hook key such as `:::warning` or `node.code_block`
- `context.call["target"]` for the resolved component target name
- `context.call["default_html"]` for the renderer output without the hook
- `context.call["children_html"]` for already-rendered child HTML
- `context.call["node"]` for the full AST node
- `context.call["type"]` for the node type
- `context.call["name"]` for the directive name when applicable
- `context.call["argument"]` for directive remainder after the name
- `context.call["text"]` for source text used by nodes such as `code_block`
- `context.call["lang"]` for fenced code language
- `context.call["href"]`, `context.call["src"]`, and `context.call["title"]`
- `context.call["options"]` for the full markdown options tree
:DirectiveSchema
Directive blocks use this form:
`:::warning title="Heads up"`
`Body markdown here`
`:::`
```md
:::warning title="Heads up"
Body markdown here
:::
```
The parser stores:
`node["name"] = "warning"`
`node["argument"] = ...` for bare trailing text
`node["attrs"] = ...` for parsed `key=value` pairs such as `title="Heads up"`
This makes directive components a good fit for alerts, callouts, cards, embeds, and any richer page-level markdown extension.
```text
node["name"] = "warning"
node["argument"] = ...
node["attrs"] = ...
```
:see
markdown_to_ast
component
component_render
json_decode
String
That makes directive components a good fit for alerts, callouts, cards, embeds, and richer page-level Markdown extensions.
:related
**PHP:** Parsedown, League CommonMark, or similar Markdown-to-HTML renderers
**JavaScript / Node.js:** `marked`, `markdown-it`, `remark-html`, or other Markdown renderers
Related:
- PHP: Parsedown, League CommonMark, or similar Markdown-to-HTML renderers
- JavaScript / Node.js: `marked`, `markdown-it`, `remark-html`, or other Markdown renderers

View File

@ -6,12 +6,15 @@ connection : connection handle
command : string containing the Memcache command
return value : string containing the Memcache server's response
:desc
Executes a command on an open memcache connection.
:see
>memcache
:related
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()`
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
:content
Executes a raw command on an open Memcache connection and returns the server response as a string.
This is the low-level escape hatch for Memcache operations that are not covered by the dedicated helpers.
Related:
- PHP: `Memcache` or `Memcached` methods such as `get()`, `set()`, `delete()`, and `getMulti()`
- JavaScript / Node.js: clients such as `memjs`, `memcached`, or similar Memcached packages

View File

@ -6,12 +6,15 @@ host : optional host name of the memcache server, defaults to local address 127.
port : optional memcache server's port, defaults to 11211
return value : the connection handle (or -1 if an error occurred)
:desc
Connects to a memcache server instance.
:see
>memcache
:related
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()`
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
:content
Connects to a Memcache server instance.
If the connection fails, the function returns `-1`.
Related:
- PHP: `Memcache` or `Memcached` methods such as `get()`, `set()`, `delete()`, and `getMulti()`
- JavaScript / Node.js: clients such as `memjs`, `memcached`, or similar Memcached packages

View File

@ -6,12 +6,15 @@ connection : connection handle
key : key string
return value : true if the operation was successful
:desc
Deletes entry specified by the 'key'.
:see
>memcache
:related
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()`
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
:content
Deletes the entry identified by `key`.
The return value is `true` when the operation succeeds.
Related:
- PHP: `Memcache` or `Memcached` methods such as `get()`, `set()`, `delete()`, and `getMulti()`
- JavaScript / Node.js: clients such as `memjs`, `memcached`, or similar Memcached packages

View File

@ -7,12 +7,15 @@ key : key string
default_value : optional default value
return value : value that was returned by the Memcache server
:desc
Retrieves a value from an existing connection to a Memcache server.
:see
>memcache
:related
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()`
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
:content
Retrieves a value from an existing Memcache connection.
If the key is missing, `default_value` is returned instead.
Related:
- PHP: `Memcache` or `Memcached` methods such as `get()`, `set()`, `delete()`, and `getMulti()`
- JavaScript / Node.js: clients such as `memjs`, `memcached`, or similar Memcached packages

View File

@ -6,12 +6,15 @@ connection : connection handle
keys : a list of strings containing the keys to be retrieved
return value : a StringMap with the retrieved entries
:desc
Retrieves a bunch of entries all at once.
:see
>memcache
:related
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()`
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
:content
Retrieves multiple entries in one call.
The result is returned as a `StringMap` keyed by the requested Memcache keys.
Related:
- PHP: `Memcache` or `Memcached` methods such as `get()`, `set()`, `delete()`, and `getMulti()`
- JavaScript / Node.js: clients such as `memjs`, `memcached`, or similar Memcached packages

View File

@ -8,12 +8,15 @@ value : the value to be set
expires_in : optional expiration timeout, defaults to one hour
return value : true if the operation was successful
:desc
Stores a 'value' on the Memcache server.
:see
>memcache
:related
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()`
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
:content
Stores `value` under `key` on the Memcache server.
`expires_in` controls the expiration timeout and defaults to one hour.
Related:
- PHP: `Memcache` or `Memcached` methods such as `get()`, `set()`, `delete()`, and `getMulti()`
- JavaScript / Node.js: clients such as `memjs`, `memcached`, or similar Memcached packages

View File

@ -5,12 +5,15 @@ bool mkdir(String path)
path : the path name to be created
return value : returns true if the directory was successfully created
:desc
Creates a directory stated by 'path'
:see
>sys
:related
**PHP:** `mkdir()`
**JavaScript / Node.js:** Node `fs.mkdirSync()` or `fs.promises.mkdir()`
:content
Creates the directory named by `path`.
The function returns `true` when the directory was created successfully.
Related:
- PHP: `mkdir()`
- JavaScript / Node.js: Node `fs.mkdirSync()` or `fs.promises.mkdir()`

View File

@ -7,12 +7,15 @@ username : user name
password : password
return value : pointer to the MySQL connection struct
:desc
Establishes a connection to a MySQL server.
:see
>mysql
:related
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
:content
Establishes a connection to a MySQL server and returns a pointer to the connection struct.
This connection handle is then used with helpers such as `mysql_query()`, `mysql_error()`, and `mysql_disconnect()`.
Related:
- PHP: modern database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
- JavaScript / Node.js: clients such as `mysql2`, query builders, or ORM adapters

View File

@ -4,12 +4,15 @@ void mysql_disconnect(MySQL* m)
:params
m : pointer to an existing MySQL connection struct
:desc
Closes a connection to a MySQL server.
:see
>mysql
:related
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
:content
Closes an existing connection to a MySQL server.
Call this when you are done using a `MySQL*` connection handle.
Related:
- PHP: modern database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
- JavaScript / Node.js: clients such as `mysql2`, query builders, or ORM adapters

View File

@ -5,12 +5,15 @@ String mysql_error(MySQL* m)
m : pointer to a MySQL connection struct
return value : MySQL error message (if present, otherwise empty string)
:desc
Returns the last error message from a connection to a MySQL server.
:see
>mysql
:related
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
:content
Returns the last error message associated with the given MySQL connection.
If there is no current error, the result is an empty string.
Related:
- PHP: modern database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
- JavaScript / Node.js: clients such as `mysql2`, query builders, or ORM adapters

View File

@ -6,12 +6,15 @@ raw : the string to be escaped
quote_char : the character that should be used to wrap the string (pass NULL for no wrapping)
return value : the safe version of the 'raw' string
:desc
Escapes a string such that it can be passed as a safe value into an SQL expression.
:see
>mysql
:related
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
:content
Escapes a string so it can be used safely as a value inside an SQL expression.
If `quote_char` is provided, the escaped result is wrapped with that quote character. Pass `NULL` when you only want escaping without wrapping.
Related:
- PHP: modern database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
- JavaScript / Node.js: clients such as `mysql2`, query builders, or ORM adapters

View File

@ -5,12 +5,15 @@ u64 mysql_insert_id(MySQL* m)
m : pointer to an active MySQL connection
return value : the last used automatic row ID
:desc
This retrieves the last row ID that was used for a column with an AUTO_INCREMENT row key.
:see
>mysql
:related
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
:content
Returns the last automatically assigned row ID used by the current MySQL connection.
This is typically used after an `INSERT` into a table with an `AUTO_INCREMENT` primary key.
Related:
- PHP: modern database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
- JavaScript / Node.js: clients such as `mysql2`, query builders, or ORM adapters

View File

@ -7,15 +7,17 @@ q : a string containing a MySQL query
params : optional, a list of query parameter keys and values
return value : a list of rows returned from executing the query
:desc
Executes a MySQL query and returns the resulting data (if any).
:Examples
(tbd)
:see
>mysql
:related
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
:content
Executes a MySQL query and returns the resulting data, if any.
`params` provides the query parameter values used by the statement.
The result is returned as a `DTree`, which makes it easy to iterate through rows and read fields with the usual `DTree` accessors.
Related:
- PHP: modern database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family
- JavaScript / Node.js: clients such as `mysql2`, query builders, or ORM adapters

View File

@ -6,12 +6,17 @@ haystack : string to be nibbled at
delim : delimiter
return value : string before first occurrence of 'delim'
:desc
Returns the part of 'haystack' before the first occurrence of 'delim', removing the corresponding part from 'haystack' (including 'delim'). If the substring 'delim' does not occurr in 'haystack', the entire string is returned and 'haystack' is set to an empty string.
:see
>string
:related
**PHP:** Small parsing helpers built with `strpos()`, `substr()`, and `explode()`
**JavaScript / Node.js:** Manual parsing with `indexOf()`, `slice()`, and `split()`
:content
Returns the part of `haystack` before the first occurrence of `delim`.
As a side effect, the consumed portion is removed from `haystack`, including the delimiter itself.
If `delim` does not occur in `haystack`, the entire string is returned and `haystack` is set to an empty string.
Related:
- PHP: small parsing helpers built with `strpos()`, `substr()`, and `explode()`
- JavaScript / Node.js: manual parsing with `indexOf()`, `slice()`, and `split()`

View File

@ -4,12 +4,15 @@ void ob_close()
:params
(none)
:desc
Discard the current output buffer. If are more output buffers on the stack, switch to the next one.
:see
>ob
:related
**PHP:** `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs
**JavaScript / Node.js:** String accumulation, buffer capture, or render-to-string patterns in server code
:content
Discards the current output buffer.
If more output buffers remain on the stack, UCE switches to the next one.
Related:
- PHP: `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs
- JavaScript / Node.js: string accumulation, buffer capture, or render-to-string patterns in server code

View File

@ -4,12 +4,15 @@ String ob_get()
:params
return value : content of the current output buffer
:desc
Returns the contents of the current output buffer.
:see
>ob
:related
**PHP:** `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs
**JavaScript / Node.js:** String accumulation, buffer capture, or render-to-string patterns in server code
:content
Returns the contents of the current output buffer.
Unlike `ob_get_close()`, this does not discard the buffer.
Related:
- PHP: `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs
- JavaScript / Node.js: string accumulation, buffer capture, or render-to-string patterns in server code

View File

@ -4,13 +4,15 @@ String ob_get_close()
:params
return value : content of the current output buffer
:desc
Returns the contents of the current output buffer and then discards the buffer.
If are more output buffers on the stack, switch to the next one.
:see
>ob
:related
**PHP:** `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs
**JavaScript / Node.js:** String accumulation, buffer capture, or render-to-string patterns in server code
:content
Returns the contents of the current output buffer and then discards that buffer.
If more output buffers remain on the stack, UCE switches to the next one.
Related:
- PHP: `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs
- JavaScript / Node.js: string accumulation, buffer capture, or render-to-string patterns in server code

View File

@ -4,12 +4,15 @@ void ob_start()
:params
(none)
:desc
Starts a new output buffer. All subsequent output will be directed into this buffer. Every call to ob_start() starts a new buffer and puts that buffer on the output buffer stack. ob_close() and ob_get_close() destroy buffers and remove them from the stack.
:see
>ob
:related
**PHP:** `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs
**JavaScript / Node.js:** String accumulation, buffer capture, or render-to-string patterns in server code
:content
Starts a new output buffer.
All subsequent output is directed into that buffer until it is closed or collected. Every call to `ob_start()` pushes another buffer onto the output buffer stack. `ob_close()` and `ob_get_close()` destroy buffers and remove them from the stack.
Related:
- PHP: `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs
- JavaScript / Node.js: string accumulation, buffer capture, or render-to-string patterns in server code

View File

@ -5,12 +5,15 @@ StringMap parse_query(String q)
q : string containing URL parameters
return value : a StringMap containing the parameters
:desc
Decodes a string of the format 'a=b&c=d' into a StringMap containing keyed entries.
:see
>uri
:related
**PHP:** `parse_str()`
**JavaScript / Node.js:** `URLSearchParams` or Node `querystring.parse()`
:content
Decodes a query-string fragment such as `a=b&c=d` into a `StringMap`.
This is useful when you need to work with URL parameter data outside the normal request parsing flow.
Related:
- PHP: `parse_str()`
- JavaScript / Node.js: `URLSearchParams` or Node `querystring.parse()`

View File

@ -6,14 +6,15 @@ base : parent path
child : child path or absolute override
return value : combined path
:desc
Joins two filesystem-style path fragments with a single `/` when needed.
If `child` is empty, `base` is returned. If `child` already starts with `/`, it is returned unchanged. This makes `path_join()` a better fit for app-level path assembly than open-coded string concatenation.
:see
>sys
:related
**PHP:** Manual path composition with `DIRECTORY_SEPARATOR` or helper wrappers around it
**JavaScript / Node.js:** Node `path.join()`
:content
Joins two filesystem-style path fragments with a single `/` when needed.
If `child` is empty, `base` is returned. If `child` already starts with `/`, it is returned unchanged. That makes `path_join()` a better fit for app-level path assembly than open-coded string concatenation.
Related:
- PHP: manual path composition with `DIRECTORY_SEPARATOR` or helper wrappers around it
- JavaScript / Node.js: Node `path.join()`

View File

@ -4,12 +4,15 @@ void print(...val)
:params
...val : one or more values that should be output
:desc
Appends data to the current request's output stream.
:see
>string
:related
**PHP:** `echo`, `print`, and output buffering patterns
**JavaScript / Node.js:** `res.write()`, stream writes, or string-returning render helpers depending on context
:content
Appends data to the current request output stream.
Use `print()` when you want to emit response content directly from UCE code.
Related:
- PHP: `echo`, `print`, and output buffering patterns
- JavaScript / Node.js: `res.write()`, stream writes, or string-returning render helpers depending on context

View File

@ -5,15 +5,16 @@ void redirect(String url, s32 code = 302)
url : target URL for the redirect
code : optional HTTP redirect status, defaults to `302`
:desc
Sets the `Location` response header and updates the current HTTP status code.
Use this helper instead of manually assigning `context.header["Location"]` and `context.set_status(...)` when you want to redirect the current response.
:see
set_status
0_context
:related
**PHP:** `header("Location: ...")` together with `http_response_code()` or implicit redirect semantics
**JavaScript / Node.js:** `res.redirect(...)`, setting `Location`, or returning a redirect `Response`
:content
Sets the `Location` response header and updates the current HTTP status code.
Use this helper instead of manually assigning `context.header["Location"]` and `context.set_status(...)` when you want to redirect the current response.
Related:
- PHP: `header("Location: ...")` together with `http_response_code()` or implicit redirect semantics
- JavaScript / Node.js: `res.redirect(...)`, setting `Location`, or returning a redirect `Response`

View File

@ -7,12 +7,15 @@ search : the string that should be searched for
replace_with : the string that should appear in places where 'search' occurs
return value : a version of 's' where all instances of 'search' have been replaced with 'replace_with'
:desc
Replace all occurrences of 'search' with the string defined in 'replace_with'.
:see
>string
:related
**PHP:** `str_replace()` or `preg_replace()`
**JavaScript / Node.js:** `String.prototype.replace()` or `replaceAll()`
:content
Replaces every occurrence of `search` in `s` with `replace_with`.
The returned string contains the fully replaced result.
Related:
- PHP: `str_replace()` or `preg_replace()`
- JavaScript / Node.js: `String.prototype.replace()` or `replaceAll()`

View File

@ -4,12 +4,15 @@ void session_destroy(String session_name)
:params
session_name : the name of the session
:desc
Deletes the cookie specified by 'session_name' and clears the data stored under the session ID. This empties the 'context.session_id' and 'context.session' variables.
:see
>session
:related
**PHP:** `session_destroy()`
**JavaScript / Node.js:** Express session store teardown or manual cookie-session invalidation
:content
Deletes the cookie specified by `session_name` and clears the data stored under the current session ID.
This also empties `context.session_id` and `context.session`.
Related:
- PHP: `session_destroy()`
- JavaScript / Node.js: Express session store teardown or manual cookie-session invalidation

View File

@ -4,12 +4,15 @@ String session_id_create()
:params
return value : a new session ID
:desc
Creates a session ID.
:see
>session
:related
**PHP:** `session_create_id()` or custom session token generators
**JavaScript / Node.js:** `crypto.randomUUID()` or custom secure session ID generation
:content
Creates and returns a new session ID.
This helper is useful when you need to generate a session token directly rather than starting a full session flow with `session_start()`.
Related:
- PHP: `session_create_id()` or custom session token generators
- JavaScript / Node.js: `crypto.randomUUID()` or custom secure session ID generation

View File

@ -5,18 +5,21 @@ String session_start(String session_name = "uce-session")
session_name : optional name of the session cookie, defaults to "uce-session"
return value : the current session ID
:desc
Starts session or connects to existing session. This function sets a cookie with the name contained in 'session_name' if it does not exist and fills that cookie with a new unique session ID. It then loads the session data for that session ID. Afterwards, the following fields are populated in the 'context' variable:
context.session_id : the current session ID
context.session_name : the current session cookie name
context.session : the current session data. The session data is automatically saved after a request completes.
:see
>session
:related
**PHP:** `session_start()`
**JavaScript / Node.js:** Express `express-session`, `cookie-session`, or similar request-bound session middleware
:content
Starts a session or reconnects to an existing one.
If the cookie named by `session_name` does not exist, UCE creates it and fills it with a new unique session ID. The function then loads the session data for that ID.
After `session_start()` completes, the following `context` fields are populated:
- `context.session_id` contains the current session ID.
- `context.session_name` contains the current session cookie name.
- `context.session` contains the current session data. The session data is automatically saved after the request completes.
Related:
- PHP: `session_start()`
- JavaScript / Node.js: Express `express-session`, `cookie-session`, or similar request-bound session middleware

View File

@ -5,15 +5,16 @@ void context.set_status(s32 code, String reason = "")
code : HTTP status code
reason : optional reason phrase override
:desc
Sets the current request status line and mirrors the numeric status into `context.flags.status`.
When `reason` is omitted, UCE fills in a standard reason phrase for common HTTP status codes such as `200`, `302`, `400`, `404`, and `500`.
:see
0_context
>types
:related
**PHP:** `http_response_code()` and explicit status-line header control
**JavaScript / Node.js:** `res.status(...)`, `Response` init status, or low-level status assignment on an HTTP response
:content
Sets the current request status line and mirrors the numeric status into `context.flags.status`.
When `reason` is omitted, UCE fills in a standard reason phrase for common HTTP status codes such as `200`, `302`, `400`, `404`, and `500`.
Related:
- PHP: `http_response_code()` and explicit status-line header control
- JavaScript / Node.js: `res.status(...)`, `Response` init status, or low-level status assignment on an HTTP response

View File

@ -5,12 +5,15 @@ String shell_escape(String raw)
raw : string that should be escaped
return value : escaped version of 'raw'
:desc
Escapes a parameter for shell_exec
:see
>sys
:related
**PHP:** `escapeshellarg()` and `escapeshellcmd()`
**JavaScript / Node.js:** There is no direct built-in equivalent; prefer `spawn()` argument arrays and avoid shell interpolation
:content
Escapes a parameter so it can be used more safely with `shell_exec()`.
This is the helper to reach for when building shell command lines from dynamic input.
Related:
- PHP: `escapeshellarg()` and `escapeshellcmd()`
- JavaScript / Node.js: there is no direct built-in equivalent; prefer `spawn()` argument arrays and avoid shell interpolation

View File

@ -5,12 +5,15 @@ String shell_exec(String cmd)
cmd : string that contains the shell command line to be executed
return value : output of the command execution
:desc
Executes a Linux shell command and returns the generated output
:see
>sys
:related
**PHP:** `shell_exec()`, `exec()`, or `proc_open()`
**JavaScript / Node.js:** Node `child_process.exec()` or `spawn()`
:content
Executes a Linux shell command and returns the generated output.
When command text includes user-controlled input, escape that input first with `shell_escape()`.
Related:
- PHP: `shell_exec()`, `exec()`, or `proc_open()`
- JavaScript / Node.js: Node `child_process.exec()` or `spawn()`

View File

@ -4,12 +4,15 @@ void socket_close(u64 sockfd)
:params
sockfd : socket handle
:desc
Closes an existing socket connection.
:see
>socket
:related
**PHP:** PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients
**JavaScript / Node.js:** Node `net.Socket` connect, read, write, and close operations
:content
Closes an existing socket connection.
Use this when you are done with a socket opened through `socket_connect()`.
Related:
- PHP: PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients
- JavaScript / Node.js: Node `net.Socket` connect, read, write, and close operations

View File

@ -6,12 +6,15 @@ host : host name
port : port number
return value : the socket handle
:desc
Opens a socket connection to the given 'host' and 'port'.
:see
>socket
:related
**PHP:** PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients
**JavaScript / Node.js:** Node `net.Socket` connect, read, write, and close operations
:content
Opens a socket connection to the given `host` and `port`.
The returned socket handle is then used with `socket_read()`, `socket_write()`, and `socket_close()`.
Related:
- PHP: PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients
- JavaScript / Node.js: Node `net.Socket` connect, read, write, and close operations

View File

@ -7,12 +7,15 @@ max_length : optional maximum data size, defaults to 128kBytes
timeout : optional operation timeout, defaults to one second
return value : string containing the data that was read
:desc
Reads data from a socket connection.
:see
>socket
:related
**PHP:** PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients
**JavaScript / Node.js:** Node `net.Socket` connect, read, write, and close operations
:content
Reads data from a socket connection.
`max_length` limits how much data is read, and `timeout` controls how long the operation is allowed to wait.
Related:
- PHP: PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients
- JavaScript / Node.js: Node `net.Socket` connect, read, write, and close operations

View File

@ -6,12 +6,15 @@ sockfd : socket handle
data : a string containing the data to be written to the socket
return value : true if the write operation was successful
:desc
Writes a string of 'data' to the given socket.
:see
>socket
:related
**PHP:** PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients
**JavaScript / Node.js:** Node `net.Socket` connect, read, write, and close operations
:content
Writes `data` to the given socket.
The function returns `true` when the write succeeds.
Related:
- PHP: PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients
- JavaScript / Node.js: Node `net.Socket` connect, read, write, and close operations

View File

@ -6,12 +6,15 @@ str : string to be split
delim : delimiter
return value : a list of strings
:desc
Splits 'str' into multiple strings based on the given delimiter 'delim'.
:see
>string
:related
**PHP:** `explode()` or `preg_split()`
**JavaScript / Node.js:** `String.prototype.split()`
:content
Splits `str` into multiple strings using `delim` as the separator.
Every exact occurrence of `delim` creates a new entry in the returned `StringList`.
Related:
- PHP: `explode()` or `preg_split()`
- JavaScript / Node.js: `String.prototype.split()`

View File

@ -5,12 +5,15 @@ StringList split_space(String str)
str : string to be split
return value : a list of strings
:desc
Splits 'str' into multiple strings along any whitespace characters (multiple whitespace characters count as one).
:see
>string
:related
**PHP:** Whitespace splitting via `preg_split(/\s+/, ...)`
**JavaScript / Node.js:** Whitespace splitting via regex with `split(/\\s+/)`
:content
Splits `str` on runs of whitespace.
Multiple adjacent whitespace characters are treated as a single separator, so repeated spaces, tabs, or line breaks do not create empty entries.
Related:
- PHP: whitespace splitting via `preg_split(/\s+/, ...)`
- JavaScript / Node.js: regex-based splitting with `split(/\\s+/)`

View File

@ -7,18 +7,22 @@ str : string to be split
compound_characters : optional, if true tries to combine compound characters
return value : a list of Unicode characters
:desc
Splits the string 'str' into its constituent Unicode code points.
If 'compound_characters' is true, split_utf8 will attempt to combine compound characters based on very simple rules:
<li>combine characters if they're connected by a Zero-Width Joiner (ZWJ) character</li>
<li>combine two characters if they're both a Regional Indicator Symbol Letter</li>
<li>if a character is a Variation Selector, append it to the previous character</li>
<li>in all other cases, characters remain on their own</li>
:see
>string
:related
**PHP:** `preg_split(//u, ...)`, `mb_*` helpers, or grapheme-aware libraries
**JavaScript / Node.js:** `Array.from(str)` or iterator-based Unicode-aware splitting
:content
Splits `str` into its constituent Unicode code points.
If `compound_characters` is `true`, `split_utf8()` also applies a small amount of grouping so some multi-code-point glyphs stay together. The current rules are:
- combine characters joined by a Zero-Width Joiner (ZWJ)
- combine two Regional Indicator Symbol Letter characters
- append Variation Selectors to the previous character
- otherwise leave characters as separate entries
This is useful when simple byte-wise or ASCII splitting would break Unicode text incorrectly.
Related:
- PHP: `preg_split(//u, ...)`, `mb_*` helpers, or grapheme-aware libraries
- JavaScript / Node.js: `Array.from(str)` or iterator-based Unicode-aware splitting

View File

@ -6,12 +6,13 @@ haystack : string to inspect
needle : suffix to compare against the end of `haystack`
return value : `true` when `haystack` ends with `needle`, otherwise `false`
:desc
Checks whether `haystack` ends with the given suffix.
:see
>string
:related
**PHP:** `str_ends_with()`
**JavaScript / Node.js:** `String.prototype.endsWith()`
:content
Checks whether `haystack` ends with `needle`.
Related:
- PHP: `str_ends_with()`
- JavaScript / Node.js: `String.prototype.endsWith()`

View File

@ -6,12 +6,13 @@ haystack : string to inspect
needle : prefix to compare against the start of `haystack`
return value : `true` when `haystack` begins with `needle`, otherwise `false`
:desc
Checks whether `haystack` starts with the given prefix.
:see
>string
:related
**PHP:** `str_starts_with()`
**JavaScript / Node.js:** `String.prototype.startsWith()`
:content
Checks whether `haystack` starts with `needle`.
Related:
- PHP: `str_starts_with()`
- JavaScript / Node.js: `String.prototype.startsWith()`

View File

@ -7,16 +7,17 @@ needle : substring to search for
offset : optional start offset; negative values count from the end of the string
return value : zero-based position of the first match, or `-1` if `needle` is not found
:desc
:see
>string
:content
Finds the first occurrence of `needle` inside `haystack`.
This is the closest UCE equivalent to PHP `strpos()`, but it returns `-1` instead of `false` when no match is found.
If `needle` is an empty string, `strpos()` returns the normalized start offset.
:see
>string
Related:
:related
**PHP:** `strpos()`
**JavaScript / Node.js:** `String.prototype.indexOf()`
- PHP: `strpos()`
- JavaScript / Node.js: `String.prototype.indexOf()`

View File

@ -8,7 +8,10 @@ start_pos : zero-based start position; negative values count from the end of the
length : optional substring length; negative values trim bytes from the end of the result range
return value : extracted substring, or an empty string if the requested range is outside the source string
:desc
:see
>string
:content
Extracts part of a string using PHP-style start and length semantics.
Use the two-argument form to return everything from `start_pos` to the end of the string.
@ -17,9 +20,7 @@ If `start_pos` is negative, counting starts from the end of the string.
If `length` is negative, the returned range stops that many bytes before the end of the string.
:see
>string
Related:
:related
**PHP:** `substr()`
**JavaScript / Node.js:** `String.prototype.slice()` or `substring()`
- PHP: `substr()`
- JavaScript / Node.js: `String.prototype.slice()` or `substring()`

View File

@ -6,12 +6,17 @@ key : string uniquely identifying the task
exec_func : function to execute
return value : the process ID of the started (or still running) task
:desc
task() starts the 'exec_func' in a new process and returns that process' ID. If a process with the same 'key' is already running, task will not start a new process but instead just return the PID of the process that is already running.
:see
>task
:related
**PHP:** Background-process patterns using `proc_open()`, queues, cron, or worker supervisors
**JavaScript / Node.js:** Node `child_process`, worker queues, timers, schedulers, and supervised background jobs
:content
Starts `exec_func` in a new process and returns that process ID.
If a process with the same `key` is already running, `task()` does not start a second copy. Instead it returns the PID of the already-running task.
Use the `key` to make a background job idempotent across repeated calls.
Related:
- PHP: background-process patterns using `proc_open()`, queues, cron, or worker supervisors
- JavaScript / Node.js: Node `child_process`, worker queues, timers, schedulers, and supervised background jobs

View File

@ -6,14 +6,17 @@ pid : PID of the process
sig : signal number
return value : 0 if signal was sent, -1 otherwise
:desc
Wraps the standard POSIX `kill()` function.
Possible signal numbers are: SIGABND, SIGABRT, SIGALRM, SIGBUS, SIGFPE, SIGHUP, SIGILL, SIGINT, SIGKILL, SIGPIPE, SIGPOLL, SIGPROF, SIGQUIT, SIGSEGV, SIGSYS, SIGTERM, SIGTRAP, SIGURG, SIGUSR1, SIGUSR2, SIGVTALRM, SIGXCPU, SIGXFSZ, SIGCHLD, SIGIO, SIGIOERR, SIGWINCH, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGCONT.
:see
>task
:related
**PHP:** Background-process patterns using `proc_open()`, queues, cron, or worker supervisors
**JavaScript / Node.js:** Node `child_process`, worker queues, timers, schedulers, and supervised background jobs
:content
Wraps the standard POSIX `kill()` function.
`sig` may be any supported POSIX signal, including values such as `SIGTERM`, `SIGKILL`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `SIGCHLD`, `SIGCONT`, and related process-control signals.
Passing `0` as the signal performs an existence and permission check without actually delivering a signal.
Related:
- PHP: background-process patterns using `proc_open()`, queues, cron, or worker supervisors
- JavaScript / Node.js: Node `child_process`, worker queues, timers, schedulers, and supervised background jobs

View File

@ -5,12 +5,15 @@ pid_t task_pid(String key)
key : string uniquely identifying the task
return value : the process ID of the task
:desc
Checks whether a process with the given 'key' is running and returns its PID if it is. Returns 0 otherwise.
:see
>task
:related
**PHP:** Background-process patterns using `proc_open()`, queues, cron, or worker supervisors
**JavaScript / Node.js:** Node `child_process`, worker queues, timers, schedulers, and supervised background jobs
:content
Checks whether a process with the given `key` is running and returns its PID if it is.
Returns `0` when no matching task is active.
Related:
- PHP: background-process patterns using `proc_open()`, queues, cron, or worker supervisors
- JavaScript / Node.js: Node `child_process`, worker queues, timers, schedulers, and supervised background jobs

View File

@ -8,14 +8,17 @@ exec_func : function to execute repeatedly
timeout : optional task timeout value
return value : the process ID of the started (or still running) task
:desc
Starts a repeating background worker process. The function `exec_func` is executed in a loop and the worker sleeps for `interval` seconds between executions.
If a process with the same `key` is already running, `task_repeat()` does not start a second worker and instead returns the PID of the existing one.
:see
>task
:related
**PHP:** Background-process patterns using `proc_open()`, queues, cron, or worker supervisors
**JavaScript / Node.js:** Node `child_process`, worker queues, timers, schedulers, and supervised background jobs
:content
Starts a repeating background worker process.
`exec_func` runs in a loop, and the worker sleeps for `interval` seconds between executions.
If a process with the same `key` is already running, `task_repeat()` does not start a second worker and instead returns the PID of the existing one.
Related:
- PHP: background-process patterns using `proc_open()`, queues, cron, or worker supervisors
- JavaScript / Node.js: Node `child_process`, worker queues, timers, schedulers, and supervised background jobs

View File

@ -4,12 +4,13 @@ u64 time()
:params
return value : second-accurate current Unix timestamp
:desc
Returns a 64 bit integer containing the current Unix timestamp.
:see
>time
:related
**PHP:** `time()`
**JavaScript / Node.js:** `Math.floor(Date.now() / 1000)` or `Date.now()` depending on units
:content
Returns the current Unix timestamp as a 64-bit integer with second precision.
Related:
- PHP: `time()`
- JavaScript / Node.js: `Math.floor(Date.now() / 1000)` or `Date.now()` depending on units

View File

@ -6,137 +6,84 @@ format : formatting string specifying the date format
timestamp : optional timestamp value, defaults to current time
return value : a formatted date
:desc
Returns a formatted date. This is based on the Linux date() command. The formatting string supports the following sequences:
:pre
%% a literal %
%a locale's abbreviated weekday name (e.g., Sun)
%A locale's full weekday name (e.g., Sunday)
%b locale's abbreviated month name (e.g., Jan)
%B locale's full month name (e.g., January)
%c locale's date and time (e.g., Thu Mar 3 23:05:25 2005)
%C century; like %Y, except omit last two digits (e.g., 20)
%d day of month (e.g., 01)
%D date; same as %m/%d/%y
%e day of month, space padded; same as %_d
%F full date; like %+4Y-%m-%d
%g last two digits of year of ISO week number (see %G)
%G year of ISO week number (see %V); normally useful only
with %V
%h same as %b
%H hour (00..23)
%I hour (01..12)
%j day of year (001..366)
%k hour, space padded ( 0..23); same as %_H
%l hour, space padded ( 1..12); same as %_I
%m month (01..12)
%M minute (00..59)
%n a newline
%N nanoseconds (000000000..999999999)
%p locale's equivalent of either AM or PM; blank if not known
%P like %p, but lower case
%q quarter of year (1..4)
%r locale's 12-hour clock time (e.g., 11:11:04 PM)
%R 24-hour hour and minute; same as %H:%M
%s seconds since 1970-01-01 00:00:00 UTC
%S second (00..60)
%t a tab
%T time; same as %H:%M:%S
%u day of week (1..7); 1 is Monday
%U week number of year, with Sunday as first day of week
(00..53)
%V ISO week number, with Monday as first day of week (01..53)
%w day of week (0..6); 0 is Sunday
%W week number of year, with Monday as first day of week
(00..53)
%x locale's date representation (e.g., 12/31/99)
%X locale's time representation (e.g., 23:13:48)
%y last two digits of year (00..99)
%Y year
%z +hhmm numeric time zone (e.g., -0400)
%:z +hh:mm numeric time zone (e.g., -04:00)
%::z +hh:mm:ss numeric time zone (e.g., -04:00:00)
%:::z numeric time zone with : to necessary precision (e.g.,
-04, +05:30)
%Z alphabetic time zone abbreviation (e.g., EDT)
%deltaS total elapsed seconds between the timestamp and now
%deltaM total elapsed minutes between the timestamp and now
%deltaH total elapsed hours between the timestamp and now
%deltad total elapsed days between the timestamp and now
%deltam total elapsed 30-day months between the timestamp and now
%deltaY total elapsed 365-day years between the timestamp and now
By default, date pads numeric fields with zeroes. The following
optional flags may follow '%':
- (hyphen) do not pad the field
_ (underscore) pad with spaces
0 (zero) pad with zeros
+ pad with zeros, and put '+' before future years with >4
digits
^ use upper case if possible
# use opposite case if possible
:see
>time
>time_format_relative
:related
**PHP:** `date()` and `DateTime` formatting in the server local timezone
**JavaScript / Node.js:** `Intl.DateTimeFormat`, `Date#toLocaleString()`, or date libraries
:content
Formats a timestamp in the server's local timezone.
This formatter is based on the Linux `date` command and supports the same core formatting tokens plus UCE's relative-time delta tokens.
Supported format sequences:
```text
%% a literal %
%a locale's abbreviated weekday name (e.g., Sun)
%A locale's full weekday name (e.g., Sunday)
%b locale's abbreviated month name (e.g., Jan)
%B locale's full month name (e.g., January)
%c locale's date and time (e.g., Thu Mar 3 23:05:25 2005)
%C century; like %Y, except omit last two digits (e.g., 20)
%d day of month (e.g., 01)
%D date; same as %m/%d/%y
%e day of month, space padded; same as %_d
%F full date; like %+4Y-%m-%d
%g last two digits of year of ISO week number (see %G)
%G year of ISO week number (see %V); normally useful only with %V
%h same as %b
%H hour (00..23)
%I hour (01..12)
%j day of year (001..366)
%k hour, space padded ( 0..23); same as %_H
%l hour, space padded ( 1..12); same as %_I
%m month (01..12)
%M minute (00..59)
%n a newline
%N nanoseconds (000000000..999999999)
%p locale's equivalent of either AM or PM; blank if not known
%P like %p, but lower case
%q quarter of year (1..4)
%r locale's 12-hour clock time (e.g., 11:11:04 PM)
%R 24-hour hour and minute; same as %H:%M
%s seconds since 1970-01-01 00:00:00 UTC
%S second (00..60)
%t a tab
%T time; same as %H:%M:%S
%u day of week (1..7); 1 is Monday
%U week number of year, with Sunday as first day of week (00..53)
%V ISO week number, with Monday as first day of week (01..53)
%w day of week (0..6); 0 is Sunday
%W week number of year, with Monday as first day of week (00..53)
%x locale's date representation (e.g., 12/31/99)
%X locale's time representation (e.g., 23:13:48)
%y last two digits of year (00..99)
%Y year
%z +hhmm numeric time zone (e.g., -0400)
%:z +hh:mm numeric time zone (e.g., -04:00)
%::z +hh:mm:ss numeric time zone (e.g., -04:00:00)
%:::z numeric time zone with : to necessary precision (e.g., -04, +05:30)
%Z alphabetic time zone abbreviation (e.g., EDT)
%deltaS total elapsed seconds between the timestamp and now
%deltaM total elapsed minutes between the timestamp and now
%deltaH total elapsed hours between the timestamp and now
%deltad total elapsed days between the timestamp and now
%deltam total elapsed 30-day months between the timestamp and now
%deltaY total elapsed 365-day years between the timestamp and now
```
Padding and case flags may follow `%`:
```text
- do not pad the field
_ pad with spaces
0 pad with zeros
+ pad with zeros, and put '+' before future years with >4 digits
^ use upper case if possible
# use opposite case if possible
```
Related:
- PHP: `date()` and `DateTime` formatting in the server local timezone
- JavaScript / Node.js: `Intl.DateTimeFormat`, `Date#toLocaleString()`, or date libraries

View File

@ -10,46 +10,45 @@ not_recent_seconds : cutoff between the medium-recent and not-recent formats, de
format_not_recent : output format for older timestamps, defaults to `%deltaH hours ago`
return value : a formatted relative-time string
:desc
Formats a timestamp relative to the current time using the same formatting engine as `time_format_local()` and `time_format_utc()`.
The chosen format depends on the elapsed time:
- if `now - timestamp` is less than `medium_recency_seconds`, use `format_very_recent`
- else if it is less than `not_recent_seconds`, use `format_medium_recent`
- otherwise use `format_not_recent`
The custom relative-time sequences available in all time formatters are:
:pre
%deltaS total elapsed seconds between the timestamp and now
%deltaM total elapsed minutes between the timestamp and now
%deltaH total elapsed hours between the timestamp and now
%deltad total elapsed days between the timestamp and now
%deltam total elapsed 30-day months between the timestamp and now
%deltaY total elapsed 365-day years between the timestamp and now
:pre
Default behavior examples:
time_format_relative(time() - 12)
=> just now
time_format_relative(time() - 600)
=> 10 minutes ago
time_format_relative(time() - 7200)
=> 2 hours ago
:see
>time
>time_format_local
>time_format_utc
:related
**PHP:** `DateTimeImmutable` diff formatting or libraries such as Carbon `diffForHumans()`
**JavaScript / Node.js:** relative time helpers such as `Intl.RelativeTimeFormat`, `date-fns/formatDistanceToNow`, or Luxon
:content
Formats a timestamp relative to the current time using the same formatting engine as `time_format_local()` and `time_format_utc()`.
The formatter chooses one of three output formats:
- if `now - timestamp` is less than `medium_recency_seconds`, use `format_very_recent`
- else if it is less than `not_recent_seconds`, use `format_medium_recent`
- otherwise use `format_not_recent`
The relative-time tokens available in all time formatters are:
```text
%deltaS total elapsed seconds between the timestamp and now
%deltaM total elapsed minutes between the timestamp and now
%deltaH total elapsed hours between the timestamp and now
%deltad total elapsed days between the timestamp and now
%deltam total elapsed 30-day months between the timestamp and now
%deltaY total elapsed 365-day years between the timestamp and now
```
Default behavior examples:
```text
time_format_relative(time() - 12)
=> just now
time_format_relative(time() - 600)
=> 10 minutes ago
time_format_relative(time() - 7200)
=> 2 hours ago
```
Related:
- PHP: `DateTimeImmutable` diff formatting or libraries such as Carbon `diffForHumans()`
- JavaScript / Node.js: relative time helpers such as `Intl.RelativeTimeFormat`, `date-fns/formatDistanceToNow`, or Luxon

View File

@ -6,137 +6,84 @@ format : formatting string specifying the date format
timestamp : optional timestamp value, defaults to current time
return value : a formatted date
:desc
Returns a formatted date in the GMT/UTC timezone. This is based on the Linux date() command. The formatting string supports the following sequences:
:pre
%% a literal %
%a locale's abbreviated weekday name (e.g., Sun)
%A locale's full weekday name (e.g., Sunday)
%b locale's abbreviated month name (e.g., Jan)
%B locale's full month name (e.g., January)
%c locale's date and time (e.g., Thu Mar 3 23:05:25 2005)
%C century; like %Y, except omit last two digits (e.g., 20)
%d day of month (e.g., 01)
%D date; same as %m/%d/%y
%e day of month, space padded; same as %_d
%F full date; like %+4Y-%m-%d
%g last two digits of year of ISO week number (see %G)
%G year of ISO week number (see %V); normally useful only
with %V
%h same as %b
%H hour (00..23)
%I hour (01..12)
%j day of year (001..366)
%k hour, space padded ( 0..23); same as %_H
%l hour, space padded ( 1..12); same as %_I
%m month (01..12)
%M minute (00..59)
%n a newline
%N nanoseconds (000000000..999999999)
%p locale's equivalent of either AM or PM; blank if not known
%P like %p, but lower case
%q quarter of year (1..4)
%r locale's 12-hour clock time (e.g., 11:11:04 PM)
%R 24-hour hour and minute; same as %H:%M
%s seconds since 1970-01-01 00:00:00 UTC
%S second (00..60)
%t a tab
%T time; same as %H:%M:%S
%u day of week (1..7); 1 is Monday
%U week number of year, with Sunday as first day of week
(00..53)
%V ISO week number, with Monday as first day of week (01..53)
%w day of week (0..6); 0 is Sunday
%W week number of year, with Monday as first day of week
(00..53)
%x locale's date representation (e.g., 12/31/99)
%X locale's time representation (e.g., 23:13:48)
%y last two digits of year (00..99)
%Y year
%z +hhmm numeric time zone (e.g., -0400)
%:z +hh:mm numeric time zone (e.g., -04:00)
%::z +hh:mm:ss numeric time zone (e.g., -04:00:00)
%:::z numeric time zone with : to necessary precision (e.g.,
-04, +05:30)
%Z alphabetic time zone abbreviation (e.g., EDT)
%deltaS total elapsed seconds between the timestamp and now
%deltaM total elapsed minutes between the timestamp and now
%deltaH total elapsed hours between the timestamp and now
%deltad total elapsed days between the timestamp and now
%deltam total elapsed 30-day months between the timestamp and now
%deltaY total elapsed 365-day years between the timestamp and now
By default, date pads numeric fields with zeroes. The following
optional flags may follow '%':
- (hyphen) do not pad the field
_ (underscore) pad with spaces
0 (zero) pad with zeros
+ pad with zeros, and put '+' before future years with >4
digits
^ use upper case if possible
# use opposite case if possible
:see
>time
>time_format_relative
:related
**PHP:** `gmdate()` and UTC `DateTime` formatting
**JavaScript / Node.js:** `Date#toISOString()` and UTC formatting helpers
:content
Formats a timestamp in the GMT/UTC timezone.
This formatter is based on the Linux `date` command and supports the same core formatting tokens plus UCE's relative-time delta tokens.
Supported format sequences:
```text
%% a literal %
%a locale's abbreviated weekday name (e.g., Sun)
%A locale's full weekday name (e.g., Sunday)
%b locale's abbreviated month name (e.g., Jan)
%B locale's full month name (e.g., January)
%c locale's date and time (e.g., Thu Mar 3 23:05:25 2005)
%C century; like %Y, except omit last two digits (e.g., 20)
%d day of month (e.g., 01)
%D date; same as %m/%d/%y
%e day of month, space padded; same as %_d
%F full date; like %+4Y-%m-%d
%g last two digits of year of ISO week number (see %G)
%G year of ISO week number (see %V); normally useful only with %V
%h same as %b
%H hour (00..23)
%I hour (01..12)
%j day of year (001..366)
%k hour, space padded ( 0..23); same as %_H
%l hour, space padded ( 1..12); same as %_I
%m month (01..12)
%M minute (00..59)
%n a newline
%N nanoseconds (000000000..999999999)
%p locale's equivalent of either AM or PM; blank if not known
%P like %p, but lower case
%q quarter of year (1..4)
%r locale's 12-hour clock time (e.g., 11:11:04 PM)
%R 24-hour hour and minute; same as %H:%M
%s seconds since 1970-01-01 00:00:00 UTC
%S second (00..60)
%t a tab
%T time; same as %H:%M:%S
%u day of week (1..7); 1 is Monday
%U week number of year, with Sunday as first day of week (00..53)
%V ISO week number, with Monday as first day of week (01..53)
%w day of week (0..6); 0 is Sunday
%W week number of year, with Monday as first day of week (00..53)
%x locale's date representation (e.g., 12/31/99)
%X locale's time representation (e.g., 23:13:48)
%y last two digits of year (00..99)
%Y year
%z +hhmm numeric time zone (e.g., -0400)
%:z +hh:mm numeric time zone (e.g., -04:00)
%::z +hh:mm:ss numeric time zone (e.g., -04:00:00)
%:::z numeric time zone with : to necessary precision (e.g., -04, +05:30)
%Z alphabetic time zone abbreviation (e.g., EDT)
%deltaS total elapsed seconds between the timestamp and now
%deltaM total elapsed minutes between the timestamp and now
%deltaH total elapsed hours between the timestamp and now
%deltad total elapsed days between the timestamp and now
%deltam total elapsed 30-day months between the timestamp and now
%deltaY total elapsed 365-day years between the timestamp and now
```
Padding and case flags may follow `%`:
```text
- do not pad the field
_ pad with spaces
0 pad with zeros
+ pad with zeros, and put '+' before future years with >4 digits
^ use upper case if possible
# use opposite case if possible
```
Related:
- PHP: `gmdate()` and UTC `DateTime` formatting
- JavaScript / Node.js: `Date#toISOString()` and UTC formatting helpers

View File

@ -5,12 +5,13 @@ u64 time_parse(String time_string)
time_string : a string containing a date and/or time in text form
return value : the interpreted 'time_string' as a Unix timestamp
:desc
Attempts to parse the given 'time_string' into a Unix timestamp.
:see
>time
:related
**PHP:** `strtotime()` or `DateTimeImmutable` parsing
**JavaScript / Node.js:** `Date.parse()` or date-library parsing helpers
:content
Attempts to parse `time_string` into a Unix timestamp.
Related:
- PHP: `strtotime()` or `DateTimeImmutable` parsing
- JavaScript / Node.js: `Date.parse()` or date-library parsing helpers

View File

@ -4,12 +4,13 @@ f64 time_precise()
:params
return value : current Unix timestamp
:desc
Returns a 64 bit float containing the current Unix timestamp with millisecond accuracy or better.
:see
>time
:related
**PHP:** `microtime(true)` or high-resolution timers
**JavaScript / Node.js:** `performance.now()` or high-resolution Node timers
:content
Returns the current Unix timestamp as a 64-bit float with millisecond accuracy or better.
Related:
- PHP: `microtime(true)` or high-resolution timers
- JavaScript / Node.js: `performance.now()` or high-resolution Node timers

Some files were not shown because too many files have changed in this diff Show More