Show repr in monospace 📏
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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::<Value>(ctx, "value") {
|
||||
value.type_name().into()
|
||||
} else {
|
||||
Value::Error
|
||||
match args.require::<Value>(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::<Value>(ctx, "value") {
|
||||
Some(value) => pretty(&value).into(),
|
||||
None => Value::Error,
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.8 KiB |
@ -14,9 +14,8 @@
|
||||
{(true, false)}
|
||||
|
||||
// Multiple lines and items and trailing comma.
|
||||
{("one"
|
||||
, 2
|
||||
, #003
|
||||
{("1"
|
||||
, #002
|
||||
,)}
|
||||
|
||||
// Error: 3 expected closing paren
|
||||
|
@ -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("]
|
||||
|
@ -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 `<function f> (Okay.)`.
|
||||
#f (Okay.)
|
||||
// Should output `<function args> (Okay.)`.
|
||||
#args (Okay.)
|
||||
|
||||
---
|
||||
// Call function assigned to variable.
|
||||
|
@ -5,7 +5,7 @@
|
||||
{(:)}
|
||||
|
||||
// Two pairs.
|
||||
{(one: 1, two: 2)}
|
||||
{(a1: 1, a2: 2)}
|
||||
|
||||
---
|
||||
// Simple expression after already being identified as a dictionary.
|
||||
|
@ -33,6 +33,9 @@
|
||||
{2.5rad} \
|
||||
{45deg} \
|
||||
|
||||
// Not in monospace via repr.
|
||||
#repr(45deg)
|
||||
|
||||
---
|
||||
// Colors.
|
||||
{#f7a20500} \
|
||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.0 KiB |
@ -312,7 +312,7 @@ struct Panic {
|
||||
}
|
||||
|
||||
fn register_helpers(scope: &mut Scope, panics: Rc<RefCell<Vec<Panic>>>) {
|
||||
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<RefCell<Vec<Panic>>>) {
|
||||
}
|
||||
};
|
||||
|
||||
scope.def_const("f", ValueFunc::new("f", f));
|
||||
scope.def_const("args", ValueFunc::new("args", args));
|
||||
scope.def_const("test", ValueFunc::new("test", test));
|
||||
}
|
||||
|
||||
|