markdown.rs

  1use assets::Assets;
  2use gpui::{prelude::*, App, KeyBinding, Task, View, WindowOptions};
  3use language::{language_settings::AllLanguageSettings, LanguageRegistry};
  4use markdown::{Markdown, MarkdownStyle};
  5use node_runtime::FakeNodeRuntime;
  6use settings::SettingsStore;
  7use std::sync::Arc;
  8use theme::LoadThemes;
  9use ui::prelude::*;
 10use ui::{div, WindowContext};
 11
 12const MARKDOWN_EXAMPLE: &'static 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## Emphasis
 19Emphasis can be added with italics or bold. *This text will be italic*. _This will also be italic_
 20
 21## Lists
 22
 23### Unordered Lists
 24Unordered lists use asterisks `*`, plus `+`, or minus `-` as list markers.
 25
 26* Item 1
 27* Item 2
 28  * Item 2a
 29  * Item 2b
 30
 31### Ordered Lists
 32Ordered lists use numbers followed by a period.
 33
 341. Item 1
 352. Item 2
 363. Item 3
 37   1. Item 3a
 38   2. Item 3b
 39
 40## Links
 41Links are created using the format [http://zed.dev](https://zed.dev).
 42
 43They can also be detected automatically, for example https://zed.dev/blog.
 44
 45## Images
 46Images are like links, but with an exclamation mark `!` in front.
 47
 48```todo!
 49![This is an image](/images/logo.png)
 50```
 51
 52## Code
 53Inline `code` can be wrapped with backticks `` ` ``.
 54
 55```markdown
 56Inline `code` has `back-ticks around` it.
 57```
 58
 59Code blocks can be created by indenting lines by four spaces or with triple backticks ```.
 60
 61```javascript
 62function test() {
 63  console.log("notice the blank line before this function?");
 64}
 65```
 66
 67## Blockquotes
 68Blockquotes are created with `>`.
 69
 70> This is a blockquote.
 71
 72## Horizontal Rules
 73Horizontal rules are created using three or more asterisks `***`, dashes `---`, or underscores `___`.
 74
 75## Line breaks
 76This is a
 77\
 78line break!
 79
 80---
 81
 82Remember, 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.
 83"#;
 84
 85pub fn main() {
 86    env_logger::init();
 87    App::new().with_assets(Assets).run(|cx| {
 88        let store = SettingsStore::test(cx);
 89        cx.set_global(store);
 90        language::init(cx);
 91        SettingsStore::update(cx, |store, cx| {
 92            store.update_user_settings::<AllLanguageSettings>(cx, |_| {});
 93        });
 94        cx.bind_keys([KeyBinding::new("cmd-c", markdown::Copy, None)]);
 95
 96        let node_runtime = FakeNodeRuntime::new();
 97        let language_registry = Arc::new(LanguageRegistry::new(
 98            Task::ready(()),
 99            cx.background_executor().clone(),
100        ));
101        languages::init(language_registry.clone(), node_runtime, cx);
102        theme::init(LoadThemes::JustBase, cx);
103        Assets.load_fonts(cx).unwrap();
104
105        cx.activate(true);
106        cx.open_window(WindowOptions::default(), |cx| {
107            cx.new_view(|cx| {
108                MarkdownExample::new(
109                    MARKDOWN_EXAMPLE.to_string(),
110                    MarkdownStyle {
111                        code_block: gpui::TextStyleRefinement {
112                            font_family: Some("Zed Plex Mono".into()),
113                            color: Some(cx.theme().colors().editor_foreground),
114                            background_color: Some(cx.theme().colors().editor_background),
115                            ..Default::default()
116                        },
117                        inline_code: gpui::TextStyleRefinement {
118                            font_family: Some("Zed Plex Mono".into()),
119                            // @nate: Could we add inline-code specific styles to the theme?
120                            color: Some(cx.theme().colors().editor_foreground),
121                            background_color: Some(cx.theme().colors().editor_background),
122                            ..Default::default()
123                        },
124                        rule_color: Color::Muted.color(cx),
125                        block_quote_border_color: Color::Muted.color(cx),
126                        block_quote: gpui::TextStyleRefinement {
127                            color: Some(Color::Muted.color(cx)),
128                            ..Default::default()
129                        },
130                        link: gpui::TextStyleRefinement {
131                            color: Some(Color::Accent.color(cx)),
132                            underline: Some(gpui::UnderlineStyle {
133                                thickness: px(1.),
134                                color: Some(Color::Accent.color(cx)),
135                                wavy: false,
136                            }),
137                            ..Default::default()
138                        },
139                        syntax: cx.theme().syntax().clone(),
140                        selection_background_color: {
141                            let mut selection = cx.theme().players().local().selection;
142                            selection.fade_out(0.7);
143                            selection
144                        },
145                    },
146                    language_registry,
147                    cx,
148                )
149            })
150        })
151        .unwrap();
152    });
153}
154
155struct MarkdownExample {
156    markdown: View<Markdown>,
157}
158
159impl MarkdownExample {
160    pub fn new(
161        text: String,
162        style: MarkdownStyle,
163        language_registry: Arc<LanguageRegistry>,
164        cx: &mut WindowContext,
165    ) -> Self {
166        let markdown = cx.new_view(|cx| Markdown::new(text, style, Some(language_registry), cx));
167        Self { markdown }
168    }
169}
170
171impl Render for MarkdownExample {
172    fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
173        div()
174            .id("markdown-example")
175            .debug_selector(|| "foo".into())
176            .relative()
177            .bg(gpui::white())
178            .size_full()
179            .p_4()
180            .overflow_y_scroll()
181            .child(self.markdown.clone())
182    }
183}