Show repr in monospace 📏

This commit is contained in:
Laurenz 2021-02-18 14:17:20 +01:00
parent cc964e32c9
commit ed81049ddc
17 changed files with 73 additions and 41 deletions

View File

@ -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. /// Apply a forced line break.
pub fn apply_linebreak(&mut self) { pub fn apply_linebreak(&mut self) {
self.end_par_group(); self.end_par_group();

View File

@ -97,9 +97,7 @@ impl ExecWithMap for NodeHeading {
impl Exec for NodeRaw { impl Exec for NodeRaw {
fn exec(&self, ctx: &mut ExecContext) { fn exec(&self, ctx: &mut ExecContext) {
let prev = Rc::clone(&ctx.state.font.families); let prev = Rc::clone(&ctx.state.font.families);
let families = ctx.state.font.families_mut(); ctx.apply_monospace();
families.list.insert(0, "monospace".to_string());
families.flatten();
let em = ctx.state.font.font_size(); let em = ctx.state.font.font_size();
let line_spacing = ctx.state.par.line_spacing.resolve(em); let line_spacing = ctx.state.par.line_spacing.resolve(em);
@ -136,9 +134,19 @@ impl Exec for Value {
fn exec(&self, ctx: &mut ExecContext) { fn exec(&self, ctx: &mut ExecContext) {
match self { match self {
Value::None => {} 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::Str(s) => ctx.push_text(s),
Value::Template(template) => template.exec(ctx), 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;
}
} }
} }
} }

View File

@ -1,4 +1,5 @@
use crate::prelude::*; use crate::prelude::*;
use crate::pretty::pretty;
/// `type`: Find out the name of a value's type. /// `type`: Find out the name of a value's type.
/// ///
@ -8,9 +9,22 @@ use crate::prelude::*;
/// # Return value /// # Return value
/// The name of the value's type as a string. /// The name of the value's type as a string.
pub fn type_(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value { pub fn type_(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
if let Some(value) = args.require::<Value>(ctx, "value") { match args.require::<Value>(ctx, "value") {
value.type_name().into() Some(value) => value.type_name().into(),
} else { None => Value::Error,
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,
} }
} }

View File

@ -38,6 +38,7 @@ pub fn new() -> Scope {
set!(func: "image", image); set!(func: "image", image);
set!(func: "page", page); set!(func: "page", page);
set!(func: "pagebreak", pagebreak); set!(func: "pagebreak", pagebreak);
set!(func: "repr", repr);
set!(func: "rgb", rgb); set!(func: "rgb", rgb);
set!(func: "type", type_); set!(func: "type", type_);
set!(func: "v", v); set!(func: "v", v);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -14,9 +14,8 @@
{(true, false)} {(true, false)}
// Multiple lines and items and trailing comma. // Multiple lines and items and trailing comma.
{("one" {("1"
, 2 , #002
, #003
,)} ,)}
// Error: 3 expected closing paren // Error: 3 expected closing paren

View File

@ -5,24 +5,24 @@
# #
--- ---
// Error: 4-5 expected expression, found colon // Error: 7-8 expected expression, found colon
#f(:) #args(:)
// Error: 7-9 expected expression, found end of block comment // Error: 10-12 expected expression, found end of block comment
#f(a:1*/) #args(a:1*/)
// Error: 5 expected comma // Error: 8 expected comma
#f(1 2) #args(1 2)
// Error: 2:4-2:5 expected identifier // Error: 2:7-2:8 expected identifier
// Error: 1:6 expected expression // Error: 1:9 expected expression
#f(1:) #args(1:)
// Error: 4-5 expected identifier // Error: 7-8 expected identifier
#f(1:2) #args(1:2)
// Error: 4-7 expected identifier // Error: 7-10 expected identifier
{f((x):1)} {args((x):1)}
--- ---
#let x = "string" #let x = "string"
@ -32,13 +32,13 @@
--- ---
// Error: 3:1 expected closing bracket // Error: 3:1 expected closing bracket
#f[`a]` #args[`a]`
--- ---
// Error: 4 expected closing paren // Error: 7 expected closing paren
{f(} {args(}
--- ---
// Error: 3:1 expected quote // Error: 3:1 expected quote
// Error: 2:1 expected closing paren // Error: 2:1 expected closing paren
#f("] #args("]

View File

@ -2,16 +2,16 @@
--- ---
// One argument. // One argument.
#f(bold) #args(bold)
// One argument and trailing comma. // One argument and trailing comma.
#f(1,) #args(1,)
// One named argument. // One named argument.
#f(a:2) #args(a:2)
// Mixed arguments. // Mixed arguments.
{f(1, a: (3, 4), 2, b: "5")} {args(1, b: "2", 3)}
--- ---
// Different forms of template arguments. // Different forms of template arguments.
@ -19,17 +19,17 @@
#let a = "a" #let a = "a"
#f[a] \ #args[a] \
#f(a) \ #args(a) \
#f(a, [b]) \ #args(a, [b]) \
#f(a)[b] \ #args(a)[b] \
// Template can be argument or body depending on whitespace. // Template can be argument or body depending on whitespace.
#if "template" == type[b] [Sure ] #if "template" == type[b] [Sure ]
#if "template" == type [Nope.] #else [thing.] #if "template" == type [Nope.] #else [thing.]
// Should output `<function f> (Okay.)`. // Should output `<function args> (Okay.)`.
#f (Okay.) #args (Okay.)
--- ---
// Call function assigned to variable. // Call function assigned to variable.

View File

@ -5,7 +5,7 @@
{(:)} {(:)}
// Two pairs. // Two pairs.
{(one: 1, two: 2)} {(a1: 1, a2: 2)}
--- ---
// Simple expression after already being identified as a dictionary. // Simple expression after already being identified as a dictionary.

View File

@ -33,6 +33,9 @@
{2.5rad} \ {2.5rad} \
{45deg} \ {45deg} \
// Not in monospace via repr.
#repr(45deg)
--- ---
// Colors. // Colors.
{#f7a20500} \ {#f7a20500} \

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -312,7 +312,7 @@ struct Panic {
} }
fn register_helpers(scope: &mut Scope, panics: Rc<RefCell<Vec<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(); let value = args.clone().into();
args.items.clear(); args.items.clear();
value 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)); scope.def_const("test", ValueFunc::new("test", test));
} }