Use generated Typst code from Rust

finchie
Oct 26, 2023, 9:45 AM
ZYNEMGAZXWHIWGNPB2RTYG3JWTH5Y5XY4JWJ3TTPANIOORTCLISAC

Dependencies

  • [2] HEUMSBES Ouput use statements in generated file
  • [3] C73UJ7ZY Create simple `xilem_html` demo
  • [4] A4E5KLI2 Turn arguments into sidebar
  • [5] REI53XR4 Render argument state as HTML
  • [6] JFJVY57R List `clap` argument IDs
  • [7] BSJYWOYS Implement MVP Typst embedding
  • [8] BA5Y6VSE Output Rust code using `syn`
  • [*] BMG4FSHN Add basic `clap` support
  • [*] 2N3KOCP7 Create MVP Pandoc->Rust compiler

Change contents

  • edit in src/main.rs at line 7
    [10.141]
    [3.189]
    include!(concat!(env!("OUT_DIR"), "/docs.rs"));
  • edit in src/main.rs at line 81
    [3.1766][3.0:129]()
    }
    fn content(state: &AppState) -> impl View<AppState> + ViewMarker {
    el::div(include_str!("../dist/.stage/docs/test.html"))
  • replacement in src/main.rs at line 93
    [3.114][3.130:190]()
    el::div(content(&state)).attr("id", "content"),
    [3.114]
    [3.161]
    el::div(test()).attr("id", "content"),
  • edit in crates/typst_rust_gen/src/lib.rs at line 114
    [2.1366][2.1366:1693]()
    syn::UseTree::Name(syn::UseName {
    ident: syn::Ident::new(
    "ViewMarker",
    proc_macro2::Span::call_site(),
    ),
    }),
  • replacement in crates/typst_rust_gen/src/lib.rs at line 131
    [2.2379][2.2379:2435]()
    generics: syn::Generics::default(),
    [2.2379]
    [2.2435]
    generics: syn::Generics { lt_token: None, params: Punctuated::from_iter(vec![syn::GenericParam::Type(syn::TypeParam { attrs: Vec::new(), ident: syn::Ident::new("T", proc_macro2::Span::call_site()), colon_token: None, bounds: Punctuated::new(), eq_token: None, default: None })].into_iter()), gt_token: None, where_clause: None },
  • replacement in crates/typst_rust_gen/src/lib.rs at line 135
    [2.2581][2.2581:2635]()
    output: syn::ReturnType::Default,
    [2.2581]
    [2.2635]
    output: syn::ReturnType::Type(
    syn::token::RArrow::default(),
    Box::new(syn::Type::ImplTrait(syn::TypeImplTrait {
    impl_token: syn::token::Impl::default(),
    bounds: Punctuated::from_iter(
    vec![syn::TypeParamBound::Trait(syn::TraitBound {
    paren_token: None,
    modifier: syn::TraitBoundModifier::None,
    lifetimes: None,
    path: syn::Path {
    leading_colon: None,
    segments: Punctuated::from_iter(
    vec![syn::PathSegment {
    ident: syn::Ident::new(
    "ViewSequence",
    proc_macro2::Span::call_site(),
    ),
    arguments: syn::PathArguments::AngleBracketed(
    syn::AngleBracketedGenericArguments {
    colon2_token: None,
    lt_token: syn::token::Lt::default(),
    args: Punctuated::from_iter(
    vec![syn::GenericArgument::Type(
    syn::Type::Path(syn::TypePath {
    qself: None,
    path: syn::Path {
    leading_colon: None,
    segments: Punctuated::from_iter(vec![syn::PathSegment { ident: syn::Ident::new("T", proc_macro2::Span::call_site()), arguments: syn::PathArguments::None }].into_iter()),
    },
    }),
    )]
    .into_iter(),
    ),
    gt_token: syn::token::Gt::default(),
    },
    ),
    }]
    .into_iter(),
    ),
    },
    })]
    .into_iter(),
    ),
    })),
    ),
  • replacement in build.rs at line 1
    [3.302][3.303:359]()
    use std::{ffi::OsStr, path::PathBuf, process::Command};
    [3.302]
    [3.359]
    use std::{ffi::OsStr, path::PathBuf};
  • edit in build.rs at line 3
    [3.360]
    [3.360]
    use typst_rust_gen::transform_pandoc;
  • edit in build.rs at line 6
    [3.383][3.383:436]()
    const TRUNK_STAGING_DIRECTORY: &str = "dist/.stage";
  • edit in build.rs at line 10
    [3.526]
    [3.526]
    println!("cargo:rerun-if-changed=docs");
    println!("cargo:rerun-if-changed=crates/typst_rust_gen");
  • replacement in build.rs at line 24
    [3.988][3.988:1051]()
    std::fs::create_dir_all(TRUNK_STAGING_DIRECTORY).unwrap();
    [3.988]
    [3.1051]
    let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
    std::fs::create_dir_all(&out_dir).unwrap();
  • edit in build.rs at line 29
    [3.1124][3.1124:1204]()
    let staging_dir = PathBuf::from(TRUNK_STAGING_DIRECTORY).join(DOCS_SOURCE);
  • replacement in build.rs at line 33
    [3.1288][3.1288:1550]()
    // Handle nested directories correctly
    let remainder = if parent != prefix {
    assert!(parent.starts_with(&prefix));
    parent.strip_prefix(&prefix).unwrap().to_path_buf()
    } else {
    PathBuf::new()
    };
    [3.1288]
    [3.1550]
    // TODO: Handle nested directories correctly
    // let remainder = if parent != prefix {
    // assert!(parent.starts_with(&prefix));
    // parent.strip_prefix(&prefix).unwrap().to_path_buf()
    // } else {
    // PathBuf::new()
    // };
  • replacement in build.rs at line 41
    [3.1551][3.1551:1819]()
    // Create the appropriate directory layout
    let mut output_path = staging_dir
    .join(remainder)
    .join(file.path().file_name().unwrap());
    // Our input is .typ, but output is .html
    output_path.set_extension("html");
    [3.1551]
    [3.1819]
    // Store everything inside one large autogenerated Rust file
    let output_path = out_dir.join("docs.rs");
  • replacement in build.rs at line 45
    [3.1893][3.1893:2167]()
    Command::new("pandoc")
    .args([
    file.path().to_str().unwrap(),
    "-o",
    output_path.to_str().unwrap(),
    ])
    .status()
    .expect("Error running pandoc. Check if it's installed");
    [3.1893]
    [3.2167]
    // TODO: this will only work for a single file, in the top-level directory
    let rust_code = transform_pandoc(file.path());
    std::fs::write(&output_path, rust_code).unwrap();