3 use std::process::{Command, Output};
5 fn check_html_file(file: &Path) -> usize {
7 // "disabled" on <link> or "autocomplete" on <select> emit this warning
8 "PROPRIETARY_ATTRIBUTE",
9 // It complains when multiple in the same page link to the same anchor for some reason...
11 // If a <span> contains only HTML elements and no text, it complains about it.
13 // FIXME: the three next warnings are about <pre> elements which are not supposed to
14 // contain HTML. The solution here would be to replace them with a <div>
15 "MISSING_ENDTAG_BEFORE",
17 "DISCARDING_UNEXPECTED",
18 // This error is caused by nesting the Notable Traits tooltip within an <h4> tag.
19 // The solution is to avoid doing that, but we need to have the <h4> tags for accessibility
20 // reasons, and we need the Notable Traits tooltip to help everyone understand the Iterator
24 let to_mute_s = to_mute.join(",");
25 let mut command = Command::new("tidy");
29 .arg("--mute-id") // this option is useful in case we want to mute more warnings
35 let Output { status, stderr, .. } = command.output().expect("failed to run tidy command");
39 let stderr = String::from_utf8(stderr).expect("String::from_utf8 failed...");
40 if stderr.is_empty() && status.code() != Some(2) {
44 "=> Errors for `{}` (error code: {}) <=",
46 status.code().unwrap_or(-1)
48 eprintln!("{}", stderr);
49 stderr.lines().count()
54 const DOCS_TO_CHECK: &[&str] =
55 &["alloc", "core", "proc_macro", "implementors", "src", "std", "test"];
57 // Returns the number of files read and the number of errors.
58 fn find_all_html_files(dir: &Path) -> (usize, usize) {
59 let mut files_read = 0;
62 for entry in walkdir::WalkDir::new(dir).into_iter().filter_entry(|e| {
66 .map(|s| DOCS_TO_CHECK.into_iter().any(|d| *d == s))
69 let entry = entry.expect("failed to read file");
70 if !entry.file_type().is_file() {
73 let entry = entry.path();
74 if entry.extension().and_then(|s| s.to_str()) == Some("html") {
75 errors += check_html_file(&entry);
82 fn main() -> Result<(), String> {
83 let args = env::args().collect::<Vec<_>>();
85 return Err(format!("Usage: {} <doc folder>", args[0]));
88 println!("Running HTML checker...");
90 let (files_read, errors) = find_all_html_files(&Path::new(&args[1]));
91 println!("Done! Read {} files...", files_read);
93 Err(format!("HTML check failed: {} errors", errors))
95 println!("No error found!");