class LineFeed {
originalText = undefined;
/**
* @type {string[]}
*/
feed = undefined;
/**
*
* @param {string} markdown
*/
constructor(markdown) {
this.originalText = markdown;
// TODO: Need to identify line endings
this.feed = markdown.split("\n");
}
/**
* @returns {string}
*/
peek() {
return this.feed[0] ?? undefined;
}
/**
*
* @returns {string}
*/
claim() {
const line = this.feed.shift();
if (line === undefined) throw new Error("Feed is empty");
return line;
}
/**
*
* @returns {boolean}
*/
isEmpty() {
return this.feed.length === 0;
}
}
class Symbol {
static canParse(line) {
throw new Error("Not implemented");
}
static create(lineFeed) {
throw new Error("Not implemented");
}
render() {
throw new Error("Not implemented");
}
}
class Heading extends Symbol {
/**
* @type {string}
*/
text = "";
/**
* @type {number}
*/
level = 1;
/**
*
* @param {string} line
* @returns {boolean}
*/
static canParse(line) {
return line.trim().startsWith("#");
}
/**
*
* @param {LineFeed} lineFeed
* @returns {Symbol}
*/
static create(lineFeed) {
const instance = new Heading();
const line = lineFeed.claim();
instance.text = line.replaceAll("#", "").trim();
instance.level = line.split("").reduce((aggregate, current) => {
return current === "#" ? aggregate + 1 : aggregate;
}, 0);
return instance;
}
render() {
return `
${this.text}
`; } } const Factories = [Heading, CatchAll]; export const toHtml = (markdown) => { const symbols = toSymbols(markdown); const html = symbols.map((s) => s.render()).join(""); return `