commit f3628ce9acdf899c4f21166db95279e8292c099a Author: Fenris Wolf Date: Wed Feb 7 15:14:30 2024 +0100 [ini] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1bff2e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/build/ +/temp/ diff --git a/misc/description.json b/misc/description.json new file mode 100644 index 0000000..50fb34a --- /dev/null +++ b/misc/description.json @@ -0,0 +1,23 @@ +{ + "group": { + "attributes": [ + "members" + ] + }, + "section": { + "attributes": [ + "title", + "content" + ] + }, + "list": { + "attributes": [ + "items" + ] + }, + "text": { + "attributes": [ + "content" + ] + } +} diff --git a/misc/example-polyhedra.md b/misc/example-polyhedra.md new file mode 100644 index 0000000..caf331b --- /dev/null +++ b/misc/example-polyhedra.md @@ -0,0 +1,36 @@ +# Polyhedra + +## Tetrahedron + +- vertices: 4 +- faces: 4 +- edges: 6 + + +## Hexahedron + +- vertices: 8 +- faces: 6 +- edges: 12 + + +## Octahedron + +- vertices: 6 +- faces: 8 +- edges: 12 + + +## Dodecahedron + +- vertices: 20 +- faces: 12 +- edges: 30 + + +## Icosahedron + +- vertices: 12 +- faces: 20 +- edges: 30 + diff --git a/misc/example-polyhedra.sd.json b/misc/example-polyhedra.sd.json new file mode 100644 index 0000000..7954476 --- /dev/null +++ b/misc/example-polyhedra.sd.json @@ -0,0 +1,169 @@ +{ + "kind": "section", + "data": { + "title": "Polyhedra", + "content": { + "kind": "group", + "data": { + "members": [ + { + "kind": "section", + "data": { + "title": "Tetrahedron", + "content": { + "kind": "list", + "data": { + "items": [ + { + "kind": "text", + "data": { + "content": "vertices: 4" + } + }, + { + "kind": "text", + "data": { + "content": "faces: 4" + } + }, + { + "kind": "text", + "data": { + "content": "edges: 6" + } + } + ] + } + } + } + }, + { + "kind": "section", + "data": { + "title": "Hexahedron", + "content": { + "kind": "list", + "data": { + "items": [ + { + "kind": "text", + "data": { + "content": "vertices: 6" + } + }, + { + "kind": "text", + "data": { + "content": "faces: 8" + } + }, + { + "kind": "text", + "data": { + "content": "edges: 12" + } + } + ] + } + } + } + }, + { + "kind": "section", + "data": { + "title": "Octahedron", + "content": { + "kind": "list", + "data": { + "items": [ + { + "kind": "text", + "data": { + "content": "vertices: 6" + } + }, + { + "kind": "text", + "data": { + "content": "faces: 8" + } + }, + { + "kind": "text", + "data": { + "content": "edges: 12" + } + } + ] + } + } + } + }, + { + "kind": "section", + "data": { + "title": "Dodecahedron", + "content": { + "kind": "list", + "data": { + "items": [ + { + "kind": "text", + "data": { + "content": "vertices: 20" + } + }, + { + "kind": "text", + "data": { + "content": "faces: 12" + } + }, + { + "kind": "text", + "data": { + "content": "edges: 30" + } + } + ] + } + } + } + }, + { + "kind": "section", + "data": { + "title": "Icosahedron", + "content": { + "kind": "list", + "data": { + "items": [ + { + "kind": "text", + "data": { + "content": "vertices: 12" + } + }, + { + "kind": "text", + "data": { + "content": "faces: 20" + } + }, + { + "kind": "text", + "data": { + "content": "edges: 30" + } + } + ] + } + } + } + } + ] + } + } + } +} + diff --git a/misc/notes.md b/misc/notes.md new file mode 100644 index 0000000..89b5d5c --- /dev/null +++ b/misc/notes.md @@ -0,0 +1,15 @@ +- coproduct `element` + - group + - section + - list + - … +- coproduct `output` + - (markdown) + - html + - tex + - odt + - … +- coproduct `input` + - markdown + + diff --git a/misc/sd.schema.json b/misc/sd.schema.json new file mode 100644 index 0000000..123a07e --- /dev/null +++ b/misc/sd.schema.json @@ -0,0 +1,7 @@ +{ + "anyOf": [ + { + "type": " + } + ] +} diff --git a/source/base.ts b/source/base.ts new file mode 100644 index 0000000..60f5e1e --- /dev/null +++ b/source/base.ts @@ -0,0 +1,2 @@ +declare var process; + diff --git a/source/elements/base.ts b/source/elements/base.ts new file mode 100644 index 0000000..d151d29 --- /dev/null +++ b/source/elements/base.ts @@ -0,0 +1,80 @@ +/* +type type_element_text = { + content : string; +}; + +type type_element_group = { + members : Array; +}; + +type type_element = ( + type_element_text + | + type_element_group +); + */ + + +/** + */ +interface type_element +{ + render_html( + ) : string + ; +} + + +/** + */ +let element_kind_pool : Record< + string, + ( + ( + data : any, + make : ((raw : any) => type_element) + ) + => + type_element + ) +> = {}; + + +/** + */ +function element_kind_register( + name : string, + factory : ( + (data : any, make : ((raw : any) => type_element)) + => + type_element + ) +) : void +{ + if (name in element_kind_pool) + { + throw (new Error("kind '" + name + "' already registered")); + } + else + { + element_kind_pool[name] = factory; + } +} + + +/** + */ +function element_make( + raw : any +) : type_element +{ + if (! (raw["kind"] in element_kind_pool)) + { + throw (new Error("kind '" + raw["kind"] + "' not registered")); + } + else + { + return element_kind_pool[raw["kind"]](raw["data"], element_make); + } +} + diff --git a/source/elements/implementations/group.ts b/source/elements/implementations/group.ts new file mode 100644 index 0000000..0e7a0fb --- /dev/null +++ b/source/elements/implementations/group.ts @@ -0,0 +1,51 @@ +/** + */ +class type_element_group implements type_element +{ + + /** + */ + private members : Array; + + + /** + */ + public constructor( + members : Array + ) + { + this.members = members; + } + + + /** + * @implementation + */ + public render_html( + ) : string + { + return ( + "
\n" + + + ( + this.members + .map(x => x.render_html()) + .join("") + ) + + + "
\n" + ); + } + +} + + +element_kind_register( + "group", + (data, sub) => ( + new type_element_group( + data["members"].map(x => sub(x)) + ) + ) +); + diff --git a/source/elements/implementations/text.ts b/source/elements/implementations/text.ts new file mode 100644 index 0000000..74a5cde --- /dev/null +++ b/source/elements/implementations/text.ts @@ -0,0 +1,47 @@ +/** + */ +class type_element_text implements type_element +{ + + /** + */ + private content : string; + + + /** + */ + public constructor( + content : string + ) + { + this.content = content; + } + + + /** + * @implementation + */ + public render_html( + ) : string + { + return ( + "" + + + this.content + + + "\n" + ); + } + +} + + +element_kind_register( + "text", + (data) => ( + new type_element_text( + data["content"] + ) + ) +); + diff --git a/source/main.ts b/source/main.ts new file mode 100644 index 0000000..ce78753 --- /dev/null +++ b/source/main.ts @@ -0,0 +1,30 @@ +function main() : void +{ + let element : type_element = element_make( + { + "kind": "group", + "data": { + "members": [ + { + "kind": "text", + "data": { + "content": "foo" + } + }, + { + "kind": "text", + "data": { + "content": "bar" + } + } + ] + } + } + ); + const html : string = element.render_html(); + process.stdout.write(html + "\n"); +} + + +main(); + diff --git a/source/outputs/base.ts b/source/outputs/base.ts new file mode 100644 index 0000000..41f52ff --- /dev/null +++ b/source/outputs/base.ts @@ -0,0 +1,4 @@ +interface interface_output +{ +} + diff --git a/source/outputs/implementations/html.ts b/source/outputs/implementations/html.ts new file mode 100644 index 0000000..de436a8 --- /dev/null +++ b/source/outputs/implementations/html.ts @@ -0,0 +1 @@ +class diff --git a/source/outputs/implementations/raw.ts b/source/outputs/implementations/raw.ts new file mode 100644 index 0000000..e69de29 diff --git a/tools/build b/tools/build new file mode 100755 index 0000000..223d276 --- /dev/null +++ b/tools/build @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +import os as _os +import argparse as _argparse + + +def string_coin(template, arguments): + result = template + for (key, value, ) in arguments.items(): + result = result.replace("{{%s}}" % key, value) + return result + + +def main(): + ## args + argument_parser = _argparse.ArgumentParser() + argument_parser.add_argument( + "-o", + "--output-directory", + type = str, + default = "build", + metavar = "", + ) + args = argument_parser.parse_args() + + ## exec + _os.system( + string_coin( + "make --file={{path_makefile}} dir_build={{dir_build}}", + { + "path_makefile": "tools/makefile", + "dir_build": args.output_directory, + } + ) + ) + + +main() + + diff --git a/tools/makefile b/tools/makefile new file mode 100644 index 0000000..b4bac1e --- /dev/null +++ b/tools/makefile @@ -0,0 +1,39 @@ +## vars + +dir_source := source +dir_temp := temp +dir_build := build + + +## commands + +cmd_mkdir := mkdir --parents +cmd_log := echo "--" +cmd_tsc := tsc +cmd_chmod := chmod +cmd_echo := echo +cmd_cat := cat + + +## rules + +.PHONY: _default +_default: ${dir_build}/sd + +${dir_temp}/sd-unlinked.js: \ + ${dir_source}/base.ts \ + ${dir_source}/elements/base.ts \ + ${dir_source}/elements/implementations/text.ts \ + ${dir_source}/elements/implementations/group.ts \ + ${dir_source}/main.ts + @ ${cmd_log} "compiling …" + @ ${cmd_mkdir} $(dir $@) + @ ${cmd_tsc} $^ --outFile $@ + +${dir_build}/sd: ${dir_temp}/sd-unlinked.js + @ ${cmd_log} "linking …" + @ ${cmd_mkdir} $(dir $@) + @ ${cmd_echo} "#!/usr/bin/env node" > $@ + @ ${cmd_cat} $^ >> $@ + @ ${cmd_chmod} +x $@ +