Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ if (process.env.CI_MERGE_REQUEST_IID) {
const config = {
future: {
experimental_faster: (process.env.DOCUSAURUS_FASTER ?? "true") === "true",
v4: true
v4: true,
},
title: "Develop with Palo Alto Networks",
tagline:
Expand Down Expand Up @@ -1171,6 +1171,7 @@ const config = {
},
],
tailwindPlugin,
require.resolve("./plugins/markdown-route/index.cjs"),
],
stylesheets: [
{
Expand Down
13 changes: 13 additions & 0 deletions plugins/markdown-route/index.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function markdownRoutePlugin() {
return {
name: "markdown-route-plugin",
async contentLoaded({ actions }) {
actions.addRoute({
path: "/__md",
matchPath: "/:route+.md",
component: "@site/src/components/MarkdownPage",
});
},
};
}
module.exports = markdownRoutePlugin;
74 changes: 74 additions & 0 deletions src/components/MarkdownPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useEffect, useState } from "react";
import { useLocation } from "@docusaurus/router";
import TurndownService from "turndown";

export default function MarkdownPage() {
const location = useLocation();
const [markdown, setMarkdown] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);

useEffect(() => {
async function fetchAndConvert() {
const htmlPath = location.pathname.replace(/\.md$/, "/index.html");
try {
const res = await fetch(htmlPath);
if (!res.ok) {
throw new Error(`Failed to fetch source page: ${res.status}`);
}
const html = await res.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
const content =
doc.querySelector(".openapi-left-panel__container") ||
doc.querySelector(".theme-doc-markdown");
if (!content) {
throw new Error("Unable to locate markdown source");
}
const turndownService = new TurndownService();
turndownService.addRule("details-rule", {
filter: "details",
replacement: function (content, node) {
const summary = node.querySelector("summary");
const summaryText = summary ? summary.textContent?.trim() : "";
const detailsContent = content.substring(
content.indexOf("</summary>") + 1
);
let md = `\n${summaryText}\n`;
const indented = detailsContent
.split("\n")
.map((line) => {
if (line.trim() === "") return line;
return ` ${line}`;
})
.join("\n");
md += indented;
return md + "\n";
},
});
setMarkdown(turndownService.turndown(content));
} catch (e) {
setError((e as Error).message);
}
}
fetchAndConvert();
}, [location.pathname]);

const preStyle: React.CSSProperties = {
all: "unset",
whiteSpace: "pre-wrap",
fontFamily: "monospace",
display: "block",
padding: 0,
margin: 0,
background: "transparent",
color: "inherit",
};

if (error) {
return <pre style={preStyle}>{error}</pre>;
}
if (markdown === null) {
return <p>Loading...</p>;
}
return <pre style={preStyle}>{markdown}</pre>;
}