stashing
This commit is contained in:
parent
69fd9a1753
commit
8e0eee5847
8 changed files with 220 additions and 70 deletions
6
src/features/source/index.ts
Normal file
6
src/features/source/index.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
export type { Source } from './source';
|
||||
|
||||
export { createParser as createHtmlParser } from './parser/html';
|
||||
export { createParser as createMarkdownParser } from './parser/markdown';
|
||||
export { createSource } from './source';
|
28
src/features/source/parser.ts
Normal file
28
src/features/source/parser.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
enum Decoration {
|
||||
None = 0,
|
||||
Bold = 1,
|
||||
Italic = 2,
|
||||
Underline = 4,
|
||||
StrikeThrough = 8,
|
||||
}
|
||||
|
||||
interface TextNode {
|
||||
type: 'text';
|
||||
decoration: Decoration;
|
||||
nodes: (string | Node)[];
|
||||
}
|
||||
|
||||
interface HeaderNode {
|
||||
type: 'header';
|
||||
nodes: Node[];
|
||||
}
|
||||
|
||||
type Node = TextNode | HeaderNode;
|
||||
|
||||
export interface RichTextAST {
|
||||
nodes: Node[];
|
||||
}
|
||||
|
||||
export interface Parser {
|
||||
parse(source: string): RichTextAST;
|
||||
}
|
9
src/features/source/parser/html.ts
Normal file
9
src/features/source/parser/html.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { Parser } from "../parser";
|
||||
|
||||
export function createParser(): Parser {
|
||||
return {
|
||||
parse(value) {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
}
|
80
src/features/source/parser/markdown.ts
Normal file
80
src/features/source/parser/markdown.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
import { Parser } from "../parser";
|
||||
|
||||
export function createParser(): Parser {
|
||||
return {
|
||||
parse(source) {
|
||||
// console.log(source);
|
||||
|
||||
for (const token of tokenize(source)) {
|
||||
console.log(token);
|
||||
}
|
||||
|
||||
return {
|
||||
nodes: [],
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// const states = {
|
||||
// none(): State {
|
||||
|
||||
// },
|
||||
// } as const;
|
||||
|
||||
|
||||
type Token = { start: number, length: number } & (
|
||||
| { kind: 'bold' }
|
||||
| { kind: 'italic' }
|
||||
| { kind: 'underline' }
|
||||
| { kind: 'strikethrough' }
|
||||
| { kind: 'header', level: number }
|
||||
| { kind: 'text', value: string }
|
||||
);
|
||||
function* tokenize(characters: string): Generator<Token, void, unknown> {
|
||||
let buffer: string = '';
|
||||
let clearBuffer = false;
|
||||
let start = 0;
|
||||
let i = 0;
|
||||
|
||||
for (const character of characters) {
|
||||
if (buffer.length === 0) {
|
||||
start = i;
|
||||
}
|
||||
|
||||
buffer += character;
|
||||
const length = buffer.length;
|
||||
|
||||
if (buffer === '**') {
|
||||
yield { kind: 'bold', start, length };
|
||||
clearBuffer = true;
|
||||
}
|
||||
else if (buffer === '') {
|
||||
yield { kind: 'italic', start, length };
|
||||
clearBuffer = true;
|
||||
}
|
||||
else if (buffer === ':') {
|
||||
yield { kind: 'underline', start, length };
|
||||
clearBuffer = true;
|
||||
}
|
||||
else if (buffer === ':') {
|
||||
yield { kind: 'strikethrough', start, length };
|
||||
clearBuffer = true;
|
||||
}
|
||||
else if (buffer.length > 1 && buffer.startsWith('#') && buffer.endsWith(' ')) {
|
||||
yield { kind: 'header', start, length, level: buffer.length - 1 };
|
||||
clearBuffer = true;
|
||||
}
|
||||
else if (buffer.length > 1 && buffer.startsWith('"') && buffer.endsWith('"')) {
|
||||
yield { kind: 'text', start, length, value: buffer.slice(1, buffer.length - 1) };
|
||||
clearBuffer = true;
|
||||
}
|
||||
|
||||
if (clearBuffer) {
|
||||
buffer = '';
|
||||
clearBuffer = false;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
31
src/features/source/source.ts
Normal file
31
src/features/source/source.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { createEffect, createSignal, Signal } from "solid-js";
|
||||
import { Parser, RichTextAST } from "./parser";
|
||||
|
||||
export interface Source<TIn extends Parser, TOut extends Parser> {
|
||||
readonly in: Signal<string>;
|
||||
readonly out: Signal<string>;
|
||||
}
|
||||
|
||||
export function createSource<TIn extends Parser, TOut extends Parser>(inParser: TIn, outParser: TOut, initalValue: string): Source<TIn, TOut> {
|
||||
const [inValue, setIn] = createSignal<string>(initalValue);
|
||||
const [outValue, setOut] = createSignal<string>('');
|
||||
|
||||
const [ast, setAst] = createSignal<RichTextAST>();
|
||||
|
||||
createEffect(() => {
|
||||
setAst(inParser.parse(inValue()));
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
setAst(outParser.parse(outValue()));
|
||||
});
|
||||
|
||||
return {
|
||||
get in() {
|
||||
return [inValue, setIn] as Signal<string>;
|
||||
},
|
||||
get out() {
|
||||
return [outValue, setOut] as Signal<string>;
|
||||
},
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue