summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/utils/MarkdownDisplay.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/utils/MarkdownDisplay.tsx')
-rw-r--r--packages/cli/src/ui/utils/MarkdownDisplay.tsx144
1 files changed, 1 insertions, 143 deletions
diff --git a/packages/cli/src/ui/utils/MarkdownDisplay.tsx b/packages/cli/src/ui/utils/MarkdownDisplay.tsx
index 55f1ce57..572ae12e 100644
--- a/packages/cli/src/ui/utils/MarkdownDisplay.tsx
+++ b/packages/cli/src/ui/utils/MarkdownDisplay.tsx
@@ -9,6 +9,7 @@ import { Text, Box } from 'ink';
import { Colors } from '../colors.js';
import { colorizeCode } from './CodeColorizer.js';
import { TableRenderer } from './TableRenderer.js';
+import { RenderInline } from './InlineMarkdownRenderer.js';
interface MarkdownDisplayProps {
text: string;
@@ -18,12 +19,6 @@ interface MarkdownDisplayProps {
}
// Constants for Markdown parsing and rendering
-const BOLD_MARKER_LENGTH = 2; // For "**"
-const ITALIC_MARKER_LENGTH = 1; // For "*" or "_"
-const STRIKETHROUGH_MARKER_LENGTH = 2; // For "~~"
-const INLINE_CODE_MARKER_LENGTH = 1; // For "`"
-const UNDERLINE_TAG_START_LENGTH = 3; // For "<u>"
-const UNDERLINE_TAG_END_LENGTH = 4; // For "</u>"
const EMPTY_LINE_HEIGHT = 1;
const CODE_BLOCK_PADDING = 1;
@@ -277,143 +272,6 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
// Helper functions (adapted from static methods of MarkdownRenderer)
-interface RenderInlineProps {
- text: string;
-}
-
-const RenderInlineInternal: React.FC<RenderInlineProps> = ({ text }) => {
- const nodes: React.ReactNode[] = [];
- let lastIndex = 0;
- const inlineRegex =
- /(\*\*.*?\*\*|\*.*?\*|_.*?_|~~.*?~~|\[.*?\]\(.*?\)|`+.+?`+|<u>.*?<\/u>)/g;
- let match;
-
- while ((match = inlineRegex.exec(text)) !== null) {
- if (match.index > lastIndex) {
- nodes.push(
- <Text key={`t-${lastIndex}`}>
- {text.slice(lastIndex, match.index)}
- </Text>,
- );
- }
-
- const fullMatch = match[0];
- let renderedNode: React.ReactNode = null;
- const key = `m-${match.index}`;
-
- try {
- if (
- fullMatch.startsWith('**') &&
- fullMatch.endsWith('**') &&
- fullMatch.length > BOLD_MARKER_LENGTH * 2
- ) {
- renderedNode = (
- <Text key={key} bold>
- {fullMatch.slice(BOLD_MARKER_LENGTH, -BOLD_MARKER_LENGTH)}
- </Text>
- );
- } else if (
- fullMatch.length > ITALIC_MARKER_LENGTH * 2 &&
- ((fullMatch.startsWith('*') && fullMatch.endsWith('*')) ||
- (fullMatch.startsWith('_') && fullMatch.endsWith('_'))) &&
- !/\w/.test(text.substring(match.index - 1, match.index)) &&
- !/\w/.test(
- text.substring(inlineRegex.lastIndex, inlineRegex.lastIndex + 1),
- ) &&
- !/\S[./\\]/.test(text.substring(match.index - 2, match.index)) &&
- !/[./\\]\S/.test(
- text.substring(inlineRegex.lastIndex, inlineRegex.lastIndex + 2),
- )
- ) {
- renderedNode = (
- <Text key={key} italic>
- {fullMatch.slice(ITALIC_MARKER_LENGTH, -ITALIC_MARKER_LENGTH)}
- </Text>
- );
- } else if (
- fullMatch.startsWith('~~') &&
- fullMatch.endsWith('~~') &&
- fullMatch.length > STRIKETHROUGH_MARKER_LENGTH * 2
- ) {
- renderedNode = (
- <Text key={key} strikethrough>
- {fullMatch.slice(
- STRIKETHROUGH_MARKER_LENGTH,
- -STRIKETHROUGH_MARKER_LENGTH,
- )}
- </Text>
- );
- } else if (
- fullMatch.startsWith('`') &&
- fullMatch.endsWith('`') &&
- fullMatch.length > INLINE_CODE_MARKER_LENGTH
- ) {
- const codeMatch = fullMatch.match(/^(`+)(.+?)\1$/s);
- if (codeMatch && codeMatch[2]) {
- renderedNode = (
- <Text key={key} color={Colors.AccentPurple}>
- {codeMatch[2]}
- </Text>
- );
- } else {
- renderedNode = (
- <Text key={key} color={Colors.AccentPurple}>
- {fullMatch.slice(
- INLINE_CODE_MARKER_LENGTH,
- -INLINE_CODE_MARKER_LENGTH,
- )}
- </Text>
- );
- }
- } else if (
- fullMatch.startsWith('[') &&
- fullMatch.includes('](') &&
- fullMatch.endsWith(')')
- ) {
- const linkMatch = fullMatch.match(/\[(.*?)\]\((.*?)\)/);
- if (linkMatch) {
- const linkText = linkMatch[1];
- const url = linkMatch[2];
- renderedNode = (
- <Text key={key}>
- {linkText}
- <Text color={Colors.AccentBlue}> ({url})</Text>
- </Text>
- );
- }
- } else if (
- fullMatch.startsWith('<u>') &&
- fullMatch.endsWith('</u>') &&
- fullMatch.length >
- UNDERLINE_TAG_START_LENGTH + UNDERLINE_TAG_END_LENGTH - 1 // -1 because length is compared to combined length of start and end tags
- ) {
- renderedNode = (
- <Text key={key} underline>
- {fullMatch.slice(
- UNDERLINE_TAG_START_LENGTH,
- -UNDERLINE_TAG_END_LENGTH,
- )}
- </Text>
- );
- }
- } catch (e) {
- console.error('Error parsing inline markdown part:', fullMatch, e);
- renderedNode = null;
- }
-
- nodes.push(renderedNode ?? <Text key={key}>{fullMatch}</Text>);
- lastIndex = inlineRegex.lastIndex;
- }
-
- if (lastIndex < text.length) {
- nodes.push(<Text key={`t-${lastIndex}`}>{text.slice(lastIndex)}</Text>);
- }
-
- return <>{nodes.filter((node) => node !== null)}</>;
-};
-
-const RenderInline = React.memo(RenderInlineInternal);
-
interface RenderCodeBlockProps {
content: string[];
lang: string | null;