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
102
103
104
105
106
use gtmpl_value::Value;
pub fn ccat(args: &[Value]) -> Result<Value, String> {
let mut res = String::new();
for v in args {
res.push_str(&v.to_string());
}
Ok(Value::String(res))
}
fn _sep(sp: &str, args: &[Value]) -> Result<String, String> {
let mut first = true;
let mut res = String::new();
for a in args {
if !first {
res.push_str(sp);
}
match a {
Value::Array(l) => res.push_str(&_sep(sp, l)?),
v => res.push_str(&v.to_string()),
}
first = false;
}
Ok(res)
}
pub fn sep(args: &[Value]) -> Result<Value, String> {
if args.len() < 2 {
return Err("Nothing to separate".to_string());
}
let sp = args[0].to_string();
Ok(Value::String(_sep(&sp, &args[1..])?))
}
pub fn wrap(args: &[Value]) -> Result<Value, String> {
let s = match args.get(0) {
Some(Value::String(s)) => s,
_ => return Err("Value 0 not a string".to_string()),
};
let n = match args.get(1) {
Some(Value::Number(n)) => n.as_u64().ok_or("Value 1 not a positive int".to_string())?,
_ => return Err("Value 1 not a num".to_string()),
};
let vs = _wrap(s, n as usize);
Ok(Value::Array(
vs.into_iter().map(|v| Value::String(v)).collect(),
))
}
fn _wrap(s: &str, mx: usize) -> Vec<String> {
let mut cword = String::new();
let mut cline = String::new();
let mut res: Vec<String> = Vec::new();
for c in s.chars() {
if cline.len() + cword.len() > mx {
if cline.len() == 0 {
cline.push_str(&cword[..mx]);
cline.push('-');
cword = String::from(&cword[mx..]);
} else {
cword = cword[1..].to_string();
}
res.push(cline);
cline = "".to_string();
}
match c {
'\n' => {
cline.push_str(&cword);
cword.clear();
res.push(cline);
cline = "".to_string();
}
'-' => {
cline.push_str(&cword);
cline.push('-');
cword = String::from(" ");
}
' ' => {
cline.push_str(&cword);
cword = String::from(" ");
}
_ => {
cword.push(c);
}
}
}
cline.push_str(&cword);
res.push(cline);
res
}
pub fn markdown(args: &[Value]) -> Result<Value, String> {
use pulldown_cmark::*;
let mut res = String::new();
for a in args {
if let Value::String(s) = a {
let p = Parser::new(s);
html::push_html(&mut res, p);
}
}
Ok(Value::String(res))
}