diff --git a/client/src/app/markleft/markleft.ts b/client/src/app/markleft/markleft.ts index a089383..11d9fb0 100644 --- a/client/src/app/markleft/markleft.ts +++ b/client/src/app/markleft/markleft.ts @@ -36,12 +36,30 @@ const styles: Record = { }, U: { className: "format-underline" - }, - P: { // for testing. TODO: right now everything is a style - className: "format-plain" - }, + } }; // i.e. %B{...} will apply "format-bold" +// blocks registry: this maps format specifiers to html block types +// if moved to another file, should stick next to the styles registry +const blocks: Record = { + H1: { + className: "h1" + }, + H2: { + className: "h2" + }, + H3: { + className: "h3" + }, + P: { + className: "p" + }, + D: { + className: "div" + } + // TODO: lists +}; // i.e. #H1{...} will create a h1 element + // angular component class @Component({ selector: 'app-markleft', @@ -54,7 +72,7 @@ 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 @@ -68,12 +86,13 @@ export class Markleft { // default text liveText: string = ` - #H{Hello World!} + #H1{Hello World!} + #H2{hi mom !!} #P{ - 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 is some %B{PhAML} (%I{%B{Ph}ishly %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. @@ -85,42 +104,41 @@ export class Markleft { // 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 - const code: string = input[index]; // TODO: validate if this code is a usable code + // step onto format specifier code index++; - if(input[index] !== "{") { // TODO: implement some expect("{") function to better validate - console.log("{ not found following format specifier"); - // return null node + let codeIndexStart: number = index; + while(input[index] != "{") { // continue stepping forward until we hit a { character + index++; + if(index >= input.length) break; + } + // the resulting substring between the style character and the { is our style code + const code: string = input.substring(codeIndexStart, index); + if(!(code in styles)) { + console.log("Style identifier is not recognized: ", code); } - console.log("Parsing text for format specifier", code); - let styles: string[] = []; + let styleList: string[] = []; if(parentStyles) { - styles = [...parentStyles, code] // append style code to styles list of this node + styleList = [...parentStyles, code] // append style code to styles list of this node } else { - styles = [code]; + styleList= [code]; } let text: string = ""; while(true) { // assemble text index++; if(input[index] === "%") { // encountered another style specifier - // commit the current node - addTextNode(text, styles, parentNode); + addTextNode(text, styleList, parentNode); text = ""; // clear the already commited text // and then move to the next - parseStyle(parentNode ? parentNode : null, styles); // recursion + parseStyle(parentNode ? parentNode : null, styleList); // recursion } else if(input[index] == "}") { // this node has closed - addTextNode(text, styles, parentNode); - //index++; // step to next + addTextNode(text, styleList, parentNode); break; } else { // regular text - if(input[index] !== "}") { - // hack. TODO: should probably fix because I think I'm doing something wrong - text += input[index]; - } + text += input[index]; // append character to the text string } if(index >= input.length) { break; @@ -129,14 +147,19 @@ export class Markleft { } function parseStructure(parentNode: blockNode | null = null) { - index++; // step onto specifier code - const code: string = input[index]; // TODO: validate if this code is a usable code + + // step onto format specifier code index++; - if(input[index] !== "{") { // TODO: implement some expect("{") function to better validate - console.log("{ not found following format specifier"); - // return null node + let codeIndexStart: number = index; + while(input[index] != "{") { // continue stepping forward until we hit a { character + index++; + if(index >= input.length) break; + } + // the resulting substring between the style character and the { is our style code + const code: string = input.substring(codeIndexStart, index); + if(!(code in blocks)) { + console.log("Code is not recognized: ", code); } - console.log("Parsing structure for format specifier", code); // create the node const node: blockNode = { @@ -149,9 +172,7 @@ export class Markleft { while(true) { // assemble text index++; if(input[index] === "%" || input[index] === "#") { // encountered another format specifier - addTextNode(text, null, node); - text = ""; // clear the already commited text // and then move to the next if(input[index] === "%") { @@ -163,7 +184,6 @@ export class Markleft { index++; // add its text addTextNode(text, null, node); - // push node to children list if(parentNode) { parentNode.children.push(node); @@ -173,10 +193,7 @@ export class Markleft { break; } else { // regular text - if(input[index] !== "}") { - // hack. TODO: should probably fix because I think I'm doing something wrong - text += input[index]; - } + text += input[index]; } if(index >= input.length) { break; @@ -199,7 +216,6 @@ export class Markleft { } function parse(endChar: string | null = null) { - console.log("parsing..."); let currentText: string = ""; while(index < input.length) { if(endChar && (input[index] === endChar)) { @@ -215,13 +231,10 @@ export class Markleft { parseStructure(); currentText = ""; } else if(input[index] === "@") { // encountered an attribute specifier - // nodes.push(parseAttribute()); + // nodes.push(parseAttribute()); // TODO: implement } else { // regular character - if(input[index] !== "}") { - // hack. TODO: should probably fix because I think I'm doing something wrong - currentText += input[index]; - } + currentText += input[index]; index++; } } @@ -255,13 +268,7 @@ export class Markleft { } else if("kind" in node) { // this is a blockNode let container: any; - if(node.kind === "H") { // TODO: registry for block types - container = this.renderer.createElement("h1"); - } else if(node.kind === "P") { - container = this.renderer.createElement("p"); - } else { - console.log("container type not recognized"); - } + container = this.renderer.createElement(blocks[node.kind].className); node.children.forEach((child: textNode | blockNode) => { if("styles" in child) { // this is a textNode @@ -300,8 +307,6 @@ export class Markleft { // parse text const nodes: (textNode | blockNode)[] = this.parsePlaintext(this.liveText); - // console.log(nodes) - // render nodes nodes.forEach((node) => { this.renderNode(node);