use crate::foundations::{Content, NativeElement, SymbolElem, elem, func};
use crate::layout::{Length, Rel};
use crate::math::Mathy;
#[elem(title = "Left/Right", Mathy)]
pub struct LrElem {
#[default(Rel::one())]
pub size: Rel<Length>,
#[required]
#[parse(
let mut arguments = args.all::<Content>()?.into_iter();
let mut body = arguments.next().unwrap_or_default();
arguments.for_each(|arg| body += SymbolElem::packed(',') + arg);
body
)]
pub body: Content,
}
#[elem(Mathy)]
pub struct MidElem {
#[required]
pub body: Content,
}
#[func]
pub fn floor(
#[named]
size: Option<Rel<Length>>,
body: Content,
) -> Content {
delimited(body, '⌊', '⌋', size)
}
#[func]
pub fn ceil(
#[named]
size: Option<Rel<Length>>,
body: Content,
) -> Content {
delimited(body, '⌈', '⌉', size)
}
#[func]
pub fn round(
#[named]
size: Option<Rel<Length>>,
body: Content,
) -> Content {
delimited(body, '⌊', '⌉', size)
}
#[func]
pub fn abs(
#[named]
size: Option<Rel<Length>>,
body: Content,
) -> Content {
delimited(body, '|', '|', size)
}
#[func]
pub fn norm(
#[named]
size: Option<Rel<Length>>,
body: Content,
) -> Content {
delimited(body, '‖', '‖', size)
}
fn delimited(
body: Content,
left: char,
right: char,
size: Option<Rel<Length>>,
) -> Content {
let span = body.span();
let mut elem = LrElem::new(Content::sequence([
SymbolElem::packed(left),
body,
SymbolElem::packed(right),
]));
if let Some(size) = size {
elem.size.set(size);
}
elem.pack().spanned(span)
}