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
+173 -122
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) 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; s32 idx = 0;
for(auto line : lines) for(auto line : lines)
{ {
@@ -18,13 +143,40 @@ void render_see_section(String name)
<></ul></div></> <></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) RENDER(Request& context)
{ {
String page = first(context.get["p"], "index"); String page = first(context.get["p"], "index");
String page_title = page; DocPage doc_page;
nibble(page_title, "_"); 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> <><html>
<head> <head>
@@ -143,135 +295,35 @@ RENDER(Request& context)
} }
else 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"; 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 ?>"> ?><div class="<?= detail_class ?>">
<article class="doc-detail"><? <article class="doc-detail"><?
String layout_class = "text";
u32 line_idx = 0; if(doc_page.sig_lines.size() > 0)
bool section_hidden = false;
for(auto s : doc)
{ {
line_idx++; ?><div class="doc-section sig">
if(s == "") <h3>Signature</h3>
{ <pre><? print(join(doc_page.sig_lines, "\n")); ?></pre>
</div><?
}
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><?
}
}
} }
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><? ?></article><?
if(equiv_lines.size() > 0 || see_lines.size() > 0) if(doc_page.see_lines.size() > 0)
{ {
?><aside class="detail-sidebar"> ?><aside class="detail-sidebar">
<div class="sidebar-card"><? <div class="sidebar-card"><?
if(equiv_lines.size() > 0) render_doc_see_links(doc_page.see_lines);
{
?><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><?
}
}
}
?></div> ?></div>
</aside><? </aside><?
} }
@@ -282,5 +334,4 @@ RENDER(Request& context)
?> ?>
</body> </body>
</html></> </html></>
} }
+129 -104
View File
@@ -1,111 +1,136 @@
:sig :title
DTree DTree
:desc :sig
Dynamic tree/container type used throughout UCE for structured data. DTree
: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.
:see :see
>types >types
get_by_path get_by_path
json_decode 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
+50 -69
View File
@@ -1,75 +1,56 @@
:title
Request
:sig :sig
Request& context; 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 :see
>types >types
:related :content
**PHP:** `$_SERVER`, `$_GET`, `$_POST`, `$_COOKIE`, `$_SESSION`, `header()`, and `http_response_code()` `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`.
**JavaScript / Node.js:** Express `req` and `res`, Fetch `Request`, `Headers`, cookies or session middleware, and per-connection state in WebSocket handlers
## 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
+28 -19
View File
@@ -1,10 +1,21 @@
:title
COMPONENT
:sig :sig
COMPONENT(Request& context) COMPONENT(Request& context)
:desc :see
>component
>component_render
>1_RENDER
>1_WS
:content
Defines the default component entrypoint for the current `.uce` file. 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: 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. 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: ## Example
`COMPONENT(Request& context)`
`{`
` &lt;&gt;&lt;section&gt;&lt;?: component(":BODY", context.call, context) ?&gt;&lt;/section&gt;&lt;/&gt;`
`}`
`COMPONENT:BODY(Request& context)` ```cpp
`{` COMPONENT(Request& context)
` &lt;&gt;&lt;p&gt;&lt;?= context.call["body"] ?&gt;&lt;/p&gt;&lt;/&gt;` {
`}` <><section><?: component(":BODY", context.call, context) ?></section></>
}
:see COMPONENT:BODY(Request& context)
>component {
>component_render <><p><?= context.call["body"] ?></p></>
>1_RENDER }
>1_WS ```
:related ## 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 - 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
+19 -7
View File
@@ -1,11 +1,19 @@
:title
RENDER
:sig :sig
RENDER(Request& context) RENDER(Request& context)
:desc :see
>ob
:content
Defines the main HTTP render handler for the current `.uce` page. 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. 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. 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()`. 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`. 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 In that case:
>ob
:related - `RENDER(Request& context)` serves the direct HTTP response
**PHP:** Front controller entrypoints, template files, `include`, `require`, and route handlers that write the HTTP response - `WS(Request& context)` handles later WebSocket messages
**JavaScript / Node.js:** Express or Fastify route handlers, page controller functions, and SSR entrypoints that build a response - `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
+14 -6
View File
@@ -1,15 +1,25 @@
:title
WS
:sig :sig
WS(Request& context) WS(Request& context)
:desc :see
>websocket
:content
Defines the WebSocket message handler for the current `.ws.uce` page. 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. 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. 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. `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`: The current message data is available in `context.call`:
- `context.call["message"]`: current message payload - `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["opcode"]`: WebSocket opcode of the current message
- `context.call["document_uri"]`: request URI of the current endpoint - `context.call["document_uri"]`: request URI of the current endpoint
:related ## Related Concepts
**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.
:see - PHP: Ratchet `onMessage`, Workerman WebSocket handlers, or lower-level callbacks around accepted socket connections
>websocket - JavaScript / Node.js: browser `WebSocket` `message` handlers and Node `ws` server `connection` and `message` callbacks
+75 -47
View File
@@ -1,12 +1,23 @@
:title
C++ Preprocessor
:sig :sig
UCE source preprocessing 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. 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. 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. - `<> ... </>` enters literal-output mode.
- Inside a literal block, `<? ... ?>` emits raw C++. - Inside a literal block, `<? ... ?>` emits raw C++.
- Inside a literal block, `<?= expression ?>` emits `print(html_escape(expression));`. - 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. - `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. - `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`. - 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 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. - 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. - 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. - `<? ... ?>` 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. - `<?: ... ?>` 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`. - `#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. - 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"`. - 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 ...`. - `scripts/compile` then compiles that generated `.cpp` into `source_file + ".so"` with `clang++ -shared -std=c++20 ...`.
:GeneratedFiles ## Generated Files
- 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`
:Example For a source file like `/some/path/page.uce`, the preprocessor produces:
Example 1: literal output with escaped data
`RENDER(Request& context)` - generated C++: `BIN_DIRECTORY/some/path/page.uce.cpp`
`{` - shared object: `BIN_DIRECTORY/some/path/page.uce.so`
` &lt;&gt;&lt;h1&gt;&lt;?= context.params["DOCUMENT_URI"] ?&gt;&lt;/h1&gt;&lt;/&gt;` - 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: 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 ```cpp
`RENDER(Request& context)` print(R"(<h1>)");
`{` print(html_escape(context.params["DOCUMENT_URI"]));
` &lt;&gt;&lt;div class="panel"&gt;&lt;?: component("components/card", context.call, context) ?&gt;&lt;/div&gt;&lt;/&gt;` 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: 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 ```cpp
`#load "partials/nav.uce"` print(R"(<div class="panel">)");
`RENDER(Request& context)` print(component("components/card", context.call, context));
`{` print(R"(</div>)");
` &lt;&gt;&lt;body&gt;...&lt;/body&gt;&lt;/&gt;` ```
`}`
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. 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 starts only on the exact token `<>`.
- Literal mode ends 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. - `#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. - 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. - 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. - 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. - 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. - 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. - `#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 ## 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.
- 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. - 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`. - 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 ## Related Concepts
load
unit_render
unit_call
0_context
1_COMPONENT
:related - PHP: template tags like `<?php ... ?>`, `<?= ... ?>`, output buffering, and compile-time include patterns
**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
**JavaScript / Node.js:** JSX transforms, tagged templates, server-side rendering pipelines, and build-time HTML generation
+7 -6
View File
@@ -1,7 +1,10 @@
:sig :sig
String String
:desc :see
>types
:content
Primary string type used throughout UCE. Primary string type used throughout UCE.
`String` is an alias for `std::string`. `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. For UTF-8-aware splitting, use helpers such as `split_utf8()` instead of assuming one byte equals one character.
:see ## Related Concepts
>types
:related - PHP: native PHP strings with helpers such as `substr()`, `trim()`, `explode()`, and `implode()`
**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()`
**JavaScript / Node.js:** JavaScript `string` values with methods such as `slice()`, `trim()`, `split()`, and `join()`
+24 -20
View File
@@ -1,26 +1,30 @@
:sig :sig
StringMap 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 :see
>types >types
:related :content
**PHP:** Associative arrays keyed by string, especially request bags like `$_GET` and `$_SERVER` Associative container mapping `String` keys to `String` values.
**JavaScript / Node.js:** Plain objects, dictionaries, `Map`, and header or query objects in web frameworks
`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
+8 -7
View File
@@ -7,18 +7,19 @@ a : left-hand source map or tree
b : right-hand source map or tree b : right-hand source map or tree
return value : merged result return value : merged result
:desc :see
>types
:content
Merges two maps or trees using PHP-like merge behavior. Merges two maps or trees using PHP-like merge behavior.
For `StringMap`, keys from `b` overwrite keys from `a`. 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. 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 ## Related Concepts
>types
:related - PHP: `array_merge()`
**PHP:** `array_merge()` - JavaScript / Node.js: object spread, `Object.assign()`, or array concatenation depending on whether the data is map-like or list-like
**JavaScript / Node.js:** Object spread, `Object.assign()`, or array concatenation depending on whether the data is map-like or list-like
+9 -8
View File
@@ -5,14 +5,15 @@ String ascii_safe_name(String raw)
raw : input string to normalize raw : input string to normalize
return value : ASCII-safe identifier made from letters, digits, and underscores 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 :see
>string >string
:related :content
**PHP:** Slug or safe-filename helpers built with `preg_replace()` and transliteration utilities Builds a conservative identifier by keeping ASCII letters, digits, and underscores and dropping other characters.
**JavaScript / Node.js:** Regex-based slugify or safe-name helpers used for URLs and filenames
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
+7 -6
View File
@@ -5,12 +5,13 @@ String basename(String fn)
fn : raw filename fn : raw filename
return value : the file's name return value : the file's name
:desc
Isolates the file name component from a path/file name.
:see :see
>sys >sys
:related :content
**PHP:** `basename()` Isolates the file name component from a path or file name.
**JavaScript / Node.js:** Node `path.basename()`
## Related Concepts
- PHP: `basename()`
- JavaScript / Node.js: Node `path.basename()`
+23 -15
View File
@@ -1,34 +1,42 @@
:sig :sig
String component(String name, [DTree props], [Request& context]) 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`. 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`. 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. 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)`. 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)`. 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. 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: ## Resolution Order
exact file name
exact file name with `.uce`
the same two forms under `components/`
Example: - exact file name
`DTree props;` - exact file name with `.uce`
`props["title"] = "Status";` - the same two forms under `components/`
`&lt;&gt;&lt;?: component("workspace/panel", props, context) ?&gt;&lt;/&gt;`
:see ## Example
>ob
:related ```cpp
**PHP:** Reusable template partials or helper-rendered view fragments returned as strings DTree props;
**JavaScript / Node.js:** Component render helpers, especially patterns that return markup as a string 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
+7 -6
View File
@@ -1,7 +1,10 @@
:sig :sig
bool component_exists(String name) bool component_exists(String name)
:desc :see
>ob
:content
Checks whether a component file can be resolved from the current page context. 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. 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. This is useful when a page wants to render an optional component if it is present without hard-failing when it is missing.
:see ## Related Concepts
>ob
:related - PHP: `function_exists()`, `class_exists()`, or file-existence checks before including a partial
**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
**JavaScript / Node.js:** Module existence checks, dynamic import guards, or registry lookups for named components
+15 -10
View File
@@ -1,7 +1,10 @@
:sig :sig
void component_render(String name, [DTree props], [Request& context]) 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. 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()`. 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`. Use `component_render()` when you want to write component output directly from C++ code instead of capturing it as a `String`.
Example: ## Example
`DTree props;`
`props["body"] = "Hello";`
`component_render("components/card:BODY", props, context);`
:see ```cpp
>ob DTree props;
props["body"] = "Hello";
:related component_render("components/card:BODY", props, context);
**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
## 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
+7 -6
View File
@@ -1,7 +1,10 @@
:sig :sig
String component_resolve(String name) String component_resolve(String name)
:desc :see
>ob
:content
Resolves a component name to the concrete `.uce` file path that will be loaded. 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. 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. This is primarily a debugging helper so you can see which concrete file a shorthand component name maps to.
:see ## Related Concepts
>ob
:related - PHP: resolving include paths or view names to a concrete template file before rendering
**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
**JavaScript / Node.js:** Resolving module paths, alias-based imports, or component registry entries
+7 -6
View File
@@ -4,12 +4,13 @@ String concat(...vals)
:params :params
...val : one or more values that should be concatenated ...val : one or more values that should be concatenated
:desc
Returns a string with all the parameters concatenated into one.
:see :see
>string >string
:related :content
**PHP:** String concatenation with `.` or helpers like `implode()` Returns a string with all parameters concatenated into one result.
**JavaScript / Node.js:** String concatenation with `+`, template literals, or `Array.prototype.join()`
## Related Concepts
- PHP: string concatenation with `.` or helpers like `implode()`
- JavaScript / Node.js: string concatenation with `+`, template literals, or `Array.prototype.join()`
+7 -6
View File
@@ -6,14 +6,15 @@ haystack : string to search in
needle : substring to look for needle : substring to look for
return value : `true` when `needle` appears in `haystack`, otherwise `false` return value : `true` when `needle` appears in `haystack`, otherwise `false`
:desc :see
>string
:content
Returns whether `haystack` contains `needle`. Returns whether `haystack` contains `needle`.
An empty `needle` always returns `true`. An empty `needle` always returns `true`.
:see ## Related Concepts
>string
:related - PHP: `str_contains()`
**PHP:** `str_contains()` - JavaScript / Node.js: `String.prototype.includes()`
**JavaScript / Node.js:** `String.prototype.includes()`
+7 -6
View File
@@ -4,12 +4,13 @@ String cwd_get()
:params :params
return value : the current working directory return value : the current working directory
:desc
Returns the current working directory.
:see :see
>sys >sys
:related :content
**PHP:** `getcwd()` Returns the current working directory.
**JavaScript / Node.js:** Node `process.cwd()`
## Related Concepts
- PHP: `getcwd()`
- JavaScript / Node.js: Node `process.cwd()`
+7 -6
View File
@@ -4,12 +4,13 @@ void cwd_set(String path)
:params :params
path : the new working directory path : the new working directory
:desc
Sets a new working directory.
:see :see
>sys >sys
:related :content
**PHP:** `chdir()` Sets a new working directory.
**JavaScript / Node.js:** Node `process.chdir()`
## Related Concepts
- PHP: `chdir()`
- JavaScript / Node.js: Node `process.chdir()`
+7 -6
View File
@@ -5,12 +5,13 @@ String dirname(String fn)
fn : raw filename fn : raw filename
return value : the directory's name return value : the directory's name
:desc
Isolates the directory name component from a path/file name.
:see :see
>sys >sys
:related :content
**PHP:** `dirname()` Isolates the directory component from a path or file name.
**JavaScript / Node.js:** Node `path.dirname()`
## Related Concepts
- PHP: `dirname()`
- JavaScript / Node.js: Node `path.dirname()`
+9 -6
View File
@@ -6,12 +6,15 @@ from : minimum value
to : maximum value to : maximum value
return value : a noise value between 'from' and 'to' 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 :see
>noise >noise
:related :content
**PHP:** `random_int()`, `mt_rand()`, and custom numeric random helpers Works like `generate_float()`, but uses `context.random_index` for the index value and `context.random_seed` for the seed.
**JavaScript / Node.js:** `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges
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
+9 -6
View File
@@ -6,12 +6,15 @@ from : minimum value
to : maximum value to : maximum value
return value : a noise value between 'from' and 'to' 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 :see
>noise >noise
:related :content
**PHP:** `random_int()`, `mt_rand()`, and custom numeric random helpers Works like `generate_int()`, but uses `context.random_index` for the index value and `context.random_seed` for the seed.
**JavaScript / Node.js:** `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges
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
+7 -6
View File
@@ -5,12 +5,13 @@ String encode_query(StringMap map)
q : StringMap containing URL parameters to be encoded q : StringMap containing URL parameters to be encoded
return value : a string with the encoded parameters return value : a string with the encoded parameters
:desc
Encodes a StringMap containing URL parameters into a single String.
:see :see
>uri >uri
:related :content
**PHP:** `http_build_query()` Encodes a `StringMap` of URL parameters into a single query-string `String`.
**JavaScript / Node.js:** `URLSearchParams` and `toString()`
## Related Concepts
- PHP: `http_build_query()`
- JavaScript / Node.js: `URLSearchParams` and `toString()`
+7 -6
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) relative_to_path : optional, expand relative to this path (if not given, the current path is used)
return value : expanded version of the 'path' 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 :see
>sys >sys
:related :content
**PHP:** `realpath()` and application-specific path normalization helpers Converts a relative path name into an absolute path, using the current working directory as a base when `relative_to_path` is not provided.
**JavaScript / Node.js:** Node `path.resolve()` and `path.normalize()`
## Related Concepts
- PHP: `realpath()` and application-specific path normalization helpers
- JavaScript / Node.js: Node `path.resolve()` and `path.normalize()`
+7 -6
View File
@@ -5,12 +5,13 @@ void file_append(String file_name, ...val)
file_name : file name of file that should be written to file_name : file name of file that should be written to
...val : one or more values that should be written into the file ...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 :see
>sys >sys
:related :content
**PHP:** `file_put_contents($file, $data, FILE_APPEND)` Opens or creates a file and appends data to it.
**JavaScript / Node.js:** Node `fs.appendFileSync()` or `fs.promises.appendFile()`
## Related Concepts
- PHP: `file_put_contents($file, $data, FILE_APPEND)`
- JavaScript / Node.js: Node `fs.appendFileSync()` or `fs.promises.appendFile()`
+7 -6
View File
@@ -5,12 +5,13 @@ bool file_exists(String path)
path : the path name to be checked path : the path name to be checked
return value : true if the file exists return value : true if the file exists
:desc
Checks whether the file or path specified by 'path' exists.
:see :see
>sys >sys
:related :content
**PHP:** `file_exists()` or `is_file()` Checks whether the file or path specified by `path` exists.
**JavaScript / Node.js:** Node `fs.existsSync()` or `fs.stat()`
## Related Concepts
- PHP: `file_exists()` or `is_file()`
- JavaScript / Node.js: Node `fs.existsSync()` or `fs.stat()`
+9 -6
View File
@@ -5,12 +5,15 @@ String file_get_contents(String file_name)
file_name : file name of file that should be read file_name : file name of file that should be read
return value : String containing the file's contents 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 :see
>sys >sys
:related :content
**PHP:** `file_get_contents()` Reads the file identified by `file_name` and returns it as a `String`.
**JavaScript / Node.js:** Node `fs.readFileSync()` or `fs.promises.readFile()`
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()`
+7 -6
View File
@@ -5,13 +5,14 @@ time_t file_mtime(String file_name)
file_name : name of the file file_name : name of the file
return value : Unix time stamp of the file's last modification 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 :see
>sys >sys
>time >time
:related :content
**PHP:** `filemtime()` Retrieves the last modification date of `file_name` as a Unix timestamp.
**JavaScript / Node.js:** Node `fs.statSync().mtimeMs` or `fs.promises.stat()`
## Related Concepts
- PHP: `filemtime()`
- JavaScript / Node.js: Node `fs.statSync().mtimeMs` or `fs.promises.stat()`
+7 -6
View File
@@ -6,12 +6,13 @@ file_name : file name of file that should be written
content : content that should be written content : content that should be written
return value : true if write was successful 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 :see
>sys >sys
:related :content
**PHP:** `file_put_contents()` Writes `content` into the file identified by `file_name`, overwriting any pre-existing content.
**JavaScript / Node.js:** Node `fs.writeFileSync()` or `fs.promises.writeFile()`
## Related Concepts
- PHP: `file_put_contents()`
- JavaScript / Node.js: Node `fs.writeFileSync()` or `fs.promises.writeFile()`
+7 -6
View File
@@ -4,12 +4,13 @@ void file_unlink(String file_name)
:params :params
file_name : name of the file file_name : name of the file
:desc
Deletes the file identified by `file_name`.
:see :see
>sys >sys
:related :content
**PHP:** `unlink()` Deletes the file identified by `file_name`.
**JavaScript / Node.js:** Node `fs.unlinkSync()` or `fs.promises.unlink()`
## Related Concepts
- PHP: `unlink()`
- JavaScript / Node.js: Node `fs.unlinkSync()` or `fs.promises.unlink()`
+7 -6
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 f : a function that decides which items should be in the new list
return value : a new list return value : a new list
:desc
Returns a list containing the members of 'items' for which 'f' returned boolean true.
:see :see
>string >string
:related :content
**PHP:** `array_filter()` for arrays or custom predicate-based filtering over strings and collections Returns a new list containing the members of `items` for which `f` returned `true`.
**JavaScript / Node.js:** `Array.prototype.filter()` and custom predicate helpers
## 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
+9 -6
View File
@@ -5,12 +5,15 @@ String first(String... args)
args : a variable number of String arguments args : a variable number of String arguments
return value : first of the 'args' that was not empty. 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 :see
>string >string
:related :content
**PHP:** Null-coalescing patterns like `$a ?? $b`, fallback helpers, or `reset()` for arrays Returns the first non-empty string from the provided arguments.
**JavaScript / Node.js:** `??`, `||`, and small fallback helper functions
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
+7 -5
View File
@@ -5,10 +5,12 @@ f64 float_val(String s)
s : string to be converted s : string to be converted
return value : a f64 containing the number (0 if no number could be identified). return value : a f64 containing the number (0 if no number could be identified).
:desc :content
Extracts a floating point number from a String. Extracts a floating point number from a `String`.
If no usable number can be identified, the result is `0`.
:related ## Related Concepts
**PHP:** `floatval()`
**JavaScript / Node.js:** `Number()` or `parseFloat()` - PHP: `floatval()`
- JavaScript / Node.js: `Number()` or `parseFloat()`
+7 -7
View File
@@ -8,13 +8,13 @@ index : index position to generate number from
seed : seed position to generate number from (defaults to 0) seed : seed position to generate number from (defaults to 0)
return value : noise value return value : noise value
:desc
Generates a noise value between 'from' and 'to', given the 'index' and 'seed' numbers.
:see :see
>noise >noise
:related :content
**PHP:** `random_int()`, `mt_rand()`, and custom numeric random helpers Generates a deterministic noise value between `from` and `to` for the given `index` and `seed`.
**JavaScript / Node.js:** `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges
## 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
+7 -7
View File
@@ -8,13 +8,13 @@ index : index position to generate number from
seed : seed position to generate number from (defaults to 0) seed : seed position to generate number from (defaults to 0)
return value : noise value return value : noise value
:desc
Generates a noise value between 'from' and 'to', given the 'index' and 'seed' numbers.
:see :see
>noise >noise
:related :content
**PHP:** `random_int()`, `mt_rand()`, and custom numeric random helpers Generates a deterministic noise value between `from` and `to` for the given `index` and `seed`.
**JavaScript / Node.js:** `Math.random()` or `crypto.getRandomValues()`-based helpers for numeric ranges
## 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
+7 -6
View File
@@ -6,12 +6,13 @@ index : index position
seed : seed set (defaults to 0) seed : seed set (defaults to 0)
return value : a noise value from 0 to 1 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 :see
>noise >noise
:related :content
**PHP:** There is no built-in PHP equivalent; this is closest to userland noise or deterministic pseudo-random helpers Generates a deterministic noise value in the range from `0` to `1` for the given `index` and `seed`.
**JavaScript / Node.js:** There is no built-in browser equivalent; closest matches are userland noise libraries or deterministic PRNG helpers
## 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
+7 -6
View File
@@ -6,12 +6,13 @@ index : index position
seed : seed set (defaults to 0) seed : seed set (defaults to 0)
return value : a noise value given the 'index' and 'seed' values. return value : a noise value given the 'index' and 'seed' values.
:desc
Generates a noise value for the given 'index' and 'seed' values.
:see :see
>noise >noise
:related :content
**PHP:** There is no built-in PHP equivalent; this is closest to userland noise or deterministic pseudo-random helpers Generates a deterministic 32-bit noise value for the given `index` and `seed`.
**JavaScript / Node.js:** There is no built-in browser equivalent; closest matches are userland noise libraries or deterministic PRNG helpers
## 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
+7 -6
View File
@@ -6,12 +6,13 @@ index : index position
seed : seed set (defaults to 0) seed : seed set (defaults to 0)
return value : a noise value given the 'index' and 'seed' values. return value : a noise value given the 'index' and 'seed' values.
:desc
Generates a noise value for the given 'index' and 'seed' values.
:see :see
>noise >noise
:related :content
**PHP:** There is no built-in PHP equivalent; this is closest to userland noise or deterministic pseudo-random helpers Generates a deterministic 64-bit-indexed noise value for the given `index` and `seed`.
**JavaScript / Node.js:** There is no built-in browser equivalent; closest matches are userland noise libraries or deterministic PRNG helpers
## 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
+9 -6
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) as_binary : when set to false, returns hash in hexadecimal notation (defaults to false)
return value : the resulting hash value return value : the resulting hash value
:desc
Returns the sha1 hash of 's'.
:see :see
>noise >noise
:related :content
**PHP:** `sha1()` Returns the SHA-1 hash of `s`.
**JavaScript / Node.js:** Node `crypto.createHash("sha1")` or browser `SubtleCrypto` wrappers
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
+15 -11
View File
@@ -6,19 +6,23 @@ path : slash-delimited path to traverse
delim : optional path separator delim : optional path separator
return value : the resolved child node, or an empty `DTree` when the path cannot be followed 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 :see
DTree DTree
0_context 0_context
>types >types
:related :content
**PHP:** Deep array access helpers for associative arrays, decoded JSON, or configuration trees Traverses a nested `DTree` without creating missing keys.
**JavaScript / Node.js:** Optional chaining like `obj?.a?.b`, lodash `get`, or small path-walking helpers
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
+11 -9
View File
@@ -5,13 +5,15 @@ String html_escape(String s)
s : string to be escaped s : string to be escaped
return value : an HTML-safe escaped version of 's' return value : an HTML-safe escaped version of 's'
:desc :content
Returns a version of the input string where the following characters have been replace by HTML entities: Returns a version of the input string where special HTML characters are replaced by entities:
- & → &amp
- < → lt;
- > → &gt;
- " → &quot;
:related - `&` becomes `&amp;`
**PHP:** `htmlspecialchars()` or `htmlentities()` - `<` becomes `&lt;`
**JavaScript / Node.js:** Safe text insertion via `textContent` or server-side HTML escaping libraries - `>` becomes `&gt;`
- `"` becomes `&quot;`
## Related Concepts
- PHP: `htmlspecialchars()` or `htmlentities()`
- JavaScript / Node.js: safe text insertion via `textContent` or server-side HTML escaping libraries
+7 -5
View File
@@ -6,10 +6,12 @@ s : string to be converted
base : number system base (default 10) base : number system base (default 10)
return value : a u64 containing the number (0 if no number could be identified). return value : a u64 containing the number (0 if no number could be identified).
:desc :content
Extracts an integer from a String. 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 Related:
**PHP:** `intval()`
**JavaScript / Node.js:** `Number()` or `parseInt()` - PHP: `intval()`
- JavaScript / Node.js: `Number()` or `parseInt()`
+9 -6
View File
@@ -6,12 +6,15 @@ l : list of strings to be joined
delim : delimiter (defaults to newline character) delim : delimiter (defaults to newline character)
return value : a string containing items joined by 'delim' return value : a string containing items joined by 'delim'
:desc
Joins the items contained in 'l' into a single String.
:see :see
>string >string
:related :content
**PHP:** `implode()` Joins all strings in `l` into a single `String`.
**JavaScript / Node.js:** `Array.prototype.join()`
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()`
+20 -17
View File
@@ -5,20 +5,6 @@ DTree json_decode(String s)
s : string containing JSON data s : string containing JSON data
return value : a DTree object containing the deserialized 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 :see
DTree DTree
json_encode json_encode
@@ -26,6 +12,23 @@ to_bool
to_f64 to_f64
to_u64 to_u64
:related :content
**PHP:** `json_decode()` Deserializes `s` into a `DTree` structure.
**JavaScript / Node.js:** `JSON.parse()`
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()`
+5 -4
View File
@@ -7,13 +7,14 @@ s : string to encode as a JSON string literal
t : DTree object to be serialized t : DTree object to be serialized
return value : string containing the JSON result return value : string containing the JSON result
:desc :content
Serializes either a `String` or a `DTree` into JSON notation. 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 `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. When passed a `DTree`, scalar values are serialized directly and nested map values are emitted as JSON objects.
:related Related:
**PHP:** `json_encode()`
**JavaScript / Node.js:** `JSON.stringify()` - PHP: `json_encode()`
- JavaScript / Node.js: `JSON.stringify()`
+13 -6
View File
@@ -4,12 +4,19 @@
:params :params
file name : name of an UCE file that should be included file name : name of an UCE file that should be included
:desc
Includes another UCE file
:see :see
>ob >ob
:related :content
**PHP:** `include`, `require`, and config-loader patterns that resolve and import another file Includes another UCE file.
**JavaScript / Node.js:** `import()`, `require()`, or file-loader helpers that resolve modules at runtime
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
+9 -6
View File
@@ -5,12 +5,15 @@ StringList ls(String path)
path : a filesystem path path : a filesystem path
return value : list of directory entries return value : list of directory entries
:desc
Returns a list of files and subdirectories within the given 'path'.
:see :see
>sys >sys
:related :content
**PHP:** `scandir()`, `glob()`, or `DirectoryIterator` Returns a list of files and subdirectories within `path`.
**JavaScript / Node.js:** Node `fs.readdirSync()` or `fs.promises.readdir()`
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()`
+48 -45
View File
@@ -7,11 +7,19 @@ src : markdown source text
options : optional markdown options tree options : optional markdown options tree
return value : a `DTree` document AST 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. Parses Markdown source into a structured `DTree` document tree.
The parser targets a practical GitHub-flavored subset by default: The parser targets a practical GitHub-flavored subset by default:
- ATX headings (`#`)
- ATX headings with `#`
- setext headings - setext headings
- paragraphs - paragraphs
- blockquotes - blockquotes
@@ -20,62 +28,57 @@ The parser targets a practical GitHub-flavored subset by default:
- fenced code blocks - fenced code blocks
- tables - tables
- horizontal rules - horizontal rules
- emphasis / strong / strikethrough - emphasis, strong, and strikethrough
- links, images, autolinks, and code spans - links, images, autolinks, and code spans
- `:::` directive blocks for component-based extensions - `:::` 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`. 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: Top-level documents use:
`type = "document"`
`children = [...]` ```text
type = "document"
children = [...]
```
Common block nodes: Common block nodes:
`heading`
`paragraph` - `heading`
`blockquote` - `paragraph`
`list` - `blockquote`
`list_item` - `list`
`code_block` - `list_item`
`table` - `code_block`
`directive` - `table`
`hr` - `directive`
- `hr`
Common inline nodes: Common inline nodes:
`text`
`code`
`strong`
`em`
`strike`
`link`
`image`
`raw_html`
:Example - `text`
`DTree options = json_decode("{\"components\":{\":::warning\":\"components/markdown/warning\"}}");` - `code`
`DTree ast = markdown_to_ast(file_get_contents("README.md"), options);` - `strong`
`print(json_encode(ast));` - `em`
- `strike`
- `link`
- `image`
- `raw_html`
:Options Example:
`options["gfm"]`
Enables GitHub-style extras such as tables, task lists, strikethrough, and bare-URL autolinks.
Defaults to true.
`options["allow_html"]` ```uce
Allows raw HTML passthrough nodes to be captured and rendered. DTree options = json_decode("{\"components\":{\":::warning\":\"components/markdown/warning\"}}");
Defaults to false. DTree ast = markdown_to_ast(file_get_contents("README.md"), options);
print(json_encode(ast));
```
`options["components"]` Options:
Component hook map used later by `markdown_to_html()`.
The parser preserves directive data needed by those hooks.
:see - `options["gfm"]` enables GitHub-style extras such as tables, task lists, strikethrough, and bare-URL autolinks. Defaults to `true`.
markdown_to_html - `options["allow_html"]` allows raw HTML passthrough nodes to be captured and rendered. Defaults to `false`.
component - `options["components"]` provides the component hook map later used by `markdown_to_html()`. The parser preserves directive data needed by those hooks.
component_render
json_encode
DTree
:related 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 - 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
+64 -57
View File
@@ -7,7 +7,14 @@ src : markdown source text
options : optional markdown options tree options : optional markdown options tree
return value : rendered HTML string 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`. 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. `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. By default the function aims at a practical GitHub-flavored Markdown target, including tables, task lists, fenced code blocks, autolinks, and strikethrough.
:Example Example:
`DTree options;`
`options["components"][":::warning"] = "components/markdown/warning";` ```uce
`options["components"]["node.code_block"] = "components/markdown/code_block";` DTree options;
`String html = markdown_to_html(file_get_contents("guide.md"), options);` options["components"][":::warning"] = "components/markdown/warning";
`print(html);` 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 - headings with `#` or setext underlines
- paragraphs - paragraphs
- ordered and unordered lists - ordered and unordered lists
@@ -32,73 +43,69 @@ By default the function aims at a practical GitHub-flavored Markdown target, inc
- fenced code blocks - fenced code blocks
- horizontal rules - horizontal rules
- tables - tables
- inline emphasis, strong, strikethrough, code spans - inline emphasis, strong, strikethrough, and code spans
- links, images, and bare `http://` / `https://` URLs - links, images, and bare `http://` / `https://` URLs
- `:::name ... :::` directive blocks - `:::name ... :::` directive blocks
:Options Options:
`options["gfm"]`
Defaults to true.
Turns on GitHub-style extras such as tables, task lists, autolinks, and strikethrough.
`options["allow_html"]` - `options["gfm"]` defaults to `true` and turns on GitHub-style extras such as tables, task lists, autolinks, and strikethrough.
Defaults to false. - `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.
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"]` Directive hook example:
Declares renderer extension points using normal UCE components.
Exact directive hooks: ```uce
`options["components"][":::warning"] = "components/markdown/warning"` options["components"][":::warning"] = "components/markdown/warning";
This hook is selected for `:::warning ... :::` blocks. ```
Generic node hooks: Generic node hook examples:
`options["components"]["node.code_block"] = "components/markdown/code_block"`
`options["components"]["node.table"] = "components/markdown/table"` ```uce
`options["components"]["node.link"] = "components/markdown/link"` options["components"]["node.code_block"] = "components/markdown/code_block";
`options["components"]["node.directive"] = "components/markdown/directive"` 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. 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`. When a markdown hook component is called, its props arrive in `context.call`.
Useful fields include: 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: Directive blocks use this form:
`:::warning title="Heads up"`
`Body markdown here` ```md
`:::` :::warning title="Heads up"
Body markdown here
:::
```
The parser stores: 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 That makes directive components a good fit for alerts, callouts, cards, embeds, and richer page-level Markdown extensions.
markdown_to_ast
component
component_render
json_decode
String
:related Related:
**PHP:** Parsedown, League CommonMark, or similar Markdown-to-HTML renderers
**JavaScript / Node.js:** `marked`, `markdown-it`, `remark-html`, or other Markdown renderers - PHP: Parsedown, League CommonMark, or similar Markdown-to-HTML renderers
- JavaScript / Node.js: `marked`, `markdown-it`, `remark-html`, or other Markdown renderers
+9 -6
View File
@@ -6,12 +6,15 @@ connection : connection handle
command : string containing the Memcache command command : string containing the Memcache command
return value : string containing the Memcache server's response return value : string containing the Memcache server's response
:desc
Executes a command on an open memcache connection.
:see :see
>memcache >memcache
:related :content
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()` Executes a raw command on an open Memcache connection and returns the server response as a string.
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
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
+9 -6
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 port : optional memcache server's port, defaults to 11211
return value : the connection handle (or -1 if an error occurred) return value : the connection handle (or -1 if an error occurred)
:desc
Connects to a memcache server instance.
:see :see
>memcache >memcache
:related :content
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()` Connects to a Memcache server instance.
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
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
+9 -6
View File
@@ -6,12 +6,15 @@ connection : connection handle
key : key string key : key string
return value : true if the operation was successful return value : true if the operation was successful
:desc
Deletes entry specified by the 'key'.
:see :see
>memcache >memcache
:related :content
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()` Deletes the entry identified by `key`.
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
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
+9 -6
View File
@@ -7,12 +7,15 @@ key : key string
default_value : optional default value default_value : optional default value
return value : value that was returned by the Memcache server return value : value that was returned by the Memcache server
:desc
Retrieves a value from an existing connection to a Memcache server.
:see :see
>memcache >memcache
:related :content
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()` Retrieves a value from an existing Memcache connection.
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
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
+9 -6
View File
@@ -6,12 +6,15 @@ connection : connection handle
keys : a list of strings containing the keys to be retrieved keys : a list of strings containing the keys to be retrieved
return value : a StringMap with the retrieved entries return value : a StringMap with the retrieved entries
:desc
Retrieves a bunch of entries all at once.
:see :see
>memcache >memcache
:related :content
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()` Retrieves multiple entries in one call.
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
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
+9 -6
View File
@@ -8,12 +8,15 @@ value : the value to be set
expires_in : optional expiration timeout, defaults to one hour expires_in : optional expiration timeout, defaults to one hour
return value : true if the operation was successful return value : true if the operation was successful
:desc
Stores a 'value' on the Memcache server.
:see :see
>memcache >memcache
:related :content
**PHP:** The `Memcache` or `Memcached` extension methods such as `get()`, `set()`, `delete()`, and `getMulti()` Stores `value` under `key` on the Memcache server.
**JavaScript / Node.js:** Node clients like `memjs`, `memcached`, or similar Memcached packages
`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
+9 -6
View File
@@ -5,12 +5,15 @@ bool mkdir(String path)
path : the path name to be created path : the path name to be created
return value : returns true if the directory was successfully created return value : returns true if the directory was successfully created
:desc
Creates a directory stated by 'path'
:see :see
>sys >sys
:related :content
**PHP:** `mkdir()` Creates the directory named by `path`.
**JavaScript / Node.js:** Node `fs.mkdirSync()` or `fs.promises.mkdir()`
The function returns `true` when the directory was created successfully.
Related:
- PHP: `mkdir()`
- JavaScript / Node.js: Node `fs.mkdirSync()` or `fs.promises.mkdir()`
+9 -6
View File
@@ -7,12 +7,15 @@ username : user name
password : password password : password
return value : pointer to the MySQL connection struct return value : pointer to the MySQL connection struct
:desc
Establishes a connection to a MySQL server.
:see :see
>mysql >mysql
:related :content
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family Establishes a connection to a MySQL server and returns a pointer to the connection struct.
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
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
+9 -6
View File
@@ -4,12 +4,15 @@ void mysql_disconnect(MySQL* m)
:params :params
m : pointer to an existing MySQL connection struct m : pointer to an existing MySQL connection struct
:desc
Closes a connection to a MySQL server.
:see :see
>mysql >mysql
:related :content
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family Closes an existing connection to a MySQL server.
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
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
+9 -6
View File
@@ -5,12 +5,15 @@ String mysql_error(MySQL* m)
m : pointer to a MySQL connection struct m : pointer to a MySQL connection struct
return value : MySQL error message (if present, otherwise empty string) return value : MySQL error message (if present, otherwise empty string)
:desc
Returns the last error message from a connection to a MySQL server.
:see :see
>mysql >mysql
:related :content
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family Returns the last error message associated with the given MySQL connection.
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
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
+9 -6
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) 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 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 :see
>mysql >mysql
:related :content
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family Escapes a string so it can be used safely as a value inside an SQL expression.
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
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
+9 -6
View File
@@ -5,12 +5,15 @@ u64 mysql_insert_id(MySQL* m)
m : pointer to an active MySQL connection m : pointer to an active MySQL connection
return value : the last used automatic row ID 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 :see
>mysql >mysql
:related :content
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family Returns the last automatically assigned row ID used by the current MySQL connection.
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
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
+11 -9
View File
@@ -7,15 +7,17 @@ q : a string containing a MySQL query
params : optional, a list of query parameter keys and values params : optional, a list of query parameter keys and values
return value : a list of rows returned from executing the query 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 :see
>mysql >mysql
:related :content
**PHP:** Modern PHP database access through `mysqli_*` or PDO methods rather than the old `mysql_*` family Executes a MySQL query and returns the resulting data, if any.
**JavaScript / Node.js:** Node database clients such as `mysql2`, query builders, or ORM adapters
`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
+11 -6
View File
@@ -6,12 +6,17 @@ haystack : string to be nibbled at
delim : delimiter delim : delimiter
return value : string before first occurrence of 'delim' 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 :see
>string >string
:related :content
**PHP:** Small parsing helpers built with `strpos()`, `substr()`, and `explode()` Returns the part of `haystack` before the first occurrence of `delim`.
**JavaScript / Node.js:** Manual parsing with `indexOf()`, `slice()`, and `split()`
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()`
+9 -6
View File
@@ -4,12 +4,15 @@ void ob_close()
:params :params
(none) (none)
:desc
Discard the current output buffer. If are more output buffers on the stack, switch to the next one.
:see :see
>ob >ob
:related :content
**PHP:** `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs Discards the current output buffer.
**JavaScript / Node.js:** String accumulation, buffer capture, or render-to-string patterns in server code
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
+9 -6
View File
@@ -4,12 +4,15 @@ String ob_get()
:params :params
return value : content of the current output buffer return value : content of the current output buffer
:desc
Returns the contents of the current output buffer.
:see :see
>ob >ob
:related :content
**PHP:** `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs Returns the contents of the current output buffer.
**JavaScript / Node.js:** String accumulation, buffer capture, or render-to-string patterns in server code
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
+9 -7
View File
@@ -4,13 +4,15 @@ String ob_get_close()
:params :params
return value : content of the current output buffer 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 :see
>ob >ob
:related :content
**PHP:** `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs Returns the contents of the current output buffer and then discards that buffer.
**JavaScript / Node.js:** String accumulation, buffer capture, or render-to-string patterns in server code
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
+9 -6
View File
@@ -4,12 +4,15 @@ void ob_start()
:params :params
(none) (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 :see
>ob >ob
:related :content
**PHP:** `ob_start()`, `ob_get_contents()`, `ob_get_clean()`, and related output-buffering APIs Starts a new output buffer.
**JavaScript / Node.js:** String accumulation, buffer capture, or render-to-string patterns in server code
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
+9 -6
View File
@@ -5,12 +5,15 @@ StringMap parse_query(String q)
q : string containing URL parameters q : string containing URL parameters
return value : a StringMap containing the 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 :see
>uri >uri
:related :content
**PHP:** `parse_str()` Decodes a query-string fragment such as `a=b&c=d` into a `StringMap`.
**JavaScript / Node.js:** `URLSearchParams` or Node `querystring.parse()`
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()`
+9 -8
View File
@@ -6,14 +6,15 @@ base : parent path
child : child path or absolute override child : child path or absolute override
return value : combined path 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 :see
>sys >sys
:related :content
**PHP:** Manual path composition with `DIRECTORY_SEPARATOR` or helper wrappers around it Joins two filesystem-style path fragments with a single `/` when needed.
**JavaScript / Node.js:** Node `path.join()`
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()`
+9 -6
View File
@@ -4,12 +4,15 @@ void print(...val)
:params :params
...val : one or more values that should be output ...val : one or more values that should be output
:desc
Appends data to the current request's output stream.
:see :see
>string >string
:related :content
**PHP:** `echo`, `print`, and output buffering patterns Appends data to the current request output stream.
**JavaScript / Node.js:** `res.write()`, stream writes, or string-returning render helpers depending on context
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
+9 -8
View File
@@ -5,15 +5,16 @@ void redirect(String url, s32 code = 302)
url : target URL for the redirect url : target URL for the redirect
code : optional HTTP redirect status, defaults to `302` 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 :see
set_status set_status
0_context 0_context
:related :content
**PHP:** `header("Location: ...")` together with `http_response_code()` or implicit redirect semantics Sets the `Location` response header and updates the current HTTP status code.
**JavaScript / Node.js:** `res.redirect(...)`, setting `Location`, or returning a redirect `Response`
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`
+9 -6
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 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' 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 :see
>string >string
:related :content
**PHP:** `str_replace()` or `preg_replace()` Replaces every occurrence of `search` in `s` with `replace_with`.
**JavaScript / Node.js:** `String.prototype.replace()` or `replaceAll()`
The returned string contains the fully replaced result.
Related:
- PHP: `str_replace()` or `preg_replace()`
- JavaScript / Node.js: `String.prototype.replace()` or `replaceAll()`
+9 -6
View File
@@ -4,12 +4,15 @@ void session_destroy(String session_name)
:params :params
session_name : the name of the session 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 :see
>session >session
:related :content
**PHP:** `session_destroy()` Deletes the cookie specified by `session_name` and clears the data stored under the current session ID.
**JavaScript / Node.js:** Express session store teardown or manual cookie-session invalidation
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
+9 -6
View File
@@ -4,12 +4,15 @@ String session_id_create()
:params :params
return value : a new session ID return value : a new session ID
:desc
Creates a session ID.
:see :see
>session >session
:related :content
**PHP:** `session_create_id()` or custom session token generators Creates and returns a new session ID.
**JavaScript / Node.js:** `crypto.randomUUID()` or custom secure session ID generation
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
+15 -12
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" session_name : optional name of the session cookie, defaults to "uce-session"
return value : the current session ID 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 :see
>session >session
:related :content
**PHP:** `session_start()` Starts a session or reconnects to an existing one.
**JavaScript / Node.js:** Express `express-session`, `cookie-session`, or similar request-bound session middleware
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
+9 -8
View File
@@ -5,15 +5,16 @@ void context.set_status(s32 code, String reason = "")
code : HTTP status code code : HTTP status code
reason : optional reason phrase override 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 :see
0_context 0_context
>types >types
:related :content
**PHP:** `http_response_code()` and explicit status-line header control Sets the current request status line and mirrors the numeric status into `context.flags.status`.
**JavaScript / Node.js:** `res.status(...)`, `Response` init status, or low-level status assignment on an HTTP response
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
+9 -6
View File
@@ -5,12 +5,15 @@ String shell_escape(String raw)
raw : string that should be escaped raw : string that should be escaped
return value : escaped version of 'raw' return value : escaped version of 'raw'
:desc
Escapes a parameter for shell_exec
:see :see
>sys >sys
:related :content
**PHP:** `escapeshellarg()` and `escapeshellcmd()` Escapes a parameter so it can be used more safely with `shell_exec()`.
**JavaScript / Node.js:** There is no direct built-in equivalent; prefer `spawn()` argument arrays and avoid shell interpolation
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
+9 -6
View File
@@ -5,12 +5,15 @@ String shell_exec(String cmd)
cmd : string that contains the shell command line to be executed cmd : string that contains the shell command line to be executed
return value : output of the command execution return value : output of the command execution
:desc
Executes a Linux shell command and returns the generated output
:see :see
>sys >sys
:related :content
**PHP:** `shell_exec()`, `exec()`, or `proc_open()` Executes a Linux shell command and returns the generated output.
**JavaScript / Node.js:** Node `child_process.exec()` or `spawn()`
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()`
+9 -6
View File
@@ -4,12 +4,15 @@ void socket_close(u64 sockfd)
:params :params
sockfd : socket handle sockfd : socket handle
:desc
Closes an existing socket connection.
:see :see
>socket >socket
:related :content
**PHP:** PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients Closes an existing socket connection.
**JavaScript / Node.js:** Node `net.Socket` connect, read, write, and close operations
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
+9 -6
View File
@@ -6,12 +6,15 @@ host : host name
port : port number port : port number
return value : the socket handle return value : the socket handle
:desc
Opens a socket connection to the given 'host' and 'port'.
:see :see
>socket >socket
:related :content
**PHP:** PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients Opens a socket connection to the given `host` and `port`.
**JavaScript / Node.js:** Node `net.Socket` connect, read, write, and close operations
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
+9 -6
View File
@@ -7,12 +7,15 @@ max_length : optional maximum data size, defaults to 128kBytes
timeout : optional operation timeout, defaults to one second timeout : optional operation timeout, defaults to one second
return value : string containing the data that was read return value : string containing the data that was read
:desc
Reads data from a socket connection.
:see :see
>socket >socket
:related :content
**PHP:** PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients Reads data from a socket connection.
**JavaScript / Node.js:** Node `net.Socket` connect, read, write, and close operations
`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
+9 -6
View File
@@ -6,12 +6,15 @@ sockfd : socket handle
data : a string containing the data to be written to the socket data : a string containing the data to be written to the socket
return value : true if the write operation was successful return value : true if the write operation was successful
:desc
Writes a string of 'data' to the given socket.
:see :see
>socket >socket
:related :content
**PHP:** PHP sockets and stream APIs like `socket_connect()`, `fread()`, `fwrite()`, and stream clients Writes `data` to the given socket.
**JavaScript / Node.js:** Node `net.Socket` connect, read, write, and close operations
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
+9 -6
View File
@@ -6,12 +6,15 @@ str : string to be split
delim : delimiter delim : delimiter
return value : a list of strings return value : a list of strings
:desc
Splits 'str' into multiple strings based on the given delimiter 'delim'.
:see :see
>string >string
:related :content
**PHP:** `explode()` or `preg_split()` Splits `str` into multiple strings using `delim` as the separator.
**JavaScript / Node.js:** `String.prototype.split()`
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()`
+9 -6
View File
@@ -5,12 +5,15 @@ StringList split_space(String str)
str : string to be split str : string to be split
return value : a list of strings return value : a list of strings
:desc
Splits 'str' into multiple strings along any whitespace characters (multiple whitespace characters count as one).
:see :see
>string >string
:related :content
**PHP:** Whitespace splitting via `preg_split(/\s+/, ...)` Splits `str` on runs of whitespace.
**JavaScript / Node.js:** Whitespace splitting via regex with `split(/\\s+/)`
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+/)`
+16 -12
View File
@@ -7,18 +7,22 @@ str : string to be split
compound_characters : optional, if true tries to combine compound characters compound_characters : optional, if true tries to combine compound characters
return value : a list of Unicode 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 :see
>string >string
:related :content
**PHP:** `preg_split(//u, ...)`, `mb_*` helpers, or grapheme-aware libraries Splits `str` into its constituent Unicode code points.
**JavaScript / Node.js:** `Array.from(str)` or iterator-based Unicode-aware splitting
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
+7 -6
View File
@@ -6,12 +6,13 @@ haystack : string to inspect
needle : suffix to compare against the end of `haystack` needle : suffix to compare against the end of `haystack`
return value : `true` when `haystack` ends with `needle`, otherwise `false` return value : `true` when `haystack` ends with `needle`, otherwise `false`
:desc
Checks whether `haystack` ends with the given suffix.
:see :see
>string >string
:related :content
**PHP:** `str_ends_with()` Checks whether `haystack` ends with `needle`.
**JavaScript / Node.js:** `String.prototype.endsWith()`
Related:
- PHP: `str_ends_with()`
- JavaScript / Node.js: `String.prototype.endsWith()`
+7 -6
View File
@@ -6,12 +6,13 @@ haystack : string to inspect
needle : prefix to compare against the start of `haystack` needle : prefix to compare against the start of `haystack`
return value : `true` when `haystack` begins with `needle`, otherwise `false` return value : `true` when `haystack` begins with `needle`, otherwise `false`
:desc
Checks whether `haystack` starts with the given prefix.
:see :see
>string >string
:related :content
**PHP:** `str_starts_with()` Checks whether `haystack` starts with `needle`.
**JavaScript / Node.js:** `String.prototype.startsWith()`
Related:
- PHP: `str_starts_with()`
- JavaScript / Node.js: `String.prototype.startsWith()`
+7 -6
View File
@@ -7,16 +7,17 @@ needle : substring to search for
offset : optional start offset; negative values count from the end of the string 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 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`. 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. 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. If `needle` is an empty string, `strpos()` returns the normalized start offset.
:see Related:
>string
:related - PHP: `strpos()`
**PHP:** `strpos()` - JavaScript / Node.js: `String.prototype.indexOf()`
**JavaScript / Node.js:** `String.prototype.indexOf()`
+7 -6
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 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 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. 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. 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. If `length` is negative, the returned range stops that many bytes before the end of the string.
:see Related:
>string
:related - PHP: `substr()`
**PHP:** `substr()` - JavaScript / Node.js: `String.prototype.slice()` or `substring()`
**JavaScript / Node.js:** `String.prototype.slice()` or `substring()`
+11 -6
View File
@@ -6,12 +6,17 @@ key : string uniquely identifying the task
exec_func : function to execute exec_func : function to execute
return value : the process ID of the started (or still running) task 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 :see
>task >task
:related :content
**PHP:** Background-process patterns using `proc_open()`, queues, cron, or worker supervisors Starts `exec_func` in a new process and returns that process ID.
**JavaScript / Node.js:** Node `child_process`, worker queues, timers, schedulers, and supervised background jobs
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
+11 -8
View File
@@ -6,14 +6,17 @@ pid : PID of the process
sig : signal number sig : signal number
return value : 0 if signal was sent, -1 otherwise 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 :see
>task >task
:related :content
**PHP:** Background-process patterns using `proc_open()`, queues, cron, or worker supervisors Wraps the standard POSIX `kill()` function.
**JavaScript / Node.js:** Node `child_process`, worker queues, timers, schedulers, and supervised background jobs
`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
+9 -6
View File
@@ -5,12 +5,15 @@ pid_t task_pid(String key)
key : string uniquely identifying the task key : string uniquely identifying the task
return value : the process ID of 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 :see
>task >task
:related :content
**PHP:** Background-process patterns using `proc_open()`, queues, cron, or worker supervisors Checks whether a process with the given `key` is running and returns its PID if it is.
**JavaScript / Node.js:** Node `child_process`, worker queues, timers, schedulers, and supervised background jobs
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
+11 -8
View File
@@ -8,14 +8,17 @@ exec_func : function to execute repeatedly
timeout : optional task timeout value timeout : optional task timeout value
return value : the process ID of the started (or still running) task 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 :see
>task >task
:related :content
**PHP:** Background-process patterns using `proc_open()`, queues, cron, or worker supervisors Starts a repeating background worker process.
**JavaScript / Node.js:** Node `child_process`, worker queues, timers, schedulers, and supervised background jobs
`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
+7 -6
View File
@@ -4,12 +4,13 @@ u64 time()
:params :params
return value : second-accurate current Unix timestamp return value : second-accurate current Unix timestamp
:desc
Returns a 64 bit integer containing the current Unix timestamp.
:see :see
>time >time
:related :content
**PHP:** `time()` Returns the current Unix timestamp as a 64-bit integer with second precision.
**JavaScript / Node.js:** `Math.floor(Date.now() / 1000)` or `Date.now()` depending on units
Related:
- PHP: `time()`
- JavaScript / Node.js: `Math.floor(Date.now() / 1000)` or `Date.now()` depending on units
+77 -130
View File
@@ -6,137 +6,84 @@ format : formatting string specifying the date format
timestamp : optional timestamp value, defaults to current time timestamp : optional timestamp value, defaults to current time
return value : a formatted date 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 :see
>time >time
>time_format_relative >time_format_relative
:related :content
**PHP:** `date()` and `DateTime` formatting in the server local timezone Formats a timestamp in the server's local timezone.
**JavaScript / Node.js:** `Intl.DateTimeFormat`, `Date#toLocaleString()`, or date libraries
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
+37 -38
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` format_not_recent : output format for older timestamps, defaults to `%deltaH hours ago`
return value : a formatted relative-time string 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 :see
>time >time
>time_format_local >time_format_local
>time_format_utc >time_format_utc
:related :content
**PHP:** `DateTimeImmutable` diff formatting or libraries such as Carbon `diffForHumans()` Formats a timestamp relative to the current time using the same formatting engine as `time_format_local()` and `time_format_utc()`.
**JavaScript / Node.js:** relative time helpers such as `Intl.RelativeTimeFormat`, `date-fns/formatDistanceToNow`, or Luxon
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
+77 -130
View File
@@ -6,137 +6,84 @@ format : formatting string specifying the date format
timestamp : optional timestamp value, defaults to current time timestamp : optional timestamp value, defaults to current time
return value : a formatted date 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 :see
>time >time
>time_format_relative >time_format_relative
:related :content
**PHP:** `gmdate()` and UTC `DateTime` formatting Formats a timestamp in the GMT/UTC timezone.
**JavaScript / Node.js:** `Date#toISOString()` and UTC formatting helpers
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
+7 -6
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 time_string : a string containing a date and/or time in text form
return value : the interpreted 'time_string' as a Unix timestamp return value : the interpreted 'time_string' as a Unix timestamp
:desc
Attempts to parse the given 'time_string' into a Unix timestamp.
:see :see
>time >time
:related :content
**PHP:** `strtotime()` or `DateTimeImmutable` parsing Attempts to parse `time_string` into a Unix timestamp.
**JavaScript / Node.js:** `Date.parse()` or date-library parsing helpers
Related:
- PHP: `strtotime()` or `DateTimeImmutable` parsing
- JavaScript / Node.js: `Date.parse()` or date-library parsing helpers
+7 -6
View File
@@ -4,12 +4,13 @@ f64 time_precise()
:params :params
return value : current Unix timestamp return value : current Unix timestamp
:desc
Returns a 64 bit float containing the current Unix timestamp with millisecond accuracy or better.
:see :see
>time >time
:related :content
**PHP:** `microtime(true)` or high-resolution timers Returns the current Unix timestamp as a 64-bit float with millisecond accuracy or better.
**JavaScript / Node.js:** `performance.now()` or high-resolution Node timers
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