1pub mod resources;
2
3mod tabs;
4mod table;
5
6pub use tabs::{Tab,Tabs};
7
8pub use table::{TableBuilder,TableDrawer,RowRef,TableError,SoftColumn};
9
10#[derive(Debug)]
11pub struct Style {
12 name: &'static str,
13 opts: Vec<(&'static str, &'static str)>,
14}
15impl Style {
16 pub fn new(style: &'static str) -> Style {
17 Style {
18 name: style,
19 opts: Vec::new(),
20 }
21 }
22 pub fn duplicate(&self,style: &'static str) -> Style {
23 Style {
24 name: style,
25 opts: self.opts.clone(),
26 }
27 }
28 pub fn opt(mut self, opt: &'static str, value: &'static str) -> Style {
29 let mut idx = None;
30 for (i,(o,_)) in self.opts.iter().enumerate() {
31 if *o == opt { idx = Some(i); break }
32 }
33 match idx {
34 Some(i) => self.opts[i] = (opt,value),
35 None => self.opts.push((opt,value)),
36 }
37 self
38 }
39}
40impl ToString for Style {
41 fn to_string(&self) -> String {
42 match self.opts.len() {
43 0 => String::new(),
44 _ => {
45 let mut s = format!(".{} {{",self.name);
46 for (o,v) in &self.opts {
47 s += " ";
48 s += o;
49 s += ": ";
50 s += v;
51 s += ";\n"
52 }
53 s += "}";
54 s
55 },
56 }
57 }
58}
59
60pub fn classed<T: ToString>(class: &'static str, t: T) -> String {
61 format!("<span class='{}'>{}</span>",class,t.to_string())
62}
63
64#[derive(Debug)]
65pub struct Block {
66 class: &'static str,
67 onclick: Option<String>,
68 id: Option<String>,
69 text: Option<String>,
70 subs: Vec<Block>,
71}
72impl Block {
73 pub fn new(class: &'static str) -> Block {
74 Block {
75 class,
76 onclick: None,
77 id: None,
78 text: None,
79 subs: Vec::new(),
80 }
81 }
82 pub fn id<T: ToString>(mut self, id: T) -> Block {
83 self.id = Some(id.to_string());
84 self
85 }
86 pub fn onclick<T: ToString>(mut self, onclick: T) -> Block {
87 self.onclick = Some(onclick.to_string());
88 self
89 }
90 pub fn text<T: ToString>(mut self, t: T) -> Block {
91 self.text = Some(t.to_string());
92 self
93 }
94 pub fn sub(mut self, s: Block) -> Block {
95 self.subs.push(s);
96 self
97 }
98 pub fn sub_mut(&mut self, s: Block) {
99 self.subs.push(s);
100 }
101}
102impl ToString for Block {
103 fn to_string(&self) -> String {
104 let t = match &self.text {
105 Some(t) => t,
106 None => "",
107 };
108 let s = match self.subs.len() {
109 0 => String::new(),
110 _ => {
111 let mut s = String::new();
112 for b in &self.subs {
113 s += &b.to_string();
114 s += "\n"
115 }
116 s
117 },
118 };
119 match (&self.id, &self.onclick) {
120 (None,None) => format!("<div class='{}'>{}{}</div>",self.class,t,s),
121 (None, Some(oc)) => format!("<div class='{}' onclick='{}'>{}{}</div>",self.class,oc,t,s),
122 (Some(id),None) => format!("<div id='{}' class='{}'>{}{}</div>",id,self.class,t,s),
123 (Some(id), Some(oc)) => format!("<div id='{}' class='{}' onclick='{}'>{}{}</div>",id,self.class,oc,t,s),
124 }
125 }
126}
127
128
129#[derive(Debug,Default)]
130pub struct HtmlProducer {
131 title: String,
132 scripts: Vec<String>,
133 styles: Vec<Style>,
134 blocks: Vec<Block>,
135
136 tables: TableDrawer,
137
138 css: String,
139 js: String,
140}
141impl ToString for HtmlProducer {
142 fn to_string(&self) -> String {
143 let mut style = self.css.clone();
144 style += "\n";
145 for s in &self.styles {
146 style += &s.to_string();
147 style += "\n";
148 }
149 let mut body = String::new();
150 for b in &self.blocks {
151 body += &b.to_string();
152 body += "\n";
153 }
154 let mut script = self.js.clone();
155 script += "\n";
156 for scr in &self.scripts {
157 script += scr;
158 script += "\n";
159 }
160 format!("<html>\n<head>\n<title>\n{}\n</title>\n<style>\n{}\n</style>\n<script>\n{}\n</script>\n</head>\n<body>\n{}\n</body>\n</html>\n",self.title,style,script,body)
161 }
162}
163impl HtmlProducer {
164 pub fn with_title<T: ToString>(mut self, t: T) -> HtmlProducer {
165 self.title = t.to_string();
166 self
167 }
168 pub fn with_styles(mut self, css: &String) -> HtmlProducer {
169 if self.css != "" { self.css += "\n"; }
170 self.css += css;
171 self
172 }
173 pub fn with_scripts(mut self, js: &String) -> HtmlProducer {
174 if self.js != "" { self.js += "\n"; }
175 self.js += js;
176 self
177 }
178
179 pub fn push_script<T: ToString>(&mut self, t: T) {
180 self.scripts.push(t.to_string());
181 }
182 pub fn push_style(&mut self, s: Style) {
183 self.styles.push(s);
184 }
185 pub fn push_block(&mut self, b: Block) {
186 self.blocks.push(b);
187 }
188
189 pub fn drawer(&mut self) -> &mut TableDrawer {
190 &mut self.tables
191 }
192 pub fn add_tables(&mut self, tb: &TableBuilder) {
193 let s = tb.styles(&self.tables);
194 if s != "" {
195 if self.css != "" { self.css += "\n"; }
196 self.css += &s;
197 }
198 }
199}