read function

This commit is contained in:
Martin Haug 2022-12-29 11:49:01 +01:00
parent 94b90761eb
commit bc535f7b71
5 changed files with 54 additions and 2 deletions
library/src
tests

@ -4,6 +4,40 @@ use typst::diag::{format_xml_like_error, FileError};
use crate::prelude::*;
/// # Read file
/// Read plain text from a file.
///
/// The file will be read and returned as a string.
///
/// ## Example
/// ```
/// #let text = read("data.html")
///
/// An HTML file could look like this:
/// #raw(text, lang: "html")
/// ```
///
/// ## Parameters
/// - path: EcoString (positional, required)
/// Path to a file.
///
/// - returns: EcoString
///
/// ## Category
/// data-loading
#[func]
pub fn read(vm: &Vm, args: &mut Args) -> SourceResult<Value> {
let Spanned { v: path, span } = args.expect::<Spanned<EcoString>>("path to file")?;
let path = vm.locate(&path).at(span)?;
let data = vm.world().file(&path).at(span)?;
let text = String::from_utf8(data.to_vec())
.map_err(|_| "file is not valid utf-8")
.at(span)?;
Ok(Value::Str(text.into()))
}
/// # CSV
/// Read structured data from a CSV file.
///
@ -184,7 +218,10 @@ fn convert_json(value: serde_json::Value) -> Value {
/// Format the user-facing JSON error message.
fn format_json_error(error: serde_json::Error) -> String {
assert!(error.is_syntax() || error.is_eof());
format!("failed to parse json file: syntax error in line {}", error.line())
format!(
"failed to parse json file: syntax error in line {}",
error.line()
)
}
/// # XML

@ -124,6 +124,7 @@ fn scope() -> Scope {
std.def_func::<compute::EvenFunc>("even");
std.def_func::<compute::OddFunc>("odd");
std.def_func::<compute::ModFunc>("mod");
std.def_func::<compute::ReadFunc>("read");
std.def_func::<compute::CsvFunc>("csv");
std.def_func::<compute::JsonFunc>("json");
std.def_func::<compute::XmlFunc>("xml");

1
tests/res/hello.txt Normal file

@ -0,0 +1 @@
Hello, world!

BIN
tests/res/invalid-utf8.txt Normal file

Binary file not shown.

@ -1,6 +1,19 @@
// Test reading structured data.
// Test reading structured data and files.
// Ref: false
---
// Test reading plain text files
#let data = read("../../res/hello.txt")
#test(data, "Hello, world!")
---
// Error: 18-41 file not found (searched at res/missing.txt)
#let data = read("../../res/missing.txt")
---
// Error: 18-46 file is not valid utf-8
#let data = read("../../res/invalid-utf8.txt")
---
// Test reading CSV data.
// Ref: true