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
|
use crate::func::prelude::*;
/// `line.break`, `n`: Ends the current line.
#[derive(Debug, PartialEq)]
pub struct LineBreak;
function! {
data: LineBreak,
parse: plain,
layout(_, _) { Ok(commands![FinishLine]) }
}
/// `paragraph.break`: Ends the current paragraph.
///
/// This has the same effect as two subsequent newlines.
#[derive(Debug, PartialEq)]
pub struct ParagraphBreak;
function! {
data: ParagraphBreak,
parse: plain,
layout(_, _) { Ok(commands![BreakParagraph]) }
}
macro_rules! space_func {
($ident:ident, $doc:expr, $var:ident => $command:expr) => (
#[doc = $doc]
#[derive(Debug, PartialEq)]
pub struct $ident(Spacing);
function! {
data: $ident,
parse(args, body, _ctx) {
parse!(forbidden: body);
let arg = args.get_pos::<ArgExpr>()?;
let spacing = match arg.val {
Expression::Size(s) => Spacing::Absolute(*s),
Expression::Num(f) => Spacing::Relative(*f as f32),
_ => err!("invalid spacing, expected size or number"),
};
Ok($ident(spacing))
}
layout(this, ctx) {
let $var = match this.0 {
Spacing::Absolute(s) => s,
Spacing::Relative(f) => f * ctx.text_style.font_size,
};
Ok(commands![$command])
}
}
);
}
/// Absolute or font-relative spacing.
#[derive(Debug, PartialEq)]
enum Spacing {
Absolute(Size),
Relative(f32),
}
// FIXME: h != primary and v != secondary.
space_func!(HorizontalSpace, "📖 `h`: Adds horizontal whitespace.",
space => AddPrimarySpace(space));
space_func!(VerticalSpace, "📑 `v`: Adds vertical whitespace.",
space => AddSecondarySpace(space));
|