html_stack/
lib.rs

1/*! by [extinct](https://extinct.at/)  
2
3A dsl (domain specific language) for writing html. This is NOT an html template.  This library focus is on html composability. It uses a FILO stack paradigm.  
4
5## usage 
6```  
7use html_stack::Stack ; 
8fn myhomepage() ->String  { 
9         let s = Stack::new()  ;
10         s .put("my homepage") .wrp("title") .wrp("head")  ;
11         s .put("my homepage") .wrp("h1")  ;
12         s .put("Lorem ipsum dolor sit amet, consectetur adipiscing elit.") .wrp("p class=someclass") .add()  ;
13         s .put("Lorem ipsum dolor sit amet, consectetur adipiscing elit.") .wrp("p class='class1 class2'") .add()  ;
14         s .put("") .wrp("img src=/img/image.jpg") .add()  ;
15         s .wrp("body") .add()  ;
16         s .put("") .wrp("script type=module src=/js/main.js") .add()  ;
17         s .wrp("html")  ;
18         return s .doctype()  ;
19``` */ 
20use  std::collections::HashSet  ;
21fn tag(c:&str ,t:&str) ->String  {
22	let mut ts:Vec<&str> = t .split(" ") .map(|i| i.trim()) .collect()  ;
23	let head = ts .remove(0)  ;
24	let t = ts .join(" ")  ;
25	if t == ""  {
26		return format!("\n<{head}>{c}</{head}>")  ;}
27	return format!("\n<{head} {t}>{c}</{head}>")  ;}
28// tag attribute values do not always need to be quoted  ;
29pub struct Stack(Vec<String>); 
30impl Stack  {
31	pub fn new()->Self  {
32		return Stack(vec!())  ;}
33	pub fn print(&mut self)  {
34		let mut i = 0  ;
35		for x in &mut self.0  {
36			println!("{}{}\n" ,i ,x)  ;
37			i += 1  ;}}
38	pub fn preview(&mut self)  {
39		let mut i = 0  ;
40		println!("\n\tSTACK")  ;
41		for x in &mut self.0  {
42			let n = x .len()  ;
43			let mut y = x .replace("\n" ,"")  ;
44			if n > 100  {
45				y = y[..100].to_string()  ;}
46			println!("\n\t[{}] {} . . ." ,i ,y)  ;
47			i += 1  ;}
48		println!("\n")  ;}
49	pub fn finish(&mut self)->String  {
50		if self.0 .len() != 1  {
51			self .preview()  ;
52			panic!("\n\n\tfinish: STACK MUST END WITH ONLY ONE ELEMENT!\n\n")  ;}
53		return self.0[0].to_string()  ;}
54	pub fn doctype(&mut self)->String  {
55		return format!("<!doctype html>{}" ,self .finish())  ;}
56	pub fn clear(&mut self)->&mut Self  {
57		self.0 = vec!()  ;
58		return self  ;}}
59impl Stack  {
60	pub fn put(&mut self ,c:&str)->&mut Self  {
61		self.0 .push(c.to_string())  ;
62		return self  ;}
63	pub fn add(&mut self)->&mut Self  {
64		if self.0 .len() < 2  {
65			self .preview()  ;
66			panic!("\n\n\tadd(): STACK NEEDS TO HAVE AT LEAST TWO ELEMENTS\n\n!")  ;}
67		let x = self.0 .pop().unwrap()  ;
68		let y = self.0 .pop().unwrap()  ;
69		self.0 .push(format!("{}{}" ,y ,x))  ;
70		return self  ;}
71	pub fn wrp(&mut self ,t:&str)->&mut Self  {
72		if self.0 .len() < 1  {
73			self .preview()  ;
74			panic!("\n\n\twrp({}): STACK NEEDS TO HAVE AT LEAST ONE ELEMENT\n\n!" ,t)  ;}
75		let c = self.0 .pop().unwrap()  ;
76		self.0 .push(tag(&c ,t))  ;
77		return self  ;}
78	pub fn swap(&mut self)->&mut Self  {
79		if self.0 .len() < 2  {
80			self .preview()  ;
81			panic!("\n\n\tswap: STACK NEEDS TO HAVE AT LEAST TWO ELEMENTS\n\n!")  ;}
82		let y = self.0 .pop().unwrap()  ;
83		let x = self.0 .pop().unwrap()  ;
84		self.0 .push(y)  ;
85		self.0 .push(x)  ;
86		return self  ;}
87	pub fn dup(&mut self)->&mut Self  {
88		if self.0 .len() < 1  {
89			self .preview()  ;
90			panic!("\n\n\tswap: STACK NEEDS TO HAVE AT LEAST ONE ELEMENT\n\n!")  ;}
91		self.0 .push(self.0.last().unwrap().to_string())  ;
92		return self  ;}
93	pub fn drop(&mut self)->&mut Self  {
94		if self.0 .len() < 1  {
95			self .preview()  ;
96			panic!("\n\n\tswap: STACK NEEDS TO HAVE AT LEAST ONE ELEMENT\n\n!")  ;}
97		self.0 .pop()  ;
98		return self  ;}}
99impl Stack  {
100	pub fn one(&mut self)->&mut Self  {
101		let mut y = "".to_string()  ;
102		for i in &self.0  {
103			y += &i  ;}
104		self.0 = vec!(y)  ;
105		return self  ;}
106	pub fn shuffle(&mut self)->&mut Self  {
107		if self.0 .len() < 2  {
108			self .preview()  ;
109			panic!("\n\n\tshuffle: STACK NEEDS TO HAVE AT LEAST TWO ELEMENTS\n\n!")  ;}
110		let mut hs:HashSet<String> = HashSet::new()  ;
111		loop  {
112			let x = self.0 .pop()  ;
113			if x .is_none()  {
114				break  ;}
115			hs .insert(x.unwrap())  ;}
116		for i in hs  {
117			self.0 .push(i)  ;}
118		return self  ;}}
119