rustex_lib 0.1.11

A crate for converting TeX/pdfTeX to HTML
Documentation
use std::path::PathBuf;
use tex_engine::engine::filesystem::{File, FileSystem, NoOutputFileSystem, VirtualFile};
use tex_engine::engine::{EngineAux, EngineTypes};
use tex_engine::prelude::CSName;
use tex_engine::tex::characters::{StringLineSource, TextLine};
use tex_engine::utils::errors::TeXResult;
use tex_engine::utils::Ptr;

static PGFSYS: &str = include_str!("../resources/pgfsys.def");
static RUSTEX_DEFS: &str = include_str!("../resources/patches.tex");

#[derive(Clone)]
pub struct RusTeXFileSystem {
    pub(crate) inner: NoOutputFileSystem<u8>,
    pub(crate) svg: (<VirtualFile<u8> as File>::SourceRefID, Ptr<[TextLine<u8>]>),
    pub(crate) defs: (<VirtualFile<u8> as File>::SourceRefID, Ptr<[TextLine<u8>]>),
}
impl RusTeXFileSystem {
    pub fn new_with_envs<I: IntoIterator<Item = (String, String)>>(pwd: PathBuf, envs: I) -> Self {
        let mut ret = Self::new(pwd);
        ret.inner.envs.extend(envs);
        ret
    }

    pub fn add_file(&mut self, path: PathBuf, file_content: &str) {
        self.inner.add_file(path, file_content);
    }

    pub fn add_envs<I: IntoIterator<Item = (String, String)>>(&mut self, envs: I) {
        self.inner.envs.extend(envs);
    }
}

impl FileSystem for RusTeXFileSystem {
    type File = VirtualFile<u8>;

    fn new(pwd: PathBuf) -> Self {
        let mut inner = NoOutputFileSystem::new(pwd);
        let svg_id = inner
            .interner
            .get_or_intern("<TEXINPUTS>/pgfsys-rustex.def");
        let ext_id = inner.interner.get_or_intern("<TEXINPUTS>/rustex_defs.def");
        Self {
            inner,
            svg: (
                Some(svg_id),
                StringLineSource::make_lines(PGFSYS.as_bytes().iter().copied()).into(),
            ),
            defs: (
                Some(ext_id),
                StringLineSource::make_lines(RUSTEX_DEFS.as_bytes().iter().copied()).into(),
            ),
        }
    }
    fn ref_str(&self, id: <Self::File as File>::SourceRefID) -> &str {
        self.inner.ref_str(id)
    }

    fn get<S: AsRef<str>>(&mut self, path: S) -> Self::File {
        let sr = path.as_ref();
        if sr.ends_with("pgfsys-rustex.def") {
            VirtualFile {
                path: self.inner.kpse.pwd.join("pgfsys-rustex.def"),
                id: self.svg.0,
                pipe: false,
                exists: true,
                source: Some(self.svg.1.clone()),
            }
        } else if sr.ends_with("rustex_defs.def") {
            VirtualFile {
                path: self.inner.kpse.pwd.join("rustex_defs.def"),
                id: self.defs.0,
                pipe: false,
                exists: true,
                source: Some(self.defs.1.clone()),
            }
        } else {
            self.inner.get(sr)
        }
    }

    fn set_pwd(&mut self, pwd: PathBuf) -> PathBuf {
        self.inner.set_pwd(pwd)
    }

    fn open_out(&mut self, idx: u8, file: Self::File) {
        self.inner.open_out(idx, file)
    }

    fn open_in(&mut self, idx: u8, file: Self::File) {
        self.inner.open_in(idx, file)
    }

    fn close_in(&mut self, idx: u8) {
        self.inner.close_in(idx)
    }

    fn close_out(&mut self, idx: u8) {
        self.inner.close_out(idx)
    }

    fn eof(&self, idx: u8) -> bool {
        self.inner.eof(idx)
    }

    fn write<ET: EngineTypes, D: std::fmt::Display>(
        &mut self,
        idx: i64,
        string: D,
        newlinechar: Option<ET::Char>,
        aux: &mut EngineAux<ET>,
    ) {
        self.inner.write(idx, string, newlinechar, aux)
    }

    fn read<ET: EngineTypes<Char = <Self::File as File>::Char>, F: FnMut(ET::Token)>(
        &mut self,
        idx: u8,
        handler: &mut <ET::CSName as CSName<ET::Char>>::Handler,
        state: &ET::State,
        cont: F,
    ) -> TeXResult<(), ET> {
        self.inner.read::<ET, F>(idx, handler, state, cont)
    }

    fn readline<ET: EngineTypes<Char = <Self::File as File>::Char>, F: FnMut(ET::Token)>(
        &mut self,
        idx: u8,
        state: &ET::State,
        cont: F,
    ) -> TeXResult<(), ET> {
        self.inner.readline(idx, state, cont)
    }
}