1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3
4mod parser;
5
6use either::Either;
7use flams_ontology::uris::{ArchiveURITrait, DocumentURI};
8use flams_system::{backend::{AnyBackend, Backend}, build_result, build_target, building::{BuildArtifact, BuildResult, BuildResultArtifact, BuildTask}, formats::{BuildArtifactTypeId, OMDocResult, CHECK, UNCHECKED_OMDOC}, source_format};
9
10source_format!(ftml ["html","xhtml","htm"] [FTML_IMPORT => FTML_OMDOC => CHECK] @
11 "Flexiformally annotated HTML"
12 = |_,_| todo!()
13);
14
15build_target!(
16 ftml_import [] => [FTML_DOC]
17 @ "Import existing FTML"
18 = |_,_| todo!()
19);
20
21build_target!(
22 ftml_omdoc [FTML_DOC] => [UNCHECKED_OMDOC]
23 @ "Extract OMDoc from FTML"
24 = extract
25);
26
27build_result!(ftml_doc @ "Semantically annotated HTML");
28
29fn extract(backend:&AnyBackend,task:&BuildTask) -> BuildResult {
30 let html:Result<HTMLString,_> = backend.with_archive(task.archive().archive_id(), |a| {
31 let Some(a) = a else {return Err(BuildResult::err())};
32 a.load(task.rel_path()).map_err(|e| BuildResult {
33 log:Either::Left(format!("Error loading html data for {}/{}: {e}",task.archive().archive_id(),task.rel_path())),
34 result:Err(Vec::new())
35 })
36 });
37 let html = match html {
38 Err(e) => return e,
39 Ok(h) => h
40 };
41 let uri = match task.document_uri() {
42 Ok(uri) => uri,
43 Err(e) => return BuildResult::with_err(format!("{e:#}"))
44 };
45 match build_ftml(backend,&html.0,uri,task.rel_path()) {
46 Err(e) => BuildResult {
47 log:Either::Left(e),
48 result:Err(Vec::new())
49 },
50 Ok((r,s)) => BuildResult {
51 log:Either::Left(s),
52 result:Ok(BuildResultArtifact::Data(Box::new(r)))
53 }
54 }
55}
56
57#[inline]
59pub fn build_ftml(backend:&AnyBackend,html:&str,uri:DocumentURI,rel_path:&str) -> Result<(OMDocResult,String),String> {
60 parser::HTMLParser::run(html,uri,rel_path,backend)
61}
62
63
64pub struct HTMLString(pub String);
65impl BuildArtifact for HTMLString {
66 #[inline] fn get_type_id() -> BuildArtifactTypeId where Self:Sized {
67 FTML_DOC
68 }
69 #[inline]
70 fn get_type(&self) -> BuildArtifactTypeId {
71 FTML_DOC
72 }
73 fn write(&self,path:&std::path::Path) -> Result<(),std::io::Error> {
74 std::fs::write(path, &self.0)
75 }
76 fn load(p:&std::path::Path) -> Result<Self,std::io::Error> where Self:Sized {
77 let s = std::fs::read_to_string(p)?;
78 Ok(Self(s))
79 }
80
81 #[inline]
82 fn as_any(&self) -> &dyn std::any::Any {self}
83}
84impl HTMLString {
85 #[must_use]
86 pub fn create(s:String) -> BuildResultArtifact {
87 BuildResultArtifact::Data(Box::new(Self(s)))
88 }
89}