Non-outlined headings

This commit is contained in:
Laurenz 2022-06-09 13:45:36 +02:00
parent cd5a14bc24
commit 6aff11057b
4 changed files with 25 additions and 12 deletions

View File

@ -604,12 +604,12 @@ impl<'a, 'b> PageExporter<'a, 'b> {
}
fn write_frame(&mut self, frame: &Frame) {
if let Some(Role::Heading(level)) = frame.role() {
if let Some(Role::Heading { level, outlined: true }) = frame.role() {
let heading = Heading {
position: Point::new(self.state.transform.tx, self.state.transform.ty),
content: frame.text(),
page: self.page_ref,
level,
level: level.get(),
};
if let Some(last) = self.exporter.heading_tree.last_mut() {

View File

@ -1,6 +1,7 @@
//! Finished layouts.
use std::fmt::{self, Debug, Formatter, Write};
use std::num::NonZeroUsize;
use std::sync::Arc;
use crate::eval::{Dict, Value};
@ -71,7 +72,7 @@ impl Frame {
/// group based on the number of elements in the frame.
pub fn push_frame(&mut self, pos: Point, frame: impl FrameRepr) {
if (self.elements.is_empty() || frame.as_ref().is_light())
&& frame.as_ref().role().is_none()
&& frame.as_ref().role().map_or(true, Role::is_weak)
{
frame.inline(self, self.layer(), pos);
} else {
@ -95,7 +96,7 @@ impl Frame {
/// Add a frame at a position in the background.
pub fn prepend_frame(&mut self, pos: Point, frame: impl FrameRepr) {
if (self.elements.is_empty() || frame.as_ref().is_light())
&& frame.as_ref().role().is_none()
&& frame.as_ref().role().map_or(true, Role::is_weak)
{
frame.inline(self, 0, pos);
} else {
@ -412,8 +413,8 @@ impl Location {
pub enum Role {
/// A paragraph.
Paragraph,
/// A heading with some level.
Heading(usize),
/// A heading with some level and whether it should be part of the outline.
Heading { level: NonZeroUsize, outlined: bool },
/// A generic block-level subdivision.
GenericBlock,
/// A generic inline subdivision.

View File

@ -55,6 +55,11 @@ impl HeadingNode {
pub const BELOW: Leveled<Option<BlockSpacing>> =
Leveled::Value(Some(Ratio::new(0.55).into()));
/// Whether the heading appears in the outline.
pub const OUTLINED: bool = true;
/// Whether the heading is numbered.
pub const NUMBERED: bool = true;
fn construct(_: &mut Machine, args: &mut Args) -> TypResult<Content> {
Ok(Content::show(Self {
body: args.expect("body")?,
@ -65,14 +70,15 @@ impl HeadingNode {
impl Show for HeadingNode {
fn unguard(&self, sel: Selector) -> ShowNode {
let body = self.body.unguard(sel).role(Role::Heading(self.level.get()));
Self { body, ..*self }.pack()
Self { body: self.body.unguard(sel), ..*self }.pack()
}
fn encode(&self, _: StyleChain) -> Dict {
fn encode(&self, styles: StyleChain) -> Dict {
dict! {
"level" => Value::Int(self.level.get() as i64),
"body" => Value::Content(self.body.clone()),
"outlined" => Value::Bool(styles.get(Self::OUTLINED)),
"numbered" => Value::Bool(styles.get(Self::NUMBERED)),
}
}
@ -115,7 +121,12 @@ impl Show for HeadingNode {
realized = realized.underlined();
}
realized = realized.styled_with_map(map).role(Role::Heading(self.level.get()));
let role = Role::Heading {
level: self.level,
outlined: styles.get(Self::OUTLINED),
};
realized = realized.styled_with_map(map).role(role);
realized = realized.spaced(
resolve!(Self::ABOVE).resolve(styles),
resolve!(Self::BELOW).resolve(styles),

View File

@ -231,9 +231,10 @@ impl Layout for LayoutNode {
let hash = fxhash::hash64(&ctx.pins);
let at = ctx.pins.cursor();
let entry = StyleEntry::Barrier(Barrier::new(node.id()));
let mut result = node.0.layout(ctx, regions, entry.chain(&styles));
let barrier = StyleEntry::Barrier(Barrier::new(node.id()));
let styles = barrier.chain(&styles);
let mut result = node.0.layout(ctx, regions, styles);
if let Some(role) = styles.role() {
result = result.map(|mut frames| {
for frame in frames.iter_mut() {