markdown.rs

  1use assets::Assets;
  2use gpui::{Application, Entity, KeyBinding, StyleRefinement, WindowOptions, prelude::*, rgb};
  3use language::{LanguageRegistry, language_settings::AllLanguageSettings};
  4use markdown::{Markdown, MarkdownStyle};
  5use node_runtime::NodeRuntime;
  6use settings::SettingsStore;
  7use std::sync::Arc;
  8use theme::LoadThemes;
  9use ui::prelude::*;
 10use ui::{App, Window, div};
 11
 12const MARKDOWN_EXAMPLE: &str = r#"
 13# Markdown Example Document
 14
 15## Headings
 16Headings are created by adding one or more `#` symbols before your heading text. The number of `#` you use will determine the size of the heading.
 17
 18```
 19function a(b: T) {
 20
 21}
 22```
 23
 24
 25Remember, markdown processors may have slight differences and extensions, so always refer to the specific documentation or guides relevant to your platform or editor for the best practices and additional features.
 26"#;
 27
 28pub fn main() {
 29    env_logger::init();
 30    Application::new().with_assets(Assets).run(|cx| {
 31        let store = SettingsStore::test(cx);
 32        cx.set_global(store);
 33        language::init(cx);
 34        SettingsStore::update(cx, |store, cx| {
 35            store.update_user_settings::<AllLanguageSettings>(cx, |_| {});
 36        });
 37        cx.bind_keys([KeyBinding::new("cmd-c", markdown::Copy, None)]);
 38
 39        let node_runtime = NodeRuntime::unavailable();
 40        theme::init(LoadThemes::JustBase, cx);
 41
 42        let language_registry = LanguageRegistry::new(cx.background_executor().clone());
 43        language_registry.set_theme(cx.theme().clone());
 44        let language_registry = Arc::new(language_registry);
 45        languages::init(language_registry.clone(), node_runtime, cx);
 46        Assets.load_fonts(cx).unwrap();
 47
 48        cx.activate(true);
 49        cx.open_window(WindowOptions::default(), |_, cx| {
 50            cx.new(|cx| {
 51                let markdown_style = MarkdownStyle {
 52                    base_text_style: gpui::TextStyle {
 53                        font_family: "Zed Plex Sans".into(),
 54                        color: cx.theme().colors().terminal_ansi_black,
 55                        ..Default::default()
 56                    },
 57                    code_block: StyleRefinement::default()
 58                        .font_family("Zed Plex Mono")
 59                        .m(rems(1.))
 60                        .bg(rgb(0xAAAAAAA)),
 61                    inline_code: gpui::TextStyleRefinement {
 62                        font_family: Some("Zed Mono".into()),
 63                        color: Some(cx.theme().colors().editor_foreground),
 64                        background_color: Some(cx.theme().colors().editor_background),
 65                        ..Default::default()
 66                    },
 67                    rule_color: Color::Muted.color(cx),
 68                    block_quote_border_color: Color::Muted.color(cx),
 69                    block_quote: gpui::TextStyleRefinement {
 70                        color: Some(Color::Muted.color(cx)),
 71                        ..Default::default()
 72                    },
 73                    link: gpui::TextStyleRefinement {
 74                        color: Some(Color::Accent.color(cx)),
 75                        underline: Some(gpui::UnderlineStyle {
 76                            thickness: px(1.),
 77                            color: Some(Color::Accent.color(cx)),
 78                            wavy: false,
 79                        }),
 80                        ..Default::default()
 81                    },
 82                    syntax: cx.theme().syntax().clone(),
 83                    selection_background_color: {
 84                        let mut selection = cx.theme().players().local().selection;
 85                        selection.fade_out(0.7);
 86                        selection
 87                    },
 88                    ..Default::default()
 89                };
 90
 91                MarkdownExample::new(
 92                    MARKDOWN_EXAMPLE.into(),
 93                    markdown_style,
 94                    language_registry,
 95                    cx,
 96                )
 97            })
 98        })
 99        .unwrap();
100    });
101}
102
103struct MarkdownExample {
104    markdown: Entity<Markdown>,
105}
106
107impl MarkdownExample {
108    pub fn new(
109        text: SharedString,
110        style: MarkdownStyle,
111        language_registry: Arc<LanguageRegistry>,
112        cx: &mut App,
113    ) -> Self {
114        let markdown = cx.new(|cx| {
115            Markdown::new(
116                text,
117                style,
118                Some(language_registry),
119                Some("TypeScript".to_string()),
120                cx,
121            )
122        });
123        Self { markdown }
124    }
125}
126
127impl Render for MarkdownExample {
128    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
129        div()
130            .id("markdown-example")
131            .debug_selector(|| "foo".into())
132            .relative()
133            .bg(gpui::white())
134            .size_full()
135            .p_4()
136            .overflow_y_scroll()
137            .child(self.markdown.clone())
138    }
139}