mirror of
https://github.com/typst/typst
synced 2025-07-01 17:52:52 +08:00
add Deref to Repeatable
honestly, all the unwrapping was just generating noise.
This commit is contained in:
parent
9a01b9bfe8
commit
71ae276071
@ -238,9 +238,9 @@ impl<'a> GridLayouter<'a> {
|
||||
while y < self.grid.rows.len() {
|
||||
if let Some(next_header) = self.upcoming_headers.get(consecutive_header_count)
|
||||
{
|
||||
if next_header.unwrap().range().contains(&y) {
|
||||
if next_header.range().contains(&y) {
|
||||
self.place_new_headers(&mut consecutive_header_count, engine)?;
|
||||
y = next_header.unwrap().end;
|
||||
y = next_header.end;
|
||||
|
||||
// Skip header rows during normal layout.
|
||||
continue;
|
||||
|
@ -18,9 +18,8 @@ impl<'a> GridLayouter<'a> {
|
||||
|
||||
if new_upcoming_headers.first().is_some_and(|next_header| {
|
||||
consecutive_headers.last().is_none_or(|latest_header| {
|
||||
!latest_header.unwrap().short_lived
|
||||
&& next_header.unwrap().start == latest_header.unwrap().end
|
||||
}) && !next_header.unwrap().short_lived
|
||||
!latest_header.short_lived && next_header.start == latest_header.end
|
||||
}) && !next_header.short_lived
|
||||
}) {
|
||||
// More headers coming, so wait until we reach them.
|
||||
// TODO: refactor
|
||||
@ -31,7 +30,7 @@ impl<'a> GridLayouter<'a> {
|
||||
*consecutive_header_count = 0;
|
||||
|
||||
// Layout short-lived headers immediately.
|
||||
if consecutive_headers.last().is_some_and(|h| h.unwrap().short_lived) {
|
||||
if consecutive_headers.last().is_some_and(|h| h.short_lived) {
|
||||
// No chance of orphans as we're immediately placing conflicting
|
||||
// headers afterwards, which basically are not headers, for all intents
|
||||
// and purposes. It is therefore guaranteed that all new headers have
|
||||
@ -104,7 +103,7 @@ impl<'a> GridLayouter<'a> {
|
||||
|
||||
// Assuming non-conflicting headers sorted by increasing y, this must
|
||||
// be the header with the lowest level (sorted by increasing levels).
|
||||
let first_level = first_header.unwrap().level;
|
||||
let first_level = first_header.level;
|
||||
|
||||
// Stop repeating conflicting headers.
|
||||
// If we go to a new region before the pending headers fit alongside
|
||||
|
@ -1,5 +1,5 @@
|
||||
use std::num::{NonZeroU32, NonZeroUsize};
|
||||
use std::ops::Range;
|
||||
use std::ops::{Deref, Range};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ecow::eco_format;
|
||||
@ -487,6 +487,14 @@ pub enum Repeatable<T> {
|
||||
NotRepeated(T),
|
||||
}
|
||||
|
||||
impl<T> Deref for Repeatable<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Repeatable<T> {
|
||||
/// Gets the value inside this repeatable, regardless of whether
|
||||
/// it repeats.
|
||||
@ -1562,10 +1570,10 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
let mut consecutive_header_start = data.start;
|
||||
for conflicting_header in
|
||||
headers.iter_mut().rev().take_while(move |h| {
|
||||
let conflicts = h.unwrap().end == consecutive_header_start
|
||||
&& h.unwrap().level >= data.level;
|
||||
let conflicts = h.end == consecutive_header_start
|
||||
&& h.level >= data.level;
|
||||
|
||||
consecutive_header_start = h.unwrap().start;
|
||||
consecutive_header_start = h.start;
|
||||
conflicts
|
||||
})
|
||||
{
|
||||
@ -1818,8 +1826,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
|
||||
// TODO: will need a global slice of headers and footers for
|
||||
// when we have multiple footers
|
||||
let last_header_end =
|
||||
headers.last().map(Repeatable::unwrap).map(|header| header.end);
|
||||
let last_header_end = headers.last().map(|header| header.end);
|
||||
|
||||
if has_gutter {
|
||||
// Convert the footer's start index to post-gutter coordinates.
|
||||
@ -1860,11 +1867,11 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
|
||||
// final footer, as short lived, given that there are no normal rows
|
||||
// after them, so repeating them is pointless.
|
||||
let mut consecutive_header_start =
|
||||
footer.as_ref().map(|f| f.unwrap().start).unwrap_or(row_amount);
|
||||
footer.as_ref().map(|f| f.start).unwrap_or(row_amount);
|
||||
for header_at_the_end in headers.iter_mut().rev().take_while(move |h| {
|
||||
let at_the_end = h.unwrap().end == consecutive_header_start;
|
||||
let at_the_end = h.end == consecutive_header_start;
|
||||
|
||||
consecutive_header_start = h.unwrap().start;
|
||||
consecutive_header_start = h.start;
|
||||
at_the_end
|
||||
}) {
|
||||
header_at_the_end.unwrap_mut().short_lived = true;
|
||||
@ -2052,9 +2059,10 @@ fn check_for_conflicting_cell_row(
|
||||
// `y + 1 = header.start` holds, that means `y < header.start`, and it
|
||||
// only occupies one row (`y`), so the cell is actually not in
|
||||
// conflict.
|
||||
if headers.iter().any(|header| {
|
||||
cell_y < header.unwrap().end && cell_y + rowspan > header.unwrap().start
|
||||
}) {
|
||||
if headers
|
||||
.iter()
|
||||
.any(|header| cell_y < header.end && cell_y + rowspan > header.start)
|
||||
{
|
||||
bail!(
|
||||
"cell would conflict with header spanning the same position";
|
||||
hint: "try moving the cell or the header"
|
||||
@ -2248,11 +2256,9 @@ fn find_next_available_position<const SKIP_ROWS: bool>(
|
||||
}
|
||||
// TODO: consider keeping vector of upcoming headers to make this check
|
||||
// non-quadratic (O(cells) instead of O(headers * cells)).
|
||||
} else if let Some(header) =
|
||||
headers.iter().map(Repeatable::unwrap).find(|header| {
|
||||
(header.start * columns..header.end * columns).contains(&resolved_index)
|
||||
})
|
||||
{
|
||||
} else if let Some(header) = headers.iter().find(|header| {
|
||||
(header.start * columns..header.end * columns).contains(&resolved_index)
|
||||
}) {
|
||||
// Skip header (can't place a cell inside it from outside it).
|
||||
resolved_index = header.end * columns;
|
||||
|
||||
|
@ -293,13 +293,13 @@ fn show_cellgrid_html(grid: CellGrid, styles: StyleChain) -> Content {
|
||||
};
|
||||
|
||||
let footer = grid.footer.map(|ft| {
|
||||
let rows = rows.drain(ft.unwrap().start..);
|
||||
let rows = rows.drain(ft.start..);
|
||||
elem(tag::tfoot, Content::sequence(rows.map(|row| tr(tag::td, row))))
|
||||
});
|
||||
// TODO: Headers and footers in arbitrary positions
|
||||
// Right now, only those at either end are accepted
|
||||
let header = grid.headers.first().filter(|h| h.unwrap().start == 0).map(|hd| {
|
||||
let rows = rows.drain(..hd.unwrap().end);
|
||||
let header = grid.headers.first().filter(|h| h.start == 0).map(|hd| {
|
||||
let rows = rows.drain(..hd.end);
|
||||
elem(tag::thead, Content::sequence(rows.map(|row| tr(tag::th, row))))
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user