markdown.rs

  1use assets::Assets;
  2use gpui::{prelude::*, rgb, App, KeyBinding, StyleRefinement, 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                let markdown_style = MarkdownStyle {
109                    base_text_style: gpui::TextStyle {
110                        font_family: "Zed Plex Sans".into(),
111                        color: cx.theme().colors().terminal_ansi_black,
112                        ..Default::default()
113                    },
114                    code_block: StyleRefinement::default()
115                        .font_family("Zed Plex Mono")
116                        .m(rems(1.))
117                        .bg(rgb(0xAAAAAAA)),
118                    inline_code: gpui::TextStyleRefinement {
119                        font_family: Some("Zed Mono".into()),
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                    ..Default::default()
146                };
147
148                MarkdownExample::new(
149                    MARKDOWN_EXAMPLE.to_string(),
150                    markdown_style,
151                    language_registry,
152                    cx,
153                )
154            })
155        })
156        .unwrap();
157    });
158}
159
160struct MarkdownExample {
161    markdown: View<Markdown>,
162}
163
164impl MarkdownExample {
165    pub fn new(
166        text: String,
167        style: MarkdownStyle,
168        language_registry: Arc<LanguageRegistry>,
169        cx: &mut WindowContext,
170    ) -> Self {
171        let markdown =
172            cx.new_view(|cx| Markdown::new(text, style, Some(language_registry), cx, None));
173        Self { markdown }
174    }
175}
176
177impl Render for MarkdownExample {
178    fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
179        div()
180            .id("markdown-example")
181            .debug_selector(|| "foo".into())
182            .relative()
183            .bg(gpui::white())
184            .size_full()
185            .p_4()
186            .overflow_y_scroll()
187            .child(self.markdown.clone())
188    }
189}