Fix PDF outline bugs

Fixes #1098
Fixes #1143
Fixes #1151
This commit is contained in:
Laurenz 2023-05-22 16:03:22 +02:00
parent ef1bf742f6
commit a3227f4ef3
2 changed files with 14 additions and 23 deletions

View File

@ -36,7 +36,7 @@ use crate::prelude::*;
/// ///
/// Display: Raw Text / Code /// Display: Raw Text / Code
/// Category: text /// Category: text
#[element(Synthesize, Show, Finalize, LocalName, Figurable)] #[element(Synthesize, Show, Finalize, LocalName, Figurable, PlainText)]
pub struct RawElem { pub struct RawElem {
/// The raw text. /// The raw text.
/// ///
@ -246,6 +246,12 @@ impl LocalName for RawElem {
impl Figurable for RawElem {} impl Figurable for RawElem {}
impl PlainText for RawElem {
fn plain_text(&self, text: &mut EcoString) {
text.push_str(&self.text());
}
}
/// Highlight a syntax node in a theme by calling `f` with ranges and their /// Highlight a syntax node in a theme by calling `f` with ranges and their
/// styles. /// styles.
fn highlight_themed<F>( fn highlight_themed<F>(

View File

@ -5,7 +5,6 @@ use pdf_writer::{Finish, Ref, TextStr};
use super::{AbsExt, PdfContext, RefExt}; use super::{AbsExt, PdfContext, RefExt};
use crate::geom::Abs; use crate::geom::Abs;
use crate::model::Content; use crate::model::Content;
use crate::util::NonZeroExt;
/// Construct the outline for the document. /// Construct the outline for the document.
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
@ -13,13 +12,13 @@ pub fn write_outline(ctx: &mut PdfContext) -> Option<Ref> {
let mut tree: Vec<HeadingNode> = vec![]; let mut tree: Vec<HeadingNode> = vec![];
for heading in ctx.introspector.query(&item!(heading_func).select()) { for heading in ctx.introspector.query(&item!(heading_func).select()) {
let leaf = HeadingNode::leaf((*heading).clone()); let leaf = HeadingNode::leaf((*heading).clone());
if let Some(last) = tree.last_mut() {
if last.try_insert(leaf.clone(), NonZeroUsize::ONE) { let mut children = &mut tree;
continue; 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() { if tree.is_empty() {
@ -64,21 +63,6 @@ impl HeadingNode {
fn len(&self) -> usize { fn len(&self) -> usize {
1 + self.children.iter().map(Self::len).sum::<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. /// Write an outline item and all its children.
@ -111,7 +95,8 @@ fn write_outline_item(
outline.count(-(node.children.len() as i32)); 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 loc = node.element.location().unwrap();
let pos = ctx.introspector.position(loc); let pos = ctx.introspector.position(loc);