diff --git a/src/exec/context.rs b/src/exec/context.rs index 821a26164..5ff55c00b 100644 --- a/src/exec/context.rs +++ b/src/exec/context.rs @@ -259,6 +259,13 @@ impl<'a> ExecContext<'a> { } } + /// Set the font to monospace. + pub fn apply_monospace(&mut self) { + let families = self.state.font.families_mut(); + families.list.insert(0, "monospace".to_string()); + families.flatten(); + } + /// Apply a forced line break. pub fn apply_linebreak(&mut self) { self.end_par_group(); diff --git a/src/exec/mod.rs b/src/exec/mod.rs index cafc55cdb..3dbe82703 100644 --- a/src/exec/mod.rs +++ b/src/exec/mod.rs @@ -97,9 +97,7 @@ impl ExecWithMap for NodeHeading { impl Exec for NodeRaw { fn exec(&self, ctx: &mut ExecContext) { let prev = Rc::clone(&ctx.state.font.families); - let families = ctx.state.font.families_mut(); - families.list.insert(0, "monospace".to_string()); - families.flatten(); + ctx.apply_monospace(); let em = ctx.state.font.font_size(); let line_spacing = ctx.state.par.line_spacing.resolve(em); @@ -136,9 +134,19 @@ impl Exec for Value { fn exec(&self, ctx: &mut ExecContext) { match self { Value::None => {} + Value::Int(v) => ctx.push_text(pretty(v)), + Value::Float(v) => ctx.push_text(pretty(v)), Value::Str(s) => ctx.push_text(s), Value::Template(template) => template.exec(ctx), - other => ctx.push_text(pretty(other)), + Value::Error => {} + other => { + // For values which can't be shown "naturally", we print + // the representation in monospace. + let prev = Rc::clone(&ctx.state.font.families); + ctx.apply_monospace(); + ctx.push_text(pretty(other)); + ctx.state.font.families = prev; + } } } } diff --git a/src/library/extend.rs b/src/library/extend.rs index 6396274e0..cf69dbd0d 100644 --- a/src/library/extend.rs +++ b/src/library/extend.rs @@ -1,4 +1,5 @@ use crate::prelude::*; +use crate::pretty::pretty; /// `type`: Find out the name of a value's type. /// @@ -8,9 +9,22 @@ use crate::prelude::*; /// # Return value /// The name of the value's type as a string. pub fn type_(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value { - if let Some(value) = args.require::(ctx, "value") { - value.type_name().into() - } else { - Value::Error + match args.require::(ctx, "value") { + Some(value) => value.type_name().into(), + None => Value::Error, + } +} + +/// `repr`: Get the string representation of a value. +/// +/// # Positional arguments +/// - Any value. +/// +/// # Return value +/// The string representation of the value. +pub fn repr(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value { + match args.require::(ctx, "value") { + Some(value) => pretty(&value).into(), + None => Value::Error, } } diff --git a/src/library/mod.rs b/src/library/mod.rs index 48da093b2..59198846d 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -38,6 +38,7 @@ pub fn new() -> Scope { set!(func: "image", image); set!(func: "page", page); set!(func: "pagebreak", pagebreak); + set!(func: "repr", repr); set!(func: "rgb", rgb); set!(func: "type", type_); set!(func: "v", v); diff --git a/tests/lang/ref/array.png b/tests/lang/ref/array.png index 36845b5f2..5bfddeb18 100644 Binary files a/tests/lang/ref/array.png and b/tests/lang/ref/array.png differ diff --git a/tests/lang/ref/call-invalid.png b/tests/lang/ref/call-invalid.png index f6c2d67f2..eee20e4d2 100644 Binary files a/tests/lang/ref/call-invalid.png and b/tests/lang/ref/call-invalid.png differ diff --git a/tests/lang/ref/call.png b/tests/lang/ref/call.png index d44d7178a..5963d30ea 100644 Binary files a/tests/lang/ref/call.png and b/tests/lang/ref/call.png differ diff --git a/tests/lang/ref/dict.png b/tests/lang/ref/dict.png index 45d23ad39..b30f13000 100644 Binary files a/tests/lang/ref/dict.png and b/tests/lang/ref/dict.png differ diff --git a/tests/lang/ref/if.png b/tests/lang/ref/if.png index 4e7f471a4..75a20d000 100644 Binary files a/tests/lang/ref/if.png and b/tests/lang/ref/if.png differ diff --git a/tests/lang/ref/repr.png b/tests/lang/ref/repr.png index 16c7ea958..13ba62972 100644 Binary files a/tests/lang/ref/repr.png and b/tests/lang/ref/repr.png differ diff --git a/tests/lang/typ/array.typ b/tests/lang/typ/array.typ index b17b722c5..c93835017 100644 --- a/tests/lang/typ/array.typ +++ b/tests/lang/typ/array.typ @@ -14,9 +14,8 @@ {(true, false)} // Multiple lines and items and trailing comma. -{("one" - , 2 - , #003 +{("1" + , #002 ,)} // Error: 3 expected closing paren diff --git a/tests/lang/typ/call-invalid.typ b/tests/lang/typ/call-invalid.typ index 56b23a195..0ed5246ff 100644 --- a/tests/lang/typ/call-invalid.typ +++ b/tests/lang/typ/call-invalid.typ @@ -5,24 +5,24 @@ # --- -// Error: 4-5 expected expression, found colon -#f(:) +// Error: 7-8 expected expression, found colon +#args(:) -// Error: 7-9 expected expression, found end of block comment -#f(a:1*/) +// Error: 10-12 expected expression, found end of block comment +#args(a:1*/) -// Error: 5 expected comma -#f(1 2) +// Error: 8 expected comma +#args(1 2) -// Error: 2:4-2:5 expected identifier -// Error: 1:6 expected expression -#f(1:) +// Error: 2:7-2:8 expected identifier +// Error: 1:9 expected expression +#args(1:) -// Error: 4-5 expected identifier -#f(1:2) +// Error: 7-8 expected identifier +#args(1:2) -// Error: 4-7 expected identifier -{f((x):1)} +// Error: 7-10 expected identifier +{args((x):1)} --- #let x = "string" @@ -32,13 +32,13 @@ --- // Error: 3:1 expected closing bracket -#f[`a]` +#args[`a]` --- -// Error: 4 expected closing paren -{f(} +// Error: 7 expected closing paren +{args(} --- // Error: 3:1 expected quote // Error: 2:1 expected closing paren -#f("] +#args("] diff --git a/tests/lang/typ/call.typ b/tests/lang/typ/call.typ index 101fb99c2..213d55541 100644 --- a/tests/lang/typ/call.typ +++ b/tests/lang/typ/call.typ @@ -2,16 +2,16 @@ --- // One argument. -#f(bold) +#args(bold) // One argument and trailing comma. -#f(1,) +#args(1,) // One named argument. -#f(a:2) +#args(a:2) // Mixed arguments. -{f(1, a: (3, 4), 2, b: "5")} +{args(1, b: "2", 3)} --- // Different forms of template arguments. @@ -19,17 +19,17 @@ #let a = "a" -#f[a] \ -#f(a) \ -#f(a, [b]) \ -#f(a)[b] \ +#args[a] \ +#args(a) \ +#args(a, [b]) \ +#args(a)[b] \ // Template can be argument or body depending on whitespace. #if "template" == type[b] [Sure ] #if "template" == type [Nope.] #else [thing.] -// Should output ` (Okay.)`. -#f (Okay.) +// Should output ` (Okay.)`. +#args (Okay.) --- // Call function assigned to variable. diff --git a/tests/lang/typ/dict.typ b/tests/lang/typ/dict.typ index 076a572f0..655a32992 100644 --- a/tests/lang/typ/dict.typ +++ b/tests/lang/typ/dict.typ @@ -5,7 +5,7 @@ {(:)} // Two pairs. -{(one: 1, two: 2)} +{(a1: 1, a2: 2)} --- // Simple expression after already being identified as a dictionary. diff --git a/tests/lang/typ/repr.typ b/tests/lang/typ/repr.typ index 6229165aa..666db4285 100644 --- a/tests/lang/typ/repr.typ +++ b/tests/lang/typ/repr.typ @@ -33,6 +33,9 @@ {2.5rad} \ {45deg} \ +// Not in monospace via repr. +#repr(45deg) + --- // Colors. {#f7a20500} \ diff --git a/tests/library/ref/rgb.png b/tests/library/ref/rgb.png index 3060e42c3..a6e6f7d41 100644 Binary files a/tests/library/ref/rgb.png and b/tests/library/ref/rgb.png differ diff --git a/tests/typeset.rs b/tests/typeset.rs index ac4fe9b01..3041499a3 100644 --- a/tests/typeset.rs +++ b/tests/typeset.rs @@ -312,7 +312,7 @@ struct Panic { } fn register_helpers(scope: &mut Scope, panics: Rc>>) { - pub fn f(_: &mut EvalContext, args: &mut ValueArgs) -> Value { + pub fn args(_: &mut EvalContext, args: &mut ValueArgs) -> Value { let value = args.clone().into(); args.items.clear(); value @@ -329,7 +329,7 @@ fn register_helpers(scope: &mut Scope, panics: Rc>>) { } }; - scope.def_const("f", ValueFunc::new("f", f)); + scope.def_const("args", ValueFunc::new("args", args)); scope.def_const("test", ValueFunc::new("test", test)); }