Image link support

This commit is contained in:
2023-09-17 11:05:17 +02:00
parent 973acd70f2
commit d8ee8c348c
2 changed files with 78 additions and 6 deletions

View File

@@ -53,7 +53,7 @@ class Symbol {
static canParse(line) {
throw new Error("Not implemented");
}
static create(lineFeed) {
static create(lineFeed, assetDirectory) {
throw new Error("Not implemented");
}
render() {
@@ -217,6 +217,62 @@ class Link extends Symbol {
}
}
class ImageLink extends Symbol {
/**
* @type {RegExp}
*/
static canParseRegExp = new RegExp(/^!\[.*\]\(.*\)/);
/**
* @type {RegExp}
*/
static textAndLinkRegExp = new RegExp(/!\[(?<text>.*)\]\((?<link>.*)\)/);
/**
* @type {string}
*/
static assetDirectoryToken = "@asset/";
/**
* @type {string}
*/
alt = "";
/**
* @type {string}
*/
link = "";
/**
*
* @param {string} line
* @returns {boolean}
*/
static canParse(line) {
return ImageLink.canParseRegExp.test(line.trim());
}
/**
*
* @param {LineFeed} lineFeed
* @returns {Symbol}
*/
static create(lineFeed, assetDirectory) {
const instance = new ImageLink();
const line = lineFeed.claim().trim();
const [linkLine, rest] = extractTokenAndRest(
ImageLink.textAndLinkRegExp,
line
);
lineFeed.push(rest);
const { text, link } =
ImageLink.textAndLinkRegExp.exec(linkLine)?.groups ?? {};
instance.link =
link.replace(ImageLink.assetDirectoryToken, assetDirectory) ?? "";
instance.alt = text ?? "";
return instance;
}
render() {
return `<img src="${this.link}" alt="${this.alt}"/>`;
}
}
class Italic extends Symbol {
/**
* @type {string}
@@ -525,32 +581,48 @@ const getAmountOfTokenInBeginningOfFile = (token, string) => {
}
};
/**
* @type {Symbol[]}
*/
const Factories = [
Heading,
UnorderedListItem,
OrderedListItem,
Bold,
Italic,
ImageLink,
Link,
MultiLineCode,
SingleLineCode,
CatchAll,
];
export const toHtml = (markdown) => {
const symbols = toSymbols(markdown);
/**
*
* @param {string} markdown
* @param {string} assetDirectory
* @returns {string}
*/
export const toHtml = (markdown, assetDirectory) => {
const symbols = toSymbols(markdown, assetDirectory);
const html = symbols.map((s) => s.render()).join("");
return `<div>${html}</div>`;
};
const toSymbols = (markdown) => {
/**
*
* @param {string} markdown
* @param {string} assetDirectory
* @returns {Symbol[]}
*/
const toSymbols = (markdown, assetDirectory) => {
const lineFeed = new LineFeed(markdown);
const symbols = [];
while (!lineFeed.isEmpty()) {
const line = lineFeed.peek();
const factory = Factories.find((factory) => factory.canParse(line));
const symbol = factory.create(lineFeed);
const symbol = factory.create(lineFeed, assetDirectory);
symbols.push(symbol);
}