fix: embed setup -- now embedded content should render properly based on the remark setup in the astro config.
This commit is contained in:
+19
-17
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user