feat: add error framework and parse sys arguments for typlite (#478)

* feat: parse sys arguments for typlite

* feat: add error framework to typlite

* dev: allow output to stdout

* fix: error in docs
This commit is contained in:
Myriad-Dreamin 2024-07-30 16:49:04 +08:00 committed by GitHub
parent 6ef09724dd
commit bc3bd9f762
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 76 additions and 13 deletions

12
contrib/typlite/README.md Normal file
View file

@ -0,0 +1,12 @@
# Typlite
Converts a subset of typst to markdown.
## Usage
```shell
# default output is main.md
typlite main.typ
# specify output
typlite main.typ output.md
```

View file

@ -1,13 +1,29 @@
//! # Typlite
#![doc = include_str!("../README.md")]
extern crate typlite;
use std::path::{Path, PathBuf};
use typlite::Typlite;
fn main() {
let input = r#"..\..\..\..\ts\typst-blog\source\_posts\simple-se.typ"#;
let input = std::env::args().nth(1).unwrap();
let input = Path::new(&input);
let output = match std::env::args().nth(2) {
Some(e) if e == "-" => None,
Some(e) => Some(PathBuf::from(e)),
None => Some(input.with_extension("md")),
};
let input = std::fs::read_to_string(input).unwrap();
let typlite = Typlite::new_with_content(&input);
let output = typlite.convert().unwrap();
std::fs::write(r#"..\..\..\..\ts\typst-blog\public\simple-se.md"#, output).unwrap();
let conv = Typlite::new_with_content(&input).convert();
match (conv, output) {
(Ok(conv), None) => println!("{}", conv),
(Ok(conv), Some(output)) => std::fs::write(output, conv.as_str()).unwrap(),
(Err(e), ..) => {
eprintln!("{e}");
std::process::exit(1);
}
}
}

View file

@ -25,6 +25,7 @@ insta.workspace = true
regex.workspace = true
[features]
texmath = []
[lints]
workspace = true

View file

@ -0,0 +1,33 @@
use core::fmt;
use std::{borrow::Cow, ops::Deref};
/// An error that can occur during the conversion process.
pub struct Error(Box<Repr>);
enum Repr {
/// Just a message.
Msg(Cow<'static, str>),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0.deref() {
Repr::Msg(s) => write!(f, "{s}"),
}
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
<Self as fmt::Display>::fmt(self, f)
}
}
impl<T> From<T> for Error
where
T: Into<Cow<'static, str>>,
{
fn from(s: T) -> Self {
Error(Box::new(Repr::Msg(s.into())))
}
}

View file

@ -1,25 +1,26 @@
//! # Typlite
mod error;
mod library;
pub mod scopes;
mod value;
mod world;
pub use error::*;
use base64::Engine;
use scopes::Scopes;
use typst::{eval::Tracer, layout::Abs};
use value::{Args, Value};
use world::LiteWorld;
use std::borrow::Cow;
use ecow::{eco_format, EcoString};
use typst_syntax::{
ast::{self, AstNode},
Source, SyntaxKind, SyntaxNode,
};
type Result<T, Err = Cow<'static, str>> = std::result::Result<T, Err>;
type Result<T, Err = Error> = std::result::Result<T, Err>;
/// Task builder for converting a typst document to Markdown.
#[derive(Debug, Clone)]
@ -37,7 +38,7 @@ impl Typlite {
/// use typlite::Typlite;
/// let content = "= Hello, World";
/// let res = Typlite::new_with_content(content).convert();
/// assert_eq!(res, Ok("# Hello, World".into()));
/// assert!(matches!(res, Ok(e) if e == "# Hello, World"));
/// ```
pub fn new_with_content(content: &str) -> Self {
let main = Source::detached(content);

View file

@ -1,7 +1,7 @@
//! Variable scopes.
use super::Result;
use std::{borrow::Cow, collections::HashMap};
use super::*;
use std::collections::HashMap;
/// A single scope.
#[derive(Debug, Clone)]
@ -100,6 +100,6 @@ impl<T> Scopes<T> {
}
/// The error message when a variable is not found.
fn unknown_variable(var: &str) -> Cow<'static, str> {
Cow::Owned(format!("unknown variable: {var}"))
fn unknown_variable(var: &str) -> Error {
format!("unknown variable: {var}").into()
}