ftml_viewer_components/
extractor.rs

1use flams_ontology::{narration::documents::DocumentStyles, uris::NarrativeURI, Unchecked};
2use flams_utils::{id_counters::IdCounter, vecmap::VecSet};
3use ftml_extraction::prelude::{Attributes, FTMLExtractor, GnoteState};
4use leptos::{prelude::expect_context, web_sys::Element};
5use smallvec::SmallVec;
6use std::borrow::Cow;
7
8#[derive(Default)]
9pub struct DOMExtractor {
10    in_notation: bool,
11    in_term: bool,
12    pub(crate) styles: DocumentStyles,
13    id_counter: IdCounter,
14}
15
16impl FTMLExtractor for DOMExtractor {
17    type Attr<'a> = NodeAttrs<'a>;
18
19    #[inline(always)]
20    fn add_error(&mut self, err: ftml_extraction::errors::FTMLError) {
21        tracing::error!("{err}");
22    }
23
24    fn styles(&mut self) -> &mut DocumentStyles {
25        &mut self.styles
26    }
27
28    #[inline]
29    fn new_id(&mut self, prefix: Cow<'static, str>) -> Box<str> {
30        self.id_counter.new_id(prefix)
31    }
32
33    #[inline]
34    fn in_term(&self) -> bool {
35        self.in_term
36    }
37
38    #[inline]
39    fn set_in_term(&mut self, value: bool) {
40        self.in_term = value
41    }
42
43    #[inline]
44    fn in_notation(&self) -> bool {
45        self.in_notation
46    }
47
48    #[cfg(feature = "rdf")]
49    const RDF: bool = false;
50
51    #[cfg(feature = "rdf")]
52    fn add_triples<const N: usize>(&mut self, _triples: [flams_ontology::rdf::Triple; N]) {}
53
54    #[cfg(feature = "rdf")]
55    fn get_content_iri(&self) -> Option<flams_ontology::rdf::NamedNode> {
56        todo!()
57    }
58    #[cfg(feature = "rdf")]
59    fn get_document_iri(&self) -> flams_ontology::rdf::NamedNode {
60        todo!()
61    }
62
63    fn add_objective(
64        &mut self,
65        _uri: flams_ontology::uris::SymbolURI,
66        _dim: flams_ontology::narration::problems::CognitiveDimension,
67    ) {
68        todo!()
69    }
70    fn add_precondition(
71        &mut self,
72        _uri: flams_ontology::uris::SymbolURI,
73        _dim: flams_ontology::narration::problems::CognitiveDimension,
74    ) {
75        todo!()
76    }
77
78    fn resolve_variable_name(
79        &self,
80        _name: flams_ontology::uris::Name,
81    ) -> flams_ontology::content::terms::Var {
82        todo!()
83    }
84
85    fn add_arg(
86        &mut self,
87        _pos: (u8, Option<u8>),
88        _tm: flams_ontology::content::terms::Term,
89        _mode: flams_ontology::content::terms::ArgMode,
90    ) -> Result<(), ()> {
91        todo!()
92    }
93    fn add_content_element(
94        &mut self,
95        _elem: flams_ontology::content::declarations::OpenDeclaration<Unchecked>,
96    ) -> Result<(), flams_ontology::content::declarations::OpenDeclaration<Unchecked>> {
97        todo!()
98    }
99    fn add_document_element(
100        &mut self,
101        _elem: flams_ontology::narration::DocumentElement<Unchecked>,
102    ) {
103        todo!()
104    }
105    fn add_module(&mut self, _module: flams_ontology::content::modules::OpenModule<Unchecked>) {
106        todo!()
107    }
108    fn add_notation(
109        &mut self,
110        _spec: ftml_extraction::prelude::NotationSpec,
111    ) -> Result<(), ftml_extraction::prelude::NotationSpec> {
112        todo!()
113    }
114    fn add_op_notation(
115        &mut self,
116        _op: flams_ontology::narration::notations::OpNotation,
117    ) -> Result<(), flams_ontology::narration::notations::OpNotation> {
118        todo!()
119    }
120    fn add_resource<T: flams_ontology::Resourcable>(
121        &mut self,
122        _t: &T,
123    ) -> flams_ontology::narration::LazyDocRef<T> {
124        todo!()
125    }
126    fn add_term(
127        &mut self,
128        _symbol: Option<flams_ontology::uris::SymbolURI>,
129        _tm: flams_ontology::content::terms::Term,
130    ) -> Result<(), flams_ontology::content::terms::Term> {
131        todo!()
132    }
133    fn add_title(
134        &mut self,
135        _title: flams_ontology::DocumentRange,
136    ) -> Result<(), flams_ontology::DocumentRange> {
137        todo!()
138    }
139    fn add_type(
140        &mut self,
141        _tm: flams_ontology::content::terms::Term,
142    ) -> Result<(), flams_ontology::content::terms::Term> {
143        todo!()
144    }
145    fn close_args(
146        &mut self,
147    ) -> (
148        Vec<flams_ontology::content::terms::Arg>,
149        Option<flams_ontology::content::terms::Term>,
150    ) {
151        todo!()
152    }
153    fn close_complex_term(&mut self) -> Option<flams_ontology::content::terms::Term> {
154        todo!()
155    }
156    fn close_content(
157        &mut self,
158    ) -> Option<(
159        flams_ontology::uris::ModuleURI,
160        Vec<flams_ontology::content::declarations::OpenDeclaration<Unchecked>>,
161    )> {
162        todo!()
163    }
164    fn close_decl(
165        &mut self,
166    ) -> Option<(
167        Option<flams_ontology::content::terms::Term>,
168        Option<flams_ontology::content::terms::Term>,
169    )> {
170        todo!()
171    }
172    fn close_problem(&mut self) -> Option<ftml_extraction::prelude::ProblemState> {
173        todo!()
174    }
175    fn close_narrative(
176        &mut self,
177    ) -> Option<(
178        flams_ontology::uris::NarrativeURI,
179        Vec<flams_ontology::narration::DocumentElement<Unchecked>>,
180    )> {
181        todo!()
182    }
183    fn close_notation(&mut self) -> Option<ftml_extraction::prelude::NotationState> {
184        todo!()
185    }
186    fn close_paragraph(&mut self) -> Option<ftml_extraction::prelude::ParagraphState> {
187        todo!()
188    }
189    fn close_section(
190        &mut self,
191    ) -> Option<(
192        flams_ontology::uris::DocumentElementURI,
193        Option<flams_ontology::DocumentRange>,
194        Vec<flams_ontology::narration::DocumentElement<Unchecked>>,
195    )> {
196        todo!()
197    }
198    fn get_content_uri(&self) -> Option<&flams_ontology::uris::ModuleURI> {
199        todo!()
200    }
201    fn get_narrative_uri(&self) -> flams_ontology::uris::NarrativeURI {
202        expect_context::<NarrativeURI>()
203    }
204    fn with_problem<R>(
205        &mut self,
206        _then: impl FnOnce(&mut ftml_extraction::prelude::ProblemState) -> R,
207    ) -> Option<R> {
208        todo!()
209    }
210    fn close_gnote(&mut self) -> Option<GnoteState> {
211        todo!()
212    }
213    fn close_choice_block(&mut self) -> Option<ftml_extraction::prelude::ChoiceBlockState> {
214        todo!()
215    }
216    fn close_fillinsol(&mut self) -> Option<ftml_extraction::prelude::FillinsolState> {
217        todo!()
218    }
219    fn close_slide(
220        &mut self,
221    ) -> Option<Vec<flams_ontology::narration::DocumentElement<Unchecked>>> {
222        todo!()
223    }
224
225    fn add_definiendum(&mut self, _uri: flams_ontology::uris::SymbolURI) {}
226    fn push_fillinsol_case(&mut self, _case: flams_ontology::narration::problems::FillInSolOption) {
227    }
228    fn open_fillinsol(&mut self, _width: Option<f32>) {}
229    fn push_answer_class(
230        &mut self,
231        _id: Box<str>,
232        _kind: flams_ontology::narration::problems::AnswerKind,
233    ) {
234    }
235    fn push_problem_choice(&mut self, _correct: bool) {}
236    fn open_gnote(&mut self) {}
237    fn open_choice_block(&mut self, _multiple: bool, _styles: Box<[Box<str>]>) {}
238    fn open_args(&mut self) {}
239    fn open_complex_term(&mut self) {}
240    fn open_content(&mut self, _uri: flams_ontology::uris::ModuleURI) {}
241    fn open_decl(&mut self) {}
242    fn open_problem(&mut self, _uri: flams_ontology::uris::DocumentElementURI) {}
243    fn open_narrative(&mut self, _uri: Option<flams_ontology::uris::NarrativeURI>) {}
244    fn open_notation(&mut self) {}
245    fn open_slide(&mut self) {}
246    fn open_paragraph(
247        &mut self,
248        _uri: flams_ontology::uris::DocumentElementURI,
249        _fors: VecSet<flams_ontology::uris::SymbolURI>,
250    ) {
251    }
252    fn open_section(&mut self, _uri: flams_ontology::uris::DocumentElementURI) {}
253    fn set_document_title(&mut self, _title: Box<str>) {}
254}
255
256pub struct NodeAttrs<'n> {
257    elem: Cow<'n, Element>,
258    keys: SmallVec<String, 4>,
259}
260impl<'n> NodeAttrs<'n> {
261    pub(crate) fn new(elem: &'n Element) -> Self {
262        Self {
263            elem: Cow::Borrowed(elem),
264            keys: Self::attr_names(elem),
265        }
266    }
267
268    fn attr_names(e: &Element) -> SmallVec<String, 4> {
269        let mut ret = SmallVec::new();
270        for k in e.get_attribute_names() {
271            if let Some(s) = k.as_string() {
272                ret.push(s)
273            }
274        }
275        ret
276    }
277}
278impl Attributes for NodeAttrs<'_> {
279    type KeyIter<'a>
280        = std::iter::Map<std::slice::Iter<'a, String>, for<'b> fn(&'b String) -> &'b str>
281    where
282        Self: 'a;
283    type Value<'a>
284        = String
285    where
286        Self: 'a;
287    fn keys(&self) -> Self::KeyIter<'_> {
288        self.keys.iter().map(AsRef::as_ref)
289    }
290    fn value(&self, key: &str) -> Option<Self::Value<'_>> {
291        self.elem.get_attribute(key)
292    }
293    fn set(&mut self, key: &str, value: &str) {
294        let _ = self.elem.set_attribute(key, value);
295    }
296    fn take(&mut self, key: &str) -> Option<String> {
297        let r = self.elem.get_attribute(key);
298        let _ = self.elem.remove_attribute(key);
299        r
300    }
301}