Extract location type into its own file

This commit is contained in:
Laurenz 2023-11-21 14:49:59 +01:00
parent 7cd684f725
commit ec8230c02e
3 changed files with 88 additions and 82 deletions

View File

@ -1,97 +1,19 @@
use std::cell::RefCell;
use std::collections::{BTreeSet, HashMap};
use std::fmt::Debug;
use std::hash::Hash;
use std::num::NonZeroUsize;
use comemo::{Prehashed, Track, Tracked, Validate};
use ecow::{eco_format, EcoString, EcoVec};
use ecow::{eco_format, EcoVec};
use indexmap::IndexMap;
use crate::diag::{bail, StrResult};
use crate::doc::{Frame, FrameItem, Meta, Position};
use crate::eval::{cast, func, scope, ty, Dict, Repr, Value, Vm};
use crate::eval::{Repr, Value};
use crate::geom::{Point, Transform};
use crate::model::{Content, Label, Selector};
use crate::model::{Content, Label, Location, Selector};
use crate::util::NonZeroExt;
/// Identifies an element in the document.
///
/// A location uniquely identifies an element in the document and lets you
/// access its absolute position on the pages. You can retrieve the current
/// location with the [`locate`]($locate) function and the location of a queried
/// or shown element with the [`location()`]($content.location) method on
/// content.
#[ty(scope)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Location {
/// The hash of the element.
hash: u128,
/// An unique number among elements with the same hash. This is the reason
/// we need a `Locator` everywhere.
disambiguator: usize,
/// A synthetic location created from another one. This is used for example
/// in bibliography management to create individual linkable locations for
/// reference entries from the bibliography's location.
variant: usize,
}
impl Location {
/// Produce a variant of this location.
pub fn variant(mut self, n: usize) -> Self {
self.variant = n;
self
}
}
#[scope]
impl Location {
/// Return the page number for this location.
///
/// Note that this does not return the value of the [page counter]($counter)
/// at this location, but the true page number (starting from one).
///
/// If you want to know the value of the page counter, use
/// `{counter(page).at(loc)}` instead.
#[func]
pub fn page(self, vm: &mut Vm) -> NonZeroUsize {
vm.vt.introspector.page(self)
}
/// Return a dictionary with the page number and the x, y position for this
/// location. The page number starts at one and the coordinates are measured
/// from the top-left of the page.
///
/// If you only need the page number, use `page()` instead as it allows
/// Typst to skip unnecessary work.
#[func]
pub fn position(self, vm: &mut Vm) -> Dict {
vm.vt.introspector.position(self).into()
}
/// Returns the page numbering pattern of the page at this location. This
/// can be used when displaying the page counter in order to obtain the
/// local numbering. This is useful if you are building custom indices or
/// outlines.
///
/// If the page numbering is set to `none` at that location, this function
/// returns `none`.
#[func]
pub fn page_numbering(self, vm: &mut Vm) -> Value {
vm.vt.introspector.page_numbering(self)
}
}
impl Repr for Location {
fn repr(&self) -> EcoString {
"..".into()
}
}
cast! {
type Location,
}
/// Provides locations for elements in the document.
///
/// A [`Location`] consists of an element's hash plus a disambiguator. Just the

View File

@ -0,0 +1,82 @@
use std::num::NonZeroUsize;
use ecow::EcoString;
use crate::eval::{cast, func, scope, ty, Dict, Repr, Value, Vm};
/// Identifies an element in the document.
///
/// A location uniquely identifies an element in the document and lets you
/// access its absolute position on the pages. You can retrieve the current
/// location with the [`locate`]($locate) function and the location of a queried
/// or shown element with the [`location()`]($content.location) method on
/// content.
#[ty(scope)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Location {
/// The hash of the element.
pub hash: u128,
/// An unique number among elements with the same hash. This is the reason
/// we need a `Locator` everywhere.
pub disambiguator: usize,
/// A synthetic location created from another one. This is used for example
/// in bibliography management to create individual linkable locations for
/// reference entries from the bibliography's location.
pub variant: usize,
}
impl Location {
/// Produce a variant of this location.
pub fn variant(mut self, n: usize) -> Self {
self.variant = n;
self
}
}
#[scope]
impl Location {
/// Return the page number for this location.
///
/// Note that this does not return the value of the [page counter]($counter)
/// at this location, but the true page number (starting from one).
///
/// If you want to know the value of the page counter, use
/// `{counter(page).at(loc)}` instead.
#[func]
pub fn page(self, vm: &mut Vm) -> NonZeroUsize {
vm.vt.introspector.page(self)
}
/// Return a dictionary with the page number and the x, y position for this
/// location. The page number starts at one and the coordinates are measured
/// from the top-left of the page.
///
/// If you only need the page number, use `page()` instead as it allows
/// Typst to skip unnecessary work.
#[func]
pub fn position(self, vm: &mut Vm) -> Dict {
vm.vt.introspector.position(self).into()
}
/// Returns the page numbering pattern of the page at this location. This
/// can be used when displaying the page counter in order to obtain the
/// local numbering. This is useful if you are building custom indices or
/// outlines.
///
/// If the page numbering is set to `none` at that location, this function
/// returns `none`.
#[func]
pub fn page_numbering(self, vm: &mut Vm) -> Value {
vm.vt.introspector.page_numbering(self)
}
}
impl Repr for Location {
fn repr(&self) -> EcoString {
"..".into()
}
}
cast! {
type Location,
}

View File

@ -5,6 +5,7 @@ mod content;
mod element;
mod introspect;
mod label;
mod location;
mod realize;
mod selector;
mod styles;
@ -18,8 +19,9 @@ pub use self::content::{fat, Content, MetaElem, PlainText};
pub use self::element::{
Construct, Element, ElementFields, LocalName, NativeElement, NativeElementData, Set,
};
pub use self::introspect::{Introspector, Location, Locator};
pub use self::introspect::{Introspector, Locator};
pub use self::label::{Label, Unlabellable};
pub use self::location::Location;
pub use self::realize::{
applicable, realize, Behave, Behaviour, Finalize, Guard, Locatable, Show, Synthesize,
};