diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-05-22 16:03:22 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-05-22 16:05:13 +0200 |
| commit | a3227f4ef3b759faa506109c0235df5ffd2a4b7d (patch) | |
| tree | e62d8d04e389cfb71a4ec3213dc322366b920a8a /src/export/pdf | |
| parent | ef1bf742f6b73e60a8adb40281140314dc3e7ff4 (diff) | |
Fix PDF outline bugs
Fixes #1098
Fixes #1143
Fixes #1151
Diffstat (limited to 'src/export/pdf')
| -rw-r--r-- | src/export/pdf/outline.rs | 29 |
1 files changed, 7 insertions, 22 deletions
diff --git a/src/export/pdf/outline.rs b/src/export/pdf/outline.rs index d4e4c8ef..539647eb 100644 --- a/src/export/pdf/outline.rs +++ b/src/export/pdf/outline.rs @@ -5,7 +5,6 @@ use pdf_writer::{Finish, Ref, TextStr}; use super::{AbsExt, PdfContext, RefExt}; use crate::geom::Abs; use crate::model::Content; -use crate::util::NonZeroExt; /// Construct the outline for the document. #[tracing::instrument(skip_all)] @@ -13,13 +12,13 @@ pub fn write_outline(ctx: &mut PdfContext) -> Option<Ref> { let mut tree: Vec<HeadingNode> = vec![]; for heading in ctx.introspector.query(&item!(heading_func).select()) { let leaf = HeadingNode::leaf((*heading).clone()); - if let Some(last) = tree.last_mut() { - if last.try_insert(leaf.clone(), NonZeroUsize::ONE) { - continue; - } + + let mut children = &mut tree; + while children.last().map_or(false, |last| last.level < leaf.level) { + children = &mut children.last_mut().unwrap().children; } - tree.push(leaf); + children.push(leaf); } if tree.is_empty() { @@ -64,21 +63,6 @@ impl HeadingNode { fn len(&self) -> usize { 1 + self.children.iter().map(Self::len).sum::<usize>() } - - fn try_insert(&mut self, child: Self, level: NonZeroUsize) -> bool { - if level >= child.level { - return false; - } - - if let Some(last) = self.children.last_mut() { - if last.try_insert(child.clone(), level.saturating_add(1)) { - return true; - } - } - - self.children.push(child); - true - } } /// Write an outline item and all its children. @@ -111,7 +95,8 @@ fn write_outline_item( outline.count(-(node.children.len() as i32)); } - outline.title(TextStr(node.element.plain_text().trim())); + let body = node.element.expect_field::<Content>("body"); + outline.title(TextStr(body.plain_text().trim())); let loc = node.element.location().unwrap(); let pos = ctx.introspector.position(loc); |
