1pub mod alerts;
8pub mod ast;
9pub mod attributes;
10pub mod block_quotes;
11pub mod blocks;
12pub mod chunk_options;
13pub mod citations;
14pub mod code_blocks;
15pub mod crossrefs;
16pub mod definitions;
17pub mod fenced_divs;
18pub mod headings;
19pub mod inlines;
20pub mod kind;
21pub mod links;
22pub mod lists;
23pub mod math;
24pub mod myst;
25pub mod raw_tex;
26pub mod references;
27pub mod shortcodes;
28pub mod tables;
29pub mod yaml;
30pub mod yaml_ast;
31
32pub use alerts::*;
33pub use ast::*;
34pub use attributes::*;
35pub use block_quotes::*;
36pub use blocks::*;
37pub use chunk_options::*;
38pub use citations::*;
39pub use code_blocks::*;
40pub use crossrefs::*;
41pub use definitions::*;
42pub use fenced_divs::*;
43pub use headings::*;
44pub use inlines::*;
45pub use kind::*;
46pub use links::*;
47pub use lists::*;
48pub use math::*;
49pub use myst::*;
50pub use raw_tex::*;
51pub use references::*;
52pub use shortcodes::*;
53pub use tables::*;
54pub use yaml::*;
55pub use yaml_ast::*;
56
57pub type SyntaxNode = rowan::SyntaxNode<PanacheLanguage>;
58pub type SyntaxToken = rowan::SyntaxToken<PanacheLanguage>;
59pub type SyntaxElement = rowan::SyntaxElement<PanacheLanguage>;
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn test_heading_wrapper() {
67 use crate::ParserOptions;
68 use crate::parser::parse;
69
70 let input = "# Hello World\n\nParagraph.";
71 let tree = parse(input, Some(ParserOptions::default()));
72
73 let heading = tree
74 .children()
75 .find_map(Heading::cast)
76 .expect("should find heading");
77
78 assert_eq!(heading.level(), 1);
79 assert_eq!(heading.text(), "Hello World");
80 }
81
82 #[test]
83 fn test_link_wrapper() {
84 use crate::ParserOptions;
85 use crate::parser::parse;
86
87 let input = "Click [here](https://example.com).";
88 let tree = parse(input, Some(ParserOptions::default()));
89
90 let link = tree
92 .descendants()
93 .find_map(Link::cast)
94 .expect("should find link");
95
96 assert_eq!(
97 link.text().map(|t| t.text_content()),
98 Some("here".to_string())
99 );
100 assert_eq!(
101 link.dest().map(|d| d.url_content()),
102 Some("https://example.com".to_string())
103 );
104 }
105
106 #[test]
107 fn test_image_wrapper() {
108 use crate::ParserOptions;
109 use crate::parser::parse;
110
111 let input = "";
112 let tree = parse(input, Some(ParserOptions::default()));
113
114 let image = tree
115 .descendants()
116 .find_map(ImageLink::cast)
117 .expect("should find image");
118
119 assert_eq!(image.alt().map(|a| a.text()), Some("Alt text".to_string()));
120 }
121
122 #[test]
123 fn test_autolink_wrapper() {
124 use crate::ParserOptions;
125 use crate::parser::parse;
126
127 let input = "<https://example.com>";
128 let tree = parse(input, Some(ParserOptions::default()));
129
130 let autolink = tree
131 .descendants()
132 .find_map(AutoLink::cast)
133 .expect("should find autolink");
134
135 assert_eq!(autolink.target(), "https://example.com");
136 }
137
138 #[test]
139 fn test_shortcode_wrapper() {
140 use crate::ParserOptions;
141 use crate::parser::parse;
142
143 let input = "{{< include \"chapters/part 1.qmd\" >}}";
144 let tree = parse(input, Some(ParserOptions::default()));
145
146 let shortcode = tree
147 .descendants()
148 .find_map(Shortcode::cast)
149 .expect("should find shortcode");
150
151 assert_eq!(shortcode.name().as_deref(), Some("include"));
152 assert_eq!(
153 shortcode.args(),
154 vec!["include".to_string(), "chapters/part 1.qmd".to_string()]
155 );
156 }
157
158 #[test]
159 fn test_table_wrapper() {
160 use crate::ParserOptions;
161 use crate::parser::parse;
162
163 let input = r#"| A | B |
164|---|---|
165| 1 | 2 |
166
167Table: My caption
168"#;
169 let tree = parse(input, Some(ParserOptions::default()));
170
171 let table = tree
172 .descendants()
173 .find_map(PipeTable::cast)
174 .expect("should find table");
175
176 assert_eq!(
177 table.caption().map(|c| c.text()),
178 Some("My caption".to_string())
179 );
180 assert!(table.rows().count() > 0);
181 }
182}