lex_babel/formats/lex/
mod.rs1use crate::error::FormatError;
8use crate::format::Format;
9use lex_core::lex::ast::Document;
10use lex_core::lex::transforms::standard::STRING_TO_AST;
11
12mod annotation_inline;
13mod blank_coalesce;
14pub mod formatting_rules;
15pub mod serializer;
16
17use annotation_inline::inline_attached_annotations;
18use blank_coalesce::coalesce_blank_line_groups;
19use formatting_rules::FormattingRules;
20use serializer::LexSerializer;
21#[derive(Default)]
25pub struct LexFormat {
26 rules: FormattingRules,
27}
28
29impl LexFormat {
30 pub fn new(rules: FormattingRules) -> Self {
31 Self { rules }
32 }
33}
34
35impl Format for LexFormat {
36 fn name(&self) -> &str {
37 "lex"
38 }
39
40 fn description(&self) -> &str {
41 "Lex document format"
42 }
43
44 fn file_extensions(&self) -> &[&str] {
45 &["lex"]
46 }
47
48 fn supports_parsing(&self) -> bool {
49 true
50 }
51
52 fn supports_serialization(&self) -> bool {
53 true
54 }
55
56 fn parse(&self, source: &str) -> Result<Document, FormatError> {
57 STRING_TO_AST
58 .run(source.to_string())
59 .map_err(|e| FormatError::ParseError(e.to_string()))
60 }
61
62 fn serialize(&self, doc: &Document) -> Result<String, FormatError> {
63 let mut doc = doc.clone();
68 inline_attached_annotations(&mut doc);
69 coalesce_blank_line_groups(&mut doc);
70 let serializer = LexSerializer::new(self.rules.clone());
71 serializer
72 .serialize(&doc)
73 .map_err(FormatError::SerializationError)
74 }
75}
76
77pub fn export(doc: &Document) -> Result<String, FormatError> {
80 LexFormat::default().serialize(doc)
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use lex_core::lex::ast::{ContentItem, Paragraph};
87
88 #[test]
89 fn test_lex_format_name() {
90 let format = LexFormat::default();
91 assert_eq!(format.name(), "lex");
92 }
93
94 #[test]
95 fn test_lex_format_supports_parsing() {
96 let format = LexFormat::default();
97 assert!(format.supports_parsing());
98 assert!(format.supports_serialization());
99 }
100
101 #[test]
102 fn test_lex_format_parse_simple() {
103 let format = LexFormat::default();
104 let source = "Hello world\n";
105
106 let result = format.parse(source);
107 assert!(result.is_ok());
108
109 let doc = result.unwrap();
110 assert_eq!(doc.root.children.len(), 1);
111
112 match &doc.root.children[0] {
113 ContentItem::Paragraph(_) => {}
114 _ => panic!("Expected paragraph"),
115 }
116 }
117
118 #[test]
119 fn test_lex_format_parse_session() {
120 let format = LexFormat::default();
121 let source = "Introduction:\n Welcome to the guide\n";
122
123 let result = format.parse(source);
124 assert!(result.is_ok());
125
126 let doc = result.unwrap();
127 assert!(!doc.root.children.is_empty());
130 }
131
132 #[test]
133 fn test_lex_format_parse_error() {
134 let format = LexFormat::default();
135 let source = "";
139
140 let result = format.parse(source);
141 assert!(result.is_ok());
143 }
144
145 #[test]
146 fn test_lex_format_serialize_supported() {
147 let format = LexFormat::default();
148 let doc = Document::with_content(vec![ContentItem::Paragraph(Paragraph::from_line(
149 "Test".to_string(),
150 ))]);
151
152 let result = format.serialize(&doc);
153 assert!(result.is_ok());
154 assert_eq!(result.unwrap(), "Test\n");
155 }
156}