Skip to main content

Module visibility

Module visibility 

Source
Expand description

Audience visibility filtering: which parts of a document leave.

The gate (prov::exports) decides which documents a site publishes. This decides which regions of one does, filtered against the same audience name, so a body and the site holding it can never disagree about who a paragraph is for.

§A region is a container

Every grammar spells a marked region as one node, and twig parses all three into the same AST kind — a container with a name, a class list and children:

GrammarSpellingnameclasses
Markdown:::vis{.family}:::"vis"family
Markdown (inline):vis[text]{.family}"vis"family
Djot{.vis .family} on the line above :::""vis family
HTML<div class="vis family">"div"vis family

So the predicate is uniform and needs no per-grammar branch: a region is a container named vis, or one whose classes contain vis, and its declared audiences are its classes, less vis itself. That is why a Djot body and a Markdown body filter through one function rather than two that agree until one of them is fixed.

§Why the parser and not a scanner

This module used to scan text for :::vis{…} and :vis[…]{…} without parsing it, which was grammar-blind on purpose — one scanner for three grammars. It was also blind to everything else, and the cost was a disclosure bug: a marker inside a code span (`:::vis{.family}`, in a document explaining the syntax) was treated as a real directive, and a real directive whose fence a list had indented was not.

twig parses the body it is going to render anyway, so the spans are available for free and they are the spans the renderer will agree with. prov re-exports twig for exactly this (prov::twig).

§Fail-closed

Filtering is a disclosure boundary, so every way this can fail ends with less leaving rather than more. A body whose grammar cannot be parsed, a region this cannot account for, a marker left standing after the walk — all are Error, never a body returned unfiltered. See Error for why the residue check exists at all.

Enums§

Audience
Who the filtered body is for.
Error
Why a body could not be filtered.

Constants§

MARKER
The class — and, in Markdown, the directive name — that marks a region as audience-scoped.

Functions§

filter_body
Filter body to the regions audience may see.
has_visibility_directives
Cheap pre-check: is it even worth parsing this body?