mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Better value representations, type function 🌐
This commit is contained in:
parent
77c06ebc24
commit
2e77b1c836
30
src/color.rs
30
src/color.rs
@ -1,6 +1,6 @@
|
||||
//! Color handling.
|
||||
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
use std::str::FromStr;
|
||||
|
||||
/// A color in a dynamic format.
|
||||
@ -10,10 +10,18 @@ pub enum Color {
|
||||
Rgba(RgbaColor),
|
||||
}
|
||||
|
||||
impl Display for Color {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::Rgba(c) => Display::fmt(c, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Color {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::Rgba(c) => c.fmt(f),
|
||||
Self::Rgba(c) => Debug::fmt(c, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,6 +84,16 @@ impl FromStr for RgbaColor {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for RgbaColor {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)?;
|
||||
if self.a != 255 {
|
||||
write!(f, "{:02x}", self.a)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for RgbaColor {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
if f.alternate() {
|
||||
@ -83,14 +101,10 @@ impl Debug for RgbaColor {
|
||||
f,
|
||||
"rgba({:02}, {:02}, {:02}, {:02})",
|
||||
self.r, self.g, self.b, self.a,
|
||||
)?;
|
||||
)
|
||||
} else {
|
||||
write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)?;
|
||||
if self.a != 255 {
|
||||
write!(f, "{:02x}", self.a)?;
|
||||
}
|
||||
Display::fmt(self, f)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,15 +119,17 @@ impl EvalContext {
|
||||
if !children.is_empty() || keep_empty(group.softness) {
|
||||
self.runs.push(NodePages {
|
||||
size: group.size,
|
||||
child: Node::any(NodePad {
|
||||
child: NodePad {
|
||||
padding: group.padding,
|
||||
child: Node::any(NodeStack {
|
||||
child: NodeStack {
|
||||
dirs: group.dirs,
|
||||
align: group.align,
|
||||
expansion: Gen::uniform(Expansion::Fill),
|
||||
children,
|
||||
}),
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
}
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
group.softness
|
||||
|
@ -128,7 +128,22 @@ impl StateFont {
|
||||
impl Default for StateFont {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
families: Rc::new(default_font_families()),
|
||||
/// The default tree of font fallbacks.
|
||||
families: Rc::new(fallback! {
|
||||
list: ["sans-serif"],
|
||||
classes: {
|
||||
"serif" => ["source serif pro", "noto serif"],
|
||||
"sans-serif" => ["source sans pro", "noto sans"],
|
||||
"monospace" => ["source code pro", "noto sans mono"],
|
||||
},
|
||||
base: [
|
||||
"source sans pro",
|
||||
"noto sans",
|
||||
"segoe ui emoji",
|
||||
"noto emoji",
|
||||
"latin modern math",
|
||||
],
|
||||
}),
|
||||
variant: FontVariant {
|
||||
style: FontStyle::Normal,
|
||||
weight: FontWeight::REGULAR,
|
||||
@ -141,22 +156,3 @@ impl Default for StateFont {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The default tree of font fallbacks.
|
||||
fn default_font_families() -> FallbackTree {
|
||||
fallback! {
|
||||
list: ["sans-serif"],
|
||||
classes: {
|
||||
"serif" => ["source serif pro", "noto serif"],
|
||||
"sans-serif" => ["source sans pro", "noto sans"],
|
||||
"monospace" => ["source code pro", "noto sans mono"],
|
||||
},
|
||||
base: [
|
||||
"source sans pro",
|
||||
"noto sans",
|
||||
"segoe ui emoji",
|
||||
"noto emoji",
|
||||
"latin modern math",
|
||||
],
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -45,14 +45,6 @@ pub enum Value {
|
||||
}
|
||||
|
||||
impl Value {
|
||||
/// Create a new dynamic value.
|
||||
pub fn any<T>(any: T) -> Self
|
||||
where
|
||||
T: Type + Debug + Clone + PartialEq + 'static,
|
||||
{
|
||||
Self::Any(ValueAny::new(any))
|
||||
}
|
||||
|
||||
/// Try to cast the value into a specific type.
|
||||
pub fn cast<T>(self) -> CastResult<T, Self>
|
||||
where
|
||||
@ -68,8 +60,8 @@ impl Value {
|
||||
Self::Bool(_) => bool::TYPE_NAME,
|
||||
Self::Int(_) => i64::TYPE_NAME,
|
||||
Self::Float(_) => f64::TYPE_NAME,
|
||||
Self::Relative(_) => Relative::TYPE_NAME,
|
||||
Self::Length(_) => Length::TYPE_NAME,
|
||||
Self::Relative(_) => Relative::TYPE_NAME,
|
||||
Self::Linear(_) => Linear::TYPE_NAME,
|
||||
Self::Color(_) => Color::TYPE_NAME,
|
||||
Self::Str(_) => String::TYPE_NAME,
|
||||
@ -88,16 +80,24 @@ impl Eval for &Value {
|
||||
|
||||
/// Evaluate everything contained in this value.
|
||||
fn eval(self, ctx: &mut EvalContext) -> Self::Output {
|
||||
match self {
|
||||
// Don't print out none values.
|
||||
Value::None => {}
|
||||
|
||||
// Pass through.
|
||||
Value::Content(tree) => tree.eval(ctx),
|
||||
|
||||
// Format with debug.
|
||||
val => ctx.push(ctx.make_text_node(format!("{:?}", val))),
|
||||
}
|
||||
ctx.push(ctx.make_text_node(match self {
|
||||
Value::None => return,
|
||||
Value::Bool(v) => v.to_string(),
|
||||
Value::Int(v) => v.to_string(),
|
||||
Value::Float(v) => v.to_string(),
|
||||
Value::Length(v) => v.to_string(),
|
||||
Value::Relative(v) => v.to_string(),
|
||||
Value::Linear(v) => v.to_string(),
|
||||
Value::Color(v) => v.to_string(),
|
||||
Value::Str(v) => v.clone(),
|
||||
// TODO: Find good representation for composite types.
|
||||
Value::Array(_v) => "(array)".into(),
|
||||
Value::Dict(_v) => "(dictionary)".into(),
|
||||
Value::Content(tree) => return tree.eval(ctx),
|
||||
Value::Func(v) => v.to_string(),
|
||||
Value::Any(v) => v.to_string(),
|
||||
Value::Error => "(error)".into(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,21 +110,21 @@ impl Default for Value {
|
||||
impl Debug for Value {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::None => f.pad("none"),
|
||||
Self::Bool(v) => v.fmt(f),
|
||||
Self::Int(v) => v.fmt(f),
|
||||
Self::Float(v) => v.fmt(f),
|
||||
Self::Length(v) => v.fmt(f),
|
||||
Self::Relative(v) => v.fmt(f),
|
||||
Self::Linear(v) => v.fmt(f),
|
||||
Self::Color(v) => v.fmt(f),
|
||||
Self::Str(v) => v.fmt(f),
|
||||
Self::Array(v) => v.fmt(f),
|
||||
Self::Dict(v) => v.fmt(f),
|
||||
Self::Content(v) => v.fmt(f),
|
||||
Self::Func(v) => v.fmt(f),
|
||||
Self::Any(v) => v.fmt(f),
|
||||
Self::Error => f.pad("<error>"),
|
||||
Self::None => f.pad("None"),
|
||||
Self::Bool(v) => Debug::fmt(v, f),
|
||||
Self::Int(v) => Debug::fmt(v, f),
|
||||
Self::Float(v) => Debug::fmt(v, f),
|
||||
Self::Length(v) => Debug::fmt(v, f),
|
||||
Self::Relative(v) => Debug::fmt(v, f),
|
||||
Self::Linear(v) => Debug::fmt(v, f),
|
||||
Self::Color(v) => Debug::fmt(v, f),
|
||||
Self::Str(v) => Debug::fmt(v, f),
|
||||
Self::Array(v) => Debug::fmt(v, f),
|
||||
Self::Dict(v) => Debug::fmt(v, f),
|
||||
Self::Content(v) => Debug::fmt(v, f),
|
||||
Self::Func(v) => Debug::fmt(v, f),
|
||||
Self::Any(v) => Debug::fmt(v, f),
|
||||
Self::Error => f.pad("Error"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,15 +140,18 @@ pub type ValueContent = Tree;
|
||||
|
||||
/// A wrapper around a reference-counted executable function.
|
||||
#[derive(Clone)]
|
||||
pub struct ValueFunc(Rc<dyn Fn(&mut EvalContext, &mut Args) -> Value>);
|
||||
pub struct ValueFunc {
|
||||
name: String,
|
||||
f: Rc<dyn Fn(&mut EvalContext, &mut Args) -> Value>,
|
||||
}
|
||||
|
||||
impl ValueFunc {
|
||||
/// Create a new function value from a rust function or closure.
|
||||
pub fn new<F>(func: F) -> Self
|
||||
pub fn new<F>(name: impl Into<String>, f: F) -> Self
|
||||
where
|
||||
F: Fn(&mut EvalContext, &mut Args) -> Value + 'static,
|
||||
{
|
||||
Self(Rc::new(func))
|
||||
Self { name: name.into(), f: Rc::new(f) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,13 +165,18 @@ impl Deref for ValueFunc {
|
||||
type Target = dyn Fn(&mut EvalContext, &mut Args) -> Value;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.as_ref()
|
||||
self.f.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for ValueFunc {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "<function {}>", self.name)
|
||||
}
|
||||
}
|
||||
impl Debug for ValueFunc {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
f.pad("<function>")
|
||||
Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,7 +187,7 @@ impl ValueAny {
|
||||
/// Create a new instance from any value that satisifies the required bounds.
|
||||
pub fn new<T>(any: T) -> Self
|
||||
where
|
||||
T: Type + Debug + Clone + PartialEq + 'static,
|
||||
T: Type + Debug + Display + Clone + PartialEq + 'static,
|
||||
{
|
||||
Self(Box::new(any))
|
||||
}
|
||||
@ -221,13 +229,19 @@ impl PartialEq for ValueAny {
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for ValueAny {
|
||||
impl Display for ValueAny {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
trait Bounds: Debug + 'static {
|
||||
impl Debug for ValueAny {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
Debug::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
trait Bounds: Debug + Display + 'static {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn into_any(self: Box<Self>) -> Box<dyn Any>;
|
||||
fn dyn_eq(&self, other: &ValueAny) -> bool;
|
||||
@ -237,7 +251,7 @@ trait Bounds: Debug + 'static {
|
||||
|
||||
impl<T> Bounds for T
|
||||
where
|
||||
T: Type + Debug + Clone + PartialEq + 'static,
|
||||
T: Type + Debug + Display + Clone + PartialEq + 'static,
|
||||
{
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
@ -304,6 +318,16 @@ impl<T, V> CastResult<T, V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Type for Value {
|
||||
const TYPE_NAME: &'static str = "value";
|
||||
}
|
||||
|
||||
impl Cast<Value> for Value {
|
||||
fn cast(value: Value) -> CastResult<Self, Value> {
|
||||
CastResult::Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Cast<Spanned<Value>> for T
|
||||
where
|
||||
T: Cast<Value>,
|
||||
@ -390,15 +414,6 @@ impl From<&str> for Value {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> From<F> for Value
|
||||
where
|
||||
F: Fn(&mut EvalContext, &mut Args) -> Value + 'static,
|
||||
{
|
||||
fn from(func: F) -> Self {
|
||||
Self::Func(ValueFunc::new(func))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValueAny> for Value {
|
||||
fn from(v: ValueAny) -> Self {
|
||||
Self::Any(v)
|
||||
@ -407,9 +422,8 @@ impl From<ValueAny> for Value {
|
||||
|
||||
/// Make a type usable as a [`Value`].
|
||||
///
|
||||
/// Given a type `T`, this implements the following traits:
|
||||
/// Given a type `T`, this always implements the following traits:
|
||||
/// - [`Type`] for `T`,
|
||||
/// - [`From<T>`](From) for [`Value`],
|
||||
/// - [`Cast<Value>`](Cast) for `T`.
|
||||
#[macro_export]
|
||||
macro_rules! impl_type {
|
||||
@ -423,12 +437,6 @@ macro_rules! impl_type {
|
||||
const TYPE_NAME: &'static str = $type_name;
|
||||
}
|
||||
|
||||
impl From<$type> for $crate::eval::Value {
|
||||
fn from(any: $type) -> Self {
|
||||
$crate::eval::Value::any(any)
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::eval::Cast<$crate::eval::Value> for $type {
|
||||
fn cast(
|
||||
value: $crate::eval::Value,
|
||||
|
@ -90,7 +90,7 @@ impl Display for Length {
|
||||
} else {
|
||||
(self.to_cm(), Unit::Cm)
|
||||
};
|
||||
write!(f, "{:.2}{}", val, unit)
|
||||
write!(f, "{}{}", (val * 100.0).round() / 100.0, unit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,8 +214,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_length_formatting() {
|
||||
assert_eq!(Length::pt(-28.34).to_string(), "-1.00cm".to_string());
|
||||
assert_eq!(Length::pt(23.0).to_string(), "23.00pt".to_string());
|
||||
assert_eq!(Length::pt(-28.34).to_string(), "-1cm".to_string());
|
||||
assert_eq!(Length::pt(23.0).to_string(), "23pt".to_string());
|
||||
assert_eq!(Length::cm(12.728).to_string(), "12.73cm".to_string());
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ impl Relative {
|
||||
|
||||
impl Display for Relative {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "{:.2}%", self.0)
|
||||
write!(f, "{}%", (self.0 * 10000.0).round() / 100.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,8 +25,8 @@ impl Layout for NodeFixed {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NodeFixed> for Node {
|
||||
impl From<NodeFixed> for NodeAny {
|
||||
fn from(fixed: NodeFixed) -> Self {
|
||||
Self::any(fixed)
|
||||
Self::new(fixed)
|
||||
}
|
||||
}
|
||||
|
@ -14,16 +14,6 @@ pub enum Node {
|
||||
Any(NodeAny),
|
||||
}
|
||||
|
||||
impl Node {
|
||||
/// Create a new dynamic node.
|
||||
pub fn any<T>(any: T) -> Self
|
||||
where
|
||||
T: Layout + Debug + Clone + PartialEq + 'static,
|
||||
{
|
||||
Self::Any(NodeAny::new(any))
|
||||
}
|
||||
}
|
||||
|
||||
impl Layout for Node {
|
||||
fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted {
|
||||
match self {
|
||||
@ -81,9 +71,12 @@ impl Debug for NodeAny {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NodeAny> for Node {
|
||||
fn from(dynamic: NodeAny) -> Self {
|
||||
Self::Any(dynamic)
|
||||
impl<T> From<T> for Node
|
||||
where
|
||||
T: Into<NodeAny>,
|
||||
{
|
||||
fn from(t: T) -> Self {
|
||||
Self::Any(t.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,9 +29,9 @@ impl Layout for NodePad {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NodePad> for Node {
|
||||
impl From<NodePad> for NodeAny {
|
||||
fn from(pad: NodePad) -> Self {
|
||||
Self::any(pad)
|
||||
Self::new(pad)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,9 +36,9 @@ impl Layout for NodePar {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NodePar> for Node {
|
||||
impl From<NodePar> for NodeAny {
|
||||
fn from(par: NodePar) -> Self {
|
||||
Self::any(par)
|
||||
Self::new(par)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,9 @@ impl Layout for NodeStack {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NodeStack> for Node {
|
||||
impl From<NodeStack> for NodeAny {
|
||||
fn from(stack: NodeStack) -> Self {
|
||||
Self::any(stack)
|
||||
Self::new(stack)
|
||||
}
|
||||
}
|
||||
|
||||
|
16
src/library/extend.rs
Normal file
16
src/library/extend.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
/// `type`: Find out the name of a value's type.
|
||||
///
|
||||
/// # Positional arguments
|
||||
/// - Any value.
|
||||
///
|
||||
/// # Return value
|
||||
/// The name of the value's type as a string.
|
||||
pub fn type_(ctx: &mut EvalContext, args: &mut Args) -> Value {
|
||||
if let Some(value) = args.require::<Value>(ctx, "value") {
|
||||
value.type_name().into()
|
||||
} else {
|
||||
Value::Error
|
||||
}
|
||||
}
|
@ -83,8 +83,8 @@ impl Layout for NodeImage {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NodeImage> for Node {
|
||||
impl From<NodeImage> for NodeAny {
|
||||
fn from(image: NodeImage) -> Self {
|
||||
Self::any(image)
|
||||
Self::new(image)
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
use crate::eval::Softness;
|
||||
use crate::layout::{Expansion, NodeFixed, NodeSpacing, NodeStack};
|
||||
use crate::paper::{Paper, PaperClass};
|
||||
@ -153,7 +155,19 @@ impl Switch for Alignment {
|
||||
}
|
||||
|
||||
impl_type! {
|
||||
Alignment: "alignment"
|
||||
Alignment: "alignment",
|
||||
}
|
||||
|
||||
impl Display for Alignment {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
f.pad(match self {
|
||||
Self::Left => "left",
|
||||
Self::Center => "center",
|
||||
Self::Right => "right",
|
||||
Self::Top => "top",
|
||||
Self::Bottom => "bottom",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// `box`: Layout content into a box.
|
||||
@ -161,7 +175,7 @@ impl_type! {
|
||||
/// # Named arguments
|
||||
/// - Width of the box: `width`, of type `linear` relative to parent width.
|
||||
/// - Height of the box: `height`, of type `linear` relative to parent height.
|
||||
pub fn boxed(ctx: &mut EvalContext, args: &mut Args) -> Value {
|
||||
pub fn box_(ctx: &mut EvalContext, args: &mut Args) -> Value {
|
||||
let snapshot = ctx.state.clone();
|
||||
|
||||
let width = args.get(ctx, "width");
|
||||
@ -189,7 +203,7 @@ pub fn boxed(ctx: &mut EvalContext, args: &mut Args) -> Value {
|
||||
ctx.push(NodeFixed {
|
||||
width,
|
||||
height,
|
||||
child: Node::any(NodeStack { dirs, align, expansion, children }),
|
||||
child: NodeStack { dirs, align, expansion, children }.into(),
|
||||
});
|
||||
|
||||
ctx.state = snapshot;
|
||||
|
@ -1,67 +1,78 @@
|
||||
//! The standard library.
|
||||
|
||||
mod extend;
|
||||
mod insert;
|
||||
mod layout;
|
||||
mod style;
|
||||
|
||||
pub use extend::*;
|
||||
pub use insert::*;
|
||||
pub use layout::*;
|
||||
pub use style::*;
|
||||
|
||||
use fontdock::{FontStretch, FontStyle, FontWeight};
|
||||
|
||||
use crate::eval::Scope;
|
||||
use crate::eval::{Scope, ValueAny, ValueFunc};
|
||||
use crate::geom::Dir;
|
||||
|
||||
/// The scope containing the standard library.
|
||||
pub fn _std() -> Scope {
|
||||
let mut std = Scope::new();
|
||||
macro_rules! set {
|
||||
(func: $name:expr, $func:expr) => {
|
||||
std.set($name, ValueFunc::new($name, $func))
|
||||
};
|
||||
(any: $var:expr, $any:expr) => {
|
||||
std.set($var, ValueAny::new($any))
|
||||
};
|
||||
}
|
||||
|
||||
// Functions.
|
||||
std.set("align", align);
|
||||
std.set("box", boxed);
|
||||
std.set("font", font);
|
||||
std.set("h", h);
|
||||
std.set("image", image);
|
||||
std.set("page", page);
|
||||
std.set("pagebreak", pagebreak);
|
||||
std.set("rgb", rgb);
|
||||
std.set("v", v);
|
||||
set!(func: "align", align);
|
||||
set!(func: "box", box_);
|
||||
set!(func: "font", font);
|
||||
set!(func: "h", h);
|
||||
set!(func: "image", image);
|
||||
set!(func: "page", page);
|
||||
set!(func: "pagebreak", pagebreak);
|
||||
set!(func: "rgb", rgb);
|
||||
set!(func: "type", type_);
|
||||
set!(func: "v", v);
|
||||
|
||||
// Constants.
|
||||
std.set("left", Alignment::Left);
|
||||
std.set("center", Alignment::Center);
|
||||
std.set("right", Alignment::Right);
|
||||
std.set("top", Alignment::Top);
|
||||
std.set("bottom", Alignment::Bottom);
|
||||
std.set("ltr", Dir::LTR);
|
||||
std.set("rtl", Dir::RTL);
|
||||
std.set("ttb", Dir::TTB);
|
||||
std.set("btt", Dir::BTT);
|
||||
std.set("serif", FontFamily::Serif);
|
||||
std.set("sans-serif", FontFamily::SansSerif);
|
||||
std.set("monospace", FontFamily::Monospace);
|
||||
std.set("normal", FontStyle::Normal);
|
||||
std.set("italic", FontStyle::Italic);
|
||||
std.set("oblique", FontStyle::Oblique);
|
||||
std.set("thin", FontWeight::THIN);
|
||||
std.set("extralight", FontWeight::EXTRALIGHT);
|
||||
std.set("light", FontWeight::LIGHT);
|
||||
std.set("regular", FontWeight::REGULAR);
|
||||
std.set("medium", FontWeight::MEDIUM);
|
||||
std.set("semibold", FontWeight::SEMIBOLD);
|
||||
std.set("bold", FontWeight::BOLD);
|
||||
std.set("extrabold", FontWeight::EXTRABOLD);
|
||||
std.set("black", FontWeight::BLACK);
|
||||
std.set("ultra-condensed", FontStretch::UltraCondensed);
|
||||
std.set("extra-condensed", FontStretch::ExtraCondensed);
|
||||
std.set("condensed", FontStretch::Condensed);
|
||||
std.set("semi-condensed", FontStretch::SemiCondensed);
|
||||
std.set("normal", FontStretch::Normal);
|
||||
std.set("semi-expanded", FontStretch::SemiExpanded);
|
||||
std.set("expanded", FontStretch::Expanded);
|
||||
std.set("extra-expanded", FontStretch::ExtraExpanded);
|
||||
std.set("ultra-expanded", FontStretch::UltraExpanded);
|
||||
set!(any: "left", Alignment::Left);
|
||||
set!(any: "center", Alignment::Center);
|
||||
set!(any: "right", Alignment::Right);
|
||||
set!(any: "top", Alignment::Top);
|
||||
set!(any: "bottom", Alignment::Bottom);
|
||||
set!(any: "ltr", Dir::LTR);
|
||||
set!(any: "rtl", Dir::RTL);
|
||||
set!(any: "ttb", Dir::TTB);
|
||||
set!(any: "btt", Dir::BTT);
|
||||
set!(any: "serif", FontFamily::Serif);
|
||||
set!(any: "sans-serif", FontFamily::SansSerif);
|
||||
set!(any: "monospace", FontFamily::Monospace);
|
||||
set!(any: "normal", FontStyle::Normal);
|
||||
set!(any: "italic", FontStyle::Italic);
|
||||
set!(any: "oblique", FontStyle::Oblique);
|
||||
set!(any: "thin", FontWeight::THIN);
|
||||
set!(any: "extralight", FontWeight::EXTRALIGHT);
|
||||
set!(any: "light", FontWeight::LIGHT);
|
||||
set!(any: "regular", FontWeight::REGULAR);
|
||||
set!(any: "medium", FontWeight::MEDIUM);
|
||||
set!(any: "semibold", FontWeight::SEMIBOLD);
|
||||
set!(any: "bold", FontWeight::BOLD);
|
||||
set!(any: "extrabold", FontWeight::EXTRABOLD);
|
||||
set!(any: "black", FontWeight::BLACK);
|
||||
set!(any: "ultra-condensed", FontStretch::UltraCondensed);
|
||||
set!(any: "extra-condensed", FontStretch::ExtraCondensed);
|
||||
set!(any: "condensed", FontStretch::Condensed);
|
||||
set!(any: "semi-condensed", FontStretch::SemiCondensed);
|
||||
set!(any: "normal", FontStretch::Normal);
|
||||
set!(any: "semi-expanded", FontStretch::SemiExpanded);
|
||||
set!(any: "expanded", FontStretch::Expanded);
|
||||
set!(any: "extra-expanded", FontStretch::ExtraExpanded);
|
||||
set!(any: "ultra-expanded", FontStretch::UltraExpanded);
|
||||
|
||||
std
|
||||
}
|
||||
|
@ -269,14 +269,14 @@ impl Location {
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Location {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Location {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "{}:{}", self.line, self.column)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Location {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user