krz/orgo
Lightning fast org-mode static site generator.
clone: git clone https://gitbay.org/krz/orgo.git
ce3f2623d5c9eede9c2179aa21afcdf1a4fea05e
signed_unknown_key
author: Christian Cleberg <hello@cleberg.net> · 2026-08-23T04:39:33Z
committer: <noreply@github.com>
docs/guide/09-auditing.org | 14 +++++--------- src/audit.rs | 26 +++++++++----------------- tests/constructs.rs | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 26 deletions(-) @@ -26,26 +26,22 @@ IN heading 1148 176 blog/2018-11-28-aes-encr IN verbatim 1048 130 blog/2018-11-28-aes-encryption.org:79 ... IN table formula (#+TBLFM:) 4 1 blog/2024-08-11-org-mode-features.org:191 -OUT unmodelled block type 1 1 blog/2026-03-03-auditing-aws-s3.org:50 +IN special block 1 1 blog/2026-03-03-auditing-aws-s3.org:50 -coverage: 9001 in-scope use(s) (100.0%), 1 out-of-scope (0.0%) +coverage: 9002 in-scope use(s) (100.0%), 0 out-of-scope (0.0%) KEYWORDS SLUG 180 180 blog/2018-11-28-aes-encryption.org:4 TITLE 180 180 blog/2018-11-28-aes-encryption.org:2 ... - -BLOCK TYPES - SRC 941 123 blog/2018-11-28-cpp-compiler.org:17 - QUOTE 115 48 blog/2018-11-28-aes-encryption.org:21 -??? NOTE 1 1 blog/2026-03-03-auditing-aws-s3.org:50 #+END_EXAMPLE - =IN= is supported; =OUT= is excluded by design and degrades as described in [[file:05-org-support.org][Org support]]. - The *coverage* line is the number to look at first. -- =???= marks a name orgo does not recognise at all — here =#+begin_note=, which one - post uses once. That is the blind-spot signal: not "known unsupported", but unknown. +- =???= marks a name orgo does not recognise at all. That is the blind-spot signal — + not "known unsupported", but unknown — and this corpus has none. Block names never + carry it: an unrecognised one is still a special block, and still renders. Four censuses follow the construct table: every distinct =#+KEYWORD:=, block type, drawer name and link scheme in the corpus. A =???= in any of them is worth a look. @@ -83,12 +83,6 @@ const KNOWN_KEYWORDS: &[&str] = &[ // Leaving them out reported the corpus's most-used keyword as unrecognized. "SLUG", "DRAFT", "TEMPLATE", ]; -/// Blocks with dedicated handling. Any *other* name renders as a special block — a div -/// with that name holding parsed org — so an unlisted block is a note about what a corpus -/// contains rather than a construct that will be lost. -const KNOWN_BLOCKS: &[&str] = &[ - "SRC", "QUOTE", "EXAMPLE", "CENTER", "EXPORT", "VERSE", "COMMENT", -]; const KNOWN_DRAWERS: &[&str] = &["PROPERTIES", "LOGBOOK", "END"]; /// Keyword names conventional enough to be worth flagging when they lead a heading. /// A custom sequence is only *real* if some `#+TODO:` declares it, which the census @@ -107,7 +101,11 @@ impl Audit { pub fn is_known(kind: Census, name: &str) -> bool { let known = match kind { Census::Keyword => KNOWN_KEYWORDS, - Census::Block => KNOWN_BLOCKS, + // Every block name renders, and renders as org renders it: the names in + // `block_construct` through dedicated handling, every other name as a special + // block — a div carrying the name, holding parsed org, which is exactly what + // org's exporter emits. No block name is a blind spot. + Census::Block => return true, Census::Drawer => KNOWN_DRAWERS, Census::Scheme => KNOWN_SCHEMES, }; @@ -198,7 +196,7 @@ impl Audit { if let Some(rest) = trimmed.to_ascii_uppercase().strip_prefix("#+BEGIN_") { let kind = rest.split_whitespace().next().unwrap_or("").to_string(); self.count_census(Census::Block, &kind, &at); - self.count(scope_of_block(&kind), block_construct(&kind), &at); + self.count(Scope::In, block_construct(&kind), &at); if trimmed.to_ascii_uppercase().contains(":RESULTS") { self.count(Scope::Out, "babel header args (:results)", &at); } @@ -440,14 +438,6 @@ fn is_drawer(trimmed: &str) -> bool { && t.len() > 2 } -fn scope_of_block(kind: &str) -> Scope { - if KNOWN_BLOCKS.iter().any(|k| k.eq_ignore_ascii_case(kind)) { - Scope::In - } else { - Scope::Out - } -} - fn block_construct(kind: &str) -> &'static str { match kind.to_ascii_uppercase().as_str() { "SRC" => "source block", @@ -455,7 +445,9 @@ fn block_construct(kind: &str) -> &'static str { "EXAMPLE" => "example block", "CENTER" => "center block", "EXPORT" => "export block", - _ => "unmodelled block type", + "VERSE" => "verse block", + "COMMENT" => "comment block", + _ => "special block", } } @@ -816,3 +816,24 @@ fn audit_counts_table_formulas_as_in_scope() { "a #+TBLFM: table orgo renders exactly as Emacs does must not read as a gap:\n{line}" ); } + +/// A block name with no dedicated handling is a special block, which org itself renders +/// as a div carrying the name — `fixtures/blocks.org` holds `#+BEGIN_NOTE` and is in the +/// Emacs oracle. So it is neither out of scope nor a `???` blind spot. +#[test] +fn audit_counts_special_blocks_as_in_scope() { + let report = audit_fixture("blocks.org"); + let line = report + .lines() + .find(|l| l.contains("special block")) + .expect("the NOTE block is counted as a special block"); + assert!( + line.starts_with("IN "), + "a block orgo renders exactly as Emacs does must not read as a gap:\n{line}" + ); + let flagged: Vec<&str> = report.lines().filter(|l| l.starts_with("???")).collect(); + assert!( + flagged.is_empty(), + "no block name is unrecognised — every one renders: {flagged:?}" + ); +}