fix: embed setup -- now embedded content should render properly based on the remark setup in the astro config.

This commit is contained in:
manunamz
2024-09-03 14:47:14 -04:00
parent 06ebc36941
commit 7ece9da7fc
2 changed files with 75 additions and 42 deletions
+19 -17
View File
@@ -1,18 +1,33 @@
import { base, defineConfig } from 'astro/config'; import { base, defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap'; import sitemap from '@astrojs/sitemap';
import { remarkWikiRefs } from 'remark-wikirefs'; import { remarkWikiRefs } from 'remark-wikirefs';
import { remarkCaml } from 'remark-caml'; import { remarkCaml } from 'remark-caml';
import { import {
resolveHtmlHref, resolveHtmlHref,
resolveHtmlText, resolveHtmlText,
resolveEmbedContent, createResolveEmbedContent,
generateForeRefsRemarkPlugin, generateForeRefsRemarkPlugin,
} from './src/wikibonsai/wikirefs'; } from './src/wikibonsai/wikirefs';
const remarkPlugins = [
remarkCaml,
[
remarkWikiRefs,
{
resolveHtmlHref: resolveHtmlHref,
resolveHtmlText: resolveHtmlText,
resolveEmbedContent: null, // we'll set this later -- see below
},
],
generateForeRefsRemarkPlugin,
];
// embed content needs access to a unified processor
const resolveEmbedContent = createResolveEmbedContent(remarkPlugins);
remarkPlugins[1][1].resolveEmbedContent = resolveEmbedContent;
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
site: 'https://astro-wikibonsai.netlify.app', site: 'https://astro-wikibonsai.netlify.app',
@@ -24,19 +39,6 @@ export default defineConfig({
// Preserve Astro's default plugins: GitHub-flavored Markdown and Smartypants // Preserve Astro's default plugins: GitHub-flavored Markdown and Smartypants
extendDefaultPlugins: true, extendDefaultPlugins: true,
// Applied to .md and .mdx files // Applied to .md and .mdx files
remarkPlugins: [ remarkPlugins: remarkPlugins,
remarkCaml,
[
remarkWikiRefs,
{
baseUrl: base,
resolveHtmlHref: resolveHtmlHref,
resolveHtmlText: resolveHtmlText,
resolveEmbedContent: resolveEmbedContent,
},
],
// this plugin is necessary for backrefs to work
generateForeRefsRemarkPlugin,
],
}, },
}); });
+56 -25
View File
@@ -1,13 +1,69 @@
import type { Processor } from 'unified';
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs';
import fg from 'fast-glob'; import fg from 'fast-glob';
import matter from 'gray-matter'; import matter from 'gray-matter';
import { selectAll } from 'unist-util-select'; import { selectAll } from 'unist-util-select';
import * as wikirefs from 'wikirefs'; import * as wikirefs from 'wikirefs';
import { unified } from 'unified';
import remarkParse from 'remark-parse';
const CONTENT_GLOB: string = './src/content/**/*.md'; const CONTENT_GLOB: string = './src/content/**/*.md';
let globalProcessor: Processor;
let cycleStack: string[] = [];
export function createResolveEmbedContent(remarkPlugins: any[]) {
console.log("createResolveEmbedContent", remarkPlugins);
if (!globalProcessor) {
globalProcessor = unified().use(remarkParse);
// apply same remark plugins as in astro config
remarkPlugins.forEach(plugin => {
if (Array.isArray(plugin)) {
globalProcessor.use(plugin[0], plugin[1]);
} else {
globalProcessor.use(plugin);
}
});
// note: we're not using remarkRehype or rehypeStringify here
}
return function resolveEmbedContentInternal(filename: string): any {
// markdown-only
if (wikirefs.isMedia(filename)) { return; }
// cycle detection
if (cycleStack.length === 0) {
cycleStack = [];
} else if (cycleStack.includes(filename)) {
// reset stack before leaving
cycleStack = [];
return 'cycle detected';
}
cycleStack.push(filename);
const docPaths: string[] = fg.sync(CONTENT_GLOB);
const docPath: string | undefined = docPaths.find((p) => {
return path.basename(p, '.md') === filename;
});
let content: string = '';
if (docPath === undefined) {
content = 'Error: Content not found for ' + "'" + filename + "'";
} else {
const text: string | undefined = fs.readFileSync(docPath, { encoding: 'utf8', flag: 'r' });
content = matter(text).content;
}
let mdastContent: any;
if (content.length === 0) {
mdastContent = '';
} else {
mdastContent = globalProcessor.parse(content);
}
// reset stack before leaving
cycleStack = [];
return mdastContent;
};
}
export function resolveHtmlHref(fname: string): string | undefined { export function resolveHtmlHref(fname: string): string | undefined {
// #todo revisit: https://docs.astro.build/en/reference/api-reference/#importmeta // #todo revisit: https://docs.astro.build/en/reference/api-reference/#importmeta
// 'import.meta.glob' docs: // 'import.meta.glob' docs:
@@ -66,31 +122,6 @@ export function resolveHtmlText(fname: string): string | undefined {
} }
} }
export function resolveEmbedContent(filename: string): any {
// markdown-only
if (wikirefs.isMedia(filename)) { return; }
const docPaths: string[] = fg.sync(CONTENT_GLOB);
const docPath: string | undefined = docPaths.find((p) => {
return path.basename(p, '.md') === filename;
});
let content: string = '';
if (docPath === undefined) {
content = 'Error: Content not found for ' + "'" + filename + "'";
} else {
const text: string | undefined = fs.readFileSync(docPath, { encoding: 'utf8', flag: 'r' });
content = matter(text).content;
}
// return mdast node
return {
type: 'text',
// todo: render
value: content,
};
}
// forerfs
// todo: don't include index documents when calculating metadata -- and skip index docs too
export function generateForeRefsRemarkPlugin() { export function generateForeRefsRemarkPlugin() {
return function (tree: any, file: any) { return function (tree: any, file: any) {
// from: https://observablehq.com/@tmcw/extracting-links-from-markdown-using-remark-and-unist-util // from: https://observablehq.com/@tmcw/extracting-links-from-markdown-using-remark-and-unist-util