299 lines
6.6 KiB
Plaintext
299 lines
6.6 KiB
Plaintext
#include "lib/doc_page.h"
|
|
|
|
void render_doc_page_link(String page, String label = "", String badge = "")
|
|
{
|
|
page = trim(page);
|
|
if(page == "")
|
|
return;
|
|
if(label == "")
|
|
label = doc_index_label(page);
|
|
if(badge == "")
|
|
badge = doc_page_kind_badge(doc_page_kind(page));
|
|
|
|
?><a href="index.uce?p=<?= uri_encode(page) ?>"><?= label ?><?
|
|
if(badge != "")
|
|
{
|
|
?><span class="badge"><?= badge ?></span><?
|
|
}
|
|
else
|
|
{
|
|
?><span class="dim">()</span><?
|
|
}
|
|
?></a><?
|
|
}
|
|
|
|
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></>
|
|
}
|
|
|
|
String doc_example_path(String page, u64 idx)
|
|
{
|
|
return("examples/_gen/" + page + "_" + std::to_string(idx + 1) + ".uce");
|
|
}
|
|
|
|
String doc_example_unit_source(String body)
|
|
{
|
|
return("RENDER(Request& context)\n{\n" + body + "\n}\n");
|
|
}
|
|
|
|
bool doc_write_if_changed(String path, String content)
|
|
{
|
|
if(file_exists(path) && file_get_contents(path) == content)
|
|
return(true);
|
|
return(file_put_contents(path, content));
|
|
}
|
|
|
|
String doc_render_example_output(String page, u64 idx, String body)
|
|
{
|
|
String path = doc_example_path(page, idx);
|
|
String unit_source = doc_example_unit_source(body);
|
|
if(!doc_write_if_changed(path, unit_source))
|
|
return("DOC EXAMPLE ERROR: could not write " + path);
|
|
if(!unit_compile(path))
|
|
return("DOC EXAMPLE ERROR: unit_compile failed for " + path);
|
|
|
|
ob_start();
|
|
unit_render(path);
|
|
String out = ob_get_close();
|
|
if(out == "")
|
|
return("DOC EXAMPLE ERROR: example produced no output");
|
|
return(out);
|
|
}
|
|
|
|
void render_doc_examples(String page, StringList example_blocks)
|
|
{
|
|
for(u64 idx = 0; idx < example_blocks.size(); idx++)
|
|
{
|
|
String body = example_blocks[idx];
|
|
String output = doc_render_example_output(page, idx, body);
|
|
?><div class="doc-section example">
|
|
<h3>Example</h3>
|
|
<pre class="example-source"><?= body ?></pre>
|
|
<div class="example-output">
|
|
<div class="example-output-label">Output</div>
|
|
<pre><?= output ?></pre>
|
|
</div>
|
|
</div><?
|
|
}
|
|
}
|
|
|
|
void render_see_section(String name)
|
|
{
|
|
StringList lines = split(file_get_contents("areas/" + name + ".txt"), "\n");
|
|
s32 idx = 0;
|
|
for(auto line : lines)
|
|
{
|
|
line = trim(line);
|
|
if(line == "")
|
|
{
|
|
idx += 1;
|
|
continue;
|
|
}
|
|
if(idx == 0)
|
|
{
|
|
<><div class="category"><h3><?= line ?></h3><ul></>
|
|
}
|
|
else
|
|
{
|
|
?><li><? render_doc_page_link(line); ?></li><?
|
|
}
|
|
idx += 1;
|
|
}
|
|
<></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] == '>')
|
|
{
|
|
String target = trim(sl.substr(1));
|
|
if(doc_has_area(target))
|
|
{
|
|
render_see_section(target);
|
|
}
|
|
else if(doc_has_page(target))
|
|
{
|
|
?><div><? render_doc_page_link(target); ?></div><?
|
|
}
|
|
}
|
|
else
|
|
{
|
|
?><div><? render_doc_page_link(trim(sl)); ?></div><?
|
|
}
|
|
}
|
|
?>
|
|
</>
|
|
}
|
|
|
|
|
|
RENDER(Request& context)
|
|
{
|
|
String page = first(context.get["p"], "index");
|
|
DocPage doc_page;
|
|
String page_title = doc_default_title(page);
|
|
if(page != "index")
|
|
{
|
|
doc_page = load_doc_page(page);
|
|
if(doc_page.title != "")
|
|
page_title = doc_page.title;
|
|
}
|
|
|
|
<><html>
|
|
<head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"></meta>
|
|
<link rel="stylesheet" href='style.css?v=<?= time() ?>'></link>
|
|
</head>
|
|
<body>
|
|
<h1>
|
|
<a href="index.uce">UCE Docs</a><?
|
|
if(page != "index")
|
|
{
|
|
?><span class="dim"> / </span><?= page_title ?><?
|
|
}
|
|
?>
|
|
</h1>
|
|
<?
|
|
|
|
if(page == "index")
|
|
{
|
|
?><div class="search-bar">
|
|
<input id="doc-search" type="search" placeholder="Search API…" autocomplete="off" spellcheck="false"/>
|
|
<span class="search-count" id="search-count"></span>
|
|
</div>
|
|
<div id="search-results" hidden></div>
|
|
<div class="index-pane" id="index-pane">
|
|
<div class="index-layout">
|
|
<nav class="sidebar"><?
|
|
for(auto file_name : ls("areas/"))
|
|
{
|
|
String ft = nibble(file_name, ".");
|
|
render_see_section(ft);
|
|
}
|
|
?></nav>
|
|
<main class="content">
|
|
<h2>All API Functions</h2>
|
|
<div class="func-grid"><?
|
|
for(auto file_name : ls("pages/"))
|
|
{
|
|
String ft = nibble(file_name, ".");
|
|
String label = doc_index_label(ft);
|
|
String badge = doc_page_kind_badge(doc_page_kind(ft));
|
|
?><div class="func-item"><? render_doc_page_link(ft, label, badge); ?></div><?
|
|
}
|
|
?></div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
<?
|
|
<><script>
|
|
(function () {
|
|
var input = document.getElementById('doc-search');
|
|
var results = document.getElementById('search-results');
|
|
var pane = document.getElementById('index-pane');
|
|
var counter = document.getElementById('search-count');
|
|
var timer;
|
|
|
|
function showResults(html) {
|
|
results.innerHTML = html;
|
|
results.hidden = false;
|
|
pane.hidden = true;
|
|
var hits = results.querySelectorAll('.search-hit').length;
|
|
counter.textContent = hits ? hits + ' result' + (hits > 1 ? 's' : '') : '';
|
|
}
|
|
|
|
function showIndex() {
|
|
results.innerHTML = '';
|
|
results.hidden = true;
|
|
pane.hidden = false;
|
|
counter.textContent = '';
|
|
}
|
|
|
|
input.addEventListener('input', function () {
|
|
var q = this.value.trim();
|
|
clearTimeout(timer);
|
|
if (q.length < 2) { showIndex(); return; }
|
|
counter.textContent = '\u2026';
|
|
timer = setTimeout(function () {
|
|
fetch('search.uce?q=' + encodeURIComponent(q))
|
|
.then(function (r) { return r.text(); })
|
|
.then(showResults);
|
|
}, 220);
|
|
});
|
|
|
|
input.addEventListener('keydown', function (e) {
|
|
if (e.key === 'Escape') { this.value = ''; showIndex(); }
|
|
});
|
|
})();
|
|
</script></>
|
|
}
|
|
else
|
|
{
|
|
String detail_class = "detail-layout";
|
|
if(doc_page.see_lines.size() == 0)
|
|
detail_class += " no-sidebar";
|
|
|
|
?><div class="<?= detail_class ?>">
|
|
<article class="doc-detail"><?
|
|
|
|
if(doc_page.sig_lines.size() > 0)
|
|
{
|
|
?><div class="doc-section sig">
|
|
<h3>Signature</h3>
|
|
<pre><? print(join(doc_page.sig_lines, "\n")); ?></pre>
|
|
</div><?
|
|
}
|
|
|
|
render_doc_params(doc_page.param_lines);
|
|
|
|
if(trim(doc_page.content) != "")
|
|
{
|
|
?><div class="doc-section content"><?: markdown_to_html(doc_page.content) ?></div><?
|
|
}
|
|
|
|
render_doc_examples(page, doc_page.example_blocks);
|
|
|
|
?></article><?
|
|
|
|
if(doc_page.see_lines.size() > 0)
|
|
{
|
|
?><aside class="detail-sidebar">
|
|
<div class="sidebar-card"><?
|
|
render_doc_see_links(doc_page.see_lines);
|
|
?></div>
|
|
</aside><?
|
|
}
|
|
|
|
?></div><?
|
|
}
|
|
|
|
?>
|
|
</body>
|
|
</html></>
|
|
}
|