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