feat: add typescript lib, add daletl parser, add html converter

This commit is contained in:
Artemy Egorov 2024-07-24 23:48:18 +03:00
parent dfa42ae830
commit bc6b6a7db4
10 changed files with 224 additions and 0 deletions

View file

@ -0,0 +1,14 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {}
}

View file

@ -0,0 +1,36 @@
{
"name": "@txtdot/dalet",
"version": "1.0.0-pre0",
"description": "Dalet realization in typescript",
"main": "dist/lib.js",
"types": "dist/lib.d.ts",
"files": [
"/dist"
],
"scripts": {
"build": "tsc"
},
"repository": {
"type": "git",
"url": "git+https://github.com/TxtDot/dalet.git"
},
"keywords": [
"dalet",
"markup-language",
"markup",
"language",
"web"
],
"author": "artegoser",
"license": "MIT",
"bugs": {
"url": "https://github.com/TxtDot/dalet/issues"
},
"homepage": "https://github.com/TxtDot/dalet#readme",
"devDependencies": {
"tsc": "^2.0.4"
},
"dependencies": {
"@msgpack/msgpack": "3.0.0-beta2"
}
}

View file

@ -0,0 +1,33 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
'@msgpack/msgpack':
specifier: 3.0.0-beta2
version: 3.0.0-beta2
devDependencies:
tsc:
specifier: ^2.0.4
version: 2.0.4
packages:
'@msgpack/msgpack@3.0.0-beta2':
resolution: {integrity: sha512-y+l1PNV0XDyY8sM3YtuMLK5vE3/hkfId+Do8pLo/OPxfxuFAUwcGz3oiiUuV46/aBpwTzZ+mRWVMtlSKbradhw==}
engines: {node: '>= 14'}
tsc@2.0.4:
resolution: {integrity: sha512-fzoSieZI5KKJVBYGvwbVZs/J5za84f2lSTLPYf6AGiIf43tZ3GNrI1QzTLcjtyDDP4aLxd46RTZq1nQxe7+k5Q==}
hasBin: true
snapshots:
'@msgpack/msgpack@3.0.0-beta2': {}
tsc@2.0.4: {}

View file

@ -0,0 +1,51 @@
import { Root, Tag } from "../daletl/types";
interface Props {
[key: string]: string;
}
function hy(tag: string, body?: string, props?: Props) {
return `<${tag} ${
props
? Object.entries(props)
.map(([key, value]) => `${key}="${value}"`)
.join(" ")
: ""
}>${body}</${tag}>`;
}
function comp(
name: string,
body: string | Tag[],
classNames: string,
classes: boolean,
props: Props = {}
): string {
let realBody = Array.isArray(body)
? body.map((b) => htmlTag(b, classes)).join("")
: body;
return hy(name, realBody, {
class: classes ? classNames : undefined,
...props,
});
}
function element(tag: Tag, classes: boolean): string {
return comp("section", tag.body, "el", classes);
}
function heading(tag: Tag, classes: boolean): string {
if (typeof tag.argument !== "number") {
return comp("h1", tag.body, "h", classes);
}
return comp(`h${tag.argument}`, tag.body, `h hl${tag.argument}`, classes);
}
function htmlTag(tag: Tag, classes: boolean): string {
return [element, heading][tag.id](tag, classes);
}
export function toHtml(root: Root, classes: boolean = true): string {
return root.map((t) => htmlTag(t, classes)).join("");
}

View file

@ -0,0 +1 @@
export { toHtml } from "./html";

View file

@ -0,0 +1,64 @@
import { encode, decode } from "@msgpack/msgpack";
import { ParseError, Root, Tag } from "./types";
export function parseRawTag(raw_tag: any[] | string): Tag {
if (typeof raw_tag === "string") {
return {
id: 0,
body: raw_tag,
argument: null,
};
}
if (Array.isArray(raw_tag)) {
if (Array.isArray(raw_tag[0])) {
return {
id: 0,
body: parseRawTagBody(raw_tag),
argument: null,
};
}
if (typeof raw_tag[0] === "number") {
return {
id: raw_tag[0],
body: parseRawTagBody(raw_tag[1]),
argument: raw_tag[3] || null,
};
}
}
throw new ParseError("Invalid tag");
}
export function parseRawTagBody(body: string | null | any[]): Tag["body"] {
if (typeof body === "string") {
return body;
}
if (body === null) {
return null;
}
if (Array.isArray(body)) {
if (Array.isArray(body[0])) {
return body.map(parseRawTag);
}
if (typeof body[0] === "number") {
return [parseRawTag(body)];
}
}
throw new ParseError("Invalid tag body");
}
export function parse(root_data?: Uint8Array): Root {
let root = root_data ? decode(root_data) : [];
if (!Array.isArray(root)) {
throw new ParseError("Daletl root must be array");
}
return root.map(parseRawTag);
}

View file

@ -0,0 +1,14 @@
export interface Tag {
id: number;
body: string | null | Tag[];
argument: number | string | null;
}
export type Root = Tag[];
export class ParseError extends Error {
constructor(message: string = "Parse error") {
super(message);
this.name = "ParseError";
}
}

View file

@ -0,0 +1,2 @@
export { parse } from "./daletl/main";
export * as converters from "./converters/main";

View file

@ -0,0 +1,9 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2019",
"declaration": true,
"outDir": "./dist"
},
"include": ["src/**/*"]
}