diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-07-27 00:09:15 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-07-27 00:09:15 +0200 |
| commit | 9362c279de362eac1b7ec76834dd76a0235c5dd2 (patch) | |
| tree | fdcec0de57deac0f94c2b4521ff09e94b1c785ee /src | |
| parent | fc574b39454aec77cf2c33270566225917c7c823 (diff) | |
CSV reading
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 3 | ||||
| -rw-r--r-- | src/library/mod.rs | 1 | ||||
| -rw-r--r-- | src/library/prelude.rs | 5 | ||||
| -rw-r--r-- | src/library/utility/data.rs | 30 | ||||
| -rw-r--r-- | src/library/utility/mod.rs | 2 |
5 files changed, 40 insertions, 1 deletions
@@ -79,6 +79,8 @@ pub fn typeset(ctx: &mut Context, id: SourceId) -> TypResult<Vec<Frame>> { /// The core context which holds the configuration and stores. pub struct Context { + /// The loader for fonts and files. + pub loader: Arc<dyn Loader>, /// Stores loaded source files. pub sources: SourceStore, /// Stores parsed font faces. @@ -97,6 +99,7 @@ impl Context { /// Create a new context. pub fn new(loader: Arc<dyn Loader>, config: Config) -> Self { Self { + loader: Arc::clone(&loader), sources: SourceStore::new(Arc::clone(&loader)), fonts: FontStore::new(Arc::clone(&loader)), images: ImageStore::new(loader), diff --git a/src/library/mod.rs b/src/library/mod.rs index d78e38ca..bd34590a 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -97,6 +97,7 @@ pub fn new() -> Scope { std.def_fn("roman", utility::roman); std.def_fn("symbol", utility::symbol); std.def_fn("lorem", utility::lorem); + std.def_fn("csv", utility::csv); // Predefined colors. std.define("black", Color::BLACK); diff --git a/src/library/prelude.rs b/src/library/prelude.rs index c033b631..f55447c3 100644 --- a/src/library/prelude.rs +++ b/src/library/prelude.rs @@ -2,12 +2,15 @@ pub use std::fmt::{self, Debug, Formatter}; pub use std::hash::Hash; +pub use std::io; pub use std::num::NonZeroUsize; pub use std::sync::Arc; pub use typst_macros::node; -pub use crate::diag::{with_alternative, At, Error, StrResult, TypError, TypResult}; +pub use crate::diag::{ + failed_to_load, with_alternative, At, Error, StrResult, TypError, TypResult, +}; pub use crate::eval::{ Arg, Args, Array, Cast, Dict, Dynamic, Func, Machine, Node, RawAlign, RawLength, RawStroke, Scope, Smart, Value, diff --git a/src/library/utility/data.rs b/src/library/utility/data.rs new file mode 100644 index 00000000..0f9e6bf0 --- /dev/null +++ b/src/library/utility/data.rs @@ -0,0 +1,30 @@ +use crate::library::prelude::*; + +/// Read structured data from a CSV file. +pub fn csv(vm: &mut Machine, args: &mut Args) -> TypResult<Value> { + let Spanned { v: path, span } = + args.expect::<Spanned<EcoString>>("path to csv file")?; + + let path = vm.locate(&path).at(span)?; + let try_load = || -> io::Result<Value> { + let data = vm.ctx.loader.load(&path)?; + + let mut builder = csv::ReaderBuilder::new(); + builder.has_headers(false); + + let mut reader = builder.from_reader(data.as_slice()); + let mut vec = vec![]; + + for result in reader.records() { + vec.push(Value::Array( + result?.iter().map(|field| Value::Str(field.into())).collect(), + )) + } + + Ok(Value::Array(Array::from_vec(vec))) + }; + + try_load() + .map_err(|err| failed_to_load("csv file", &path, err)) + .at(span) +} diff --git a/src/library/utility/mod.rs b/src/library/utility/mod.rs index 10aa7c7a..9c95e60c 100644 --- a/src/library/utility/mod.rs +++ b/src/library/utility/mod.rs @@ -1,10 +1,12 @@ //! Computational utility functions. mod color; +mod data; mod math; mod string; pub use color::*; +pub use data::*; pub use math::*; pub use string::*; |
