commit 362c6156dbf8d8cb402215b241898dfbc96ad4fd
parent 71f2b6bd4568ec40a795a2ebba824f52d511f2ed
Author: Demonstrandum <moi@knutsen.co>
Date: Sat, 10 Oct 2020 21:27:24 +0100
Allow input from stdin.
Diffstat:
7 files changed, 99 insertions(+), 44 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -83,7 +83,7 @@ dependencies = [
[[package]]
name = "seam"
-version = "0.1.2"
+version = "0.1.3"
dependencies = [
"chrono",
"colored",
diff --git a/Cargo.toml b/Cargo.toml
@@ -4,7 +4,7 @@ description = "Symbolic Expressions As Markup."
keywords = ["markup", "lisp", "macro", "symbolic-expression", "sexp"]
license-file = "LICENSE"
homepage = "https://git.knutsen.co/seam"
-version = "0.1.2"
+version = "0.1.3"
authors = ["Demonstrandum <moi@knutsen.co>"]
edition = "2018"
diff --git a/README.md b/README.md
@@ -21,6 +21,40 @@ client.
- HTML
- CSS
+### Using The Binary
+
+Providing you have installed `seam` with
+```sh
+cargo install seam
+```
+
+You may use it by doing
+```sh
+seam test.sex --html > test.html
+```
+
+`test.sex` contains your symbolic-expressions, which is used to generate
+HTML, saved in `test.html`.
+
+Likewise, you may do
+```sh
+cat test.sex | seam --html > test.html
+```
+or
+```sh
+seam --html <<< "(p Hello World)"
+#stdout:
+# <!DOCTYPE html>
+# <html>
+# <head></head>
+# <body>
+# <p>Hello World</p>
+# <!-- Generated by SEAM, from symbolic-expressions into HTML. -->
+# </body>
+# </html>
+```
+
+
## TODO
- Caching or checking time-stamps as to not regenerate unmodified source files.
- HTML object `style="..."` object should handle s-expressions well, (e.g. `(p :style (:color red :border none) Hello World)`)
@@ -35,13 +69,3 @@ client.
`(+ 1 2)` with Chez-Scheme LISP, and places the result in the source
(i.e. `3`).
-### Using The Binary
-
-(Providing you have cloned this repo, and `cd`'d into it)
-
-```console
-cargo run test.sex --html > test.html
-```
-
-`test.sex` contains your symbolic-expressions, which is used to generate
-HTML, saved in `test.html`.
diff --git a/src/bin.rs b/src/bin.rs
@@ -1,7 +1,7 @@
use seam;
use seam::assemble::MarkupDisplay;
-use std::env;
+use std::{io, env};
use std::path::PathBuf;
use std::error::Error;
@@ -22,6 +22,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let mut files = Vec::new();
let mut target = "";
+ let mut from_stdin = false;
for arg in args {
if arg.chars().nth(0) == Some('-') {
@@ -38,6 +39,9 @@ fn main() -> Result<(), Box<dyn Error>> {
major, minor, tiny).bold());
std::process::exit(0);
},
+ "" => {
+ from_stdin = true;
+ },
_ => argument_fatal(
format!("Unknown argument (`-{}').", opt))
}
@@ -50,10 +54,23 @@ fn main() -> Result<(), Box<dyn Error>> {
}
if files.is_empty() {
- argument_fatal("No input files given.");
+ from_stdin = true;
}
if target.is_empty() {
- argument_fatal("No such target exists / no target given.");
+ argument_fatal("No such target format exists / \
+ no target format given.");
+ }
+
+ if from_stdin {
+ let mut stdin = io::stdin();
+ let tree = match seam::parse_stream(&mut stdin) {
+ Ok(tree) => tree,
+ Err(e) => {
+ eprintln!("{}", e);
+ std::process::exit(1)
+ }
+ };
+ print_generated(tree, target);
}
for file in files {
@@ -68,33 +85,38 @@ fn main() -> Result<(), Box<dyn Error>> {
eprintln!("{}", &tree
.iter().fold(String::new(),
|acc, s| acc + "\n" + &s.to_string()));
- let result = match target {
- "html" => {
- let fmt = seam::assemble::html::HTMLFormatter::new(tree);
- fmt.document()
- },
- "xml" => {
- let fmt = seam::assemble::xml::XMLFormatter::new(tree);
- fmt.document()
- },
- "css" => {
- let fmt = seam::assemble::css::CSSFormatter::new(tree);
- fmt.document()
- },
- _ => {
- argument_fatal(
- format!("Target `{}', does not exist.", target))
- }
- };
- match result {
- Ok(generated) => print!("{}", generated),
- Err(e) => {
- eprintln!("{}", e);
- std::process::exit(1)
- }
- }
+ print_generated(tree, target);
}
Ok(())
}
+
+fn print_generated(tree : seam::parse::ParseTree, target : &str) {
+ let result = match target {
+ "html" => {
+ let fmt = seam::assemble::html::HTMLFormatter::new(tree);
+ fmt.document()
+ },
+ "xml" => {
+ let fmt = seam::assemble::xml::XMLFormatter::new(tree);
+ fmt.document()
+ },
+ "css" => {
+ let fmt = seam::assemble::css::CSSFormatter::new(tree);
+ fmt.document()
+ },
+ _ => {
+ argument_fatal(
+ format!("Target `{}', does not exist.", target))
+ }};
+
+ match result {
+ Ok(generated) => print!("{}", generated),
+ Err(e) => {
+ eprintln!("{}", e);
+ std::process::exit(1)
+ }
+ }
+}
+
diff --git a/src/lib.rs b/src/lib.rs
@@ -2,11 +2,12 @@ pub mod parse;
pub mod assemble;
use parse::{expander, parser, lexer};
+pub use parse::parse_stream;
use std::error::Error;
use std::{fs, path::Path};
-pub const VERSION : (u8, u8, u8) = (0, 1, 2);
+pub const VERSION : (u8, u8, u8) = (0, 1, 3);
pub fn parse<P: AsRef<Path>>(string : String, source : Option<P>)
-> Result<parser::ParseTree, Box<dyn Error>> {
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
@@ -4,8 +4,16 @@ pub mod lexer;
pub mod parser;
-use parser::ParseTree;
-use std::{fs, path::Path, error::Error};
+pub use parser::ParseTree;
+use std::{fs, path::Path, io, error::Error};
+
+pub fn parse_stream(stream : &mut impl io::Read) -> Result<ParseTree, Box<dyn Error>> {
+ let mut contents = String::new();
+ stream.read_to_string(&mut contents)?;
+ let tokens = lexer::lex(contents, Option::<&Path>::None)?;
+ let tree = parser::parse_stream(tokens)?;
+ Ok(tree)
+}
pub fn parse_file(path : &Path) -> Result<ParseTree, Box<dyn Error>> {
let contents = fs::read_to_string(&path)?;
diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs
@@ -46,7 +46,7 @@ impl Display for Site {
if let Some(source) = &self.source {
write!(f, "{}:", source)?;
} else {
- write!(f, "no-file:")?;
+ write!(f, "<stdin>:")?;
}
write!(f, "{}:{})", self.line, self.bytes_from_start + 1)
}