1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! # Femstache
//!
//! Femstache is a mustache-like templating library with its own extensions.
//!
//! ## Syntax
//!
//! Templates are composed of text interspersed with three kinds of control sequences:
//!
//! - `{{ ... }}`: interpolation
//! - `{% ... %}`: control
//! - `{# ... #}`: metadata (only at the top of a document)
//!
//! There are a few kinds of control structures:
//!
//! - `{% if COND %} ... {% end %}`
//! - `{% for item in LIST %} ... {% end %}`
//! - `{% for item in dict DICT %} ... {% end %}`
//!
//! There are also variable assignments, these are of the form `{% let VAR = EXPR %}`.
//!
//! Template inheritance is also supported, using `{# inherit "PATH_TO_PARENT" #}` and
//! `{% block BLOCKNAME %}{% end %}`.
//!
//! Expressions have the typical syntax of most programming languages, there are
//! a few binary operators:
//!
//! - Equals: `x == y`
//! - Not equals: `x != y`
//! - String concat: `x ++ y`
//! - Member access: `x.y`
//! - Dict access: `x[y]`
//! - Function calls: `x(y)`
//!
//! ## Types
//!
//! There are several available types:
//!
//! - boolean values: `bool`
//! - string values: `string` (these can be raw strings, which are not escaped)
//! - optional values: `option T`
//! - lists: `list T`
//! - dicts: `dict T` (this is from strings to `T`)
//! - structs: `struct(field1: ty1, field2: ty2, ...)`
//! - functions: `fun A -> R`
//!
//! These types are truthy: (currently the typechecker doesn't allow non-`bool` conditions, though)
//!
//! - `true`
//! - non-empty string
//! - non-empty dict
//! - non-empty list
//! - non-empty struct
//! - non-empty option
//! - function
//!
//! ## Typechecking
//!
//! Typechecking is handled using Hindley-Milner and supports extensible records.
//!
//! ## Example
//!
//! ```rust
//! use std::{collections::BTreeMap, path::PathBuf};
//! use femstache::{Femstache, TemplateSource, EscapeMode, Value};
//!
//! let mut files = BTreeMap::new();
//!
//! files.insert(PathBuf::from("hello.fem.html"), "{% for place in places %}hello {{ place }}! :3\n{% end %}".to_owned());
//!
//! let mut femstache = Femstache::new(TemplateSource::map(files), EscapeMode::Html);
//!
//! let mut inputs = BTreeMap::new();
//! inputs.insert("places".to_owned(), Value::List(vec![
//! Value::string("world"),
//! Value::string("mom"),
//! Value::string("puniqt"),
//! ]));
//!
//! let output = femstache.render("hello.fem.html", &inputs).unwrap();
//!
//! assert_eq!(output, "hello world! :3\nhello mom! :3\nhello puniqt! :3\n");
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use EscapeMode;
pub use TemplateInput;