mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Add group
in addition to group_by_key
This commit is contained in:
parent
bdc7127adf
commit
90fb28b4b6
@ -239,9 +239,9 @@ impl<'a> ParLayouter<'a> {
|
|||||||
ParChild::Text(_) => {
|
ParChild::Text(_) => {
|
||||||
// TODO: Also split by language and script.
|
// TODO: Also split by language and script.
|
||||||
let mut cursor = range.start;
|
let mut cursor = range.start;
|
||||||
for (level, group) in bidi.levels[range].group_by_key(|&lvl| lvl) {
|
for (level, count) in bidi.levels[range].group() {
|
||||||
let start = cursor;
|
let start = cursor;
|
||||||
cursor += group.len();
|
cursor += count;
|
||||||
let subrange = start .. cursor;
|
let subrange = start .. cursor;
|
||||||
let text = &bidi.text[subrange.clone()];
|
let text = &bidi.text[subrange.clone()];
|
||||||
let shaped = shape(ctx.fonts, text, styles, level.dir());
|
let shaped = shape(ctx.fonts, text, styles, level.dir());
|
||||||
|
@ -82,9 +82,14 @@ where
|
|||||||
|
|
||||||
/// Additional methods for slices.
|
/// Additional methods for slices.
|
||||||
pub trait SliceExt<T> {
|
pub trait SliceExt<T> {
|
||||||
/// Split a slice into consecutive groups with the same key.
|
/// Find consecutive runs of the same elements in a slice and yield for
|
||||||
///
|
/// each such run the element and number of times it appears.
|
||||||
/// Returns an iterator of pairs of a key and the group with that key.
|
fn group(&self) -> Group<'_, T>
|
||||||
|
where
|
||||||
|
T: PartialEq;
|
||||||
|
|
||||||
|
/// Split a slice into consecutive runs with the same key and yield for
|
||||||
|
/// each such run the key and the slice of elements with that key.
|
||||||
fn group_by_key<K, F>(&self, f: F) -> GroupByKey<'_, T, F>
|
fn group_by_key<K, F>(&self, f: F) -> GroupByKey<'_, T, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&T) -> K,
|
F: FnMut(&T) -> K,
|
||||||
@ -92,15 +97,35 @@ pub trait SliceExt<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> SliceExt<T> for [T] {
|
impl<T> SliceExt<T> for [T] {
|
||||||
fn group_by_key<K, F>(&self, f: F) -> GroupByKey<'_, T, F>
|
fn group(&self) -> Group<'_, T> {
|
||||||
where
|
Group { slice: self }
|
||||||
F: FnMut(&T) -> K,
|
}
|
||||||
K: PartialEq,
|
|
||||||
{
|
fn group_by_key<K, F>(&self, f: F) -> GroupByKey<'_, T, F> {
|
||||||
GroupByKey { slice: self, f }
|
GroupByKey { slice: self, f }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This struct is created by [`SliceExt::group`].
|
||||||
|
pub struct Group<'a, T> {
|
||||||
|
slice: &'a [T],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Iterator for Group<'a, T>
|
||||||
|
where
|
||||||
|
T: PartialEq,
|
||||||
|
{
|
||||||
|
type Item = (&'a T, usize);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let mut iter = self.slice.iter();
|
||||||
|
let first = iter.next()?;
|
||||||
|
let count = 1 + iter.take_while(|&t| t == first).count();
|
||||||
|
self.slice = &self.slice[count ..];
|
||||||
|
Some((first, count))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This struct is created by [`SliceExt::group_by_key`].
|
/// This struct is created by [`SliceExt::group_by_key`].
|
||||||
pub struct GroupByKey<'a, T, F> {
|
pub struct GroupByKey<'a, T, F> {
|
||||||
slice: &'a [T],
|
slice: &'a [T],
|
||||||
@ -115,15 +140,10 @@ where
|
|||||||
type Item = (K, &'a [T]);
|
type Item = (K, &'a [T]);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let first = self.slice.first()?;
|
let mut iter = self.slice.iter();
|
||||||
let key = (self.f)(first);
|
let key = (self.f)(iter.next()?);
|
||||||
|
let count = 1 + iter.take_while(|t| (self.f)(t) == key).count();
|
||||||
let mut i = 1;
|
let (head, tail) = self.slice.split_at(count);
|
||||||
while self.slice.get(i).map_or(false, |t| (self.f)(t) == key) {
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (head, tail) = self.slice.split_at(i);
|
|
||||||
self.slice = tail;
|
self.slice = tail;
|
||||||
Some((key, head))
|
Some((key, head))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user