Markdown parser fork with extended syntax for personal use.
1use alloc::{boxed::Box, string::String};
2
3/// Signal used as feedback when parsing MDX ESM/expressions.
4#[derive(Clone, Debug)]
5pub enum Signal {
6 /// A syntax error.
7 ///
8 /// `markdown-rs` will crash with error message `String`, and convert the
9 /// `usize` (byte offset into `&str` passed to `MdxExpressionParse` or
10 /// `MdxEsmParse`) to where it happened in the whole document.
11 ///
12 /// ## Examples
13 ///
14 /// ```rust ignore
15 /// Signal::Error("Unexpected `\"`, expected identifier".into(), 1)
16 /// ```
17 Error(String, usize, Box<String>, Box<String>),
18 /// An error at the end of the (partial?) expression.
19 ///
20 /// `markdown-rs` will either crash with error message `String` if it
21 /// doesn’t have any more text, or it will try again later when more text
22 /// is available.
23 ///
24 /// ## Examples
25 ///
26 /// ```rust ignore
27 /// Signal::Eof("Unexpected end of file in string literal".into())
28 /// ```
29 Eof(String, Box<String>, Box<String>),
30 /// Done, successfully.
31 ///
32 /// `markdown-rs` knows that this is the end of a valid expression/esm and
33 /// continues with markdown.
34 ///
35 /// ## Examples
36 ///
37 /// ```rust ignore
38 /// Signal::Ok
39 /// ```
40 Ok,
41}
42
43/// Signature of a function that parses MDX ESM.
44///
45/// Can be passed as `mdx_esm_parse` in
46/// [`ParseOptions`][crate::configuration::ParseOptions] to support
47/// ESM according to a certain grammar (typically, a programming language).
48pub type EsmParse = dyn Fn(&str) -> Signal;
49
50/// Expression kind.
51#[derive(Clone, Debug)]
52pub enum ExpressionKind {
53 /// Kind of expressions in prose.
54 ///
55 /// ```mdx
56 /// > | # {Math.PI}
57 /// ^^^^^^^^^
58 /// |
59 /// > | {Math.PI}
60 /// ^^^^^^^^^
61 /// ```
62 Expression,
63 /// Kind of expressions as attributes.
64 ///
65 /// ```mdx
66 /// > | <a {...b}>
67 /// ^^^^^^
68 /// ```
69 AttributeExpression,
70 /// Kind of expressions as attribute values.
71 ///
72 /// ```mdx
73 /// > | <a b={c}>
74 /// ^^^
75 /// ```
76 AttributeValueExpression,
77}
78
79/// Signature of a function that parses MDX expressions.
80///
81/// Can be passed as `mdx_expression_parse` in
82/// [`ParseOptions`][crate::configuration::ParseOptions] to support
83/// expressions according to a certain grammar (typically, a programming
84/// language).
85///
86pub type ExpressionParse = dyn Fn(&str, &ExpressionKind) -> Signal;
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use alloc::boxed::Box;
92
93 #[test]
94 fn test_mdx_expression_parse() {
95 fn func(_value: &str, _kind: &ExpressionKind) -> Signal {
96 Signal::Ok
97 }
98
99 let func_accepting = |_a: Box<ExpressionParse>| true;
100
101 assert!(
102 matches!(func("a", &ExpressionKind::Expression), Signal::Ok),
103 "should expose an `ExpressionParse` type (1)"
104 );
105
106 assert!(
107 func_accepting(Box::new(func)),
108 "should expose an `ExpressionParse` type (2)"
109 );
110 }
111
112 #[test]
113 fn test_mdx_esm_parse() {
114 fn func(_value: &str) -> Signal {
115 Signal::Ok
116 }
117
118 let func_accepting = |_a: Box<EsmParse>| true;
119
120 assert!(
121 matches!(func("a"), Signal::Ok),
122 "should expose an `EsmParse` type (1)"
123 );
124
125 assert!(
126 func_accepting(Box::new(func)),
127 "should expose an `EsmParse` type (2)"
128 );
129 }
130}