Skip to main content

flams/
check.rs

1use std::path::PathBuf;
2
3use flams_ftml::{FTML_CONTENT, FtmlResult};
4use flams_math_archives::{
5    MathArchive,
6    artifacts::{ContentResult, ContentUpdate, FileOrString, FtmlString},
7    backend::{AnyBackend, GlobalBackend, LocalBackend},
8    utils::{AllSyncEngine, path_ext::PathExt},
9};
10use flams_stex::RusTeX;
11use ftml_solver::CHECK;
12use ftml_uris::{ArchiveId, DocumentUri};
13
14pub fn check(archive: ArchiveId, path: PathBuf, persist: bool, truncate: bool) {
15    let _ = enable_ansi_support::enable_ansi_support();
16    tracing_subscriber::fmt()
17        .with_max_level(tracing::Level::INFO)
18        .init();
19    GlobalBackend::initialize::<AllSyncEngine>(false);
20    let (uri, full_path) = GlobalBackend
21        .get()
22        .with_local_archive(&archive, |a| {
23            a.map(|a| (a.uri().clone(), a.source_dir().join(&path)))
24        })
25        .expect("File not found in archive");
26    let uri =
27        DocumentUri::from_archive_relpath(uri, &path.as_slash_str()).expect("Invalid file path");
28    let text = std::fs::read_to_string(&full_path).expect("error reading tex file");
29    let mh = flams_math_archives::mathhub::mathhubs()
30        .iter()
31        .copied()
32        .map(|p| p.display().to_string())
33        .collect::<Vec<_>>()
34        .join(",");
35
36    tracing::info!("Initializing RusTeX...");
37    RusTeX::initialize();
38
39    tracing::info!("Running RusTeX...");
40    let rustex = RusTeX::get()
41        .expect("Failed to initialize RusTeX")
42        .builder()
43        .set_envs([
44            ("STEX_USESMS".to_string(), "true".to_string()),
45            ("MATHHUB".to_string(), mh),
46        ])
47        .set_sourcerefs(true)
48        .set_font_debug_info(true)
49        .set_string(&full_path, &text)
50        .expect("Failed to initialize RusTeX"); //.set_output(TracingOutput);
51
52    let (res, _) = rustex.run();
53    if let Some(e) = &res.error {
54        panic!("{e:?}");
55    }
56    tracing::info!("RusTeX: success");
57    let html = res.to_string();
58    if persist
59        && let Err(e) = GlobalBackend.get().save(
60            &uri,
61            None,
62            FileOrString::Str("".into()),
63            flams_stex::RUSTEX.id(),
64            Some(Box::new(FtmlString(html.clone().into_boxed_str()))),
65        )
66    {
67        panic!("Error persisting: {e}")
68    }
69    let r: FtmlResult = match flams_system::logging::ignore_traces(|| {
70        flams_ftml::build_ftml(&AnyBackend::Global, &html, uri.clone())
71    }) {
72        Ok(r) => r,
73        Err(e) => panic!("Error: {e}"),
74    };
75    if !r.errors.is_empty() {
76        for e in r.errors {
77            tracing::error!("Error {e}");
78        }
79        panic!("FTML extraction failed");
80    }
81    tracing::info!("Extracting FTML: success");
82    let doc = r.doc.document.clone();
83    let modules = r.doc.modules.clone();
84    if persist
85        && let Err(e) = GlobalBackend.get().save(
86            &uri,
87            None,
88            FileOrString::Str("".into()),
89            FTML_CONTENT.id(),
90            Some(Box::new(ContentResult {
91                document: r.doc.document,
92                modules: r.doc.modules,
93                data: r.doc.data,
94                body: r.body,
95                inner_offset: r.inner_offset,
96                css: r.css,
97                ftml: r.ftml,
98                triples: r.doc.triples,
99            })),
100        )
101    {
102        panic!("Error persisting: {e}")
103    }
104    let mut checker =
105        ftml_solver::Checker::<ftml_solver::split::SingleThreadedSplit>::new(AnyBackend::Global);
106
107    let _ = checker.add_modules(modules);
108    let (mut drs, modules) = match checker.check_document(&doc) {
109        Ok((drs, modules)) => (drs, modules),
110        Err(e) => {
111            panic!("Error checking: Missing module: {e}");
112        }
113    };
114    if persist
115        && let Err(e) = GlobalBackend.get().save(
116            &uri,
117            None,
118            FileOrString::Str("".into()),
119            CHECK.id(),
120            Some(Box::new(ContentUpdate {
121                document: Some(doc),
122                modules,
123            })),
124        )
125    {
126        panic!("Error persisting: {e}")
127    }
128    if truncate {
129        drs.filter_failures(false);
130    }
131    println!("{}", drs.colored());
132}