f2ab12e65b
- checkout.el and main.el: replace raw import of el-html vessel with direct extern fn declarations; implementations come from dist/elhtml_impl.c (c_source) - Add src/elhtml.el as reference file (all el-html extern fn declarations; not imported) - dist/elhtml_impl.c: pre-compiled el-html vessel C (strips int main + sample global) - dist/page_close.c: pre-compiled page_close implementation; elc OOMs after emitting the ~71KB page_open body and silently drops page_close, so supply it as c_source - manifest.el: add elhtml_impl.c and page_close.c as c_source entries - .gitignore: un-ignore dist/elhtml_impl.c and dist/page_close.c
342 lines
14 KiB
C
342 lines
14 KiB
C
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include "el_runtime.h"
|
|
|
|
el_val_t el_escape(el_val_t s);
|
|
el_val_t el_text(el_val_t s);
|
|
el_val_t el_attr(el_val_t name, el_val_t value);
|
|
el_val_t el_div(el_val_t attrs, el_val_t children);
|
|
el_val_t el_section(el_val_t attrs, el_val_t children);
|
|
el_val_t el_article(el_val_t attrs, el_val_t children);
|
|
el_val_t el_header(el_val_t attrs, el_val_t children);
|
|
el_val_t el_footer(el_val_t attrs, el_val_t children);
|
|
el_val_t el_main(el_val_t attrs, el_val_t children);
|
|
el_val_t el_nav(el_val_t attrs, el_val_t children);
|
|
el_val_t el_aside(el_val_t attrs, el_val_t children);
|
|
el_val_t el_ul(el_val_t attrs, el_val_t children);
|
|
el_val_t el_ol(el_val_t attrs, el_val_t children);
|
|
el_val_t el_li(el_val_t attrs, el_val_t children);
|
|
el_val_t el_p(el_val_t attrs, el_val_t children);
|
|
el_val_t el_span(el_val_t attrs, el_val_t children);
|
|
el_val_t el_form(el_val_t attrs, el_val_t children);
|
|
el_val_t el_h1(el_val_t attrs, el_val_t text);
|
|
el_val_t el_h2(el_val_t attrs, el_val_t text);
|
|
el_val_t el_h3(el_val_t attrs, el_val_t text);
|
|
el_val_t el_h4(el_val_t attrs, el_val_t text);
|
|
el_val_t el_button(el_val_t attrs, el_val_t label);
|
|
el_val_t el_a(el_val_t href, el_val_t attrs, el_val_t children);
|
|
el_val_t el_input(el_val_t type_attr, el_val_t attrs);
|
|
el_val_t el_textarea(el_val_t attrs, el_val_t value);
|
|
el_val_t el_label(el_val_t for_id, el_val_t attrs, el_val_t children);
|
|
el_val_t el_img(el_val_t src, el_val_t alt, el_val_t attrs);
|
|
el_val_t el_video(el_val_t attrs, el_val_t children);
|
|
el_val_t el_strong(el_val_t children);
|
|
el_val_t el_em(el_val_t children);
|
|
el_val_t el_code(el_val_t children);
|
|
el_val_t el_pre(el_val_t attrs, el_val_t children);
|
|
el_val_t el_hr(void);
|
|
el_val_t el_br(void);
|
|
el_val_t el_html_doc(el_val_t lang, el_val_t head_html, el_val_t body_html);
|
|
el_val_t el_meta(el_val_t name, el_val_t content);
|
|
el_val_t el_meta_charset(el_val_t charset);
|
|
el_val_t el_link_stylesheet(el_val_t href);
|
|
el_val_t el_script_src(el_val_t src, el_val_t defer_load);
|
|
el_val_t el_script_inline(el_val_t js);
|
|
el_val_t el_title(el_val_t text);
|
|
|
|
|
|
el_val_t el_escape(el_val_t s) {
|
|
s = str_replace(s, EL_STR("&"), EL_STR("&"));
|
|
s = str_replace(s, EL_STR("<"), EL_STR("<"));
|
|
s = str_replace(s, EL_STR(">"), EL_STR(">"));
|
|
s = str_replace(s, EL_STR("\""), EL_STR("""));
|
|
return str_replace(s, EL_STR("'"), EL_STR("'"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_text(el_val_t s) {
|
|
return el_escape(s);
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_attr(el_val_t name, el_val_t value) {
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR(" "), name), EL_STR("=\"")), el_escape(value)), EL_STR("\""));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_div(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<div>"), children), EL_STR("</div>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<div "), attrs), EL_STR(">")), children), EL_STR("</div>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_section(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<section>"), children), EL_STR("</section>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<section "), attrs), EL_STR(">")), children), EL_STR("</section>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_article(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<article>"), children), EL_STR("</article>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<article "), attrs), EL_STR(">")), children), EL_STR("</article>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_header(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<header>"), children), EL_STR("</header>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<header "), attrs), EL_STR(">")), children), EL_STR("</header>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_footer(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<footer>"), children), EL_STR("</footer>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<footer "), attrs), EL_STR(">")), children), EL_STR("</footer>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_main(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<main>"), children), EL_STR("</main>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<main "), attrs), EL_STR(">")), children), EL_STR("</main>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_nav(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<nav>"), children), EL_STR("</nav>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<nav "), attrs), EL_STR(">")), children), EL_STR("</nav>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_aside(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<aside>"), children), EL_STR("</aside>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<aside "), attrs), EL_STR(">")), children), EL_STR("</aside>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_ul(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<ul>"), children), EL_STR("</ul>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<ul "), attrs), EL_STR(">")), children), EL_STR("</ul>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_ol(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<ol>"), children), EL_STR("</ol>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<ol "), attrs), EL_STR(">")), children), EL_STR("</ol>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_li(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<li>"), children), EL_STR("</li>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<li "), attrs), EL_STR(">")), children), EL_STR("</li>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_p(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<p>"), children), EL_STR("</p>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<p "), attrs), EL_STR(">")), children), EL_STR("</p>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_span(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<span>"), children), EL_STR("</span>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<span "), attrs), EL_STR(">")), children), EL_STR("</span>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_form(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<form>"), children), EL_STR("</form>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<form "), attrs), EL_STR(">")), children), EL_STR("</form>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_h1(el_val_t attrs, el_val_t text) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<h1>"), el_escape(text)), EL_STR("</h1>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<h1 "), attrs), EL_STR(">")), el_escape(text)), EL_STR("</h1>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_h2(el_val_t attrs, el_val_t text) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<h2>"), el_escape(text)), EL_STR("</h2>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<h2 "), attrs), EL_STR(">")), el_escape(text)), EL_STR("</h2>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_h3(el_val_t attrs, el_val_t text) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<h3>"), el_escape(text)), EL_STR("</h3>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<h3 "), attrs), EL_STR(">")), el_escape(text)), EL_STR("</h3>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_h4(el_val_t attrs, el_val_t text) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<h4>"), el_escape(text)), EL_STR("</h4>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<h4 "), attrs), EL_STR(">")), el_escape(text)), EL_STR("</h4>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_button(el_val_t attrs, el_val_t label) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<button type=\"button\">"), el_escape(label)), EL_STR("</button>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<button type=\"button\" "), attrs), EL_STR(">")), el_escape(label)), EL_STR("</button>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_a(el_val_t href, el_val_t attrs, el_val_t children) {
|
|
el_val_t h = el_str_concat(el_str_concat(EL_STR("href=\""), el_escape(href)), EL_STR("\""));
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<a "), h), EL_STR(">")), children), EL_STR("</a>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<a "), h), EL_STR(" ")), attrs), EL_STR(">")), children), EL_STR("</a>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_input(el_val_t type_attr, el_val_t attrs) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<input type=\""), type_attr), EL_STR("\" />"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<input type=\""), type_attr), EL_STR("\" ")), attrs), EL_STR(" />"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_textarea(el_val_t attrs, el_val_t value) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<textarea>"), el_escape(value)), EL_STR("</textarea>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<textarea "), attrs), EL_STR(">")), el_escape(value)), EL_STR("</textarea>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_label(el_val_t for_id, el_val_t attrs, el_val_t children) {
|
|
el_val_t f = el_str_concat(el_str_concat(EL_STR("for=\""), el_escape(for_id)), EL_STR("\""));
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<label "), f), EL_STR(">")), children), EL_STR("</label>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<label "), f), EL_STR(" ")), attrs), EL_STR(">")), children), EL_STR("</label>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_img(el_val_t src, el_val_t alt, el_val_t attrs) {
|
|
el_val_t base = el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("src=\""), el_escape(src)), EL_STR("\" alt=\"")), el_escape(alt)), EL_STR("\""));
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<img "), base), EL_STR(" />"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<img "), base), EL_STR(" ")), attrs), EL_STR(" />"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_video(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<video>"), children), EL_STR("</video>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<video "), attrs), EL_STR(">")), children), EL_STR("</video>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_strong(el_val_t children) {
|
|
return el_str_concat(el_str_concat(EL_STR("<strong>"), children), EL_STR("</strong>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_em(el_val_t children) {
|
|
return el_str_concat(el_str_concat(EL_STR("<em>"), children), EL_STR("</em>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_code(el_val_t children) {
|
|
return el_str_concat(el_str_concat(EL_STR("<code>"), children), EL_STR("</code>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_pre(el_val_t attrs, el_val_t children) {
|
|
if (str_eq(attrs, EL_STR(""))) {
|
|
return el_str_concat(el_str_concat(EL_STR("<pre>"), children), EL_STR("</pre>"));
|
|
}
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<pre "), attrs), EL_STR(">")), children), EL_STR("</pre>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_hr(void) {
|
|
return EL_STR("<hr />");
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_br(void) {
|
|
return EL_STR("<br />");
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_html_doc(el_val_t lang, el_val_t head_html, el_val_t body_html) {
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<!doctype html><html lang=\""), el_escape(lang)), EL_STR("\"><head>")), head_html), EL_STR("</head><body>")), body_html), EL_STR("</body></html>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_meta(el_val_t name, el_val_t content) {
|
|
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("<meta name=\""), el_escape(name)), EL_STR("\" content=\"")), el_escape(content)), EL_STR("\" />"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_meta_charset(el_val_t charset) {
|
|
return el_str_concat(el_str_concat(EL_STR("<meta charset=\""), el_escape(charset)), EL_STR("\" />"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_link_stylesheet(el_val_t href) {
|
|
return el_str_concat(el_str_concat(EL_STR("<link rel=\"stylesheet\" href=\""), el_escape(href)), EL_STR("\" />"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_script_src(el_val_t src, el_val_t defer_load) {
|
|
if (defer_load) {
|
|
return el_str_concat(el_str_concat(EL_STR("<script src=\""), el_escape(src)), EL_STR("\" defer></script>"));
|
|
}
|
|
return el_str_concat(el_str_concat(EL_STR("<script src=\""), el_escape(src)), EL_STR("\"></script>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_script_inline(el_val_t js) {
|
|
return el_str_concat(el_str_concat(EL_STR("<script>"), js), EL_STR("</script>"));
|
|
return 0;
|
|
}
|
|
|
|
el_val_t el_title(el_val_t text) {
|
|
return el_str_concat(el_str_concat(EL_STR("<title>"), el_escape(text)), EL_STR("</title>"));
|
|
return 0;
|
|
}
|
|
|
|
|