1use assets::Assets;
2use gpui::{prelude::*, App, 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
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
95 let node_runtime = FakeNodeRuntime::new();
96 let language_registry = Arc::new(LanguageRegistry::new(
97 Task::ready(()),
98 cx.background_executor().clone(),
99 ));
100 languages::init(language_registry.clone(), node_runtime, cx);
101 theme::init(LoadThemes::JustBase, cx);
102 Assets.load_fonts(cx).unwrap();
103
104 cx.activate(true);
105 cx.open_window(WindowOptions::default(), |cx| {
106 cx.new_view(|cx| {
107 MarkdownExample::new(
108 MARKDOWN_EXAMPLE.to_string(),
109 MarkdownStyle {
110 code_block: gpui::TextStyleRefinement {
111 font_family: Some("Zed Mono".into()),
112 color: Some(cx.theme().colors().editor_foreground),
113 background_color: Some(cx.theme().colors().editor_background),
114 ..Default::default()
115 },
116 inline_code: gpui::TextStyleRefinement {
117 font_family: Some("Zed Mono".into()),
118 // @nate: Could we add inline-code specific styles to the theme?
119 color: Some(cx.theme().colors().editor_foreground),
120 background_color: Some(cx.theme().colors().editor_background),
121 ..Default::default()
122 },
123 rule_color: Color::Muted.color(cx),
124 block_quote_border_color: Color::Muted.color(cx),
125 block_quote: gpui::TextStyleRefinement {
126 color: Some(Color::Muted.color(cx)),
127 ..Default::default()
128 },
129 link: gpui::TextStyleRefinement {
130 color: Some(Color::Accent.color(cx)),
131 underline: Some(gpui::UnderlineStyle {
132 thickness: px(1.),
133 color: Some(Color::Accent.color(cx)),
134 wavy: false,
135 }),
136 ..Default::default()
137 },
138 syntax: cx.theme().syntax().clone(),
139 selection_background_color: {
140 let mut selection = cx.theme().players().local().selection;
141 selection.fade_out(0.7);
142 selection
143 },
144 },
145 language_registry,
146 cx,
147 )
148 })
149 });
150 });
151}
152
153struct MarkdownExample {
154 markdown: View<Markdown>,
155}
156
157impl MarkdownExample {
158 pub fn new(
159 text: String,
160 style: MarkdownStyle,
161 language_registry: Arc<LanguageRegistry>,
162 cx: &mut WindowContext,
163 ) -> Self {
164 let markdown = cx.new_view(|cx| Markdown::new(text, style, language_registry, cx));
165 Self { markdown }
166 }
167}
168
169impl Render for MarkdownExample {
170 fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
171 div()
172 .id("markdown-example")
173 .debug_selector(|| "foo".into())
174 .relative()
175 .bg(gpui::white())
176 .size_full()
177 .p_4()
178 .overflow_y_scroll()
179 .child(self.markdown.clone())
180 }
181}