css_ast/selector/
tag.rs

1use crate::CssAtomSet;
2use css_parse::{Cursor, Diagnostic, Parse, Parser, Peek, Result, T};
3use csskit_derives::{IntoCursor, Parse, Peek, ToCursors};
4
5#[derive(Parse, ToCursors, IntoCursor, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
7#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
8pub enum Tag {
9	Html(HtmlTag),
10	HtmlNonStandard(HtmlNonStandardTag),
11	HtmlNonConforming(HtmlNonConformingTag),
12	Svg(SvgTag),
13	Mathml(MathmlTag),
14	CustomElement(CustomElementTag),
15	Unknown(UnknownTag),
16}
17
18impl<'a> Peek<'a> for Tag {
19	fn peek<I>(p: &Parser<'a, I>, c: Cursor) -> bool
20	where
21		I: Iterator<Item = Cursor> + Clone,
22	{
23		<T![Ident]>::peek(p, c)
24	}
25}
26
27#[derive(ToCursors, IntoCursor, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
29#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
30pub struct CustomElementTag(T![Ident]);
31
32impl CustomElementTag {
33	fn is_invalid(atom: CssAtomSet) -> bool {
34		matches!(
35			atom,
36			CssAtomSet::AnnotationXml
37				| CssAtomSet::ColorProfile
38				| CssAtomSet::FontFace
39				| CssAtomSet::FontFaceSrc
40				| CssAtomSet::FontFaceUri
41				| CssAtomSet::FontFaceFormat
42				| CssAtomSet::FontFaceName
43				| CssAtomSet::MissingGlyph
44		)
45	}
46}
47
48impl<'a> Peek<'a> for CustomElementTag {
49	fn peek<I>(p: &Parser<'a, I>, c: Cursor) -> bool
50	where
51		I: Iterator<Item = Cursor> + Clone,
52	{
53		let str = p.to_source_cursor(c).parse(p.bump());
54		if Self::is_invalid(p.to_atom(c)) {
55			return false;
56		}
57		let mut chars = str.chars();
58		if !matches!(chars.next(), Some('a'..='z')) {
59			return false;
60		}
61		let mut has_dash = false;
62		for char in chars {
63			if char == '-' {
64				has_dash = true;
65				continue;
66			}
67			if !matches!(char,
68				'.' |
69				'_' |
70				'0'..='9' |
71				'a'..='z' |
72				'\u{b7}' |
73				'\u{c0}'..='\u{d6}' |
74				'\u{d8}'..='\u{f6}' |
75				'\u{f8}'..='\u{37d}' |
76				'\u{37F}'..='\u{1fff}' |
77				'\u{200c}'..='\u{200d}' |
78				'\u{203f}'..='\u{2040}' |
79				'\u{2070}'..='\u{218f}' |
80				'\u{2c00}'..='\u{2fef}' |
81				'\u{3001}'..='\u{d7ff}' |
82				'\u{f900}'..='\u{fdcf}' |
83				'\u{fdf0}'..='\u{fffd}' |
84				'\u{10000}'..='\u{effff}'
85			) {
86				return false;
87			}
88		}
89		has_dash
90	}
91}
92
93impl<'a> Parse<'a> for CustomElementTag {
94	fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
95	where
96		I: Iterator<Item = Cursor> + Clone,
97	{
98		if p.peek::<Self>() {
99			p.parse::<T![Ident]>().map(Self)
100		} else {
101			Err(Diagnostic::new(p.next(), Diagnostic::unexpected))?
102		}
103	}
104}
105
106/// <https://html.spec.whatwg.org/multipage/indices.html#elements-3>
107#[derive(Parse, Peek, ToCursors, IntoCursor, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
108#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
109#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
110pub enum HtmlTag {
111	#[atom(CssAtomSet::A)]
112	A(T![Ident]),
113	#[atom(CssAtomSet::Abbr)]
114	Abbr(T![Ident]),
115	#[atom(CssAtomSet::Address)]
116	Address(T![Ident]),
117	#[atom(CssAtomSet::Area)]
118	Area(T![Ident]),
119	#[atom(CssAtomSet::Article)]
120	Article(T![Ident]),
121	#[atom(CssAtomSet::Aside)]
122	Aside(T![Ident]),
123	#[atom(CssAtomSet::Audio)]
124	Audio(T![Ident]),
125	#[atom(CssAtomSet::B)]
126	B(T![Ident]),
127	#[atom(CssAtomSet::Base)]
128	Base(T![Ident]),
129	#[atom(CssAtomSet::Bdi)]
130	Bdi(T![Ident]),
131	#[atom(CssAtomSet::Bdo)]
132	Bdo(T![Ident]),
133	#[atom(CssAtomSet::Blockquote)]
134	Blockquote(T![Ident]),
135	#[atom(CssAtomSet::Body)]
136	Body(T![Ident]),
137	#[atom(CssAtomSet::Br)]
138	Br(T![Ident]),
139	#[atom(CssAtomSet::Button)]
140	Button(T![Ident]),
141	#[atom(CssAtomSet::Canvas)]
142	Canvas(T![Ident]),
143	#[atom(CssAtomSet::Caption)]
144	Caption(T![Ident]),
145	#[atom(CssAtomSet::Cite)]
146	Cite(T![Ident]),
147	#[atom(CssAtomSet::Code)]
148	Code(T![Ident]),
149	#[atom(CssAtomSet::Col)]
150	Col(T![Ident]),
151	#[atom(CssAtomSet::Colgroup)]
152	Colgroup(T![Ident]),
153	#[atom(CssAtomSet::Data)]
154	Data(T![Ident]),
155	#[atom(CssAtomSet::Datalist)]
156	Datalist(T![Ident]),
157	#[atom(CssAtomSet::Dd)]
158	Dd(T![Ident]),
159	#[atom(CssAtomSet::Del)]
160	Del(T![Ident]),
161	#[atom(CssAtomSet::Details)]
162	Details(T![Ident]),
163	#[atom(CssAtomSet::Dfn)]
164	Dfn(T![Ident]),
165	#[atom(CssAtomSet::Dialog)]
166	Dialog(T![Ident]),
167	#[atom(CssAtomSet::Div)]
168	Div(T![Ident]),
169	#[atom(CssAtomSet::Dl)]
170	Dl(T![Ident]),
171	#[atom(CssAtomSet::Dt)]
172	Dt(T![Ident]),
173	#[atom(CssAtomSet::Em)]
174	Em(T![Ident]),
175	#[atom(CssAtomSet::Embed)]
176	Embed(T![Ident]),
177	#[atom(CssAtomSet::Fieldset)]
178	Fieldset(T![Ident]),
179	#[atom(CssAtomSet::Figcaption)]
180	Figcaption(T![Ident]),
181	#[atom(CssAtomSet::Figure)]
182	Figure(T![Ident]),
183	#[atom(CssAtomSet::Footer)]
184	Footer(T![Ident]),
185	#[atom(CssAtomSet::Form)]
186	Form(T![Ident]),
187	#[atom(CssAtomSet::H1)]
188	H1(T![Ident]),
189	#[atom(CssAtomSet::H2)]
190	H2(T![Ident]),
191	#[atom(CssAtomSet::H3)]
192	H3(T![Ident]),
193	#[atom(CssAtomSet::H4)]
194	H4(T![Ident]),
195	#[atom(CssAtomSet::H5)]
196	H5(T![Ident]),
197	#[atom(CssAtomSet::H6)]
198	H6(T![Ident]),
199	#[atom(CssAtomSet::Head)]
200	Head(T![Ident]),
201	#[atom(CssAtomSet::Header)]
202	Header(T![Ident]),
203	#[atom(CssAtomSet::Hgroup)]
204	Hgroup(T![Ident]),
205	#[atom(CssAtomSet::Hr)]
206	Hr(T![Ident]),
207	#[atom(CssAtomSet::Html)]
208	Html(T![Ident]),
209	#[atom(CssAtomSet::I)]
210	I(T![Ident]),
211	#[atom(CssAtomSet::Iframe)]
212	Iframe(T![Ident]),
213	#[atom(CssAtomSet::Img)]
214	Img(T![Ident]),
215	#[atom(CssAtomSet::Input)]
216	Input(T![Ident]),
217	#[atom(CssAtomSet::Ins)]
218	Ins(T![Ident]),
219	#[atom(CssAtomSet::Kbd)]
220	Kbd(T![Ident]),
221	#[atom(CssAtomSet::Label)]
222	Label(T![Ident]),
223	#[atom(CssAtomSet::Legend)]
224	Legend(T![Ident]),
225	#[atom(CssAtomSet::Li)]
226	Li(T![Ident]),
227	#[atom(CssAtomSet::Link)]
228	Link(T![Ident]),
229	#[atom(CssAtomSet::Main)]
230	Main(T![Ident]),
231	#[atom(CssAtomSet::Map)]
232	Map(T![Ident]),
233	#[atom(CssAtomSet::Mark)]
234	Mark(T![Ident]),
235	#[atom(CssAtomSet::Menu)]
236	Menu(T![Ident]),
237	#[atom(CssAtomSet::Meta)]
238	Meta(T![Ident]),
239	#[atom(CssAtomSet::Meter)]
240	Meter(T![Ident]),
241	#[atom(CssAtomSet::Nav)]
242	Nav(T![Ident]),
243	#[atom(CssAtomSet::Noscript)]
244	Noscript(T![Ident]),
245	#[atom(CssAtomSet::Object)]
246	Object(T![Ident]),
247	#[atom(CssAtomSet::Ol)]
248	Ol(T![Ident]),
249	#[atom(CssAtomSet::Optgroup)]
250	Optgroup(T![Ident]),
251	#[atom(CssAtomSet::Option)]
252	Option(T![Ident]),
253	#[atom(CssAtomSet::Output)]
254	Output(T![Ident]),
255	#[atom(CssAtomSet::P)]
256	P(T![Ident]),
257	#[atom(CssAtomSet::Picture)]
258	Picture(T![Ident]),
259	#[atom(CssAtomSet::Pre)]
260	Pre(T![Ident]),
261	#[atom(CssAtomSet::Progress)]
262	Progress(T![Ident]),
263	#[atom(CssAtomSet::Q)]
264	Q(T![Ident]),
265	#[atom(CssAtomSet::Rp)]
266	Rp(T![Ident]),
267	#[atom(CssAtomSet::Rt)]
268	Rt(T![Ident]),
269	#[atom(CssAtomSet::Ruby)]
270	Ruby(T![Ident]),
271	#[atom(CssAtomSet::S)]
272	S(T![Ident]),
273	#[atom(CssAtomSet::Samp)]
274	Samp(T![Ident]),
275	#[atom(CssAtomSet::Script)]
276	Script(T![Ident]),
277	#[atom(CssAtomSet::Search)]
278	Search(T![Ident]),
279	#[atom(CssAtomSet::Section)]
280	Section(T![Ident]),
281	#[atom(CssAtomSet::Select)]
282	Select(T![Ident]),
283	#[atom(CssAtomSet::Slot)]
284	Slot(T![Ident]),
285	#[atom(CssAtomSet::Small)]
286	Small(T![Ident]),
287	#[atom(CssAtomSet::Source)]
288	Source(T![Ident]),
289	#[atom(CssAtomSet::Span)]
290	Span(T![Ident]),
291	#[atom(CssAtomSet::Strong)]
292	Strong(T![Ident]),
293	#[atom(CssAtomSet::Style)]
294	Style(T![Ident]),
295	#[atom(CssAtomSet::Sub)]
296	Sub(T![Ident]),
297	#[atom(CssAtomSet::Summary)]
298	Summary(T![Ident]),
299	#[atom(CssAtomSet::Sup)]
300	Sup(T![Ident]),
301	#[atom(CssAtomSet::Table)]
302	Table(T![Ident]),
303	#[atom(CssAtomSet::Tbody)]
304	Tbody(T![Ident]),
305	#[atom(CssAtomSet::Td)]
306	Td(T![Ident]),
307	#[atom(CssAtomSet::Template)]
308	Template(T![Ident]),
309	#[atom(CssAtomSet::Textarea)]
310	Textarea(T![Ident]),
311	#[atom(CssAtomSet::Tfoot)]
312	Tfoot(T![Ident]),
313	#[atom(CssAtomSet::Th)]
314	Th(T![Ident]),
315	#[atom(CssAtomSet::Thead)]
316	Thead(T![Ident]),
317	#[atom(CssAtomSet::Time)]
318	Time(T![Ident]),
319	#[atom(CssAtomSet::Title)]
320	Title(T![Ident]),
321	#[atom(CssAtomSet::Tr)]
322	Tr(T![Ident]),
323	#[atom(CssAtomSet::Track)]
324	Track(T![Ident]),
325	#[atom(CssAtomSet::U)]
326	U(T![Ident]),
327	#[atom(CssAtomSet::Ul)]
328	Ul(T![Ident]),
329	#[atom(CssAtomSet::Var)]
330	Var(T![Ident]),
331	#[atom(CssAtomSet::Video)]
332	Video(T![Ident]),
333	#[atom(CssAtomSet::Wbr)]
334	Wbr(T![Ident]),
335}
336
337/// <https://html.spec.whatwg.org/multipage/obsolete.html#non-conforming-features>
338#[derive(Parse, Peek, ToCursors, IntoCursor, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
339#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
340#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
341pub enum HtmlNonConformingTag {
342	#[atom(CssAtomSet::Acronym)]
343	Acronym(T![Ident]),
344	#[atom(CssAtomSet::Applet)]
345	Applet(T![Ident]),
346	#[atom(CssAtomSet::Basefont)]
347	Basefont(T![Ident]),
348	#[atom(CssAtomSet::Bgsound)]
349	Bgsound(T![Ident]),
350	#[atom(CssAtomSet::Big)]
351	Big(T![Ident]),
352	#[atom(CssAtomSet::Blink)]
353	Blink(T![Ident]),
354	#[atom(CssAtomSet::Center)]
355	Center(T![Ident]),
356	#[atom(CssAtomSet::Dir)]
357	Dir(T![Ident]),
358	#[atom(CssAtomSet::Font)]
359	Font(T![Ident]),
360	#[atom(CssAtomSet::Frame)]
361	Frame(T![Ident]),
362	#[atom(CssAtomSet::Frameset)]
363	Frameset(T![Ident]),
364	#[atom(CssAtomSet::Isindex)]
365	Isindex(T![Ident]),
366	#[atom(CssAtomSet::Keygen)]
367	Keygen(T![Ident]),
368	#[atom(CssAtomSet::Listing)]
369	Listing(T![Ident]),
370	#[atom(CssAtomSet::Marquee)]
371	Marquee(T![Ident]),
372	#[atom(CssAtomSet::Menuitem)]
373	Menuitem(T![Ident]),
374	#[atom(CssAtomSet::Multicol)]
375	Multicol(T![Ident]),
376	#[atom(CssAtomSet::Nextid)]
377	Nextid(T![Ident]),
378	#[atom(CssAtomSet::Nobr)]
379	Nobr(T![Ident]),
380	#[atom(CssAtomSet::Noembed)]
381	Noembed(T![Ident]),
382	#[atom(CssAtomSet::Noframes)]
383	Noframes(T![Ident]),
384	#[atom(CssAtomSet::Param)]
385	Param(T![Ident]),
386	#[atom(CssAtomSet::Plaintext)]
387	Plaintext(T![Ident]),
388	#[atom(CssAtomSet::Rb)]
389	Rb(T![Ident]),
390	#[atom(CssAtomSet::Rtc)]
391	Rtc(T![Ident]),
392	#[atom(CssAtomSet::Spacer)]
393	Spacer(T![Ident]),
394	#[atom(CssAtomSet::Strike)]
395	Strike(T![Ident]),
396	#[atom(CssAtomSet::Tt)]
397	Tt(T![Ident]),
398	#[atom(CssAtomSet::Xmp)]
399	Xmp(T![Ident]),
400}
401
402#[derive(Parse, Peek, ToCursors, IntoCursor, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
403#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
404#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
405pub enum HtmlNonStandardTag {
406	// https://wicg.github.io/fenced-frame/#the-fencedframe-element
407	#[atom(CssAtomSet::Fencedframe)]
408	Fencedframe(T![Ident]),
409	// https://wicg.github.io/portals/#the-portal-element
410	#[atom(CssAtomSet::Portal)]
411	Portal(T![Ident]),
412	// https://wicg.github.io/PEPC/permission-element.html#the-permission-element
413	#[atom(CssAtomSet::Permission)]
414	Permission(T![Ident]),
415	// https://open-ui.org/components/customizableselect/
416	#[atom(CssAtomSet::Selectedcontent)]
417	Selectedcontent(T![Ident]),
418}
419
420/// <https://svgwg.org/svg2-draft/eltindex.html>
421#[derive(Parse, Peek, ToCursors, IntoCursor, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
422#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
423#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
424pub enum SvgTag {
425	#[atom(CssAtomSet::A)]
426	A(T![Ident]),
427	#[atom(CssAtomSet::Animate)]
428	Animate(T![Ident]),
429	#[atom(CssAtomSet::Animatemotion)]
430	Animatemotion(T![Ident]),
431	#[atom(CssAtomSet::Animatetransform)]
432	Animatetransform(T![Ident]),
433	#[atom(CssAtomSet::Circle)]
434	Circle(T![Ident]),
435	#[atom(CssAtomSet::Clippath)]
436	Clippath(T![Ident]),
437	#[atom(CssAtomSet::Defs)]
438	Defs(T![Ident]),
439	#[atom(CssAtomSet::Desc)]
440	Desc(T![Ident]),
441	#[atom(CssAtomSet::Discard)]
442	Discard(T![Ident]),
443	#[atom(CssAtomSet::Ellipse)]
444	Ellipse(T![Ident]),
445	#[atom(CssAtomSet::Feblend)]
446	Feblend(T![Ident]),
447	#[atom(CssAtomSet::Fecolormatrix)]
448	Fecolormatrix(T![Ident]),
449	#[atom(CssAtomSet::Fecomponenttransfer)]
450	Fecomponenttransfer(T![Ident]),
451	#[atom(CssAtomSet::Fecomposite)]
452	Fecomposite(T![Ident]),
453	#[atom(CssAtomSet::Feconvolvematrix)]
454	Feconvolvematrix(T![Ident]),
455	#[atom(CssAtomSet::Fediffuselighting)]
456	Fediffuselighting(T![Ident]),
457	#[atom(CssAtomSet::Fedisplacementmap)]
458	Fedisplacementmap(T![Ident]),
459	#[atom(CssAtomSet::Fedistantlight)]
460	Fedistantlight(T![Ident]),
461	#[atom(CssAtomSet::Fedropshadow)]
462	Fedropshadow(T![Ident]),
463	#[atom(CssAtomSet::Feflood)]
464	Feflood(T![Ident]),
465	#[atom(CssAtomSet::Fefunca)]
466	Fefunca(T![Ident]),
467	#[atom(CssAtomSet::Fefuncb)]
468	Fefuncb(T![Ident]),
469	#[atom(CssAtomSet::Fefuncg)]
470	Fefuncg(T![Ident]),
471	#[atom(CssAtomSet::Fefuncr)]
472	Fefuncr(T![Ident]),
473	#[atom(CssAtomSet::Fegaussianblur)]
474	Fegaussianblur(T![Ident]),
475	#[atom(CssAtomSet::Feimage)]
476	Feimage(T![Ident]),
477	#[atom(CssAtomSet::Femerge)]
478	Femerge(T![Ident]),
479	#[atom(CssAtomSet::Femergenode)]
480	Femergenode(T![Ident]),
481	#[atom(CssAtomSet::Femorphology)]
482	Femorphology(T![Ident]),
483	#[atom(CssAtomSet::Feoffset)]
484	Feoffset(T![Ident]),
485	#[atom(CssAtomSet::Fepointlight)]
486	Fepointlight(T![Ident]),
487	#[atom(CssAtomSet::Fespecularlighting)]
488	Fespecularlighting(T![Ident]),
489	#[atom(CssAtomSet::Fespotlight)]
490	Fespotlight(T![Ident]),
491	#[atom(CssAtomSet::Fetile)]
492	Fetile(T![Ident]),
493	#[atom(CssAtomSet::Feturbulence)]
494	Feturbulence(T![Ident]),
495	#[atom(CssAtomSet::Filter)]
496	Filter(T![Ident]),
497	#[atom(CssAtomSet::Foreignobject)]
498	Foreignobject(T![Ident]),
499	#[atom(CssAtomSet::G)]
500	G(T![Ident]),
501	#[atom(CssAtomSet::Image)]
502	Image(T![Ident]),
503	#[atom(CssAtomSet::Line)]
504	Line(T![Ident]),
505	#[atom(CssAtomSet::Lineargradient)]
506	Lineargradient(T![Ident]),
507	#[atom(CssAtomSet::Marker)]
508	Marker(T![Ident]),
509	#[atom(CssAtomSet::Mask)]
510	Mask(T![Ident]),
511	#[atom(CssAtomSet::Metadata)]
512	Metadata(T![Ident]),
513	#[atom(CssAtomSet::Mpath)]
514	Mpath(T![Ident]),
515	#[atom(CssAtomSet::Path)]
516	Path(T![Ident]),
517	#[atom(CssAtomSet::Pattern)]
518	Pattern(T![Ident]),
519	#[atom(CssAtomSet::Polygon)]
520	Polygon(T![Ident]),
521	#[atom(CssAtomSet::Polyline)]
522	Polyline(T![Ident]),
523	#[atom(CssAtomSet::Radialgradient)]
524	Radialgradient(T![Ident]),
525	#[atom(CssAtomSet::Rect)]
526	Rect(T![Ident]),
527	#[atom(CssAtomSet::Script)]
528	Script(T![Ident]),
529	#[atom(CssAtomSet::Set)]
530	Set(T![Ident]),
531	#[atom(CssAtomSet::Stop)]
532	Stop(T![Ident]),
533	#[atom(CssAtomSet::Style)]
534	Style(T![Ident]),
535	#[atom(CssAtomSet::Svg)]
536	Svg(T![Ident]),
537	#[atom(CssAtomSet::Switch)]
538	Switch(T![Ident]),
539	#[atom(CssAtomSet::Symbol)]
540	Symbol(T![Ident]),
541	#[atom(CssAtomSet::Text)]
542	Text(T![Ident]),
543	#[atom(CssAtomSet::Textpath)]
544	Textpath(T![Ident]),
545	#[atom(CssAtomSet::Title)]
546	Title(T![Ident]),
547	#[atom(CssAtomSet::Tspan)]
548	Tspan(T![Ident]),
549	#[atom(CssAtomSet::Use)]
550	Use(T![Ident]),
551	#[atom(CssAtomSet::View)]
552	View(T![Ident]),
553}
554
555/// <https://w3c.github.io/mathml/#mmlindex_elements>
556#[derive(Parse, Peek, ToCursors, IntoCursor, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
557#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
558#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
559pub enum MathmlTag {
560	#[atom(CssAtomSet::Abs)]
561	Abs(T![Ident]),
562	#[atom(CssAtomSet::And)]
563	And(T![Ident]),
564	#[atom(CssAtomSet::Annotation)]
565	Annotation(T![Ident]),
566	#[atom(CssAtomSet::AnnotationXml)]
567	AnnotationXml(T![Ident]),
568	#[atom(CssAtomSet::Apply)]
569	Apply(T![Ident]),
570	#[atom(CssAtomSet::Approx)]
571	Approx(T![Ident]),
572	#[atom(CssAtomSet::Arg)]
573	Arg(T![Ident]),
574	#[atom(CssAtomSet::Bind)]
575	Bind(T![Ident]),
576	#[atom(CssAtomSet::Bvar)]
577	Bvar(T![Ident]),
578	#[atom(CssAtomSet::Card)]
579	Card(T![Ident]),
580	#[atom(CssAtomSet::Cartesianproduct)]
581	Cartesianproduct(T![Ident]),
582	#[atom(CssAtomSet::Cbytes)]
583	Cbytes(T![Ident]),
584	#[atom(CssAtomSet::Ceiling)]
585	Ceiling(T![Ident]),
586	#[atom(CssAtomSet::Cerror)]
587	Cerror(T![Ident]),
588	#[atom(CssAtomSet::Ci)]
589	Ci(T![Ident]),
590	#[atom(CssAtomSet::Cn)]
591	Cn(T![Ident]),
592	#[atom(CssAtomSet::Codomain)]
593	Codomain(T![Ident]),
594	#[atom(CssAtomSet::Compose)]
595	Compose(T![Ident]),
596	#[atom(CssAtomSet::Condition)]
597	Condition(T![Ident]),
598	#[atom(CssAtomSet::Conjugate)]
599	Conjugate(T![Ident]),
600	#[atom(CssAtomSet::Cs)]
601	Cs(T![Ident]),
602	#[atom(CssAtomSet::Csymbol)]
603	Csymbol(T![Ident]),
604	#[atom(CssAtomSet::Curl)]
605	Curl(T![Ident]),
606	#[atom(CssAtomSet::Declare)]
607	Declare(T![Ident]),
608	#[atom(CssAtomSet::Degree)]
609	Degree(T![Ident]),
610	#[atom(CssAtomSet::Determinant)]
611	Determinant(T![Ident]),
612	#[atom(CssAtomSet::Diff)]
613	Diff(T![Ident]),
614	#[atom(CssAtomSet::Divergence)]
615	Divergence(T![Ident]),
616	#[atom(CssAtomSet::Divide)]
617	Divide(T![Ident]),
618	#[atom(CssAtomSet::Domain)]
619	Domain(T![Ident]),
620	#[atom(CssAtomSet::Domainofapplication)]
621	Domainofapplication(T![Ident]),
622	#[atom(CssAtomSet::Emptyset)]
623	Emptyset(T![Ident]),
624	#[atom(CssAtomSet::Eq)]
625	Eq(T![Ident]),
626	#[atom(CssAtomSet::Equivalent)]
627	Equivalent(T![Ident]),
628	#[atom(CssAtomSet::Exists)]
629	Exists(T![Ident]),
630	#[atom(CssAtomSet::Exp)]
631	Exp(T![Ident]),
632	#[atom(CssAtomSet::Factorial)]
633	Factorial(T![Ident]),
634	#[atom(CssAtomSet::Factorof)]
635	Factorof(T![Ident]),
636	#[atom(CssAtomSet::Floor)]
637	Floor(T![Ident]),
638	#[atom(CssAtomSet::Fn)]
639	Fn(T![Ident]),
640	#[atom(CssAtomSet::Forall)]
641	Forall(T![Ident]),
642	#[atom(CssAtomSet::Gcd)]
643	Gcd(T![Ident]),
644	#[atom(CssAtomSet::Geq)]
645	Geq(T![Ident]),
646	#[atom(CssAtomSet::Grad)]
647	Grad(T![Ident]),
648	#[atom(CssAtomSet::Gt)]
649	Gt(T![Ident]),
650	#[atom(CssAtomSet::Ident)]
651	Ident(T![Ident]),
652	#[atom(CssAtomSet::Image)]
653	Image(T![Ident]),
654	#[atom(CssAtomSet::Imaginary)]
655	Imaginary(T![Ident]),
656	#[atom(CssAtomSet::Img)]
657	Img(T![Ident]),
658	#[atom(CssAtomSet::Implies)]
659	Implies(T![Ident]),
660	#[atom(CssAtomSet::In)]
661	In(T![Ident]),
662	#[atom(CssAtomSet::Int)]
663	Int(T![Ident]),
664	#[atom(CssAtomSet::Intersect)]
665	Intersect(T![Ident]),
666	#[atom(CssAtomSet::Interval)]
667	Interval(T![Ident]),
668	#[atom(CssAtomSet::Inverse)]
669	Inverse(T![Ident]),
670	#[atom(CssAtomSet::Lambda)]
671	Lambda(T![Ident]),
672	#[atom(CssAtomSet::Laplacian)]
673	Laplacian(T![Ident]),
674	#[atom(CssAtomSet::Lcm)]
675	Lcm(T![Ident]),
676	#[atom(CssAtomSet::Leq)]
677	Leq(T![Ident]),
678	#[atom(CssAtomSet::Limit)]
679	Limit(T![Ident]),
680	#[atom(CssAtomSet::List)]
681	List(T![Ident]),
682	#[atom(CssAtomSet::Ln)]
683	Ln(T![Ident]),
684	#[atom(CssAtomSet::Log)]
685	Log(T![Ident]),
686	#[atom(CssAtomSet::Logbase)]
687	Logbase(T![Ident]),
688	#[atom(CssAtomSet::Lowlimit)]
689	Lowlimit(T![Ident]),
690	#[atom(CssAtomSet::Lt)]
691	Lt(T![Ident]),
692	#[atom(CssAtomSet::Maction)]
693	Maction(T![Ident]),
694	#[atom(CssAtomSet::Maligngroup)]
695	Maligngroup(T![Ident]),
696	#[atom(CssAtomSet::Malignmark)]
697	Malignmark(T![Ident]),
698	#[atom(CssAtomSet::Math)]
699	Math(T![Ident]),
700	#[atom(CssAtomSet::Matrix)]
701	Matrix(T![Ident]),
702	#[atom(CssAtomSet::Matrixrow)]
703	Matrixrow(T![Ident]),
704	#[atom(CssAtomSet::Max)]
705	Max(T![Ident]),
706	#[atom(CssAtomSet::Mean)]
707	Mean(T![Ident]),
708	#[atom(CssAtomSet::Median)]
709	Median(T![Ident]),
710	#[atom(CssAtomSet::Menclose)]
711	Menclose(T![Ident]),
712	#[atom(CssAtomSet::Merror)]
713	Merror(T![Ident]),
714	#[atom(CssAtomSet::Mfenced)]
715	Mfenced(T![Ident]),
716	#[atom(CssAtomSet::Mfrac)]
717	Mfrac(T![Ident]),
718	#[atom(CssAtomSet::Mfraction)]
719	Mfraction(T![Ident]),
720	#[atom(CssAtomSet::Mglyph)]
721	Mglyph(T![Ident]),
722	#[atom(CssAtomSet::Mi)]
723	Mi(T![Ident]),
724	#[atom(CssAtomSet::Min)]
725	Min(T![Ident]),
726	#[atom(CssAtomSet::Minus)]
727	Minus(T![Ident]),
728	#[atom(CssAtomSet::Mlabeledtr)]
729	Mlabeledtr(T![Ident]),
730	#[atom(CssAtomSet::Mlongdiv)]
731	Mlongdiv(T![Ident]),
732	#[atom(CssAtomSet::Mmultiscripts)]
733	Mmultiscripts(T![Ident]),
734	#[atom(CssAtomSet::Mn)]
735	Mn(T![Ident]),
736	#[atom(CssAtomSet::Mo)]
737	Mo(T![Ident]),
738	#[atom(CssAtomSet::Mode)]
739	Mode(T![Ident]),
740	#[atom(CssAtomSet::Moment)]
741	Moment(T![Ident]),
742	#[atom(CssAtomSet::Momentabout)]
743	Momentabout(T![Ident]),
744	#[atom(CssAtomSet::Mover)]
745	Mover(T![Ident]),
746	#[atom(CssAtomSet::Mpadded)]
747	Mpadded(T![Ident]),
748	#[atom(CssAtomSet::Mphantom)]
749	Mphantom(T![Ident]),
750	#[atom(CssAtomSet::Mprescripts)]
751	Mprescripts(T![Ident]),
752	#[atom(CssAtomSet::Mroot)]
753	Mroot(T![Ident]),
754	#[atom(CssAtomSet::Mrow)]
755	Mrow(T![Ident]),
756	#[atom(CssAtomSet::Ms)]
757	Ms(T![Ident]),
758	#[atom(CssAtomSet::Mscarries)]
759	Mscarries(T![Ident]),
760	#[atom(CssAtomSet::Mscarry)]
761	Mscarry(T![Ident]),
762	#[atom(CssAtomSet::Msgroup)]
763	Msgroup(T![Ident]),
764	#[atom(CssAtomSet::Msline)]
765	Msline(T![Ident]),
766	#[atom(CssAtomSet::Mspace)]
767	Mspace(T![Ident]),
768	#[atom(CssAtomSet::Msqrt)]
769	Msqrt(T![Ident]),
770	#[atom(CssAtomSet::Msrow)]
771	Msrow(T![Ident]),
772	#[atom(CssAtomSet::Mstack)]
773	Mstack(T![Ident]),
774	#[atom(CssAtomSet::Mstyle)]
775	Mstyle(T![Ident]),
776	#[atom(CssAtomSet::Msub)]
777	Msub(T![Ident]),
778	#[atom(CssAtomSet::Msubsup)]
779	Msubsup(T![Ident]),
780	#[atom(CssAtomSet::Msup)]
781	Msup(T![Ident]),
782	#[atom(CssAtomSet::Mtable)]
783	Mtable(T![Ident]),
784	#[atom(CssAtomSet::Mtd)]
785	Mtd(T![Ident]),
786	#[atom(CssAtomSet::Mtext)]
787	Mtext(T![Ident]),
788	#[atom(CssAtomSet::Mtr)]
789	Mtr(T![Ident]),
790	#[atom(CssAtomSet::Munder)]
791	Munder(T![Ident]),
792	#[atom(CssAtomSet::Munderover)]
793	Munderover(T![Ident]),
794	#[atom(CssAtomSet::Neq)]
795	Neq(T![Ident]),
796	#[atom(CssAtomSet::None)]
797	None(T![Ident]),
798	#[atom(CssAtomSet::Not)]
799	Not(T![Ident]),
800	#[atom(CssAtomSet::Notin)]
801	Notin(T![Ident]),
802	#[atom(CssAtomSet::Notprsubset)]
803	Notprsubset(T![Ident]),
804	#[atom(CssAtomSet::Notsubset)]
805	Notsubset(T![Ident]),
806	#[atom(CssAtomSet::Or)]
807	Or(T![Ident]),
808	#[atom(CssAtomSet::Otherwise)]
809	Otherwise(T![Ident]),
810	#[atom(CssAtomSet::Outerproduct)]
811	Outerproduct(T![Ident]),
812	#[atom(CssAtomSet::Partialdiff)]
813	Partialdiff(T![Ident]),
814	#[atom(CssAtomSet::Piece)]
815	Piece(T![Ident]),
816	#[atom(CssAtomSet::Piecewise)]
817	Piecewise(T![Ident]),
818	#[atom(CssAtomSet::Plus)]
819	Plus(T![Ident]),
820	#[atom(CssAtomSet::Power)]
821	Power(T![Ident]),
822	#[atom(CssAtomSet::Product)]
823	Product(T![Ident]),
824	#[atom(CssAtomSet::Prsubset)]
825	Prsubset(T![Ident]),
826	#[atom(CssAtomSet::Quotient)]
827	Quotient(T![Ident]),
828	#[atom(CssAtomSet::Real)]
829	Real(T![Ident]),
830	#[atom(CssAtomSet::Reln)]
831	Reln(T![Ident]),
832	#[atom(CssAtomSet::Rem)]
833	Rem(T![Ident]),
834	#[atom(CssAtomSet::Root)]
835	Root(T![Ident]),
836	#[atom(CssAtomSet::Scalarproduct)]
837	Scalarproduct(T![Ident]),
838	#[atom(CssAtomSet::Sdev)]
839	Sdev(T![Ident]),
840	#[atom(CssAtomSet::Selector)]
841	Selector(T![Ident]),
842	#[atom(CssAtomSet::Semantics)]
843	Semantics(T![Ident]),
844	#[atom(CssAtomSet::Sep)]
845	Sep(T![Ident]),
846	#[atom(CssAtomSet::Set)]
847	Set(T![Ident]),
848	#[atom(CssAtomSet::Setdiff)]
849	Setdiff(T![Ident]),
850	#[atom(CssAtomSet::Share)]
851	Share(T![Ident]),
852	#[atom(CssAtomSet::Sin)]
853	Sin(T![Ident]),
854	#[atom(CssAtomSet::Subset)]
855	Subset(T![Ident]),
856	#[atom(CssAtomSet::Sum)]
857	Sum(T![Ident]),
858	#[atom(CssAtomSet::Tendsto)]
859	Tendsto(T![Ident]),
860	#[atom(CssAtomSet::Times)]
861	Times(T![Ident]),
862	#[atom(CssAtomSet::Transpose)]
863	Transpose(T![Ident]),
864	#[atom(CssAtomSet::Union)]
865	Union(T![Ident]),
866	#[atom(CssAtomSet::Uplimit)]
867	Uplimit(T![Ident]),
868	#[atom(CssAtomSet::Variance)]
869	Variance(T![Ident]),
870	#[atom(CssAtomSet::Vector)]
871	Vector(T![Ident]),
872	#[atom(CssAtomSet::Vectorproduct)]
873	Vectorproduct(T![Ident]),
874	#[atom(CssAtomSet::Xo)]
875	Xo(T![Ident]),
876}
877
878#[derive(ToCursors, Parse, IntoCursor, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
879#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
880#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
881pub struct UnknownTag(T![Ident]);
882
883impl<'a> Peek<'a> for UnknownTag {
884	fn peek<I>(p: &Parser<'a, I>, c: Cursor) -> bool
885	where
886		I: Iterator<Item = Cursor> + Clone,
887	{
888		<T![Ident]>::peek(p, c)
889	}
890}
891
892#[cfg(test)]
893mod tests {
894	use super::*;
895	use crate::CssAtomSet;
896	use css_parse::assert_parse;
897
898	#[test]
899	fn size_test() {
900		assert_eq!(std::mem::size_of::<Tag>(), 20);
901		assert_eq!(std::mem::size_of::<HtmlTag>(), 16);
902		assert_eq!(std::mem::size_of::<SvgTag>(), 16);
903		assert_eq!(std::mem::size_of::<MathmlTag>(), 16);
904		assert_eq!(std::mem::size_of::<CustomElementTag>(), 12);
905		assert_eq!(std::mem::size_of::<HtmlNonConformingTag>(), 16);
906		assert_eq!(std::mem::size_of::<HtmlNonStandardTag>(), 16);
907	}
908
909	#[test]
910	fn test_writes() {
911		assert_parse!(CssAtomSet::ATOMS, Tag, "div");
912	}
913}