108 lines
4.5 KiB
TypeScript
108 lines
4.5 KiB
TypeScript
/**
|
|
* Based on https://github.com/dwengovzw/Learning-Object-Repository/blob/main/app/processors/markdown/learing_object_markdown_renderer.js [sic!]
|
|
*/
|
|
import PdfProcessor from '../pdf/pdf-processor.js';
|
|
import AudioProcessor from '../audio/audio-processor.js';
|
|
import ExternProcessor from '../extern/extern-processor.js';
|
|
import InlineImageProcessor from '../image/inline-image-processor.js';
|
|
import * as marked from 'marked';
|
|
import { getUrlStringForLearningObjectHTML, isValidHttpUrl } from '../../../../util/links.js';
|
|
import { ProcessingError } from '../processing-error.js';
|
|
import Image = marked.Tokens.Image;
|
|
import Heading = marked.Tokens.Heading;
|
|
import Link = marked.Tokens.Link;
|
|
import RendererObject = marked.RendererObject;
|
|
import { LearningObjectIdentifierDTO } from '@dwengo-1/common/interfaces/learning-content';
|
|
import { Language } from '@dwengo-1/common/util/language';
|
|
|
|
const prefixes = {
|
|
learningObject: '@learning-object',
|
|
pdf: '@pdf',
|
|
audio: '@audio',
|
|
extern: '@extern',
|
|
video: '@youtube',
|
|
notebook: '@notebook',
|
|
blockly: '@blockly',
|
|
};
|
|
|
|
function extractLearningObjectIdFromHref(href: string): LearningObjectIdentifierDTO {
|
|
const [hruid, language, version] = href.split(/\/(.+)/, 2)[1].split('/');
|
|
return {
|
|
hruid,
|
|
language: language as Language,
|
|
version: parseInt(version),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* An extension for the renderer of the Marked Markdown renderer which adds support for
|
|
* - a custom heading,
|
|
* - links to other learning objects,
|
|
* - embeddings of other learning objects.
|
|
*/
|
|
const dwengoMarkedRenderer: RendererObject = {
|
|
heading(heading: Heading): string {
|
|
const text = heading.text;
|
|
const level = heading.depth;
|
|
const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
|
|
|
|
return (
|
|
`<h${level}>\n` +
|
|
` <a name="${escapedText}" class="anchor" href="#${escapedText}">\n` +
|
|
` <span class="header-link"></span>\n` +
|
|
` </a>\n` +
|
|
` ${text}\n` +
|
|
`</h${level}>\n`
|
|
);
|
|
},
|
|
|
|
// When the syntax for a link is used => [text](href "title")
|
|
// Render a custom link when the prefix for a learning object is used.
|
|
link(link: Link): string {
|
|
const href = link.href;
|
|
const title = link.title || '';
|
|
const text = marked.parseInline(link.text); // There could for example be an image in the link.
|
|
|
|
if (href.startsWith(prefixes.learningObject)) {
|
|
// Link to learning-object
|
|
const learningObjectId = extractLearningObjectIdFromHref(href);
|
|
return `<a href="${getUrlStringForLearningObjectHTML(learningObjectId)}" target="_blank" title="${title}">${text}</a>`;
|
|
}
|
|
// Any other link
|
|
if (!isValidHttpUrl(href)) {
|
|
throw new ProcessingError('Link is not a valid HTTP URL!');
|
|
}
|
|
//<a href="https://kiks.ilabt.imec.be/hub/tmplogin?id=0101" title="Notebooks Werking"><img src="Knop.png" alt="" title="Knop"></a>
|
|
return `<a href="${href}" target="_blank" title="${title}">${text}</a>`;
|
|
},
|
|
|
|
// When the syntax for an image is used => 
|
|
// Render a learning object, pdf, audio or video if a prefix is used.
|
|
image(img: Image): string {
|
|
const href = img.href;
|
|
if (href.startsWith(prefixes.learningObject)) {
|
|
// Embedded learning-object
|
|
const learningObjectId = extractLearningObjectIdFromHref(href);
|
|
return `
|
|
<learning-object hruid="${learningObjectId.hruid}" language="${learningObjectId.language}" version="${learningObjectId.version}"/>
|
|
`; // Placeholder for the learning object since we cannot fetch its HTML here (this has to be a sync function!)
|
|
} else if (href.startsWith(prefixes.pdf)) {
|
|
// Embedded pdf
|
|
const proc = new PdfProcessor();
|
|
return proc.render(href.split(/\/(.+)/, 2)[1]);
|
|
} else if (href.startsWith(prefixes.audio)) {
|
|
// Embedded audio
|
|
const proc = new AudioProcessor();
|
|
return proc.render(href.split(/\/(.+)/, 2)[1]);
|
|
} else if (href.startsWith(prefixes.extern) || href.startsWith(prefixes.video) || href.startsWith(prefixes.notebook)) {
|
|
// Embedded youtube video or notebook (or other extern content)
|
|
const proc = new ExternProcessor();
|
|
return proc.render(href.split(/\/(.+)/, 2)[1]);
|
|
}
|
|
// Embedded image
|
|
const proc = new InlineImageProcessor();
|
|
return proc.render(href);
|
|
},
|
|
};
|
|
|
|
export default dwengoMarkedRenderer;
|