[ini]
This commit is contained in:
commit
f3628ce9ac
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/build/
|
||||
/temp/
|
||||
23
misc/description.json
Normal file
23
misc/description.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"group": {
|
||||
"attributes": [
|
||||
"members"
|
||||
]
|
||||
},
|
||||
"section": {
|
||||
"attributes": [
|
||||
"title",
|
||||
"content"
|
||||
]
|
||||
},
|
||||
"list": {
|
||||
"attributes": [
|
||||
"items"
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"attributes": [
|
||||
"content"
|
||||
]
|
||||
}
|
||||
}
|
||||
36
misc/example-polyhedra.md
Normal file
36
misc/example-polyhedra.md
Normal file
|
|
@ -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
|
||||
|
||||
169
misc/example-polyhedra.sd.json
Normal file
169
misc/example-polyhedra.sd.json
Normal file
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
misc/notes.md
Normal file
15
misc/notes.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
- coproduct `element`
|
||||
- group
|
||||
- section
|
||||
- list
|
||||
- …
|
||||
- coproduct `output`
|
||||
- (markdown)
|
||||
- html
|
||||
- tex
|
||||
- odt
|
||||
- …
|
||||
- coproduct `input`
|
||||
- markdown
|
||||
|
||||
|
||||
7
misc/sd.schema.json
Normal file
7
misc/sd.schema.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "
|
||||
}
|
||||
]
|
||||
}
|
||||
2
source/base.ts
Normal file
2
source/base.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare var process;
|
||||
|
||||
80
source/elements/base.ts
Normal file
80
source/elements/base.ts
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
type type_element_text = {
|
||||
content : string;
|
||||
};
|
||||
|
||||
type type_element_group = {
|
||||
members : Array<type_element>;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
51
source/elements/implementations/group.ts
Normal file
51
source/elements/implementations/group.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
*/
|
||||
class type_element_group implements type_element
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
private members : Array<type_element>;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public constructor(
|
||||
members : Array<type_element>
|
||||
)
|
||||
{
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @implementation
|
||||
*/
|
||||
public render_html(
|
||||
) : string
|
||||
{
|
||||
return (
|
||||
"<div class=\"ds-group\">\n"
|
||||
+
|
||||
(
|
||||
this.members
|
||||
.map(x => x.render_html())
|
||||
.join("")
|
||||
)
|
||||
+
|
||||
"</div>\n"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
element_kind_register(
|
||||
"group",
|
||||
(data, sub) => (
|
||||
new type_element_group(
|
||||
data["members"].map(x => sub(x))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
47
source/elements/implementations/text.ts
Normal file
47
source/elements/implementations/text.ts
Normal file
|
|
@ -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 (
|
||||
"<span class=\"ds-text\">"
|
||||
+
|
||||
this.content
|
||||
+
|
||||
"</span>\n"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
element_kind_register(
|
||||
"text",
|
||||
(data) => (
|
||||
new type_element_text(
|
||||
data["content"]
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
30
source/main.ts
Normal file
30
source/main.ts
Normal file
|
|
@ -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();
|
||||
|
||||
4
source/outputs/base.ts
Normal file
4
source/outputs/base.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
interface interface_output
|
||||
{
|
||||
}
|
||||
|
||||
1
source/outputs/implementations/html.ts
Normal file
1
source/outputs/implementations/html.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
class
|
||||
0
source/outputs/implementations/raw.ts
Normal file
0
source/outputs/implementations/raw.ts
Normal file
40
tools/build
Executable file
40
tools/build
Executable file
|
|
@ -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 = "<output-directory>",
|
||||
)
|
||||
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()
|
||||
|
||||
|
||||
39
tools/makefile
Normal file
39
tools/makefile
Normal file
|
|
@ -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 $@
|
||||
|
||||
Loading…
Reference in a new issue