flams_ftml/
lib.rs

1//#![feature(string_from_utf8_lossy_owned)]
2#![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/// #### Errors
58#[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}