HTML5
This commit is contained in:
@@ -138,6 +138,8 @@ HELP_TEXT :: `Usage:
|
|||||||
If there is no file provided, TypoML reads from stdin.
|
If there is no file provided, TypoML reads from stdin.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
--html Output HTML5 (default)
|
||||||
|
--html4, --html-4 Output HTML4
|
||||||
--title <text> Set the HTML document title (default: "TypoML")
|
--title <text> Set the HTML document title (default: "TypoML")
|
||||||
--plain Don't wrap the output in <html>, <head>, <body> and <style> tags
|
--plain Don't wrap the output in <html>, <head>, <body> and <style> tags
|
||||||
--no-js Don't include the JavaScript variable proxy (<script>)
|
--no-js Don't include the JavaScript variable proxy (<script>)
|
||||||
@@ -166,6 +168,10 @@ parse_args :: proc(args: []string) -> (files: [dynamic]string, flags: renderer.D
|
|||||||
}
|
}
|
||||||
case "--print-tree":
|
case "--print-tree":
|
||||||
flags.print_tree = true
|
flags.print_tree = true
|
||||||
|
case "--html":
|
||||||
|
flags.mode = .HTML5
|
||||||
|
case "--html4", "--html-4":
|
||||||
|
flags.mode = .HTML4
|
||||||
case:
|
case:
|
||||||
if strings.has_prefix(arg, "--") {
|
if strings.has_prefix(arg, "--") {
|
||||||
fmt.eprintf("typoml: unknown option '%s'\n", arg)
|
fmt.eprintf("typoml: unknown option '%s'\n", arg)
|
||||||
|
|||||||
@@ -5,47 +5,47 @@ import "../token"
|
|||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
|
|
||||||
render_aligned_cell :: proc(tok: ^token.Token, tag: string) {
|
html4_render_aligned_cell :: proc(tok: ^token.Token, tag: string) {
|
||||||
align := get_alignment_attribute(tok)
|
align := get_alignment_attribute(tok)
|
||||||
if align != "" {
|
if align != "" {
|
||||||
fmt.printf("<%s align=\"%s\">", tag, align)
|
fmt.printf("<%s align=\"%s\">", tag, align)
|
||||||
for child in tok.children[0].children {
|
for child in tok.children[0].children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.printf("<%s>", tag)
|
fmt.printf("<%s>", tag)
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.printf("</%s>", tag)
|
fmt.printf("</%s>", tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
render_simple_wrapper :: proc(tok: ^token.Token, tag: string) {
|
html4_render_simple_wrapper :: proc(tok: ^token.Token, tag: string) {
|
||||||
fmt.printf("<%s>", tag)
|
fmt.printf("<%s>", tag)
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.printf("</%s>", tag)
|
fmt.printf("</%s>", tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
render_div_wrapper :: proc(tok: ^token.Token, align: string) {
|
html4_render_div_wrapper :: proc(tok: ^token.Token, align: string) {
|
||||||
fmt.printf("<div align=\"%s\">", align)
|
fmt.printf("<div align=\"%s\">", align)
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</div>")
|
fmt.print("</div>")
|
||||||
}
|
}
|
||||||
|
|
||||||
render_container :: proc(tok: ^token.Token, tag: string) {
|
html4_render_container :: proc(tok: ^token.Token, tag: string) {
|
||||||
fmt.printf("<%s>\n", tag)
|
fmt.printf("<%s>\n", tag)
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.printf("</%s>\n", tag)
|
fmt.printf("</%s>\n", tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
render_media_object :: proc(tok: ^token.Token, mime_type: string) {
|
html4_render_media_object :: proc(tok: ^token.Token, mime_type: string) {
|
||||||
url, ok := tok.value.(string)
|
url, ok := tok.value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
@@ -66,7 +66,7 @@ render_media_object :: proc(tok: ^token.Token, mime_type: string) {
|
|||||||
fmt.print("</object>\n")
|
fmt.print("</object>\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
TEMPLATE_PROXY_SCRIPT :: `
|
HTML4_TEMPLATE_PROXY_SCRIPT :: `
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
var defs = {};
|
var defs = {};
|
||||||
@@ -95,10 +95,10 @@ TEMPLATE_PROXY_SCRIPT :: `
|
|||||||
})();
|
})();
|
||||||
</script>`
|
</script>`
|
||||||
|
|
||||||
print_document :: proc(root: ^token.Token, flags: DocumentFlags) {
|
print_html4_document :: proc(root: ^token.Token, flags: DocumentFlags) {
|
||||||
if flags.plain {
|
if flags.plain {
|
||||||
for child in root.children {
|
for child in root.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -119,23 +119,16 @@ print_document :: proc(root: ^token.Token, flags: DocumentFlags) {
|
|||||||
style,
|
style,
|
||||||
)
|
)
|
||||||
for child in root.children {
|
for child in root.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
if !flags.no_js {
|
if !flags.no_js {
|
||||||
fmt.print("\n" + TEMPLATE_PROXY_SCRIPT + "\n")
|
fmt.print("\n" + HTML4_TEMPLATE_PROXY_SCRIPT + "\n")
|
||||||
}
|
}
|
||||||
fmt.print("</body></html>\n")
|
fmt.print("</body></html>\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
DocumentFlags :: struct {
|
|
||||||
plain: bool,
|
|
||||||
no_js: bool,
|
|
||||||
title: string,
|
|
||||||
print_tree: bool,
|
|
||||||
help: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
print_html :: proc(tok: ^token.Token) {
|
print_html4 :: proc(tok: ^token.Token) {
|
||||||
switch tok.type {
|
switch tok.type {
|
||||||
case token.TokenType.Root:
|
case token.TokenType.Root:
|
||||||
has_footnotes := false
|
has_footnotes := false
|
||||||
@@ -144,7 +137,7 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
fmt.print("<hr class=\"footnotes-sep\">\n")
|
fmt.print("<hr class=\"footnotes-sep\">\n")
|
||||||
has_footnotes = true
|
has_footnotes = true
|
||||||
}
|
}
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
|
|
||||||
case token.TokenType.Header:
|
case token.TokenType.Header:
|
||||||
@@ -161,7 +154,7 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
|
|
||||||
fmt.printf("<h%d id=\"%s\">", level, escape_html(slug))
|
fmt.printf("<h%d id=\"%s\">", level, escape_html(slug))
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.printf("</h%d>\n", level)
|
fmt.printf("</h%d>\n", level)
|
||||||
|
|
||||||
@@ -170,73 +163,73 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
if !only_var_defs {
|
if !only_var_defs {
|
||||||
fmt.print("<p>")
|
fmt.print("<p>")
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</p>\n")
|
fmt.print("</p>\n")
|
||||||
} else {
|
} else {
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
if child.type != .BreakLine {
|
if child.type != .BreakLine {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case token.TokenType.Blockquote:
|
case token.TokenType.Blockquote:
|
||||||
render_container(tok, "blockquote")
|
html4_render_container(tok, "blockquote")
|
||||||
|
|
||||||
case token.TokenType.UnorderedList:
|
case token.TokenType.UnorderedList:
|
||||||
render_container(tok, "ul")
|
html4_render_container(tok, "ul")
|
||||||
|
|
||||||
case token.TokenType.OrderedList:
|
case token.TokenType.OrderedList:
|
||||||
render_container(tok, "ol")
|
html4_render_container(tok, "ol")
|
||||||
|
|
||||||
case token.TokenType.ListItem:
|
case token.TokenType.ListItem:
|
||||||
fmt.print("<li>")
|
fmt.print("<li>")
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</li>\n")
|
fmt.print("</li>\n")
|
||||||
|
|
||||||
case token.TokenType.Bold:
|
case token.TokenType.Bold:
|
||||||
render_simple_wrapper(tok, "strong")
|
html4_render_simple_wrapper(tok, "strong")
|
||||||
|
|
||||||
case token.TokenType.Italics:
|
case token.TokenType.Italics:
|
||||||
render_simple_wrapper(tok, "em")
|
html4_render_simple_wrapper(tok, "em")
|
||||||
|
|
||||||
case token.TokenType.Strikethrough:
|
case token.TokenType.Strikethrough:
|
||||||
render_simple_wrapper(tok, "strike")
|
html4_render_simple_wrapper(tok, "strike")
|
||||||
|
|
||||||
case token.TokenType.Table:
|
case token.TokenType.Table:
|
||||||
render_container(tok, "table")
|
html4_render_container(tok, "table")
|
||||||
|
|
||||||
case token.TokenType.TableHeaderRow:
|
case token.TokenType.TableHeaderRow:
|
||||||
fmt.print("<tr>")
|
fmt.print("<tr>")
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
render_aligned_cell(child, "th")
|
html4_render_aligned_cell(child, "th")
|
||||||
}
|
}
|
||||||
fmt.print("</tr>\n")
|
fmt.print("</tr>\n")
|
||||||
|
|
||||||
case token.TokenType.TableRow:
|
case token.TokenType.TableRow:
|
||||||
fmt.print("<tr>")
|
fmt.print("<tr>")
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</tr>\n")
|
fmt.print("</tr>\n")
|
||||||
|
|
||||||
case token.TokenType.TableCell:
|
case token.TokenType.TableCell:
|
||||||
render_aligned_cell(tok, "td")
|
html4_render_aligned_cell(tok, "td")
|
||||||
|
|
||||||
case token.TokenType.TableSeparator:
|
case token.TokenType.TableSeparator:
|
||||||
fmt.print("<tr class=\"table-sep\"><td colspan=\"100\"></td></tr>\n")
|
fmt.print("<tr class=\"table-sep\"><td colspan=\"100\"></td></tr>\n")
|
||||||
|
|
||||||
case token.TokenType.Left:
|
case token.TokenType.Left:
|
||||||
render_div_wrapper(tok, "left")
|
html4_render_div_wrapper(tok, "left")
|
||||||
|
|
||||||
case token.TokenType.Right:
|
case token.TokenType.Right:
|
||||||
render_div_wrapper(tok, "right")
|
html4_render_div_wrapper(tok, "right")
|
||||||
|
|
||||||
case token.TokenType.Middle:
|
case token.TokenType.Middle:
|
||||||
render_div_wrapper(tok, "center")
|
html4_render_div_wrapper(tok, "center")
|
||||||
|
|
||||||
case token.TokenType.FootnoteRef:
|
case token.TokenType.FootnoteRef:
|
||||||
if id, ok := tok.value.(string); ok {
|
if id, ok := tok.value.(string); ok {
|
||||||
@@ -256,7 +249,7 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
escape_html(id),
|
escape_html(id),
|
||||||
)
|
)
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</div>\n")
|
fmt.print("</div>\n")
|
||||||
}
|
}
|
||||||
@@ -272,7 +265,7 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
fmt.print("<pre><code>")
|
fmt.print("<pre><code>")
|
||||||
}
|
}
|
||||||
for i := 0; i < len(tok.children); i += 1 {
|
for i := 0; i < len(tok.children); i += 1 {
|
||||||
print_html(tok.children[i])
|
print_html4(tok.children[i])
|
||||||
if i + 1 < len(tok.children) {
|
if i + 1 < len(tok.children) {
|
||||||
fmt.print("\n")
|
fmt.print("\n")
|
||||||
}
|
}
|
||||||
@@ -290,21 +283,21 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
case token.TokenType.Underline:
|
case token.TokenType.Underline:
|
||||||
fmt.print("<u>")
|
fmt.print("<u>")
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</u>")
|
fmt.print("</u>")
|
||||||
|
|
||||||
case token.TokenType.Superscript:
|
case token.TokenType.Superscript:
|
||||||
fmt.print("<sup>")
|
fmt.print("<sup>")
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</sup>")
|
fmt.print("</sup>")
|
||||||
|
|
||||||
case token.TokenType.Subscript:
|
case token.TokenType.Subscript:
|
||||||
fmt.print("<sub>")
|
fmt.print("<sub>")
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</sub>")
|
fmt.print("</sub>")
|
||||||
|
|
||||||
@@ -313,7 +306,7 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
slug := slugifyifyifyify(target)
|
slug := slugifyifyifyify(target)
|
||||||
fmt.printf("<a href=\"#%s\">", escape_html(slug))
|
fmt.printf("<a href=\"#%s\">", escape_html(slug))
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</a>")
|
fmt.print("</a>")
|
||||||
}
|
}
|
||||||
@@ -322,7 +315,7 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
if url, ok := tok.value.(string); ok {
|
if url, ok := tok.value.(string); ok {
|
||||||
fmt.printf("<a href=\"%s\">", escape_html(url))
|
fmt.printf("<a href=\"%s\">", escape_html(url))
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</a>")
|
fmt.print("</a>")
|
||||||
}
|
}
|
||||||
@@ -339,12 +332,12 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
|
|
||||||
case token.TokenType.Audio:
|
case token.TokenType.Audio:
|
||||||
if url, ok := tok.value.(string); ok {
|
if url, ok := tok.value.(string); ok {
|
||||||
render_media_object(tok, mime.detect_mime_type(url))
|
html4_render_media_object(tok, mime.detect_mime_type(url))
|
||||||
}
|
}
|
||||||
|
|
||||||
case token.TokenType.Video:
|
case token.TokenType.Video:
|
||||||
if url, ok := tok.value.(string); ok {
|
if url, ok := tok.value.(string); ok {
|
||||||
render_media_object(tok, mime.detect_mime_type(url))
|
html4_render_media_object(tok, mime.detect_mime_type(url))
|
||||||
}
|
}
|
||||||
|
|
||||||
case token.TokenType.Iframe:
|
case token.TokenType.Iframe:
|
||||||
@@ -366,7 +359,7 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
if name, ok := tok.value.(string); ok {
|
if name, ok := tok.value.(string); ok {
|
||||||
fmt.printf("<span data-tlm-var=\"%s\">", escape_html(name))
|
fmt.printf("<span data-tlm-var=\"%s\">", escape_html(name))
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
fmt.print("</span>")
|
fmt.print("</span>")
|
||||||
}
|
}
|
||||||
@@ -393,7 +386,7 @@ print_html :: proc(tok: ^token.Token) {
|
|||||||
fmt.print(escape_html(v))
|
fmt.print(escape_html(v))
|
||||||
}
|
}
|
||||||
for child in tok.children {
|
for child in tok.children {
|
||||||
print_html(child)
|
print_html4(child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,392 @@
|
|||||||
|
package renderer
|
||||||
|
|
||||||
|
import "../mime"
|
||||||
|
import "../token"
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strings"
|
||||||
|
|
||||||
|
html5_render_aligned_cell :: proc(tok: ^token.Token, tag: string) {
|
||||||
|
align := get_alignment_attribute(tok)
|
||||||
|
if align != "" {
|
||||||
|
fmt.printf("<%s style=\"text-align: %s\">", tag, align)
|
||||||
|
for child in tok.children[0].children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.printf("<%s>", tag)
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.printf("</%s>", tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
html5_render_simple_wrapper :: proc(tok: ^token.Token, tag: string) {
|
||||||
|
fmt.printf("<%s>", tag)
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.printf("</%s>", tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
html5_render_div_wrapper :: proc(tok: ^token.Token, align: string) {
|
||||||
|
fmt.printf("<div style=\"text-align: %s\">", align)
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</div>")
|
||||||
|
}
|
||||||
|
|
||||||
|
html5_render_container :: proc(tok: ^token.Token, tag: string) {
|
||||||
|
fmt.printf("<%s>\n", tag)
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.printf("</%s>\n", tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
html5_render_media_object :: proc(tok: ^token.Token, mime_type: string) {
|
||||||
|
url, ok := tok.value.(string)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b := strings.builder_make(context.temp_allocator)
|
||||||
|
for child in tok.children {
|
||||||
|
get_text_content(child, &b)
|
||||||
|
}
|
||||||
|
alt_text := strings.to_string(b)
|
||||||
|
if alt_text == "" {
|
||||||
|
alt_text = url
|
||||||
|
}
|
||||||
|
fmt.printf("<object data=\"%s\" type=\"%s\">\n", escape_html(url), escape_html(mime_type))
|
||||||
|
fmt.printf("<param name=\"src\" value=\"%s\">\n", escape_html(url))
|
||||||
|
fmt.printf("<param name=\"autoplay\" value=\"false\">\n")
|
||||||
|
fmt.printf("<param name=\"controller\" value=\"true\">\n")
|
||||||
|
fmt.printf("<a href=\"%s\">%s</a>\n", escape_html(url), escape_html(alt_text))
|
||||||
|
fmt.print("</object>\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
HTML5_TEMPLATE_PROXY_SCRIPT :: `
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
var defs = {};
|
||||||
|
var spans = document.querySelectorAll("[data-tlm-def]");
|
||||||
|
for (var i = 0; i < spans.length; i++) {
|
||||||
|
var el = spans[i];
|
||||||
|
defs[el.dataset.tlmDef] = el.dataset.tlmValue;
|
||||||
|
}
|
||||||
|
var tlm = new Proxy({}, {
|
||||||
|
get: function (_, name) {
|
||||||
|
return defs[name];
|
||||||
|
},
|
||||||
|
set: function (_, name, value) {
|
||||||
|
defs[name] = value;
|
||||||
|
var refs = document.querySelectorAll("[data-tlm-var=\"" + name + "\"]");
|
||||||
|
for (var i = 0; i < refs.length; i++) {
|
||||||
|
refs[i].textContent = value;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
ownKeys: function () {
|
||||||
|
return Object.keys(defs);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
window.tlm = tlm;
|
||||||
|
})();
|
||||||
|
</script>`
|
||||||
|
|
||||||
|
print_html5_document :: proc(root: ^token.Token, flags: DocumentFlags) {
|
||||||
|
if flags.plain {
|
||||||
|
for child in root.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
doctype := "<!DOCTYPE html>"
|
||||||
|
meta := "<meta charset=\"utf-8\">"
|
||||||
|
style := "<style>" + DEFAULT_STYLE + "</style>"
|
||||||
|
title := flags.title
|
||||||
|
if title == "" {
|
||||||
|
title = "TypoML"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.printf(
|
||||||
|
"%s\n<html><head><title>%s</title>%s%s</head>\n<body>\n",
|
||||||
|
doctype,
|
||||||
|
escape_html(title),
|
||||||
|
meta,
|
||||||
|
style,
|
||||||
|
)
|
||||||
|
for child in root.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
if !flags.no_js {
|
||||||
|
fmt.print("\n" + HTML5_TEMPLATE_PROXY_SCRIPT + "\n")
|
||||||
|
}
|
||||||
|
fmt.print("</body></html>\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
print_html5 :: proc(tok: ^token.Token) {
|
||||||
|
switch tok.type {
|
||||||
|
case token.TokenType.Root:
|
||||||
|
has_footnotes := false
|
||||||
|
for child in tok.children {
|
||||||
|
if child.type == .FootnoteDef && !has_footnotes {
|
||||||
|
fmt.print("<hr class=\"footnotes-sep\">\n")
|
||||||
|
has_footnotes = true
|
||||||
|
}
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.Header:
|
||||||
|
level := 1
|
||||||
|
if v, ok := tok.value.(int); ok {
|
||||||
|
level = v
|
||||||
|
}
|
||||||
|
|
||||||
|
b := strings.builder_make(context.temp_allocator)
|
||||||
|
for child in tok.children {
|
||||||
|
get_text_content(child, &b)
|
||||||
|
}
|
||||||
|
slug := slugifyifyifyify(strings.to_string(b))
|
||||||
|
|
||||||
|
fmt.printf("<h%d id=\"%s\">", level, escape_html(slug))
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.printf("</h%d>\n", level)
|
||||||
|
|
||||||
|
case token.TokenType.Paragraph:
|
||||||
|
only_var_defs := check_only_var_defs(tok)
|
||||||
|
if !only_var_defs {
|
||||||
|
fmt.print("<p>")
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</p>\n")
|
||||||
|
} else {
|
||||||
|
for child in tok.children {
|
||||||
|
if child.type != .BreakLine {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.Blockquote:
|
||||||
|
html5_render_container(tok, "blockquote")
|
||||||
|
|
||||||
|
case token.TokenType.UnorderedList:
|
||||||
|
html5_render_container(tok, "ul")
|
||||||
|
|
||||||
|
case token.TokenType.OrderedList:
|
||||||
|
html5_render_container(tok, "ol")
|
||||||
|
|
||||||
|
case token.TokenType.ListItem:
|
||||||
|
fmt.print("<li>")
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</li>\n")
|
||||||
|
|
||||||
|
case token.TokenType.Bold:
|
||||||
|
html5_render_simple_wrapper(tok, "strong")
|
||||||
|
|
||||||
|
case token.TokenType.Italics:
|
||||||
|
html5_render_simple_wrapper(tok, "em")
|
||||||
|
|
||||||
|
case token.TokenType.Strikethrough:
|
||||||
|
html5_render_simple_wrapper(tok, "strike")
|
||||||
|
|
||||||
|
case token.TokenType.Table:
|
||||||
|
html5_render_container(tok, "table")
|
||||||
|
|
||||||
|
case token.TokenType.TableHeaderRow:
|
||||||
|
fmt.print("<tr>")
|
||||||
|
for child in tok.children {
|
||||||
|
html5_render_aligned_cell(child, "th")
|
||||||
|
}
|
||||||
|
fmt.print("</tr>\n")
|
||||||
|
|
||||||
|
case token.TokenType.TableRow:
|
||||||
|
fmt.print("<tr>")
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</tr>\n")
|
||||||
|
|
||||||
|
case token.TokenType.TableCell:
|
||||||
|
html5_render_aligned_cell(tok, "td")
|
||||||
|
|
||||||
|
case token.TokenType.TableSeparator:
|
||||||
|
fmt.print("<tr class=\"table-sep\"><td colspan=\"100\"></td></tr>\n")
|
||||||
|
|
||||||
|
case token.TokenType.Left:
|
||||||
|
html5_render_div_wrapper(tok, "left")
|
||||||
|
|
||||||
|
case token.TokenType.Right:
|
||||||
|
html5_render_div_wrapper(tok, "right")
|
||||||
|
|
||||||
|
case token.TokenType.Middle:
|
||||||
|
html5_render_div_wrapper(tok, "center")
|
||||||
|
|
||||||
|
case token.TokenType.FootnoteRef:
|
||||||
|
if id, ok := tok.value.(string); ok {
|
||||||
|
fmt.printf(
|
||||||
|
"<a href=\"#fn-%s\" id=\"ref-%s\"><sup>%s</sup></a>",
|
||||||
|
escape_html(id),
|
||||||
|
escape_html(id),
|
||||||
|
escape_html(id),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.FootnoteDef:
|
||||||
|
if id, ok := tok.value.(string); ok {
|
||||||
|
fmt.printf(
|
||||||
|
"<div class=\"footnote\" id=\"fn-%s\"><a href=\"#ref-%s\">^</a> ",
|
||||||
|
escape_html(id),
|
||||||
|
escape_html(id),
|
||||||
|
)
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</div>\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.CodeBlock:
|
||||||
|
lang := ""
|
||||||
|
if v, ok := tok.value.(string); ok && v != "" {
|
||||||
|
lang = v
|
||||||
|
}
|
||||||
|
if lang != "" {
|
||||||
|
fmt.printf("<pre><code class=\"lang-%s\">", lang)
|
||||||
|
} else {
|
||||||
|
fmt.print("<pre><code>")
|
||||||
|
}
|
||||||
|
for i := 0; i < len(tok.children); i += 1 {
|
||||||
|
print_html5(tok.children[i])
|
||||||
|
if i + 1 < len(tok.children) {
|
||||||
|
fmt.print("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.print("\n</code></pre>\n")
|
||||||
|
|
||||||
|
case token.TokenType.InlineCode:
|
||||||
|
if code, ok := tok.value.(string); ok {
|
||||||
|
fmt.printf("<code>%s</code>", escape_html(code))
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.HorizontalRule:
|
||||||
|
fmt.print("<hr>\n")
|
||||||
|
|
||||||
|
case token.TokenType.Underline:
|
||||||
|
fmt.print("<u>")
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</u>")
|
||||||
|
|
||||||
|
case token.TokenType.Superscript:
|
||||||
|
fmt.print("<sup>")
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</sup>")
|
||||||
|
|
||||||
|
case token.TokenType.Subscript:
|
||||||
|
fmt.print("<sub>")
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</sub>")
|
||||||
|
|
||||||
|
case token.TokenType.HeaderLink:
|
||||||
|
if target, ok := tok.value.(string); ok {
|
||||||
|
slug := slugifyifyifyify(target)
|
||||||
|
fmt.printf("<a href=\"#%s\">", escape_html(slug))
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</a>")
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.Link:
|
||||||
|
if url, ok := tok.value.(string); ok {
|
||||||
|
fmt.printf("<a href=\"%s\">", escape_html(url))
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</a>")
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.Image:
|
||||||
|
if url, ok := tok.value.(string); ok {
|
||||||
|
b := strings.builder_make(context.temp_allocator)
|
||||||
|
for child in tok.children {
|
||||||
|
get_text_content(child, &b)
|
||||||
|
}
|
||||||
|
alt_text := strings.to_string(b)
|
||||||
|
fmt.printf("<img src=\"%s\" alt=\"%s\">", escape_html(url), escape_html(alt_text))
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.Audio:
|
||||||
|
if url, ok := tok.value.(string); ok {
|
||||||
|
fmt.printf("<audio controls src=\"%s\"></audio>", escape_html(url))
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.Video:
|
||||||
|
if url, ok := tok.value.(string); ok {
|
||||||
|
fmt.printf("<video controls src=\"%s\"></video>", escape_html(url))
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.Iframe:
|
||||||
|
if url, ok := tok.value.(string); ok {
|
||||||
|
fmt.printf("<iframe src=\"%s\"></iframe>", escape_html(url))
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.Script:
|
||||||
|
if url, ok := tok.value.(string); ok {
|
||||||
|
fmt.printf("<script src=\"%s\"></script>", escape_html(url))
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.ScriptBlock:
|
||||||
|
if content, ok := tok.value.(string); ok {
|
||||||
|
fmt.printf("<script>%s</script>", content)
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.Variable:
|
||||||
|
if name, ok := tok.value.(string); ok {
|
||||||
|
fmt.printf("<span data-tlm-var=\"%s\">", escape_html(name))
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
fmt.print("</span>")
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.VariableDef:
|
||||||
|
if name, ok := tok.value.(string); ok {
|
||||||
|
b := strings.builder_make(context.temp_allocator)
|
||||||
|
for child in tok.children {
|
||||||
|
get_text_content(child, &b)
|
||||||
|
}
|
||||||
|
val := strings.to_string(b)
|
||||||
|
fmt.printf(
|
||||||
|
"<template data-tlm-def=\"%s\" data-tlm-value=\"%s\"></template>",
|
||||||
|
escape_html(name),
|
||||||
|
escape_html(val),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
case token.TokenType.BreakLine:
|
||||||
|
fmt.print("<br>\n")
|
||||||
|
|
||||||
|
case token.TokenType.Text:
|
||||||
|
if v, ok := tok.value.(string); ok {
|
||||||
|
fmt.print(escape_html(v))
|
||||||
|
}
|
||||||
|
for child in tok.children {
|
||||||
|
print_html5(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package renderer
|
||||||
|
|
||||||
|
import "../token"
|
||||||
|
import "core:fmt"
|
||||||
|
|
||||||
|
OutputMode :: enum {
|
||||||
|
HTML5,
|
||||||
|
HTML4,
|
||||||
|
}
|
||||||
|
|
||||||
|
DocumentFlags :: struct {
|
||||||
|
plain: bool,
|
||||||
|
no_js: bool,
|
||||||
|
title: string,
|
||||||
|
print_tree: bool,
|
||||||
|
help: bool,
|
||||||
|
mode: OutputMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
print_document :: proc(root: ^token.Token, flags: DocumentFlags) {
|
||||||
|
switch flags.mode {
|
||||||
|
case .HTML5:
|
||||||
|
print_html5_document(root, flags)
|
||||||
|
case .HTML4:
|
||||||
|
print_html4_document(root, flags)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user