diff --git a/understand-anything-plugin/packages/dashboard/package.json b/understand-anything-plugin/packages/dashboard/package.json index 63ce6cac..41319a46 100644 --- a/understand-anything-plugin/packages/dashboard/package.json +++ b/understand-anything-plugin/packages/dashboard/package.json @@ -26,6 +26,7 @@ "react": "^19.0.0", "react-dom": "^19.0.0", "react-markdown": "^10.1.0", + "remark-gfm": "^4.0.1", "zustand": "^5.0.0" }, "devDependencies": { diff --git a/understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx b/understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx index 592fb1a3..c7256063 100644 --- a/understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx +++ b/understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx @@ -1,5 +1,7 @@ import { useEffect, useMemo, useState } from "react"; import { Highlight, themes } from "prism-react-renderer"; +import ReactMarkdown from "react-markdown"; +import remarkGfm from "remark-gfm"; import { useDashboardStore } from "../store"; import { useI18n } from "../contexts/I18nContext"; @@ -56,6 +58,66 @@ function formatBytes(bytes: number): string { return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; } +/** Rendered markdown view for .md files, styled for the dark theme. */ +function MarkdownView({ content }: { content: string }) { + return ( +
+

{children}

, + h2: ({ children }) =>

{children}

, + h3: ({ children }) =>

{children}

, + h4: ({ children }) =>

{children}

, + h5: ({ children }) =>
{children}
, + h6: ({ children }) =>
{children}
, + p: ({ children }) =>

{children}

, + a: ({ children, href }) => ( + + {children} + + ), + ul: ({ children }) => , + ol: ({ children }) =>
    {children}
, + blockquote: ({ children }) => ( +
{children}
+ ), + hr: () =>
, + pre: ({ children }) => ( +
+              {children}
+            
+ ), + code: ({ className, children }) => { + const isInline = !className && !String(children).includes("\n"); + return isInline ? ( + {children} + ) : ( + {children} + ); + }, + table: ({ children }) => ( +
+ {children}
+
+ ), + th: ({ children }) => ( + + {children} + + ), + td: ({ children }) => {children}, + img: ({ src, alt }) => ( + {alt} + ), + }} + > + {content} +
+
+ ); +} + export default function CodeViewer({ accessToken, presentation = "sidebar", @@ -79,6 +141,9 @@ export default function CodeViewer({ source: null, error: null, }); + // Markdown files default to the rendered view (#555); toggle back to + // source for line numbers / lineRange highlighting. + const [mdView, setMdView] = useState<"rendered" | "source">("rendered"); const { t } = useI18n(); useEffect(() => { @@ -134,6 +199,8 @@ export default function CodeViewer({ const source = state.source; const language = source?.language ?? fallbackLanguage(node.filePath); + const isMarkdown = language === "markdown"; + const showRendered = isMarkdown && mdView === "rendered"; const lineInfo = highlightedRange ? `${t.codeViewer.lines} ${highlightedRange.start}-${highlightedRange.end}` : t.codeViewer.fullFile; @@ -212,8 +279,31 @@ export default function CodeViewer({ <>
{source.lineCount} {t.codeViewer.linesLabel} - {formatBytes(source.sizeBytes)} +
+ {isMarkdown && ( +
+ {(["rendered", "source"] as const).map((view) => ( + + ))} +
+ )} + {formatBytes(source.sizeBytes)} +
+ {showRendered && } + {!showRendered && ( {({ className, style, tokens, getLineProps, getTokenProps }) => (
               )}
             
+            )}
           
         )}
       
diff --git a/understand-anything-plugin/packages/dashboard/src/locales/en.ts b/understand-anything-plugin/packages/dashboard/src/locales/en.ts
index 83777182..cd28d26b 100644
--- a/understand-anything-plugin/packages/dashboard/src/locales/en.ts
+++ b/understand-anything-plugin/packages/dashboard/src/locales/en.ts
@@ -179,6 +179,8 @@ export const en = {
     closeExpanded: "Close expanded code viewer",
     closeViewer: "Close code viewer",
     sourceUnavailable: "Source unavailable",
+    rendered: "Rendered",
+    source: "Source",
   },
   customNode: {
     tested: "Tested",
diff --git a/understand-anything-plugin/packages/dashboard/src/locales/ja.ts b/understand-anything-plugin/packages/dashboard/src/locales/ja.ts
index e222d266..f3ccbce6 100644
--- a/understand-anything-plugin/packages/dashboard/src/locales/ja.ts
+++ b/understand-anything-plugin/packages/dashboard/src/locales/ja.ts
@@ -179,6 +179,8 @@ export const ja = {
     closeExpanded: "展開したコードビューアを閉じる",
     closeViewer: "コードビューアを閉じる",
     sourceUnavailable: "ソースが利用できません",
+    rendered: "プレビュー",
+    source: "ソース",
   },
   customNode: {
     tested: "テスト済み",
diff --git a/understand-anything-plugin/packages/dashboard/src/locales/ko.ts b/understand-anything-plugin/packages/dashboard/src/locales/ko.ts
index de894a79..f537114c 100644
--- a/understand-anything-plugin/packages/dashboard/src/locales/ko.ts
+++ b/understand-anything-plugin/packages/dashboard/src/locales/ko.ts
@@ -179,6 +179,8 @@ export const ko = {
     closeExpanded: "확장된 코드 뷰어 닫기",
     closeViewer: "코드 뷰어 닫기",
     sourceUnavailable: "소스 사용 불가",
+    rendered: "렌더링",
+    source: "소스",
   },
   customNode: {
     tested: "테스트됨",
diff --git a/understand-anything-plugin/packages/dashboard/src/locales/ru.ts b/understand-anything-plugin/packages/dashboard/src/locales/ru.ts
index 27cc5546..8b1fb643 100644
--- a/understand-anything-plugin/packages/dashboard/src/locales/ru.ts
+++ b/understand-anything-plugin/packages/dashboard/src/locales/ru.ts
@@ -179,6 +179,8 @@ export const ru = {
     closeExpanded: "Закрыть расширенный просмотрщик кода",
     closeViewer: "Закрыть просмотрщик кода",
     sourceUnavailable: "Исходный код недоступен",
+    rendered: "Просмотр",
+    source: "Исходник",
   },
   customNode: {
     tested: "Покрыт тестами",
diff --git a/understand-anything-plugin/packages/dashboard/src/locales/zh-TW.ts b/understand-anything-plugin/packages/dashboard/src/locales/zh-TW.ts
index 2ffab482..0a958c5b 100644
--- a/understand-anything-plugin/packages/dashboard/src/locales/zh-TW.ts
+++ b/understand-anything-plugin/packages/dashboard/src/locales/zh-TW.ts
@@ -179,6 +179,8 @@ export const zhTW = {
     closeExpanded: "關閉展開的程式碼檢視器",
     closeViewer: "關閉程式碼檢視器",
     sourceUnavailable: "原始碼不可用",
+    rendered: "渲染",
+    source: "原始碼",
   },
   customNode: {
     tested: "已測試",
diff --git a/understand-anything-plugin/packages/dashboard/src/locales/zh.ts b/understand-anything-plugin/packages/dashboard/src/locales/zh.ts
index c308eb48..7e8a21a7 100644
--- a/understand-anything-plugin/packages/dashboard/src/locales/zh.ts
+++ b/understand-anything-plugin/packages/dashboard/src/locales/zh.ts
@@ -179,6 +179,8 @@ export const zh = {
     closeExpanded: "关闭展开的代码查看器",
     closeViewer: "关闭代码查看器",
     sourceUnavailable: "源码不可用",
+    rendered: "渲染",
+    source: "源码",
   },
   customNode: {
     tested: "已测试",