1mod components;
2mod options;
3mod settings;
4mod store;
5
6pub use options::Options;
7
8use {
9 components::{
10 Blockquote, Code, Definition, Delete, Emphasis, FootnoteDefinition, FootnoteReference,
11 Footnotes, Header, Headings, Html, Image, ImageReference, InlineCode, InlineMath, Link,
12 LinkReference, List, ListItem, Math, Paragraph, Strong, Table, TableCell, TableRow, Text,
13 Toml, Yaml,
14 },
15 dioxus::prelude::*,
16 markdown::mdast::Node,
17 settings::Settings,
18};
19
20#[derive(PartialEq, Clone, Props)]
21pub struct MarkdownProps {
22 src: ReadSignal<String>,
24
25 #[props(default)]
28 options: Options,
29}
30
31#[component]
57pub fn Markdown(props: MarkdownProps) -> Element {
58 let node = match markdown::to_mdast(&props.src.read(), &Settings::default().into()) {
59 Ok(v) => v,
60 Err(err) => {
61 return rsx! {
62 h1 { "Error" }
63 strong { "{err}" }
64 };
65 }
66 };
67
68 use_context_provider(|| props.options.clone());
69 use_context_provider(|| Signal::new(store::Html::default()));
70 use_context_provider(|| Signal::new(store::Headings::default()));
71 use_context_provider(|| Signal::new(store::References::default()));
72 use_context_provider(|| Signal::new(store::Footnotes::default()));
73 use_context_provider(|| Signal::new(store::Frontmatter::default()));
74 use_context_provider(store::Math::default);
75
76 rsx! {
77 if !props.options.disable_default_theme {
78 document::Link { rel: "stylesheet", href: asset!("/assets/styles.css") }
79 }
80 div { id: "markdown-dx",
81 if props.options.include_frontmatter_header {
82 Header {}
83 }
84 DxNode { src: node }
85 hr {}
86 Footnotes {}
87 }
88 }
89}
90
91#[component]
93fn DxNode(src: Node) -> Element {
94 match src {
95 Node::Root(v) => rsx! {
96 ChildNodes { src: v.children }
97 },
98 Node::Blockquote(src) => rsx! {
99 Blockquote { src }
100 },
101 Node::Break(_src) => rsx! {
102 br {}
103 },
104 Node::Code(src) => rsx! {
105 Code { src }
106 },
107 Node::Definition(src) => rsx! {
108 Definition { src }
109 },
110 Node::Delete(src) => rsx! {
111 Delete { src }
112 },
113 Node::Emphasis(src) => rsx! {
114 Emphasis { src }
115 },
116 Node::FootnoteDefinition(src) => rsx! {
117 FootnoteDefinition { src }
118 },
119 Node::FootnoteReference(src) => rsx! {
120 FootnoteReference { src }
121 },
122 Node::Heading(src) => rsx! {
123 Headings { src }
124 },
125 Node::Html(src) => rsx! {
126 Html { src }
127 },
128 Node::Image(src) => rsx! {
129 Image { src }
130 },
131 Node::ImageReference(src) => rsx! {
132 ImageReference { src }
133 },
134 Node::InlineCode(src) => rsx! {
135 InlineCode { src }
136 },
137 Node::InlineMath(src) => rsx! {
138 InlineMath { src }
139 },
140 Node::Link(src) => rsx! {
141 Link { src }
142 },
143 Node::LinkReference(src) => rsx! {
144 LinkReference { src }
145 },
146 Node::List(src) => rsx! {
147 List { src }
148 },
149 Node::ListItem(src) => rsx! {
150 ListItem { src }
151 },
152 Node::Math(src) => rsx! {
153 Math { src }
154 },
155 Node::MdxFlowExpression(src) => rsx! {
156 h1 { "Unimplemented: MdxFlowExpression" }
157 pre { "{src:#?}" }
158 },
159 Node::MdxJsxFlowElement(src) => rsx! {
160 h1 { "Unimplemented: MdxJsxFlowElement" }
161 pre { "{src:#?}" }
162 },
163 Node::MdxJsxTextElement(src) => rsx! {
164 h1 { "Unimplemented: MdxJsxTextElement" }
165 pre { "{src:#?}" }
166 },
167 Node::MdxTextExpression(src) => rsx! {
168 h1 { "Unimplemented: MdxTextExpression" }
169 pre { "{src:#?}" }
170 },
171 Node::MdxjsEsm(src) => rsx! {
172 h1 { "Unimplemented: MdxjsEsm" }
173 pre { "{src:#?}" }
174 },
175 Node::Paragraph(src) => rsx! {
176 Paragraph { src }
177 },
178 Node::Strong(src) => rsx! {
179 Strong { src }
180 },
181 Node::Table(src) => rsx! {
182 Table { src }
183 },
184 Node::TableCell(src) => rsx! {
185 TableCell { src, id: "" }
186 },
187 Node::TableRow(src) => rsx! {
188 TableRow { src }
189 },
190 Node::Text(src) => rsx! {
191 Text { src }
192 },
193 Node::ThematicBreak(_src) => rsx! {
194 hr {}
195 },
196 Node::Toml(src) => rsx! {
197 Toml { src }
198 },
199 Node::Yaml(src) => rsx! {
200 Yaml { src }
201 },
202 }
203}
204
205#[component]
208fn ChildNodes(src: Vec<Node>) -> Element {
209 rsx! {
210 for node in src {
211 DxNode { src: node }
212 }
213 }
214}