Compare commits

...

10 commits

32 changed files with 3458 additions and 877 deletions

View file

@ -6,13 +6,28 @@ type int = number;
* @author fenris
*/
type float = number;
/**
* @author fenris
*/
type type_date = {
year: int;
month: int;
day: int;
};
/**
* @author fenris
*/
type type_time = {
hours: int;
minutes: int;
seconds: int;
hour: int;
minute: int;
second: int;
};
/**
* @author fenris
*/
type type_datetimeobject = {
date: type_date;
time: type_time;
};
declare var process: any;
declare var require: any;
@ -230,12 +245,12 @@ declare namespace lib_plankton.base {
*
* @author fenris
*/
function get_current_timestamp(rounded?: boolean): int;
function get_current_timestamp(rounded?: boolean): float;
/**
*/
function object_merge(core: Record<string, any>, mantle: Record<string, any>): Record<string, any>;
}
declare namespace lib_plankton.pod {
declare module lib_plankton.pod {
/**
* @author fenris
*/
@ -279,7 +294,7 @@ declare namespace lib_plankton.pod {
show_value?: ((value: type_value) => string);
}): string;
}
declare namespace lib_plankton.pod {
declare module lib_plankton.pod {
/**
*/
class class_pod<type_value> {
@ -294,59 +309,9 @@ declare namespace lib_plankton.pod {
distinguish<type_result>(function_empty: (() => type_result), function_filled: ((value: type_value) => type_result)): type_result;
}
}
declare namespace lib_plankton.call {
/**
* @author fenris
/**
* might be completely obsolete
*/
type type_executor<type_result, type_reason> = ((resolve: (result?: type_result) => any, reject?: (reason?: type_reason) => void) => void);
/**
* @author fenris
*/
function executor_resolve<type_result, type_reason>(result: type_result): type_executor<type_result, type_reason>;
/**
* @author fenris
*/
function executor_reject<type_result, type_reason>(reason: type_reason): type_executor<type_result, type_reason>;
/**
* @author fenris
*/
function executor_transform<type_result_from, type_error_from, type_result_to, type_error_to>(executor: type_executor<type_result_from, type_error_from>, transform_result: (result_from: type_result_from) => type_result_to, transform_reason: (error_from: type_error_from) => type_error_to): type_executor<type_result_to, type_error_to>;
/**
* @author fenris
*/
function executor_transform_default<type_result_from, type_result_to>(executor: type_executor<type_result_from, Error>, transform_result: (result_from: type_result_from) => type_result_to, wrap_string?: string): type_executor<type_result_to, Error>;
/**
* @author fenris
*/
function executor_compose_sequential<type_result_first, type_result_second, type_reason>(first: type_executor<type_result_first, type_reason>, second: (result: type_result_first) => type_executor<type_result_second, type_reason>): type_executor<type_result_second, type_reason>;
/**
* @author fenris
*/
function executor_chain<type_state, type_error>(state: type_state, executors: Array<(state: type_state) => type_executor<type_state, type_error>>): type_executor<type_state, type_error>;
/**
* @author fenris
*/
function executor_first<type_result, type_reason>(executors: Array<type_executor<type_result, type_reason>>): type_executor<type_result, Array<type_reason>>;
/**
* @author fenris
*/
function executor_condense<type_element>(executors: Array<type_executor<type_element, Error>>): type_executor<Array<type_element>, Error>;
/**
* @author fenris
* @deprecated use condense
*/
function executor_filter<type_element>(executors: Array<type_executor<type_element, Error>>, predicate: (element: type_element) => boolean): type_executor<Array<type_element>, Error>;
/**
* @author fenris
* @deprecated use condense
*/
function executor_map<type_element1, type_element2>(executors: Array<type_executor<type_element1, Error>>, transformator: (element1: type_element1) => type_element2): type_executor<Array<type_element2>, Error>;
/**
* @author fenris
* @deprecated use condense
*/
function executor_reduce<type_element, type_result>(executors: Array<type_executor<type_element, Error>>, initial: type_result, accumulator: (result: type_result, element: type_element) => type_result): type_executor<type_result, Error>;
}
declare namespace lib_plankton.call {
/**
* @author fenris
@ -363,15 +328,15 @@ declare namespace lib_plankton.call {
/**
* @author fenris
*/
function promise_make<type_result, type_reason>(executor: (resolve: (result?: type_result) => void, reject: (reason?: type_reason) => void) => void): type_promise<type_result, type_reason>;
function promise_make<type_result, type_reason>(executor: (resolve: ((result?: type_result) => void), reject: ((reason?: type_reason) => void)) => void): type_promise<type_result, type_reason>;
/**
* @author fenris
*/
function promise_then_close<type_result, type_reason>(promise: type_promise<type_result, type_reason>, resolver: (result: type_result) => void, rejector: (reason: type_reason) => void): void;
function promise_then_close<type_result, type_reason>(promise: type_promise<type_result, type_reason>, resolver: ((result: type_result) => void), rejector: ((reason: type_reason) => void)): void;
/**
* @author fenris
*/
function promise_then_append<type_result, type_reason, type_result_>(promise: type_promise<type_result, type_reason>, resolver: (result: type_result) => type_promise<type_result_, type_reason>, rejector?: (reason: type_reason) => type_promise<type_result_, type_reason>): type_promise<type_result_, type_result>;
function promise_then_append<type_result, type_reason, type_result_>(promise: type_promise<type_result, type_reason>, resolver: ((result: type_result) => type_promise<type_result_, type_reason>), rejector?: ((reason: type_reason) => type_promise<type_result_, type_reason>)): type_promise<type_result_, type_result>;
/**
* @author fenris
*/
@ -379,7 +344,7 @@ declare namespace lib_plankton.call {
/**
* @author fenris
*/
function promise_chain<type_result, type_reason>(promises: Array<(input: type_result) => type_promise<type_result, type_reason>>, start?: type_result): type_promise<type_result, type_reason>;
function promise_chain<type_result, type_reason>(promises: (Array<(input: type_result) => type_promise<type_result, type_reason>>), start?: type_result): type_promise<type_result, type_reason>;
/**
* @author fenris
*/
@ -387,15 +352,13 @@ declare namespace lib_plankton.call {
/**
* @author fenris
*/
function promise_group<type_reason>(promises: {
[name: string]: () => type_promise<any, type_reason>;
}, serial?: boolean): type_promise<{
[name: string]: any;
}, type_reason>;
function promise_group<type_reason>(promises: Record<string, (() => type_promise<any, type_reason>)>, options?: {
serial?: boolean;
}): type_promise<Record<string, any>, type_reason>;
/**
* @author fenris
*/
function promise_wrap<type_result_inner, type_result_outer, type_reason>(promise: type_promise<type_result_inner, type_reason>, transformator_result: (reason: type_result_inner) => type_result_outer, transformator_reason?: (reason: type_reason) => type_reason): type_promise<type_result_outer, type_reason>;
function promise_wrap<type_result_inner, type_result_outer, type_reason>(promise: type_promise<type_result_inner, type_reason>, transformator_result: ((reason: type_result_inner) => type_result_outer), transformator_reason?: ((reason: type_reason) => type_reason)): type_promise<type_result_outer, type_reason>;
/**
* @author fenris
*/
@ -405,19 +368,11 @@ declare namespace lib_plankton.call {
/**
* @author fenris
*/
function promise_attach<type_reason>(state: {
[name: string]: any;
}, promise: type_promise<any, type_reason>, name: string): type_promise<{
[name: string]: any;
}, type_reason>;
function promise_attach<type_reason>(state: Record<string, any>, promise: type_promise<any, type_reason>, name: string): type_promise<Record<string, any>, type_reason>;
/**
* @author fenris
*/
function promise_delay<type_result, type_reason>(promise: type_promise<type_result, type_reason>, delay: int): type_promise<type_result, type_reason>;
/**
* @author fenris
*/
function promise_to_executor<type_result, type_reason>(promise: type_promise<type_result, type_reason>): type_executor<type_result, type_reason>;
}
declare namespace lib_plankton.call {
/**
@ -449,6 +404,9 @@ declare namespace lib_plankton.call {
cancel(): void;
}
}
/**
* initializer might be obsolete, since promises are reusable after having been resolved or rejected
*/
declare namespace lib_plankton.call {
/**
* @author fenris
@ -637,7 +595,7 @@ declare namespace lib_plankton.call {
*/
function compose<type_x, type_y, type_z>(function_f: ((type_x: any) => type_y), function_g: ((type_y: any) => type_z)): ((value: type_x) => type_z);
/**
* transforms a function with sequential input into a function with leveled input; example: add(2,3) = curryfy(add)(2)(3)
* transforms a function with sequential input to a function with leveled input; example: add(2,3) = curryfy(add)(2)(3)
*
* @param {function} f
* @return {function} the currified version of the in put function
@ -651,7 +609,13 @@ declare namespace lib_plankton.call {
/**
* @author fenris
*/
function timeout(procedure: (() => void), delay: int): int;
function timeout(procedure: (() => void), delay_in_seconds: float): int;
/**
* Promise version of "setTimeout"
*
* @author fenris
*/
function defer<type_result>(seconds: float, action: (() => type_result)): Promise<type_result>;
/**
* a definition for a value being "defined"
*
@ -698,12 +662,6 @@ declare namespace lib_plankton.call {
function distinguish<type_output>(coproduct: type_coproduct, handlers: Record<string, ((data?: any) => type_output)>, options?: {
fallback?: (null | ((coproduct?: type_coproduct) => type_output));
}): type_output;
/**
* Promise version of "setTimeout"
*
* @author fenris
*/
function defer<type_result>(seconds: float, action: (() => type_result)): Promise<type_result>;
/**
* for rate_limit_check
*
@ -733,6 +691,207 @@ declare namespace lib_plankton.call {
seconds: (null | float);
}>;
}
declare namespace lib_plankton.list {
/**
* @desc returns a certain list of integer numbers
* @param {int} from
* @param {int} to
* @param {int} step; default: 1
* @author fenris
*/
function range(from: int, to: int, step?: int): Array<int>;
/**
* @desc returns a certain list of integer numbers
* @param {int} length
* @author fenris
*/
function sequence(length: int): Array<int>;
/**
* @author fenris
*/
function from_structure<type_element>(structure: {
length: int;
}): Array<type_element>;
/**
* @author fenris
*/
function from_iterator<type_element>(iterator: any): Array<type_element>;
/**
* @author fenris
*/
function empty<type_element>(list: Array<type_element>): boolean;
/**
* @desc creates a list, which contains pairs of elements from the input lists (corresponding by index)
* @param {boolean} [cut] whether the result list will be as long as the shortest input list or an exception is thrown if they have different lengths; default: true
* @author fenris
*/
function zip<type_element1, type_element2>(list1: Array<type_element1>, list2: Array<type_element2>, cut?: boolean): Array<{
first: type_element1;
second: type_element2;
}>;
/**
* @desc checks whether two lists are equal
* @todo define common function "equals" and default predicate to
* @author fenris
*/
function equals<type_element>(list1: Array<type_element>, list2: Array<type_element>, collate?: (element1: type_element, element2: type_element) => boolean): boolean;
/**
* @author fenris
*/
function reversed<type_element>(list: Array<type_element>): Array<type_element>;
/**
* @author fenris
*/
function sorted<type_element>(list: Array<type_element>, order: (element1: type_element, element2: type_element) => int): Array<type_element>;
/**
* @desc creates a list with the elements from the input list, which fulfil a certain predicate
* @author fenris
*/
function keep<type_element>(list: Array<type_element>, predicate: (element: type_element, index?: int) => boolean): Array<type_element>;
/**
* @desc creates a list with the elements from the input list, which do not fulfil a certain predicate
* @author fenris
*/
function drop<type_element>(list: Array<type_element>, predicate: (element: type_element, index?: int) => boolean): Array<type_element>;
/**
* @desc returns a list with no duplicates
* @author fenris
*/
function clean<type_element>(list: Array<type_element>, collate?: (x: type_element, y: type_element) => boolean): Array<type_element>;
/**
* @author fenris
*/
function clone<type_element>(list: Array<type_element>): Array<type_element>;
/**
* @desc creates a binary partition of the list according to a given predicate
* @author fenris
*/
type type_separation<type_element> = {
yes: Array<type_element>;
no: Array<type_element>;
};
function separate<type_element>(list: Array<type_element>, predicate: (element: type_element) => boolean): type_separation<type_element>;
/**
* die Liste in gleich große Blöcke zerlegen
*
* @author fenris
*/
function split<type_element>(list: Array<type_element>, chunk_size: int): Array<Array<type_element>>;
/**
* @author fenris
*/
function group<type_element>(list: Array<type_element>, collate?: (x: type_element, y: type_element) => boolean): Array<Array<type_element>>;
/**
* @author fenris
*/
function groups_<type_element>(list: Array<type_element>, collate?: (x: type_element, y: type_element) => boolean): Array<Array<type_element>>;
/**
* @author fenris
* @deprecated
*/
function groups<type_element, type_value>(list: Array<type_element>, sorting: (x: type_element, y: type_element) => int, hashing: (element: type_element) => type_value): Array<Array<type_element>>;
/**
* @desc searches for the first element in a list, that fulfils a given condition
* @author fenris
*/
function find<type_element>(list: Array<type_element>, predicate: (element: type_element) => boolean, null_if_not_found?: boolean): type_element;
/**
* @author fenris
*/
function has<type_element>(list: Array<type_element>, predicate: (element: type_element) => boolean): boolean;
/**
* @author fenris
*/
function contains<type_element>(list: Array<type_element>, element: type_element, collation?: (element1: type_element, element2: type_element) => boolean): boolean;
/**
* @desc retrieves the element and its index of the list, which has the maximum value
* @author fenris
*/
type type_result_max<type_element, type_value> = {
index: int;
element: type_element;
value: type_value;
};
function max<type_element, type_value>(list: Array<type_element>, targetfunction: (element: type_element) => type_value, compare?: (value1: type_value, value2: type_value) => boolean): type_result_max<type_element, type_value>;
/**
* @desc retrieves the element and its index of the list, which has the mininum value
* @author fenris
*/
function min<type_element, type_value>(list: Array<type_element>, targetfunction: (element: type_element) => type_value, compare?: (value1: type_value, value2: type_value) => boolean): type_result_max<type_element, type_value>;
/**
* @desc retrieves the element of the list, which has the maximum output for a given target-function
* @author fenris
*/
function maxarg<type_element, type_value>(list: Array<type_element>, targetfunction: (element: type_element) => type_value, compare?: (value1: type_value, value2: type_value) => boolean): type_element;
/**
* @desc retrieves the element of the list, which has the minimum output for a given target-function
* @author fenris
*/
function minarg<type_element, type_value>(list: Array<type_element>, targetfunction: (element: type_element) => type_value, compare?: (value1: type_value, value2: type_value) => boolean): type_element;
/**
* @desc implements the idea of arithmetic distribution like in "(a+b)·(c+d) = (a·c)+(a·d)+(b·c)+(b·d)"
* example: distribute([[1,2],[3],[4,5,6]]) = [[1,3,4],[1,3,5],[1,3,6],[2,3,4],[2,3,5],[2,3,6]]
* @author fenris
*/
function distribute<type_element>(lists: Array<Array<type_element>>): Array<Array<type_element>>;
/**
* @desc lexicographic order
* @author fenris
* @deprecated
*/
function lex<type_element>(list1: Array<type_element>, list2: Array<type_element>, order?: (element1: type_element, element2: type_element) => int): int;
function lex_lt<type_element>(list1: Array<type_element>, list2: Array<type_element>): boolean;
function lex_gt<type_element>(list1: Array<type_element>, list2: Array<type_element>): boolean;
function lex_le<type_element>(list1: Array<type_element>, list2: Array<type_element>): boolean;
function lex_ge<type_element>(list1: Array<type_element>, list2: Array<type_element>): boolean;
function lex_eq<type_element>(list1: Array<type_element>, list2: Array<type_element>): boolean;
function lex_ne<type_element>(list1: Array<type_element>, list2: Array<type_element>): boolean;
/**
* @author fenris
*/
function filter_inplace<type_element>(list: Array<type_element>, predicate: (element: type_element, index?: int) => boolean): void;
}
/**
* @deprecated
*/
declare namespace lib_list {
type type_separation<type_element> = lib_plankton.list.type_separation<type_element>;
type type_result_max<type_element, type_value> = lib_plankton.list.type_result_max<type_element, type_value>;
const range: typeof lib_plankton.list.range;
const sequence: typeof lib_plankton.list.sequence;
const from_structure: typeof lib_plankton.list.from_structure;
const from_iterator: typeof lib_plankton.list.from_iterator;
const empty: typeof lib_plankton.list.empty;
const zip: typeof lib_plankton.list.zip;
const equals: typeof lib_plankton.list.equals;
const reversed: typeof lib_plankton.list.reversed;
const sorted: typeof lib_plankton.list.sorted;
const keep: typeof lib_plankton.list.keep;
const drop: typeof lib_plankton.list.drop;
const clean: typeof lib_plankton.list.clean;
const clone: typeof lib_plankton.list.clone;
const separate: typeof lib_plankton.list.separate;
const split: typeof lib_plankton.list.split;
const group: typeof lib_plankton.list.group;
const groups_: typeof lib_plankton.list.groups_;
const groups: typeof lib_plankton.list.groups;
const find: typeof lib_plankton.list.find;
const has: typeof lib_plankton.list.has;
const contains: typeof lib_plankton.list.contains;
const max: typeof lib_plankton.list.max;
const min: typeof lib_plankton.list.min;
const maxarg: typeof lib_plankton.list.maxarg;
const minarg: typeof lib_plankton.list.minarg;
const distribute: typeof lib_plankton.list.distribute;
const lex: typeof lib_plankton.list.lex;
const lex_lt: typeof lib_plankton.list.lex_lt;
const lex_gt: typeof lib_plankton.list.lex_gt;
const lex_le: typeof lib_plankton.list.lex_le;
const lex_ge: typeof lib_plankton.list.lex_ge;
const lex_eq: typeof lib_plankton.list.lex_eq;
const lex_ne: typeof lib_plankton.list.lex_ne;
const filter_inplace: typeof lib_plankton.list.filter_inplace;
}
declare namespace lib_plankton.code {
/**
* @author fenris
@ -948,6 +1107,10 @@ declare namespace lib_plankton.json {
}
}
declare namespace lib_plankton.file {
/**
* @author fenris
*/
function exists(path: string): Promise<boolean>;
/**
* @author fenris
*/
@ -1350,3 +1513,242 @@ declare namespace lib_plankton.args {
}): string;
}
}
declare var plain_text_to_html: (text: string) => string;
/**
* @desc makes a valid
*/
declare var format_sentence: (str: string, rtl?: boolean, caseSense?: boolean) => string;
declare var fill_string_template: (template_string: string, object: any, fabric: Function, delimiter: string, default_string: string, sloppy: boolean) => string;
declare var make_string_template: (_template: string, _fabrics?: Object) => (object: {
[key: string]: string;
}) => string;
declare var make_eml_header: (object: {
[key: string]: string;
}) => string;
declare var make_eml_body: Object;
declare namespace lib_plankton.string {
/**
* @author neuc,frac
*/
function empty(str: string): boolean;
/**
* @desc returns a unique string
* @param {string} prefix an optional prefix for the generated string
* @return {string}
* @author fenris
*/
function generate(prefix?: string): string;
/**
* @author fenris
*/
function join(parts: Array<string>, glue?: string): string;
/**
* @desc splits a string, but returns an empty list, if the string is empty
* @param {string} chain
* @param {string} separator
* @return {Array<string>}
* @author fenris
*/
function split(chain: string, separator?: string): Array<string>;
/**
* @author neu3no
*/
function explode(str: string, needle: string, max: int): Array<string>;
/**
* @desc concats a given word with itself n times
* @param {string} word
* @param {int}
* @return {string}
* @author fenris
*/
function repeat(word: string, count: int): string;
/**
* @desc lengthens a string by repeatedly appending or prepending another string
* @param {string} word the string to pad
* @param {int} length the length, which the result shall have
* @param {string} symbol the string, which will be added (multiple times)
* @param {boolean} [prepend]; whether to prepend (~true) or append (~false); default: false
* @return {string} the padded string
* @author fenris
*/
function pad(word: string, length: int, symbol?: string, mode?: string): string;
/**
* @desc checks if a given string conttains a certain substring
* @param {string} string
* @param {string} part
* @return {boolean}
* @author fenris
*/
function contains(chain: string, part: string): boolean;
/**
* @desc checks if a given string starts with a certain substring
* @param {string} string
* @param {string} part
* @return {boolean}
* @author fenris
*/
function startsWith(chain: string, part: string): boolean;
/**
* @desc checks if a given string ends with a certain substring
* @param {string} string
* @param {string} part
* @return {boolean}
* @author fenris
*/
function endsWith(chain: string, part: string): boolean;
/**
* @desc count the occourrences of a string in a string
* @param string haystack_string the string wich should be examined
* @param string needle_string the string which should be counted
* @author neuc
*/
function count_occourrences(haystack_string: string, needle_string: string, check_escape: boolean): int;
/**
* @author fenris
*/
function replace(str: string, replacements: Array<{
from: string;
to: string;
}>, options?: {}): string;
/**
* @desc replaces occurences of "{{name}}" in a string by the corresponding values of an argument object
* @author fenris
*/
function coin(str: string, args: {
[id: string]: string;
}, options?: {
legacy?: boolean;
open?: string;
close?: string;
}): string;
/**
* @author fenris
* @deprecated use limit
*/
function cut(str: string, length: int, delimiter?: string): string;
/**
*/
function limit(str: string, options?: {
length?: int;
indicator?: string;
}): string;
/**
*/
function slice(str: string, size: int): Array<string>;
}
/**
* @deprecated
*/
declare namespace lib_string {
const empty: typeof lib_plankton.string.empty;
const generate: typeof lib_plankton.string.generate;
const split: typeof lib_plankton.string.split;
const explode: typeof lib_plankton.string.repeat;
const repeat: typeof lib_plankton.string.repeat;
const pad: typeof lib_plankton.string.pad;
const contains: typeof lib_plankton.string.contains;
const startsWith: typeof lib_plankton.string.startsWith;
const endsWith: typeof lib_plankton.string.endsWith;
const count_occourrences: typeof lib_plankton.string.count_occourrences;
const coin: typeof lib_plankton.string.coin;
const stance: typeof lib_plankton.string.coin;
const cut: typeof lib_plankton.string.cut;
}
declare namespace lib_plankton.string {
/**
* an implementation of c sprintf
* @param {string} string format string
* @param {array} args arguments which should be filled into
* @returns {string}
*/
var sprintf: (input: string, args?: Array<any>, original?: any) => string;
/**
* an implementation of c printf
* @param {string} string format string
* @param {array} args arguments which should be filled into
* @returns {string}
*/
function printf(format: any, args: any): void;
}
declare var sprintf: (input: string, args?: Array<any>, original?: any) => string;
declare var printf: typeof lib_plankton.string.printf;
declare var eml_log: any;
declare var track_exports: any;
declare var make_logger: (prefix: any, current_loglevel: any) => (obj: any, lvl: any) => void;
/**
* @author fenris
*/
declare namespace lib_plankton.xml {
/**
* @author fenris
*/
abstract class class_node {
/**
* @author fenris
*/
abstract compile(depth?: int): string;
}
/**
* @author fenris
*/
class class_node_text extends class_node {
/**
* @author fenris
*/
protected content: string;
/**
* @author fenris
*/
constructor(content: string);
/**
* @author fenris
*/
compile(depth?: int): string;
}
/**
* @author fenris
*/
class class_node_comment extends class_node {
/**
* @author fenris
*/
protected content: string;
/**
* @author fenris
*/
constructor(content: string);
/**
* @author fenris
*/
compile(depth?: int): string;
}
/**
* @author fenris
*/
class class_node_complex extends class_node {
/**
* @author fenris
*/
protected name: string;
/**
* @author fenris
*/
protected attributes: {
[key: string]: string;
};
/**
* @author fenris
*/
protected children: Array<class_node>;
/**
* @author fenris
*/
constructor(name: string, attributes?: {
[key: string]: string;
}, children?: any[]);
/**
* @author fenris
*/
compile(depth?: int): string;
}
}

File diff suppressed because it is too large Load diff

21
misc/conv Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env node
function main(args)
{
// args
const path_transform = ((args.length >= 0) ? args.shift() : "transform.js");
const path_data = ((args.length >= 0) ? args.shift() : "data.json");
// exec
const _fs = require("fs");
const data = JSON.parse(_fs.readFileSync(path_data).toString());
const transformation_code = _fs.readFileSync(path_transform).toString()
const sd = eval(transformation_code)(data);
// output
const output = (JSON.stringify(sd, undefined, "\t") + "\n");
process.stdout.write(output);
}
main(process.argv.slice(2));

View file

@ -1,23 +0,0 @@
{
"group": {
"attributes": [
"members"
]
},
"section": {
"attributes": [
"title",
"content"
]
},
"list": {
"attributes": [
"items"
]
},
"text": {
"attributes": [
"content"
]
}
}

View file

@ -1,36 +0,0 @@
# 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

View file

@ -1,169 +0,0 @@
{
"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"
}
}
]
}
}
}
}
]
}
}
}
}

View file

@ -0,0 +1,41 @@
{
"stock": {
"tetrahedron": {
"name": "Tetrahedron",
"vertices": 4,
"faces": 4,
"edges": 6
},
"hexahedron": {
"name": "Hexahedron",
"vertices": 8,
"faces": 6,
"edges": 12
},
"octahedron": {
"name": "Octahedron",
"vertices": 6,
"faces": 8,
"edges": 12
},
"dodecahedron": {
"name": "Dodecahedron",
"vertices": 20,
"faces": 12,
"edges": 30
},
"icosahedron": {
"name": "Icosahedron",
"vertices": 12,
"faces": 20,
"edges": 30
}
},
"order": [
"tetrahedron",
"hexahedron",
"octahedron",
"dodecahedron",
"icosahedron"
]
}

View file

@ -0,0 +1,51 @@
(data) => ({
"definitions": {
},
"content": {
"title": "Polyhedra",
"main": {
"kind": "section",
"data": {
"title": "Polyhedra",
"content": {
"kind": "group",
"data": {
"members": data.order.map(
name => ({
"kind": "section",
"data": {
"title": data.stock[name].name,
"content": {
"kind": "list",
"data": {
"items": [
{
"kind": "text",
"data": {
"content": ("vertices: " + data.stock[name].vertices.toFixed(0)),
}
},
{
"kind": "text",
"data": {
"content": ("faces: " + data.stock[name].faces.toFixed(0)),
}
},
{
"kind": "text",
"data": {
"content": ("edges: " + data.stock[name].edges.toFixed(0)),
}
},
]
}
}
}
})
)
}
}
}
}
}
})

View file

@ -0,0 +1,72 @@
(data) => ({
"definitions": {
},
"content": {
"title": "Polyhedra",
"main": {
"kind": "section",
"data": {
"title": "Polyhedra",
"content": {
"kind": "table",
"data": {
"head": [
{
"kind": "text",
"data": {
"content": "name"
}
},
{
"kind": "text",
"data": {
"content": "vertices"
}
},
{
"kind": "text",
"data": {
"content": "faces"
}
},
{
"kind": "text",
"data": {
"content": "edges"
}
}
],
"rows": data.order.map(
name => ([
{
"kind": "text",
"data": {
"content": data.stock[name].name
}
},
{
"kind": "code",
"data": {
"content": data.stock[name].vertices.toFixed(0)
}
},
{
"kind": "code",
"data": {
"content": data.stock[name].faces.toFixed(0)
}
},
{
"kind": "code",
"data": {
"content": data.stock[name].edges.toFixed(0)
}
}
])
),
}
}
}
}
}
})

View file

@ -1,15 +0,0 @@
- coproduct `element`
- group
- section
- list
- …
- coproduct `output`
- (markdown)
- html
- tex
- odt
- …
- coproduct `input`
- markdown

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

@ -1,31 +1,70 @@
function main() : void
declare var console;
async function main(args_raw : Array<string>) : Promise<void>
{
let element : type_element = element_make(
// args
const arg_handler : lib_plankton.args.class_handler = new lib_plankton.args.class_handler(
{
"kind": "group",
"data": {
"members": [
{
"kind": "text",
"data": {
"content": "foo"
}
},
{
"kind": "text",
"data": {
"content": "bar"
}
}
]
}
/*
"input": lib_plankton.args.class_argument.positional({
"index": 0,
"type": lib_plankton.args.enum_type.string,
"mode": lib_plankton.args.enum_mode.replace,
"default": null,
"info": "path to input file",
"name": "input",
}),
*/
"output": lib_plankton.args.class_argument.volatile({
"indicators_long": ["output"],
"indicators_short": ["o"],
"type": lib_plankton.args.enum_type.string,
"mode": lib_plankton.args.enum_mode.replace,
"default": "html",
"info": "output format",
"name": "output",
}),
"help": lib_plankton.args.class_argument.volatile({
"indicators_long": ["help"],
"indicators_short": ["h"],
"type": lib_plankton.args.enum_type.boolean,
"mode": lib_plankton.args.enum_mode.replace,
"default": false,
"info": "show help",
"name": "help",
}),
}
);
const output : type_output<string> = new type_output_html({});
const html : string = output.render_element(element);
process.stdout.write(html + "\n");
const args : Record<string, any> = arg_handler.read(lib_plankton.args.enum_environment.cli, args_raw.join(" "));
// process.stdout.write(JSON.stringify(args)); return;
// exec
if (args.help)
{
process.stdout.write(
arg_handler.generate_help(
{
}
)
);
}
else
{
const document_raw : string = lib_plankton.json.decode(await lib_plankton.file/*.read(args.input)*/.read_stdin());
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_document(document);
process.stdout.write(result + "\n");
}
}
main();
main(process.argv.slice(2))
.then(() => {})
.catch((reason) => {process.stderr.write(String(reason));})
;

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_code_data = {
content : string;
};
/**
*/
class type_object_code implements type_object
{
public readonly kind : string = "code";
public readonly data : type_object_code_data;
public constructor(data : type_object_code_data) {this.data = data;}
}
/**
*/
object_kind_register(
"code",
(data) => (
new type_object_code(
{
"content": data["content"],
}
)
)
);

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,32 @@
/**
*/
type type_object_link_data = {
target : string;
label : (null | string);
};
/**
*/
class type_object_link implements type_object
{
public readonly kind : string = "link";
public readonly data : type_object_link_data;
public constructor(data : type_object_link_data) {this.data = data;}
}
/**
*/
object_kind_register(
"link",
(data) => (
new type_object_link(
{
"target": data["target"],
"label": (data["label"] ?? null),
}
)
)
);

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,33 @@
/**
*/
type type_object_table_data = {
head : (null | Array<type_object>);
rows : Array<Array<type_object>>;
};
/**
* @todo check sanity (length of head and rows)
*/
class type_object_table implements type_object
{
public readonly kind : string = "table";
public readonly data : type_object_table_data;
public constructor(data : type_object_table_data) {this.data = data;}
}
/**
*/
object_kind_register(
"table",
(data) => (
new type_object_table(
{
"head": data["head"],
"rows": data["rows"],
}
)
)
);

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,62 +9,281 @@ class type_output_html implements type_output<string>
/**
*/
public render_element(
element : type_element
) : string
private render_object_internal(
object : type_object,
options : {
level ?: int;
depth ?: int;
} = {}
) : lib_plankton.xml.class_node
{
return lib_plankton.call.distinguish<string>(
element,
options = Object.assign(
{
"text": ({"content": content}) => (
"<span class=\"sd-text\">"
+
content
+
"</span>"
"level": 0,
"depth": 0,
},
options
);
return lib_plankton.call.distinguish<lib_plankton.xml.class_node>(
object,
{
"text": ({"content": content}) => new lib_plankton.xml.class_node_complex(
"span",
{
"class": "sd-text",
},
[
new lib_plankton.xml.class_node_text(content),
]
),
"group": ({"members": members}) => (
"<div class=\"sd-group\">\n"
+
members.map(x => this.render_element(x)).join("")
+
"</div>\n"
"code": ({"content": content}) => new lib_plankton.xml.class_node_complex(
"code",
{
"class": "sd-code",
},
[
new lib_plankton.xml.class_node_text(content),
]
),
"section": ({"title": title, "content": content}) => (
"<section class=\"sd-section\">\n"
+
"link": ({"target": target, "label": label}) => new lib_plankton.xml.class_node_complex(
"a",
{
"class": "sd-link",
"href": target,
},
(
"<header>"
+
title
+
"</header>"
(label === null)
? []
: [new lib_plankton.xml.class_node_text(label)]
)
),
"section": ({"title": title, "content": content}) => new lib_plankton.xml.class_node_complex(
"section",
{
"class": "sd-section",
},
[
new lib_plankton.xml.class_node_complex(
("h" + (options.level + 1).toFixed(0)),
{},
[
new lib_plankton.xml.class_node_text(title),
]
),
this.render_object_internal(
content,
{
"level": (options.level + 1),
"depth": (options.depth + 1),
}
),
]
),
"group": ({"members": members}) => new lib_plankton.xml.class_node_complex(
"div",
{
"class": "sd-group",
},
(
members
.map(
x => this.render_object_internal(
x,
{
"depth": options.depth,
"level": options.level,
}
)
)
)
),
"list": ({"items": items}) => new lib_plankton.xml.class_node_complex(
"ul",
{
"class": "sd-list",
},
(
items
.map(
item => new lib_plankton.xml.class_node_complex(
"li",
{},
[
this.render_object_internal(
item,
{
"level": options.level,
"depth": (options.depth + 1),
}
),
]
)
)
),
),
"table": ({"head": head, "rows": rows}) => new lib_plankton.xml.class_node_complex(
"table",
{
"class": "sd-table",
},
(
[]
.concat(
(head === null)
? []
: [
new lib_plankton.xml.class_node_complex(
"thead",
{},
[
new lib_plankton.xml.class_node_complex(
"tr",
{},
(
head.map(
cell => new lib_plankton.xml.class_node_complex(
"th",
{},
[
this.render_object_internal(
cell,
{
"level": options.level,
"depth": (options.depth + 1),
}
),
]
)
)
)
),
]
),
]
)
.concat(
[
new lib_plankton.xml.class_node_complex(
"tbody",
{},
(
rows.map(
row => new lib_plankton.xml.class_node_complex(
"tr",
{},
(
row.map(
cell => new lib_plankton.xml.class_node_complex(
"td",
{},
[
this.render_object_internal(
cell,
{
"level": options.level,
"depth": (options.depth + 1),
}
),
]
)
)
)
)
)
)
)
]
)
+
this.render_element(content)
+
"</section>\n"
),
"list": ({"items": items}) => (
"<ul class=\"sd-list\">\n"
+
items.map(x => this.render_element(x)).map(x => ("<li>" + x + "</li>\n")).join("")
+
"</ul>\n"
),
},
{
"fallback": (element) => (
"<pre class=\"sd-unhandled\" rel=\"" + element.kind + "\">"
+
JSON.stringify(element, undefined, " ")
+
"</pre>"
"fallback": (object) => new lib_plankton.xml.class_node_complex(
"pre",
{
"class": "sd-unhandled",
"rel": object.kind,
},
[
new lib_plankton.xml.class_node_text(
JSON.stringify(object, undefined, " "),
)
]
),
}
);
}
/**
* @implementation
*/
public render_object(
object : type_object
) : string
{
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

@ -0,0 +1,174 @@
/**
*/
class type_output_markdown implements type_output<string>
{
public readonly kind : string = "markdown";
public readonly data : {};
public constructor(data : {}) {this.data = data;}
/**
*/
private render_object_internal(
object : type_object,
options : {
depth ?: int;
headline_level ?: int;
list_level ?: int;
} = {}
) : string
{
options = Object.assign(
{
"depth": 0,
"headline_level": 0,
"list_level": 0,
},
options
);
return lib_plankton.call.distinguish<string>(
object,
{
"text": ({"content": content}) => lib_plankton.string.coin(
"{{content}}",
{
"content": content,
}
),
"code": ({"content": content}) => lib_plankton.string.coin(
"`{{content}}`",
{
"content": content,
}
),
"link": ({"target": target, "label": label}) => lib_plankton.string.coin(
"[{{label}}]({{target}})",
{
"target": target,
"label": label,
}
),
"section": ({"title": title, "content": content}) => lib_plankton.string.coin(
"{{head}}\n\n{{body}}\n\n\n",
{
"head": lib_plankton.string.coin(
"{{prefix}} {{value}}",
{
"prefix": "#".repeat(options.level + 1),
"value": title,
}
),
"body": this.render_object_internal(
content,
{
"depth": (options.depth + 1),
"headline_level": (options.level + 1),
"list_level": options.list_level,
}
),
}
),
"group": ({"members": members}) => lib_plankton.string.coin(
"{{members}}",
{
"members": (
members
.map(
x => this.render_object_internal(
x,
{
"depth": options.depth,
"headline_level": options.level,
"list_level": options.list_level
}
)
)
.join(
""
)
)
}
),
"list": ({"items": items}) => lib_plankton.string.coin(
"{{items}}",
{
"items": (
items
.map(
item => lib_plankton.string.coin(
"{{indentation}}- {{content}}",
{
"indentation": " ".repeat(options.list_level),
"content": this.render_object_internal(
item,
{
"depth": (options.depth + 1),
"headline_level": options.level,
"list_level": (options.list_level + 1),
}
),
},
)
)
.join(
"\n"
)
),
}
),
"table": ({"head": head, "rows": rows}) => lib_plankton.string.coin(
"(unhandled)",
{
}
),
},
{
"fallback": (object) => lib_plankton.string.coin(
"(unhandled)",
{
}
),
}
);
}
/**
* @implementation
*/
public render_object(
object : type_object
) : string
{
return this.render_object_internal(object);
}
/**
* @implementation
*/
public render_document(
document : type_document
) : string
{
return this.render_object_internal(
document.content_main,
{
}
);
}
}
/**
*/
output_kind_register(
"markdown",
(data, sub) => (
new type_output_markdown(
{
}
)
)
);

View file

@ -0,0 +1,267 @@
/**
*/
class type_output_tex implements type_output<string>
{
public readonly kind : string = "tex";
public readonly data : {};
public constructor(data : {}) {this.data = data;}
/**
*/
private static coin(
template : string,
arguments_ : Record<string, any>
) : string
{
return lib_plankton.string.coin(
template,
arguments_,
{
"open": "<<",
"close": ">>",
}
);
}
/**
*/
private render_object_internal(
object : type_object,
options : {
level ?: int;
depth ?: int;
} = {}
) : string
{
options = Object.assign(
{
"level": 0,
"depth": 0,
},
options
);
return lib_plankton.call.distinguish<string>(
object,
{
"text": ({"content": content}) => content,
"code": ({"content": content}) => type_output_tex.coin(
"\\( <<content>> \\)",
{
"content": content,
}
),
"link": ({"target": target, "label": label}) => type_output_tex.coin(
"\\href{<<target>>}{<<label>>}",
{
"target": target,
"label": label,
}
),
"section": ({"title": title, "content": content}) => type_output_tex.coin(
(
"\\begin{section}{<<title>>}\n"
+
"<<content>>\n"
+
"\\end{section}\n"
),
{
"title": title,
"content": this.render_object_internal(
content,
{
"level": (options.level + 1),
"depth": (options.depth + 1),
}
),
}
),
"group": ({"members": members}) => (
members
.map(
x => this.render_object_internal(
x,
{
"depth": options.depth,
"level": options.level,
}
)
)
.join("\n\n")
),
"list": ({"items": items}) => type_output_tex.coin(
(
"\\begin{itemize}\n"
+
"<<items>>"
+
"\\end{itemize}\n"
),
{
"items": (
items
.map(
item => type_output_tex.coin(
"\item{<<item>>}",
{
"item": this.render_object_internal(
item,
{
"level": options.level,
"depth": (options.depth + 1),
}
),
}
)
)
)
}
),
"table": ({"head": head, "rows": rows}) => type_output_tex.coin(
(
"\\begin{tabular}{<<definition>>}\n"
+
"<<head>> \\\\\n"
+
"\\hline\n"
+
"<<body>>\n"
+
"\\end{tabular}\n"
),
{
"definition": (
lib_plankton.list.sequence(head.length)
.map(x => "l")
.join("|")
),
"head": (
head
.map(
cell => this.render_object_internal(
cell,
{
"level": options.level,
"depth": (options.depth + 1),
}
)
)
.join(" & ")
),
"body": (
rows
.map(
row => (
row
.map(
cell => this.render_object_internal(
cell,
{
"level": options.level,
"depth": (options.depth + 1),
}
),
)
.join(" & ")
)
)
.join(" \\\\\n")
),
}
),
},
{
"fallback": (object) => type_output_tex.coin(
(
"\\begin{comment}\n"
+
"<<content>>"
+
"\\end{comment}\n"
),
{
"content": JSON.stringify(object, undefined, " "),
}
),
}
);
}
/**
* @implementation
*/
public render_object(
object : type_object
) : string
{
return this.render_object_internal(object);
}
/**
* @implementation
*/
public render_document(
document : type_document
) : string
{
return type_output_tex.coin(
(
"\\documentclass{article}\n"
+
"<<packages>>\n"
+
"<<settings>>\n"
+
"\\begin{document}\n"
+
"<<main>>\n"
+
"\\end{document}\n"
),
{
"packages": (
[
"hyperref",
"verbatim",
"fontspec",
"unicode-math",
]
.map(
name => ("\\usepackage{" + name + "}\n")
)
.join("")
),
"settings": (
"\\setmainfont{Linux Biolinum O}\n"
+
"\\setmathfont{Noto Mono}\n"
),
"main": this.render_object_internal(
document.content_main,
{
"depth": 1,
}
),
}
);
}
}
/**
*/
output_kind_register(
"tex",
(data, sub) => (
new type_output_tex(
{
}
)
)
);

View file

@ -24,14 +24,20 @@ _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/code.ts \
${dir_source}/objects/implementations/link.ts \
${dir_source}/objects/implementations/group.ts \
${dir_source}/objects/implementations/section.ts \
${dir_source}/objects/implementations/list.ts \
${dir_source}/objects/implementations/table.ts \
${dir_source}/document.ts \
${dir_source}/outputs/base.ts \
${dir_source}/outputs/implementations/json.ts \
${dir_source}/outputs/implementations/markdown.ts \
${dir_source}/outputs/implementations/html.ts \
${dir_source}/outputs/implementations/tex.ts \
${dir_source}/main.ts
@ ${cmd_log} "compiling …"
@ ${cmd_mkdir} $(dir $@)

View file

@ -10,9 +10,12 @@ dir="lib/plankton"
modules=""
modules="${modules} base"
modules="${modules} call"
modules="${modules} list"
modules="${modules} json"
modules="${modules} file"
modules="${modules} args"
modules="${modules} string"
modules="${modules} xml"
## exec