rumdl_lib/utils/anchor_styles/
mod.rs1pub mod common;
16pub mod github;
17pub mod kramdown;
18pub mod kramdown_gfm; pub mod python_markdown;
20
21use serde::{Deserialize, Serialize};
22
23#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
25#[serde(rename_all = "kebab-case")]
26#[derive(Default)]
27pub enum AnchorStyle {
28 #[default]
30 #[serde(rename = "github")]
31 GitHub,
32 #[serde(rename = "kramdown-gfm", alias = "kramdown_gfm", alias = "jekyll")]
35 KramdownGfm,
36 #[serde(rename = "kramdown")]
38 Kramdown,
39 #[serde(rename = "python-markdown", alias = "python_markdown", alias = "mkdocs")]
41 PythonMarkdown,
42}
43
44impl AnchorStyle {
45 pub fn generate_fragment(&self, heading: &str) -> String {
47 match self {
48 AnchorStyle::GitHub => github::heading_to_fragment(heading),
49 AnchorStyle::KramdownGfm => kramdown_gfm::heading_to_fragment(heading),
50 AnchorStyle::Kramdown => kramdown::heading_to_fragment(heading),
51 AnchorStyle::PythonMarkdown => python_markdown::heading_to_fragment(heading),
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn test_anchor_style_serde() {
62 assert_eq!(serde_json::to_string(&AnchorStyle::GitHub).unwrap(), "\"github\"");
64 assert_eq!(
65 serde_json::to_string(&AnchorStyle::KramdownGfm).unwrap(),
66 "\"kramdown-gfm\""
67 );
68 assert_eq!(serde_json::to_string(&AnchorStyle::Kramdown).unwrap(), "\"kramdown\"");
69 assert_eq!(
70 serde_json::to_string(&AnchorStyle::PythonMarkdown).unwrap(),
71 "\"python-markdown\""
72 );
73
74 assert_eq!(
76 serde_json::from_str::<AnchorStyle>("\"github\"").unwrap(),
77 AnchorStyle::GitHub
78 );
79 assert_eq!(
80 serde_json::from_str::<AnchorStyle>("\"kramdown-gfm\"").unwrap(),
81 AnchorStyle::KramdownGfm
82 );
83 assert_eq!(
84 serde_json::from_str::<AnchorStyle>("\"kramdown\"").unwrap(),
85 AnchorStyle::Kramdown
86 );
87 assert_eq!(
88 serde_json::from_str::<AnchorStyle>("\"python-markdown\"").unwrap(),
89 AnchorStyle::PythonMarkdown
90 );
91
92 assert_eq!(
94 serde_json::from_str::<AnchorStyle>("\"kramdown_gfm\"").unwrap(),
95 AnchorStyle::KramdownGfm
96 );
97 assert_eq!(
98 serde_json::from_str::<AnchorStyle>("\"python_markdown\"").unwrap(),
99 AnchorStyle::PythonMarkdown
100 );
101
102 assert_eq!(
104 serde_json::from_str::<AnchorStyle>("\"jekyll\"").unwrap(),
105 AnchorStyle::KramdownGfm
106 );
107 assert_eq!(
108 serde_json::from_str::<AnchorStyle>("\"mkdocs\"").unwrap(),
109 AnchorStyle::PythonMarkdown
110 );
111 }
112
113 #[test]
114 fn test_anchor_style_differences() {
115 let test_cases = [
116 "cbrown --> sbrown: --unsafe-paths",
117 "Update login_type",
118 "Test---with---multiple---hyphens",
119 "API::Response > Error--Handling",
120 ];
121
122 for case in test_cases {
123 let github = AnchorStyle::GitHub.generate_fragment(case);
124 let kramdown_gfm = AnchorStyle::KramdownGfm.generate_fragment(case);
125 let kramdown = AnchorStyle::Kramdown.generate_fragment(case);
126 let python_md = AnchorStyle::PythonMarkdown.generate_fragment(case);
127
128 assert!(!github.is_empty(), "GitHub style failed for: {case}");
130 assert!(!kramdown_gfm.is_empty(), "KramdownGfm style failed for: {case}");
131 assert!(!kramdown.is_empty(), "Kramdown style failed for: {case}");
132 assert!(!python_md.is_empty(), "PythonMarkdown style failed for: {case}");
133 }
134 }
135}