cascading_wasm_language/
lib.rs

1extern crate html_minifier;
2extern crate proc_macro;
3extern crate proc_macro2;
4extern crate quote;
5extern crate syn;
6mod data;
7mod misc;
8mod transform;
9
10use {
11	data::{ast::Document, semantics::Semantics},
12	proc_macro::TokenStream,
13	proc_macro2::TokenStream as TokenStream2,
14	quote::{quote, ToTokens},
15	std::{
16		fs::{read_dir, read_to_string, write},
17		path::Path,
18	},
19	syn::parse_macro_input,
20};
21
22// type BoxResult<T> = Result<T, Box<dyn std::error::ErrorError>>;
23
24fn pipeline(document: Document) -> (String, TokenStream2) {
25	let mut semantics = document.analyze();
26	semantics.render();
27	for (i, group) in semantics.groups.iter().enumerate() {
28		eprintln!("{} {:?}", i, group);
29	}
30	(semantics.html().0, semantics.wasm(true))
31}
32
33#[proc_macro]
34pub fn cwl(input: TokenStream) -> TokenStream {
35	let mut input = input.into();
36
37	// if it exists, import .cwl files from the `cwl` directory and attach them to the input
38	let path = "./cwl";
39	if Path::new(path).exists() {
40		for entry in read_dir(path).expect(&*format!("reading from {}", path)) {
41			let entry = entry.expect("reading .cwl file");
42			let filename = entry.path().display().to_string();
43			if filename.ends_with(".cwl") {
44				let contents: TokenStream2 = read_to_string(entry.path()).unwrap().parse().unwrap();
45				contents.to_tokens(&mut input);
46			}
47		}
48	}
49
50	let input = input.into();
51	let (html, runtime) = pipeline(parse_macro_input!(input as Document));
52	let destination = format!("target/html/index.html");
53	write(&destination, html).expect(&*format!("writing output html code to {}", destination));
54	write("target/cwl_macro_output.rs", runtime.to_string()).expect("writing output rust code");
55
56	runtime.into()
57}
58
59#[proc_macro]
60pub fn cwl_document(input: TokenStream) -> TokenStream {
61	let document = parse_macro_input!(input as Document);
62	let mut semantics = document.analyze();
63	semantics.render();
64
65	let (pages, styles) = semantics.html_parts();
66	let content = pages.get(&String::from("/")).unwrap();
67
68	let wasm = semantics.wasm(false);
69	let wasm = quote! {
70		let window = web_sys::window().expect("getting window");
71		let document = &window.document().expect("getting `window.document`");
72		let head = &document.head().expect("getting `window.document.head`");
73		let body = &document.body().expect("getting `window.document.body`");
74		{
75			let style = document
76				.create_element("style")
77				.unwrap()
78				.dyn_into::<HtmlElement>()
79				.unwrap();
80			style.set_inner_text(#styles);
81			head.append_child(&style).unwrap();
82
83			let content = document.create_element("div").unwrap();
84			body.prepend_with_node_1(&content).unwrap();
85			content.set_outer_html(#content);
86		}
87		#wasm
88	};
89
90	eprintln!("***************************");
91	eprintln!("{}", wasm);
92	eprintln!("***************************");
93
94	wasm.into()
95}
96
97#[proc_macro]
98pub fn cwl_header(_input: TokenStream) -> TokenStream {
99	Semantics::header().into()
100}