Markdown parser fork with extended syntax for personal use.
at main 2345 lines 78 kB view raw
1//! markdown syntax tree: [mdast][]. 2//! 3//! [mdast]: https://github.com/syntax-tree/mdast 4 5use crate::unist::Position; 6use alloc::{ 7 fmt, 8 string::{String, ToString}, 9 vec::Vec, 10}; 11 12/// MDX: relative byte index into a string, to an absolute byte index into the 13/// whole document. 14pub type Stop = (usize, usize); 15 16/// Explicitness of a reference. 17#[derive(Clone, Copy, Debug, Eq, PartialEq)] 18#[cfg_attr( 19 feature = "serde", 20 derive(serde::Serialize, serde::Deserialize), 21 serde(rename_all = "lowercase") 22)] 23pub enum ReferenceKind { 24 /// The reference is implicit, its identifier inferred from its content. 25 Shortcut, 26 /// The reference is explicit, its identifier inferred from its content. 27 Collapsed, 28 /// The reference is explicit, its identifier explicitly set. 29 Full, 30} 31 32/// GFM: alignment of phrasing content. 33/// 34/// Used to align the contents of table cells within a table. 35#[derive(Clone, Copy, Debug, Eq, PartialEq)] 36pub enum AlignKind { 37 /// Left alignment. 38 /// 39 /// See the `left` value of the `text-align` CSS property. 40 /// 41 /// ```markdown 42 /// | | aaa | 43 /// > | | :-- | 44 /// ^^^ 45 /// ``` 46 Left, 47 /// Right alignment. 48 /// 49 /// See the `right` value of the `text-align` CSS property. 50 /// 51 /// ```markdown 52 /// | | aaa | 53 /// > | | --: | 54 /// ^^^ 55 /// ``` 56 Right, 57 /// Center alignment. 58 /// 59 /// See the `center` value of the `text-align` CSS property. 60 /// 61 /// ```markdown 62 /// | | aaa | 63 /// > | | :-: | 64 /// ^^^ 65 /// ``` 66 Center, 67 /// No alignment. 68 /// 69 /// Phrasing content is aligned as defined by the host environment. 70 /// 71 /// ```markdown 72 /// | | aaa | 73 /// > | | --- | 74 /// ^^^ 75 /// ``` 76 None, 77} 78 79/// Implement serde according to <https://github.com/syntax-tree/mdast#aligntype> 80#[cfg(feature = "serde")] 81impl serde::ser::Serialize for AlignKind { 82 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 83 where 84 S: serde::ser::Serializer, 85 { 86 match self { 87 AlignKind::Left => serializer.serialize_unit_variant("AlignKind", 0, "left"), 88 AlignKind::Right => serializer.serialize_unit_variant("AlignKind", 1, "right"), 89 AlignKind::Center => serializer.serialize_unit_variant("AlignKind", 2, "center"), 90 AlignKind::None => serializer.serialize_none(), 91 } 92 } 93} 94 95#[cfg(feature = "serde")] 96struct AlignKindVisitor; 97 98#[cfg(feature = "serde")] 99impl serde::de::Visitor<'_> for AlignKindVisitor { 100 type Value = AlignKind; 101 102 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 103 formatter.write_str("'left', 'right', 'center' or null") 104 } 105 106 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> 107 where 108 E: serde::de::Error, 109 { 110 match v { 111 "left" => Ok(AlignKind::Left), 112 "right" => Ok(AlignKind::Right), 113 "center" => Ok(AlignKind::Center), 114 &_ => Err(serde::de::Error::invalid_type( 115 serde::de::Unexpected::Str(v), 116 &self, 117 )), 118 } 119 } 120 121 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> 122 where 123 E: serde::de::Error, 124 { 125 match v { 126 b"left" => Ok(AlignKind::Left), 127 b"right" => Ok(AlignKind::Right), 128 b"center" => Ok(AlignKind::Center), 129 &_ => Err(serde::de::Error::invalid_type( 130 serde::de::Unexpected::Bytes(v), 131 &self, 132 )), 133 } 134 } 135 136 fn visit_none<E>(self) -> Result<Self::Value, E> 137 where 138 E: serde::de::Error, 139 { 140 Ok(AlignKind::None) 141 } 142 143 fn visit_unit<E>(self) -> Result<Self::Value, E> 144 where 145 E: serde::de::Error, 146 { 147 Ok(AlignKind::None) 148 } 149} 150 151#[cfg(feature = "serde")] 152impl<'de> serde::de::Deserialize<'de> for AlignKind { 153 fn deserialize<D>(deserializer: D) -> Result<AlignKind, D::Error> 154 where 155 D: serde::de::Deserializer<'de>, 156 { 157 deserializer.deserialize_any(AlignKindVisitor) 158 } 159} 160 161/// Nodes. 162#[derive(Clone, Eq, PartialEq)] 163#[cfg_attr( 164 feature = "serde", 165 derive(serde::Serialize, serde::Deserialize), 166 serde(tag = "type", rename_all = "camelCase") 167)] 168pub enum Node { 169 // Document: 170 /// Root. 171 Root(Root), 172 173 // Container: 174 /// Block quote. 175 Blockquote(Blockquote), 176 /// Footnote definition. 177 FootnoteDefinition(FootnoteDefinition), 178 /// MDX: JSX element (container). 179 MdxJsxFlowElement(MdxJsxFlowElement), 180 /// List. 181 List(List), 182 183 // Frontmatter: 184 /// MDX.js ESM. 185 MdxjsEsm(MdxjsEsm), 186 /// Toml. 187 Toml(Toml), 188 /// Yaml. 189 Yaml(Yaml), 190 191 // Phrasing: 192 /// Break. 193 Break(Break), 194 /// Code (phrasing). 195 InlineCode(InlineCode), 196 /// Math (phrasing). 197 InlineMath(InlineMath), 198 /// Delete. 199 Delete(Delete), 200 /// Emphasis. 201 Emphasis(Emphasis), 202 // MDX: expression (text). 203 MdxTextExpression(MdxTextExpression), 204 /// Footnote reference. 205 FootnoteReference(FootnoteReference), 206 /// Html (phrasing). 207 Html(Html), 208 /// Image. 209 Image(Image), 210 /// Image reference. 211 ImageReference(ImageReference), 212 // MDX: JSX element (text). 213 MdxJsxTextElement(MdxJsxTextElement), 214 /// Link. 215 Link(Link), 216 /// Link reference. 217 LinkReference(LinkReference), 218 /// Strong 219 Strong(Strong), 220 /// Text. 221 Text(Text), 222 223 // Flow: 224 /// Code (flow). 225 Code(Code), 226 /// Math (flow). 227 Math(Math), 228 // MDX: expression (flow). 229 MdxFlowExpression(MdxFlowExpression), 230 /// Heading. 231 Heading(Heading), 232 /// Html (flow). 233 // Html(Html), 234 /// Table. 235 Table(Table), 236 /// Thematic break. 237 ThematicBreak(ThematicBreak), 238 239 // Table content. 240 /// Table row. 241 TableRow(TableRow), 242 243 // Row content. 244 /// Table cell. 245 TableCell(TableCell), 246 247 // List content. 248 /// List item. 249 ListItem(ListItem), 250 251 // Content. 252 /// Definition. 253 Definition(Definition), 254 /// Paragraph. 255 Paragraph(Paragraph), 256} 257 258impl fmt::Debug for Node { 259 // Debug the wrapped struct. 260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 261 match self { 262 Node::Root(x) => x.fmt(f), 263 Node::Blockquote(x) => x.fmt(f), 264 Node::FootnoteDefinition(x) => x.fmt(f), 265 Node::MdxJsxFlowElement(x) => x.fmt(f), 266 Node::List(x) => x.fmt(f), 267 Node::MdxjsEsm(x) => x.fmt(f), 268 Node::Toml(x) => x.fmt(f), 269 Node::Yaml(x) => x.fmt(f), 270 Node::Break(x) => x.fmt(f), 271 Node::InlineCode(x) => x.fmt(f), 272 Node::InlineMath(x) => x.fmt(f), 273 Node::Delete(x) => x.fmt(f), 274 Node::Emphasis(x) => x.fmt(f), 275 Node::MdxTextExpression(x) => x.fmt(f), 276 Node::FootnoteReference(x) => x.fmt(f), 277 Node::Html(x) => x.fmt(f), 278 Node::Image(x) => x.fmt(f), 279 Node::ImageReference(x) => x.fmt(f), 280 Node::MdxJsxTextElement(x) => x.fmt(f), 281 Node::Link(x) => x.fmt(f), 282 Node::LinkReference(x) => x.fmt(f), 283 Node::Strong(x) => x.fmt(f), 284 Node::Text(x) => x.fmt(f), 285 Node::Code(x) => x.fmt(f), 286 Node::Math(x) => x.fmt(f), 287 Node::MdxFlowExpression(x) => x.fmt(f), 288 Node::Heading(x) => x.fmt(f), 289 Node::Table(x) => x.fmt(f), 290 Node::ThematicBreak(x) => x.fmt(f), 291 Node::TableRow(x) => x.fmt(f), 292 Node::TableCell(x) => x.fmt(f), 293 Node::ListItem(x) => x.fmt(f), 294 Node::Definition(x) => x.fmt(f), 295 Node::Paragraph(x) => x.fmt(f), 296 } 297 } 298} 299 300fn children_to_string(children: &[Node]) -> String { 301 children.iter().map(ToString::to_string).collect() 302} 303 304// To do: clippy may be right but that’s a breaking change. 305#[allow(clippy::to_string_trait_impl)] 306impl ToString for Node { 307 fn to_string(&self) -> String { 308 match self { 309 // Parents. 310 Node::Root(x) => children_to_string(&x.children), 311 Node::Blockquote(x) => children_to_string(&x.children), 312 Node::FootnoteDefinition(x) => children_to_string(&x.children), 313 Node::MdxJsxFlowElement(x) => children_to_string(&x.children), 314 Node::List(x) => children_to_string(&x.children), 315 Node::Delete(x) => children_to_string(&x.children), 316 Node::Emphasis(x) => children_to_string(&x.children), 317 Node::MdxJsxTextElement(x) => children_to_string(&x.children), 318 Node::Link(x) => children_to_string(&x.children), 319 Node::LinkReference(x) => children_to_string(&x.children), 320 Node::Strong(x) => children_to_string(&x.children), 321 Node::Heading(x) => children_to_string(&x.children), 322 Node::Table(x) => children_to_string(&x.children), 323 Node::TableRow(x) => children_to_string(&x.children), 324 Node::TableCell(x) => children_to_string(&x.children), 325 Node::ListItem(x) => children_to_string(&x.children), 326 Node::Paragraph(x) => children_to_string(&x.children), 327 328 // Literals. 329 Node::MdxjsEsm(x) => x.value.clone(), 330 Node::Toml(x) => x.value.clone(), 331 Node::Yaml(x) => x.value.clone(), 332 Node::InlineCode(x) => x.value.clone(), 333 Node::InlineMath(x) => x.value.clone(), 334 Node::MdxTextExpression(x) => x.value.clone(), 335 Node::Html(x) => x.value.clone(), 336 Node::Text(x) => x.value.clone(), 337 Node::Code(x) => x.value.clone(), 338 Node::Math(x) => x.value.clone(), 339 Node::MdxFlowExpression(x) => x.value.clone(), 340 341 // Voids. 342 Node::Break(_) 343 | Node::FootnoteReference(_) 344 | Node::Image(_) 345 | Node::ImageReference(_) 346 | Node::ThematicBreak(_) 347 | Node::Definition(_) => String::new(), 348 } 349 } 350} 351 352impl Node { 353 #[must_use] 354 pub fn children(&self) -> Option<&Vec<Node>> { 355 match self { 356 // Parent. 357 Node::Root(x) => Some(&x.children), 358 Node::Paragraph(x) => Some(&x.children), 359 Node::Heading(x) => Some(&x.children), 360 Node::Blockquote(x) => Some(&x.children), 361 Node::List(x) => Some(&x.children), 362 Node::ListItem(x) => Some(&x.children), 363 Node::Emphasis(x) => Some(&x.children), 364 Node::Strong(x) => Some(&x.children), 365 Node::Link(x) => Some(&x.children), 366 Node::LinkReference(x) => Some(&x.children), 367 Node::FootnoteDefinition(x) => Some(&x.children), 368 Node::Table(x) => Some(&x.children), 369 Node::TableRow(x) => Some(&x.children), 370 Node::TableCell(x) => Some(&x.children), 371 Node::Delete(x) => Some(&x.children), 372 Node::MdxJsxFlowElement(x) => Some(&x.children), 373 Node::MdxJsxTextElement(x) => Some(&x.children), 374 // Non-parent. 375 _ => None, 376 } 377 } 378 379 pub fn children_mut(&mut self) -> Option<&mut Vec<Node>> { 380 match self { 381 // Parent. 382 Node::Root(x) => Some(&mut x.children), 383 Node::Paragraph(x) => Some(&mut x.children), 384 Node::Heading(x) => Some(&mut x.children), 385 Node::Blockquote(x) => Some(&mut x.children), 386 Node::List(x) => Some(&mut x.children), 387 Node::ListItem(x) => Some(&mut x.children), 388 Node::Emphasis(x) => Some(&mut x.children), 389 Node::Strong(x) => Some(&mut x.children), 390 Node::Link(x) => Some(&mut x.children), 391 Node::LinkReference(x) => Some(&mut x.children), 392 Node::FootnoteDefinition(x) => Some(&mut x.children), 393 Node::Table(x) => Some(&mut x.children), 394 Node::TableRow(x) => Some(&mut x.children), 395 Node::TableCell(x) => Some(&mut x.children), 396 Node::Delete(x) => Some(&mut x.children), 397 Node::MdxJsxFlowElement(x) => Some(&mut x.children), 398 Node::MdxJsxTextElement(x) => Some(&mut x.children), 399 // Non-parent. 400 _ => None, 401 } 402 } 403 404 #[must_use] 405 pub fn position(&self) -> Option<&Position> { 406 match self { 407 Node::Root(x) => x.position.as_ref(), 408 Node::Blockquote(x) => x.position.as_ref(), 409 Node::FootnoteDefinition(x) => x.position.as_ref(), 410 Node::MdxJsxFlowElement(x) => x.position.as_ref(), 411 Node::List(x) => x.position.as_ref(), 412 Node::MdxjsEsm(x) => x.position.as_ref(), 413 Node::Toml(x) => x.position.as_ref(), 414 Node::Yaml(x) => x.position.as_ref(), 415 Node::Break(x) => x.position.as_ref(), 416 Node::InlineCode(x) => x.position.as_ref(), 417 Node::InlineMath(x) => x.position.as_ref(), 418 Node::Delete(x) => x.position.as_ref(), 419 Node::Emphasis(x) => x.position.as_ref(), 420 Node::MdxTextExpression(x) => x.position.as_ref(), 421 Node::FootnoteReference(x) => x.position.as_ref(), 422 Node::Html(x) => x.position.as_ref(), 423 Node::Image(x) => x.position.as_ref(), 424 Node::ImageReference(x) => x.position.as_ref(), 425 Node::MdxJsxTextElement(x) => x.position.as_ref(), 426 Node::Link(x) => x.position.as_ref(), 427 Node::LinkReference(x) => x.position.as_ref(), 428 Node::Strong(x) => x.position.as_ref(), 429 Node::Text(x) => x.position.as_ref(), 430 Node::Code(x) => x.position.as_ref(), 431 Node::Math(x) => x.position.as_ref(), 432 Node::MdxFlowExpression(x) => x.position.as_ref(), 433 Node::Heading(x) => x.position.as_ref(), 434 Node::Table(x) => x.position.as_ref(), 435 Node::ThematicBreak(x) => x.position.as_ref(), 436 Node::TableRow(x) => x.position.as_ref(), 437 Node::TableCell(x) => x.position.as_ref(), 438 Node::ListItem(x) => x.position.as_ref(), 439 Node::Definition(x) => x.position.as_ref(), 440 Node::Paragraph(x) => x.position.as_ref(), 441 } 442 } 443 444 pub fn position_mut(&mut self) -> Option<&mut Position> { 445 match self { 446 Node::Root(x) => x.position.as_mut(), 447 Node::Blockquote(x) => x.position.as_mut(), 448 Node::FootnoteDefinition(x) => x.position.as_mut(), 449 Node::MdxJsxFlowElement(x) => x.position.as_mut(), 450 Node::List(x) => x.position.as_mut(), 451 Node::MdxjsEsm(x) => x.position.as_mut(), 452 Node::Toml(x) => x.position.as_mut(), 453 Node::Yaml(x) => x.position.as_mut(), 454 Node::Break(x) => x.position.as_mut(), 455 Node::InlineCode(x) => x.position.as_mut(), 456 Node::InlineMath(x) => x.position.as_mut(), 457 Node::Delete(x) => x.position.as_mut(), 458 Node::Emphasis(x) => x.position.as_mut(), 459 Node::MdxTextExpression(x) => x.position.as_mut(), 460 Node::FootnoteReference(x) => x.position.as_mut(), 461 Node::Html(x) => x.position.as_mut(), 462 Node::Image(x) => x.position.as_mut(), 463 Node::ImageReference(x) => x.position.as_mut(), 464 Node::MdxJsxTextElement(x) => x.position.as_mut(), 465 Node::Link(x) => x.position.as_mut(), 466 Node::LinkReference(x) => x.position.as_mut(), 467 Node::Strong(x) => x.position.as_mut(), 468 Node::Text(x) => x.position.as_mut(), 469 Node::Code(x) => x.position.as_mut(), 470 Node::Math(x) => x.position.as_mut(), 471 Node::MdxFlowExpression(x) => x.position.as_mut(), 472 Node::Heading(x) => x.position.as_mut(), 473 Node::Table(x) => x.position.as_mut(), 474 Node::ThematicBreak(x) => x.position.as_mut(), 475 Node::TableRow(x) => x.position.as_mut(), 476 Node::TableCell(x) => x.position.as_mut(), 477 Node::ListItem(x) => x.position.as_mut(), 478 Node::Definition(x) => x.position.as_mut(), 479 Node::Paragraph(x) => x.position.as_mut(), 480 } 481 } 482 483 pub fn position_set(&mut self, position: Option<Position>) { 484 match self { 485 Node::Root(x) => x.position = position, 486 Node::Blockquote(x) => x.position = position, 487 Node::FootnoteDefinition(x) => x.position = position, 488 Node::MdxJsxFlowElement(x) => x.position = position, 489 Node::List(x) => x.position = position, 490 Node::MdxjsEsm(x) => x.position = position, 491 Node::Toml(x) => x.position = position, 492 Node::Yaml(x) => x.position = position, 493 Node::Break(x) => x.position = position, 494 Node::InlineCode(x) => x.position = position, 495 Node::InlineMath(x) => x.position = position, 496 Node::Delete(x) => x.position = position, 497 Node::Emphasis(x) => x.position = position, 498 Node::MdxTextExpression(x) => x.position = position, 499 Node::FootnoteReference(x) => x.position = position, 500 Node::Html(x) => x.position = position, 501 Node::Image(x) => x.position = position, 502 Node::ImageReference(x) => x.position = position, 503 Node::MdxJsxTextElement(x) => x.position = position, 504 Node::Link(x) => x.position = position, 505 Node::LinkReference(x) => x.position = position, 506 Node::Strong(x) => x.position = position, 507 Node::Text(x) => x.position = position, 508 Node::Code(x) => x.position = position, 509 Node::Math(x) => x.position = position, 510 Node::MdxFlowExpression(x) => x.position = position, 511 Node::Heading(x) => x.position = position, 512 Node::Table(x) => x.position = position, 513 Node::ThematicBreak(x) => x.position = position, 514 Node::TableRow(x) => x.position = position, 515 Node::TableCell(x) => x.position = position, 516 Node::ListItem(x) => x.position = position, 517 Node::Definition(x) => x.position = position, 518 Node::Paragraph(x) => x.position = position, 519 } 520 } 521} 522 523/// MDX: attribute content. 524#[derive(Clone, Debug, Eq, PartialEq)] 525#[cfg_attr( 526 feature = "serde", 527 derive(serde::Serialize, serde::Deserialize), 528 serde(untagged) 529)] 530pub enum AttributeContent { 531 /// JSX expression. 532 /// 533 /// ```markdown 534 /// > | <a {...b} /> 535 /// ^^^^^^ 536 /// ``` 537 Expression(MdxJsxExpressionAttribute), 538 /// JSX property. 539 /// 540 /// ```markdown 541 /// > | <a b /> 542 /// ^ 543 /// ``` 544 Property(MdxJsxAttribute), 545} 546// 547#[derive(Clone, Debug, Eq, PartialEq)] 548#[cfg_attr( 549 feature = "serde", 550 derive(serde::Serialize, serde::Deserialize), 551 serde(tag = "type", rename = "mdxJsxAttributeValueExpression") 552)] 553pub struct AttributeValueExpression { 554 pub value: String, 555 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))] 556 pub stops: Vec<Stop>, 557} 558 559/// MDX: attribute value. 560#[derive(Clone, Debug, Eq, PartialEq)] 561#[cfg_attr( 562 feature = "serde", 563 derive(serde::Serialize, serde::Deserialize), 564 serde(untagged) 565)] 566pub enum AttributeValue { 567 /// Expression value. 568 /// 569 /// ```markdown 570 /// > | <a b={c} /> 571 /// ^^^ 572 /// ``` 573 Expression(AttributeValueExpression), 574 /// Static value. 575 /// 576 /// ```markdown 577 /// > | <a b="c" /> 578 /// ^^^ 579 /// ``` 580 Literal(String), 581} 582 583/// Document. 584/// 585/// ```markdown 586/// > | a 587/// ^ 588/// ``` 589#[derive(Clone, Debug, Eq, PartialEq)] 590#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 591pub struct Root { 592 // Parent. 593 /// Content model. 594 pub children: Vec<Node>, 595 /// Positional info. 596 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 597 pub position: Option<Position>, 598} 599 600/// Paragraph. 601/// 602/// ```markdown 603/// > | a 604/// ^ 605/// ``` 606#[derive(Clone, Debug, Eq, PartialEq)] 607#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 608pub struct Paragraph { 609 // Parent. 610 /// Content model. 611 pub children: Vec<Node>, 612 /// Positional info. 613 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 614 pub position: Option<Position>, 615} 616 617/// Heading. 618/// 619/// ```markdown 620/// > | # a 621/// ^^^ 622/// ``` 623#[derive(Clone, Debug, Eq, PartialEq)] 624#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 625pub struct Heading { 626 // Parent. 627 /// Content model. 628 pub children: Vec<Node>, 629 /// Positional info. 630 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 631 pub position: Option<Position>, 632 // Extra. 633 /// Rank (between `1` and `6`, both including). 634 pub depth: u8, 635} 636 637/// Thematic break. 638/// 639/// ```markdown 640/// > | *** 641/// ^^^ 642/// ``` 643#[derive(Clone, Debug, Eq, PartialEq)] 644#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 645pub struct ThematicBreak { 646 // Void. 647 /// Positional info. 648 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 649 pub position: Option<Position>, 650} 651 652/// Block quote. 653/// 654/// ```markdown 655/// > | > a 656/// ^^^ 657/// ``` 658#[derive(Clone, Debug, Eq, PartialEq)] 659#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 660pub struct Blockquote { 661 // Parent. 662 /// Content model. 663 pub children: Vec<Node>, 664 /// Positional info. 665 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 666 pub position: Option<Position>, 667} 668 669/// List. 670/// 671/// ```markdown 672/// > | * a 673/// ^^^ 674/// ``` 675#[derive(Clone, Debug, Eq, PartialEq)] 676#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 677pub struct List { 678 // Parent. 679 /// Content model. 680 pub children: Vec<Node>, 681 /// Positional info. 682 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 683 pub position: Option<Position>, 684 // Extra. 685 /// Ordered (`true`) or unordered (`false`). 686 pub ordered: bool, 687 /// Starting number of the list. 688 /// `None` when unordered. 689 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 690 pub start: Option<u32>, 691 /// One or more of its children are separated with a blank line from its 692 /// siblings (when `true`), or not (when `false`). 693 pub spread: bool, 694} 695 696/// List item. 697/// 698/// ```markdown 699/// > | * a 700/// ^^^ 701/// ``` 702#[derive(Clone, Debug, Eq, PartialEq)] 703#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 704pub struct ListItem { 705 // Parent. 706 /// Content model. 707 pub children: Vec<Node>, 708 /// Positional info. 709 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 710 pub position: Option<Position>, 711 // Extra. 712 /// The item contains two or more children separated by a blank line 713 /// (when `true`), or not (when `false`). 714 pub spread: bool, 715 /// GFM: whether the item is done (when `true`), not done (when `false`), 716 /// or indeterminate or not applicable (`None`). 717 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 718 pub checked: Option<bool>, 719} 720 721/// Html (flow or phrasing). 722/// 723/// ```markdown 724/// > | <a> 725/// ^^^ 726/// ``` 727#[derive(Clone, Debug, Eq, PartialEq)] 728#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 729pub struct Html { 730 // Text. 731 /// Content model. 732 pub value: String, 733 /// Positional info. 734 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 735 pub position: Option<Position>, 736} 737 738/// Code (flow). 739/// 740/// ```markdown 741/// > | ~~~ 742/// ^^^ 743/// > | a 744/// ^ 745/// > | ~~~ 746/// ^^^ 747/// ``` 748#[derive(Clone, Debug, Eq, PartialEq)] 749#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 750pub struct Code { 751 // Text. 752 /// Content model. 753 pub value: String, 754 /// Positional info. 755 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 756 pub position: Option<Position>, 757 // Extra. 758 /// The language of computer code being marked up. 759 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 760 pub lang: Option<String>, 761 /// Custom info relating to the node. 762 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 763 pub meta: Option<String>, 764} 765 766/// Math (flow). 767/// 768/// ```markdown 769/// > | $$ 770/// ^^ 771/// > | a 772/// ^ 773/// > | $$ 774/// ^^ 775/// ``` 776#[derive(Clone, Debug, Eq, PartialEq)] 777#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 778pub struct Math { 779 // Text. 780 /// Content model. 781 pub value: String, 782 /// Positional info. 783 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 784 pub position: Option<Position>, 785 // Extra. 786 /// Custom info relating to the node. 787 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 788 pub meta: Option<String>, 789} 790 791/// Definition. 792/// 793/// ```markdown 794/// > | [a]: b 795/// ^^^^^^ 796/// ``` 797#[derive(Clone, Debug, Eq, PartialEq)] 798#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 799pub struct Definition { 800 // Void. 801 /// Positional info. 802 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 803 pub position: Option<Position>, 804 // Resource. 805 /// URL to the referenced resource. 806 pub url: String, 807 /// Advisory info for the resource, such as something that would be 808 /// appropriate for a tooltip. 809 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 810 pub title: Option<String>, 811 // Association. 812 /// Value that can match another node. 813 /// `identifier` is a source value: character escapes and character references 814 /// are *not* parsed. 815 /// Its value must be normalized. 816 pub identifier: String, 817 /// `label` is a string value: it works just like `title` on a link or a 818 /// `lang` on code: character escapes and character references are parsed. 819 /// 820 /// To normalize a value, collapse markdown whitespace (`[\t\n\r ]+`) to a 821 /// space, trim the optional initial and/or final space, and perform 822 /// case-folding. 823 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 824 pub label: Option<String>, 825} 826 827/// Text. 828/// 829/// ```markdown 830/// > | a 831/// ^ 832/// ``` 833#[derive(Clone, Debug, Eq, PartialEq)] 834#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 835pub struct Text { 836 // Text. 837 /// Content model. 838 pub value: String, 839 /// Positional info. 840 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 841 pub position: Option<Position>, 842} 843 844/// Emphasis. 845/// 846/// ```markdown 847/// > | *a* 848/// ^^^ 849/// ``` 850#[derive(Clone, Debug, Eq, PartialEq)] 851#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 852pub struct Emphasis { 853 // Parent. 854 /// Content model. 855 pub children: Vec<Node>, 856 /// Positional info. 857 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 858 pub position: Option<Position>, 859} 860 861/// Strong. 862/// 863/// ```markdown 864/// > | **a** 865/// ^^^^^ 866/// ``` 867#[derive(Clone, Debug, Eq, PartialEq)] 868#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 869pub struct Strong { 870 // Parent. 871 /// Content model. 872 pub children: Vec<Node>, 873 /// Positional info. 874 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 875 pub position: Option<Position>, 876} 877 878/// Code (phrasing). 879/// 880/// ```markdown 881/// > | `a` 882/// ^^^ 883/// ``` 884#[derive(Clone, Debug, Eq, PartialEq)] 885#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 886pub struct InlineCode { 887 // Text. 888 /// Content model. 889 pub value: String, 890 /// Positional info. 891 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 892 pub position: Option<Position>, 893} 894 895/// Math (phrasing). 896/// 897/// ```markdown 898/// > | $a$ 899/// ^^^ 900/// ``` 901#[derive(Clone, Debug, Eq, PartialEq)] 902#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 903pub struct InlineMath { 904 // Text. 905 /// Content model. 906 pub value: String, 907 /// Positional info. 908 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 909 pub position: Option<Position>, 910} 911 912/// Break. 913/// 914/// ```markdown 915/// > | a\ 916/// ^ 917/// | b 918/// ``` 919#[derive(Clone, Debug, Eq, PartialEq)] 920#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 921pub struct Break { 922 // Void. 923 /// Positional info. 924 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 925 pub position: Option<Position>, 926} 927 928/// Link. 929/// 930/// ```markdown 931/// > | [a](b) 932/// ^^^^^^ 933/// ``` 934#[derive(Clone, Debug, Eq, PartialEq)] 935#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 936pub struct Link { 937 // Parent. 938 /// Content model. 939 pub children: Vec<Node>, 940 /// Positional info. 941 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 942 pub position: Option<Position>, 943 // Resource. 944 /// URL to the referenced resource. 945 pub url: String, 946 /// Advisory info for the resource, such as something that would be 947 /// appropriate for a tooltip. 948 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 949 pub title: Option<String>, 950} 951 952/// Image. 953/// 954/// ```markdown 955/// > | ![a](b) 956/// ^^^^^^^ 957/// ``` 958#[derive(Clone, Debug, Eq, PartialEq)] 959#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 960pub struct Image { 961 // Void. 962 /// Positional info. 963 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 964 pub position: Option<Position>, 965 // Alternative. 966 /// Equivalent content for environments that cannot represent the node as 967 /// intended. 968 pub alt: String, 969 // Resource. 970 /// URL to the referenced resource. 971 pub url: String, 972 /// Advisory info for the resource, such as something that would be 973 /// appropriate for a tooltip. 974 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 975 pub title: Option<String>, 976} 977 978/// Link reference. 979/// 980/// ```markdown 981/// > | [a] 982/// ^^^ 983/// ``` 984#[derive(Clone, Debug, Eq, PartialEq)] 985#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 986pub struct LinkReference { 987 // Parent. 988 /// Content model. 989 pub children: Vec<Node>, 990 /// Positional info. 991 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 992 pub position: Option<Position>, 993 // Reference. 994 /// Explicitness of a reference. 995 #[cfg_attr(feature = "serde", serde(rename = "referenceType"))] 996 pub reference_kind: ReferenceKind, 997 // Association. 998 /// Value that can match another node. 999 /// `identifier` is a source value: character escapes and character references 1000 /// are *not* parsed. 1001 /// Its value must be normalized. 1002 pub identifier: String, 1003 /// `label` is a string value: it works just like `title` on a link or a 1004 /// `lang` on code: character escapes and character references are parsed. 1005 /// 1006 /// To normalize a value, collapse markdown whitespace (`[\t\n\r ]+`) to a 1007 /// space, trim the optional initial and/or final space, and perform 1008 /// case-folding. 1009 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1010 pub label: Option<String>, 1011} 1012 1013/// Image reference. 1014/// 1015/// ```markdown 1016/// > | ![a] 1017/// ^^^^ 1018/// ``` 1019#[derive(Clone, Debug, Eq, PartialEq)] 1020#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1021pub struct ImageReference { 1022 // Void. 1023 /// Positional info. 1024 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1025 pub position: Option<Position>, 1026 // Alternative. 1027 /// Equivalent content for environments that cannot represent the node as 1028 /// intended. 1029 pub alt: String, 1030 // Reference. 1031 /// Explicitness of a reference. 1032 #[cfg_attr(feature = "serde", serde(rename = "referenceType"))] 1033 pub reference_kind: ReferenceKind, 1034 // Association. 1035 /// Value that can match another node. 1036 /// `identifier` is a source value: character escapes and character references 1037 /// are *not* parsed. 1038 /// Its value must be normalized. 1039 pub identifier: String, 1040 /// `label` is a string value: it works just like `title` on a link or a 1041 /// `lang` on code: character escapes and character references are parsed. 1042 /// 1043 /// To normalize a value, collapse markdown whitespace (`[\t\n\r ]+`) to a 1044 /// space, trim the optional initial and/or final space, and perform 1045 /// case-folding. 1046 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1047 pub label: Option<String>, 1048} 1049 1050/// GFM: footnote definition. 1051/// 1052/// ```markdown 1053/// > | [^a]: b 1054/// ^^^^^^^ 1055/// ``` 1056#[derive(Clone, Debug, Eq, PartialEq)] 1057#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1058pub struct FootnoteDefinition { 1059 // Parent. 1060 /// Content model. 1061 pub children: Vec<Node>, 1062 /// Positional info. 1063 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1064 pub position: Option<Position>, 1065 // Association. 1066 /// Value that can match another node. 1067 /// `identifier` is a source value: character escapes and character references 1068 /// are *not* parsed. 1069 /// Its value must be normalized. 1070 pub identifier: String, 1071 /// `label` is a string value: it works just like `title` on a link or a 1072 /// `lang` on code: character escapes and character references are parsed. 1073 /// 1074 /// To normalize a value, collapse markdown whitespace (`[\t\n\r ]+`) to a 1075 /// space, trim the optional initial and/or final space, and perform 1076 /// case-folding. 1077 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1078 pub label: Option<String>, 1079} 1080 1081/// GFM: footnote reference. 1082/// 1083/// ```markdown 1084/// > | [^a] 1085/// ^^^^ 1086/// ``` 1087#[derive(Clone, Debug, Eq, PartialEq)] 1088#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1089pub struct FootnoteReference { 1090 // Void. 1091 /// Positional info. 1092 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1093 pub position: Option<Position>, 1094 // Association. 1095 /// Value that can match another node. 1096 /// `identifier` is a source value: character escapes and character references 1097 /// are *not* parsed. 1098 /// Its value must be normalized. 1099 pub identifier: String, 1100 /// `label` is a string value: it works just like `title` on a link or a 1101 /// `lang` on code: character escapes and character references are parsed. 1102 /// 1103 /// To normalize a value, collapse markdown whitespace (`[\t\n\r ]+`) to a 1104 /// space, trim the optional initial and/or final space, and perform 1105 /// case-folding. 1106 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1107 pub label: Option<String>, 1108} 1109 1110/// GFM: table. 1111/// 1112/// ```markdown 1113/// > | | a | 1114/// ^^^^^ 1115/// > | | - | 1116/// ^^^^^ 1117/// ``` 1118#[derive(Clone, Debug, Eq, PartialEq)] 1119#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1120pub struct Table { 1121 // Parent. 1122 /// Content model. 1123 pub children: Vec<Node>, 1124 /// Positional info. 1125 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1126 pub position: Option<Position>, 1127 // Extra. 1128 /// Represents how cells in columns are aligned. 1129 pub align: Vec<AlignKind>, 1130} 1131 1132/// GFM: table row. 1133/// 1134/// ```markdown 1135/// > | | a | 1136/// ^^^^^ 1137/// ``` 1138#[derive(Clone, Debug, Eq, PartialEq)] 1139#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1140pub struct TableRow { 1141 // Parent. 1142 /// Content model. 1143 pub children: Vec<Node>, 1144 /// Positional info. 1145 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1146 pub position: Option<Position>, 1147} 1148 1149/// GFM: table cell. 1150/// 1151/// ```markdown 1152/// > | | a | 1153/// ^^^^^ 1154/// ``` 1155#[derive(Clone, Debug, Eq, PartialEq)] 1156#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1157pub struct TableCell { 1158 // Parent. 1159 /// Content model. 1160 pub children: Vec<Node>, 1161 /// Positional info. 1162 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1163 pub position: Option<Position>, 1164} 1165 1166/// GFM: delete. 1167/// 1168/// ```markdown 1169/// > | ~~a~~ 1170/// ^^^^^ 1171/// ``` 1172#[derive(Clone, Debug, Eq, PartialEq)] 1173#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1174pub struct Delete { 1175 // Parent. 1176 /// Content model. 1177 pub children: Vec<Node>, 1178 /// Positional info. 1179 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1180 pub position: Option<Position>, 1181} 1182 1183/// Frontmatter: yaml. 1184/// 1185/// ```markdown 1186/// > | --- 1187/// ^^^ 1188/// > | a: b 1189/// ^^^^ 1190/// > | --- 1191/// ^^^ 1192/// ``` 1193#[derive(Clone, Debug, Eq, PartialEq)] 1194#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1195pub struct Yaml { 1196 // Void. 1197 /// Content model. 1198 pub value: String, 1199 /// Positional info. 1200 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1201 pub position: Option<Position>, 1202} 1203 1204/// Frontmatter: toml. 1205/// 1206/// ```markdown 1207/// > | +++ 1208/// ^^^ 1209/// > | a: b 1210/// ^^^^ 1211/// > | +++ 1212/// ^^^ 1213/// ``` 1214#[derive(Clone, Debug, Eq, PartialEq)] 1215#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1216pub struct Toml { 1217 // Void. 1218 /// Content model. 1219 pub value: String, 1220 /// Positional info. 1221 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1222 pub position: Option<Position>, 1223} 1224 1225/// MDX: ESM. 1226/// 1227/// ```markdown 1228/// > | import a from 'b' 1229/// ^^^^^^^^^^^^^^^^^ 1230/// ``` 1231#[derive(Clone, Debug, Eq, PartialEq)] 1232#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1233pub struct MdxjsEsm { 1234 // Literal. 1235 /// Content model. 1236 pub value: String, 1237 /// Positional info. 1238 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1239 pub position: Option<Position>, 1240 1241 // Custom data on where each slice of `value` came from. 1242 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))] 1243 pub stops: Vec<Stop>, 1244} 1245 1246/// MDX: expression (flow). 1247/// 1248/// ```markdown 1249/// > | {a} 1250/// ^^^ 1251/// ``` 1252#[derive(Clone, Debug, Eq, PartialEq)] 1253#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1254pub struct MdxFlowExpression { 1255 // Literal. 1256 /// Content model. 1257 pub value: String, 1258 /// Positional info. 1259 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1260 pub position: Option<Position>, 1261 1262 // Custom data on where each slice of `value` came from. 1263 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))] 1264 pub stops: Vec<Stop>, 1265} 1266 1267/// MDX: expression (text). 1268/// 1269/// ```markdown 1270/// > | a {b} 1271/// ^^^ 1272/// ``` 1273#[derive(Clone, Debug, Eq, PartialEq)] 1274#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 1275pub struct MdxTextExpression { 1276 // Literal. 1277 /// Content model. 1278 pub value: String, 1279 /// Positional info. 1280 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1281 pub position: Option<Position>, 1282 1283 // Custom data on where each slice of `value` came from. 1284 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))] 1285 pub stops: Vec<Stop>, 1286} 1287 1288/// MDX: JSX element (container). 1289/// 1290/// ```markdown 1291/// > | <a /> 1292/// ^^^^^ 1293/// ``` 1294#[derive(Clone, Debug, Eq, PartialEq)] 1295#[cfg_attr( 1296 feature = "serde", 1297 derive(serde::Serialize, serde::Deserialize), 1298 serde(rename_all = "camelCase") 1299)] 1300pub struct MdxJsxFlowElement { 1301 // Parent. 1302 /// Content model. 1303 pub children: Vec<Node>, 1304 /// Positional info. 1305 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1306 pub position: Option<Position>, 1307 // JSX element. 1308 /// Name. 1309 /// 1310 /// Fragments have no name. 1311 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1312 pub name: Option<String>, 1313 /// Attributes. 1314 pub attributes: Vec<AttributeContent>, 1315} 1316 1317/// MDX: JSX element (text). 1318/// 1319/// ```markdown 1320/// > | <a />. 1321/// ^^^^^ 1322/// ``` 1323#[derive(Clone, Debug, Eq, PartialEq)] 1324#[cfg_attr( 1325 feature = "serde", 1326 derive(serde::Serialize, serde::Deserialize), 1327 serde(rename_all = "camelCase") 1328)] 1329pub struct MdxJsxTextElement { 1330 // Parent. 1331 /// Content model. 1332 pub children: Vec<Node>, 1333 /// Positional info. 1334 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1335 pub position: Option<Position>, 1336 // JSX element. 1337 /// Name. 1338 /// 1339 /// Fragments have no name. 1340 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1341 pub name: Option<String>, 1342 /// Attributes. 1343 pub attributes: Vec<AttributeContent>, 1344} 1345 1346/// MDX: JSX attribute. 1347/// 1348/// ```markdown 1349/// > | <a b /> 1350/// ^ 1351/// ``` 1352#[derive(Clone, Debug, Eq, PartialEq)] 1353#[cfg_attr( 1354 feature = "serde", 1355 derive(serde::Serialize, serde::Deserialize), 1356 serde(tag = "type", rename = "mdxJsxAttribute") 1357)] 1358pub struct MdxJsxAttribute { 1359 // Void. 1360 /// Positional info. 1361 // pub position: Option<Position>, 1362 /// Key. 1363 pub name: String, 1364 /// Value. 1365 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] 1366 pub value: Option<AttributeValue>, 1367} 1368 1369/// MDX: JSX expression attribute. 1370/// 1371/// ```markdown 1372/// > | <a {...b} /> 1373/// ^ 1374/// ``` 1375#[derive(Clone, Debug, Eq, PartialEq)] 1376#[cfg_attr( 1377 feature = "serde", 1378 derive(serde::Serialize, serde::Deserialize), 1379 serde(tag = "type", rename = "mdxJsxExpressionAttribute") 1380)] 1381pub struct MdxJsxExpressionAttribute { 1382 /// Value. 1383 pub value: String, 1384 /// Stops 1385 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))] 1386 pub stops: Vec<Stop>, 1387} 1388 1389#[cfg(test)] 1390mod tests { 1391 use super::*; 1392 use crate::unist::Position; 1393 use alloc::{format, string::ToString, vec}; 1394 1395 // Literals. 1396 1397 #[test] 1398 fn text() { 1399 let mut node = Node::Text(Text { 1400 value: "a".into(), 1401 position: None, 1402 }); 1403 1404 assert_eq!( 1405 format!("{:?}", node), 1406 "Text { value: \"a\", position: None }", 1407 "should support `Debug`" 1408 ); 1409 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1410 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1411 assert_eq!(node.children(), None, "should support `children`"); 1412 assert_eq!(node.position(), None, "should support `position`"); 1413 assert_eq!(node.position_mut(), None, "should support `position`"); 1414 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1415 assert_eq!( 1416 format!("{:?}", node), 1417 "Text { value: \"a\", position: Some(1:1-1:2 (0-1)) }", 1418 "should support `position_set`" 1419 ); 1420 } 1421 1422 #[test] 1423 fn inline_code() { 1424 let mut node = Node::InlineCode(InlineCode { 1425 value: "a".into(), 1426 position: None, 1427 }); 1428 1429 assert_eq!( 1430 format!("{:?}", node), 1431 "InlineCode { value: \"a\", position: None }", 1432 "should support `Debug`" 1433 ); 1434 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1435 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1436 assert_eq!(node.children(), None, "should support `children`"); 1437 assert_eq!(node.position(), None, "should support `position`"); 1438 assert_eq!(node.position_mut(), None, "should support `position`"); 1439 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1440 assert_eq!( 1441 format!("{:?}", node), 1442 "InlineCode { value: \"a\", position: Some(1:1-1:2 (0-1)) }", 1443 "should support `position_set`" 1444 ); 1445 } 1446 1447 #[test] 1448 fn code() { 1449 let mut node = Node::Code(Code { 1450 value: "a".into(), 1451 position: None, 1452 lang: None, 1453 meta: None, 1454 }); 1455 1456 assert_eq!( 1457 format!("{:?}", node), 1458 "Code { value: \"a\", position: None, lang: None, meta: None }", 1459 "should support `Debug`" 1460 ); 1461 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1462 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1463 assert_eq!(node.children(), None, "should support `children`"); 1464 assert_eq!(node.position(), None, "should support `position`"); 1465 assert_eq!(node.position_mut(), None, "should support `position`"); 1466 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1467 assert_eq!( 1468 format!("{:?}", node), 1469 "Code { value: \"a\", position: Some(1:1-1:2 (0-1)), lang: None, meta: None }", 1470 "should support `position_set`" 1471 ); 1472 } 1473 1474 #[test] 1475 fn inline_math() { 1476 let mut node = Node::InlineMath(InlineMath { 1477 value: "a".into(), 1478 position: None, 1479 }); 1480 1481 assert_eq!( 1482 format!("{:?}", node), 1483 "InlineMath { value: \"a\", position: None }", 1484 "should support `Debug`" 1485 ); 1486 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1487 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1488 assert_eq!(node.children(), None, "should support `children`"); 1489 assert_eq!(node.position(), None, "should support `position`"); 1490 assert_eq!(node.position_mut(), None, "should support `position`"); 1491 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1492 assert_eq!( 1493 format!("{:?}", node), 1494 "InlineMath { value: \"a\", position: Some(1:1-1:2 (0-1)) }", 1495 "should support `position_set`" 1496 ); 1497 } 1498 1499 #[test] 1500 fn math() { 1501 let mut node = Node::Math(Math { 1502 value: "a".into(), 1503 position: None, 1504 meta: None, 1505 }); 1506 1507 assert_eq!( 1508 format!("{:?}", node), 1509 "Math { value: \"a\", position: None, meta: None }", 1510 "should support `Debug`" 1511 ); 1512 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1513 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1514 assert_eq!(node.children(), None, "should support `children`"); 1515 assert_eq!(node.position(), None, "should support `position`"); 1516 assert_eq!(node.position_mut(), None, "should support `position`"); 1517 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1518 assert_eq!( 1519 format!("{:?}", node), 1520 "Math { value: \"a\", position: Some(1:1-1:2 (0-1)), meta: None }", 1521 "should support `position_set`" 1522 ); 1523 } 1524 1525 #[test] 1526 fn html() { 1527 let mut node = Node::Html(Html { 1528 value: "a".into(), 1529 position: None, 1530 }); 1531 1532 assert_eq!( 1533 format!("{:?}", node), 1534 "Html { value: \"a\", position: None }", 1535 "should support `Debug`" 1536 ); 1537 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1538 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1539 assert_eq!(node.children(), None, "should support `children`"); 1540 assert_eq!(node.position(), None, "should support `position`"); 1541 assert_eq!(node.position_mut(), None, "should support `position`"); 1542 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1543 assert_eq!( 1544 format!("{:?}", node), 1545 "Html { value: \"a\", position: Some(1:1-1:2 (0-1)) }", 1546 "should support `position_set`" 1547 ); 1548 } 1549 1550 #[test] 1551 fn mdx_text_expression() { 1552 let mut node = Node::MdxTextExpression(MdxTextExpression { 1553 value: "a".into(), 1554 stops: vec![], 1555 position: None, 1556 }); 1557 1558 assert_eq!( 1559 format!("{:?}", node), 1560 "MdxTextExpression { value: \"a\", position: None, stops: [] }", 1561 "should support `Debug`" 1562 ); 1563 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1564 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1565 assert_eq!(node.children(), None, "should support `children`"); 1566 assert_eq!(node.position(), None, "should support `position`"); 1567 assert_eq!(node.position_mut(), None, "should support `position`"); 1568 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1569 assert_eq!( 1570 format!("{:?}", node), 1571 "MdxTextExpression { value: \"a\", position: Some(1:1-1:2 (0-1)), stops: [] }", 1572 "should support `position_set`" 1573 ); 1574 } 1575 1576 #[test] 1577 fn mdx_flow_expression() { 1578 let mut node = Node::MdxFlowExpression(MdxFlowExpression { 1579 value: "a".into(), 1580 stops: vec![], 1581 position: None, 1582 }); 1583 1584 assert_eq!( 1585 format!("{:?}", node), 1586 "MdxFlowExpression { value: \"a\", position: None, stops: [] }", 1587 "should support `Debug`" 1588 ); 1589 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1590 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1591 assert_eq!(node.children(), None, "should support `children`"); 1592 assert_eq!(node.position(), None, "should support `position`"); 1593 assert_eq!(node.position_mut(), None, "should support `position`"); 1594 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1595 assert_eq!( 1596 format!("{:?}", node), 1597 "MdxFlowExpression { value: \"a\", position: Some(1:1-1:2 (0-1)), stops: [] }", 1598 "should support `position_set`" 1599 ); 1600 } 1601 1602 #[test] 1603 fn mdxjs_esm() { 1604 let mut node = Node::MdxjsEsm(MdxjsEsm { 1605 value: "a".into(), 1606 stops: vec![], 1607 position: None, 1608 }); 1609 1610 assert_eq!( 1611 format!("{:?}", node), 1612 "MdxjsEsm { value: \"a\", position: None, stops: [] }", 1613 "should support `Debug`" 1614 ); 1615 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1616 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1617 assert_eq!(node.children(), None, "should support `children`"); 1618 assert_eq!(node.position(), None, "should support `position`"); 1619 assert_eq!(node.position_mut(), None, "should support `position`"); 1620 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1621 assert_eq!( 1622 format!("{:?}", node), 1623 "MdxjsEsm { value: \"a\", position: Some(1:1-1:2 (0-1)), stops: [] }", 1624 "should support `position_set`" 1625 ); 1626 } 1627 1628 #[test] 1629 fn toml() { 1630 let mut node = Node::Toml(Toml { 1631 value: "a".into(), 1632 position: None, 1633 }); 1634 1635 assert_eq!( 1636 format!("{:?}", node), 1637 "Toml { value: \"a\", position: None }", 1638 "should support `Debug`" 1639 ); 1640 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1641 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1642 assert_eq!(node.children(), None, "should support `children`"); 1643 assert_eq!(node.position(), None, "should support `position`"); 1644 assert_eq!(node.position_mut(), None, "should support `position`"); 1645 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1646 assert_eq!( 1647 format!("{:?}", node), 1648 "Toml { value: \"a\", position: Some(1:1-1:2 (0-1)) }", 1649 "should support `position_set`" 1650 ); 1651 } 1652 1653 #[test] 1654 fn yaml() { 1655 let mut node = Node::Yaml(Yaml { 1656 value: "a".into(), 1657 position: None, 1658 }); 1659 1660 assert_eq!( 1661 format!("{:?}", node), 1662 "Yaml { value: \"a\", position: None }", 1663 "should support `Debug`" 1664 ); 1665 assert_eq!(node.to_string(), "a", "should support `ToString`"); 1666 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1667 assert_eq!(node.children(), None, "should support `children`"); 1668 assert_eq!(node.position(), None, "should support `position`"); 1669 assert_eq!(node.position_mut(), None, "should support `position`"); 1670 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1671 assert_eq!( 1672 format!("{:?}", node), 1673 "Yaml { value: \"a\", position: Some(1:1-1:2 (0-1)) }", 1674 "should support `position_set`" 1675 ); 1676 } 1677 1678 // Voids. 1679 1680 #[test] 1681 fn break_node() { 1682 let mut node = Node::Break(Break { position: None }); 1683 1684 assert_eq!( 1685 format!("{:?}", node), 1686 "Break { position: None }", 1687 "should support `Debug`" 1688 ); 1689 assert_eq!(node.to_string(), "", "should support `ToString`"); 1690 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1691 assert_eq!(node.children(), None, "should support `children`"); 1692 assert_eq!(node.position(), None, "should support `position`"); 1693 assert_eq!(node.position_mut(), None, "should support `position`"); 1694 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1695 assert_eq!( 1696 format!("{:?}", node), 1697 "Break { position: Some(1:1-1:2 (0-1)) }", 1698 "should support `position_set`" 1699 ); 1700 } 1701 1702 #[test] 1703 fn thematic_break() { 1704 let mut node = Node::ThematicBreak(ThematicBreak { position: None }); 1705 1706 assert_eq!( 1707 format!("{:?}", node), 1708 "ThematicBreak { position: None }", 1709 "should support `Debug`" 1710 ); 1711 assert_eq!(node.to_string(), "", "should support `ToString`"); 1712 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1713 assert_eq!(node.children(), None, "should support `children`"); 1714 assert_eq!(node.position(), None, "should support `position`"); 1715 assert_eq!(node.position_mut(), None, "should support `position`"); 1716 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1717 assert_eq!( 1718 format!("{:?}", node), 1719 "ThematicBreak { position: Some(1:1-1:2 (0-1)) }", 1720 "should support `position_set`" 1721 ); 1722 } 1723 1724 #[test] 1725 fn footnote_reference() { 1726 let mut node = Node::FootnoteReference(FootnoteReference { 1727 position: None, 1728 identifier: "a".into(), 1729 label: Some("b".into()), 1730 }); 1731 1732 assert_eq!( 1733 format!("{:?}", node), 1734 "FootnoteReference { position: None, identifier: \"a\", label: Some(\"b\") }", 1735 "should support `Debug`" 1736 ); 1737 assert_eq!(node.to_string(), "", "should support `ToString`"); 1738 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1739 assert_eq!(node.children(), None, "should support `children`"); 1740 assert_eq!(node.position(), None, "should support `position`"); 1741 assert_eq!(node.position_mut(), None, "should support `position`"); 1742 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1743 assert_eq!( 1744 format!("{:?}", node), 1745 "FootnoteReference { position: Some(1:1-1:2 (0-1)), identifier: \"a\", label: Some(\"b\") }", 1746 "should support `position_set`" 1747 ); 1748 } 1749 1750 #[test] 1751 fn image_reference() { 1752 let mut node = Node::ImageReference(ImageReference { 1753 position: None, 1754 alt: "a".into(), 1755 identifier: "b".into(), 1756 label: Some("c".into()), 1757 reference_kind: ReferenceKind::Full, 1758 }); 1759 1760 assert_eq!( 1761 format!("{:?}", node), 1762 "ImageReference { position: None, alt: \"a\", reference_kind: Full, identifier: \"b\", label: Some(\"c\") }", 1763 "should support `Debug`" 1764 ); 1765 assert_eq!(node.to_string(), "", "should support `ToString`"); 1766 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1767 assert_eq!(node.children(), None, "should support `children`"); 1768 assert_eq!(node.position(), None, "should support `position`"); 1769 assert_eq!(node.position_mut(), None, "should support `position`"); 1770 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1771 assert_eq!( 1772 format!("{:?}", node), 1773 "ImageReference { position: Some(1:1-1:2 (0-1)), alt: \"a\", reference_kind: Full, identifier: \"b\", label: Some(\"c\") }", 1774 "should support `position_set`" 1775 ); 1776 } 1777 1778 #[test] 1779 fn image() { 1780 let mut node = Node::Image(Image { 1781 position: None, 1782 alt: "a".into(), 1783 url: "b".into(), 1784 title: None, 1785 }); 1786 1787 assert_eq!( 1788 format!("{:?}", node), 1789 "Image { position: None, alt: \"a\", url: \"b\", title: None }", 1790 "should support `Debug`" 1791 ); 1792 assert_eq!(node.to_string(), "", "should support `ToString`"); 1793 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1794 assert_eq!(node.children(), None, "should support `children`"); 1795 assert_eq!(node.position(), None, "should support `position`"); 1796 assert_eq!(node.position_mut(), None, "should support `position`"); 1797 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1798 assert_eq!( 1799 format!("{:?}", node), 1800 "Image { position: Some(1:1-1:2 (0-1)), alt: \"a\", url: \"b\", title: None }", 1801 "should support `position_set`" 1802 ); 1803 } 1804 1805 #[test] 1806 fn definition() { 1807 let mut node = Node::Definition(Definition { 1808 position: None, 1809 identifier: "a".into(), 1810 label: None, 1811 url: "b".into(), 1812 title: None, 1813 }); 1814 1815 assert_eq!( 1816 format!("{:?}", node), 1817 "Definition { position: None, url: \"b\", title: None, identifier: \"a\", label: None }", 1818 "should support `Debug`" 1819 ); 1820 assert_eq!(node.to_string(), "", "should support `ToString`"); 1821 assert_eq!(node.children_mut(), None, "should support `children_mut`"); 1822 assert_eq!(node.children(), None, "should support `children`"); 1823 assert_eq!(node.position(), None, "should support `position`"); 1824 assert_eq!(node.position_mut(), None, "should support `position`"); 1825 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1826 assert_eq!( 1827 format!("{:?}", node), 1828 "Definition { position: Some(1:1-1:2 (0-1)), url: \"b\", title: None, identifier: \"a\", label: None }", 1829 "should support `position_set`" 1830 ); 1831 } 1832 1833 // Parents. 1834 1835 #[test] 1836 fn root() { 1837 let mut node = Node::Root(Root { 1838 position: None, 1839 children: vec![], 1840 }); 1841 1842 assert_eq!( 1843 format!("{:?}", node), 1844 "Root { children: [], position: None }", 1845 "should support `Debug`" 1846 ); 1847 assert_eq!(node.to_string(), "", "should support `ToString`"); 1848 assert_eq!( 1849 node.children_mut(), 1850 Some(&mut vec![]), 1851 "should support `children_mut`" 1852 ); 1853 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 1854 assert_eq!(node.position(), None, "should support `position`"); 1855 assert_eq!(node.position_mut(), None, "should support `position`"); 1856 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1857 assert_eq!( 1858 format!("{:?}", node), 1859 "Root { children: [], position: Some(1:1-1:2 (0-1)) }", 1860 "should support `position_set`" 1861 ); 1862 } 1863 1864 #[test] 1865 fn block_quote() { 1866 let mut node = Node::Blockquote(Blockquote { 1867 position: None, 1868 children: vec![], 1869 }); 1870 1871 assert_eq!( 1872 format!("{:?}", node), 1873 "Blockquote { children: [], position: None }", 1874 "should support `Debug`" 1875 ); 1876 assert_eq!(node.to_string(), "", "should support `ToString`"); 1877 assert_eq!( 1878 node.children_mut(), 1879 Some(&mut vec![]), 1880 "should support `children_mut`" 1881 ); 1882 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 1883 assert_eq!(node.position(), None, "should support `position`"); 1884 assert_eq!(node.position_mut(), None, "should support `position`"); 1885 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1886 assert_eq!( 1887 format!("{:?}", node), 1888 "Blockquote { children: [], position: Some(1:1-1:2 (0-1)) }", 1889 "should support `position_set`" 1890 ); 1891 } 1892 1893 #[test] 1894 fn delete() { 1895 let mut node = Node::Delete(Delete { 1896 position: None, 1897 children: vec![], 1898 }); 1899 1900 assert_eq!( 1901 format!("{:?}", node), 1902 "Delete { children: [], position: None }", 1903 "should support `Debug`" 1904 ); 1905 assert_eq!(node.to_string(), "", "should support `ToString`"); 1906 assert_eq!( 1907 node.children_mut(), 1908 Some(&mut vec![]), 1909 "should support `children_mut`" 1910 ); 1911 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 1912 assert_eq!(node.position(), None, "should support `position`"); 1913 assert_eq!(node.position_mut(), None, "should support `position`"); 1914 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1915 assert_eq!( 1916 format!("{:?}", node), 1917 "Delete { children: [], position: Some(1:1-1:2 (0-1)) }", 1918 "should support `position_set`" 1919 ); 1920 } 1921 1922 #[test] 1923 fn emphasis() { 1924 let mut node = Node::Emphasis(Emphasis { 1925 position: None, 1926 children: vec![], 1927 }); 1928 1929 assert_eq!( 1930 format!("{:?}", node), 1931 "Emphasis { children: [], position: None }", 1932 "should support `Debug`" 1933 ); 1934 assert_eq!(node.to_string(), "", "should support `ToString`"); 1935 assert_eq!( 1936 node.children_mut(), 1937 Some(&mut vec![]), 1938 "should support `children_mut`" 1939 ); 1940 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 1941 assert_eq!(node.position(), None, "should support `position`"); 1942 assert_eq!(node.position_mut(), None, "should support `position`"); 1943 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1944 assert_eq!( 1945 format!("{:?}", node), 1946 "Emphasis { children: [], position: Some(1:1-1:2 (0-1)) }", 1947 "should support `position_set`" 1948 ); 1949 } 1950 1951 #[test] 1952 fn strong() { 1953 let mut node = Node::Strong(Strong { 1954 position: None, 1955 children: vec![], 1956 }); 1957 1958 assert_eq!( 1959 format!("{:?}", node), 1960 "Strong { children: [], position: None }", 1961 "should support `Debug`" 1962 ); 1963 assert_eq!(node.to_string(), "", "should support `ToString`"); 1964 assert_eq!( 1965 node.children_mut(), 1966 Some(&mut vec![]), 1967 "should support `children_mut`" 1968 ); 1969 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 1970 assert_eq!(node.position(), None, "should support `position`"); 1971 assert_eq!(node.position_mut(), None, "should support `position`"); 1972 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 1973 assert_eq!( 1974 format!("{:?}", node), 1975 "Strong { children: [], position: Some(1:1-1:2 (0-1)) }", 1976 "should support `position_set`" 1977 ); 1978 } 1979 1980 #[test] 1981 fn paragraph() { 1982 let mut node = Node::Paragraph(Paragraph { 1983 position: None, 1984 children: vec![], 1985 }); 1986 1987 assert_eq!( 1988 format!("{:?}", node), 1989 "Paragraph { children: [], position: None }", 1990 "should support `Debug`" 1991 ); 1992 assert_eq!(node.to_string(), "", "should support `ToString`"); 1993 assert_eq!( 1994 node.children_mut(), 1995 Some(&mut vec![]), 1996 "should support `children_mut`" 1997 ); 1998 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 1999 assert_eq!(node.position(), None, "should support `position`"); 2000 assert_eq!(node.position_mut(), None, "should support `position`"); 2001 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2002 assert_eq!( 2003 format!("{:?}", node), 2004 "Paragraph { children: [], position: Some(1:1-1:2 (0-1)) }", 2005 "should support `position_set`" 2006 ); 2007 } 2008 2009 #[test] 2010 fn table_row() { 2011 let mut node = Node::TableRow(TableRow { 2012 position: None, 2013 children: vec![], 2014 }); 2015 2016 assert_eq!( 2017 format!("{:?}", node), 2018 "TableRow { children: [], position: None }", 2019 "should support `Debug`" 2020 ); 2021 assert_eq!(node.to_string(), "", "should support `ToString`"); 2022 assert_eq!( 2023 node.children_mut(), 2024 Some(&mut vec![]), 2025 "should support `children_mut`" 2026 ); 2027 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2028 assert_eq!(node.position(), None, "should support `position`"); 2029 assert_eq!(node.position_mut(), None, "should support `position`"); 2030 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2031 assert_eq!( 2032 format!("{:?}", node), 2033 "TableRow { children: [], position: Some(1:1-1:2 (0-1)) }", 2034 "should support `position_set`" 2035 ); 2036 } 2037 2038 #[test] 2039 fn table_cell() { 2040 let mut node = Node::TableCell(TableCell { 2041 position: None, 2042 children: vec![], 2043 }); 2044 2045 assert_eq!( 2046 format!("{:?}", node), 2047 "TableCell { children: [], position: None }", 2048 "should support `Debug`" 2049 ); 2050 assert_eq!(node.to_string(), "", "should support `ToString`"); 2051 assert_eq!( 2052 node.children_mut(), 2053 Some(&mut vec![]), 2054 "should support `children_mut`" 2055 ); 2056 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2057 assert_eq!(node.position(), None, "should support `position`"); 2058 assert_eq!(node.position_mut(), None, "should support `position`"); 2059 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2060 assert_eq!( 2061 format!("{:?}", node), 2062 "TableCell { children: [], position: Some(1:1-1:2 (0-1)) }", 2063 "should support `position_set`" 2064 ); 2065 } 2066 2067 #[test] 2068 fn heading() { 2069 let mut node = Node::Heading(Heading { 2070 position: None, 2071 depth: 1, 2072 children: vec![], 2073 }); 2074 2075 assert_eq!( 2076 format!("{:?}", node), 2077 "Heading { children: [], position: None, depth: 1 }", 2078 "should support `Debug`" 2079 ); 2080 assert_eq!(node.to_string(), "", "should support `ToString`"); 2081 assert_eq!( 2082 node.children_mut(), 2083 Some(&mut vec![]), 2084 "should support `children_mut`" 2085 ); 2086 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2087 assert_eq!(node.position(), None, "should support `position`"); 2088 assert_eq!(node.position_mut(), None, "should support `position`"); 2089 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2090 assert_eq!( 2091 format!("{:?}", node), 2092 "Heading { children: [], position: Some(1:1-1:2 (0-1)), depth: 1 }", 2093 "should support `position_set`" 2094 ); 2095 } 2096 2097 #[test] 2098 fn table() { 2099 let mut node = Node::Table(Table { 2100 position: None, 2101 align: vec![], 2102 children: vec![], 2103 }); 2104 2105 assert_eq!( 2106 format!("{:?}", node), 2107 "Table { children: [], position: None, align: [] }", 2108 "should support `Debug`" 2109 ); 2110 assert_eq!(node.to_string(), "", "should support `ToString`"); 2111 assert_eq!( 2112 node.children_mut(), 2113 Some(&mut vec![]), 2114 "should support `children_mut`" 2115 ); 2116 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2117 assert_eq!(node.position(), None, "should support `position`"); 2118 assert_eq!(node.position_mut(), None, "should support `position`"); 2119 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2120 assert_eq!( 2121 format!("{:?}", node), 2122 "Table { children: [], position: Some(1:1-1:2 (0-1)), align: [] }", 2123 "should support `position_set`" 2124 ); 2125 } 2126 2127 #[test] 2128 fn list_item() { 2129 let mut node = Node::ListItem(ListItem { 2130 position: None, 2131 spread: false, 2132 checked: None, 2133 children: vec![], 2134 }); 2135 2136 assert_eq!( 2137 format!("{:?}", node), 2138 "ListItem { children: [], position: None, spread: false, checked: None }", 2139 "should support `Debug`" 2140 ); 2141 assert_eq!(node.to_string(), "", "should support `ToString`"); 2142 assert_eq!( 2143 node.children_mut(), 2144 Some(&mut vec![]), 2145 "should support `children_mut`" 2146 ); 2147 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2148 assert_eq!(node.position(), None, "should support `position`"); 2149 assert_eq!(node.position_mut(), None, "should support `position`"); 2150 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2151 assert_eq!( 2152 format!("{:?}", node), 2153 "ListItem { children: [], position: Some(1:1-1:2 (0-1)), spread: false, checked: None }", 2154 "should support `position_set`" 2155 ); 2156 } 2157 2158 #[test] 2159 fn list() { 2160 let mut node = Node::List(List { 2161 position: None, 2162 spread: false, 2163 ordered: false, 2164 start: None, 2165 children: vec![], 2166 }); 2167 2168 assert_eq!( 2169 format!("{:?}", node), 2170 "List { children: [], position: None, ordered: false, start: None, spread: false }", 2171 "should support `Debug`" 2172 ); 2173 assert_eq!(node.to_string(), "", "should support `ToString`"); 2174 assert_eq!( 2175 node.children_mut(), 2176 Some(&mut vec![]), 2177 "should support `children_mut`" 2178 ); 2179 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2180 assert_eq!(node.position(), None, "should support `position`"); 2181 assert_eq!(node.position_mut(), None, "should support `position`"); 2182 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2183 assert_eq!( 2184 format!("{:?}", node), 2185 "List { children: [], position: Some(1:1-1:2 (0-1)), ordered: false, start: None, spread: false }", 2186 "should support `position_set`" 2187 ); 2188 } 2189 2190 #[test] 2191 fn link_reference() { 2192 let mut node = Node::LinkReference(LinkReference { 2193 position: None, 2194 identifier: "a".into(), 2195 label: None, 2196 reference_kind: ReferenceKind::Full, 2197 children: vec![], 2198 }); 2199 2200 assert_eq!( 2201 format!("{:?}", node), 2202 "LinkReference { children: [], position: None, reference_kind: Full, identifier: \"a\", label: None }", 2203 "should support `Debug`" 2204 ); 2205 assert_eq!(node.to_string(), "", "should support `ToString`"); 2206 assert_eq!( 2207 node.children_mut(), 2208 Some(&mut vec![]), 2209 "should support `children_mut`" 2210 ); 2211 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2212 assert_eq!(node.position(), None, "should support `position`"); 2213 assert_eq!(node.position_mut(), None, "should support `position`"); 2214 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2215 assert_eq!( 2216 format!("{:?}", node), 2217 "LinkReference { children: [], position: Some(1:1-1:2 (0-1)), reference_kind: Full, identifier: \"a\", label: None }", 2218 "should support `position_set`" 2219 ); 2220 } 2221 2222 #[test] 2223 fn link() { 2224 let mut node = Node::Link(Link { 2225 position: None, 2226 url: "a".into(), 2227 title: None, 2228 children: vec![], 2229 }); 2230 2231 assert_eq!( 2232 format!("{:?}", node), 2233 "Link { children: [], position: None, url: \"a\", title: None }", 2234 "should support `Debug`" 2235 ); 2236 assert_eq!(node.to_string(), "", "should support `ToString`"); 2237 assert_eq!( 2238 node.children_mut(), 2239 Some(&mut vec![]), 2240 "should support `children_mut`" 2241 ); 2242 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2243 assert_eq!(node.position(), None, "should support `position`"); 2244 assert_eq!(node.position_mut(), None, "should support `position`"); 2245 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2246 assert_eq!( 2247 format!("{:?}", node), 2248 "Link { children: [], position: Some(1:1-1:2 (0-1)), url: \"a\", title: None }", 2249 "should support `position_set`" 2250 ); 2251 } 2252 2253 #[test] 2254 fn footnote_definition() { 2255 let mut node = Node::FootnoteDefinition(FootnoteDefinition { 2256 position: None, 2257 identifier: "a".into(), 2258 label: None, 2259 children: vec![], 2260 }); 2261 2262 assert_eq!( 2263 format!("{:?}", node), 2264 "FootnoteDefinition { children: [], position: None, identifier: \"a\", label: None }", 2265 "should support `Debug`" 2266 ); 2267 assert_eq!(node.to_string(), "", "should support `ToString`"); 2268 assert_eq!( 2269 node.children_mut(), 2270 Some(&mut vec![]), 2271 "should support `children_mut`" 2272 ); 2273 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2274 assert_eq!(node.position(), None, "should support `position`"); 2275 assert_eq!(node.position_mut(), None, "should support `position`"); 2276 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2277 assert_eq!( 2278 format!("{:?}", node), 2279 "FootnoteDefinition { children: [], position: Some(1:1-1:2 (0-1)), identifier: \"a\", label: None }", 2280 "should support `position_set`" 2281 ); 2282 } 2283 2284 #[test] 2285 fn mdx_jsx_flow_element() { 2286 let mut node = Node::MdxJsxFlowElement(MdxJsxFlowElement { 2287 position: None, 2288 name: None, 2289 attributes: vec![], 2290 children: vec![], 2291 }); 2292 2293 assert_eq!( 2294 format!("{:?}", node), 2295 "MdxJsxFlowElement { children: [], position: None, name: None, attributes: [] }", 2296 "should support `Debug`" 2297 ); 2298 assert_eq!(node.to_string(), "", "should support `ToString`"); 2299 assert_eq!( 2300 node.children_mut(), 2301 Some(&mut vec![]), 2302 "should support `children_mut`" 2303 ); 2304 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2305 assert_eq!(node.position(), None, "should support `position`"); 2306 assert_eq!(node.position_mut(), None, "should support `position`"); 2307 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2308 assert_eq!( 2309 format!("{:?}", node), 2310 "MdxJsxFlowElement { children: [], position: Some(1:1-1:2 (0-1)), name: None, attributes: [] }", 2311 "should support `position_set`" 2312 ); 2313 } 2314 2315 #[test] 2316 fn mdx_jsx_text_element() { 2317 let mut node = Node::MdxJsxTextElement(MdxJsxTextElement { 2318 position: None, 2319 name: None, 2320 attributes: vec![], 2321 children: vec![], 2322 }); 2323 2324 assert_eq!( 2325 format!("{:?}", node), 2326 "MdxJsxTextElement { children: [], position: None, name: None, attributes: [] }", 2327 "should support `Debug`" 2328 ); 2329 assert_eq!(node.to_string(), "", "should support `ToString`"); 2330 assert_eq!( 2331 node.children_mut(), 2332 Some(&mut vec![]), 2333 "should support `children_mut`" 2334 ); 2335 assert_eq!(node.children(), Some(&vec![]), "should support `children`"); 2336 assert_eq!(node.position(), None, "should support `position`"); 2337 assert_eq!(node.position_mut(), None, "should support `position`"); 2338 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1))); 2339 assert_eq!( 2340 format!("{:?}", node), 2341 "MdxJsxTextElement { children: [], position: Some(1:1-1:2 (0-1)), name: None, attributes: [] }", 2342 "should support `position_set`" 2343 ); 2344 } 2345}