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) { static canParse(line) {
throw new Error("Not implemented"); throw new Error("Not implemented");
} }
static create(lineFeed) { static create(lineFeed, assetDirectory) {
throw new Error("Not implemented"); throw new Error("Not implemented");
} }
render() { 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 { class Italic extends Symbol {
/** /**
* @type {string} * @type {string}
@@ -525,32 +581,48 @@ const getAmountOfTokenInBeginningOfFile = (token, string) => {
} }
}; };
/**
* @type {Symbol[]}
*/
const Factories = [ const Factories = [
Heading, Heading,
UnorderedListItem, UnorderedListItem,
OrderedListItem, OrderedListItem,
Bold, Bold,
Italic, Italic,
ImageLink,
Link, Link,
MultiLineCode, MultiLineCode,
SingleLineCode, SingleLineCode,
CatchAll, 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(""); const html = symbols.map((s) => s.render()).join("");
return `<div>${html}</div>`; 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 lineFeed = new LineFeed(markdown);
const symbols = []; const symbols = [];
while (!lineFeed.isEmpty()) { while (!lineFeed.isEmpty()) {
const line = lineFeed.peek(); const line = lineFeed.peek();
const factory = Factories.find((factory) => factory.canParse(line)); const factory = Factories.find((factory) => factory.canParse(line));
const symbol = factory.create(lineFeed); const symbol = factory.create(lineFeed, assetDirectory);
symbols.push(symbol); symbols.push(symbol);
} }

View File

@@ -73,4 +73,4 @@ const y = () => {
[link to the index](https://blog.zacke.dev) [link to the index](https://blog.zacke.dev)
[link to the index](https://blog.zacke.dev) with text after it [link to the index](https://blog.zacke.dev) with text after it
![alt-text](@asset/picture.png) ![alt-text](@asset/git.png)