Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

SUMMARY.md Generation

Loading…

SUMMARY.md Generation

Relevant source files

Purpose and Scope

This document explains how the SUMMARY.md file is dynamically generated from the scraped markdown content structure. The SUMMARY.md file serves as mdBook’s table of contents, defining the navigation structure and page hierarchy for the generated HTML documentation.

For information about how the markdown files are initially organized during scraping, see Wiki Structure Discovery. For details about the overall mdBook build configuration, see Configuration Generation.

SUMMARY.md in mdBook

The SUMMARY.md file is mdBook’s primary navigation document. It defines:

  • The order of pages in the documentation
  • The hierarchical structure (chapters and sub-chapters)
  • The titles displayed in the navigation sidebar
  • Which markdown files map to which sections

mdBook parses SUMMARY.md to construct the entire book structure. Pages not listed in SUMMARY.md will not be included in the generated documentation.

Sources: build-docs.sh:108-161

Generation Process Overview

The SUMMARY.md generation occurs in Step 3 of the build pipeline build-docs.sh:124-188 after markdown extraction is complete but before the mdBook build begins. The generation algorithm automatically discovers the file structure, applies numeric sorting to section files, and constructs a hierarchical table of contents.

SUMMARY.md Generation Pipeline

flowchart TD
    Start["Start Step 3:\nbuild-docs.sh:126"]
Init["Write Header:\necho '# Summary'\nLines 129-131"]
ListFiles["List all files:\nmain_pages_list=$(ls $WIKI_DIR/*.md)"]
FindOverview["Find overview_file:\ngrep -Ev '^[0-9]' /head -1 Lines 136-138"]
HasOverview{"overview_file exists?"}
ExtractOvTitle["Extract title: head -1/ sed 's/^# //'\nLine 140"]
WriteOv["Write: [{title}]($overview_file)\nLines 141-143"]
RemoveOv["Filter overview_file from list\nLine 143"]
NumericSort["Numeric Sort:\ngrep -E '^[0-9]' /sort -t- -k1 -n Lines 147-155"]
IterateMain["for file in main_pages Line 158"]
ExtractTitle["title=$ head -1/ sed 's/^# //')"]
ExtractSecNum["section_num=$(grep -oE '^[0-9]+')"]
CheckSecDir{"[ -d section-$section_num ]"}
WriteSec["echo '- [$title]($filename)'\nLine 171"]
IterateSub["ls section-$section_num/*.md /sort -t- -k1 -n Lines 174-180"]
WriteSub["echo ' - [$subtitle] section-$section_num/$subfilename '"]
WriteStandalone["echo '- [$title] $filename ' Line 183"]
Complete["Redirect to: src/SUMMARY.md Line 186"]
LogCount["Log entry count: grep -c '\\[' src/SUMMARY.md Line 188"]
End["End Step 3"]
Start --> Init
 Init --> ListFiles
 ListFiles --> FindOverview
 FindOverview --> HasOverview
 HasOverview -->|Yes|ExtractOvTitle
 ExtractOvTitle --> WriteOv
 WriteOv --> RemoveOv
 RemoveOv --> NumericSort
 HasOverview -->|No|NumericSort
 NumericSort --> IterateMain
 IterateMain --> ExtractTitle
 ExtractTitle --> ExtractSecNum
 ExtractSecNum --> CheckSecDir
 CheckSecDir -->|Yes: Has subsections|WriteSec
 WriteSec --> IterateSub
 IterateSub --> WriteSub
 WriteSub --> IterateMain
 CheckSecDir -->|No: Standalone|WriteStandalone
 WriteStandalone --> IterateMain
 IterateMain -->|Done| Complete
 
   Complete --> LogCount
 
   LogCount --> End

Sources: build-docs.sh:124-188

The algorithm executes three key phases:

PhaseLinesDescription
Overview Extraction133-145Identifies and writes non-numbered introduction page
Numeric Sorting147-155Sorts numbered pages by numeric prefix using sort -t- -k1 -n
Hierarchical Writing158-185Iterates sorted pages, detecting and nesting subsections

Sources: build-docs.sh:124-188

Algorithm Components

Step 1: Overview File Selection

The algorithm identifies a special overview file by searching for files without numeric prefixes. This file becomes the introduction page, written before the numbered sections.

Overview File Detection Algorithm

flowchart TD
    Start["main_pages_list =\nls $WIKI_DIR/*.md"]
Filter["overview_file =\nawk -F/ '{print $NF}' /grep -Ev '^[0-9]'/\nhead -1"]
Check{"overview_file\nnot empty?"}
Verify{"File exists?\n[ -f $WIKI_DIR/$overview_file ]"}
Extract["title=$(head -1 $WIKI_DIR/$overview_file /sed 's/^# //'"]
Write["echo '[{title:-Overview}] $overview_file ' echo ''"]
Remove["main_pages_list = grep -v $overview_file"]
Continue["Proceed to numeric sorting"]
Start --> Filter
 Filter --> Check
 Check -->|Yes|Verify
 Check -->|No|Continue
 Verify -->|Yes|Extract
 Verify -->|No| Continue
 
   Extract --> Write
 
   Write --> Remove
 
   Remove --> Continue

Sources: build-docs.sh:133-145

Detection Logic:

StepCommandPurposeExample
List filesls "$WIKI_DIR"/*.mdGet all root markdown filesOverview.md 1-intro.md 2-start.md
Extract basenameawk -F/ '{print $NF}'Get filename onlyOverview.md
Filter non-numericgrep -Ev '^[0-9]'Exclude numbered filesOverview.md (matches)
Take firsthead -1Select single overviewOverview.md
Extract title`head -1sed ‘s/^# //’`Get page title

The overview file is then excluded from main_pages_list before numeric sorting build-docs.sh143

Sources: build-docs.sh:133-145

Step 2: Numeric Sorting Pipeline

After overview extraction, remaining files are sorted numerically by their leading number prefix. This ensures pages appear in logical order (e.g., 2-start.md before 10-advanced.md).

Numeric Sorting Implementation

flowchart LR
    Input["main_pages_list\n(filtered from overview)"]
Basename["awk -F/ '{print $NF}'\nExtract filename"]
GrepNum["grep -E '^[0-9]'\nKeep only numbered files"]
NumSort["sort -t- -k1 -n\nNumeric sort on first field"]
Reconstruct["while read fname; do\n echo $WIKI_DIR/$fname\ndone"]
Output["main_pages\n(sorted file paths)"]
Input --> Basename
 
   Basename --> GrepNum
 
   GrepNum --> NumSort
 
   NumSort --> Reconstruct
 
   Reconstruct --> Output

Sources: build-docs.sh:147-155

Sort Command Breakdown:

FlagPurposeExample Effect
-t-Set delimiter to -Split 10-advanced.md into 10 and advanced.md
-k1Sort by field 1Use 10 as sort key
-nNumeric comparison2 sorts before 10 (not lexicographic)

Example Sorting:

Unsorted FilenamesNumeric SortOutput Order
10-advanced.mdExtract 101-overview.md
2-start.mdExtract 22-start.md
1-overview.mdExtract 15-components.md
5-components.mdExtract 510-advanced.md

Sources: build-docs.sh:147-155

Step 3: Subsection Detection and Iteration

For each main page, the algorithm extracts the numeric prefix (section_num) and checks for a corresponding section-N/ directory. If found, all subsection files are written with 2-space indentation.

Subsection Detection and Writing Flow

flowchart TD
    LoopStart["for file in main_pages\nLine 158"]
FileCheck["[ -f $file ] // continue"]
GetBasename["filename=$(basename $file)"]
ExtractTitle["title=$(head -1 $file /sed 's/^# //' Line 163"]
ExtractNum["section_num=$ echo $filename/\ngrep -oE '^[0-9]+' // true)\nLine 166"]
BuildPath["section_dir=$WIKI_DIR/section-$section_num\nLine 167"]
CheckBoth{"[ -n $section_num ] &&\n[ -d $section_dir ]"}
WriteMain["echo '- [$title]($filename)'\nLine 171"]
ListSubs["ls $section_dir/*.md 2>/dev/null /awk -F/ '{print $NF}'/\nsort -t- -k1 -n\nLines 174-175"]
SubLoop["while read subname\nLine 174"]
SubCheck["[ -f $section_dir/$subname ] // continue"]
SubBasename["subfilename=$(basename $subfile)"]
SubTitle["subtitle=$(head -1 $subfile /sed 's/^# //' Line 178"]
SubWrite["echo ' - [$subtitle] section-$section_num/$subfilename ' Line 179"]
WriteStandalone["echo '- [$title] $filename ' Line 183"]
NextFile["Continue loop"]
LoopStart --> FileCheck
 FileCheck --> GetBasename
 GetBasename --> ExtractTitle
 ExtractTitle --> ExtractNum
 ExtractNum --> BuildPath
 BuildPath --> CheckBoth
 CheckBoth -->|Yes: Has subsections|WriteMain
 WriteMain --> ListSubs
 ListSubs --> SubLoop
 SubLoop --> SubCheck
 SubCheck --> SubBasename
 SubBasename --> SubTitle
 SubTitle --> SubWrite
 SubWrite --> SubLoop
 SubLoop -->|Done|NextFile
 CheckBoth -->|No: Standalone| WriteStandalone
 
   WriteStandalone --> NextFile
    
 
   NextFile --> LoopStart

Sources: build-docs.sh:158-185

Variable Mapping:

VariableTypePurposeExample Value
filenameStringMain page filename5-component-reference.md
titleStringMain page titleComponent Reference
section_numStringNumeric prefix5
section_dirPathSubsection directory/workspace/wiki/section-5
subfilenameStringSubsection filename5.1-build-docs.md
subtitleStringSubsection titlebuild-docs.sh Orchestrator

Sources: build-docs.sh:158-185

Step 4: Subsection Numeric Sorting

Subsection files within section-N/ directories undergo the same numeric sorting as main pages, ensuring proper ordering (e.g., 5.2 before 5.10).

Subsection Sorting Pipeline

flowchart LR
    Dir["section_dir/\nsection-5/"]
List["ls $section_dir/*.md 2>/dev/null"]
Awk["awk -F/ '{print $NF}'"]
Sort["sort -t- -k1 -n"]
Loop["while read subname"]
Verify["[ -f $subfile ] // continue"]
Extract["subtitle=$(head -1 / sed 's/^# //')"]
Write["echo ' - [$subtitle](section-N/$subfilename)'"]
Dir --> List
 
   List --> Awk
 
   Awk --> Sort
 
   Sort --> Loop
 
   Loop --> Verify
 
   Verify --> Extract
 
   Extract --> Write
 
   Write --> Loop

Sources: build-docs.sh:174-180

Key Implementation Details:

AspectImplementationPurpose
Indentationecho " - <FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/$subtitle" undefined file-path="$subtitle">Hii</FileRef>"Two spaces for mdBook nesting
Path prefixsection-$section_num/$subfilenameCorrect relative path for mdBook
Numeric sortsort -t- -k1 -nSame algorithm as main pages
Title extraction`head -1sed ‘s/^# //’`

Sorting Example:

Input files:        After sort:         SUMMARY.md output:
section-5/          section-5/          - <FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/Component Reference" undefined  file-path="Component Reference">Hii</FileRef>
├── 5.10-tools.md   ├── 5.1-build.md      - <FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/build-docs.sh" undefined  file-path="build-docs.sh">Hii</FileRef>
├── 5.2-scraper.md  ├── 5.2-scraper.md    - <FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/Scraper" undefined  file-path="Scraper">Hii</FileRef>
└── 5.1-build.md    └── 5.10-tools.md     - <FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/Tools" undefined  file-path="Tools">Hii</FileRef>

Sources: build-docs.sh:174-180

File Structure Conventions

The generation algorithm depends on the file structure created during markdown extraction (see Wiki Structure Discovery):

Diagram: File Structure Conventions for SUMMARY.md Generation

PatternLocationSUMMARY.md Output
*.mdRoot directoryMain pages
N-*.mdRoot directoryMain section (if section-N/ exists)
*.mdsection-N/ directorySubsections (indented under section N)

Sources: build-docs.sh:126-158

Title Extraction Method

All page titles are extracted using a consistent pattern:

This assumes that every markdown file begins with a level-1 heading (# Title). The sed command removes the # prefix, leaving only the title text.

Extraction Pipeline:

CommandPurposeExample InputExample Output
head -1 "$file"Get first line# Component Reference# Component Reference
sed 's/^# //'Remove heading syntax# Component ReferenceComponent Reference

Sources: build-docs.sh120 build-docs.sh134 build-docs.sh150

Output Format

The generated SUMMARY.md follows mdBook’s syntax:

Format Rules:

ElementSyntaxPurpose
Header# SummaryRequired mdBook header
Introduction<FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/Title" undefined file-path="Title">Hii</FileRef>First page (no bullet)
Main Page- <FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/Title" undefined file-path="Title">Hii</FileRef>Top-level navigation item
Section Header# Section NameVisual grouping in sidebar
Subsection - <FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/Title" undefined file-path="Title">Hii</FileRef>Nested under main section (2-space indent)

Sources: build-docs.sh:113-159

flowchart TD
    Step3["Step 3 Comment\nLine 124-126"]
Header["Write Header Block\nLines 129-131\n{\n echo '# Summary'\n echo ''\n}"]
Overview["Overview Detection\nLines 133-145\nmain_pages_list=$(ls)\noverview_file=$(grep -Ev '^[0-9]')\nif [ -n $overview_file ]; then\n title=$(head -1)\n echo '[$title]($overview_file)'\n main_pages_list=$(grep -v $overview_file)\nfi"]
NumSort["Numeric Sort Block\nLines 147-155\nmain_pages=$(\n printf '%s' $main_pages_list\n /awk -F/ '{print $NF}'/ grep -E '^[0-9]'\n /sort -t- -k1 -n/ while read fname; do\n echo $WIKI_DIR/$fname\n done\n)"]
MainLoop["Main Page Loop\nLines 158-185\necho $main_pages /while read file do filename=$ basename $file title=$ head -1/ sed 's/^# //')\n section_num=$(grep -oE '^[0-9]+')\n section_dir=$WIKI_DIR/section-$section_num\n if [ -n $section_num ] && [ -d $section_dir ]; then\n ...\n fi\ndone"]
Subsection["Subsection Block\nLines 174-180\nls $section_dir/*.md\n /awk -F/ '{print $NF}'/ sort -t- -k1 -n\n / while read subname; do\n subtitle=$(head -1)\n echo ' - [$subtitle](...)'\n done"]
Redirect["Output Redirection\nLine 186\n} > src/SUMMARY.md"]
Log["Entry Count Log\nLine 188\necho 'Generated SUMMARY.md with\n$(grep -c '\\[' src/SUMMARY.md)
entries'"]
Step3 --> Header
 
   Header --> Overview
 
   Overview --> NumSort
 
   NumSort --> MainLoop
 
   MainLoop --> Subsection
 
   Subsection --> MainLoop
 
   MainLoop --> Redirect
 
   Redirect --> Log

Implementation Code Mapping

The SUMMARY.md generation is implemented in a single contiguous block within build-docs.sh. The following diagram maps algorithm phases to specific line ranges:

Code Structure and Execution Flow

Sources: build-docs.sh:124-188

Shell Variable Reference:

VariableScopeTypeInitializationExample Value
WIKI_DIRGlobalPathLine 28/workspace/wiki
main_pages_listLocalStringLine 135Multi-line list of paths
overview_fileLocalStringLine 138Overview.md
main_pagesLocalStringLine 147Sorted, newline-separated paths
filenameLoopStringLine 1605-component-reference.md
titleLoopStringLine 163Component Reference
section_numLoopStringLine 1665
section_dirLoopPathLine 167/workspace/wiki/section-5
subfilenameNested LoopStringLine 1775.1-build-docs.md
subtitleNested LoopStringLine 178build-docs.sh Orchestrator

Sources: build-docs.sh28 build-docs.sh:124-188

Generation Statistics and Output

After generation completes, the script logs statistical information about the generated SUMMARY.md file:

Entry Counting Logic

Sources: build-docs.sh188

The grep -c command counts lines containing the <FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/ character, which appears in every markdown link. This count includes#LNaN-LNaN“ NaN file-path=“ character, which appears in every markdown link. This count includes">Hii</FileRef> | +1 | | Main pages | - <FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/Title" undefined file-path="Title">Hii</FileRef> | +1 per main page | | Subsections | - <FileRef file-url="https://github.com/jzombie/deepwiki-to-mdbook/blob/0378ae61/Title" undefined file-path="Title">Hii</FileRef> | +1 per subsection |

Example Output:

Generated SUMMARY.md with 23 entries

This indicates the book contains 23 total navigation links (overview + main pages + all subsections combined).

Sources: build-docs.sh188

Integration with mdBook Build

The generated src/SUMMARY.md file is used directly by mdBook during the build process (Step 6):

  1. mdBook reads src/SUMMARY.md to determine book structure
  2. For each entry, mdBook looks up the corresponding markdown file in src/
  3. Files are processed in the order they appear in SUMMARY.md
  4. The navigation sidebar reflects the hierarchy defined in SUMMARY.md

The generation happens in build-docs.sh:108-161 markdown files are copied to src/ in build-docs.sh166 and the mdBook build executes in build-docs.sh176

Sources: build-docs.sh:108-176

Dismiss

Refresh this wiki

Enter email to refresh