mirror of
https://github.com/typst/typst
synced 2025-08-23 19:24:14 +08:00
Merge bea97e1f8b3e20bb5ffd82780eea09c0f4c7d4dc into 82da96ed957a68017e092e2606226b45c34324f1
This commit is contained in:
commit
c747c2f9db
@ -142,12 +142,10 @@ pub struct BibliographyElem {
|
|||||||
pub style: Derived<CslSource, CslStyle>,
|
pub style: Derived<CslSource, CslStyle>,
|
||||||
|
|
||||||
/// The language setting where the bibliography is.
|
/// The language setting where the bibliography is.
|
||||||
#[internal]
|
|
||||||
#[synthesized]
|
#[synthesized]
|
||||||
pub lang: Lang,
|
pub lang: Lang,
|
||||||
|
|
||||||
/// The region setting where the bibliography is.
|
/// The region setting where the bibliography is.
|
||||||
#[internal]
|
|
||||||
#[synthesized]
|
#[synthesized]
|
||||||
pub region: Option<Region>,
|
pub region: Option<Region>,
|
||||||
}
|
}
|
||||||
|
@ -110,12 +110,10 @@ pub struct CiteElem {
|
|||||||
pub style: Smart<Derived<CslSource, CslStyle>>,
|
pub style: Smart<Derived<CslSource, CslStyle>>,
|
||||||
|
|
||||||
/// The text language setting where the citation is.
|
/// The text language setting where the citation is.
|
||||||
#[internal]
|
|
||||||
#[synthesized]
|
#[synthesized]
|
||||||
pub lang: Lang,
|
pub lang: Lang,
|
||||||
|
|
||||||
/// The text region setting where the citation is.
|
/// The text region setting where the citation is.
|
||||||
#[internal]
|
|
||||||
#[synthesized]
|
#[synthesized]
|
||||||
pub region: Option<Region>,
|
pub region: Option<Region>,
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ use typst_utils::NonZeroExt;
|
|||||||
|
|
||||||
use crate::diag::{bail, SourceResult};
|
use crate::diag::{bail, SourceResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
|
use crate::foundations::func;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
cast, elem, scope, select_where, Content, Element, NativeElement, Packed, Selector,
|
cast, elem, scope, select_where, Content, Element, NativeElement, Packed, Selector,
|
||||||
Show, ShowSet, Smart, StyleChain, Styles, Synthesize, TargetElem,
|
Show, ShowSet, Smart, StyleChain, Styles, Synthesize, TargetElem,
|
||||||
@ -241,7 +242,7 @@ pub struct FigureElem {
|
|||||||
/// These are the counters you'll need to modify if you want to skip a
|
/// These are the counters you'll need to modify if you want to skip a
|
||||||
/// number or reset the counter.
|
/// number or reset the counter.
|
||||||
#[synthesized]
|
#[synthesized]
|
||||||
pub counter: Option<Counter>,
|
pub counter: Counter,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[scope]
|
#[scope]
|
||||||
@ -315,15 +316,21 @@ impl Synthesize for Packed<FigureElem> {
|
|||||||
if let Some(caption) = &mut caption {
|
if let Some(caption) = &mut caption {
|
||||||
caption.synthesize(engine, styles)?;
|
caption.synthesize(engine, styles)?;
|
||||||
caption.push_kind(kind.clone());
|
caption.push_kind(kind.clone());
|
||||||
caption.push_supplement(supplement.clone());
|
if let Some(supplement) = supplement.clone() {
|
||||||
caption.push_numbering(numbering.clone());
|
caption.push_supplement(supplement);
|
||||||
caption.push_counter(Some(counter.clone()));
|
}
|
||||||
caption.push_figure_location(location);
|
if let Some(numbering) = numbering.clone() {
|
||||||
|
caption.push_numbering(numbering);
|
||||||
|
}
|
||||||
|
caption.push_counter(counter.clone());
|
||||||
|
if let Some(location) = location {
|
||||||
|
caption.push_figure_location(location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elem.push_kind(Smart::Custom(kind));
|
elem.push_kind(Smart::Custom(kind));
|
||||||
elem.push_supplement(Smart::Custom(supplement.map(Supplement::Content)));
|
elem.push_supplement(Smart::Custom(supplement.map(Supplement::Content)));
|
||||||
elem.push_counter(Some(counter));
|
elem.push_counter(counter);
|
||||||
elem.push_caption(caption);
|
elem.push_caption(caption);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -423,7 +430,6 @@ impl Refable for Packed<FigureElem> {
|
|||||||
(**self)
|
(**self)
|
||||||
.counter()
|
.counter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.flatten()
|
|
||||||
.unwrap_or_else(|| Counter::of(FigureElem::elem()))
|
.unwrap_or_else(|| Counter::of(FigureElem::elem()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,20 +466,24 @@ impl Outlinable for Packed<FigureElem> {
|
|||||||
/// customize the appearance of captions for all figures or figures of a
|
/// customize the appearance of captions for all figures or figures of a
|
||||||
/// specific kind.
|
/// specific kind.
|
||||||
///
|
///
|
||||||
/// In addition to its `position` and `body`, the `caption` also provides the
|
/// In addition to its `position` and `body`, it is possible to retrieve the
|
||||||
/// figure's `kind`, `supplement`, `counter`, and `numbering` as fields. These
|
/// corresponding figure's `kind`, `supplement`, `counter`, and `numbering` by
|
||||||
/// parts can be used in [`where`]($function.where) selectors and show rules to
|
/// using the corresponding methods. These parts can be used in show rules to
|
||||||
/// build a completely custom caption.
|
/// build a completely custom caption.
|
||||||
///
|
///
|
||||||
/// ```example
|
/// ```example
|
||||||
/// #show figure.caption: emph
|
/// #show figure.caption: it => [
|
||||||
|
/// #underline(it.body) |
|
||||||
|
/// #it.supplement()
|
||||||
|
/// #context it.counter().display(it.numbering())
|
||||||
|
/// ]
|
||||||
///
|
///
|
||||||
/// #figure(
|
/// #figure(
|
||||||
/// rect[Hello],
|
/// rect[Hello],
|
||||||
/// caption: [A rectangle],
|
/// caption: [A rectangle],
|
||||||
/// )
|
/// )
|
||||||
/// ```
|
/// ```
|
||||||
#[elem(name = "caption", Synthesize, Show)]
|
#[elem(scope, name = "caption", Synthesize, Show)]
|
||||||
pub struct FigureCaption {
|
pub struct FigureCaption {
|
||||||
/// The caption's position in the figure. Either `{top}` or `{bottom}`.
|
/// The caption's position in the figure. Either `{top}` or `{bottom}`.
|
||||||
///
|
///
|
||||||
@ -519,22 +529,6 @@ pub struct FigureCaption {
|
|||||||
pub separator: Smart<Content>,
|
pub separator: Smart<Content>,
|
||||||
|
|
||||||
/// The caption's body.
|
/// The caption's body.
|
||||||
///
|
|
||||||
/// Can be used alongside `kind`, `supplement`, `counter`, `numbering`, and
|
|
||||||
/// `location` to completely customize the caption.
|
|
||||||
///
|
|
||||||
/// ```example
|
|
||||||
/// #show figure.caption: it => [
|
|
||||||
/// #underline(it.body) |
|
|
||||||
/// #it.supplement
|
|
||||||
/// #context it.counter.display(it.numbering)
|
|
||||||
/// ]
|
|
||||||
///
|
|
||||||
/// #figure(
|
|
||||||
/// rect[Hello],
|
|
||||||
/// caption: [A rectangle],
|
|
||||||
/// )
|
|
||||||
/// ```
|
|
||||||
#[required]
|
#[required]
|
||||||
pub body: Content,
|
pub body: Content,
|
||||||
|
|
||||||
@ -544,20 +538,71 @@ pub struct FigureCaption {
|
|||||||
|
|
||||||
/// The figure's supplement.
|
/// The figure's supplement.
|
||||||
#[synthesized]
|
#[synthesized]
|
||||||
pub supplement: Option<Content>,
|
pub supplement: Content,
|
||||||
|
|
||||||
/// How to number the figure.
|
/// How to number the figure.
|
||||||
#[synthesized]
|
#[synthesized]
|
||||||
pub numbering: Option<Numbering>,
|
pub numbering: Numbering,
|
||||||
|
|
||||||
/// The counter for the figure.
|
/// The counter for the figure.
|
||||||
#[synthesized]
|
#[synthesized]
|
||||||
pub counter: Option<Counter>,
|
pub counter: Counter,
|
||||||
|
|
||||||
/// The figure's location.
|
/// The figure's location.
|
||||||
#[internal]
|
|
||||||
#[synthesized]
|
#[synthesized]
|
||||||
pub figure_location: Option<Location>,
|
pub figure_location: Location,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[scope]
|
||||||
|
impl FigureCaption {
|
||||||
|
/// The kind of the corresponding figure.
|
||||||
|
///
|
||||||
|
/// This returns `{none}` in case the corresponding figure does not appear
|
||||||
|
/// in the document.
|
||||||
|
#[func]
|
||||||
|
pub fn kind_(self) -> Option<FigureKind> {
|
||||||
|
self.kind
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The supplement of the corresponding figure.
|
||||||
|
///
|
||||||
|
/// This returns `{none}` in case the corresponding figure does not appear
|
||||||
|
/// in the document.
|
||||||
|
#[func]
|
||||||
|
pub fn supplement_(self) -> Option<Content> {
|
||||||
|
self.supplement
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The numbering of the corresponding figure.
|
||||||
|
///
|
||||||
|
/// This returns `{none}` in case the corresponding figure does not appear
|
||||||
|
/// in the document.
|
||||||
|
#[func]
|
||||||
|
pub fn numbering_(self) -> Option<Numbering> {
|
||||||
|
self.numbering
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The counter for the corresponding figure:
|
||||||
|
/// `{counter(figure.where(kind: kind))}` for a figure of kind `{kind}`.
|
||||||
|
///
|
||||||
|
/// For example, for a table figure, this returns
|
||||||
|
/// `{counter(figure.where(kind: table))}`.
|
||||||
|
///
|
||||||
|
/// This returns `{none}` in case the corresponding figure does not appear
|
||||||
|
/// in the document, or it is not numbered.
|
||||||
|
#[func]
|
||||||
|
pub fn counter_(self) -> Option<Counter> {
|
||||||
|
self.counter
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The location of the corresponding figure.
|
||||||
|
///
|
||||||
|
/// This returns `{none}` in case the corresponding figure does not appear
|
||||||
|
/// in the document.
|
||||||
|
#[func]
|
||||||
|
pub fn figure_location_(self) -> Option<Location> {
|
||||||
|
self.figure_location
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FigureCaption {
|
impl FigureCaption {
|
||||||
@ -595,12 +640,7 @@ impl Show for Packed<FigureCaption> {
|
|||||||
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
||||||
let mut realized = self.body.clone();
|
let mut realized = self.body.clone();
|
||||||
|
|
||||||
if let (
|
if let (Some(mut supplement), Some(numbering), Some(counter), Some(location)) = (
|
||||||
Some(Some(mut supplement)),
|
|
||||||
Some(Some(numbering)),
|
|
||||||
Some(Some(counter)),
|
|
||||||
Some(Some(location)),
|
|
||||||
) = (
|
|
||||||
self.supplement().cloned(),
|
self.supplement().cloned(),
|
||||||
self.numbering(),
|
self.numbering(),
|
||||||
self.counter(),
|
self.counter(),
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use comemo::Track;
|
use comemo::Track;
|
||||||
use ecow::eco_format;
|
use ecow::eco_format;
|
||||||
|
|
||||||
use crate::diag::{bail, At, Hint, SourceResult};
|
use crate::diag::{bail, At, Hint, SourceResult, StrResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
|
use crate::foundations::func;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
cast, elem, Cast, Content, Context, Func, IntoValue, Label, NativeElement, Packed,
|
cast, elem, Cast, Content, Context, Func, IntoValue, Label, NativeElement, Packed,
|
||||||
Show, Smart, StyleChain, Synthesize,
|
Show, Smart, StyleChain, Synthesize,
|
||||||
@ -13,6 +14,7 @@ use crate::model::{
|
|||||||
BibliographyElem, CiteElem, Destination, Figurable, FootnoteElem, Numbering,
|
BibliographyElem, CiteElem, Destination, Figurable, FootnoteElem, Numbering,
|
||||||
};
|
};
|
||||||
use crate::text::TextElem;
|
use crate::text::TextElem;
|
||||||
|
use typst_macros::scope;
|
||||||
|
|
||||||
/// A reference to a label or bibliography.
|
/// A reference to a label or bibliography.
|
||||||
///
|
///
|
||||||
@ -90,7 +92,7 @@ use crate::text::TextElem;
|
|||||||
///
|
///
|
||||||
/// #show ref: it => {
|
/// #show ref: it => {
|
||||||
/// let eq = math.equation
|
/// let eq = math.equation
|
||||||
/// let el = it.element
|
/// let el = it.element()
|
||||||
/// if el != none and el.func() == eq {
|
/// if el != none and el.func() == eq {
|
||||||
/// // Override equation references.
|
/// // Override equation references.
|
||||||
/// link(el.location(),numbering(
|
/// link(el.location(),numbering(
|
||||||
@ -107,7 +109,7 @@ use crate::text::TextElem;
|
|||||||
/// In @beginning we prove @pythagoras.
|
/// In @beginning we prove @pythagoras.
|
||||||
/// $ a^2 + b^2 = c^2 $ <pythagoras>
|
/// $ a^2 + b^2 = c^2 $ <pythagoras>
|
||||||
/// ```
|
/// ```
|
||||||
#[elem(title = "Reference", Synthesize, Locatable, Show)]
|
#[elem(scope, title = "Reference", Locatable, Show)]
|
||||||
pub struct RefElem {
|
pub struct RefElem {
|
||||||
/// The target label that should be referenced.
|
/// The target label that should be referenced.
|
||||||
///
|
///
|
||||||
@ -161,37 +163,6 @@ pub struct RefElem {
|
|||||||
/// ```
|
/// ```
|
||||||
#[default(RefForm::Normal)]
|
#[default(RefForm::Normal)]
|
||||||
pub form: RefForm,
|
pub form: RefForm,
|
||||||
|
|
||||||
/// A synthesized citation.
|
|
||||||
#[synthesized]
|
|
||||||
pub citation: Option<Packed<CiteElem>>,
|
|
||||||
|
|
||||||
/// The referenced element.
|
|
||||||
#[synthesized]
|
|
||||||
pub element: Option<Content>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Synthesize for Packed<RefElem> {
|
|
||||||
fn synthesize(
|
|
||||||
&mut self,
|
|
||||||
engine: &mut Engine,
|
|
||||||
styles: StyleChain,
|
|
||||||
) -> SourceResult<()> {
|
|
||||||
let citation = to_citation(self, engine, styles)?;
|
|
||||||
|
|
||||||
let elem = self.as_mut();
|
|
||||||
elem.push_citation(Some(citation));
|
|
||||||
elem.push_element(None);
|
|
||||||
|
|
||||||
if !BibliographyElem::has(engine, elem.target) {
|
|
||||||
if let Ok(found) = engine.introspector.query_label(elem.target).cloned() {
|
|
||||||
elem.push_element(Some(found));
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Show for Packed<RefElem> {
|
impl Show for Packed<RefElem> {
|
||||||
@ -334,6 +305,25 @@ fn to_citation(
|
|||||||
Ok(elem)
|
Ok(elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[scope]
|
||||||
|
impl RefElem {
|
||||||
|
/// The referenced element.
|
||||||
|
///
|
||||||
|
/// If this is a reference to a bibliography entry, this returns `{none}`.
|
||||||
|
#[func]
|
||||||
|
pub fn element(self, engine: &mut Engine) -> StrResult<Option<Content>> {
|
||||||
|
if BibliographyElem::has(engine, self.target) {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
engine.introspector.query_label(self.target).cloned().map(Some)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cast! {
|
||||||
|
RefElem,
|
||||||
|
v: Content => v.unpack::<Self>().map_err(|_| "expected reference")?
|
||||||
|
}
|
||||||
|
|
||||||
/// Additional content for a reference.
|
/// Additional content for a reference.
|
||||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||||
pub enum Supplement {
|
pub enum Supplement {
|
||||||
|
@ -6,6 +6,7 @@ use comemo::Tracked;
|
|||||||
use ecow::{eco_format, EcoString, EcoVec};
|
use ecow::{eco_format, EcoString, EcoVec};
|
||||||
use syntect::highlighting as synt;
|
use syntect::highlighting as synt;
|
||||||
use syntect::parsing::{SyntaxDefinition, SyntaxSet, SyntaxSetBuilder};
|
use syntect::parsing::{SyntaxDefinition, SyntaxSet, SyntaxSetBuilder};
|
||||||
|
use typst_macros::func;
|
||||||
use typst_syntax::{split_newlines, LinkedNode, Span, Spanned};
|
use typst_syntax::{split_newlines, LinkedNode, Span, Spanned};
|
||||||
use typst_utils::ManuallyHash;
|
use typst_utils::ManuallyHash;
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
@ -14,8 +15,8 @@ use super::Lang;
|
|||||||
use crate::diag::{At, FileError, SourceResult, StrResult};
|
use crate::diag::{At, FileError, SourceResult, StrResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
cast, elem, scope, Bytes, Content, Derived, NativeElement, OneOrMultiple, Packed,
|
cast, elem, scope, Bytes, Content, Context, Derived, NativeElement, OneOrMultiple,
|
||||||
PlainText, Show, ShowSet, Smart, StyleChain, Styles, Synthesize, TargetElem,
|
Packed, PlainText, Show, ShowSet, Smart, StyleChain, Styles, TargetElem,
|
||||||
};
|
};
|
||||||
use crate::html::{tag, HtmlElem};
|
use crate::html::{tag, HtmlElem};
|
||||||
use crate::layout::{BlockBody, BlockElem, Em, HAlignment};
|
use crate::layout::{BlockBody, BlockElem, Em, HAlignment};
|
||||||
@ -72,16 +73,7 @@ use crate::World;
|
|||||||
/// needed, start the text with a single space (which will be trimmed) or use
|
/// needed, start the text with a single space (which will be trimmed) or use
|
||||||
/// the single backtick syntax. If your text should start or end with a
|
/// the single backtick syntax. If your text should start or end with a
|
||||||
/// backtick, put a space before or after it (it will be trimmed).
|
/// backtick, put a space before or after it (it will be trimmed).
|
||||||
#[elem(
|
#[elem(scope, title = "Raw Text / Code", Show, ShowSet, LocalName, Figurable, PlainText)]
|
||||||
scope,
|
|
||||||
title = "Raw Text / Code",
|
|
||||||
Synthesize,
|
|
||||||
Show,
|
|
||||||
ShowSet,
|
|
||||||
LocalName,
|
|
||||||
Figurable,
|
|
||||||
PlainText
|
|
||||||
)]
|
|
||||||
pub struct RawElem {
|
pub struct RawElem {
|
||||||
/// The raw text.
|
/// The raw text.
|
||||||
///
|
///
|
||||||
@ -265,19 +257,27 @@ pub struct RawElem {
|
|||||||
/// ````
|
/// ````
|
||||||
#[default(2)]
|
#[default(2)]
|
||||||
pub tab_size: usize,
|
pub tab_size: usize,
|
||||||
|
|
||||||
/// The stylized lines of raw text.
|
|
||||||
///
|
|
||||||
/// Made accessible for the [`raw.line` element]($raw.line).
|
|
||||||
/// Allows more styling control in `show` rules.
|
|
||||||
#[synthesized]
|
|
||||||
pub lines: Vec<Packed<RawLine>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[scope]
|
#[scope]
|
||||||
impl RawElem {
|
impl RawElem {
|
||||||
#[elem]
|
#[elem]
|
||||||
type RawLine;
|
type RawLine;
|
||||||
|
|
||||||
|
/// The stylized lines of raw text.
|
||||||
|
#[func(contextual)]
|
||||||
|
pub fn lines(
|
||||||
|
self,
|
||||||
|
context: Tracked<Context>,
|
||||||
|
span: Span,
|
||||||
|
) -> SourceResult<Vec<Packed<RawLine>>> {
|
||||||
|
Ok(self.highlight(context.styles().at(span)?, span))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cast! {
|
||||||
|
RawElem,
|
||||||
|
v: Content => v.unpack::<Self>().map_err(|_| "expected raw text / code")?
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawElem {
|
impl RawElem {
|
||||||
@ -299,24 +299,13 @@ impl RawElem {
|
|||||||
])
|
])
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Synthesize for Packed<RawElem> {
|
|
||||||
fn synthesize(&mut self, _: &mut Engine, styles: StyleChain) -> SourceResult<()> {
|
|
||||||
let seq = self.highlight(styles);
|
|
||||||
self.push_lines(seq);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Packed<RawElem> {
|
|
||||||
#[comemo::memoize]
|
#[comemo::memoize]
|
||||||
fn highlight(&self, styles: StyleChain) -> Vec<Packed<RawLine>> {
|
fn highlight(&self, styles: StyleChain, span: Span) -> Vec<Packed<RawLine>> {
|
||||||
let elem = self.as_ref();
|
let lines = preprocess(&self.text, styles, span);
|
||||||
let lines = preprocess(&elem.text, styles, self.span());
|
|
||||||
|
|
||||||
let count = lines.len() as i64;
|
let count = lines.len() as i64;
|
||||||
let lang = elem
|
let lang = self
|
||||||
.lang(styles)
|
.lang(styles)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -335,8 +324,8 @@ impl Packed<RawElem> {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let syntaxes = LazyCell::new(|| elem.syntaxes(styles));
|
let syntaxes = LazyCell::new(|| self.syntaxes(styles));
|
||||||
let theme: &synt::Theme = match elem.theme(styles) {
|
let theme: &synt::Theme = match self.theme(styles) {
|
||||||
Smart::Auto => &RAW_THEME,
|
Smart::Auto => &RAW_THEME,
|
||||||
Smart::Custom(Some(theme)) => theme.derived.get(),
|
Smart::Custom(Some(theme)) => theme.derived.get(),
|
||||||
Smart::Custom(None) => return non_highlighted_result(lines).collect(),
|
Smart::Custom(None) => return non_highlighted_result(lines).collect(),
|
||||||
@ -432,7 +421,7 @@ impl Packed<RawElem> {
|
|||||||
impl Show for Packed<RawElem> {
|
impl Show for Packed<RawElem> {
|
||||||
#[typst_macros::time(name = "raw", span = self.span())]
|
#[typst_macros::time(name = "raw", span = self.span())]
|
||||||
fn show(&self, _: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
fn show(&self, _: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
||||||
let lines = self.lines().map(|v| v.as_slice()).unwrap_or_default();
|
let lines = self.as_ref().highlight(styles, self.span());
|
||||||
|
|
||||||
let mut seq = EcoVec::with_capacity((2 * lines.len()).saturating_sub(1));
|
let mut seq = EcoVec::with_capacity((2 * lines.len()).saturating_sub(1));
|
||||||
for (i, line) in lines.iter().enumerate() {
|
for (i, line) in lines.iter().enumerate() {
|
||||||
|
@ -78,9 +78,7 @@ impl Elem {
|
|||||||
|
|
||||||
/// Fields that show up in the documentation.
|
/// Fields that show up in the documentation.
|
||||||
fn doc_fields(&self) -> impl Iterator<Item = &Field> + Clone {
|
fn doc_fields(&self) -> impl Iterator<Item = &Field> + Clone {
|
||||||
self.fields
|
self.fields.iter().filter(|field| !field.internal)
|
||||||
.iter()
|
|
||||||
.filter(|field| !field.internal && !field.synthesized)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fields that are relevant for `Construct` impl.
|
/// Fields that are relevant for `Construct` impl.
|
||||||
@ -89,9 +87,8 @@ impl Elem {
|
|||||||
/// because it's a pattern used a lot for parsing data from the input and
|
/// because it's a pattern used a lot for parsing data from the input and
|
||||||
/// then storing it in a field.
|
/// then storing it in a field.
|
||||||
fn construct_fields(&self) -> impl Iterator<Item = &Field> + Clone {
|
fn construct_fields(&self) -> impl Iterator<Item = &Field> + Clone {
|
||||||
self.real_fields().filter(|field| {
|
self.real_fields()
|
||||||
field.parse.is_some() || (!field.synthesized && !field.internal)
|
.filter(|field| field.parse.is_some() || !field.internal)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fields that can be configured with set rules.
|
/// Fields that can be configured with set rules.
|
||||||
@ -242,6 +239,8 @@ fn parse_field(field: &syn::Field) -> Result<Field> {
|
|||||||
let variadic = has_attr(&mut attrs, "variadic");
|
let variadic = has_attr(&mut attrs, "variadic");
|
||||||
let required = has_attr(&mut attrs, "required") || variadic;
|
let required = has_attr(&mut attrs, "required") || variadic;
|
||||||
let positional = has_attr(&mut attrs, "positional") || required;
|
let positional = has_attr(&mut attrs, "positional") || required;
|
||||||
|
let synthesized = has_attr(&mut attrs, "synthesized");
|
||||||
|
let internal = has_attr(&mut attrs, "internal") || synthesized;
|
||||||
|
|
||||||
let mut field = Field {
|
let mut field = Field {
|
||||||
ident: ident.clone(),
|
ident: ident.clone(),
|
||||||
@ -261,11 +260,11 @@ fn parse_field(field: &syn::Field) -> Result<Field> {
|
|||||||
variadic,
|
variadic,
|
||||||
resolve: has_attr(&mut attrs, "resolve"),
|
resolve: has_attr(&mut attrs, "resolve"),
|
||||||
fold: has_attr(&mut attrs, "fold"),
|
fold: has_attr(&mut attrs, "fold"),
|
||||||
internal: has_attr(&mut attrs, "internal"),
|
internal,
|
||||||
external: has_attr(&mut attrs, "external"),
|
external: has_attr(&mut attrs, "external"),
|
||||||
borrowed: has_attr(&mut attrs, "borrowed"),
|
borrowed: has_attr(&mut attrs, "borrowed"),
|
||||||
ghost: has_attr(&mut attrs, "ghost"),
|
ghost: has_attr(&mut attrs, "ghost"),
|
||||||
synthesized: has_attr(&mut attrs, "synthesized"),
|
synthesized,
|
||||||
parse: parse_attr(&mut attrs, "parse")?.flatten(),
|
parse: parse_attr(&mut attrs, "parse")?.flatten(),
|
||||||
default: parse_attr::<syn::Expr>(&mut attrs, "default")?.flatten(),
|
default: parse_attr::<syn::Expr>(&mut attrs, "default")?.flatten(),
|
||||||
};
|
};
|
||||||
|
@ -201,7 +201,9 @@ pub fn ty(stream: BoundaryStream, item: BoundaryStream) -> BoundaryStream {
|
|||||||
/// flexibility.
|
/// flexibility.
|
||||||
/// - `#[synthesized]`: The field cannot be specified in a constructor or set
|
/// - `#[synthesized]`: The field cannot be specified in a constructor or set
|
||||||
/// rule. Instead, it is added to an element before its show rule runs
|
/// rule. Instead, it is added to an element before its show rule runs
|
||||||
/// through the `Synthesize` trait.
|
/// through the `Synthesize` trait. This implies `#[internal]`. If a
|
||||||
|
/// synthesized field needs to be exposed to the user, that should be done via
|
||||||
|
/// a getter method.
|
||||||
/// - `#[ghost]`: Allows creating fields that are only present in the style chain,
|
/// - `#[ghost]`: Allows creating fields that are only present in the style chain,
|
||||||
/// this means that they *cannot* be accessed by the user, they cannot be set
|
/// this means that they *cannot* be accessed by the user, they cannot be set
|
||||||
/// on an individual instantiated element, and must be set via the style chain.
|
/// on an individual instantiated element, and must be set via the style chain.
|
||||||
|
@ -58,8 +58,7 @@ $x$$y$
|
|||||||
--- issue-2821-missing-fields ---
|
--- issue-2821-missing-fields ---
|
||||||
// Issue #2821: Setting a figure's supplement to none removes the field
|
// Issue #2821: Setting a figure's supplement to none removes the field
|
||||||
#show figure.caption: it => {
|
#show figure.caption: it => {
|
||||||
assert(it.has("supplement"))
|
assert(it.supplement() == none)
|
||||||
assert(it.supplement == none)
|
|
||||||
}
|
}
|
||||||
#figure([], caption: [], supplement: none)
|
#figure([], caption: [], supplement: none)
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ We can clearly see that @fig-cylinder and
|
|||||||
if not it.numbering == none {
|
if not it.numbering == none {
|
||||||
title = it.supplement
|
title = it.supplement
|
||||||
if not it.numbering == none {
|
if not it.numbering == none {
|
||||||
title += " " + it.counter.display(it.numbering)
|
title += " " + counter(figure.where(kind: it.kind)).display(it.numbering)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
title = strong(title)
|
title = strong(title)
|
||||||
@ -168,7 +168,10 @@ We can clearly see that @fig-cylinder and
|
|||||||
|
|
||||||
--- figure-caption-where-selector ---
|
--- figure-caption-where-selector ---
|
||||||
// Test figure.caption element for specific figure kinds
|
// Test figure.caption element for specific figure kinds
|
||||||
#show figure.caption.where(kind: table): underline
|
#show figure.where(kind: table): it => {
|
||||||
|
show figure.caption: underline
|
||||||
|
it
|
||||||
|
}
|
||||||
|
|
||||||
#figure(
|
#figure(
|
||||||
[Not a table],
|
[Not a table],
|
||||||
@ -212,8 +215,8 @@ We can clearly see that @fig-cylinder and
|
|||||||
|
|
||||||
#show figure.caption: it => emph[
|
#show figure.caption: it => emph[
|
||||||
#it.body
|
#it.body
|
||||||
(#it.supplement
|
(#it.supplement()
|
||||||
#context it.counter.display(it.numbering))
|
#context it.counter().display(it.numbering()))
|
||||||
]
|
]
|
||||||
|
|
||||||
#figure(
|
#figure(
|
||||||
|
@ -513,7 +513,7 @@ fn main() {
|
|||||||
|
|
||||||
--- raw-line-alternating-fill ---
|
--- raw-line-alternating-fill ---
|
||||||
#set page(width: 200pt)
|
#set page(width: 200pt)
|
||||||
#show raw: it => stack(dir: ttb, ..it.lines)
|
#show raw: it => stack(dir: ttb, ..it.lines())
|
||||||
#show raw.line: it => {
|
#show raw.line: it => {
|
||||||
box(
|
box(
|
||||||
width: 100%,
|
width: 100%,
|
||||||
@ -564,21 +564,21 @@ print(y)
|
|||||||
// Test line extraction works.
|
// Test line extraction works.
|
||||||
|
|
||||||
#show raw: code => {
|
#show raw: code => {
|
||||||
for i in code.lines {
|
for i in code.lines() {
|
||||||
test(i.count, 10)
|
test(i.count, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
test(code.lines.at(0).text, "import numpy as np")
|
test(code.lines().at(0).text, "import numpy as np")
|
||||||
test(code.lines.at(1).text, "")
|
test(code.lines().at(1).text, "")
|
||||||
test(code.lines.at(2).text, "def f(x):")
|
test(code.lines().at(2).text, "def f(x):")
|
||||||
test(code.lines.at(3).text, " return x**2")
|
test(code.lines().at(3).text, " return x**2")
|
||||||
test(code.lines.at(4).text, "")
|
test(code.lines().at(4).text, "")
|
||||||
test(code.lines.at(5).text, "x = np.linspace(0, 10, 100)")
|
test(code.lines().at(5).text, "x = np.linspace(0, 10, 100)")
|
||||||
test(code.lines.at(6).text, "y = f(x)")
|
test(code.lines().at(6).text, "y = f(x)")
|
||||||
test(code.lines.at(7).text, "")
|
test(code.lines().at(7).text, "")
|
||||||
test(code.lines.at(8).text, "print(x)")
|
test(code.lines().at(8).text, "print(x)")
|
||||||
test(code.lines.at(9).text, "print(y)")
|
test(code.lines().at(9).text, "print(y)")
|
||||||
test(code.lines.at(10, default: none), none)
|
test(code.lines().at(10, default: none), none)
|
||||||
}
|
}
|
||||||
|
|
||||||
```py
|
```py
|
||||||
|
Loading…
x
Reference in New Issue
Block a user