{{- /* fragments.html - Split page content into searchable fragments This partial processes a Hugo page and splits its content into fragments based on headings, creating a data structure suitable for search indexing. It supports different fragment types and handles hierarchical heading structures (h1, h2). Parameters: - .context (Page): The Hugo page to process - .type (string): Fragment type - "content" (default), "heading", "title", or "summary" Returns: - dict: Map of heading keys to content fragments Example: Input page with content: # Introduction This is the intro text. ## Setup Setup instructions here. # Configuration Config details here. Output (type "content"): { "": "This is the intro text.", "intro#Introduction": "This is the intro text. Setup instructions here.", "setup#Setup": "Setup instructions here.", "config#Configuration": "Config details here." } Fragment types: - "content": Splits page content by headings (default) - "heading": Returns heading keys with empty content - "title": Returns empty content (title handled elsewhere) - "summary": Returns page summary only */ -}} {{- /* Extract page context and fragment type */ -}} {{- $page := .context -}} {{- $type := .type | default "content" -}} {{- /* Initialize slices to store heading data */ -}} {{- $headingKeys := slice -}} {{- /* Keys for indexing (ID#Title or just Title) */ -}} {{- $headingTitles := slice -}} {{- /* HTML heading tags for content splitting */ -}} {{- /* Process all h1 headings and their nested h2 headings */ -}} {{- range $h1 := $page.Fragments.Headings -}} {{- /* Handle h1 headings - empty titles get special treatment */ -}} {{- if eq $h1.Title "" -}} {{- $headingKeys = $headingKeys | append $h1.Title -}} {{- else -}} {{- $headingKeys = $headingKeys | append (printf "%s#%s" $h1.ID $h1.Title) -}} {{- end -}} {{- $headingTitles = $headingTitles | append (printf "

%s" $h1.Title) -}} {{- /* Process nested h2 headings */ -}} {{- range $h2 := $h1.Headings -}} {{- $headingKeys = $headingKeys | append (printf "%s#%s" $h2.ID $h2.Title) -}} {{- $headingTitles = $headingTitles | append (printf "

%s" $h2.Title) -}} {{- end -}} {{- end -}} {{- $content := $page.Content | htmlUnescape -}} {{- $len := len $headingKeys -}} {{- $data := dict -}} {{ if eq $type "content" }} {{/* Include full content of the page */}} {{ if eq $len 0 }} {{ $data = $data | merge (dict "" ($page.Plain | htmlUnescape | strings.TrimSpace)) }} {{ else }} {{/* Split the raw content from bottom to top */}} {{ range seq $len }} {{ $i := sub $len . }} {{ $headingKey := index $headingKeys $i }} {{ $headingTitle := index $headingTitles $i }} {{ if eq $i 0 }} {{ $data = $data | merge (dict $headingKey ($content | plainify | htmlUnescape | strings.TrimSpace)) }} {{ else }} {{ $parts := split $content (printf "%s" $headingTitle) }} {{ $lastPart := index $parts (sub (len $parts) 1) | strings.TrimSpace }} {{ $data = $data | merge (dict $headingKey ($lastPart | plainify | htmlUnescape | strings.TrimSpace)) }} {{ $content = strings.TrimSuffix $lastPart $content }} {{ $content = strings.TrimSuffix (printf "%s" $headingTitle) $content }} {{ end }} {{ end }} {{ end }} {{ else if (eq $type "heading" ) }} {{/* Put heading keys with empty content to the data object */}} {{ $data = dict "" "" }} {{ range $headingKeys }} {{ $data = $data | merge (dict . "") }} {{ end }} {{ else if (eq $type "title") }} {{/* Use empty data object since title is included in search-data.json */}} {{ $data = $data | merge (dict "" "") }} {{ else if (eq $type "summary" ) }} {{ $data = $data | merge (dict "" ($page.Summary | plainify | htmlUnescape | strings.TrimSpace)) }} {{ end }} {{ return $data }}