1use std::fs::File;
2
3use anyhow::{anyhow, Context as _};
4
5use once_cell::sync::Lazy;
6mod config;
7pub use config::Config;
8
9#[derive(Default)]
10pub struct Renderer {
11 logfile: Option<File>,
12}
13
14impl Renderer {
15 pub fn new() -> Self {
16 Self { logfile: None }
17 }
18
19 const NAME: &'static str = "typstpdf";
20 const CONFIG_KEY: &'static str = "output.typstpdf";
21}
22
23impl mdbook::Renderer for Renderer {
24 fn name(&self) -> &str {
25 Self::NAME
26 }
27
28 fn render(&self, ctx: &mdbook::renderer::RenderContext) -> anyhow::Result<()> {
29 if self.logfile.is_none() {
30 log::info!("no logfile");
31 }
32 static MDBOOK_VERSION_REQ: Lazy<semver::VersionReq> = Lazy::new(|| {
35 let compiled_mdbook_version = semver::Version::parse(mdbook::MDBOOK_VERSION).unwrap();
36 semver::VersionReq {
37 comparators: vec![semver::Comparator {
38 op: semver::Op::Caret,
39 major: compiled_mdbook_version.major,
40 minor: Some(compiled_mdbook_version.minor),
41 patch: None,
42 pre: Default::default(),
43 }],
44 }
45 });
46 let mdbook_server_version = semver::Version::parse(&ctx.version).unwrap();
47 if !MDBOOK_VERSION_REQ.matches(&mdbook_server_version) {
48 log::warn!(
49 "{} is semver-incompatible with mdbook {} (requires {})",
50 env!("CARGO_PKG_NAME"),
51 mdbook_server_version,
52 *MDBOOK_VERSION_REQ,
53 );
54 }
55
56 let cfg: Config = ctx
57 .config
58 .get_deserialized_opt(Self::CONFIG_KEY)
59 .with_context(|| format!("Unable to deserialize {}", Self::CONFIG_KEY))?
60 .ok_or(anyhow!("No {} table found", Self::CONFIG_KEY))?;
61
62 log::info!("cfg: {:?}", cfg);
63
64 cfg.renderer(ctx)
78 }
79}