Skip to main content

css_ast/selector/
tag.rs

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