summaryrefslogtreecommitdiff
path: root/src/library/page.rs
blob: 40872d6301df489c22b4b9f8ddbf16ac730e6fe4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use crate::func::prelude::*;

/// `page.break`: Ends the current page.
#[derive(Debug, PartialEq)]
pub struct PageBreak;

function! {
    data: PageBreak,
    parse: plain,
    layout(_, _) { Ok(commands![FinishSpace]) }
}

/// `page.size`: Set the size of pages.
#[derive(Debug, PartialEq)]
pub struct PageSize {
    width: Option<Size>,
    height: Option<Size>,
}

function! {
    data: PageSize,

    parse(args, body, _ctx) {
        parse!(forbidden: body);
        Ok(PageSize {
            width: args.get_key_opt::<ArgSize>("width")?.map(|a| a.val),
            height: args.get_key_opt::<ArgSize>("height")?.map(|a| a.val),
        })
    }

    layout(this, ctx) {
        let mut style = ctx.page_style;

        if let Some(width) = this.width { style.dimensions.x = width; }
        if let Some(height) = this.height { style.dimensions.y = height; }

        Ok(commands![SetPageStyle(style)])
    }
}

/// `page.margins`: Set the margins of pages.
#[derive(Debug, PartialEq)]
pub struct PageMargins {
    left: Option<Size>,
    top: Option<Size>,
    right: Option<Size>,
    bottom: Option<Size>,
}

function! {
    data: PageMargins,

    parse(args, body, _ctx) {
        parse!(forbidden: body);
        let default = args.get_pos_opt::<ArgSize>()?;
        let mut get = |which| {
            args.get_key_opt::<ArgSize>(which)
                .map(|size| size.or(default).map(|a| a.val))
        };

        Ok(PageMargins {
            left: get("left")?,
            top: get("top")?,
            right: get("right")?,
            bottom: get("bottom")?,
        })
    }

    layout(this, ctx) {
        let mut style = ctx.page_style;

        if let Some(left) = this.left { style.margins.left = left; }
        if let Some(top) = this.top { style.margins.top = top; }
        if let Some(right) = this.right { style.margins.right = right; }
        if let Some(bottom) = this.bottom { style.margins.bottom = bottom; }

        Ok(commands![SetPageStyle(style)])
    }
}