Crates.io | seam |
lib.rs | seam |
version | |
source | src |
created_at | 2020-10-10 19:22:48.261707 |
updated_at | 2024-12-09 22:54:01.421842 |
description | Symbolic Expressions As Markup. |
homepage | https://git.knutsen.co/seam |
repository | |
max_upload_size | |
id | 298141 |
Cargo.toml error: | TOML parse error at line 18, column 1 | 18 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
Symbolic Expressions As Markup.
Because all markup is terrible, especially XML/SGML and derivatives.
But mainly, for easier static markup code generation, such as by macros and code includes and such.
This may be used as a Rust library, such as from within a server,
generating HTML (or any other supported markup) before it is served to the
client. Personally, I just use the seam
binary to statically
generate my personal websites through a Makefile.
Read the USAGE.md file for code examples and documentation.
--xml
; including: SVG, MathML)--html
; SGML)--css
)--sexp
; S-expression, basically a macro expansion utility)--text
; renders escaped strings to text)You may clone the repo, then build and install by
git clone git://git.knutsen.co/seam
cd seam
cargo build --release
cargo install --path .
Or install it from crates.io
cargo install seam
Either way, you'll need the Rust (nightly) compiler and along
with it, comes cargo
.
You may use it by passing in a file and piping from STDOUT.
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 read from STDIN
seam --html < example.sex > example.html
# ... same as
cat example.sex | seam --html > example.html
You may also use here-strings or here-docs, if your shell supports it.
seam --html <<< "(p Hello World)"
#stdout:
# <!DOCTYPE html>
# <html>
# <head></head>
# <body>
# <p>Hello World</p>
# </body>
# </html>
seam --html --nodocument <<< "(p Hello World)"
#stdout:
# <p>Hello World</p>
seam --xml <<< '(para Today is a day in (%date "%B, year %Y").)'
#stdout:
# <?xml version="1.0" encoding="UTF-8" ?>
# <para>Today is a day in November, year 2020.</para>
seam --sexp <<< '(hello (%define subject world) %subject)'
#stdout:
# (hello world)
(%error msg)
macro for aborting compilation.(%reverse (...))
.(%symbol lit)
, (%number lit)
, (%string lit)
, (%raw lit)
.(%sort (...))
which sorts alphanumerically on literals.
Allow providing a :key
to sort "by field": e.g. sort by title name (%sort :key (%lambda ((:title _ &&_)) %title) %posts)
(%date)
to be able to read UNIX numeric timestamps and display relative to timezones.
Add complementary strptime-style utility (%timestamp)
to convert date-strings to timestamps (relative to a timezone).(%match expr (pat1 ...) (pat2 ...))
macro.
Pattern matching is already implemented for %define
internally.&&rest
matches excess keyword.
Extracting a value from a map (:a 1 :b 2 :c 3)
is done with:
(%match %h ((:b default &&_) %b))
.%get
macro: (%get b (:a 1 :b 2))
becomes 2
; (%get 0 (a b c))
becomes a
.(%yaml "...")
, (%toml "...")
and (%json "...")
converts
whichever config-lang definition into a seam %define
-definition.(%do ...)
which just expands to the ...
; the identity function.(%try :catch index-error (%do code-to-try) :error the-error (%do caught-error %the-error))
.(%strip ...)
which evaluates to the ...
without any of the leading whitespace.(%splat (a b c))
becomes a b c
.(%define x %body)
evaluates %body
eagerly (at definition),
while (%define (y) %body)
only evaluates %body
per call-site (%y)
.(%namespace ns (%include "file.sex"))
will prefix all definitions in its body with ns/
, e.g. %ns/defn
.
Allows for a customizable separator, e.g. (%namespace ns :separator "-" ...)
will allow for writing %ns-defn
.
Otherwise, the macro leaves the content produced by the body completely unchanged.-I
include directory.(%os/env ENV_VAR)
environment variable macro.ifdef
) with use of new (%eval ...)
macro.(%apply name x y z)
macro which is equivalent to (%name x y z)
.(%lambda (x y) ...)
macro which just evaluates to an secret symbol, e.g. __lambda0
.
used by applying %apply
, e.g. (%apply (%lambda (a b) b a) x y)
becomes y x
(%string ...)
, (%join ...)
, (%map ...)
, (%filter ...)
macros.(%concat ...)
which is just (%join "" ...)
.(%basename)
, (%dirname)
and (%extension)
macros for paths.%glob
for sorting by type, date(s), name, etc.(%format "{}")
macro with Rust's format
syntax. e.g. (%format "Hello {}, age {age:0>2}" "Sam" :age 9)
(%raw ...)
macro which takes a string and leaves it unchanged in the final output.(%formatter/text ...)
can take any seam (sexp) source code, for which it just embeds the expanded code (plain-text formatter).(%formatter/html ...)
etc. which call the respective available formatters.(%embed "/path")
macro, like %include
, but just returns the file contents as a string.&rest
syntax.%list
macro which expands from (%list %a %b %c)
to ( %a %b %c )
but without calling %a
as a macro with %b
and %c
as argument.%for
-loop macro, iterating over %list
s.%glob
which returns a list of files/directories matching a glob.%markdown
renders Markdown given to it as %raw
html-string.style="..."
object should handle s-expressions well, (e.g. (p :style (:color red :border none) Hello World)
)JSON
, JS
, TOML
, &c.).(%chez (+ 1 2))
executes
(+ 1 2)
with Chez-Scheme LISP, and places the result in the source (i.e. 3
).