mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Optimization to Introspector::extract
(#734)
This commit is contained in:
parent
72d8785abe
commit
5bc73be90f
5
Cargo.lock
generated
5
Cargo.lock
generated
@ -731,9 +731,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.2"
|
version = "1.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
@ -1606,6 +1606,7 @@ dependencies = [
|
|||||||
"flate2",
|
"flate2",
|
||||||
"if_chain",
|
"if_chain",
|
||||||
"image",
|
"image",
|
||||||
|
"indexmap",
|
||||||
"log",
|
"log",
|
||||||
"miniz_oxide 0.5.4",
|
"miniz_oxide 0.5.4",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
@ -43,6 +43,7 @@ unicode-xid = "0.2"
|
|||||||
unscanny = "0.1"
|
unscanny = "0.1"
|
||||||
usvg = { version = "0.22", default-features = false }
|
usvg = { version = "0.22", default-features = false }
|
||||||
xmp-writer = "0.1"
|
xmp-writer = "0.1"
|
||||||
|
indexmap = "1.9.3"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
debug = 0
|
debug = 0
|
||||||
|
@ -2,6 +2,8 @@ use std::fmt::{self, Debug, Formatter};
|
|||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use super::{Content, Selector};
|
use super::{Content, Selector};
|
||||||
use crate::diag::StrResult;
|
use crate::diag::StrResult;
|
||||||
use crate::doc::{Frame, FrameItem, Meta, Position};
|
use crate::doc::{Frame, FrameItem, Meta, Position};
|
||||||
@ -83,7 +85,7 @@ impl StabilityProvider {
|
|||||||
/// Can be queried for elements and their positions.
|
/// Can be queried for elements and their positions.
|
||||||
pub struct Introspector {
|
pub struct Introspector {
|
||||||
pages: usize,
|
pages: usize,
|
||||||
elems: Vec<(Content, Position)>,
|
elems: IndexMap<Option<Location>, (Content, Position)>,
|
||||||
// Indexed by page number.
|
// Indexed by page number.
|
||||||
page_numberings: Vec<Value>,
|
page_numberings: Vec<Value>,
|
||||||
}
|
}
|
||||||
@ -93,7 +95,7 @@ impl Introspector {
|
|||||||
pub fn new(frames: &[Frame]) -> Self {
|
pub fn new(frames: &[Frame]) -> Self {
|
||||||
let mut introspector = Self {
|
let mut introspector = Self {
|
||||||
pages: frames.len(),
|
pages: frames.len(),
|
||||||
elems: vec![],
|
elems: IndexMap::new(),
|
||||||
page_numberings: vec![],
|
page_numberings: vec![],
|
||||||
};
|
};
|
||||||
for (i, frame) in frames.iter().enumerate() {
|
for (i, frame) in frames.iter().enumerate() {
|
||||||
@ -105,7 +107,7 @@ impl Introspector {
|
|||||||
|
|
||||||
/// Iterate over all elements.
|
/// Iterate over all elements.
|
||||||
pub fn all(&self) -> impl Iterator<Item = &Content> {
|
pub fn all(&self) -> impl Iterator<Item = &Content> {
|
||||||
self.elems.iter().map(|(elem, _)| elem)
|
self.elems.values().map(|(elem, _)| elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract metadata from a frame.
|
/// Extract metadata from a frame.
|
||||||
@ -119,13 +121,14 @@ impl Introspector {
|
|||||||
self.extract(&group.frame, page, ts);
|
self.extract(&group.frame, page, ts);
|
||||||
}
|
}
|
||||||
FrameItem::Meta(Meta::Elem(content), _)
|
FrameItem::Meta(Meta::Elem(content), _)
|
||||||
if !self
|
if !self.elems.contains_key(&content.location()) =>
|
||||||
.elems
|
|
||||||
.iter()
|
|
||||||
.any(|(prev, _)| prev.location() == content.location()) =>
|
|
||||||
{
|
{
|
||||||
let pos = pos.transform(ts);
|
let pos = pos.transform(ts);
|
||||||
self.elems.push((content.clone(), Position { page, point: pos }));
|
let ret = self.elems.insert(
|
||||||
|
content.location(),
|
||||||
|
(content.clone(), Position { page, point: pos }),
|
||||||
|
);
|
||||||
|
assert!(ret.is_none(), "duplicate locations");
|
||||||
}
|
}
|
||||||
FrameItem::Meta(Meta::PageNumbering(numbering), _) => {
|
FrameItem::Meta(Meta::PageNumbering(numbering), _) => {
|
||||||
self.page_numberings.push(numbering.clone());
|
self.page_numberings.push(numbering.clone());
|
||||||
@ -202,8 +205,7 @@ impl Introspector {
|
|||||||
/// Find the position for the given location.
|
/// Find the position for the given location.
|
||||||
pub fn position(&self, location: Location) -> Position {
|
pub fn position(&self, location: Location) -> Position {
|
||||||
self.elems
|
self.elems
|
||||||
.iter()
|
.get(&Some(location))
|
||||||
.find(|(elem, _)| elem.location() == Some(location))
|
|
||||||
.map(|(_, loc)| *loc)
|
.map(|(_, loc)| *loc)
|
||||||
.unwrap_or(Position { page: NonZeroUsize::ONE, point: Point::zero() })
|
.unwrap_or(Position { page: NonZeroUsize::ONE, point: Point::zero() })
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user