vtcode_core/ui/
markdown.rs1use crate::config::loader::SyntaxHighlightingConfig;
2use crate::ui::theme::{self, ThemeStyles};
3use anstyle::Style;
4
5#[cfg(feature = "tui")]
7pub use vtcode_ui::tui::ui::markdown::{
8 HighlightedSegment, MarkdownLine, MarkdownSegment, RenderMarkdownOptions, highlight_code_to_ansi,
9 highlight_code_to_segments, highlight_line_for_diff,
10};
11
12#[cfg(not(feature = "tui"))]
14pub use vtcode_commons::ui_protocol::{HighlightedSegment, MarkdownLine, MarkdownSegment, RenderMarkdownOptions};
15
16#[cfg(not(feature = "tui"))]
18pub fn highlight_code_to_ansi(code: &str, _language: Option<&str>, _theme: &str) -> String {
19 code.to_string()
20}
21
22#[cfg(not(feature = "tui"))]
24pub fn highlight_code_to_segments(code: &str, _language: Option<&str>, _theme: &str) -> Vec<HighlightedSegment> {
25 vec![HighlightedSegment { style: Style::default(), text: code.to_string() }]
26}
27
28#[cfg(not(feature = "tui"))]
30pub fn highlight_line_for_diff(line: &str, _language: Option<&str>) -> Option<Vec<(Style, String)>> {
31 Some(vec![(Style::default(), line.to_string())])
32}
33
34pub fn render_markdown_to_lines(
38 source: &str,
39 base_style: Style,
40 theme_styles: &ThemeStyles,
41 highlight_config: Option<&SyntaxHighlightingConfig>,
42) -> Vec<MarkdownLine> {
43 render_markdown_to_lines_with_options(
44 source,
45 base_style,
46 theme_styles,
47 highlight_config,
48 RenderMarkdownOptions::default(),
49 )
50}
51
52#[cfg(feature = "tui")]
54pub fn render_markdown_to_lines_with_options(
55 source: &str,
56 base_style: Style,
57 theme_styles: &ThemeStyles,
58 highlight_config: Option<&SyntaxHighlightingConfig>,
59 render_options: RenderMarkdownOptions,
60) -> Vec<MarkdownLine> {
61 let tui_theme_styles = crate::ui::tui_compat::tui_theme_styles_from_core(theme_styles);
62 let tui_highlight_cfg = highlight_config.map(|cfg| vtcode_ui::tui::TuiSyntaxHighlightingConfig {
63 enabled: cfg.enabled,
64 theme: cfg.theme.clone(),
65 cache_themes: cfg.cache_themes,
66 max_file_size_mb: cfg.max_file_size_mb,
67 enabled_languages: cfg.enabled_languages.clone(),
68 highlight_timeout_ms: cfg.highlight_timeout_ms,
69 });
70 vtcode_ui::tui::ui::markdown::render_markdown_to_lines_with_options(
71 source,
72 base_style,
73 &tui_theme_styles,
74 tui_highlight_cfg.as_ref(),
75 render_options,
76 )
77}
78
79#[cfg(not(feature = "tui"))]
81pub fn render_markdown_to_lines_with_options(
82 source: &str,
83 base_style: Style,
84 _theme_styles: &ThemeStyles,
85 _highlight_config: Option<&SyntaxHighlightingConfig>,
86 _render_options: RenderMarkdownOptions,
87) -> Vec<MarkdownLine> {
88 let mut lines: Vec<MarkdownLine> = source
89 .lines()
90 .map(|line| MarkdownLine {
91 segments: if line.is_empty() {
92 Vec::new()
93 } else {
94 vec![MarkdownSegment {
95 style: base_style,
96 text: line.to_string(),
97 link_target: None,
98 }]
99 },
100 })
101 .collect();
102 if lines.is_empty() {
103 lines.push(MarkdownLine::default());
104 }
105 lines
106}
107
108pub fn render_markdown(source: &str) -> Vec<MarkdownLine> {
110 let styles = theme::active_styles();
111 render_markdown_to_lines(source, Style::default(), &styles, None)
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 #[test]
119 fn facade_renders_markdown() {
120 let lines = render_markdown("# Heading");
121 assert!(!lines.is_empty());
122 }
123}