This commit is contained in:
fenris 2024-02-08 18:10:46 +01:00
parent 95469e839f
commit f751b57ab9
17 changed files with 540 additions and 370 deletions

View file

@ -1,12 +1,6 @@
{
"kind": "section",
"data": {
"title": "Polyhedra",
"content": {
"kind": "group",
"data": {
"members": [
{
"definitions": {
"tetrahedron": {
"kind": "section",
"data": {
"title": "Tetrahedron",
@ -37,7 +31,7 @@
}
}
},
{
"hexahedron": {
"kind": "section",
"data": {
"title": "Hexahedron",
@ -68,7 +62,7 @@
}
}
},
{
"octahedron": {
"kind": "section",
"data": {
"title": "Octahedron",
@ -99,7 +93,7 @@
}
}
},
{
"dodecahedron": {
"kind": "section",
"data": {
"title": "Dodecahedron",
@ -130,7 +124,7 @@
}
}
},
{
"icosahedron": {
"kind": "section",
"data": {
"title": "Icosahedron",
@ -161,9 +155,53 @@
}
}
}
},
"content": {
"title": "Polyhedra",
"main": {
"kind": "section",
"data": {
"title": "Polyhedra",
"content": {
"kind": "group",
"data": {
"members": [
{
"kind": "reference",
"data": {
"name": "tetrahedron"
}
},
{
"kind": "reference",
"data": {
"name": "hexahedron"
}
},
{
"kind": "reference",
"data": {
"name": "octahedron"
}
},
{
"kind": "reference",
"data": {
"name": "dodecahedron"
}
},
{
"kind": "reference",
"data": {
"name": "icosahedron"
}
}
]
}
}
}
}
}
}

51
source/document.ts Normal file
View file

@ -0,0 +1,51 @@
/**
*/
class type_document
{
/**
*/
public readonly definitions : Record<string, type_object>;
/**
*/
public readonly content_title : string;
/**
*/
public readonly content_main : type_object;
/**
*/
public constructor(
definitions : Record<string, type_object>,
content_title : string,
content_main : type_object
)
{
this.definitions = definitions;
this.content_title = content_title;
this.content_main = content_main;
}
/**
*/
public static from_raw(
document_raw : any
) : type_document
{
return (new type_document(
Object.fromEntries(
Object.entries(document_raw["definitions"])
.map(([name, object_raw]) => ([name, object_make(object_raw)]))
),
document_raw["content"]["title"],
object_make(document_raw["content"]["main"])
));
}
}

View file

@ -1,61 +0,0 @@
/**
*/
interface type_element extends lib_plankton.call.type_coproduct
{
}
/**
*/
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);
}
}

View file

@ -1,30 +0,0 @@
/**
*/
type type_element_group_data = {
members : type_element;
};
/**
*/
class type_element_group implements type_element
{
public readonly kind : string = "group";
public readonly data : type_element_group_data;
public constructor(data : type_element_group_data) {this.data = data;}
}
/**
*/
element_kind_register(
"group",
(data, sub) => (
new type_element_group(
{
"members": data["members"].map(x => sub(x))
}
)
)
);

View file

@ -1,30 +0,0 @@
/**
*/
type type_element_list_data = {
items : Array<type_element>;
};
/**
*/
class type_element_list implements type_element
{
public readonly kind : string = "list";
public readonly data : type_element_list_data;
public constructor(data : type_element_list_data) {this.data = data;}
}
/**
*/
element_kind_register(
"list",
(data) => (
new type_element_list(
{
"items": data["items"],
}
)
)
);

View file

@ -1,32 +0,0 @@
/**
*/
type type_element_section_data = {
title : string;
content : type_element;
};
/**
*/
class type_element_section implements type_element
{
public readonly kind : string = "section";
public readonly data : type_element_section_data;
public constructor(data : type_element_section_data) {this.data = data;}
}
/**
*/
element_kind_register(
"section",
(data) => (
new type_element_section(
{
"title": data["title"],
"content": data["content"],
}
)
)
);

View file

@ -1,30 +0,0 @@
/**
*/
type type_element_text_data = {
content : string;
};
/**
*/
class type_element_text implements type_element
{
public readonly kind : string = "text";
public readonly data : type_element_text_data;
public constructor(data : type_element_text_data) {this.data = data;}
}
/**
*/
element_kind_register(
"text",
(data) => (
new type_element_text(
{
"content": data["content"],
}
)
)
);

View file

@ -46,12 +46,13 @@ async function main(args_raw : Array<string>) : Promise<void>
}
else
{
const element_raw : string = lib_plankton.json.decode(await lib_plankton.file.read(args.input))
let element : type_element = element_make(element_raw);
const document_raw : string = lib_plankton.json.decode(await lib_plankton.file.read(args.input))
const document : type_document = type_document.from_raw(document_raw);
// let object : type_object = object_make(document_raw["content"]["main"]);
const output : type_output<string> = output_make<string>({"kind": args.output, "data": {}});
const result : string = output.render_element(element);
const result : string = output.render_document(document);
process.stdout.write(result + "\n");
}
}

61
source/objects/base.ts Normal file
View file

@ -0,0 +1,61 @@
/**
*/
interface type_object extends lib_plankton.call.type_coproduct
{
}
/**
*/
let object_kind_pool : Record<
string,
(
(
data : any,
make : ((raw : any) => type_object)
)
=>
type_object
)
> = {};
/**
*/
function object_kind_register(
name : string,
factory : (
(data : any, make : ((raw : any) => type_object))
=>
type_object
)
) : void
{
if (name in object_kind_pool)
{
throw (new Error("kind '" + name + "' already registered"));
}
else
{
object_kind_pool[name] = factory;
}
}
/**
*/
function object_make(
raw : any
) : type_object
{
if (! (raw["kind"] in object_kind_pool))
{
throw (new Error("kind '" + raw["kind"] + "' not registered"));
}
else
{
return object_kind_pool[raw["kind"]](raw["data"], object_make);
}
}

View file

@ -0,0 +1,30 @@
/**
*/
type type_object_group_data = {
members : type_object;
};
/**
*/
class type_object_group implements type_object
{
public readonly kind : string = "group";
public readonly data : type_object_group_data;
public constructor(data : type_object_group_data) {this.data = data;}
}
/**
*/
object_kind_register(
"group",
(data, sub) => (
new type_object_group(
{
"members": data["members"].map(x => sub(x))
}
)
)
);

View file

@ -0,0 +1,30 @@
/**
*/
type type_object_list_data = {
items : Array<type_object>;
};
/**
*/
class type_object_list implements type_object
{
public readonly kind : string = "list";
public readonly data : type_object_list_data;
public constructor(data : type_object_list_data) {this.data = data;}
}
/**
*/
object_kind_register(
"list",
(data) => (
new type_object_list(
{
"items": data["items"],
}
)
)
);

View file

@ -0,0 +1,32 @@
/**
*/
type type_object_section_data = {
title : string;
content : type_object;
};
/**
*/
class type_object_section implements type_object
{
public readonly kind : string = "section";
public readonly data : type_object_section_data;
public constructor(data : type_object_section_data) {this.data = data;}
}
/**
*/
object_kind_register(
"section",
(data) => (
new type_object_section(
{
"title": data["title"],
"content": data["content"],
}
)
)
);

View file

@ -0,0 +1,30 @@
/**
*/
type type_object_text_data = {
content : string;
};
/**
*/
class type_object_text implements type_object
{
public readonly kind : string = "text";
public readonly data : type_object_text_data;
public constructor(data : type_object_text_data) {this.data = data;}
}
/**
*/
object_kind_register(
"text",
(data) => (
new type_object_text(
{
"content": data["content"],
}
)
)
);

View file

@ -6,8 +6,16 @@ interface type_output<type_result> extends lib_plankton.call.type_coproduct
/**
*/
render_element(
element : type_element
render_object(
object : type_object
) : type_result
;
/**
*/
render_document(
document : type_document
) : type_result
;

View file

@ -9,23 +9,23 @@ class type_output_html implements type_output<string>
/**
*/
private render_element_internal(
element : type_element,
private render_object_internal(
object : type_object,
options : {
depth ?: int;
level ?: int;
depth ?: int;
} = {}
) : lib_plankton.xml.class_node
{
options = Object.assign(
{
"depth": 0,
"level": 0,
"depth": 0,
},
options
);
return lib_plankton.call.distinguish<lib_plankton.xml.class_node>(
element,
object,
{
"text": ({"content": content}) => new lib_plankton.xml.class_node_complex(
"span",
@ -44,7 +44,7 @@ class type_output_html implements type_output<string>
(
members
.map(
x => this.render_element_internal(
x => this.render_object_internal(
x,
{
"depth": options.depth,
@ -67,11 +67,11 @@ class type_output_html implements type_output<string>
new lib_plankton.xml.class_node_text(title),
]
),
this.render_element_internal(
this.render_object_internal(
content,
{
"depth": (options.depth + 1),
"level": (options.level + 1),
"depth": (options.depth + 1),
}
),
]
@ -88,7 +88,7 @@ class type_output_html implements type_output<string>
"li",
{},
[
this.render_element_internal(
this.render_object_internal(
item,
{
"level": options.level,
@ -102,15 +102,15 @@ class type_output_html implements type_output<string>
),
},
{
"fallback": (element) => new lib_plankton.xml.class_node_complex(
"fallback": (object) => new lib_plankton.xml.class_node_complex(
"pre",
{
"class": "sd-unhandled",
"rel": element.kind,
"rel": object.kind,
},
[
new lib_plankton.xml.class_node_text(
JSON.stringify(element, undefined, " "),
JSON.stringify(object, undefined, " "),
)
]
),
@ -122,11 +122,70 @@ class type_output_html implements type_output<string>
/**
* @implementation
*/
public render_element(
element : type_element
public render_object(
object : type_object
) : string
{
return this.render_element_internal(element).compile();
return this.render_object_internal(object).compile();
}
/**
* @implementation
*/
public render_document(
document : type_document
) : string
{
return lib_plankton.string.coin(
"<!DOCTYPE html>\n{{html}}",
{
"html": new lib_plankton.xml.class_node_complex(
"html",
{},
[
new lib_plankton.xml.class_node_complex(
"head",
{
},
[
new lib_plankton.xml.class_node_complex(
"meta",
{
"charset": "utf-8",
},
[
]
),
new lib_plankton.xml.class_node_complex(
"title",
{
},
[
new lib_plankton.xml.class_node_text(
document.content_title
),
]
),
]
),
new lib_plankton.xml.class_node_complex(
"body",
{
},
[
this.render_object_internal(
document.content_main,
{
"depth": 1,
}
),
]
)
]
).compile()
}
);
}
}

View file

@ -9,20 +9,32 @@ class type_output_json implements type_output<string>
/**
*/
public render_element(
element : type_element
public render_object(
object : type_object
) : string
{
return lib_plankton.call.distinguish<string>(
element,
object,
{
},
{
"fallback": (element) => JSON.stringify(element, undefined, "\t"),
"fallback": (object) => JSON.stringify(object, undefined, "\t"),
}
);
}
/**
* @todo
* @implementation
*/
public render_document(
document : type_document
) : string
{
return ""
}
}

View file

@ -24,11 +24,12 @@ _default: ${dir_build}/sd
${dir_temp}/sd-unlinked.js: \
${dir_lib}/plankton/plankton.d.ts \
${dir_source}/base.ts \
${dir_source}/elements/base.ts \
${dir_source}/elements/implementations/text.ts \
${dir_source}/elements/implementations/group.ts \
${dir_source}/elements/implementations/section.ts \
${dir_source}/elements/implementations/list.ts \
${dir_source}/objects/base.ts \
${dir_source}/objects/implementations/text.ts \
${dir_source}/objects/implementations/group.ts \
${dir_source}/objects/implementations/section.ts \
${dir_source}/objects/implementations/list.ts \
${dir_source}/document.ts \
${dir_source}/outputs/base.ts \
${dir_source}/outputs/implementations/json.ts \
${dir_source}/outputs/implementations/html.ts \