Skip to main content

css_ast/selector/
tag.rs

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