Bläddra i källkod

Remove the need for remarkPlugin for codeblock

arvid-e 8 månader sedan
förälder
incheckning
4c4fbf3bea

+ 34 - 47
apps/app/src/services/renderer/rehype-plugins/add-inline-code-attribute.ts

@@ -1,56 +1,43 @@
-// apps/app/src/services/renderer/rehype-plugins/add-inline-code-attribute.ts
+import type { Element } from 'hast';
 
 
-import type { Element, Root } from 'hast';
-import type { Plugin } from 'unified';
-import type { Node, Parent } from 'unist'; // Import Node and Parent for 'parent' property
-import { visit, type Test } from 'unist-util-visit';
+export function rehypePlugin() {
+  return (tree: any) => { // 'any' needs replacing probably
+    function visitor(node: Element, parent: Element | null) {
+      if (node.tagName === 'code') {
+        const isInsidePre = parent
+                            && parent.type === 'element'
+                            && parent.tagName === 'pre';
 
 
+        if (!isInsidePre) {
+          node.properties = node.properties || {};
 
 
-// WORKAROUND: Define a local type that explicitly includes the 'parent' property.
-// This is necessary because the 'parent' property is optional or not always
-// directly typed on 'Node' in some versions of unist.
-interface NodeWithParent extends Node {
-  parent?: Parent | undefined;
-}
-
-/**
- * A Rehype plugin to ensure 'inline="true"' attribute is correctly applied to <code> tags.
- *
- * It aims to:
- * 1. Ensure <code> tags wrapped directly inside <pre> tags (block code) DO NOT have 'inline="true"'.
- * 2. Ensure <code> tags NOT wrapped directly inside <pre> tags (true inline code,
- * whether from Markdown backticks or raw HTML `<code>`) DO have 'inline="true"'.
- */
-export const rehypePlugin: Plugin<[], Root> = () => {
-  const isCodeElement: Test = { tagName: 'code', type: 'element' };
-
-  return (tree) => {
-    visit(tree, isCodeElement, (node: Element) => {
-      const typedNode = node as NodeWithParent; // Cast to access 'parent' property
-
-      // Determine if the <code> tag is directly inside a <pre> tag
-      const isInsidePre = typedNode.parent
-                          && typedNode.parent.type === 'element'
-                          && (typedNode.parent as Element).tagName === 'pre';
+          if (!node.properties.className) {
+            node.properties.className = [];
+          }
+          // This is the key part: push 'code-inline' to className
+          if (Array.isArray(node.properties.className) && !node.properties.className.includes('code-inline')) {
+            (node.properties.className as string[]).push('code-inline');
+          }
+        }
+      }
 
 
-      // --- Decision Logic ---
-      if (isInsidePre) {
-        // If it's inside a <pre> tag, it's a block code.
-        // Ensure 'inline' property is removed if present.
-        if (node.properties?.inline) {
-          delete (node.properties as Record<string, any>).inline;
-          // Clean up properties object if it becomes empty
-          if (Object.keys(node.properties).length === 0) {
-            node.properties = {};
+      if ('children' in node && Array.isArray(node.children)) {
+        for (let i = 0; i < node.children.length; i++) {
+          const child = node.children[i];
+          if (child.type === 'element') {
+            visitor(child as Element, node);
           }
           }
         }
         }
       }
       }
-      else {
-        // If it's NOT inside a <pre> tag, it should be treated as inline code.
-        // Ensure 'inline="true"' is set.
-        node.properties = node.properties || {};
-        node.properties.inline = true;
+    }
+
+    if ('children' in tree && Array.isArray(tree.children)) {
+      for (let i = 0; i < tree.children.length; i++) {
+        const child = tree.children[i];
+        if (child.type === 'element') {
+          visitor(child as Element, tree as Element); // Pass tree as parent for its direct children
+        }
       }
       }
-    });
+    }
   };
   };
-};
+}

+ 10 - 5
apps/app/src/services/renderer/remark-plugins/codeblock.ts

@@ -4,13 +4,10 @@ import type { Plugin } from 'unified';
 import { visit } from 'unist-util-visit';
 import { visit } from 'unist-util-visit';
 
 
 
 
-const SUPPORTED_CODE = ['inline'];
-
 export const remarkPlugin: Plugin = () => {
 export const remarkPlugin: Plugin = () => {
   return (tree) => {
   return (tree) => {
     visit(tree, 'inlineCode', (node: InlineCode) => {
     visit(tree, 'inlineCode', (node: InlineCode) => {
-      const data = node.data || (node.data = {});
-      data.hProperties = { inline: 'true' }; // set 'true' explicitly because the empty string is evaluated as false for `if (inline) { ... }`
+      // REMOVE THIS BLOCK
     });
     });
   };
   };
 };
 };
@@ -18,6 +15,14 @@ export const remarkPlugin: Plugin = () => {
 export const sanitizeOption: SanitizeOption = {
 export const sanitizeOption: SanitizeOption = {
   tagNames: ['code'],
   tagNames: ['code'],
   attributes: {
   attributes: {
-    code: SUPPORTED_CODE,
+
+    code: [
+      'className', // Allow the 'class' attribute on <code> tags
+      ['className', 'code-inline'], // Explicitly allow 'code-inline' as a class value
+      // By NOT listing 'inline' here, rehype-sanitize will strip inline="true"
+      // which is what you want for Markdown inline code.
+    ],
+    // If you have `data-line` attributes on code blocks, you might need to allow them globally or specifically:
+    '*': ['data-line'],
   },
   },
 };
 };

+ 0 - 2
apps/app/src/services/renderer/renderer.tsx

@@ -102,7 +102,6 @@ export const generateCommonOptions = (pagePath: string|undefined): RendererOptio
       remarkDirective,
       remarkDirective,
       echoDirective.remarkPlugin,
       echoDirective.remarkPlugin,
       remarkFrontmatter,
       remarkFrontmatter,
-      codeBlock.remarkPlugin,
     ],
     ],
     remarkRehypeOptions: {
     remarkRehypeOptions: {
       clobberPrefix: '', // remove clobber prefix
       clobberPrefix: '', // remove clobber prefix
@@ -119,7 +118,6 @@ export const generateCommonOptions = (pagePath: string|undefined): RendererOptio
     ],
     ],
     components: {
     components: {
       a: NextLink,
       a: NextLink,
-      code: CodeBlock,
     },
     },
   };
   };
 };
 };