diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-05-26 11:59:53 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-05-26 11:59:53 +0200 |
| commit | 66d8f4569a9f13270c5f477e0730f127a22333e2 (patch) | |
| tree | ebb60254e69d7f65ec2245aeae3543f6efff0cbb /src/library | |
| parent | 99cb655832161d4ebec73273a15453a8f6acc1b7 (diff) | |
Locate me!
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/mod.rs | 1 | ||||
| -rw-r--r-- | src/library/text/par.rs | 43 | ||||
| -rw-r--r-- | src/library/utility/locate.rs | 8 | ||||
| -rw-r--r-- | src/library/utility/mod.rs | 2 |
4 files changed, 42 insertions, 12 deletions
diff --git a/src/library/mod.rs b/src/library/mod.rs index ac0cbb92..3321a36b 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -92,6 +92,7 @@ pub fn new() -> Scope { std.def_fn("roman", utility::roman); std.def_fn("symbol", utility::symbol); std.def_fn("lorem", utility::lorem); + std.def_fn("locate", utility::locate); // Predefined colors. std.def_const("black", Color::BLACK); diff --git a/src/library/text/par.rs b/src/library/text/par.rs index 1269ffed..65098b61 100644 --- a/src/library/text/par.rs +++ b/src/library/text/par.rs @@ -26,6 +26,8 @@ pub enum ParChild { Spacing(Spacing), /// An arbitrary inline-level node. Node(LayoutNode), + /// A pin identified by index. + Pin(usize), } #[node] @@ -100,6 +102,7 @@ impl Debug for ParChild { Self::Quote { double } => write!(f, "Quote({double})"), Self::Spacing(kind) => write!(f, "{:?}", kind), Self::Node(node) => node.fmt(f), + Self::Pin(idx) => write!(f, "Pin({idx})"), } } } @@ -275,6 +278,8 @@ enum Segment<'a> { Spacing(Spacing), /// An arbitrary inline-level layout node. Node(&'a LayoutNode), + /// A pin identified by index. + Pin(usize), } impl Segment<'_> { @@ -282,7 +287,7 @@ impl Segment<'_> { fn len(&self) -> usize { match *self { Self::Text(len) => len, - Self::Spacing(_) => SPACING_REPLACE.len_utf8(), + Self::Spacing(_) | Self::Pin(_) => SPACING_REPLACE.len_utf8(), Self::Node(_) => NODE_REPLACE.len_utf8(), } } @@ -301,6 +306,8 @@ enum Item<'a> { Frame(Arc<Frame>), /// A repeating node. Repeat(&'a RepeatNode, StyleChain<'a>), + /// A pin identified by index. + Pin(usize), } impl<'a> Item<'a> { @@ -316,7 +323,9 @@ impl<'a> Item<'a> { fn len(&self) -> usize { match self { Self::Text(shaped) => shaped.text.len(), - Self::Absolute(_) | Self::Fractional(_) => SPACING_REPLACE.len_utf8(), + Self::Absolute(_) | Self::Fractional(_) | Self::Pin(_) => { + SPACING_REPLACE.len_utf8() + } Self::Frame(_) | Self::Repeat(_, _) => NODE_REPLACE.len_utf8(), } } @@ -324,10 +333,10 @@ impl<'a> Item<'a> { /// The natural width of the item. fn width(&self) -> Length { match self { - Item::Text(shaped) => shaped.width, - Item::Absolute(v) => *v, - Item::Fractional(_) | Self::Repeat(_, _) => Length::zero(), - Item::Frame(frame) => frame.size.x, + Self::Text(shaped) => shaped.width, + Self::Absolute(v) => *v, + Self::Frame(frame) => frame.size.x, + Self::Fractional(_) | Self::Repeat(_, _) | Self::Pin(_) => Length::zero(), } } } @@ -447,7 +456,7 @@ fn collect<'a>( } Segment::Text(full.len() - prev) } - ParChild::Quote { double } => { + &ParChild::Quote { double } => { let prev = full.len(); if styles.get(TextNode::SMART_QUOTES) { let lang = styles.get(TextNode::LANG); @@ -456,24 +465,28 @@ fn collect<'a>( let peeked = iter.peek().and_then(|(child, _)| match child { ParChild::Text(text) => text.chars().next(), ParChild::Quote { .. } => Some('"'), - ParChild::Spacing(_) => Some(SPACING_REPLACE), + ParChild::Spacing(_) | ParChild::Pin(_) => Some(SPACING_REPLACE), ParChild::Node(_) => Some(NODE_REPLACE), }); - full.push_str(quoter.quote("es, *double, peeked)); + full.push_str(quoter.quote("es, double, peeked)); } else { - full.push(if *double { '"' } else { '\'' }); + full.push(if double { '"' } else { '\'' }); } Segment::Text(full.len() - prev) } - ParChild::Spacing(spacing) => { + &ParChild::Spacing(spacing) => { full.push(SPACING_REPLACE); - Segment::Spacing(*spacing) + Segment::Spacing(spacing) } ParChild::Node(node) => { full.push(NODE_REPLACE); Segment::Node(node) } + &ParChild::Pin(idx) => { + full.push(SPACING_REPLACE); + Segment::Pin(idx) + } }; if let Some(last) = full.chars().last() { @@ -540,6 +553,7 @@ fn prepare<'a>( items.push(Item::Frame(frame)); } } + Segment::Pin(idx) => items.push(Item::Pin(idx)), } cursor = end; @@ -1171,6 +1185,11 @@ fn commit( } offset = before + width; } + Item::Pin(idx) => { + let mut frame = Frame::new(Size::zero()); + frame.push(Point::zero(), Element::Pin(*idx)); + push(&mut offset, MaybeShared::Owned(frame)); + } } } diff --git a/src/library/utility/locate.rs b/src/library/utility/locate.rs new file mode 100644 index 00000000..0352199f --- /dev/null +++ b/src/library/utility/locate.rs @@ -0,0 +1,8 @@ +use crate::library::prelude::*; +use crate::model::LocateNode; + +/// Format content with access to its location on the page. +pub fn locate(_: &mut Machine, args: &mut Args) -> TypResult<Value> { + let node = LocateNode::new(args.expect("recipe")?); + Ok(Value::Content(Content::Locate(node))) +} diff --git a/src/library/utility/mod.rs b/src/library/utility/mod.rs index 10aa7c7a..32815607 100644 --- a/src/library/utility/mod.rs +++ b/src/library/utility/mod.rs @@ -1,10 +1,12 @@ //! Computational utility functions. mod color; +mod locate; mod math; mod string; pub use color::*; +pub use locate::*; pub use math::*; pub use string::*; |
