Arguments
This commit is contained in:
@@ -3,9 +3,6 @@ all: build
|
||||
build:
|
||||
odin build src/ -out:TypoML
|
||||
|
||||
run:
|
||||
odin run src/
|
||||
|
||||
clean:
|
||||
rm -f TypoML
|
||||
|
||||
|
||||
+25
@@ -18,6 +18,31 @@ TypoML reads from stdin and outputs HTML to stdout:
|
||||
cat input.tlm | ./TypoML > output.html
|
||||
```
|
||||
|
||||
It can also read one or more (added in the order of command line arguments) `.tlm` files:
|
||||
|
||||
```
|
||||
./TypoML input.tlm > output.html
|
||||
```
|
||||
|
||||
Run `./TypoML --help` for the full list of options.
|
||||
|
||||
!! Options
|
||||
|
||||
- `--title <text>` - Set the HTML document `<title>` (default: `TypoML`)
|
||||
- `--plain` - Don't wrap the output in `<html>`, `<head>`, `<body>` and `<style>` tags
|
||||
- `--no-js` - Don't include the JavaScript variable proxy
|
||||
- `--no-wrapper` - Shortcut for `--plain` and `--no-js` at once
|
||||
- `--print-tree` - Print the token tree instead of HTML
|
||||
- `-h`, `--help` - Show the help text and exit
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
./TypoML doc.tlm --title "TITLE" > doc.html
|
||||
./TypoML doc.tlm --no-wrapper > fragment.html
|
||||
./TypoML doc.tlm --print-tree
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
!! Syntax
|
||||
|
||||
@@ -1,39 +1,3 @@
|
||||
#!/bin/sh
|
||||
input=$(cat -)
|
||||
input="${input#odin run src/}"
|
||||
style="<style>$(cat styles.css)</style>"
|
||||
doctype='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
|
||||
meta='<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
|
||||
start="$doctype<html><head><title>TypoML Preview</title>$meta$style</head><body>"
|
||||
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>'
|
||||
end="$script</body></html>"
|
||||
output="$start$input$end"
|
||||
echo "$output" > preview.html
|
||||
cat - > preview.html
|
||||
nohup xdg-open preview.html > /dev/null 2>&1 &
|
||||
|
||||
+82
-8
@@ -7,10 +7,26 @@ import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:strings"
|
||||
|
||||
read_stdin :: proc() -> []string {
|
||||
data, err := os.read_entire_file_from_file(os.stdin, context.allocator)
|
||||
content := string(data)
|
||||
return strings.split_lines(content)
|
||||
read_input :: proc(paths: []string) -> []string {
|
||||
if len(paths) == 0 {
|
||||
data, err := os.read_entire_file_from_file(os.stdin, context.allocator)
|
||||
content := string(data)
|
||||
return strings.split_lines(content)
|
||||
}
|
||||
|
||||
b := strings.builder_make(context.allocator)
|
||||
for path, i in paths {
|
||||
data, err := os.read_entire_file(path, context.allocator)
|
||||
if err != nil {
|
||||
fmt.eprintf("typoml: cannot read file '%s': %v\n", path, err)
|
||||
os.exit(1)
|
||||
}
|
||||
if i > 0 {
|
||||
strings.write_string(&b, "\n")
|
||||
}
|
||||
strings.write_string(&b, string(data))
|
||||
}
|
||||
return strings.split_lines(strings.to_string(b))
|
||||
}
|
||||
|
||||
print_token :: proc(tok: ^token.Token, depth: int = 0) {
|
||||
@@ -116,8 +132,66 @@ print_token :: proc(tok: ^token.Token, depth: int = 0) {
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
lines := read_stdin()
|
||||
parsed := parser.parse(lines)
|
||||
renderer.print_html(&parsed)
|
||||
HELP_TEXT :: `Usage:
|
||||
TypoML [options] [file...]
|
||||
|
||||
If there is no file provided, TypoML reads from stdin.
|
||||
|
||||
Options:
|
||||
--title <text> Set the HTML document title (default: "TypoML")
|
||||
--plain Don't wrap the output in <html>, <head>, <body> and <style> tags
|
||||
--no-js Don't include the JavaScript variable proxy (<script>)
|
||||
--no-wrapper Shortcut for --plain and --no-js at once
|
||||
--print-tree Print the token tree instead of HTML
|
||||
-h, --help Show this help and exit
|
||||
`
|
||||
|
||||
parse_args :: proc(args: []string) -> (files: [dynamic]string, flags: renderer.DocumentFlags) {
|
||||
for i := 0; i < len(args); i += 1 {
|
||||
arg := args[i]
|
||||
switch arg {
|
||||
case "-h", "--help":
|
||||
flags.help = true
|
||||
case "--plain":
|
||||
flags.plain = true
|
||||
case "--no-js":
|
||||
flags.no_js = true
|
||||
case "--no-wrapper":
|
||||
flags.plain = true
|
||||
flags.no_js = true
|
||||
case "--title":
|
||||
if i + 1 < len(args) {
|
||||
i += 1
|
||||
flags.title = args[i]
|
||||
}
|
||||
case "--print-tree":
|
||||
flags.print_tree = true
|
||||
case:
|
||||
if strings.has_prefix(arg, "--") {
|
||||
fmt.eprintf("typoml: unknown option '%s'\n", arg)
|
||||
os.exit(1)
|
||||
}
|
||||
append(&files, arg)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
files, flags := parse_args(os.args[1:])
|
||||
|
||||
if flags.help {
|
||||
fmt.print(HELP_TEXT)
|
||||
return
|
||||
}
|
||||
|
||||
lines := read_input(files[:])
|
||||
parsed := parser.parse(lines)
|
||||
|
||||
if flags.print_tree {
|
||||
print_token(&parsed)
|
||||
return
|
||||
}
|
||||
|
||||
renderer.print_document(&parsed, flags)
|
||||
}
|
||||
|
||||
@@ -66,6 +66,75 @@ render_media_object :: proc(tok: ^token.Token, mime_type: string) {
|
||||
fmt.print("</object>\n")
|
||||
}
|
||||
|
||||
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_document :: proc(root: ^token.Token, flags: DocumentFlags) {
|
||||
if flags.plain {
|
||||
for child in root.children {
|
||||
print_html(child)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
doctype := "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"
|
||||
meta := "<meta http-equiv=\"Content-Type\" content=\"text/html; 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_html(child)
|
||||
}
|
||||
if !flags.no_js {
|
||||
fmt.print("\n" + TEMPLATE_PROXY_SCRIPT + "\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) {
|
||||
switch tok.type {
|
||||
case token.TokenType.Root:
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
package renderer
|
||||
|
||||
DEFAULT_STYLE :: `
|
||||
body {
|
||||
font-family: Georgia, "Times New Roman", Times, serif;
|
||||
color: #e0e0e0;
|
||||
@@ -72,3 +75,4 @@ hr.footnotes-sep {
|
||||
.footnote a {
|
||||
text-decoration: none;
|
||||
}
|
||||
`
|
||||
Reference in New Issue
Block a user