mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Track context (#3623)
This commit is contained in:
parent
d01ccffad6
commit
633c32a552
@ -67,8 +67,12 @@ pub fn analyze_import(world: &dyn World, source: &LinkedNode) -> Option<Value> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let context = Context::none();
|
let context = Context::none();
|
||||||
let mut vm =
|
let mut vm = Vm::new(
|
||||||
Vm::new(engine, &context, Scopes::new(Some(world.library())), Span::detached());
|
engine,
|
||||||
|
context.track(),
|
||||||
|
Scopes::new(Some(world.library())),
|
||||||
|
Span::detached(),
|
||||||
|
);
|
||||||
typst::eval::import(&mut vm, source, Span::detached(), true)
|
typst::eval::import(&mut vm, source, Span::detached(), true)
|
||||||
.ok()
|
.ok()
|
||||||
.map(Value::Module)
|
.map(Value::Module)
|
||||||
|
@ -278,7 +278,7 @@ pub(crate) fn call_closure(
|
|||||||
route: Tracked<Route>,
|
route: Tracked<Route>,
|
||||||
locator: Tracked<Locator>,
|
locator: Tracked<Locator>,
|
||||||
tracer: TrackedMut<Tracer>,
|
tracer: TrackedMut<Tracer>,
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
mut args: Args,
|
mut args: Args,
|
||||||
) -> SourceResult<Value> {
|
) -> SourceResult<Value> {
|
||||||
let (name, params, body) = match closure.node.cast::<ast::Closure>() {
|
let (name, params, body) = match closure.node.cast::<ast::Closure>() {
|
||||||
|
@ -63,7 +63,7 @@ pub fn eval(
|
|||||||
let context = Context::none();
|
let context = Context::none();
|
||||||
let scopes = Scopes::new(Some(world.library()));
|
let scopes = Scopes::new(Some(world.library()));
|
||||||
let root = source.root();
|
let root = source.root();
|
||||||
let mut vm = Vm::new(engine, &context, scopes, root.span());
|
let mut vm = Vm::new(engine, context.track(), scopes, root.span());
|
||||||
|
|
||||||
// Check for well-formedness unless we are in trace mode.
|
// Check for well-formedness unless we are in trace mode.
|
||||||
let errors = root.errors();
|
let errors = root.errors();
|
||||||
@ -131,7 +131,7 @@ pub fn eval_string(
|
|||||||
// Prepare VM.
|
// Prepare VM.
|
||||||
let context = Context::none();
|
let context = Context::none();
|
||||||
let scopes = Scopes::new(Some(world.library()));
|
let scopes = Scopes::new(Some(world.library()));
|
||||||
let mut vm = Vm::new(engine, &context, scopes, root.span());
|
let mut vm = Vm::new(engine, context.track(), scopes, root.span());
|
||||||
vm.scopes.scopes.push(scope);
|
vm.scopes.scopes.push(scope);
|
||||||
|
|
||||||
// Evaluate the code.
|
// Evaluate the code.
|
||||||
|
@ -21,14 +21,14 @@ pub struct Vm<'a> {
|
|||||||
/// A span that is currently under inspection.
|
/// A span that is currently under inspection.
|
||||||
pub(crate) inspected: Option<Span>,
|
pub(crate) inspected: Option<Span>,
|
||||||
/// Data that is contextually made accessible to code behind the scenes.
|
/// Data that is contextually made accessible to code behind the scenes.
|
||||||
pub(crate) context: &'a Context<'a>,
|
pub(crate) context: Tracked<'a, Context<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Vm<'a> {
|
impl<'a> Vm<'a> {
|
||||||
/// Create a new virtual machine.
|
/// Create a new virtual machine.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
engine: Engine<'a>,
|
engine: Engine<'a>,
|
||||||
context: &'a Context<'a>,
|
context: Tracked<'a, Context<'a>>,
|
||||||
scopes: Scopes<'a>,
|
scopes: Scopes<'a>,
|
||||||
target: Span,
|
target: Span,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -55,6 +55,6 @@ impl<'a> Vm<'a> {
|
|||||||
pub fn trace(&mut self, value: Value) {
|
pub fn trace(&mut self, value: Value) {
|
||||||
self.engine
|
self.engine
|
||||||
.tracer
|
.tracer
|
||||||
.value(value.clone(), self.context.styles.map(|s| s.to_map()));
|
.value(value.clone(), self.context.styles().ok().map(|s| s.to_map()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use std::fmt::{Debug, Formatter};
|
|||||||
use std::num::{NonZeroI64, NonZeroUsize};
|
use std::num::{NonZeroI64, NonZeroUsize};
|
||||||
use std::ops::{Add, AddAssign};
|
use std::ops::{Add, AddAssign};
|
||||||
|
|
||||||
|
use comemo::Tracked;
|
||||||
use ecow::{eco_format, EcoString, EcoVec};
|
use ecow::{eco_format, EcoString, EcoVec};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
@ -301,7 +302,7 @@ impl Array {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The function to apply to each item. Must return a boolean.
|
/// The function to apply to each item. Must return a boolean.
|
||||||
searcher: Func,
|
searcher: Func,
|
||||||
) -> SourceResult<Option<Value>> {
|
) -> SourceResult<Option<Value>> {
|
||||||
@ -325,7 +326,7 @@ impl Array {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The function to apply to each item. Must return a boolean.
|
/// The function to apply to each item. Must return a boolean.
|
||||||
searcher: Func,
|
searcher: Func,
|
||||||
) -> SourceResult<Option<i64>> {
|
) -> SourceResult<Option<i64>> {
|
||||||
@ -402,7 +403,7 @@ impl Array {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The function to apply to each item. Must return a boolean.
|
/// The function to apply to each item. Must return a boolean.
|
||||||
test: Func,
|
test: Func,
|
||||||
) -> SourceResult<Array> {
|
) -> SourceResult<Array> {
|
||||||
@ -427,7 +428,7 @@ impl Array {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The function to apply to each item.
|
/// The function to apply to each item.
|
||||||
mapper: Func,
|
mapper: Func,
|
||||||
) -> SourceResult<Array> {
|
) -> SourceResult<Array> {
|
||||||
@ -536,7 +537,7 @@ impl Array {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The initial value to start with.
|
/// The initial value to start with.
|
||||||
init: Value,
|
init: Value,
|
||||||
/// The folding function. Must have two parameters: One for the
|
/// The folding function. Must have two parameters: One for the
|
||||||
@ -598,7 +599,7 @@ impl Array {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The function to apply to each item. Must return a boolean.
|
/// The function to apply to each item. Must return a boolean.
|
||||||
test: Func,
|
test: Func,
|
||||||
) -> SourceResult<bool> {
|
) -> SourceResult<bool> {
|
||||||
@ -618,7 +619,7 @@ impl Array {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The function to apply to each item. Must return a boolean.
|
/// The function to apply to each item. Must return a boolean.
|
||||||
test: Func,
|
test: Func,
|
||||||
) -> SourceResult<bool> {
|
) -> SourceResult<bool> {
|
||||||
@ -765,7 +766,7 @@ impl Array {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The callsite span.
|
/// The callsite span.
|
||||||
span: Span,
|
span: Span,
|
||||||
/// If given, applies this function to the elements in the array to
|
/// If given, applies this function to the elements in the array to
|
||||||
@ -815,7 +816,7 @@ impl Array {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// If given, applies this function to the elements in the array to
|
/// If given, applies this function to the elements in the array to
|
||||||
/// determine the keys to deduplicate by.
|
/// determine the keys to deduplicate by.
|
||||||
#[named]
|
#[named]
|
||||||
|
@ -6,6 +6,7 @@ use std::marker::PhantomData;
|
|||||||
use std::ops::{Add, AddAssign, Deref, DerefMut};
|
use std::ops::{Add, AddAssign, Deref, DerefMut};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use comemo::Tracked;
|
||||||
use ecow::{eco_format, EcoString};
|
use ecow::{eco_format, EcoString};
|
||||||
use serde::{Serialize, Serializer};
|
use serde::{Serialize, Serializer};
|
||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
@ -345,7 +346,7 @@ impl Content {
|
|||||||
pub fn styled_with_recipe(
|
pub fn styled_with_recipe(
|
||||||
self,
|
self,
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
recipe: Recipe,
|
recipe: Recipe,
|
||||||
) -> SourceResult<Self> {
|
) -> SourceResult<Self> {
|
||||||
if recipe.selector.is_none() {
|
if recipe.selector.is_none() {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use comemo::Track;
|
||||||
|
|
||||||
use crate::diag::{bail, Hint, HintedStrResult, SourceResult};
|
use crate::diag::{bail, Hint, HintedStrResult, SourceResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
@ -28,7 +30,10 @@ impl<'a> Context<'a> {
|
|||||||
pub fn new(location: Option<Location>, styles: Option<StyleChain<'a>>) -> Self {
|
pub fn new(location: Option<Location>, styles: Option<StyleChain<'a>>) -> Self {
|
||||||
Self { location, styles }
|
Self { location, styles }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[comemo::track]
|
||||||
|
impl<'a> Context<'a> {
|
||||||
/// Try to extract the location.
|
/// Try to extract the location.
|
||||||
pub fn location(&self) -> HintedStrResult<Location> {
|
pub fn location(&self) -> HintedStrResult<Location> {
|
||||||
require(self.location)
|
require(self.location)
|
||||||
@ -75,6 +80,6 @@ impl Show for Packed<ContextElem> {
|
|||||||
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
||||||
let loc = self.location().unwrap();
|
let loc = self.location().unwrap();
|
||||||
let context = Context::new(Some(loc), Some(styles));
|
let context = Context::new(Some(loc), Some(styles));
|
||||||
Ok(self.func.call::<[Value; 0]>(engine, &context, [])?.display())
|
Ok(self.func.call::<[Value; 0]>(engine, context.track(), [])?.display())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::fmt::{self, Debug, Formatter};
|
use std::fmt::{self, Debug, Formatter};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use comemo::TrackedMut;
|
use comemo::{Tracked, TrackedMut};
|
||||||
use ecow::{eco_format, EcoString};
|
use ecow::{eco_format, EcoString};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ impl Func {
|
|||||||
pub fn call<A: IntoArgs>(
|
pub fn call<A: IntoArgs>(
|
||||||
&self,
|
&self,
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
args: A,
|
args: A,
|
||||||
) -> SourceResult<Value> {
|
) -> SourceResult<Value> {
|
||||||
self.call_impl(engine, context, args.into_args(self.span))
|
self.call_impl(engine, context, args.into_args(self.span))
|
||||||
@ -272,7 +272,7 @@ impl Func {
|
|||||||
fn call_impl(
|
fn call_impl(
|
||||||
&self,
|
&self,
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
mut args: Args,
|
mut args: Args,
|
||||||
) -> SourceResult<Value> {
|
) -> SourceResult<Value> {
|
||||||
match &self.repr {
|
match &self.repr {
|
||||||
@ -440,7 +440,7 @@ pub trait NativeFunc {
|
|||||||
/// Defines a native function.
|
/// Defines a native function.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NativeFuncData {
|
pub struct NativeFuncData {
|
||||||
pub function: fn(&mut Engine, &Context, &mut Args) -> SourceResult<Value>,
|
pub function: fn(&mut Engine, Tracked<Context>, &mut Args) -> SourceResult<Value>,
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub title: &'static str,
|
pub title: &'static str,
|
||||||
pub docs: &'static str,
|
pub docs: &'static str,
|
||||||
|
@ -304,7 +304,7 @@ impl LocatableSelector {
|
|||||||
pub fn resolve_unique(
|
pub fn resolve_unique(
|
||||||
&self,
|
&self,
|
||||||
introspector: Tracked<Introspector>,
|
introspector: Tracked<Introspector>,
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
) -> HintedStrResult<Location> {
|
) -> HintedStrResult<Location> {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
Selector::Location(loc) => Ok(*loc),
|
Selector::Location(loc) => Ok(*loc),
|
||||||
|
@ -3,6 +3,7 @@ use std::fmt::{self, Debug, Display, Formatter};
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ops::{Add, AddAssign, Deref, Range};
|
use std::ops::{Add, AddAssign, Deref, Range};
|
||||||
|
|
||||||
|
use comemo::Tracked;
|
||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
@ -425,7 +426,7 @@ impl Str {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The pattern to search for.
|
/// The pattern to search for.
|
||||||
pattern: StrPattern,
|
pattern: StrPattern,
|
||||||
/// The string to replace the matches with or a function that gets a
|
/// The string to replace the matches with or a function that gets a
|
||||||
|
@ -3,6 +3,7 @@ use std::fmt::{self, Debug, Formatter};
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
|
||||||
|
use comemo::{Track, Tracked};
|
||||||
use ecow::{eco_vec, EcoString, EcoVec};
|
use ecow::{eco_vec, EcoString, EcoVec};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
@ -57,7 +58,10 @@ impl Show for Packed<StyleElem> {
|
|||||||
#[typst_macros::time(name = "style", span = self.span())]
|
#[typst_macros::time(name = "style", span = self.span())]
|
||||||
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
||||||
let context = Context::new(self.location(), Some(styles));
|
let context = Context::new(self.location(), Some(styles));
|
||||||
Ok(self.func().call(engine, &context, [styles.to_map()])?.display())
|
Ok(self
|
||||||
|
.func()
|
||||||
|
.call(engine, context.track(), [styles.to_map()])?
|
||||||
|
.display())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +389,7 @@ impl Recipe {
|
|||||||
pub fn apply(
|
pub fn apply(
|
||||||
&self,
|
&self,
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
content: Content,
|
content: Content,
|
||||||
) -> SourceResult<Content> {
|
) -> SourceResult<Content> {
|
||||||
let mut content = match &self.transform {
|
let mut content = match &self.transform {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use comemo::{Tracked, TrackedMut};
|
use comemo::{Track, Tracked, TrackedMut};
|
||||||
use ecow::{eco_format, eco_vec, EcoString, EcoVec};
|
use ecow::{eco_format, eco_vec, EcoString, EcoVec};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ impl Counter {
|
|||||||
let context = Context::new(Some(loc), Some(styles));
|
let context = Context::new(Some(loc), Some(styles));
|
||||||
Ok(self
|
Ok(self
|
||||||
.at_loc(engine, loc)?
|
.at_loc(engine, loc)?
|
||||||
.display(engine, &context, numbering)?
|
.display(engine, context.track(), numbering)?
|
||||||
.display())
|
.display())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +392,7 @@ impl Counter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let context = Context::new(Some(location), styles);
|
let context = Context::new(Some(location), styles);
|
||||||
state.display(engine, &context, &numbering)
|
state.display(engine, context.track(), &numbering)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +425,7 @@ impl Counter {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The callsite span.
|
/// The callsite span.
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> SourceResult<CounterState> {
|
) -> SourceResult<CounterState> {
|
||||||
@ -446,7 +446,7 @@ impl Counter {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The call span of the display.
|
/// The call span of the display.
|
||||||
span: Span,
|
span: Span,
|
||||||
/// A [numbering pattern or a function]($numbering), which specifies how
|
/// A [numbering pattern or a function]($numbering), which specifies how
|
||||||
@ -468,8 +468,8 @@ impl Counter {
|
|||||||
#[default(false)]
|
#[default(false)]
|
||||||
both: bool,
|
both: bool,
|
||||||
) -> SourceResult<Value> {
|
) -> SourceResult<Value> {
|
||||||
if let Some(loc) = context.location {
|
if let Ok(loc) = context.location() {
|
||||||
self.display_impl(engine, loc, numbering, both, context.styles)
|
self.display_impl(engine, loc, numbering, both, context.styles().ok())
|
||||||
} else {
|
} else {
|
||||||
Ok(CounterDisplayElem::new(self, numbering, both)
|
Ok(CounterDisplayElem::new(self, numbering, both)
|
||||||
.pack()
|
.pack()
|
||||||
@ -494,7 +494,7 @@ impl Counter {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The callsite span.
|
/// The callsite span.
|
||||||
span: Span,
|
span: Span,
|
||||||
/// The place at which the counter's value should be retrieved.
|
/// The place at which the counter's value should be retrieved.
|
||||||
@ -512,7 +512,7 @@ impl Counter {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The callsite span.
|
/// The callsite span.
|
||||||
span: Span,
|
span: Span,
|
||||||
/// _Compatibility:_ This argument only exists for compatibility with
|
/// _Compatibility:_ This argument only exists for compatibility with
|
||||||
@ -669,7 +669,7 @@ impl CounterState {
|
|||||||
CounterUpdate::Step(level) => self.step(level, 1),
|
CounterUpdate::Step(level) => self.step(level, 1),
|
||||||
CounterUpdate::Func(func) => {
|
CounterUpdate::Func(func) => {
|
||||||
*self = func
|
*self = func
|
||||||
.call(engine, &Context::none(), self.0.iter().copied())?
|
.call(engine, Context::none().track(), self.0.iter().copied())?
|
||||||
.cast()
|
.cast()
|
||||||
.at(func.span())?
|
.at(func.span())?
|
||||||
}
|
}
|
||||||
@ -700,7 +700,7 @@ impl CounterState {
|
|||||||
pub fn display(
|
pub fn display(
|
||||||
&self,
|
&self,
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
numbering: &Numbering,
|
numbering: &Numbering,
|
||||||
) -> SourceResult<Value> {
|
) -> SourceResult<Value> {
|
||||||
numbering.apply(engine, context, &self.0)
|
numbering.apply(engine, context, &self.0)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use comemo::Tracked;
|
||||||
|
|
||||||
use crate::diag::HintedStrResult;
|
use crate::diag::HintedStrResult;
|
||||||
use crate::foundations::{func, Context};
|
use crate::foundations::{func, Context};
|
||||||
use crate::introspection::Location;
|
use crate::introspection::Location;
|
||||||
@ -44,7 +46,7 @@ use crate::introspection::Location;
|
|||||||
#[func(contextual)]
|
#[func(contextual)]
|
||||||
pub fn here(
|
pub fn here(
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
) -> HintedStrResult<Location> {
|
) -> HintedStrResult<Location> {
|
||||||
context.location()
|
context.location()
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use comemo::{Track, Tracked};
|
||||||
|
|
||||||
use crate::diag::{HintedStrResult, SourceResult};
|
use crate::diag::{HintedStrResult, SourceResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
@ -37,7 +39,7 @@ pub fn locate(
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The span of the `locate` call.
|
/// The span of the `locate` call.
|
||||||
span: Span,
|
span: Span,
|
||||||
/// A selector that should match exactly one element. This element will be
|
/// A selector that should match exactly one element. This element will be
|
||||||
@ -106,6 +108,6 @@ impl Show for Packed<LocateElem> {
|
|||||||
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
||||||
let location = self.location().unwrap();
|
let location = self.location().unwrap();
|
||||||
let context = Context::new(Some(location), Some(styles));
|
let context = Context::new(Some(location), Some(styles));
|
||||||
Ok(self.func().call(engine, &context, [location])?.display())
|
Ok(self.func().call(engine, context.track(), [location])?.display())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use comemo::Tracked;
|
||||||
|
|
||||||
use crate::diag::HintedStrResult;
|
use crate::diag::HintedStrResult;
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{func, Array, Context, LocatableSelector, Value};
|
use crate::foundations::{func, Array, Context, LocatableSelector, Value};
|
||||||
@ -135,7 +137,7 @@ pub fn query(
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// Can be
|
/// Can be
|
||||||
/// - an element function like a `heading` or `figure`,
|
/// - an element function like a `heading` or `figure`,
|
||||||
/// - a `{<label>}`,
|
/// - a `{<label>}`,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use comemo::{Tracked, TrackedMut};
|
use comemo::{Track, Tracked, TrackedMut};
|
||||||
use ecow::{eco_format, eco_vec, EcoString, EcoVec};
|
use ecow::{eco_format, eco_vec, EcoString, EcoVec};
|
||||||
|
|
||||||
use crate::diag::{bail, At, SourceResult};
|
use crate::diag::{bail, At, SourceResult};
|
||||||
@ -249,7 +249,7 @@ impl State {
|
|||||||
match elem.update() {
|
match elem.update() {
|
||||||
StateUpdate::Set(value) => state = value.clone(),
|
StateUpdate::Set(value) => state = value.clone(),
|
||||||
StateUpdate::Func(func) => {
|
StateUpdate::Func(func) => {
|
||||||
state = func.call(&mut engine, &Context::none(), [state])?
|
state = func.call(&mut engine, Context::none().track(), [state])?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stops.push(state.clone());
|
stops.push(state.clone());
|
||||||
@ -287,7 +287,7 @@ impl State {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The callsite span.
|
/// The callsite span.
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> SourceResult<Value> {
|
) -> SourceResult<Value> {
|
||||||
@ -310,7 +310,7 @@ impl State {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The callsite span.
|
/// The callsite span.
|
||||||
span: Span,
|
span: Span,
|
||||||
/// The place at which the state's value should be retrieved.
|
/// The place at which the state's value should be retrieved.
|
||||||
@ -327,7 +327,7 @@ impl State {
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The callsite span.
|
/// The callsite span.
|
||||||
span: Span,
|
span: Span,
|
||||||
/// _Compatibility:_ This argument only exists for compatibility with
|
/// _Compatibility:_ This argument only exists for compatibility with
|
||||||
@ -451,7 +451,7 @@ impl Show for Packed<StateDisplayElem> {
|
|||||||
let context = Context::new(Some(location), Some(styles));
|
let context = Context::new(Some(location), Some(styles));
|
||||||
let value = self.state().at_loc(engine, location)?;
|
let value = self.state().at_loc(engine, location)?;
|
||||||
Ok(match self.func() {
|
Ok(match self.func() {
|
||||||
Some(func) => func.call(engine, &context, [value])?.display(),
|
Some(func) => func.call(engine, context.track(), [value])?.display(),
|
||||||
None => value.display(),
|
None => value.display(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use std::hash::Hash;
|
|||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use comemo::Track;
|
||||||
use ecow::eco_format;
|
use ecow::eco_format;
|
||||||
|
|
||||||
use super::lines::{
|
use super::lines::{
|
||||||
@ -50,7 +51,7 @@ impl<T: Default + Clone + FromValue> Celled<T> {
|
|||||||
Ok(match self {
|
Ok(match self {
|
||||||
Self::Value(value) => value.clone(),
|
Self::Value(value) => value.clone(),
|
||||||
Self::Func(func) => func
|
Self::Func(func) => func
|
||||||
.call(engine, &Context::new(None, Some(styles)), [x, y])?
|
.call(engine, Context::new(None, Some(styles)).track(), [x, y])?
|
||||||
.cast()
|
.cast()
|
||||||
.at(func.span())?,
|
.at(func.span())?,
|
||||||
Self::Array(array) => x
|
Self::Array(array) => x
|
||||||
@ -151,7 +152,7 @@ where
|
|||||||
Ok(match &self.0 {
|
Ok(match &self.0 {
|
||||||
Celled::Value(value) => value.clone(),
|
Celled::Value(value) => value.clone(),
|
||||||
Celled::Func(func) => func
|
Celled::Func(func) => func
|
||||||
.call(engine, &Context::new(None, Some(styles)), [x, y])?
|
.call(engine, Context::new(None, Some(styles)).track(), [x, y])?
|
||||||
.cast::<T>()
|
.cast::<T>()
|
||||||
.at(func.span())?
|
.at(func.span())?
|
||||||
.resolve(styles),
|
.resolve(styles),
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use comemo::Track;
|
||||||
|
|
||||||
use crate::diag::SourceResult;
|
use crate::diag::SourceResult;
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
@ -84,7 +86,7 @@ impl LayoutMultiple for Packed<LayoutElem> {
|
|||||||
let context = Context::new(Some(loc), Some(styles));
|
let context = Context::new(Some(loc), Some(styles));
|
||||||
let result = self
|
let result = self
|
||||||
.func()
|
.func()
|
||||||
.call(engine, &context, [dict! { "width" => x, "height" => y }])?
|
.call(engine, context.track(), [dict! { "width" => x, "height" => y }])?
|
||||||
.display();
|
.display();
|
||||||
result.layout(engine, styles, regions)
|
result.layout(engine, styles, regions)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ use std::cmp::Ordering;
|
|||||||
use std::fmt::{self, Debug, Formatter};
|
use std::fmt::{self, Debug, Formatter};
|
||||||
use std::ops::{Add, Div, Mul, Neg};
|
use std::ops::{Add, Div, Mul, Neg};
|
||||||
|
|
||||||
|
use comemo::Tracked;
|
||||||
use ecow::{eco_format, EcoString};
|
use ecow::{eco_format, EcoString};
|
||||||
|
|
||||||
use crate::diag::{At, Hint, HintedStrResult, SourceResult};
|
use crate::diag::{At, Hint, HintedStrResult, SourceResult};
|
||||||
@ -151,7 +152,7 @@ impl Length {
|
|||||||
/// ]
|
/// ]
|
||||||
/// ```
|
/// ```
|
||||||
#[func]
|
#[func]
|
||||||
pub fn to_absolute(&self, context: &Context) -> HintedStrResult<Length> {
|
pub fn to_absolute(&self, context: Tracked<Context>) -> HintedStrResult<Length> {
|
||||||
Ok(self.resolve(context.styles()?).into())
|
Ok(self.resolve(context.styles()?).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use comemo::Tracked;
|
||||||
|
|
||||||
use crate::diag::{At, SourceResult};
|
use crate::diag::{At, SourceResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{dict, func, Content, Context, Dict, StyleChain, Styles};
|
use crate::foundations::{dict, func, Content, Context, Dict, StyleChain, Styles};
|
||||||
@ -43,7 +45,7 @@ pub fn measure(
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// The callsite span.
|
/// The callsite span.
|
||||||
span: Span,
|
span: Span,
|
||||||
/// The content whose size to measure.
|
/// The content whose size to measure.
|
||||||
|
@ -3,6 +3,8 @@ use std::num::NonZeroUsize;
|
|||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use comemo::Track;
|
||||||
|
|
||||||
use crate::diag::{bail, SourceResult};
|
use crate::diag::{bail, SourceResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
@ -691,7 +693,7 @@ impl Marginal {
|
|||||||
Ok(match self {
|
Ok(match self {
|
||||||
Self::Content(content) => Cow::Borrowed(content),
|
Self::Content(content) => Cow::Borrowed(content),
|
||||||
Self::Func(func) => Cow::Owned(
|
Self::Func(func) => Cow::Owned(
|
||||||
func.call(engine, &Context::new(None, Some(styles)), [page])?
|
func.call(engine, Context::new(None, Some(styles)).track(), [page])?
|
||||||
.display(),
|
.display(),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use comemo::Track;
|
||||||
|
|
||||||
use crate::diag::{At, SourceResult};
|
use crate::diag::{At, SourceResult};
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
cast, elem, Content, Context, Func, Packed, Resolve, Smart, StyleChain,
|
cast, elem, Content, Context, Func, Packed, Resolve, Smart, StyleChain,
|
||||||
@ -204,7 +206,7 @@ fn draw_cancel_line(
|
|||||||
CancelAngle::Angle(v) => *v,
|
CancelAngle::Angle(v) => *v,
|
||||||
// This specifies a function that takes the default angle as input.
|
// This specifies a function that takes the default angle as input.
|
||||||
CancelAngle::Func(func) => func
|
CancelAngle::Func(func) => func
|
||||||
.call(ctx.engine, &Context::new(None, Some(styles)), [default])?
|
.call(ctx.engine, Context::new(None, Some(styles)).track(), [default])?
|
||||||
.cast()
|
.cast()
|
||||||
.at(span)?,
|
.at(span)?,
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use comemo::Track;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
use crate::diag::{bail, SourceResult};
|
use crate::diag::{bail, SourceResult};
|
||||||
@ -247,7 +248,8 @@ impl LayoutMultiple for Packed<EnumElem> {
|
|||||||
let context = Context::new(None, Some(styles));
|
let context = Context::new(None, Some(styles));
|
||||||
let resolved = if full {
|
let resolved = if full {
|
||||||
parents.push(number);
|
parents.push(number);
|
||||||
let content = numbering.apply(engine, &context, &parents)?.display();
|
let content =
|
||||||
|
numbering.apply(engine, context.track(), &parents)?.display();
|
||||||
parents.pop();
|
parents.pop();
|
||||||
content
|
content
|
||||||
} else {
|
} else {
|
||||||
@ -255,7 +257,7 @@ impl LayoutMultiple for Packed<EnumElem> {
|
|||||||
Numbering::Pattern(pattern) => {
|
Numbering::Pattern(pattern) => {
|
||||||
TextElem::packed(pattern.apply_kth(parents.len(), number))
|
TextElem::packed(pattern.apply_kth(parents.len(), number))
|
||||||
}
|
}
|
||||||
other => other.apply(engine, &context, &[number])?.display(),
|
other => other.apply(engine, context.track(), &[number])?.display(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use comemo::Track;
|
||||||
|
|
||||||
use crate::diag::{bail, SourceResult};
|
use crate::diag::{bail, SourceResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
@ -218,7 +220,7 @@ impl ListMarker {
|
|||||||
list.get(depth % list.len()).cloned().unwrap_or_default()
|
list.get(depth % list.len()).cloned().unwrap_or_default()
|
||||||
}
|
}
|
||||||
Self::Func(func) => func
|
Self::Func(func) => func
|
||||||
.call(engine, &Context::new(None, Some(styles)), [depth])?
|
.call(engine, Context::new(None, Some(styles)).track(), [depth])?
|
||||||
.display(),
|
.display(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use chinese_number::{ChineseCase, ChineseCountMethod, ChineseVariant, NumberToChinese};
|
use chinese_number::{ChineseCase, ChineseCountMethod, ChineseVariant, NumberToChinese};
|
||||||
|
use comemo::Tracked;
|
||||||
use ecow::{eco_format, EcoString, EcoVec};
|
use ecow::{eco_format, EcoString, EcoVec};
|
||||||
|
|
||||||
use crate::diag::SourceResult;
|
use crate::diag::SourceResult;
|
||||||
@ -36,7 +37,7 @@ pub fn numbering(
|
|||||||
/// The engine.
|
/// The engine.
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
/// The callsite context.
|
/// The callsite context.
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
/// Defines how the numbering works.
|
/// Defines how the numbering works.
|
||||||
///
|
///
|
||||||
/// **Counting symbols** are `1`, `a`, `A`, `i`, `I`, `一`, `壹`, `あ`, `い`, `ア`, `イ`, `א`, `가`,
|
/// **Counting symbols** are `1`, `a`, `A`, `i`, `I`, `一`, `壹`, `あ`, `い`, `ア`, `イ`, `א`, `가`,
|
||||||
@ -85,7 +86,7 @@ impl Numbering {
|
|||||||
pub fn apply(
|
pub fn apply(
|
||||||
&self,
|
&self,
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
numbers: &[usize],
|
numbers: &[usize],
|
||||||
) -> SourceResult<Value> {
|
) -> SourceResult<Value> {
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use comemo::Track;
|
||||||
|
|
||||||
use crate::diag::{bail, At, SourceResult};
|
use crate::diag::{bail, At, SourceResult};
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::foundations::{
|
use crate::foundations::{
|
||||||
@ -381,7 +383,7 @@ impl OutlineIndent {
|
|||||||
Some(Smart::Custom(OutlineIndent::Func(func))) => {
|
Some(Smart::Custom(OutlineIndent::Func(func))) => {
|
||||||
let depth = ancestors.len();
|
let depth = ancestors.len();
|
||||||
let LengthOrContent(content) = func
|
let LengthOrContent(content) = func
|
||||||
.call(engine, &Context::new(None, Some(styles)), [depth])?
|
.call(engine, Context::new(None, Some(styles)).track(), [depth])?
|
||||||
.cast()
|
.cast()
|
||||||
.at(span)?;
|
.at(span)?;
|
||||||
if !content.is_empty() {
|
if !content.is_empty() {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
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};
|
||||||
@ -275,9 +276,9 @@ impl Supplement {
|
|||||||
) -> SourceResult<Content> {
|
) -> SourceResult<Content> {
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
Supplement::Content(content) => content.clone(),
|
Supplement::Content(content) => content.clone(),
|
||||||
Supplement::Func(func) => {
|
Supplement::Func(func) => func
|
||||||
func.call(engine, &Context::new(None, Some(styles)), args)?.display()
|
.call(engine, Context::new(None, Some(styles)).track(), args)?
|
||||||
}
|
.display(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::cell::OnceCell;
|
use std::cell::OnceCell;
|
||||||
|
|
||||||
|
use comemo::{Track, Tracked};
|
||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
|
|
||||||
use crate::diag::SourceResult;
|
use crate::diag::SourceResult;
|
||||||
@ -255,11 +256,11 @@ fn show(
|
|||||||
// text element. This invokes special regex handling.
|
// text element. This invokes special regex handling.
|
||||||
Some(Selector::Regex(regex)) => {
|
Some(Selector::Regex(regex)) => {
|
||||||
let text = target.into_packed::<TextElem>().unwrap();
|
let text = target.into_packed::<TextElem>().unwrap();
|
||||||
show_regex(engine, &text, regex, recipe, guard, &context)
|
show_regex(engine, &text, regex, recipe, guard, context.track())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just apply the recipe.
|
// Just apply the recipe.
|
||||||
_ => recipe.apply(engine, &context, target.guarded(guard)),
|
_ => recipe.apply(engine, context.track(), target.guarded(guard)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +277,7 @@ fn show_regex(
|
|||||||
regex: &Regex,
|
regex: &Regex,
|
||||||
recipe: &Recipe,
|
recipe: &Recipe,
|
||||||
index: RecipeIndex,
|
index: RecipeIndex,
|
||||||
context: &Context,
|
context: Tracked<Context>,
|
||||||
) -> SourceResult<Content> {
|
) -> SourceResult<Content> {
|
||||||
let make = |s: &str| {
|
let make = |s: &str| {
|
||||||
let mut fresh = target.clone();
|
let mut fresh = target.clone();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user