| @@ -71,9 +71,9 @@ pub struct Audit { |
| 71 | 71 | pub link_schemes: BTreeMap<String, Tally>, |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | | /// Names the implementation understands, so the census can flag everything else. These |
| 75 | | /// are the *recognized* sets, not the supported ones: `INCLUDE` is recognized (it is |
| 76 | | /// deliberately inert) while an unlisted keyword is a genuine blind spot. |
| 74 | /// Names the implementation reads by name, so the census can mark everything else. These |
| 75 | /// are the *recognized* sets, not the supported ones: `INCLUDE` is recognized and |
| 76 | /// deliberately inert. |
| 77 | 77 | const KNOWN_KEYWORDS: &[&str] = &[ |
| 78 | 78 | "TITLE", "AUTHOR", "DATE", "EMAIL", "LANGUAGE", "OPTIONS", "FILETAGS", "DESCRIPTION", |
| 79 | 79 | "KEYWORDS", "CAPTION", "NAME", "ATTR_HTML", "RESULTS", "TBLFM", "INCLUDE", "TODO", |
| @@ -97,20 +97,36 @@ const KNOWN_SCHEMES: &[&str] = &[ |
| 97 | 97 | "relative", |
| 98 | 98 | ]; |
| 99 | 99 | |
| 100 | /// The census markers. A name with dedicated handling carries none; `PASS_THROUGH` says |
| 101 | /// nothing reads the name but it works anyway; `UNKNOWN` is the blind-spot signal. |
| 102 | const HANDLED: &str = ""; |
| 103 | const PASS_THROUGH: &str = "\u{2014}"; |
| 104 | const UNKNOWN: &str = "???"; |
| 105 | |
| 100 | 106 | impl Audit { |
| 101 | | /// Is this name one the implementation recognizes? |
| 102 | | pub fn is_known(kind: Census, name: &str) -> bool { |
| 103 | | let known = match kind { |
| 104 | | Census::Keyword => KNOWN_KEYWORDS, |
| 107 | /// How the report marks a census name: the recognized set to look the name up in, |
| 108 | /// and what an unlisted name means for that census. |
| 109 | pub fn marker(kind: Census, name: &str) -> &'static str { |
| 110 | let (known, unlisted) = match kind { |
| 111 | // An unlisted keyword is not a blind spot. Reaching templates as |
| 112 | // `page.keywords.<name>` is the designed behaviour, so every keyword name |
| 113 | // works; what the census reports is which ones have dedicated handling. |
| 114 | // `LEDE`, read by the shipped docs theme's template, was the case that made |
| 115 | // this concrete: `???` on it was a claim about orgo's source, not a gap. |
| 116 | Census::Keyword => (KNOWN_KEYWORDS, PASS_THROUGH), |
| 105 | 117 | // Every block name renders, and renders as org renders it: the names in |
| 106 | 118 | // `block_construct` through dedicated handling, every other name as a special |
| 107 | 119 | // block — a div carrying the name, holding parsed org, which is exactly what |
| 108 | 120 | // org's exporter emits. No block name is a blind spot. |
| 109 | | Census::Block => return true, |
| 110 | | Census::Drawer => KNOWN_DRAWERS, |
| 111 | | Census::Scheme => KNOWN_SCHEMES, |
| 121 | Census::Block => return HANDLED, |
| 122 | Census::Drawer => (KNOWN_DRAWERS, UNKNOWN), |
| 123 | Census::Scheme => (KNOWN_SCHEMES, UNKNOWN), |
| 112 | 124 | }; |
| 113 | | known.iter().any(|k| k.eq_ignore_ascii_case(name)) |
| 125 | if known.iter().any(|k| k.eq_ignore_ascii_case(name)) { |
| 126 | HANDLED |
| 127 | } else { |
| 128 | unlisted |
| 129 | } |
| 114 | 130 | } |
| 115 | 131 | } |
| 116 | 132 | |
| @@ -644,13 +660,9 @@ pub fn report(audit: &Audit) -> String { |
| 644 | 660 | names.sort_by(|a, b| b.1.occurrences.cmp(&a.1.occurrences).then(a.0.cmp(b.0))); |
| 645 | 661 | out.push_str(&format!("\n{title}\n")); |
| 646 | 662 | for (name, tally) in names { |
| 647 | | let flag = if Audit::is_known(kind, name) { |
| 648 | | " " |
| 649 | | } else { |
| 650 | | "??? " |
| 651 | | }; |
| 652 | 663 | out.push_str(&format!( |
| 653 | | "{flag}{:<32} {:>8} {:>7} {}\n", |
| 664 | "{:<4}{:<32} {:>8} {:>7} {}\n", |
| 665 | Audit::marker(kind, name), |
| 654 | 666 | name, |
| 655 | 667 | tally.occurrences, |
| 656 | 668 | tally.files, |
| @@ -658,6 +670,10 @@ pub fn report(audit: &Audit) -> String { |
| 658 | 670 | )); |
| 659 | 671 | } |
| 660 | 672 | } |
| 661 | | out.push_str("\n`???` marks a name the implementation does not recognize at all.\n"); |
| 673 | out.push_str( |
| 674 | "\n`???` marks a name the implementation does not recognize at all.\n\ |
| 675 | `\u{2014}` marks a keyword with no dedicated handling; it reaches templates \ |
| 676 | as `page.keywords.<name>`.\n", |
| 677 | ); |
| 662 | 678 | out |
| 663 | 679 | } |