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