-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathmain.rs
More file actions
179 lines (145 loc) Β· 6.41 KB
/
main.rs
File metadata and controls
179 lines (145 loc) Β· 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
use colored::*;
use regex::Regex;
use std::fs;
use std::path::Path;
use walkdir::WalkDir;
/// Check if a URL should be excluded from localization
fn should_exclude_url(url: &str, locale: &str) -> bool {
url.starts_with(&format!("/{}/", locale)) ||
url.starts_with("http") ||
url.starts_with("#") ||
url.ends_with(".txt")
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("{}", "π§ Fixing localized documentation links...".bright_cyan());
let docs_dir = Path::new("./src/content/docs");
if !docs_dir.exists() {
eprintln!("{}", "β Error: Docs directory not found at ./src/content/docs".red());
std::process::exit(1);
}
let mut total_files = 0;
let mut modified_files = 0;
let mut total_links_fixed = 0;
// Smart locale detection - matches 2-letter codes with optional country codes
let locale_regex = Regex::new(r"^[a-z]{2}(-[A-Z]{2})?$")?;
// Regex to find markdown links that need fixing
let link_regex = Regex::new(r"\[([^\]]*)\]\((/[^)#][^)]*)\)")?;
// Regex to find LinkCard href attributes that need fixing
let linkcard_regex = Regex::new(
r##"(<LinkCard\s+[^>]*href=")(/[^"#][^"]*)"([^>]*>)"##
)?;
// Auto-discover locale directories
let mut locales = Vec::new();
for entry in fs::read_dir(docs_dir)? {
let entry = entry?;
let path = entry.path();
if !path.is_dir() {
continue;
}
let locale = path.file_name()
.and_then(|n| n.to_str())
.unwrap_or("");
if locale_regex.is_match(locale) {
locales.push((locale.to_string(), path));
}
}
if locales.is_empty() {
println!("{}", "βΉοΈ No locale directories found (looking for 2-letter locale folders like zh)".yellow());
return Ok(());
}
// Sort locales for consistent output
locales.sort_by(|a, b| a.0.cmp(&b.0));
// Process each detected locale
for (locale, locale_path) in locales {
println!("{} {}", "π Processing locale:".bright_green(), locale.bright_white());
let mut locale_files = 0;
let mut locale_modified = 0;
let mut locale_links_fixed = 0;
// Process all .mdx files in this locale
for entry in WalkDir::new(&locale_path).into_iter().filter_map(|e| e.ok()) {
let file_path = entry.path();
if !file_path.extension().map_or(false, |ext| ext == "mdx") {
continue;
}
total_files += 1;
locale_files += 1;
let content = match fs::read_to_string(file_path) {
Ok(content) => content,
Err(e) => {
eprintln!(" {} Failed to read {}: {}", "β οΈ".yellow(), file_path.display(), e);
continue;
}
};
let mut modified = false;
let mut links_fixed_in_file = 0;
// First, fix markdown links
let content_after_markdown = link_regex.replace_all(&content, |caps: ®ex::Captures| {
let text = &caps[1];
let url = &caps[2];
// Skip if URL should be excluded from localization
if should_exclude_url(url, &locale) {
return caps[0].to_string();
}
// Fix the link by adding locale prefix
modified = true;
links_fixed_in_file += 1;
format!("[{}](/{}{})", text, locale, url)
});
// Then, fix LinkCard href attributes
let new_content = linkcard_regex.replace_all(&content_after_markdown, |caps: ®ex::Captures| {
let before = &caps[1];
let url = &caps[2];
let after = &caps[3];
// Skip if URL should be excluded from localization
if should_exclude_url(url, &locale) {
return caps[0].to_string();
}
// Fix the LinkCard href by adding locale prefix
modified = true;
links_fixed_in_file += 1;
format!("{}/{}{}\"{}", before, locale, url, after)
});
if modified {
match fs::write(file_path, new_content.as_ref()) {
Ok(_) => {
modified_files += 1;
locale_modified += 1;
total_links_fixed += links_fixed_in_file;
locale_links_fixed += links_fixed_in_file;
let filename = file_path.file_name().unwrap().to_str().unwrap();
println!(" {} Fixed {} links in: {}",
"β
".green(),
links_fixed_in_file.to_string().bright_yellow(),
filename.bright_white()
);
}
Err(e) => {
eprintln!(" {} Failed to write {}: {}", "β".red(), file_path.display(), e);
}
}
}
}
if locale_files > 0 {
println!(" {} Locale summary: {}/{} files modified, {} links fixed ",
"π".bright_blue(),
locale_modified.to_string().bright_yellow(),
locale_files.to_string().bright_white(),
locale_links_fixed.to_string().bright_yellow()
);
} else {
println!(" {} No .mdx files found in {}", "βΉοΈ".yellow(), locale);
}
println!();
}
println!("{}", "π Locale link fixing complete!".bright_green());
println!("{}", "π Overall Summary:".bright_blue());
println!(" - Total files processed: {}", total_files.to_string().bright_white());
println!(" - Total files modified: {}", modified_files.to_string().bright_yellow());
println!(" - Total links fixed: {}", total_links_fixed.to_string().bright_green());
println!();
println!("{}", "π‘ Run pnpm build to verify the fixes resolved all locale inconsistency errors.".bright_cyan());
if total_links_fixed == 0 {
println!("All locale links are already correct!");
}
Ok(())
}