use ecow::EcoString;
use typst_library::foundations::Target;
use typst_syntax::Spanned;
use crate::diag::{warning, At, SourceResult};
use crate::engine::Engine;
use crate::foundations::{
elem, Bytes, Cast, Content, Derived, Packed, Show, StyleChain, TargetElem,
};
use crate::introspection::Locatable;
use crate::World;
#[elem(Show, Locatable)]
pub struct EmbedElem {
#[required]
#[parse(
let Spanned { v: path, span } =
args.expect::<Spanned<EcoString>>("path")?;
let id = span.resolve_path(&path).at(span)?;
// The derived part is the project-relative resolved path.
let resolved = id.vpath().as_rootless_path().to_string_lossy().replace("\\", "/").into();
Derived::new(path.clone(), resolved)
)]
#[borrowed]
pub path: Derived<EcoString, EcoString>,
#[positional]
#[required]
#[parse(
match args.find::<Bytes>()? {
Some(data) => data,
None => engine.world.file(id).at(span)?,
}
)]
pub data: Bytes,
pub relationship: Option<EmbeddedFileRelationship>,
#[borrowed]
pub mime_type: Option<EcoString>,
#[borrowed]
pub description: Option<EcoString>,
}
impl Show for Packed<EmbedElem> {
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
if TargetElem::target_in(styles) == Target::Html {
engine
.sink
.warn(warning!(self.span(), "embed was ignored during HTML export"));
}
Ok(Content::empty())
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Cast)]
pub enum EmbeddedFileRelationship {
Source,
Data,
Alternative,
Supplement,
}