fix: refactor, tag classes, daletl add data type of tag

This commit is contained in:
Artemy Egorov 2024-07-25 15:55:09 +03:00
parent bc6b6a7db4
commit 599639dee6
12 changed files with 1178 additions and 99 deletions

View file

@ -1,14 +0,0 @@
{
"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,11 @@
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
export default [
{files: ["**/*.{js,mjs,cjs,ts}"]},
{languageOptions: { globals: globals.browser }},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
];

View file

@ -28,7 +28,11 @@
},
"homepage": "https://github.com/TxtDot/dalet#readme",
"devDependencies": {
"tsc": "^2.0.4"
"@eslint/js": "^9.7.0",
"eslint": "9.x",
"globals": "^15.8.0",
"tsc": "^2.0.4",
"typescript-eslint": "^7.17.0"
},
"dependencies": {
"@msgpack/msgpack": "3.0.0-beta2"

File diff suppressed because it is too large Load diff

View file

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

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

View file

@ -1,37 +1,34 @@
import { encode, decode } from "@msgpack/msgpack";
import { ParseError, Root, Tag } from "./types";
import { ParseError, RawTag, Tag, RawTagAsArray, RawBody, Body } from "./types";
import El from "./tags/el";
import { TagNormalizers } from "./normalizers";
export function parseRawTag(raw_tag: any[] | string): Tag {
export function parseTag(raw_tag: RawTag): Tag {
if (typeof raw_tag === "string") {
return {
id: 0,
body: raw_tag,
argument: null,
};
return new El(raw_tag);
}
if (typeof raw_tag === "number") {
return TagNormalizers[raw_tag]([raw_tag, null]);
}
if (Array.isArray(raw_tag)) {
if (Array.isArray(raw_tag[0])) {
return {
id: 0,
body: parseRawTagBody(raw_tag),
argument: null,
};
raw_tag = raw_tag as RawTag[];
return new El(raw_tag.map(parseTag));
}
if (typeof raw_tag[0] === "number") {
return {
id: raw_tag[0],
body: parseRawTagBody(raw_tag[1]),
argument: raw_tag[3] || null,
};
return TagNormalizers[(raw_tag as RawTagAsArray)[0]](
raw_tag as RawTagAsArray
);
}
}
throw new ParseError("Invalid tag");
}
export function parseRawTagBody(body: string | null | any[]): Tag["body"] {
export function parseBody(body: RawBody): Body {
if (typeof body === "string") {
return body;
}
@ -42,23 +39,38 @@ export function parseRawTagBody(body: string | null | any[]): Tag["body"] {
if (Array.isArray(body)) {
if (Array.isArray(body[0])) {
return body.map(parseRawTag);
return body.map(parseTag);
}
if (typeof body[0] === "number") {
return [parseRawTag(body)];
return [parseTag(body)];
}
}
throw new ParseError("Invalid tag body");
}
export function parse(root_data?: Uint8Array): Root {
let root = root_data ? decode(root_data) : [];
export function parse(root_data: Uint8Array): Tag[] {
let root = decode(root_data);
if (!Array.isArray(root)) {
throw new ParseError("Daletl root must be array");
}
return root.map(parseRawTag);
return root.map(parseTag);
}
export class Root {
root: Tag[];
constructor(root: Tag[]) {
this.root = root;
}
encode(): Uint8Array {
return encode(this.root.map((t) => t.encode()));
}
toHtml(classes?: boolean): string {
return this.root.map((t) => t.toHtml(classes)).join("");
}
}

View file

@ -0,0 +1,17 @@
import { parseBody } from "./main";
import El from "./tags/el";
import { ParseError, RawTagAsArray } from "./types";
export function ElNormalizer(tag: RawTagAsArray): El {
let body = parseBody(tag[1]);
if (body == null) {
throw new ParseError("Invalid tag body, must be not null");
}
return new El(body);
}
const TagNormalizers = [ElNormalizer];
export { TagNormalizers };

View file

@ -0,0 +1,16 @@
import { bodyToRaw } from "../../utils";
import { RawTag, Tag, Body } from "../types";
export default class El extends Tag {
constructor(body: string | Tag[]) {
super(0, body, null);
}
public get raw(): RawTag {
return bodyToRaw(this.body);
}
public toHtml(classes?: boolean): string {
return "";
}
}

View file

@ -1,10 +1,13 @@
export interface Tag {
id: number;
body: string | null | Tag[];
argument: number | string | null;
}
import { encode } from "@msgpack/msgpack";
import { bodyToRaw } from "../utils";
export type Root = Tag[];
export type RawBody = string | null | RawTag[] | RawTag;
export type RawId = number;
export type RawArgument = number | string | null;
export type RawTagAsArray = [RawId, RawBody, RawArgument] | [RawId, RawBody];
export type RawTag = RawTagAsArray | number | string | RawTag[];
export type RootRaw = RawTag[];
export class ParseError extends Error {
constructor(message: string = "Parse error") {
@ -12,3 +15,33 @@ export class ParseError extends Error {
this.name = "ParseError";
}
}
export abstract class Tag {
id: number;
body: Body;
argument: Argument;
constructor(id: number, body: Body, argument: Argument) {
this.id = id;
this.body = body;
this.argument = argument;
}
get raw(): RawTag {
if (this.argument == null) {
if (this.body == null) {
return this.id;
}
return [this.id, bodyToRaw(this.body)];
}
return [this.id, bodyToRaw(this.body), this.argument];
}
encode(): Uint8Array {
return encode(this.raw);
}
abstract toHtml(classes?: boolean): string;
}
export type Body = string | Tag[] | null;
export type Argument = RawArgument;
export type TagNormalizer = (tag: RawTagAsArray) => Tag;

View file

@ -0,0 +1,33 @@
import { Body, ParseError, RawBody, RawTag, Tag } from "./daletl/types";
export function bodyToRaw(body: Body): RawBody {
if (typeof body === "string") {
return body;
}
if (Array.isArray(body)) {
if (Array.isArray(body[0])) {
return body.map(getRaw);
}
}
return null;
}
export function getRaw(t: Tag): RawTag {
return t.raw;
}
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}>`;
}