cleanup and comments
All checks were successful
Build and Deploy Client / build-and-deploy (push) Successful in 8s
All checks were successful
Build and Deploy Client / build-and-deploy (push) Successful in 8s
This commit is contained in:
@@ -1,18 +1,24 @@
|
||||
import { Component, ElementRef, Renderer2, ViewChild } from '@angular/core';
|
||||
import { ReactiveFormsModule, FormsModule, FormControl, FormGroup, FormBuilder } from '@angular/forms';
|
||||
import { FormsModule } from '@angular/forms'
|
||||
|
||||
// type descriptions
|
||||
|
||||
// a formatDescriptor contains information for the renderer to apply formatting styles to a node
|
||||
interface formatDescriptor {
|
||||
className: string;
|
||||
};
|
||||
|
||||
// a textNode is an element produced by the parser to link text to applied format specifiers. The renderer will
|
||||
// apply each style to the text in the node according to the styles registry.
|
||||
interface textNode {
|
||||
type: string;
|
||||
text: string;
|
||||
styles: string[]
|
||||
}
|
||||
|
||||
// a blockNode is an element produced by the parser to structure nodes by blocks. blocks contain child nodes, either
|
||||
// other blocks or text nodes at the bottom. A block node's html element type is described by kind: p, h1, h2, div, etc
|
||||
// Maybe we blocks can also have styles, and then we can join textNode and blockNode into a single type.
|
||||
interface blockNode {
|
||||
type: string;
|
||||
kind: string;
|
||||
@@ -20,6 +26,7 @@ interface blockNode {
|
||||
}
|
||||
|
||||
// styles registry: this maps format specifiers to css classes
|
||||
// might move this to its own file
|
||||
const styles: Record<string, formatDescriptor> = {
|
||||
B: {
|
||||
className: "format-bold"
|
||||
@@ -35,9 +42,10 @@ const styles: Record<string, formatDescriptor> = {
|
||||
},
|
||||
}; // i.e. %B{...} will apply "format-bold"
|
||||
|
||||
// angular component class
|
||||
@Component({
|
||||
selector: 'app-markleft',
|
||||
imports: [FormsModule, ReactiveFormsModule],
|
||||
imports: [FormsModule],
|
||||
templateUrl: './markleft.html',
|
||||
styleUrl: './markleft.scss',
|
||||
})
|
||||
@@ -45,41 +53,36 @@ export class Markleft {
|
||||
|
||||
@ViewChild('markup_container', { static: true }) container!: ElementRef;
|
||||
|
||||
constructor(private renderer: Renderer2, private fb: FormBuilder) {
|
||||
console.log("component constructor");
|
||||
constructor(private renderer: Renderer2) {
|
||||
// console.log("component constructor");
|
||||
}
|
||||
|
||||
ngOnInit() { // DOM manipulation can't occur in constructor
|
||||
|
||||
this.markupInput = this.fb.group({
|
||||
inputText: [this.liveText],
|
||||
});
|
||||
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
markupInput = new FormGroup({
|
||||
inputText: new FormControl("")
|
||||
});
|
||||
|
||||
onSubmit() {
|
||||
// live update on each text input.
|
||||
onTextUpdate(event: Event) {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
// full demo right here
|
||||
// default text
|
||||
liveText: string = `
|
||||
#H{Hello World!}
|
||||
#P{
|
||||
This is some markleft text. This is %I{italic} and this is %B{bold}. Some might %I{even be %B{both}}.
|
||||
This is some %B{PhAML} (%I{%B{Ph}ish %B{A}mazing %B{M}arkup %B{L}anguage}) text. This is %I{italic} and this is %B{bold}. Some might %I{even be %B{both}}.
|
||||
}
|
||||
This should be plain and unstylized.
|
||||
`; // TODO: live editor
|
||||
|
||||
// parses a single string into an array of nodes
|
||||
// like noted at parseStyle, maybe can return a single node which itself contains the array of children.
|
||||
parsePlaintext(input: string): (textNode | blockNode)[] {
|
||||
|
||||
let index: number = 0;
|
||||
let index: number = 0; // position in the input string
|
||||
let nodes: (textNode | blockNode)[] = [];
|
||||
|
||||
// TODO: I might restructure the node parsing so that it starts with a generic top level node and can process all children under that node
|
||||
function parseStyle(parentNode: blockNode | null = null, parentStyles: string[] | null = null) {
|
||||
|
||||
index++; // step onto specifier code
|
||||
@@ -104,19 +107,11 @@ export class Markleft {
|
||||
if(input[index] === "%") { // encountered another style specifier
|
||||
|
||||
// commit the current node
|
||||
const node: textNode = {
|
||||
type: "text",
|
||||
text: text,
|
||||
styles: styles
|
||||
};
|
||||
if(parentNode) {
|
||||
parentNode.children.push(node);
|
||||
} else {
|
||||
nodes.push(node);
|
||||
}
|
||||
addTextNode(text, styles, parentNode);
|
||||
text = ""; // clear the already commited text
|
||||
// and then move to the next
|
||||
parseStyle(parentNode ? parentNode : null, styles); // recursion
|
||||
|
||||
} else if(input[index] == "}") { // this node has closed
|
||||
addTextNode(text, styles, parentNode);
|
||||
//index++; // step to next
|
||||
@@ -127,6 +122,9 @@ export class Markleft {
|
||||
text += input[index];
|
||||
}
|
||||
}
|
||||
if(index >= input.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,15 +150,7 @@ export class Markleft {
|
||||
index++;
|
||||
if(input[index] === "%" || input[index] === "#") { // encountered another format specifier
|
||||
|
||||
// commit current plain text to the block
|
||||
if(text.length !== 0) {
|
||||
const textNode: textNode = {
|
||||
type: "text",
|
||||
text: text,
|
||||
styles: [] // none
|
||||
};
|
||||
node.children.push(textNode);
|
||||
}
|
||||
addTextNode(text, null, node);
|
||||
|
||||
text = ""; // clear the already commited text
|
||||
// and then move to the next
|
||||
@@ -188,6 +178,9 @@ export class Markleft {
|
||||
text += input[index];
|
||||
}
|
||||
}
|
||||
if(index >= input.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,23 +290,22 @@ export class Markleft {
|
||||
}
|
||||
|
||||
refresh() {
|
||||
if(this.markupInput.value.inputText) {
|
||||
|
||||
// clear children
|
||||
const parent = this.container.nativeElement;
|
||||
while (parent.firstChild) {
|
||||
this.renderer.removeChild(parent, parent.firstChild);
|
||||
}
|
||||
|
||||
// parse text
|
||||
const nodes: (textNode | blockNode)[] = this.parsePlaintext(this.markupInput.value.inputText);
|
||||
|
||||
// console.log(nodes)
|
||||
|
||||
// render nodes
|
||||
nodes.forEach((node) => {
|
||||
this.renderNode(node);
|
||||
});
|
||||
// clear children
|
||||
const parent = this.container.nativeElement;
|
||||
while (parent.firstChild) {
|
||||
this.renderer.removeChild(parent, parent.firstChild);
|
||||
}
|
||||
|
||||
// parse text
|
||||
const nodes: (textNode | blockNode)[] = this.parsePlaintext(this.liveText);
|
||||
|
||||
// console.log(nodes)
|
||||
|
||||
// render nodes
|
||||
nodes.forEach((node) => {
|
||||
this.renderNode(node);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user