diff --git a/client/src/app/app.html b/client/src/app/app.html
index 5ced12f..c44dc77 100644
--- a/client/src/app/app.html
+++ b/client/src/app/app.html
@@ -8,4 +8,6 @@
2. automated dynamic themes. a theme based on a good color palette can rotate the hues around so the colors can change but maintain the same distance apart
3. world of text is goated, its like a chat room but infinite
+
+
diff --git a/client/src/app/app.ts b/client/src/app/app.ts
index 0c570e3..7808db9 100644
--- a/client/src/app/app.ts
+++ b/client/src/app/app.ts
@@ -1,9 +1,10 @@
import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
+import { Markleft } from './markleft/markleft'
@Component({
selector: 'app-root',
- imports: [RouterOutlet],
+ imports: [Markleft, RouterOutlet],
templateUrl: './app.html',
styleUrl: './app.scss'
})
diff --git a/client/src/app/markleft/markleft.html b/client/src/app/markleft/markleft.html
new file mode 100644
index 0000000..849e4d8
--- /dev/null
+++ b/client/src/app/markleft/markleft.html
@@ -0,0 +1 @@
+markleft works!
diff --git a/client/src/app/markleft/markleft.scss b/client/src/app/markleft/markleft.scss
new file mode 100644
index 0000000..4ee8220
--- /dev/null
+++ b/client/src/app/markleft/markleft.scss
@@ -0,0 +1,12 @@
+
+.format-bold {
+ font-weight: bold;
+}
+
+.format-italic {
+ font-style: italic;
+}
+
+.format-underline {
+ text-decoration: underline solid #000000 3px;
+}
diff --git a/client/src/app/markleft/markleft.spec.ts b/client/src/app/markleft/markleft.spec.ts
new file mode 100644
index 0000000..68b817b
--- /dev/null
+++ b/client/src/app/markleft/markleft.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { Markleft } from './markleft';
+
+describe('Markleft', () => {
+ let component: Markleft;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [Markleft],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(Markleft);
+ component = fixture.componentInstance;
+ await fixture.whenStable();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/client/src/app/markleft/markleft.ts b/client/src/app/markleft/markleft.ts
new file mode 100644
index 0000000..47b7522
--- /dev/null
+++ b/client/src/app/markleft/markleft.ts
@@ -0,0 +1,124 @@
+import { Component } from '@angular/core';
+
+// type descriptions
+
+interface formatDescriptor {
+ className: string;
+};
+
+interface textNode {
+ type: string;
+ text: string;
+ styles: formatDescriptor[]
+}
+
+interface blockNode {
+ type: string;
+ kind: string;
+ children: (blockNode | textNode)[]
+}
+
+// styles registry: this maps format specifiers to css classes
+const styles: Record = {
+ B: {
+ className: "format-bold"
+ },
+ I: {
+ className: "format-italic"
+ },
+ U: {
+ className: "format-underline"
+ },
+}; // i.e. %B{...} will apply "format-bold"
+
+@Component({
+ selector: 'app-markleft',
+ imports: [],
+ templateUrl: './markleft.html',
+ styleUrl: './markleft.scss',
+})
+export class Markleft {
+
+ 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.
+ `;
+
+ parsePlaintext(input: string): /*structureNode[]*/ void {
+
+ /* pseudocode (c lol)
+
+ int index = 0;
+
+ void parse(char endChar = null, formatDescriptor[]) {
+ const nodes = []; // start with an empty list of nodes
+
+ while(index < input.length) { // iterate over the input string
+ // break if } encountered, step forward (this format block has exited)
+ if(endChar && (input[pos] == endChar)) {
+ index++;
+ break;
+ }
+
+ if(input[index] == "%") {
+ nodes.push(parseStyle(...));
+ } else if(input[index] == "#") {
+ nodes.push(parseBlock(...));
+ } else {
+ nodes.push(parseText(...));
+ }
+
+ return mergeAdjacentText(nodes);
+ }
+
+ }
+
+ void parseStyle(parentStyle) {
+ index++; // step onto specifier
+ char code = readIdentifier(input[index])
+ index++;
+ expect("{"); // parsing error if not
+ const styles = [...parentStyles, code] // append style code to styles list of this node
+ const children = parseUntil("}", styles); // recursion probably
+
+ return children
+ }
+ ... and so on for parseBlock and parseText
+
+ */
+ return;
+ }
+
+ renderNode(node: (textNode | blockNode)): void {
+
+ /*
+ 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") {
+
+ element block = html.createElement(node.kind); // or whatever it is
+
+ // recursion
+ foreach(nodeType child in node.children) {
+ block.children.add(renderNode(child));
+ }
+ return block;
+
+ }
+
+ */
+
+ return;
+ }
+}