parent
9720424884
commit
2606034ac7
@ -298,13 +298,12 @@ impl Refable for EquationElem {
|
||||
fn reference(
|
||||
&self,
|
||||
vt: &mut Vt,
|
||||
styles: StyleChain,
|
||||
supplement: Option<Content>,
|
||||
lang: Lang,
|
||||
) -> SourceResult<Content> {
|
||||
// first we create the supplement of the heading
|
||||
let mut supplement = supplement.unwrap_or_else(|| {
|
||||
TextElem::packed(self.local_name(TextElem::lang_in(styles)))
|
||||
});
|
||||
let mut supplement =
|
||||
supplement.unwrap_or_else(|| TextElem::packed(self.local_name(lang)));
|
||||
|
||||
// we append a space if the supplement is not empty
|
||||
if !supplement.is_empty() {
|
||||
@ -312,7 +311,7 @@ impl Refable for EquationElem {
|
||||
};
|
||||
|
||||
// we check for a numbering
|
||||
let Some(numbering) = self.numbering(styles) else {
|
||||
let Some(numbering) = self.numbering(StyleChain::default()) else {
|
||||
bail!(self.span(), "only numbered equations can be referenced");
|
||||
};
|
||||
|
||||
@ -324,11 +323,11 @@ impl Refable for EquationElem {
|
||||
Ok(supplement + numbers)
|
||||
}
|
||||
|
||||
fn numbering(&self, styles: StyleChain) -> Option<Numbering> {
|
||||
self.numbering(styles)
|
||||
fn numbering(&self) -> Option<Numbering> {
|
||||
self.numbering(StyleChain::default())
|
||||
}
|
||||
|
||||
fn counter(&self, _: StyleChain) -> Counter {
|
||||
fn counter(&self) -> Counter {
|
||||
Counter::of(Self::func())
|
||||
}
|
||||
}
|
||||
|
@ -223,12 +223,14 @@ impl Synthesize for FigureElem {
|
||||
}),
|
||||
)));
|
||||
|
||||
self.push_caption(self.caption(styles));
|
||||
self.push_kind(Smart::Custom(kind));
|
||||
self.push_numbering(numbering);
|
||||
self.push_counter(Some(counter));
|
||||
self.push_supplement(Smart::Custom(Supplement::Content(
|
||||
supplement.unwrap_or_default(),
|
||||
)));
|
||||
self.push_numbering(numbering);
|
||||
self.push_outlined(self.outlined(styles));
|
||||
self.push_counter(Some(counter));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -242,7 +244,7 @@ impl Show for FigureElem {
|
||||
// We build the caption, if any.
|
||||
if self.caption(styles).is_some() {
|
||||
realized += VElem::weak(self.gap(styles).into()).pack();
|
||||
realized += self.show_caption(vt, styles)?;
|
||||
realized += self.show_caption(vt)?;
|
||||
}
|
||||
|
||||
// We wrap the contents in a block.
|
||||
@ -268,32 +270,32 @@ impl Refable for FigureElem {
|
||||
fn reference(
|
||||
&self,
|
||||
vt: &mut Vt,
|
||||
styles: StyleChain,
|
||||
supplement: Option<Content>,
|
||||
_: Lang,
|
||||
) -> SourceResult<Content> {
|
||||
// If the figure is not numbered, we cannot reference it.
|
||||
// Otherwise we build the supplement and numbering scheme.
|
||||
let Some(desc) = self.show_supplement_and_numbering(vt, styles, supplement)? else {
|
||||
let Some(desc) = self.show_supplement_and_numbering(vt, supplement)? else {
|
||||
bail!(self.span(), "cannot reference unnumbered figure")
|
||||
};
|
||||
|
||||
Ok(desc)
|
||||
}
|
||||
|
||||
fn outline(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Option<Content>> {
|
||||
fn outline(&self, vt: &mut Vt, _: Lang) -> SourceResult<Option<Content>> {
|
||||
// If the figure is not outlined, it is not referenced.
|
||||
if !self.outlined(styles) {
|
||||
if !self.outlined(StyleChain::default()) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
self.show_caption(vt, styles).map(Some)
|
||||
self.show_caption(vt).map(Some)
|
||||
}
|
||||
|
||||
fn numbering(&self, styles: StyleChain) -> Option<Numbering> {
|
||||
self.numbering(styles)
|
||||
fn numbering(&self) -> Option<Numbering> {
|
||||
self.numbering(StyleChain::default())
|
||||
}
|
||||
|
||||
fn counter(&self, _: StyleChain) -> Counter {
|
||||
fn counter(&self) -> Counter {
|
||||
self.counter().unwrap_or_else(|| Counter::of(Self::func()))
|
||||
}
|
||||
}
|
||||
@ -327,12 +329,13 @@ impl FigureElem {
|
||||
pub fn show_supplement_and_numbering(
|
||||
&self,
|
||||
vt: &mut Vt,
|
||||
styles: StyleChain,
|
||||
external_supplement: Option<Content>,
|
||||
) -> SourceResult<Option<Content>> {
|
||||
if let (Some(numbering), Some(supplement), Some(counter)) = (
|
||||
self.numbering(styles),
|
||||
self.supplement(styles).as_custom().and_then(|s| s.as_content()),
|
||||
self.numbering(StyleChain::default()),
|
||||
self.supplement(StyleChain::default())
|
||||
.as_custom()
|
||||
.and_then(|s| s.as_content()),
|
||||
self.counter(),
|
||||
) {
|
||||
let mut name = external_supplement.unwrap_or(supplement);
|
||||
@ -356,12 +359,12 @@ impl FigureElem {
|
||||
///
|
||||
/// # Errors
|
||||
/// If a numbering is specified but the [`Self::element`] is `None`.
|
||||
pub fn show_caption(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
|
||||
let Some(mut caption) = self.caption(styles) else {
|
||||
pub fn show_caption(&self, vt: &mut Vt) -> SourceResult<Content> {
|
||||
let Some(mut caption) = self.caption(StyleChain::default()) else {
|
||||
return Ok(Content::empty());
|
||||
};
|
||||
|
||||
if let Some(sup_and_num) = self.show_supplement_and_numbering(vt, styles, None)? {
|
||||
if let Some(sup_and_num) = self.show_supplement_and_numbering(vt, None)? {
|
||||
caption = sup_and_num + TextElem::packed(": ") + caption;
|
||||
}
|
||||
|
||||
|
@ -59,21 +59,6 @@ pub struct HeadingElem {
|
||||
/// ```
|
||||
pub numbering: Option<Numbering>,
|
||||
|
||||
/// Whether the heading should appear in the outline.
|
||||
///
|
||||
/// ```example
|
||||
/// #outline()
|
||||
///
|
||||
/// #heading[Normal]
|
||||
/// This is a normal heading.
|
||||
///
|
||||
/// #heading(outlined: false)[Hidden]
|
||||
/// This heading does not appear
|
||||
/// in the outline.
|
||||
/// ```
|
||||
#[default(true)]
|
||||
pub outlined: bool,
|
||||
|
||||
/// A supplement for the heading.
|
||||
///
|
||||
/// For references to headings, this is added before the
|
||||
@ -91,6 +76,21 @@ pub struct HeadingElem {
|
||||
#[default(Smart::Auto)]
|
||||
pub supplement: Smart<Option<Supplement>>,
|
||||
|
||||
/// Whether the heading should appear in the outline.
|
||||
///
|
||||
/// ```example
|
||||
/// #outline()
|
||||
///
|
||||
/// #heading[Normal]
|
||||
/// This is a normal heading.
|
||||
///
|
||||
/// #heading(outlined: false)[Hidden]
|
||||
/// This heading does not appear
|
||||
/// in the outline.
|
||||
/// ```
|
||||
#[default(true)]
|
||||
pub outlined: bool,
|
||||
|
||||
/// The heading's title.
|
||||
#[required]
|
||||
pub body: Content,
|
||||
@ -100,6 +100,7 @@ impl Synthesize for HeadingElem {
|
||||
fn synthesize(&mut self, _vt: &mut Vt, styles: StyleChain) -> SourceResult<()> {
|
||||
self.push_level(self.level(styles));
|
||||
self.push_numbering(self.numbering(styles));
|
||||
self.push_supplement(self.supplement(styles));
|
||||
self.push_outlined(self.outlined(styles));
|
||||
Ok(())
|
||||
}
|
||||
@ -159,17 +160,15 @@ impl Refable for HeadingElem {
|
||||
fn reference(
|
||||
&self,
|
||||
vt: &mut Vt,
|
||||
styles: StyleChain,
|
||||
supplement: Option<Content>,
|
||||
lang: Lang,
|
||||
) -> SourceResult<Content> {
|
||||
// Create the supplement of the heading.
|
||||
let mut supplement = if let Some(supplement) = supplement {
|
||||
supplement
|
||||
} else {
|
||||
match self.supplement(styles) {
|
||||
Smart::Auto => {
|
||||
TextElem::packed(self.local_name(TextElem::lang_in(styles)))
|
||||
}
|
||||
match self.supplement(StyleChain::default()) {
|
||||
Smart::Auto => TextElem::packed(self.local_name(lang)),
|
||||
Smart::Custom(None) => Content::empty(),
|
||||
Smart::Custom(Some(supplement)) => {
|
||||
supplement.resolve(vt, std::iter::once(Value::from(self.clone())))?
|
||||
@ -183,7 +182,7 @@ impl Refable for HeadingElem {
|
||||
};
|
||||
|
||||
// Check for a numbering.
|
||||
let Some(numbering) = self.numbering(styles) else {
|
||||
let Some(numbering) = self.numbering(StyleChain::default()) else {
|
||||
bail!(self.span(), "only numbered headings can be referenced");
|
||||
};
|
||||
|
||||
@ -195,21 +194,21 @@ impl Refable for HeadingElem {
|
||||
Ok(supplement + numbers)
|
||||
}
|
||||
|
||||
fn level(&self, styles: StyleChain) -> usize {
|
||||
self.level(styles).get()
|
||||
fn level(&self) -> usize {
|
||||
self.level(StyleChain::default()).get()
|
||||
}
|
||||
|
||||
fn numbering(&self, styles: StyleChain) -> Option<Numbering> {
|
||||
self.numbering(styles)
|
||||
fn numbering(&self) -> Option<Numbering> {
|
||||
self.numbering(StyleChain::default())
|
||||
}
|
||||
|
||||
fn counter(&self, _: StyleChain) -> Counter {
|
||||
fn counter(&self) -> Counter {
|
||||
Counter::of(Self::func())
|
||||
}
|
||||
|
||||
fn outline(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Option<Content>> {
|
||||
fn outline(&self, vt: &mut Vt, _: Lang) -> SourceResult<Option<Content>> {
|
||||
// Check whether the heading is outlined.
|
||||
if !self.outlined(styles) {
|
||||
if !self.outlined(StyleChain::default()) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
|
@ -151,6 +151,7 @@ impl Show for OutlineElem {
|
||||
|
||||
let indent = self.indent(styles);
|
||||
let depth = self.depth(styles).map_or(usize::MAX, NonZeroUsize::get);
|
||||
let lang = TextElem::lang_in(styles);
|
||||
|
||||
let mut ancestors: Vec<&Content> = vec![];
|
||||
let elems = vt.introspector.query(self.target(styles));
|
||||
@ -161,11 +162,11 @@ impl Show for OutlineElem {
|
||||
};
|
||||
|
||||
let location = elem.location().expect("missing location");
|
||||
if depth < refable.level(StyleChain::default()) {
|
||||
if depth < refable.level() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(outline) = refable.outline(vt, StyleChain::default())? else {
|
||||
let Some(outline) = refable.outline(vt, lang)? else {
|
||||
continue;
|
||||
};
|
||||
|
||||
@ -174,10 +175,7 @@ impl Show for OutlineElem {
|
||||
while ancestors
|
||||
.last()
|
||||
.and_then(|ancestor| ancestor.with::<dyn Refable>())
|
||||
.map_or(false, |last| {
|
||||
last.level(StyleChain::default())
|
||||
>= refable.level(StyleChain::default())
|
||||
})
|
||||
.map_or(false, |last| last.level() >= refable.level())
|
||||
{
|
||||
ancestors.pop();
|
||||
}
|
||||
@ -188,11 +186,9 @@ impl Show for OutlineElem {
|
||||
for ancestor in &ancestors {
|
||||
let ancestor_refable = ancestor.with::<dyn Refable>().unwrap();
|
||||
|
||||
if let Some(numbering) =
|
||||
ancestor_refable.numbering(StyleChain::default())
|
||||
{
|
||||
if let Some(numbering) = ancestor_refable.numbering() {
|
||||
let numbers = ancestor_refable
|
||||
.counter(StyleChain::default())
|
||||
.counter()
|
||||
.at(vt, ancestor.location().unwrap())?
|
||||
.display(vt, &numbering)?;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{BibliographyElem, CiteElem, Counter, Figurable, Numbering};
|
||||
use crate::prelude::*;
|
||||
use crate::text::TextElem;
|
||||
|
||||
/// A reference to a label or bibliography.
|
||||
///
|
||||
@ -131,10 +132,11 @@ impl Show for RefElem {
|
||||
}
|
||||
};
|
||||
|
||||
let lang = TextElem::lang_in(styles);
|
||||
let reference = elem
|
||||
.with::<dyn Refable>()
|
||||
.expect("element should be refable")
|
||||
.reference(vt, styles, supplement)?;
|
||||
.reference(vt, supplement, lang)?;
|
||||
|
||||
Ok(reference.linked(Destination::Location(elem.location().unwrap())))
|
||||
}
|
||||
@ -212,27 +214,27 @@ pub trait Refable {
|
||||
fn reference(
|
||||
&self,
|
||||
vt: &mut Vt,
|
||||
styles: StyleChain,
|
||||
supplement: Option<Content>,
|
||||
lang: Lang,
|
||||
) -> SourceResult<Content>;
|
||||
|
||||
/// Tries to build an outline element for this element.
|
||||
/// If this returns `None`, the outline will not include this element.
|
||||
/// By default this just calls [`Refable::reference`].
|
||||
fn outline(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Option<Content>> {
|
||||
self.reference(vt, styles, None).map(Some)
|
||||
fn outline(&self, vt: &mut Vt, lang: Lang) -> SourceResult<Option<Content>> {
|
||||
self.reference(vt, None, lang).map(Some)
|
||||
}
|
||||
|
||||
/// Returns the level of this element.
|
||||
/// This is used to determine the level of the outline.
|
||||
/// By default this returns `0`.
|
||||
fn level(&self, _styles: StyleChain) -> usize {
|
||||
fn level(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
/// Returns the numbering of this element.
|
||||
fn numbering(&self, styles: StyleChain) -> Option<Numbering>;
|
||||
fn numbering(&self) -> Option<Numbering>;
|
||||
|
||||
/// Returns the counter of this element.
|
||||
fn counter(&self, styles: StyleChain) -> Counter;
|
||||
fn counter(&self) -> Counter;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user