CSV reading
This commit is contained in:
parent
fc574b3945
commit
9362c279de
51
Cargo.lock
generated
51
Cargo.lock
generated
@ -83,6 +83,18 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.9.1"
|
||||
@ -126,6 +138,28 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"csv-core",
|
||||
"itoa 0.4.8",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-url"
|
||||
version = "0.1.1"
|
||||
@ -272,6 +306,12 @@ dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.2"
|
||||
@ -431,7 +471,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "249f9b33a3192626f2cd9f4b0cd66c1ec32d65968d58cf4d8239977feddddead"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"itoa",
|
||||
"itoa 1.0.2",
|
||||
"ryu",
|
||||
]
|
||||
|
||||
@ -547,6 +587,12 @@ dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.26"
|
||||
@ -665,7 +711,7 @@ version = "1.0.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"itoa 1.0.2",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
@ -816,6 +862,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"codespan-reporting",
|
||||
"csv",
|
||||
"dirs",
|
||||
"flate2",
|
||||
"fxhash",
|
||||
|
@ -41,6 +41,7 @@ usvg = { version = "0.22", default-features = false }
|
||||
# External implementation of user-facing features
|
||||
syntect = { version = "5", default-features = false, features = ["default-syntaxes", "regex-fancy"] }
|
||||
rex = { git = "https://github.com/laurmaedje/ReX" }
|
||||
csv = "1"
|
||||
|
||||
# PDF export
|
||||
miniz_oxide = "0.5"
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
30
src/library/utility/data.rs
Normal file
30
src/library/utility/data.rs
Normal file
@ -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)
|
||||
}
|
@ -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::*;
|
||||
|
||||
|
BIN
tests/ref/utility/csv.png
Normal file
BIN
tests/ref/utility/csv.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
4
tests/res/bad.csv
Normal file
4
tests/res/bad.csv
Normal file
@ -0,0 +1,4 @@
|
||||
A,B
|
||||
1,2
|
||||
3,4,5
|
||||
6,7
|
|
4
tests/res/zoo.csv
Normal file
4
tests/res/zoo.csv
Normal file
@ -0,0 +1,4 @@
|
||||
Name,Species,Weight,Length
|
||||
Debby,Rhinoceros,1900kg,390cm
|
||||
Fluffy,Tiger,115kg,310cm
|
||||
Sleepy,Dolphin,150kg,180cm
|
|
15
tests/typ/utility/csv.typ
Normal file
15
tests/typ/utility/csv.typ
Normal file
@ -0,0 +1,15 @@
|
||||
// Test reading structured CSV data.
|
||||
|
||||
---
|
||||
#set page(width: auto)
|
||||
#let data = csv("/res/zoo.csv")
|
||||
#let cells = data(0).map(strong) + data.slice(1).flatten()
|
||||
#table(columns: data(0).len(), ..cells)
|
||||
|
||||
---
|
||||
// Error: 6-16 file not found (searched at typ/utility/nope.csv)
|
||||
#csv("nope.csv")
|
||||
|
||||
---
|
||||
// Error: 6-20 failed to load csv file (CSV error: record 2 (line: 3, byte: 8): found record with 3 fields, but the previous record has 2 fields)
|
||||
#csv("/res/bad.csv")
|
Loading…
Reference in New Issue
Block a user