markup is making progress
All checks were successful
Build and Deploy Client / build-and-deploy (push) Successful in 13s
All checks were successful
Build and Deploy Client / build-and-deploy (push) Successful in 13s
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, ElementRef, Renderer2, ViewChild } from '@angular/core';
|
||||
|
||||
// type descriptions
|
||||
|
||||
@@ -9,7 +9,7 @@ interface formatDescriptor {
|
||||
interface textNode {
|
||||
type: string;
|
||||
text: string;
|
||||
styles: formatDescriptor[]
|
||||
styles: string[]
|
||||
}
|
||||
|
||||
interface blockNode {
|
||||
@@ -29,6 +29,9 @@ const styles: Record<string, formatDescriptor> = {
|
||||
U: {
|
||||
className: "format-underline"
|
||||
},
|
||||
P: { // for testing. TODO: right now everything is a style
|
||||
className: "format-plain"
|
||||
},
|
||||
}; // i.e. %B{...} will apply "format-bold"
|
||||
|
||||
@Component({
|
||||
@@ -39,15 +42,102 @@ const styles: Record<string, formatDescriptor> = {
|
||||
})
|
||||
export class Markleft {
|
||||
|
||||
@ViewChild('markup_container', { static: true }) container!: ElementRef;
|
||||
|
||||
constructor(private renderer: Renderer2) {
|
||||
console.log("component constructor");
|
||||
}
|
||||
|
||||
ngOnInit() { // DOM manipulation can't occur in constructor
|
||||
|
||||
const nodes: textNode[] = this.parsePlaintext("%P{this is a %B{test.} This should be unbolded. But %I{this} should be italicized.}");
|
||||
console.log(nodes);
|
||||
nodes.forEach((node) => {
|
||||
this.renderNode(node);
|
||||
});
|
||||
}
|
||||
|
||||
// full demo right here
|
||||
plaintext: String = `
|
||||
#H1{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 should be plain and unstylized.
|
||||
`;
|
||||
`; // TODO: live editor
|
||||
|
||||
parsePlaintext(input: string): /*structureNode[]*/ void {
|
||||
parsePlaintext(input: string): textNode[] {
|
||||
|
||||
let index: number = 0;
|
||||
let nodes: textNode[] = [];
|
||||
|
||||
// starting with ONLY text styles, no structure blocks yet
|
||||
function parseStyle(parentStyles: string | null = null) {
|
||||
index++; // step onto specifier code
|
||||
const code: string = input[index]; // TODO: validate if this code is a usable code
|
||||
index++;
|
||||
if(input[index] !== "{") { // TODO: implement some expect("{") function to better validate
|
||||
console.log("{ not found following format specifier");
|
||||
// return null node
|
||||
}
|
||||
console.log("Parsing text for format specifier", code);
|
||||
|
||||
let styles: string[] = [];
|
||||
if(parentStyles) {
|
||||
styles = [...parentStyles, code] // append style code to styles list of this node
|
||||
} else {
|
||||
styles = [code];
|
||||
}
|
||||
|
||||
let text: string = "";
|
||||
while(true) { // assemble text
|
||||
index++;
|
||||
console.log(input[index])
|
||||
if(input[index] === "%") { // encountered another style specifier
|
||||
|
||||
// commit the current node
|
||||
const node: textNode = {
|
||||
type: "text",
|
||||
text: text,
|
||||
styles: styles
|
||||
};
|
||||
nodes.push(node);
|
||||
text = ""; // clear the already commited text
|
||||
// and then move to the next
|
||||
parseStyle(); // recursion
|
||||
} else if(input[index] == "}") { // this node has closed
|
||||
const node: textNode = {
|
||||
type: "text",
|
||||
text: text,
|
||||
styles: styles
|
||||
};
|
||||
nodes.push(node);
|
||||
break;
|
||||
} else { // regular text
|
||||
text += input[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parse(endChar: string | null = null) {
|
||||
console.log("parsing...");
|
||||
while(index < input.length) {
|
||||
if(endChar && (input[index] === endChar)) {
|
||||
index++;
|
||||
break;
|
||||
}
|
||||
if(input[index] === "%") { // encountered a style specifier
|
||||
parseStyle();
|
||||
} else if(input[index] === "#") { // encountered a structure specifier
|
||||
// nodes.push(parseStructure());
|
||||
} else if(input[index] === "@") { // encountered an attribute specifier
|
||||
// nodes.push(parseAttribute());
|
||||
} else {
|
||||
// regular character
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* pseudocode (c lol)
|
||||
|
||||
@@ -89,23 +179,30 @@ export class Markleft {
|
||||
... and so on for parseBlock and parseText
|
||||
|
||||
*/
|
||||
return;
|
||||
|
||||
parse();
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
renderNode(node: (textNode | blockNode)): void {
|
||||
renderNode(node: textNode): void {
|
||||
|
||||
console.log("rendering...");
|
||||
|
||||
/*
|
||||
if(node.type == "text") { // text nodes only need span elements
|
||||
|
||||
element span = html.createElement("span"); // or whatever it is
|
||||
|
||||
// add styles
|
||||
foreach(style style in node.styles) {
|
||||
span.classes.add(styles[style].className);
|
||||
}
|
||||
return span;
|
||||
|
||||
} else if(node.type == "block") {
|
||||
const span = this.renderer.createElement("span"); // create container
|
||||
|
||||
node.styles.forEach((style) => {
|
||||
this.renderer.addClass(span, styles[style].className);
|
||||
});
|
||||
|
||||
const text = this.renderer.createText(node.text); // create text
|
||||
|
||||
this.renderer.appendChild(span, text); // add text to container
|
||||
this.renderer.appendChild(this.container.nativeElement, span); // add container to DOM
|
||||
|
||||
} /* else if(node.type == "block") {
|
||||
|
||||
element block = html.createElement(node.kind); // or whatever it is
|
||||
|
||||
@@ -115,9 +212,7 @@ export class Markleft {
|
||||
}
|
||||
return block;
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
} */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user