mirror of
https://github.com/TxtDot/dalet.git
synced 2024-11-23 13:26:22 +03:00
feat: heading tag, new normalizers
This commit is contained in:
parent
599639dee6
commit
8530f84830
10 changed files with 134 additions and 46 deletions
|
@ -8,7 +8,9 @@
|
||||||
"/dist"
|
"/dist"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc"
|
"build": "tsc",
|
||||||
|
"start": "node ./dist/index.js",
|
||||||
|
"bstart": "tsc && node ./dist/index.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -31,10 +33,11 @@
|
||||||
"@eslint/js": "^9.7.0",
|
"@eslint/js": "^9.7.0",
|
||||||
"eslint": "9.x",
|
"eslint": "9.x",
|
||||||
"globals": "^15.8.0",
|
"globals": "^15.8.0",
|
||||||
"tsc": "^2.0.4",
|
"typescript": "^5.5.4",
|
||||||
"typescript-eslint": "^7.17.0"
|
"typescript-eslint": "^7.17.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@msgpack/msgpack": "3.0.0-beta2"
|
"@msgpack/msgpack": "3.0.0-beta2",
|
||||||
|
"zod": "^3.23.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
libs/typescript/pnpm-lock.yaml
generated
20
libs/typescript/pnpm-lock.yaml
generated
|
@ -11,6 +11,9 @@ importers:
|
||||||
'@msgpack/msgpack':
|
'@msgpack/msgpack':
|
||||||
specifier: 3.0.0-beta2
|
specifier: 3.0.0-beta2
|
||||||
version: 3.0.0-beta2
|
version: 3.0.0-beta2
|
||||||
|
zod:
|
||||||
|
specifier: ^3.23.8
|
||||||
|
version: 3.23.8
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@eslint/js':
|
'@eslint/js':
|
||||||
specifier: ^9.7.0
|
specifier: ^9.7.0
|
||||||
|
@ -21,9 +24,9 @@ importers:
|
||||||
globals:
|
globals:
|
||||||
specifier: ^15.8.0
|
specifier: ^15.8.0
|
||||||
version: 15.8.0
|
version: 15.8.0
|
||||||
tsc:
|
typescript:
|
||||||
specifier: ^2.0.4
|
specifier: ^5.5.4
|
||||||
version: 2.0.4
|
version: 5.5.4
|
||||||
typescript-eslint:
|
typescript-eslint:
|
||||||
specifier: ^7.17.0
|
specifier: ^7.17.0
|
||||||
version: 7.17.0(eslint@9.7.0)(typescript@5.5.4)
|
version: 7.17.0(eslint@9.7.0)(typescript@5.5.4)
|
||||||
|
@ -495,10 +498,6 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.2.0'
|
typescript: '>=4.2.0'
|
||||||
|
|
||||||
tsc@2.0.4:
|
|
||||||
resolution: {integrity: sha512-fzoSieZI5KKJVBYGvwbVZs/J5za84f2lSTLPYf6AGiIf43tZ3GNrI1QzTLcjtyDDP4aLxd46RTZq1nQxe7+k5Q==}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
type-check@0.4.0:
|
type-check@0.4.0:
|
||||||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
@ -534,6 +533,9 @@ packages:
|
||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
zod@3.23.8:
|
||||||
|
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@eslint-community/eslint-utils@4.4.0(eslint@9.7.0)':
|
'@eslint-community/eslint-utils@4.4.0(eslint@9.7.0)':
|
||||||
|
@ -1006,8 +1008,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
typescript: 5.5.4
|
typescript: 5.5.4
|
||||||
|
|
||||||
tsc@2.0.4: {}
|
|
||||||
|
|
||||||
type-check@0.4.0:
|
type-check@0.4.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
prelude-ls: 1.2.1
|
prelude-ls: 1.2.1
|
||||||
|
@ -1036,3 +1036,5 @@ snapshots:
|
||||||
word-wrap@1.2.5: {}
|
word-wrap@1.2.5: {}
|
||||||
|
|
||||||
yocto-queue@0.1.0: {}
|
yocto-queue@0.1.0: {}
|
||||||
|
|
||||||
|
zod@3.23.8: {}
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
import { encode, decode } from "@msgpack/msgpack";
|
import { encode, decode } from "@msgpack/msgpack";
|
||||||
import { ParseError, RawTag, Tag, RawTagAsArray, RawBody, Body } from "./types";
|
import {
|
||||||
|
ParseError,
|
||||||
|
RawTag,
|
||||||
|
Tag,
|
||||||
|
RawTagAsArray,
|
||||||
|
RawBody,
|
||||||
|
Body,
|
||||||
|
RootRaw,
|
||||||
|
} from "./types";
|
||||||
import El from "./tags/el";
|
import El from "./tags/el";
|
||||||
import { TagNormalizers } from "./normalizers";
|
import { TagNormalizers } from "./normalizers";
|
||||||
|
|
||||||
|
@ -39,7 +47,7 @@ export function parseBody(body: RawBody): Body {
|
||||||
|
|
||||||
if (Array.isArray(body)) {
|
if (Array.isArray(body)) {
|
||||||
if (Array.isArray(body[0])) {
|
if (Array.isArray(body[0])) {
|
||||||
return body.map(parseTag);
|
return body.map((t) => parseTag(t as RawTag));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof body[0] === "number") {
|
if (typeof body[0] === "number") {
|
||||||
|
@ -50,14 +58,14 @@ export function parseBody(body: RawBody): Body {
|
||||||
throw new ParseError("Invalid tag body");
|
throw new ParseError("Invalid tag body");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parse(root_data: Uint8Array): Tag[] {
|
export function parse(root_data: Uint8Array): Root {
|
||||||
let root = decode(root_data);
|
let root = decode(root_data);
|
||||||
|
|
||||||
if (!Array.isArray(root)) {
|
if (!Array.isArray(root)) {
|
||||||
throw new ParseError("Daletl root must be array");
|
throw new ParseError("Daletl root must be array");
|
||||||
}
|
}
|
||||||
|
|
||||||
return root.map(parseTag);
|
return new Root(root.map(parseTag));
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Root {
|
export class Root {
|
||||||
|
@ -66,8 +74,12 @@ export class Root {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get raw(): RootRaw {
|
||||||
|
return this.root.map((t) => t.raw);
|
||||||
|
}
|
||||||
|
|
||||||
encode(): Uint8Array {
|
encode(): Uint8Array {
|
||||||
return encode(this.root.map((t) => t.encode()));
|
return encode(this.raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
toHtml(classes?: boolean): string {
|
toHtml(classes?: boolean): string {
|
||||||
|
|
|
@ -1,17 +1,30 @@
|
||||||
import { parseBody } from "./main";
|
import { parseBody } from "./main";
|
||||||
import El from "./tags/el";
|
import El from "./tags/el";
|
||||||
import { ParseError, RawTagAsArray } from "./types";
|
import Heading from "./tags/heading";
|
||||||
|
import { RawTagAsArray } from "./types";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
export function ElNormalizer(tag: RawTagAsArray): El {
|
const TagNormalizers = [
|
||||||
let body = parseBody(tag[1]);
|
n(
|
||||||
|
z.custom((b) => b !== null),
|
||||||
if (body == null) {
|
z.any(),
|
||||||
throw new ParseError("Invalid tag body, must be not null");
|
El
|
||||||
}
|
),
|
||||||
|
n(z.string(), z.number().int().min(1).max(6), Heading),
|
||||||
return new El(body);
|
];
|
||||||
}
|
|
||||||
|
|
||||||
const TagNormalizers = [ElNormalizer];
|
|
||||||
|
|
||||||
export { TagNormalizers };
|
export { TagNormalizers };
|
||||||
|
|
||||||
|
function n(body: z.ZodTypeAny, argument: z.ZodTypeAny, T: any) {
|
||||||
|
return (tag: RawTagAsArray) => {
|
||||||
|
let parsedBody = parseBody(tag[1]);
|
||||||
|
|
||||||
|
z.tuple([z.number().int(), body, argument]).parse([
|
||||||
|
tag[0],
|
||||||
|
parsedBody,
|
||||||
|
tag[2],
|
||||||
|
]);
|
||||||
|
|
||||||
|
return new T(parsedBody, tag[2]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { bodyToRaw } from "../../utils";
|
import { bodyToRaw, chtml } from "../../utils";
|
||||||
import { RawTag, Tag, Body } from "../types";
|
import { RawTag, Tag, Body } from "../types";
|
||||||
|
|
||||||
export default class El extends Tag {
|
export default class El extends Tag {
|
||||||
|
@ -6,11 +6,11 @@ export default class El extends Tag {
|
||||||
super(0, body, null);
|
super(0, body, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get raw(): RawTag {
|
get raw(): RawTag {
|
||||||
return bodyToRaw(this.body);
|
return bodyToRaw(this.body)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public toHtml(classes?: boolean): string {
|
toHtml(classes?: boolean): string {
|
||||||
return "";
|
return chtml("section", "el", classes, this.body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
libs/typescript/src/daletl/tags/heading.ts
Normal file
17
libs/typescript/src/daletl/tags/heading.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import { chtml } from "../../utils";
|
||||||
|
import { Tag } from "../types";
|
||||||
|
|
||||||
|
export default class Heading extends Tag {
|
||||||
|
constructor(body: string, argument: number) {
|
||||||
|
super(1, body, argument);
|
||||||
|
}
|
||||||
|
|
||||||
|
toHtml(classes?: boolean): string {
|
||||||
|
return chtml(
|
||||||
|
`h${this.argument}`,
|
||||||
|
`h hl${this.argument}`,
|
||||||
|
classes,
|
||||||
|
this.body
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
12
libs/typescript/src/index.ts
Normal file
12
libs/typescript/src/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { parse, Root, El, Heading } from "./lib";
|
||||||
|
|
||||||
|
let data = new Root([
|
||||||
|
new El("I am Element"),
|
||||||
|
new Heading("I am heading", 1),
|
||||||
|
]).encode();
|
||||||
|
|
||||||
|
let root = parse(data);
|
||||||
|
|
||||||
|
console.log(root.raw, "\n");
|
||||||
|
console.log(root.toHtml());
|
||||||
|
console.log(root.toHtml(false));
|
|
@ -1,2 +1,5 @@
|
||||||
export { parse } from "./daletl/main";
|
import El from "./daletl/tags/el";
|
||||||
export * as converters from "./converters/main";
|
import Heading from "./daletl/tags/heading";
|
||||||
|
|
||||||
|
export { parse, Root } from "./daletl/main";
|
||||||
|
export { El, Heading };
|
||||||
|
|
|
@ -14,20 +14,45 @@ export function bodyToRaw(body: Body): RawBody {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function bodyToHtml(body: Body): string {
|
||||||
|
if (typeof body === "string") {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(body)) {
|
||||||
|
return body.map((t) => t.toHtml()).join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
export function getRaw(t: Tag): RawTag {
|
export function getRaw(t: Tag): RawTag {
|
||||||
return t.raw;
|
return t.raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
[key: string]: string;
|
[key: string]: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hy(tag: string, body?: string, props?: Props) {
|
export function chtml(
|
||||||
return `<${tag} ${
|
tag: string,
|
||||||
props
|
classNames: string,
|
||||||
? Object.entries(props)
|
classes: boolean = true,
|
||||||
.map(([key, value]) => `${key}="${value}"`)
|
body?: Body,
|
||||||
.join(" ")
|
props?: Props
|
||||||
: ""
|
) {
|
||||||
}>${body}</${tag}>`;
|
let classProp = classes ? { class: classNames } : {};
|
||||||
|
return html(tag, body, { ...props, ...classProp });
|
||||||
|
}
|
||||||
|
|
||||||
|
function html(tag: string, body?: Body, props?: Props) {
|
||||||
|
let pr = Object.entries(props || {})
|
||||||
|
.map(([key, value]) => `${key}="${value}"`)
|
||||||
|
.join(" ");
|
||||||
|
|
||||||
|
if (!body) {
|
||||||
|
return `<${tag}${pr ? " " + pr : ""}/>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<${tag}${pr ? " " + pr : ""}>${bodyToHtml(body)}</${tag}>`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es2019",
|
"target": "es2019",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"outDir": "./dist"
|
"outDir": "./dist",
|
||||||
|
"strict": true
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"]
|
"include": ["src/**/*"]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue