html-to-markdown 3.14.3 → 3.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  // This file is auto-generated by alef. DO NOT EDIT.
2
- // alef:hash:b89f28165748578716b78d7870c438b5394d9c847ec7718f9620057ca8fb0688
2
+ // alef:hash:ef17e73c4a8ab3ab7874d1b469b3b0bfa02b61db141c8db6976ce5dd46217c8f
3
3
  // Re-generate with: alef generate
4
4
  #![allow(dead_code, unused_imports, unused_variables)]
5
5
  #![allow(
@@ -94,6 +94,7 @@ pub struct ConversionOptions {
94
94
  strip_tags: Vec<String>,
95
95
  preserve_tags: Vec<String>,
96
96
  skip_images: bool,
97
+ inline_data_media: InlineDataMedia,
97
98
  url_escape_style: UrlEscapeStyle,
98
99
  link_style: LinkStyle,
99
100
  output_format: OutputFormat,
@@ -105,6 +106,7 @@ pub struct ConversionOptions {
105
106
  max_depth: Option<usize>,
106
107
  exclude_selectors: Vec<String>,
107
108
  tier_strategy: TierStrategy,
109
+ base_url: Option<String>,
108
110
  }
109
111
 
110
112
  unsafe impl IntoValueFromNative for ConversionOptions {}
@@ -436,6 +438,15 @@ impl ConversionOptions {
436
438
  })?,
437
439
  None => false,
438
440
  },
441
+ inline_data_media: match kwargs.get(ruby.to_symbol("inline_data_media")) {
442
+ Some(v) => InlineDataMedia::try_convert(v).map_err(|e| {
443
+ magnus::Error::new(
444
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
445
+ format!("invalid value for `inline_data_media`: {}", e),
446
+ )
447
+ })?,
448
+ None => InlineDataMedia::Keep,
449
+ },
439
450
  url_escape_style: match kwargs.get(ruby.to_symbol("url_escape_style")) {
440
451
  Some(v) => UrlEscapeStyle::try_convert(v).map_err(|e| {
441
452
  magnus::Error::new(
@@ -535,6 +546,15 @@ impl ConversionOptions {
535
546
  })?,
536
547
  None => TierStrategy::Auto,
537
548
  },
549
+ base_url: match kwargs.get(ruby.to_symbol("base_url")).filter(|v| !v.is_nil()) {
550
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
551
+ magnus::Error::new(
552
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
553
+ format!("invalid value for `base_url`: {}", e),
554
+ )
555
+ })?),
556
+ None => None,
557
+ },
538
558
  })
539
559
  }
540
560
 
@@ -666,6 +686,10 @@ impl ConversionOptions {
666
686
  self.skip_images
667
687
  }
668
688
 
689
+ fn inline_data_media(&self) -> InlineDataMedia {
690
+ self.inline_data_media.clone()
691
+ }
692
+
669
693
  fn url_escape_style(&self) -> UrlEscapeStyle {
670
694
  self.url_escape_style.clone()
671
695
  }
@@ -709,6 +733,10 @@ impl ConversionOptions {
709
733
  fn tier_strategy(&self) -> TierStrategy {
710
734
  self.tier_strategy.clone()
711
735
  }
736
+
737
+ fn base_url(&self) -> Option<String> {
738
+ self.base_url.clone()
739
+ }
712
740
  }
713
741
 
714
742
  #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
@@ -747,6 +775,7 @@ pub struct ConversionOptionsUpdate {
747
775
  strip_tags: Option<Vec<String>>,
748
776
  preserve_tags: Option<Vec<String>>,
749
777
  skip_images: Option<bool>,
778
+ inline_data_media: Option<InlineDataMedia>,
750
779
  url_escape_style: Option<UrlEscapeStyle>,
751
780
  link_style: Option<LinkStyle>,
752
781
  output_format: Option<OutputFormat>,
@@ -758,6 +787,7 @@ pub struct ConversionOptionsUpdate {
758
787
  max_depth: Option<usize>,
759
788
  exclude_selectors: Option<Vec<String>>,
760
789
  tier_strategy: Option<TierStrategy>,
790
+ base_url: Option<String>,
761
791
  }
762
792
 
763
793
  unsafe impl IntoValueFromNative for ConversionOptionsUpdate {}
@@ -1092,6 +1122,15 @@ impl ConversionOptionsUpdate {
1092
1122
  })?),
1093
1123
  None => None,
1094
1124
  },
1125
+ inline_data_media: match kwargs.get(ruby.to_symbol("inline_data_media")).filter(|v| !v.is_nil()) {
1126
+ Some(v) => Some(InlineDataMedia::try_convert(v).map_err(|e| {
1127
+ magnus::Error::new(
1128
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1129
+ format!("invalid value for `inline_data_media`: {}", e),
1130
+ )
1131
+ })?),
1132
+ None => None,
1133
+ },
1095
1134
  url_escape_style: match kwargs.get(ruby.to_symbol("url_escape_style")).filter(|v| !v.is_nil()) {
1096
1135
  Some(v) => Some(UrlEscapeStyle::try_convert(v).map_err(|e| {
1097
1136
  magnus::Error::new(
@@ -1194,6 +1233,15 @@ impl ConversionOptionsUpdate {
1194
1233
  })?),
1195
1234
  None => None,
1196
1235
  },
1236
+ base_url: match kwargs.get(ruby.to_symbol("base_url")).filter(|v| !v.is_nil()) {
1237
+ Some(v) => Some(String::try_convert(v).map_err(|e| {
1238
+ magnus::Error::new(
1239
+ unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
1240
+ format!("invalid value for `base_url`: {}", e),
1241
+ )
1242
+ })?),
1243
+ None => None,
1244
+ },
1197
1245
  })
1198
1246
  }
1199
1247
 
@@ -1325,6 +1373,10 @@ impl ConversionOptionsUpdate {
1325
1373
  self.skip_images
1326
1374
  }
1327
1375
 
1376
+ fn inline_data_media(&self) -> Option<InlineDataMedia> {
1377
+ self.inline_data_media.clone()
1378
+ }
1379
+
1328
1380
  fn url_escape_style(&self) -> Option<UrlEscapeStyle> {
1329
1381
  self.url_escape_style.clone()
1330
1382
  }
@@ -1368,6 +1420,10 @@ impl ConversionOptionsUpdate {
1368
1420
  fn tier_strategy(&self) -> Option<TierStrategy> {
1369
1421
  self.tier_strategy.clone()
1370
1422
  }
1423
+
1424
+ fn base_url(&self) -> Option<String> {
1425
+ self.base_url.clone()
1426
+ }
1371
1427
  }
1372
1428
 
1373
1429
  #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
@@ -3642,7 +3698,8 @@ impl magnus::IntoValue for AnnotationKind {
3642
3698
 
3643
3699
  impl magnus::TryConvert for AnnotationKind {
3644
3700
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
3645
- // For data enums with fields (e.g., PageAction), try to deserialize from JSON first.
3701
+ // Generated Data variants carry native DTOs, not JSON-compatible display strings.
3702
+ let class_name: Option<String> = val.class().funcall("name", ())?; // For data enums with fields (e.g., PageAction), try to deserialize from JSON first.
3646
3703
  // For unit enums or when passed as a string, fall back to string-based conversion.
3647
3704
  let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
3648
3705
  s
@@ -3674,9 +3731,10 @@ impl magnus::TryConvert for AnnotationKind {
3674
3731
 
3675
3732
  unsafe impl IntoValueFromNative for AnnotationKind {}
3676
3733
  unsafe impl TryConvertOwned for AnnotationKind {}
3734
+
3677
3735
  impl AnnotationKind {}
3678
3736
 
3679
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
3737
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
3680
3738
  pub enum CodeBlockStyle {
3681
3739
  Indented,
3682
3740
  Backticks,
@@ -3702,7 +3760,14 @@ impl magnus::IntoValue for CodeBlockStyle {
3702
3760
 
3703
3761
  impl magnus::TryConvert for CodeBlockStyle {
3704
3762
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
3705
- let s: String = magnus::TryConvert::try_convert(val)?;
3763
+ // IntoValue emits Symbols, including when this enum is a Hash key.
3764
+ // Accept that exact representation as well as String inputs; do not
3765
+ // coerce arbitrary objects through to_s.
3766
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
3767
+ symbol.name()?.into_owned()
3768
+ } else {
3769
+ magnus::TryConvert::try_convert(val)?
3770
+ };
3706
3771
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
3707
3772
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
3708
3773
  // existing consumer code written in any of those styles keep working.
@@ -3721,7 +3786,7 @@ impl magnus::TryConvert for CodeBlockStyle {
3721
3786
  unsafe impl IntoValueFromNative for CodeBlockStyle {}
3722
3787
  unsafe impl TryConvertOwned for CodeBlockStyle {}
3723
3788
 
3724
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
3789
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
3725
3790
  pub enum HeadingStyle {
3726
3791
  Underlined,
3727
3792
  Atx,
@@ -3747,7 +3812,14 @@ impl magnus::IntoValue for HeadingStyle {
3747
3812
 
3748
3813
  impl magnus::TryConvert for HeadingStyle {
3749
3814
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
3750
- let s: String = magnus::TryConvert::try_convert(val)?;
3815
+ // IntoValue emits Symbols, including when this enum is a Hash key.
3816
+ // Accept that exact representation as well as String inputs; do not
3817
+ // coerce arbitrary objects through to_s.
3818
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
3819
+ symbol.name()?.into_owned()
3820
+ } else {
3821
+ magnus::TryConvert::try_convert(val)?
3822
+ };
3751
3823
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
3752
3824
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
3753
3825
  // existing consumer code written in any of those styles keep working.
@@ -3766,7 +3838,7 @@ impl magnus::TryConvert for HeadingStyle {
3766
3838
  unsafe impl IntoValueFromNative for HeadingStyle {}
3767
3839
  unsafe impl TryConvertOwned for HeadingStyle {}
3768
3840
 
3769
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
3841
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
3770
3842
  pub enum HighlightStyle {
3771
3843
  DoubleEqual,
3772
3844
  Html,
@@ -3794,7 +3866,14 @@ impl magnus::IntoValue for HighlightStyle {
3794
3866
 
3795
3867
  impl magnus::TryConvert for HighlightStyle {
3796
3868
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
3797
- let s: String = magnus::TryConvert::try_convert(val)?;
3869
+ // IntoValue emits Symbols, including when this enum is a Hash key.
3870
+ // Accept that exact representation as well as String inputs; do not
3871
+ // coerce arbitrary objects through to_s.
3872
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
3873
+ symbol.name()?.into_owned()
3874
+ } else {
3875
+ magnus::TryConvert::try_convert(val)?
3876
+ };
3798
3877
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
3799
3878
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
3800
3879
  // existing consumer code written in any of those styles keep working.
@@ -3814,7 +3893,7 @@ impl magnus::TryConvert for HighlightStyle {
3814
3893
  unsafe impl IntoValueFromNative for HighlightStyle {}
3815
3894
  unsafe impl TryConvertOwned for HighlightStyle {}
3816
3895
 
3817
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
3896
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
3818
3897
  #[serde(rename_all = "snake_case")]
3819
3898
  pub enum ImageType {
3820
3899
  DataUri,
@@ -3843,7 +3922,14 @@ impl magnus::IntoValue for ImageType {
3843
3922
 
3844
3923
  impl magnus::TryConvert for ImageType {
3845
3924
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
3846
- let s: String = magnus::TryConvert::try_convert(val)?;
3925
+ // IntoValue emits Symbols, including when this enum is a Hash key.
3926
+ // Accept that exact representation as well as String inputs; do not
3927
+ // coerce arbitrary objects through to_s.
3928
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
3929
+ symbol.name()?.into_owned()
3930
+ } else {
3931
+ magnus::TryConvert::try_convert(val)?
3932
+ };
3847
3933
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
3848
3934
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
3849
3935
  // existing consumer code written in any of those styles keep working.
@@ -3863,7 +3949,59 @@ impl magnus::TryConvert for ImageType {
3863
3949
  unsafe impl IntoValueFromNative for ImageType {}
3864
3950
  unsafe impl TryConvertOwned for ImageType {}
3865
3951
 
3866
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
3952
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
3953
+ pub enum InlineDataMedia {
3954
+ Keep,
3955
+ AltTextOnly,
3956
+ DropElement,
3957
+ }
3958
+
3959
+ impl Default for InlineDataMedia {
3960
+ fn default() -> Self {
3961
+ Self::Keep
3962
+ }
3963
+ }
3964
+
3965
+ impl magnus::IntoValue for InlineDataMedia {
3966
+ fn into_value_with(self, handle: &Ruby) -> magnus::Value {
3967
+ let sym = match self {
3968
+ InlineDataMedia::Keep => "Keep",
3969
+ InlineDataMedia::AltTextOnly => "AltTextOnly",
3970
+ InlineDataMedia::DropElement => "DropElement",
3971
+ };
3972
+ handle.to_symbol(sym).into_value_with(handle)
3973
+ }
3974
+ }
3975
+
3976
+ impl magnus::TryConvert for InlineDataMedia {
3977
+ fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
3978
+ // IntoValue emits Symbols, including when this enum is a Hash key.
3979
+ // Accept that exact representation as well as String inputs; do not
3980
+ // coerce arbitrary objects through to_s.
3981
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
3982
+ symbol.name()?.into_owned()
3983
+ } else {
3984
+ magnus::TryConvert::try_convert(val)?
3985
+ };
3986
+ // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
3987
+ // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
3988
+ // existing consumer code written in any of those styles keep working.
3989
+ match s.as_str() {
3990
+ "Keep" | "keep" => Ok(InlineDataMedia::Keep),
3991
+ "AltTextOnly" | "alt_text_only" => Ok(InlineDataMedia::AltTextOnly),
3992
+ "DropElement" | "drop_element" => Ok(InlineDataMedia::DropElement),
3993
+ other => Err(magnus::Error::new(
3994
+ unsafe { Ruby::get_unchecked() }.exception_arg_error(),
3995
+ format!("invalid InlineDataMedia value: {other}"),
3996
+ )),
3997
+ }
3998
+ }
3999
+ }
4000
+
4001
+ unsafe impl IntoValueFromNative for InlineDataMedia {}
4002
+ unsafe impl TryConvertOwned for InlineDataMedia {}
4003
+
4004
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
3867
4005
  pub enum LinkStyle {
3868
4006
  Inline,
3869
4007
  Reference,
@@ -3887,7 +4025,14 @@ impl magnus::IntoValue for LinkStyle {
3887
4025
 
3888
4026
  impl magnus::TryConvert for LinkStyle {
3889
4027
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
3890
- let s: String = magnus::TryConvert::try_convert(val)?;
4028
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4029
+ // Accept that exact representation as well as String inputs; do not
4030
+ // coerce arbitrary objects through to_s.
4031
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4032
+ symbol.name()?.into_owned()
4033
+ } else {
4034
+ magnus::TryConvert::try_convert(val)?
4035
+ };
3891
4036
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
3892
4037
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
3893
4038
  // existing consumer code written in any of those styles keep working.
@@ -3905,7 +4050,7 @@ impl magnus::TryConvert for LinkStyle {
3905
4050
  unsafe impl IntoValueFromNative for LinkStyle {}
3906
4051
  unsafe impl TryConvertOwned for LinkStyle {}
3907
4052
 
3908
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
4053
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
3909
4054
  #[serde(rename_all = "snake_case")]
3910
4055
  pub enum LinkType {
3911
4056
  Anchor,
@@ -3938,7 +4083,14 @@ impl magnus::IntoValue for LinkType {
3938
4083
 
3939
4084
  impl magnus::TryConvert for LinkType {
3940
4085
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
3941
- let s: String = magnus::TryConvert::try_convert(val)?;
4086
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4087
+ // Accept that exact representation as well as String inputs; do not
4088
+ // coerce arbitrary objects through to_s.
4089
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4090
+ symbol.name()?.into_owned()
4091
+ } else {
4092
+ magnus::TryConvert::try_convert(val)?
4093
+ };
3942
4094
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
3943
4095
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
3944
4096
  // existing consumer code written in any of those styles keep working.
@@ -3960,7 +4112,7 @@ impl magnus::TryConvert for LinkType {
3960
4112
  unsafe impl IntoValueFromNative for LinkType {}
3961
4113
  unsafe impl TryConvertOwned for LinkType {}
3962
4114
 
3963
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
4115
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
3964
4116
  pub enum ListIndentType {
3965
4117
  Spaces,
3966
4118
  Tabs,
@@ -3984,7 +4136,14 @@ impl magnus::IntoValue for ListIndentType {
3984
4136
 
3985
4137
  impl magnus::TryConvert for ListIndentType {
3986
4138
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
3987
- let s: String = magnus::TryConvert::try_convert(val)?;
4139
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4140
+ // Accept that exact representation as well as String inputs; do not
4141
+ // coerce arbitrary objects through to_s.
4142
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4143
+ symbol.name()?.into_owned()
4144
+ } else {
4145
+ magnus::TryConvert::try_convert(val)?
4146
+ };
3988
4147
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
3989
4148
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
3990
4149
  // existing consumer code written in any of those styles keep working.
@@ -4002,7 +4161,7 @@ impl magnus::TryConvert for ListIndentType {
4002
4161
  unsafe impl IntoValueFromNative for ListIndentType {}
4003
4162
  unsafe impl TryConvertOwned for ListIndentType {}
4004
4163
 
4005
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
4164
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
4006
4165
  pub enum NewlineStyle {
4007
4166
  Spaces,
4008
4167
  Backslash,
@@ -4026,7 +4185,14 @@ impl magnus::IntoValue for NewlineStyle {
4026
4185
 
4027
4186
  impl magnus::TryConvert for NewlineStyle {
4028
4187
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4029
- let s: String = magnus::TryConvert::try_convert(val)?;
4188
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4189
+ // Accept that exact representation as well as String inputs; do not
4190
+ // coerce arbitrary objects through to_s.
4191
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4192
+ symbol.name()?.into_owned()
4193
+ } else {
4194
+ magnus::TryConvert::try_convert(val)?
4195
+ };
4030
4196
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
4031
4197
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
4032
4198
  // existing consumer code written in any of those styles keep working.
@@ -4113,7 +4279,8 @@ impl magnus::IntoValue for NodeContent {
4113
4279
 
4114
4280
  impl magnus::TryConvert for NodeContent {
4115
4281
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4116
- // For data enums with fields (e.g., PageAction), try to deserialize from JSON first.
4282
+ // Generated Data variants carry native DTOs, not JSON-compatible display strings.
4283
+ let class_name: Option<String> = val.class().funcall("name", ())?; // For data enums with fields (e.g., PageAction), try to deserialize from JSON first.
4117
4284
  // For unit enums or when passed as a string, fall back to string-based conversion.
4118
4285
  let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
4119
4286
  s
@@ -4145,9 +4312,10 @@ impl magnus::TryConvert for NodeContent {
4145
4312
 
4146
4313
  unsafe impl IntoValueFromNative for NodeContent {}
4147
4314
  unsafe impl TryConvertOwned for NodeContent {}
4315
+
4148
4316
  impl NodeContent {}
4149
4317
 
4150
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
4318
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
4151
4319
  pub enum NodeType {
4152
4320
  Text,
4153
4321
  Element,
@@ -4343,7 +4511,14 @@ impl magnus::IntoValue for NodeType {
4343
4511
 
4344
4512
  impl magnus::TryConvert for NodeType {
4345
4513
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4346
- let s: String = magnus::TryConvert::try_convert(val)?;
4514
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4515
+ // Accept that exact representation as well as String inputs; do not
4516
+ // coerce arbitrary objects through to_s.
4517
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4518
+ symbol.name()?.into_owned()
4519
+ } else {
4520
+ magnus::TryConvert::try_convert(val)?
4521
+ };
4347
4522
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
4348
4523
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
4349
4524
  // existing consumer code written in any of those styles keep working.
@@ -4447,7 +4622,7 @@ impl magnus::TryConvert for NodeType {
4447
4622
  unsafe impl IntoValueFromNative for NodeType {}
4448
4623
  unsafe impl TryConvertOwned for NodeType {}
4449
4624
 
4450
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
4625
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
4451
4626
  pub enum OutputFormat {
4452
4627
  Markdown,
4453
4628
  Djot,
@@ -4473,7 +4648,14 @@ impl magnus::IntoValue for OutputFormat {
4473
4648
 
4474
4649
  impl magnus::TryConvert for OutputFormat {
4475
4650
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4476
- let s: String = magnus::TryConvert::try_convert(val)?;
4651
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4652
+ // Accept that exact representation as well as String inputs; do not
4653
+ // coerce arbitrary objects through to_s.
4654
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4655
+ symbol.name()?.into_owned()
4656
+ } else {
4657
+ magnus::TryConvert::try_convert(val)?
4658
+ };
4477
4659
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
4478
4660
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
4479
4661
  // existing consumer code written in any of those styles keep working.
@@ -4492,7 +4674,7 @@ impl magnus::TryConvert for OutputFormat {
4492
4674
  unsafe impl IntoValueFromNative for OutputFormat {}
4493
4675
  unsafe impl TryConvertOwned for OutputFormat {}
4494
4676
 
4495
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
4677
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
4496
4678
  pub enum PreprocessingPreset {
4497
4679
  Minimal,
4498
4680
  Standard,
@@ -4518,7 +4700,14 @@ impl magnus::IntoValue for PreprocessingPreset {
4518
4700
 
4519
4701
  impl magnus::TryConvert for PreprocessingPreset {
4520
4702
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4521
- let s: String = magnus::TryConvert::try_convert(val)?;
4703
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4704
+ // Accept that exact representation as well as String inputs; do not
4705
+ // coerce arbitrary objects through to_s.
4706
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4707
+ symbol.name()?.into_owned()
4708
+ } else {
4709
+ magnus::TryConvert::try_convert(val)?
4710
+ };
4522
4711
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
4523
4712
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
4524
4713
  // existing consumer code written in any of those styles keep working.
@@ -4537,7 +4726,7 @@ impl magnus::TryConvert for PreprocessingPreset {
4537
4726
  unsafe impl IntoValueFromNative for PreprocessingPreset {}
4538
4727
  unsafe impl TryConvertOwned for PreprocessingPreset {}
4539
4728
 
4540
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
4729
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
4541
4730
  #[serde(rename_all = "snake_case")]
4542
4731
  pub enum StructuredDataType {
4543
4732
  #[serde(rename = "json_ld")]
@@ -4566,7 +4755,14 @@ impl magnus::IntoValue for StructuredDataType {
4566
4755
 
4567
4756
  impl magnus::TryConvert for StructuredDataType {
4568
4757
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4569
- let s: String = magnus::TryConvert::try_convert(val)?;
4758
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4759
+ // Accept that exact representation as well as String inputs; do not
4760
+ // coerce arbitrary objects through to_s.
4761
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4762
+ symbol.name()?.into_owned()
4763
+ } else {
4764
+ magnus::TryConvert::try_convert(val)?
4765
+ };
4570
4766
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
4571
4767
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
4572
4768
  // existing consumer code written in any of those styles keep working.
@@ -4585,7 +4781,7 @@ impl magnus::TryConvert for StructuredDataType {
4585
4781
  unsafe impl IntoValueFromNative for StructuredDataType {}
4586
4782
  unsafe impl TryConvertOwned for StructuredDataType {}
4587
4783
 
4588
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
4784
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
4589
4785
  pub enum TextDirection {
4590
4786
  #[serde(rename = "ltr")]
4591
4787
  LeftToRight,
@@ -4614,7 +4810,14 @@ impl magnus::IntoValue for TextDirection {
4614
4810
 
4615
4811
  impl magnus::TryConvert for TextDirection {
4616
4812
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4617
- let s: String = magnus::TryConvert::try_convert(val)?;
4813
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4814
+ // Accept that exact representation as well as String inputs; do not
4815
+ // coerce arbitrary objects through to_s.
4816
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4817
+ symbol.name()?.into_owned()
4818
+ } else {
4819
+ magnus::TryConvert::try_convert(val)?
4820
+ };
4618
4821
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
4619
4822
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
4620
4823
  // existing consumer code written in any of those styles keep working.
@@ -4633,7 +4836,7 @@ impl magnus::TryConvert for TextDirection {
4633
4836
  unsafe impl IntoValueFromNative for TextDirection {}
4634
4837
  unsafe impl TryConvertOwned for TextDirection {}
4635
4838
 
4636
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
4839
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
4637
4840
  #[serde(rename_all = "snake_case")]
4638
4841
  pub enum TierStrategy {
4639
4842
  Auto,
@@ -4660,7 +4863,14 @@ impl magnus::IntoValue for TierStrategy {
4660
4863
 
4661
4864
  impl magnus::TryConvert for TierStrategy {
4662
4865
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4663
- let s: String = magnus::TryConvert::try_convert(val)?;
4866
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4867
+ // Accept that exact representation as well as String inputs; do not
4868
+ // coerce arbitrary objects through to_s.
4869
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4870
+ symbol.name()?.into_owned()
4871
+ } else {
4872
+ magnus::TryConvert::try_convert(val)?
4873
+ };
4664
4874
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
4665
4875
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
4666
4876
  // existing consumer code written in any of those styles keep working.
@@ -4679,7 +4889,7 @@ impl magnus::TryConvert for TierStrategy {
4679
4889
  unsafe impl IntoValueFromNative for TierStrategy {}
4680
4890
  unsafe impl TryConvertOwned for TierStrategy {}
4681
4891
 
4682
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
4892
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
4683
4893
  pub enum UrlEscapeStyle {
4684
4894
  Angle,
4685
4895
  Percent,
@@ -4703,7 +4913,14 @@ impl magnus::IntoValue for UrlEscapeStyle {
4703
4913
 
4704
4914
  impl magnus::TryConvert for UrlEscapeStyle {
4705
4915
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4706
- let s: String = magnus::TryConvert::try_convert(val)?;
4916
+ // IntoValue emits Symbols, including when this enum is a Hash key.
4917
+ // Accept that exact representation as well as String inputs; do not
4918
+ // coerce arbitrary objects through to_s.
4919
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
4920
+ symbol.name()?.into_owned()
4921
+ } else {
4922
+ magnus::TryConvert::try_convert(val)?
4923
+ };
4707
4924
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
4708
4925
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
4709
4926
  // existing consumer code written in any of those styles keep working.
@@ -4749,7 +4966,8 @@ impl magnus::IntoValue for VisitResult {
4749
4966
 
4750
4967
  impl magnus::TryConvert for VisitResult {
4751
4968
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4752
- // For data enums with fields (e.g., PageAction), try to deserialize from JSON first.
4969
+ // Generated Data variants carry native DTOs, not JSON-compatible display strings.
4970
+ let class_name: Option<String> = val.class().funcall("name", ())?; // For data enums with fields (e.g., PageAction), try to deserialize from JSON first.
4753
4971
  // For unit enums or when passed as a string, fall back to string-based conversion.
4754
4972
  let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
4755
4973
  s
@@ -4781,6 +4999,7 @@ impl magnus::TryConvert for VisitResult {
4781
4999
 
4782
5000
  unsafe impl IntoValueFromNative for VisitResult {}
4783
5001
  unsafe impl TryConvertOwned for VisitResult {}
5002
+
4784
5003
  impl VisitResult {
4785
5004
  pub fn custom(&self) -> Option<&String> {
4786
5005
  match self {
@@ -4796,7 +5015,7 @@ impl VisitResult {
4796
5015
  }
4797
5016
  }
4798
5017
 
4799
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
5018
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
4800
5019
  #[serde(rename_all = "snake_case")]
4801
5020
  pub enum WarningKind {
4802
5021
  ImageExtractionFailed,
@@ -4829,7 +5048,14 @@ impl magnus::IntoValue for WarningKind {
4829
5048
 
4830
5049
  impl magnus::TryConvert for WarningKind {
4831
5050
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4832
- let s: String = magnus::TryConvert::try_convert(val)?;
5051
+ // IntoValue emits Symbols, including when this enum is a Hash key.
5052
+ // Accept that exact representation as well as String inputs; do not
5053
+ // coerce arbitrary objects through to_s.
5054
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
5055
+ symbol.name()?.into_owned()
5056
+ } else {
5057
+ magnus::TryConvert::try_convert(val)?
5058
+ };
4833
5059
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
4834
5060
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
4835
5061
  // existing consumer code written in any of those styles keep working.
@@ -4851,7 +5077,7 @@ impl magnus::TryConvert for WarningKind {
4851
5077
  unsafe impl IntoValueFromNative for WarningKind {}
4852
5078
  unsafe impl TryConvertOwned for WarningKind {}
4853
5079
 
4854
- #[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
5080
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
4855
5081
  pub enum WhitespaceMode {
4856
5082
  Normalized,
4857
5083
  Strict,
@@ -4875,7 +5101,14 @@ impl magnus::IntoValue for WhitespaceMode {
4875
5101
 
4876
5102
  impl magnus::TryConvert for WhitespaceMode {
4877
5103
  fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
4878
- let s: String = magnus::TryConvert::try_convert(val)?;
5104
+ // IntoValue emits Symbols, including when this enum is a Hash key.
5105
+ // Accept that exact representation as well as String inputs; do not
5106
+ // coerce arbitrary objects through to_s.
5107
+ let s: String = if let Some(symbol) = magnus::Symbol::from_value(val) {
5108
+ symbol.name()?.into_owned()
5109
+ } else {
5110
+ magnus::TryConvert::try_convert(val)?
5111
+ };
4879
5112
  // Accept the real serde wire value, the legacy always-snake_case symbol Magnus used to
4880
5113
  // emit unconditionally, and the verbatim PascalCase Rust variant name, so fixtures and
4881
5114
  // existing consumer code written in any of those styles keep working.
@@ -6664,6 +6897,7 @@ impl From<ConversionOptions> for html_to_markdown_rs::options::ConversionOptions
6664
6897
  strip_tags: val.strip_tags.into_iter().collect(),
6665
6898
  preserve_tags: val.preserve_tags.into_iter().collect(),
6666
6899
  skip_images: val.skip_images,
6900
+ inline_data_media: val.inline_data_media.into(),
6667
6901
  url_escape_style: val.url_escape_style.into(),
6668
6902
  link_style: val.link_style.into(),
6669
6903
  output_format: val.output_format.into(),
@@ -6675,12 +6909,13 @@ impl From<ConversionOptions> for html_to_markdown_rs::options::ConversionOptions
6675
6909
  max_depth: val.max_depth,
6676
6910
  exclude_selectors: val.exclude_selectors.into_iter().collect(),
6677
6911
  tier_strategy: val.tier_strategy.into(),
6912
+ base_url: val.base_url,
6678
6913
  ..Default::default()
6679
6914
  }
6680
6915
  }
6681
6916
  }
6682
6917
 
6683
- #[allow(clippy::useless_conversion)]
6918
+ #[allow(clippy::redundant_closure, clippy::useless_conversion)]
6684
6919
  impl From<html_to_markdown_rs::options::ConversionOptions> for ConversionOptions {
6685
6920
  fn from(val: html_to_markdown_rs::options::ConversionOptions) -> Self {
6686
6921
  Self {
@@ -6716,6 +6951,7 @@ impl From<html_to_markdown_rs::options::ConversionOptions> for ConversionOptions
6716
6951
  strip_tags: val.strip_tags.into_iter().collect(),
6717
6952
  preserve_tags: val.preserve_tags.into_iter().collect(),
6718
6953
  skip_images: val.skip_images,
6954
+ inline_data_media: val.inline_data_media.into(),
6719
6955
  url_escape_style: val.url_escape_style.into(),
6720
6956
  link_style: val.link_style.into(),
6721
6957
  output_format: val.output_format.into(),
@@ -6727,6 +6963,7 @@ impl From<html_to_markdown_rs::options::ConversionOptions> for ConversionOptions
6727
6963
  max_depth: val.max_depth,
6728
6964
  exclude_selectors: val.exclude_selectors.into_iter().collect(),
6729
6965
  tier_strategy: val.tier_strategy.into(),
6966
+ base_url: val.base_url.map(|v| v.to_string()),
6730
6967
  }
6731
6968
  }
6732
6969
  }
@@ -6767,6 +7004,7 @@ impl From<html_to_markdown_rs::options::ConversionOptionsUpdate> for ConversionO
6767
7004
  strip_tags: val.strip_tags.map(|v| v.into_iter().collect()),
6768
7005
  preserve_tags: val.preserve_tags.map(|v| v.into_iter().collect()),
6769
7006
  skip_images: val.skip_images,
7007
+ inline_data_media: val.inline_data_media.map(Into::into),
6770
7008
  url_escape_style: val.url_escape_style.map(Into::into),
6771
7009
  link_style: val.link_style.map(Into::into),
6772
7010
  output_format: val.output_format.map(Into::into),
@@ -6778,6 +7016,7 @@ impl From<html_to_markdown_rs::options::ConversionOptionsUpdate> for ConversionO
6778
7016
  max_depth: val.max_depth.flatten(),
6779
7017
  exclude_selectors: val.exclude_selectors.map(|v| v.into_iter().collect()),
6780
7018
  tier_strategy: val.tier_strategy.map(Into::into),
7019
+ base_url: val.base_url.flatten().map(|v| v.to_string()),
6781
7020
  }
6782
7021
  }
6783
7022
  }
@@ -7403,6 +7642,26 @@ impl From<html_to_markdown_rs::metadata::ImageType> for ImageType {
7403
7642
  }
7404
7643
  }
7405
7644
 
7645
+ impl From<InlineDataMedia> for html_to_markdown_rs::options::InlineDataMedia {
7646
+ fn from(val: InlineDataMedia) -> Self {
7647
+ match val {
7648
+ InlineDataMedia::Keep => Self::Keep,
7649
+ InlineDataMedia::AltTextOnly => Self::AltTextOnly,
7650
+ InlineDataMedia::DropElement => Self::DropElement,
7651
+ }
7652
+ }
7653
+ }
7654
+
7655
+ impl From<html_to_markdown_rs::options::InlineDataMedia> for InlineDataMedia {
7656
+ fn from(val: html_to_markdown_rs::options::InlineDataMedia) -> Self {
7657
+ match val {
7658
+ html_to_markdown_rs::options::InlineDataMedia::Keep => Self::Keep,
7659
+ html_to_markdown_rs::options::InlineDataMedia::AltTextOnly => Self::AltTextOnly,
7660
+ html_to_markdown_rs::options::InlineDataMedia::DropElement => Self::DropElement,
7661
+ }
7662
+ }
7663
+ }
7664
+
7406
7665
  impl From<LinkStyle> for html_to_markdown_rs::options::LinkStyle {
7407
7666
  fn from(val: LinkStyle) -> Self {
7408
7667
  match val {
@@ -7889,6 +8148,19 @@ impl From<html_to_markdown_rs::options::UrlEscapeStyle> for UrlEscapeStyle {
7889
8148
  }
7890
8149
  }
7891
8150
 
8151
+ #[cfg(feature = "visitor")]
8152
+ impl From<VisitResult> for html_to_markdown_rs::VisitResult {
8153
+ fn from(val: VisitResult) -> Self {
8154
+ match val {
8155
+ VisitResult::Continue => Self::Continue,
8156
+ VisitResult::Custom(_0) => Self::Custom(_0),
8157
+ VisitResult::Skip => Self::Skip,
8158
+ VisitResult::PreserveHtml => Self::PreserveHtml,
8159
+ VisitResult::Error(_0) => Self::Error(_0),
8160
+ }
8161
+ }
8162
+ }
8163
+
7892
8164
  #[cfg(feature = "visitor")]
7893
8165
  impl From<html_to_markdown_rs::VisitResult> for VisitResult {
7894
8166
  fn from(val: html_to_markdown_rs::VisitResult) -> Self {
@@ -8031,6 +8303,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
8031
8303
 
8032
8304
  class.define_method("skip_images", method!(ConversionOptions::skip_images, 0))?;
8033
8305
 
8306
+ class.define_method("inline_data_media", method!(ConversionOptions::inline_data_media, 0))?;
8307
+
8034
8308
  class.define_method("url_escape_style", method!(ConversionOptions::url_escape_style, 0))?;
8035
8309
 
8036
8310
  class.define_method("link_style", method!(ConversionOptions::link_style, 0))?;
@@ -8056,6 +8330,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
8056
8330
 
8057
8331
  class.define_method("tier_strategy", method!(ConversionOptions::tier_strategy, 0))?;
8058
8332
 
8333
+ class.define_method("base_url", method!(ConversionOptions::base_url, 0))?;
8334
+
8059
8335
  let class = module.define_class("ConversionOptionsUpdate", ruby.class_object())?;
8060
8336
 
8061
8337
  class.define_singleton_method("new", function!(ConversionOptionsUpdate::new, -1))?;
@@ -8151,6 +8427,11 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
8151
8427
 
8152
8428
  class.define_method("skip_images", method!(ConversionOptionsUpdate::skip_images, 0))?;
8153
8429
 
8430
+ class.define_method(
8431
+ "inline_data_media",
8432
+ method!(ConversionOptionsUpdate::inline_data_media, 0),
8433
+ )?;
8434
+
8154
8435
  class.define_method(
8155
8436
  "url_escape_style",
8156
8437
  method!(ConversionOptionsUpdate::url_escape_style, 0),
@@ -8185,6 +8466,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
8185
8466
 
8186
8467
  class.define_method("tier_strategy", method!(ConversionOptionsUpdate::tier_strategy, 0))?;
8187
8468
 
8469
+ class.define_method("base_url", method!(ConversionOptionsUpdate::base_url, 0))?;
8470
+
8188
8471
  let class = module.define_class("ConversionResult", ruby.class_object())?;
8189
8472
 
8190
8473
  class.define_singleton_method("new", function!(ConversionResult::new, -1))?;