diff --git a/src/library/mod.rs b/src/library/mod.rs index c5a5a796a..9c7cc7ceb 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -24,6 +24,11 @@ pub fn std() -> Scope { std.add::("line.break"); std.add::("par.break"); std.add::("page.break"); + + std.add_with_metadata::("word.spacing", ContentKind::Word); + std.add_with_metadata::("line.spacing", ContentKind::Line); + std.add_with_metadata::("par.spacing", ContentKind::Paragraph); + std.add::("page.size"); std.add::("page.margins"); @@ -69,11 +74,49 @@ function! { layout() { vec![BreakPage] } } +function! { + /// `word.spacing`, `line.spacing`, `par.spacing`: The spacing between + /// words, lines or paragraphs as a multiple of the font size. + #[derive(Debug, PartialEq)] + pub struct ContentSpacing { + spacing: f32, + content: ContentKind, + } + + type Meta = ContentKind; + + parse(args, body, _, meta) { + parse!(forbidden: body); + ContentSpacing { + spacing: args.get_pos::()? as f32, + content: meta + } + } + + layout(self, mut ctx) { + let mut style = ctx.style.text.clone(); + match self.content { + ContentKind::Word => style.word_spacing_scale = self.spacing, + ContentKind::Line => style.line_spacing_scale = self.spacing, + ContentKind::Paragraph => style.paragraph_spacing_scale = self.spacing, + } + vec![SetTextStyle(style)] + } +} + +/// The different kinds of content that can be spaced. +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum ContentKind { + Word, + Line, + Paragraph, +} + function! { /// `page.size`: Set the size of pages. #[derive(Debug, PartialEq)] pub enum PageSize { - Paper(Paper), + Paper(Paper, bool), Custom(ExtentMap), } @@ -81,7 +124,9 @@ function! { parse!(forbidden: body); if let Some(name) = args.get_pos_opt::()? { - PageSize::Paper(Paper::from_name(name.as_str())?) + let landscape = args.get_key_opt::("landscape")? + .unwrap_or(false); + PageSize::Paper(Paper::from_name(name.as_str())?, landscape) } else { PageSize::Custom(ExtentMap::new(&mut args, true)?) } @@ -91,9 +136,12 @@ function! { let mut style = ctx.style.page; match self { - PageSize::Paper(paper) => { + PageSize::Paper(paper, landscape) => { style.class = paper.class; style.dimensions = paper.dimensions; + if *landscape { + style.dimensions.swap(); + } } PageSize::Custom(map) => { diff --git a/src/size.rs b/src/size.rs index a3380f342..04eabf394 100644 --- a/src/size.rs +++ b/src/size.rs @@ -218,6 +218,11 @@ impl Value2D { // at the call site, we still have this second function. self.generalized(axes) } + + /// Swap the `x` and `y` values. + pub fn swap(&mut self) { + std::mem::swap(&mut self.x, &mut self.y); + } } impl Display for Value2D where T: Display {