class

Hwaro::Content::Search

Inherits Reference < Object

Constants

HEADING_ID_ATTR = /\sid\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>"']+))/i
HTML_COMMENT = /<!--.*?-->/m
KNOWN_FIELDS = ["title", "content", "tags", "url", "section", "description"] of ::String

Entry fields the generator knows how to emit; anything else in search.fields is silently skipped, so the manifest's fields list must be filtered the same way.

MANIFEST_FILENAME = "index.json"
MANIFEST_VERSION = 1
ROOT_SHARD_ID = "_root"

Shard id for pages outside every section (content/about.md).

SHARDS_DIR = "search"

Sharded output lives under <output_dir>/search/: one <shard-id>.json per shard plus this manifest. Fixed names (not derived from filename) so a client can discover the layout from a single well-known URL.

SPLIT_HEADING_RE = /<h([23])\b(#{Utils::TextUtils::HTML_TAG_ATTRS_QUOTED_VALUES})>(.*?)<\/h\1\s*>/im

An h2/h3 element of the rendered page, and the id attribute in its attribute list (quote-aware: title="a > b" does not end the tag). split_by_heading cuts the page body at these.

Class methods

entry_fields(config : Models::Config) : Array(String)

The entry keys every emitted entry carries, in emission order: the configured fields (known ones only), then url (always present) and lang (always appended). Exposed for the manifest.

Source
generate(pages : Array(Models::Page), config : Models::Config, output_dir : String, verbose : Bool = false, skip_if_unchanged : Bool = false)
Source
heading_sections(html : String) : Array(NamedTuple(id: String, heading: String, body: String))

The h2/h3 sections of a rendered page body, in document order: each heading's real id (as the page's own anchor links use it), its inner HTML, and the HTML up to the next h2/h3. A heading without an id still ends the previous section but yields no record: it has no anchor to link to.

Source
manifest_path(output_dir : String) : String
Source
published_outputs(config : Models::Config, output_dir : String) : Array(String)

Every file the current config publishes, as it stands on disk after generate ran (or skipped as unchanged): the classic index when a single file is emitted, plus the manifest and each shard it lists. The builder claims these, so a warm --cache build (or a serve rebuild) removes what an earlier config published and this one does not — search.json after single_file = false or a filename change, the search/ tree after shards = "none", everything once search is disabled.

Source
truncate_words(text : String, max : Int32) : String

Truncate text to at most max characters, backing up to the last whitespace inside the cut so no word is split. A run with no whitespace at all (a long URL, untokenized CJK) is cut hard at max. max <= 0 disables truncation.

Source

Nested types