diff --git a/backend/chainlit/translations/bn.json b/backend/chainlit/translations/bn.json index d721b06d23..aa4f3bd192 100644 --- a/backend/chainlit/translations/bn.json +++ b/backend/chainlit/translations/bn.json @@ -187,5 +187,22 @@ "success": { "saved": "সফলভাবে সংরক্ষিত হয়েছে" } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" } } diff --git a/backend/chainlit/translations/en-US.json b/backend/chainlit/translations/en-US.json index dc690fd97f..4eb6849acd 100644 --- a/backend/chainlit/translations/en-US.json +++ b/backend/chainlit/translations/en-US.json @@ -187,5 +187,22 @@ "success": { "saved": "Saved successfully" } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" } } diff --git a/backend/chainlit/translations/gu.json b/backend/chainlit/translations/gu.json index 39e4db4bad..e82a794083 100644 --- a/backend/chainlit/translations/gu.json +++ b/backend/chainlit/translations/gu.json @@ -187,5 +187,22 @@ "success": { "saved": "સફળતાપૂર્વક સાચવ્યું" } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" } } diff --git a/backend/chainlit/translations/he-IL.json b/backend/chainlit/translations/he-IL.json index cfeed9b8ac..db0be6b457 100644 --- a/backend/chainlit/translations/he-IL.json +++ b/backend/chainlit/translations/he-IL.json @@ -187,5 +187,22 @@ "success": { "saved": "נשמר בהצלחה" } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" } } diff --git a/backend/chainlit/translations/hi.json b/backend/chainlit/translations/hi.json index 11807fb8ab..3102783f54 100644 --- a/backend/chainlit/translations/hi.json +++ b/backend/chainlit/translations/hi.json @@ -187,5 +187,22 @@ "success": { "saved": "सफलतापूर्वक सहेजा गया" } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" } } diff --git a/backend/chainlit/translations/ja.json b/backend/chainlit/translations/ja.json index 72a378314b..6ae60a0d12 100644 --- a/backend/chainlit/translations/ja.json +++ b/backend/chainlit/translations/ja.json @@ -187,5 +187,22 @@ "success": { "saved": "保存が完了しました" } - } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" + } } diff --git a/backend/chainlit/translations/kn.json b/backend/chainlit/translations/kn.json index 6084ada0e9..5b421715c2 100644 --- a/backend/chainlit/translations/kn.json +++ b/backend/chainlit/translations/kn.json @@ -187,5 +187,22 @@ "success": { "saved": "ಯಶಸ್ವಿಯಾಗಿ ಉಳಿಸಲಾಗಿದೆ" } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" } } diff --git a/backend/chainlit/translations/ml.json b/backend/chainlit/translations/ml.json index dfafe38c8b..e47e69dc50 100644 --- a/backend/chainlit/translations/ml.json +++ b/backend/chainlit/translations/ml.json @@ -187,5 +187,22 @@ "success": { "saved": "വിജയകരമായി സംരക്ഷിച്ചു" } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" } } diff --git a/backend/chainlit/translations/mr.json b/backend/chainlit/translations/mr.json index 8a3611e467..8aa0b779bf 100644 --- a/backend/chainlit/translations/mr.json +++ b/backend/chainlit/translations/mr.json @@ -187,5 +187,22 @@ "success": { "saved": "यशस्वीरित्या जतन केले" } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" } } diff --git a/backend/chainlit/translations/nl-NL.json b/backend/chainlit/translations/nl-NL.json index edd2faae39..be397e0557 100644 --- a/backend/chainlit/translations/nl-NL.json +++ b/backend/chainlit/translations/nl-NL.json @@ -187,5 +187,22 @@ "success": { "saved": "Succesvol opgeslagen" } - } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" + } } diff --git a/backend/chainlit/translations/ta.json b/backend/chainlit/translations/ta.json index 99c0856aac..0d43b2babf 100644 --- a/backend/chainlit/translations/ta.json +++ b/backend/chainlit/translations/ta.json @@ -187,5 +187,22 @@ "success": { "saved": "வெற்றிகரமாக சேமிக்கப்பட்டது" } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" } } diff --git a/backend/chainlit/translations/te.json b/backend/chainlit/translations/te.json index d75dd99e53..c1b4ca1b3d 100644 --- a/backend/chainlit/translations/te.json +++ b/backend/chainlit/translations/te.json @@ -187,5 +187,22 @@ "success": { "saved": "విజయవంతంగా సేవ్ చేయబడింది" } + }, + "alerts": { + "info": "Info", + "note": "Note", + "tip": "Tip", + "important": "Important", + "warning": "Warning", + "caution": "Caution", + "debug": "Debug", + "example": "Example", + "success": "Success", + "help": "Help", + "idea": "Idea", + "pending": "Pending", + "security": "Security", + "beta": "Beta", + "best-practice": "Best Practice" } } diff --git a/backend/chainlit/translations/zh-CN.json b/backend/chainlit/translations/zh-CN.json index 56f8430016..c3c0d3558c 100644 --- a/backend/chainlit/translations/zh-CN.json +++ b/backend/chainlit/translations/zh-CN.json @@ -187,5 +187,22 @@ "success": { "saved": "保存成功" } + }, + "alerts": { + "info": "信息", + "note": "注释", + "tip": "提示", + "important": "重要", + "warning": "警告", + "caution": "注意", + "debug": "调试", + "example": "示例", + "success": "成功", + "help": "帮助", + "idea": "想法", + "pending": "待处理", + "security": "安全", + "beta": "测试", + "best-practice": "最佳实践" } } diff --git a/frontend/package.json b/frontend/package.json index 82b81eb499..e9ed7df955 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -61,6 +61,7 @@ "recoil": "^0.7.7", "rehype-katex": "^7.0.0", "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.1", "remark-gfm": "^4.0.0", "remark-math": "^6.0.0", "sonner": "^1.2.3", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index c86204c734..1a3cbf3cd4 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -165,6 +165,9 @@ importers: rehype-raw: specifier: ^7.0.0 version: 7.0.0 + remark-directive: + specifier: ^3.0.1 + version: 3.0.1 remark-gfm: specifier: ^4.0.0 version: 4.0.0 @@ -3044,6 +3047,9 @@ packages: resolution: {integrity: sha512-9W0yGtkaMAkf74XGYVy4Dqw3YUMnTNB2eeiw9aQbUl4A3KmuCEHTt2DgAB07ENzOYAjsYSAYufkAq0Zd+jU7zA==} engines: {node: '>=0.10.0'} + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + mdast-util-find-and-replace@3.0.1: resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} @@ -3102,6 +3108,9 @@ packages: micromark-core-commonmark@2.0.0: resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + micromark-extension-gfm-autolink-literal@2.0.0: resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==} @@ -3719,6 +3728,9 @@ packages: rehype-raw@7.0.0: resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + remark-gfm@4.0.0: resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} @@ -4074,8 +4086,8 @@ packages: ufo@1.5.2: resolution: {integrity: sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==} - unified@11.0.4: - resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} unist-util-find-after@5.0.0: resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} @@ -7278,6 +7290,20 @@ snapshots: math-log2@1.0.1: {} + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + parse-entities: 4.0.1 + stringify-entities: 4.0.3 + unist-util-visit-parents: 6.0.1 + transitivePeerDependencies: + - supports-color + mdast-util-find-and-replace@3.0.1: dependencies: '@types/mdast': 4.0.3 @@ -7466,6 +7492,16 @@ snapshots: micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + parse-entities: 4.0.1 + micromark-extension-gfm-autolink-literal@2.0.0: dependencies: micromark-util-character: 2.1.0 @@ -8071,7 +8107,7 @@ snapshots: react: 18.3.1 remark-parse: 11.0.0 remark-rehype: 11.1.0 - unified: 11.0.4 + unified: 11.0.5 unist-util-visit: 5.0.0 vfile: 6.0.1 transitivePeerDependencies: @@ -8284,6 +8320,15 @@ snapshots: hast-util-raw: 9.0.2 vfile: 6.0.1 + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.3 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + remark-gfm@4.0.0: dependencies: '@types/mdast': 4.0.3 @@ -8291,7 +8336,7 @@ snapshots: micromark-extension-gfm: 3.0.0 remark-parse: 11.0.0 remark-stringify: 11.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color @@ -8300,7 +8345,7 @@ snapshots: '@types/mdast': 4.0.3 mdast-util-math: 3.0.0 micromark-extension-math: 3.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color @@ -8309,7 +8354,7 @@ snapshots: '@types/mdast': 4.0.3 mdast-util-from-markdown: 2.0.0 micromark-util-types: 2.0.0 - unified: 11.0.4 + unified: 11.0.5 transitivePeerDependencies: - supports-color @@ -8318,14 +8363,14 @@ snapshots: '@types/hast': 3.0.4 '@types/mdast': 4.0.3 mdast-util-to-hast: 13.1.0 - unified: 11.0.4 + unified: 11.0.5 vfile: 6.0.1 remark-stringify@11.0.0: dependencies: '@types/mdast': 4.0.3 mdast-util-to-markdown: 2.1.0 - unified: 11.0.4 + unified: 11.0.5 requires-port@1.0.0: {} @@ -8697,7 +8742,7 @@ snapshots: ufo@1.5.2: {} - unified@11.0.4: + unified@11.0.5: dependencies: '@types/unist': 3.0.2 bail: 2.0.2 diff --git a/frontend/src/components/Markdown.tsx b/frontend/src/components/Markdown.tsx index 4efea9d678..d4a0e8180b 100644 --- a/frontend/src/components/Markdown.tsx +++ b/frontend/src/components/Markdown.tsx @@ -5,6 +5,7 @@ import ReactMarkdown from 'react-markdown'; import { PluggableList } from 'react-markdown/lib'; import rehypeKatex from 'rehype-katex'; import rehypeRaw from 'rehype-raw'; +import remarkDirective from 'remark-directive'; import remarkGfm from 'remark-gfm'; import remarkMath from 'remark-math'; import { visit } from 'unist-util-visit'; @@ -26,6 +27,7 @@ import { import BlinkingCursor from './BlinkingCursor'; import CodeSnippet from './CodeSnippet'; import { ElementRef } from './Elements/ElementRef'; +import { MarkdownAlert, alertComponents } from './MarkdownAlert'; interface Props { allowHtml?: boolean; @@ -102,7 +104,12 @@ const Markdown = ({ }, [allowHtml, latex]); const remarkPlugins = useMemo(() => { - let remarkPlugins: PluggableList = [cursorPlugin, remarkGfm as any]; + let remarkPlugins: PluggableList = [ + cursorPlugin, + remarkGfm as any, + remarkDirective as any, + MarkdownAlert + ]; if (latex) { remarkPlugins = [...remarkPlugins, remarkMath as any]; @@ -116,6 +123,7 @@ const Markdown = ({ remarkPlugins={remarkPlugins} rehypePlugins={rehypePlugins} components={{ + ...alertComponents, // add alert components code(props) { return ( { + const { t } = useTranslation(); + const style = variantStyles[variant]; + const Icon = style.Icon; + + // console.log('AlertComponent rendering:', variant, children); + + return ( +
+
+
+ +
+
+
+ {t(`alerts.${variant}`)} +
+
{children}
+
+
+
+ ); +}; +// MarkdownAlert plugin +export const MarkdownAlert = () => { + return (tree: any) => { + visit(tree, 'text', (node) => { + const regex = /^:::\s*([\w-]+)\n([\s\S]*?)\n:::/i; + const match = node.value.match(regex); + + if (match) { + const [, type, content] = match; + node.type = 'element'; + node.data = { + hName: 'Alert', + hProperties: { variant: type.toLowerCase() } + }; + node.children = [{ type: 'text', value: content.trim() }]; + } + }); + }; +}; + +export const alertComponents = { + Alert: AlertComponent +};