Skip to content

Instantly share code, notes, and snippets.

@brimonk
Last active March 21, 2021 09:31
Show Gist options
  • Save brimonk/b6867bfc0f928c46d28ae2cfdd0ae398 to your computer and use it in GitHub Desktop.
Save brimonk/b6867bfc0f928c46d28ae2cfdd0ae398 to your computer and use it in GitHub Desktop.
just a little "immediate mode" experiment
// Brian Chrzanowski
// 2021-03-21 04:20:30
//
// Just a small HTML Form builder kind of a thing, no styling. This could obviously
// be extended to things other than HTML if you just replaced the `toHtml()` method
// and maybe standardized a little bit more on the sorts of tags / elements you want
// to stick into the builder.
class Builder {
public children?: Builder[] = [];
public id: number;
public depth: number = 0;
public tag: string;
public value: string;
private activegroup: boolean;
constructor(id?: number, tag?: string, value?: string, depth?: number) {
this.id = id ? id + 1 : 0;
this.tag = tag ?? null;
this.value = value ?? null;
this.depth = depth ?? 0;
}
// bGroup: begins a group
public bGroup(tag: string): Builder {
if (this.activegroup) {
const child: Builder = this.currchild();
child.bGroup(tag);
} else {
this.children.push(new Builder(this.id, tag, null, this.depth + 1));
}
this.activegroup = true;
return this;
}
// eGroup: ends a group. we don't need the tag, but have it here for completeness, or assertions
public eGroup(tag: string): Builder {
if (this.activegroup) {
const child: Builder = this.currchild();
child.eGroup(tag);
}
this.activegroup = false;
return this;
}
// make: makes a group
public make(tag: string, value: string): Builder {
if (this.activegroup) {
const child: Builder = this.currchild();
child.make(tag, value);
} else {
this.children.push(new Builder(this.id, tag, value, this.depth));
}
return this;
}
// currchild: returns the current child
public currchild(): Builder {
return this.children[this.children.length - 1];
}
// toHtml: converts the current Builder to html
public toHtml(): string {
const indent: string = "\t";
let curr: string = "";
this.children.forEach((i: Builder) => {
curr += indent.repeat(this.depth) + this.convertMe(i) + "\r\n";
});
return curr;
}
// convertMe: does the hard work of spitting out appropriate tags
public convertMe(elem: Builder): string {
switch (elem.tag) {
case "h1": return `<h1>${elem.value}</h1>`;
case "h2": return `<h2>${elem.value}</h2>`;
case "h3": return `<h3>${elem.value}</h3>`;
case "h4": return `<h4>${elem.value}</h4>`;
case "p": return `<p>${elem.value}</p>`;
case "button": return `<button type="button">${elem.value}</button>`;
case "div": return `<div>\r\n` + elem.toHtml() + "</div>";
default: return `<br>`;
}
}
}
const builder = new Builder();
builder.make("h3", "Hello World");
builder.make("p", "This is just a small test.");
builder.make("input", "Just a little input box");
builder.bGroup("div");
builder.make("h3", "this is in a div");
builder.make("button", "button goes brrrrrrrr");
builder.eGroup("div");
console.log(builder.toHtml());
@brimonk
Copy link
Author

brimonk commented Mar 21, 2021

<h3>Hello World</h3>
<p>This is just a small test.</p>
<br>
<div>
	<h3>this is in a div</h3>
	<button type="button">button goes brrrrrrrr</button>
</div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment