Open exam PDFs in new tabs
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled

This commit is contained in:
msa46 2026-09-18 09:20:36 +02:00
parent edca813c20
commit aa28e1ff21
3 changed files with 66 additions and 1 deletions

View file

@ -4,6 +4,7 @@ import { unified } from '@astrojs/markdown-remark';
import { sidebar } from './src/config/sidebar.mjs';
import { legacyBachelorRedirects } from './src/config/legacy-bachelor-redirects.mjs';
import { baseAwareLinks } from './src/config/base-aware-markdown.mjs';
import { openExamLinksInNewTab } from './src/config/open-exam-links.mjs';
const site = process.env.SITE || 'http://localhost:4321';
const base = process.env.BASE || '/';
@ -17,7 +18,12 @@ export default defineConfig({
base,
redirects: Object.fromEntries(Object.entries(legacyBachelorRedirects).map(([from, to]) => [from, `${normalizedBase}${to}`])),
markdown: {
processor: unified({ remarkPlugins: [[baseAwareLinks, { base }]] }),
processor: unified({
remarkPlugins: [
[baseAwareLinks, { base }],
openExamLinksInNewTab,
],
}),
},
integrations: [
starlight({

View file

@ -0,0 +1,24 @@
const examArchivePath = /(?:^|[/\\])previous-exams-and-documents\.md$/;
export function openExamLinksInNewTab() {
return (tree, file) => {
if (!examArchivePath.test(file?.path ?? '')) return;
const visit = (node) => {
if (node.type === 'link' && /\.pdf(?:[?#]|$)/i.test(node.url ?? '')) {
node.data = {
...node.data,
hProperties: {
...node.data?.hProperties,
target: '_blank',
rel: 'noopener noreferrer',
},
};
}
for (const child of node.children ?? []) visit(child);
};
visit(tree);
};
}

View file

@ -0,0 +1,35 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { openExamLinksInNewTab } from '../src/config/open-exam-links.mjs';
test('opens PDF links from the exam archive in a new tab', () => {
const tree = {
type: 'root',
children: [
{ type: 'link', url: '/media/exam.pdf', children: [] },
{ type: 'link', url: '/computer-science/', children: [] },
],
};
openExamLinksInNewTab()(tree, {
path: '/project/src/content/docs/previous-exams-and-documents.md',
});
assert.deepEqual(tree.children[0].data, {
hProperties: {
target: '_blank',
rel: 'noopener noreferrer',
},
});
assert.equal(tree.children[1].data, undefined);
});
test('leaves PDF links on other pages unchanged', () => {
const link = { type: 'link', url: '/media/notes.pdf', children: [] };
openExamLinksInNewTab()({ type: 'root', children: [link] }, {
path: '/project/src/content/docs/course.md',
});
assert.equal(link.data, undefined);
});