mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Add support for page references through new ref.form
property (#4729)
This commit is contained in:
parent
dadc2176e2
commit
8d4f01d284
@ -494,7 +494,7 @@ impl MultiSpill<'_, '_> {
|
|||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
regions: Regions,
|
regions: Regions,
|
||||||
) -> SourceResult<(Frame, Option<Self>)> {
|
) -> SourceResult<(Frame, Option<Self>)> {
|
||||||
// The first region becomes unchangable and committed to our backlog.
|
// The first region becomes unchangeable and committed to our backlog.
|
||||||
self.backlog.push(regions.size.y);
|
self.backlog.push(regions.size.y);
|
||||||
|
|
||||||
// The remaining regions are ephemeral and may be replaced.
|
// The remaining regions are ephemeral and may be replaced.
|
||||||
|
@ -723,7 +723,7 @@ fn layout_line_numbers(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout the number and record its width in search of the maximium.
|
// Layout the number and record its width in search of the maximum.
|
||||||
let frame = layout_line_number(engine, config, &mut locator, &marker.numbering)?;
|
let frame = layout_line_number(engine, config, &mut locator, &marker.numbering)?;
|
||||||
|
|
||||||
// Note that this line.y is larger than the previous due to sorting.
|
// Note that this line.y is larger than the previous due to sorting.
|
||||||
|
@ -35,7 +35,7 @@ pub fn distribute(composer: &mut Composer, regions: Regions) -> FlowResult<Frame
|
|||||||
struct Distributor<'a, 'b, 'x, 'y, 'z> {
|
struct Distributor<'a, 'b, 'x, 'y, 'z> {
|
||||||
/// The composer that is used to handle insertions.
|
/// The composer that is used to handle insertions.
|
||||||
composer: &'z mut Composer<'a, 'b, 'x, 'y>,
|
composer: &'z mut Composer<'a, 'b, 'x, 'y>,
|
||||||
/// Regions which are continously shrunk as new items are added.
|
/// Regions which are continuously shrunk as new items are added.
|
||||||
regions: Regions<'z>,
|
regions: Regions<'z>,
|
||||||
/// Already laid out items, not yet aligned.
|
/// Already laid out items, not yet aligned.
|
||||||
items: Vec<Item<'a, 'b>>,
|
items: Vec<Item<'a, 'b>>,
|
||||||
|
@ -774,7 +774,7 @@ fn shape_segment<'a>(
|
|||||||
buffer.guess_segment_properties();
|
buffer.guess_segment_properties();
|
||||||
|
|
||||||
// By default, Harfbuzz will create zero-width space glyphs for default
|
// By default, Harfbuzz will create zero-width space glyphs for default
|
||||||
// ignorables. This is probably useful for GUI apps that want noticable
|
// ignorables. This is probably useful for GUI apps that want noticeable
|
||||||
// effects on the cursor for those, but for us it's not useful and hurts
|
// effects on the cursor for those, but for us it's not useful and hurts
|
||||||
// text extraction.
|
// text extraction.
|
||||||
buffer.set_flags(BufferFlags::REMOVE_DEFAULT_IGNORABLES);
|
buffer.set_flags(BufferFlags::REMOVE_DEFAULT_IGNORABLES);
|
||||||
|
@ -23,6 +23,7 @@ pub fn finalize(
|
|||||||
foreground,
|
foreground,
|
||||||
fill,
|
fill,
|
||||||
numbering,
|
numbering,
|
||||||
|
supplement,
|
||||||
}: LayoutedPage,
|
}: LayoutedPage,
|
||||||
) -> SourceResult<Page> {
|
) -> SourceResult<Page> {
|
||||||
// If two sided, left becomes inside and right becomes outside.
|
// If two sided, left becomes inside and right becomes outside.
|
||||||
@ -69,5 +70,5 @@ pub fn finalize(
|
|||||||
let number = counter.logical();
|
let number = counter.logical();
|
||||||
counter.step();
|
counter.step();
|
||||||
|
|
||||||
Ok(Page { frame, fill, numbering, number })
|
Ok(Page { frame, fill, numbering, supplement, number })
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ use typst_library::layout::{
|
|||||||
};
|
};
|
||||||
use typst_library::model::Numbering;
|
use typst_library::model::Numbering;
|
||||||
use typst_library::routines::{Pair, Routines};
|
use typst_library::routines::{Pair, Routines};
|
||||||
use typst_library::text::TextElem;
|
use typst_library::text::{LocalName, TextElem};
|
||||||
use typst_library::visualize::Paint;
|
use typst_library::visualize::Paint;
|
||||||
use typst_library::World;
|
use typst_library::World;
|
||||||
use typst_utils::Numeric;
|
use typst_utils::Numeric;
|
||||||
@ -36,6 +36,7 @@ pub struct LayoutedPage {
|
|||||||
pub foreground: Option<Frame>,
|
pub foreground: Option<Frame>,
|
||||||
pub fill: Smart<Option<Paint>>,
|
pub fill: Smart<Option<Paint>>,
|
||||||
pub numbering: Option<Numbering>,
|
pub numbering: Option<Numbering>,
|
||||||
|
pub supplement: Content,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Layout a single page suitable for parity adjustment.
|
/// Layout a single page suitable for parity adjustment.
|
||||||
@ -128,6 +129,10 @@ fn layout_page_run_impl(
|
|||||||
let header_ascent = PageElem::header_ascent_in(styles).relative_to(margin.top);
|
let header_ascent = PageElem::header_ascent_in(styles).relative_to(margin.top);
|
||||||
let footer_descent = PageElem::footer_descent_in(styles).relative_to(margin.bottom);
|
let footer_descent = PageElem::footer_descent_in(styles).relative_to(margin.bottom);
|
||||||
let numbering = PageElem::numbering_in(styles);
|
let numbering = PageElem::numbering_in(styles);
|
||||||
|
let supplement = match PageElem::supplement_in(styles) {
|
||||||
|
Smart::Auto => TextElem::packed(PageElem::local_name_in(styles)),
|
||||||
|
Smart::Custom(content) => content.unwrap_or_default(),
|
||||||
|
};
|
||||||
let number_align = PageElem::number_align_in(styles);
|
let number_align = PageElem::number_align_in(styles);
|
||||||
let binding =
|
let binding =
|
||||||
PageElem::binding_in(styles).unwrap_or_else(|| match TextElem::dir_in(styles) {
|
PageElem::binding_in(styles).unwrap_or_else(|| match TextElem::dir_in(styles) {
|
||||||
@ -204,6 +209,7 @@ fn layout_page_run_impl(
|
|||||||
inner,
|
inner,
|
||||||
fill: fill.clone(),
|
fill: fill.clone(),
|
||||||
numbering: numbering.clone(),
|
numbering: numbering.clone(),
|
||||||
|
supplement: supplement.clone(),
|
||||||
header: layout_marginal(header, header_size, Alignment::BOTTOM)?,
|
header: layout_marginal(header, header_size, Alignment::BOTTOM)?,
|
||||||
footer: layout_marginal(footer, footer_size, Alignment::TOP)?,
|
footer: layout_marginal(footer, footer_size, Alignment::TOP)?,
|
||||||
background: layout_marginal(background, full_size, mid)?,
|
background: layout_marginal(background, full_size, mid)?,
|
||||||
|
@ -21,6 +21,8 @@ pub struct Introspector {
|
|||||||
pages: usize,
|
pages: usize,
|
||||||
/// The page numberings, indexed by page number minus 1.
|
/// The page numberings, indexed by page number minus 1.
|
||||||
page_numberings: Vec<Option<Numbering>>,
|
page_numberings: Vec<Option<Numbering>>,
|
||||||
|
/// The page supplements, indexed by page number minus 1.
|
||||||
|
page_supplements: Vec<Content>,
|
||||||
|
|
||||||
/// All introspectable elements.
|
/// All introspectable elements.
|
||||||
elems: Vec<Pair>,
|
elems: Vec<Pair>,
|
||||||
@ -266,6 +268,12 @@ impl Introspector {
|
|||||||
.and_then(|slot| slot.as_ref())
|
.and_then(|slot| slot.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the page supplement for the given location, if any.
|
||||||
|
pub fn page_supplement(&self, location: Location) -> Content {
|
||||||
|
let page = self.page(location);
|
||||||
|
self.page_supplements.get(page.get() - 1).cloned().unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
/// Try to find a location for an element with the given `key` hash
|
/// Try to find a location for an element with the given `key` hash
|
||||||
/// that is closest after the `anchor`.
|
/// that is closest after the `anchor`.
|
||||||
///
|
///
|
||||||
@ -339,6 +347,7 @@ impl Clone for QueryCache {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct IntrospectorBuilder {
|
struct IntrospectorBuilder {
|
||||||
page_numberings: Vec<Option<Numbering>>,
|
page_numberings: Vec<Option<Numbering>>,
|
||||||
|
page_supplements: Vec<Content>,
|
||||||
seen: HashSet<Location>,
|
seen: HashSet<Location>,
|
||||||
insertions: MultiMap<Location, Vec<Pair>>,
|
insertions: MultiMap<Location, Vec<Pair>>,
|
||||||
keys: MultiMap<u128, Location>,
|
keys: MultiMap<u128, Location>,
|
||||||
@ -355,11 +364,13 @@ impl IntrospectorBuilder {
|
|||||||
/// Build the introspector.
|
/// Build the introspector.
|
||||||
fn build(mut self, pages: &[Page]) -> Introspector {
|
fn build(mut self, pages: &[Page]) -> Introspector {
|
||||||
self.page_numberings.reserve(pages.len());
|
self.page_numberings.reserve(pages.len());
|
||||||
|
self.page_supplements.reserve(pages.len());
|
||||||
|
|
||||||
// Discover all elements.
|
// Discover all elements.
|
||||||
let mut root = Vec::new();
|
let mut root = Vec::new();
|
||||||
for (i, page) in pages.iter().enumerate() {
|
for (i, page) in pages.iter().enumerate() {
|
||||||
self.page_numberings.push(page.numbering.clone());
|
self.page_numberings.push(page.numbering.clone());
|
||||||
|
self.page_supplements.push(page.supplement.clone());
|
||||||
self.discover(
|
self.discover(
|
||||||
&mut root,
|
&mut root,
|
||||||
&page.frame,
|
&page.frame,
|
||||||
@ -379,6 +390,7 @@ impl IntrospectorBuilder {
|
|||||||
Introspector {
|
Introspector {
|
||||||
pages: pages.len(),
|
pages: pages.len(),
|
||||||
page_numberings: self.page_numberings,
|
page_numberings: self.page_numberings,
|
||||||
|
page_supplements: self.page_supplements,
|
||||||
elems,
|
elems,
|
||||||
keys: self.keys,
|
keys: self.keys,
|
||||||
locations: self.locations,
|
locations: self.locations,
|
||||||
|
@ -17,6 +17,7 @@ use crate::layout::{
|
|||||||
Sides, SpecificAlignment,
|
Sides, SpecificAlignment,
|
||||||
};
|
};
|
||||||
use crate::model::Numbering;
|
use crate::model::Numbering;
|
||||||
|
use crate::text::LocalName;
|
||||||
use crate::visualize::{Color, Paint};
|
use crate::visualize::{Color, Paint};
|
||||||
|
|
||||||
/// Layouts its child onto one or multiple pages.
|
/// Layouts its child onto one or multiple pages.
|
||||||
@ -222,6 +223,19 @@ pub struct PageElem {
|
|||||||
#[ghost]
|
#[ghost]
|
||||||
pub numbering: Option<Numbering>,
|
pub numbering: Option<Numbering>,
|
||||||
|
|
||||||
|
/// A supplement for the pages.
|
||||||
|
///
|
||||||
|
/// For page references, this is added before the page number.
|
||||||
|
///
|
||||||
|
/// ```example
|
||||||
|
/// #set page(numbering: "1.", supplement: [p.])
|
||||||
|
///
|
||||||
|
/// = Introduction <intro>
|
||||||
|
/// We are on #ref(<intro>, form: "page")!
|
||||||
|
/// ```
|
||||||
|
#[ghost]
|
||||||
|
pub supplement: Smart<Option<Content>>,
|
||||||
|
|
||||||
/// The alignment of the page numbering.
|
/// The alignment of the page numbering.
|
||||||
///
|
///
|
||||||
/// If the vertical component is `top`, the numbering is placed into the
|
/// If the vertical component is `top`, the numbering is placed into the
|
||||||
@ -376,6 +390,10 @@ impl Construct for PageElem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LocalName for PageElem {
|
||||||
|
const KEY: &'static str = "page";
|
||||||
|
}
|
||||||
|
|
||||||
/// A manual page break.
|
/// A manual page break.
|
||||||
///
|
///
|
||||||
/// Must not be used inside any containers.
|
/// Must not be used inside any containers.
|
||||||
@ -449,6 +467,8 @@ pub struct Page {
|
|||||||
pub fill: Smart<Option<Paint>>,
|
pub fill: Smart<Option<Paint>>,
|
||||||
/// The page's numbering.
|
/// The page's numbering.
|
||||||
pub numbering: Option<Numbering>,
|
pub numbering: Option<Numbering>,
|
||||||
|
/// The page's supplement.
|
||||||
|
pub supplement: Content,
|
||||||
/// The logical page number (controlled by `counter(page)` and may thus not
|
/// The logical page number (controlled by `counter(page)` and may thus not
|
||||||
/// match the physical number).
|
/// match the physical number).
|
||||||
pub number: usize,
|
pub number: usize,
|
||||||
|
@ -4,10 +4,10 @@ use ecow::eco_format;
|
|||||||
use crate::diag::{bail, At, Hint, SourceResult};
|
use crate::diag::{bail, At, Hint, SourceResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
cast, elem, Content, Context, Func, IntoValue, Label, NativeElement, Packed, Show,
|
cast, elem, Cast, Content, Context, Func, IntoValue, Label, NativeElement, Packed,
|
||||||
Smart, StyleChain, Synthesize,
|
Show, Smart, StyleChain, Synthesize,
|
||||||
};
|
};
|
||||||
use crate::introspection::{Counter, Locatable};
|
use crate::introspection::{Counter, CounterKey, Locatable};
|
||||||
use crate::math::EquationElem;
|
use crate::math::EquationElem;
|
||||||
use crate::model::{
|
use crate::model::{
|
||||||
BibliographyElem, CiteElem, Destination, Figurable, FootnoteElem, Numbering,
|
BibliographyElem, CiteElem, Destination, Figurable, FootnoteElem, Numbering,
|
||||||
@ -16,22 +16,35 @@ use crate::text::TextElem;
|
|||||||
|
|
||||||
/// A reference to a label or bibliography.
|
/// A reference to a label or bibliography.
|
||||||
///
|
///
|
||||||
/// Produces a textual reference to a label. For example, a reference to a
|
/// Takes a label and cross-references it. There are two kind of references,
|
||||||
/// heading will yield an appropriate string such as "Section 1" for a reference
|
/// determined by its [`form`]($ref.form): `{"normal"}` and `{"page"}`.
|
||||||
/// to the first heading. The references are also links to the respective
|
|
||||||
/// element. Reference syntax can also be used to [cite] from a bibliography.
|
|
||||||
///
|
///
|
||||||
/// Referenceable elements include [headings]($heading), [figures]($figure),
|
/// The default, a `{"normal"}` reference, produces a textual reference to a
|
||||||
/// [equations]($math.equation), and [footnotes]($footnote). To create a custom
|
/// label. For example, a reference to a heading will yield an appropriate
|
||||||
/// referenceable element like a theorem, you can create a figure of a custom
|
/// string such as "Section 1" for a reference to the first heading. The
|
||||||
/// [`kind`]($figure.kind) and write a show rule for it. In the future, there
|
/// references are also links to the respective element. Reference syntax can
|
||||||
/// might be a more direct way to define a custom referenceable element.
|
/// also be used to [cite] from a bibliography.
|
||||||
|
///
|
||||||
|
/// As the default form requires a supplement and numbering, the label must be
|
||||||
|
/// attached to a _referenceable element_. Referenceable elements include
|
||||||
|
/// [headings]($heading), [figures]($figure), [equations]($math.equation), and
|
||||||
|
/// [footnotes]($footnote). To create a custom referenceable element like a
|
||||||
|
/// theorem, you can create a figure of a custom [`kind`]($figure.kind) and
|
||||||
|
/// write a show rule for it. In the future, there might be a more direct way
|
||||||
|
/// to define a custom referenceable element.
|
||||||
///
|
///
|
||||||
/// If you just want to link to a labelled element and not get an automatic
|
/// If you just want to link to a labelled element and not get an automatic
|
||||||
/// textual reference, consider using the [`link`] function instead.
|
/// textual reference, consider using the [`link`] function instead.
|
||||||
///
|
///
|
||||||
|
/// A `{"page"}` reference produces a page reference to a label, displaying the
|
||||||
|
/// page number at its location. You can use the
|
||||||
|
/// [page's supplement]($page.supplement) to modify the text before the page
|
||||||
|
/// number. Unlike a `{"normal"}` reference, the label can be attached to any
|
||||||
|
/// element.
|
||||||
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```example
|
/// ```example
|
||||||
|
/// #set page(numbering: "1")
|
||||||
/// #set heading(numbering: "1.")
|
/// #set heading(numbering: "1.")
|
||||||
/// #set math.equation(numbering: "(1)")
|
/// #set math.equation(numbering: "(1)")
|
||||||
///
|
///
|
||||||
@ -40,7 +53,9 @@ use crate::text::TextElem;
|
|||||||
/// typesetting software have
|
/// typesetting software have
|
||||||
/// rekindled hope in previously
|
/// rekindled hope in previously
|
||||||
/// frustrated researchers. @distress
|
/// frustrated researchers. @distress
|
||||||
/// As shown in @results, we ...
|
/// As shown in @results (see
|
||||||
|
/// #ref(<results>, form: "page")),
|
||||||
|
/// we ...
|
||||||
///
|
///
|
||||||
/// = Results <results>
|
/// = Results <results>
|
||||||
/// We discuss our approach in
|
/// We discuss our approach in
|
||||||
@ -55,9 +70,9 @@ use crate::text::TextElem;
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Syntax
|
/// # Syntax
|
||||||
/// This function also has dedicated syntax: A reference to a label can be
|
/// This function also has dedicated syntax: A `{"normal"}` reference to a
|
||||||
/// created by typing an `@` followed by the name of the label (e.g.
|
/// label can be created by typing an `@` followed by the name of the label
|
||||||
/// `[= Introduction <intro>]` can be referenced by typing `[@intro]`).
|
/// (e.g. `[= Introduction <intro>]` can be referenced by typing `[@intro]`).
|
||||||
///
|
///
|
||||||
/// To customize the supplement, add content in square brackets after the
|
/// To customize the supplement, add content in square brackets after the
|
||||||
/// reference: `[@intro[Chapter]]`.
|
/// reference: `[@intro[Chapter]]`.
|
||||||
@ -95,22 +110,30 @@ use crate::text::TextElem;
|
|||||||
pub struct RefElem {
|
pub struct RefElem {
|
||||||
/// The target label that should be referenced.
|
/// The target label that should be referenced.
|
||||||
///
|
///
|
||||||
/// Can be a label that is defined in the document or an entry from the
|
/// Can be a label that is defined in the document or, if the
|
||||||
|
/// [`form`]($ref.form) is set to `["normal"]`, an entry from the
|
||||||
/// [`bibliography`].
|
/// [`bibliography`].
|
||||||
#[required]
|
#[required]
|
||||||
pub target: Label,
|
pub target: Label,
|
||||||
|
|
||||||
/// A supplement for the reference.
|
/// A supplement for the reference.
|
||||||
///
|
///
|
||||||
/// For references to headings or figures, this is added before the
|
/// If the [`form`]($ref.form) is set to `{"normal"}`:
|
||||||
/// referenced number. For citations, this can be used to add a page number.
|
/// - For references to headings or figures, this is added before the
|
||||||
|
/// referenced number.
|
||||||
|
/// - For citations, this can be used to add a page number.
|
||||||
|
///
|
||||||
|
/// If the [`form`]($ref.form) is set to `{"page"}`, then this is added
|
||||||
|
/// before the page number of the label referenced.
|
||||||
///
|
///
|
||||||
/// If a function is specified, it is passed the referenced element and
|
/// If a function is specified, it is passed the referenced element and
|
||||||
/// should return content.
|
/// should return content.
|
||||||
///
|
///
|
||||||
/// ```example
|
/// ```example
|
||||||
/// #set heading(numbering: "1.")
|
/// #set heading(numbering: "1.")
|
||||||
/// #set ref(supplement: it => {
|
/// #show ref.where(
|
||||||
|
/// form: "normal"
|
||||||
|
/// ): set ref(supplement: it => {
|
||||||
/// if it.func() == heading {
|
/// if it.func() == heading {
|
||||||
/// "Chapter"
|
/// "Chapter"
|
||||||
/// } else {
|
/// } else {
|
||||||
@ -127,6 +150,17 @@ pub struct RefElem {
|
|||||||
#[borrowed]
|
#[borrowed]
|
||||||
pub supplement: Smart<Option<Supplement>>,
|
pub supplement: Smart<Option<Supplement>>,
|
||||||
|
|
||||||
|
/// The kind of reference to produce.
|
||||||
|
///
|
||||||
|
/// ```example
|
||||||
|
/// #set page(numbering: "1")
|
||||||
|
///
|
||||||
|
/// Here <here> we are on
|
||||||
|
/// #ref(<here>, form: "page").
|
||||||
|
/// ```
|
||||||
|
#[default(RefForm::Normal)]
|
||||||
|
pub form: RefForm,
|
||||||
|
|
||||||
/// A synthesized citation.
|
/// A synthesized citation.
|
||||||
#[synthesized]
|
#[synthesized]
|
||||||
pub citation: Option<Packed<CiteElem>>,
|
pub citation: Option<Packed<CiteElem>>,
|
||||||
@ -167,6 +201,34 @@ impl Show for Packed<RefElem> {
|
|||||||
let elem = engine.introspector.query_label(target);
|
let elem = engine.introspector.query_label(target);
|
||||||
let span = self.span();
|
let span = self.span();
|
||||||
|
|
||||||
|
let form = self.form(styles);
|
||||||
|
if form == RefForm::Page {
|
||||||
|
let elem = elem.at(span)?;
|
||||||
|
let elem = elem.clone();
|
||||||
|
|
||||||
|
let loc = elem.location().unwrap();
|
||||||
|
let numbering = engine
|
||||||
|
.introspector
|
||||||
|
.page_numbering(loc)
|
||||||
|
.ok_or_else(|| eco_format!("cannot reference without page numbering"))
|
||||||
|
.hint(eco_format!(
|
||||||
|
"you can enable page numbering with `#set page(numbering: \"1\")`"
|
||||||
|
))
|
||||||
|
.at(span)?;
|
||||||
|
let supplement = engine.introspector.page_supplement(loc);
|
||||||
|
|
||||||
|
return show_reference(
|
||||||
|
self,
|
||||||
|
engine,
|
||||||
|
styles,
|
||||||
|
Counter::new(CounterKey::Page),
|
||||||
|
numbering.clone(),
|
||||||
|
supplement,
|
||||||
|
elem,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// RefForm::Normal
|
||||||
|
|
||||||
if BibliographyElem::has(engine, target) {
|
if BibliographyElem::has(engine, target) {
|
||||||
if elem.is_ok() {
|
if elem.is_ok() {
|
||||||
bail!(span, "label occurs in the document and its bibliography");
|
bail!(span, "label occurs in the document and its bibliography");
|
||||||
@ -212,31 +274,45 @@ impl Show for Packed<RefElem> {
|
|||||||
))
|
))
|
||||||
.at(span)?;
|
.at(span)?;
|
||||||
|
|
||||||
let loc = elem.location().unwrap();
|
show_reference(
|
||||||
let numbers = refable.counter().display_at_loc(
|
self,
|
||||||
engine,
|
engine,
|
||||||
loc,
|
|
||||||
styles,
|
styles,
|
||||||
&numbering.clone().trimmed(),
|
refable.counter(),
|
||||||
)?;
|
numbering.clone(),
|
||||||
|
refable.supplement(),
|
||||||
let supplement = match self.supplement(styles).as_ref() {
|
elem,
|
||||||
Smart::Auto => refable.supplement(),
|
)
|
||||||
Smart::Custom(None) => Content::empty(),
|
|
||||||
Smart::Custom(Some(supplement)) => {
|
|
||||||
supplement.resolve(engine, styles, [elem])?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut content = numbers;
|
|
||||||
if !supplement.is_empty() {
|
|
||||||
content = supplement + TextElem::packed("\u{a0}") + content;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(content.linked(Destination::Location(loc)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Show a reference.
|
||||||
|
fn show_reference(
|
||||||
|
reference: &Packed<RefElem>,
|
||||||
|
engine: &mut Engine,
|
||||||
|
styles: StyleChain,
|
||||||
|
counter: Counter,
|
||||||
|
numbering: Numbering,
|
||||||
|
supplement: Content,
|
||||||
|
elem: Content,
|
||||||
|
) -> SourceResult<Content> {
|
||||||
|
let loc = elem.location().unwrap();
|
||||||
|
let numbers = counter.display_at_loc(engine, loc, styles, &numbering.trimmed())?;
|
||||||
|
|
||||||
|
let supplement = match reference.supplement(styles).as_ref() {
|
||||||
|
Smart::Auto => supplement,
|
||||||
|
Smart::Custom(None) => Content::empty(),
|
||||||
|
Smart::Custom(Some(supplement)) => supplement.resolve(engine, styles, [elem])?,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut content = numbers;
|
||||||
|
if !supplement.is_empty() {
|
||||||
|
content = supplement + TextElem::packed("\u{a0}") + content;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(content.linked(Destination::Location(loc)))
|
||||||
|
}
|
||||||
|
|
||||||
/// Turn a reference into a citation.
|
/// Turn a reference into a citation.
|
||||||
fn to_citation(
|
fn to_citation(
|
||||||
reference: &Packed<RefElem>,
|
reference: &Packed<RefElem>,
|
||||||
@ -293,6 +369,16 @@ cast! {
|
|||||||
v: Func => Self::Func(v),
|
v: Func => Self::Func(v),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The form of the reference.
|
||||||
|
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash, Cast)]
|
||||||
|
pub enum RefForm {
|
||||||
|
/// Produces a textual reference to a label.
|
||||||
|
#[default]
|
||||||
|
Normal,
|
||||||
|
/// Produces a page reference to a label.
|
||||||
|
Page,
|
||||||
|
}
|
||||||
|
|
||||||
/// Marks an element as being able to be referenced. This is used to implement
|
/// Marks an element as being able to be referenced. This is used to implement
|
||||||
/// the `@ref` element.
|
/// the `@ref` element.
|
||||||
pub trait Refable {
|
pub trait Refable {
|
||||||
|
@ -5,3 +5,4 @@ bibliography = المراجع
|
|||||||
heading = الفصل
|
heading = الفصل
|
||||||
outline = المحتويات
|
outline = المحتويات
|
||||||
raw = قائمة
|
raw = قائمة
|
||||||
|
page = صفحة
|
@ -5,3 +5,4 @@ bibliography = Bibliografia
|
|||||||
heading = Secció
|
heading = Secció
|
||||||
outline = Índex
|
outline = Índex
|
||||||
raw = Llistat
|
raw = Llistat
|
||||||
|
page = pàgina
|
@ -5,3 +5,4 @@ bibliography = Bibliografie
|
|||||||
heading = Kapitola
|
heading = Kapitola
|
||||||
outline = Obsah
|
outline = Obsah
|
||||||
raw = Seznam
|
raw = Seznam
|
||||||
|
page = strana
|
@ -5,3 +5,4 @@ bibliography = Bibliografi
|
|||||||
heading = Afsnit
|
heading = Afsnit
|
||||||
outline = Indhold
|
outline = Indhold
|
||||||
raw = Liste
|
raw = Liste
|
||||||
|
page = side
|
@ -5,3 +5,4 @@ bibliography = Bibliographie
|
|||||||
heading = Abschnitt
|
heading = Abschnitt
|
||||||
outline = Inhaltsverzeichnis
|
outline = Inhaltsverzeichnis
|
||||||
raw = Listing
|
raw = Listing
|
||||||
|
page = Seite
|
@ -5,3 +5,4 @@ bibliography = Bibliography
|
|||||||
heading = Section
|
heading = Section
|
||||||
outline = Contents
|
outline = Contents
|
||||||
raw = Listing
|
raw = Listing
|
||||||
|
page = page
|
@ -5,3 +5,4 @@ bibliography = Bibliografía
|
|||||||
heading = Sección
|
heading = Sección
|
||||||
outline = Índice
|
outline = Índice
|
||||||
raw = Listado
|
raw = Listado
|
||||||
|
page = página
|
@ -5,3 +5,4 @@ bibliography = Viited
|
|||||||
heading = Peatükk
|
heading = Peatükk
|
||||||
outline = Sisukord
|
outline = Sisukord
|
||||||
raw = List
|
raw = List
|
||||||
|
page = lk.
|
@ -5,3 +5,4 @@ bibliography = Viitteet
|
|||||||
heading = Osio
|
heading = Osio
|
||||||
outline = Sisällys
|
outline = Sisällys
|
||||||
raw = Esimerkki
|
raw = Esimerkki
|
||||||
|
page = sivu
|
@ -5,3 +5,4 @@ bibliography = Bibliographie
|
|||||||
heading = Chapitre
|
heading = Chapitre
|
||||||
outline = Table des matières
|
outline = Table des matières
|
||||||
raw = Liste
|
raw = Liste
|
||||||
|
page = page
|
@ -5,3 +5,4 @@ bibliography = Bibliografía
|
|||||||
heading = Sección
|
heading = Sección
|
||||||
outline = Índice
|
outline = Índice
|
||||||
raw = Listado
|
raw = Listado
|
||||||
|
page = páxina
|
@ -5,3 +5,4 @@ bibliography = רשימת מקורות
|
|||||||
heading = חלק
|
heading = חלק
|
||||||
outline = תוכן עניינים
|
outline = תוכן עניינים
|
||||||
raw = קטע מקור
|
raw = קטע מקור
|
||||||
|
page = עמוד
|
@ -5,3 +5,4 @@ bibliography = Irodalomjegyzék
|
|||||||
heading = Fejezet
|
heading = Fejezet
|
||||||
outline = Tartalomjegyzék
|
outline = Tartalomjegyzék
|
||||||
# raw =
|
# raw =
|
||||||
|
page = oldal
|
@ -5,3 +5,4 @@ bibliography = Heimildaskrá
|
|||||||
heading = Kafli
|
heading = Kafli
|
||||||
outline = Efnisyfirlit
|
outline = Efnisyfirlit
|
||||||
raw = Sýnishorn
|
raw = Sýnishorn
|
||||||
|
page = blaðsíða
|
@ -5,3 +5,4 @@ bibliography = Bibliografia
|
|||||||
heading = Sezione
|
heading = Sezione
|
||||||
outline = Indice
|
outline = Indice
|
||||||
raw = Codice
|
raw = Codice
|
||||||
|
page = pag.
|
@ -5,3 +5,4 @@ bibliography = 参考文献
|
|||||||
heading = 節
|
heading = 節
|
||||||
outline = 目次
|
outline = 目次
|
||||||
raw = リスト
|
raw = リスト
|
||||||
|
page = ページ
|
@ -5,3 +5,4 @@ bibliography = Conspectus librorum
|
|||||||
heading = Caput
|
heading = Caput
|
||||||
outline = Index capitum
|
outline = Index capitum
|
||||||
raw = Exemplum
|
raw = Exemplum
|
||||||
|
page = charta
|
@ -5,3 +5,4 @@ bibliography = Bibliografi
|
|||||||
heading = Kapittel
|
heading = Kapittel
|
||||||
outline = Innhold
|
outline = Innhold
|
||||||
raw = Utskrift
|
raw = Utskrift
|
||||||
|
page = side
|
@ -5,3 +5,4 @@ bibliography = Bibliografie
|
|||||||
heading = Hoofdstuk
|
heading = Hoofdstuk
|
||||||
outline = Inhoudsopgave
|
outline = Inhoudsopgave
|
||||||
raw = Listing
|
raw = Listing
|
||||||
|
page = pagina
|
@ -5,3 +5,4 @@ bibliography = Bibliografi
|
|||||||
heading = Kapittel
|
heading = Kapittel
|
||||||
outline = Innhald
|
outline = Innhald
|
||||||
raw = Utskrift
|
raw = Utskrift
|
||||||
|
page = side
|
@ -5,3 +5,4 @@ bibliography = Bibliografia
|
|||||||
heading = Sekcja
|
heading = Sekcja
|
||||||
outline = Spis treści
|
outline = Spis treści
|
||||||
raw = Program
|
raw = Program
|
||||||
|
page = strona
|
@ -5,3 +5,4 @@
|
|||||||
heading = Secção
|
heading = Secção
|
||||||
outline = Índice
|
outline = Índice
|
||||||
# raw =
|
# raw =
|
||||||
|
page = página
|
@ -5,3 +5,4 @@ bibliography = Bibliografia
|
|||||||
heading = Seção
|
heading = Seção
|
||||||
outline = Sumário
|
outline = Sumário
|
||||||
raw = Listagem
|
raw = Listagem
|
||||||
|
page = página
|
@ -6,3 +6,4 @@ heading = Secțiunea
|
|||||||
outline = Cuprins
|
outline = Cuprins
|
||||||
# may be wrong
|
# may be wrong
|
||||||
raw = Listă
|
raw = Listă
|
||||||
|
page = pagina
|
@ -5,3 +5,4 @@ bibliography = Библиография
|
|||||||
heading = Раздел
|
heading = Раздел
|
||||||
outline = Содержание
|
outline = Содержание
|
||||||
raw = Листинг
|
raw = Листинг
|
||||||
|
page = с.
|
@ -5,3 +5,4 @@ bibliography = Literatura
|
|||||||
heading = Poglavje
|
heading = Poglavje
|
||||||
outline = Kazalo
|
outline = Kazalo
|
||||||
raw = Program
|
raw = Program
|
||||||
|
page = stran
|
@ -5,3 +5,4 @@ bibliography = Bibliografi
|
|||||||
heading = Kapitull
|
heading = Kapitull
|
||||||
outline = Përmbajtja
|
outline = Përmbajtja
|
||||||
raw = List
|
raw = List
|
||||||
|
page = faqe
|
@ -5,3 +5,4 @@ bibliography = Литература
|
|||||||
heading = Поглавље
|
heading = Поглавље
|
||||||
outline = Садржај
|
outline = Садржај
|
||||||
raw = Програм
|
raw = Програм
|
||||||
|
page = страна
|
@ -5,3 +5,4 @@ bibliography = Bibliografi
|
|||||||
heading = Kapitel
|
heading = Kapitel
|
||||||
outline = Innehåll
|
outline = Innehåll
|
||||||
raw = Listing
|
raw = Listing
|
||||||
|
page = sida
|
@ -5,3 +5,4 @@ bibliography = Bibliograpiya
|
|||||||
heading = Seksyon
|
heading = Seksyon
|
||||||
outline = Talaan ng mga Nilalaman
|
outline = Talaan ng mga Nilalaman
|
||||||
raw = Listahan
|
raw = Listahan
|
||||||
|
# page =
|
@ -5,3 +5,4 @@ bibliography = Kaynakça
|
|||||||
heading = Bölüm
|
heading = Bölüm
|
||||||
outline = İçindekiler
|
outline = İçindekiler
|
||||||
raw = Liste
|
raw = Liste
|
||||||
|
page = sayfa
|
@ -5,3 +5,4 @@ bibliography = Бібліографія
|
|||||||
heading = Розділ
|
heading = Розділ
|
||||||
outline = Зміст
|
outline = Зміст
|
||||||
raw = Лістинг
|
raw = Лістинг
|
||||||
|
page = c.
|
@ -6,3 +6,4 @@ heading = Phần
|
|||||||
outline = Mục lục
|
outline = Mục lục
|
||||||
# may be wrong
|
# may be wrong
|
||||||
raw = Chương trình
|
raw = Chương trình
|
||||||
|
page = trang
|
@ -5,3 +5,4 @@ bibliography = 書目
|
|||||||
heading = 小節
|
heading = 小節
|
||||||
outline = 目錄
|
outline = 目錄
|
||||||
raw = 程式
|
raw = 程式
|
||||||
|
# page =
|
@ -5,3 +5,4 @@ bibliography = 参考文献
|
|||||||
heading = 小节
|
heading = 小节
|
||||||
outline = 目录
|
outline = 目录
|
||||||
raw = 代码
|
raw = 代码
|
||||||
|
# page =
|
@ -433,7 +433,7 @@ frequently used for [figures]($figure.placement).
|
|||||||
### Use columns anywhere in your document { #columns-anywhere }
|
### Use columns anywhere in your document { #columns-anywhere }
|
||||||
To create columns within a nested layout, e.g. within a rectangle, you can use
|
To create columns within a nested layout, e.g. within a rectangle, you can use
|
||||||
the [`columns` function]($columns) directly. However, it really should only be
|
the [`columns` function]($columns) directly. However, it really should only be
|
||||||
used within nested layouts. At the page-level, the page set rule is preferrable
|
used within nested layouts. At the page-level, the page set rule is preferable
|
||||||
because it has better interactions with things like page-level floats,
|
because it has better interactions with things like page-level floats,
|
||||||
footnotes, and line numbers.
|
footnotes, and line numbers.
|
||||||
|
|
||||||
|
BIN
tests/ref/ref-form-page-unambiguous.png
Normal file
BIN
tests/ref/ref-form-page-unambiguous.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
tests/ref/ref-form-page.png
Normal file
BIN
tests/ref/ref-form-page.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
@ -230,6 +230,13 @@ Z
|
|||||||
#counter(page).update(53)
|
#counter(page).update(53)
|
||||||
#filler
|
#filler
|
||||||
|
|
||||||
|
--- page-numbering-hint ---
|
||||||
|
= Heading <intro>
|
||||||
|
|
||||||
|
// Error: 1:21-1:47 cannot reference without page numbering
|
||||||
|
// Hint: 1:21-1:47 you can enable page numbering with `#set page(numbering: "1")`
|
||||||
|
Can not be used as #ref(<intro>, form: "page")
|
||||||
|
|
||||||
--- page-suppress-headers-and-footers ---
|
--- page-suppress-headers-and-footers ---
|
||||||
#set page(header: none, footer: none, numbering: "1")
|
#set page(header: none, footer: none, numbering: "1")
|
||||||
Look, ma, no page numbers!
|
Look, ma, no page numbers!
|
||||||
|
@ -55,6 +55,32 @@ $ A = 1 $ <eq2>
|
|||||||
@arrgh
|
@arrgh
|
||||||
#bibliography("/assets/bib/works.bib")
|
#bibliography("/assets/bib/works.bib")
|
||||||
|
|
||||||
|
--- ref-form-page ---
|
||||||
|
#set page(numbering: "1")
|
||||||
|
|
||||||
|
Text <text> is on #ref(<text>, form: "page").
|
||||||
|
See #ref(<setup>, form: "page").
|
||||||
|
|
||||||
|
#set page(supplement: [p.])
|
||||||
|
|
||||||
|
== Setup <setup>
|
||||||
|
Text seen on #ref(<text>, form: "page").
|
||||||
|
Text seen on #ref(<text>, form: "page", supplement: "Page").
|
||||||
|
|
||||||
|
--- ref-form-page-unambiguous ---
|
||||||
|
// Test that page reference is not ambiguous.
|
||||||
|
#set page(numbering: "1")
|
||||||
|
|
||||||
|
= Introduction <arrgh>
|
||||||
|
|
||||||
|
#ref(<arrgh>, form: "page")
|
||||||
|
#bibliography("/assets/bib/works.bib")
|
||||||
|
|
||||||
|
--- ref-form-page-bibliography ---
|
||||||
|
// Error: 2-28 label `<quark>` does not exist in the document
|
||||||
|
#ref(<quark>, form: "page")
|
||||||
|
#bibliography("/assets/bib/works.bib")
|
||||||
|
|
||||||
--- issue-4536-non-whitespace-before-ref ---
|
--- issue-4536-non-whitespace-before-ref ---
|
||||||
// Test reference with non-whitespace before it.
|
// Test reference with non-whitespace before it.
|
||||||
#figure[] <1>
|
#figure[] <1>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user