inline_css_macros/
lib.rs

1// Copyright (C) 2023 Benjamin Stürz
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program.  If not, see <http://www.gnu.org/licenses/>.
15#![allow(dead_code)]
16use proc_macro::TokenStream;
17use proc_macro2::{Ident, Group};
18use syn::{Token, LitInt, parse_macro_input, ExprBlock, LitFloat};
19use quote::ToTokens;
20
21mod parse;
22mod gen;
23
24struct CSS(Vec<Rule>);
25
26struct Rule {
27    selector: Selector,
28    group: Group,
29    declarations: Declarations,
30}
31
32enum Selector {
33    Any(Token![*]),
34    Simple {
35        ident: Option<CSSIdent>,
36        class: Option<(Token![.], CSSIdent)>,
37        id: Option<(Token![#], CSSIdent)>,
38    },
39    Colon {
40        colon: Token![:],
41        ident: CSSIdent,
42        arg: Option<(Group, Value)>,
43    },
44    Sub {
45        left: Box<Selector>,
46        right: Box<Selector>,
47    },
48    Gt {
49        left: Box<Selector>,
50        gt: Token![>],
51        right: Box<Selector>,
52    },
53    Plus {
54        left: Box<Selector>,
55        plus: Token![+],
56        right: Box<Selector>,
57    },
58    Tilde {
59        left: Box<Selector>,
60        tilde: Token![~],
61        right: Box<Selector>,
62    },
63    Comma {
64        left: Box<Selector>,
65        comma: Token![,],
66        right: Box<Selector>,
67    },
68}
69
70struct Declarations(Vec<Declaration>);
71
72struct Declaration {
73    ident: CSSIdent,
74    colon: Token![:],
75    value: Vec<Value>,
76    semicolon: Token![;],
77}
78
79enum Value {
80    ColorCode { pound: Token![#], value: LitInt },
81    Ident(CSSIdent),
82    Int(LitInt),
83    Float(LitFloat),
84    IntPerc(LitInt, Token![%]),
85    FloatPerc(LitFloat, Token![%]),
86    Function { ident: CSSIdent, group: Group, args: Args },
87    Block(ExprBlock),
88}
89
90struct Args(Vec<Value>);
91
92struct CSSIdent(Vec<CSSIdentSegment>);
93
94enum CSSIdentSegment {
95    Ident(Ident),
96    Minus(Token![-]),
97}
98
99#[proc_macro]
100pub fn css(input: TokenStream) -> TokenStream {
101    parse_macro_input!(input as CSS).into_token_stream().into()
102}
103
104#[proc_macro]
105pub fn css_rule(input: TokenStream) -> TokenStream {
106    parse_macro_input!(input as Rule).into_token_stream().into()
107}
108
109#[proc_macro]
110pub fn css_value(input: TokenStream) -> TokenStream {
111    parse_macro_input!(input as Value).into_token_stream().into()
112}