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:
| Phase | Lines | Description |
|---|---|---|
| Overview Extraction | 133-145 | Identifies and writes non-numbered introduction page |
| Numeric Sorting | 147-155 | Sorts numbered pages by numeric prefix using sort -t- -k1 -n |
| Hierarchical Writing | 158-185 | Iterates 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:
| Step | Command | Purpose | Example |
|---|---|---|---|
| List files | ls "$WIKI_DIR"/*.md | Get all root markdown files | Overview.md 1-intro.md 2-start.md |
| Extract basename | awk -F/ '{print $NF}' | Get filename only | Overview.md |
| Filter non-numeric | grep -Ev '^[0-9]' | Exclude numbered files | Overview.md (matches) |
| Take first | head -1 | Select single overview | Overview.md |
| Extract title | `head -1 | sed ‘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:
| Flag | Purpose | Example Effect |
|---|---|---|
-t- | Set delimiter to - | Split 10-advanced.md into 10 and advanced.md |
-k1 | Sort by field 1 | Use 10 as sort key |
-n | Numeric comparison | 2 sorts before 10 (not lexicographic) |
Example Sorting:
| Unsorted Filenames | Numeric Sort | Output Order |
|---|---|---|
10-advanced.md | Extract 10 | 1-overview.md |
2-start.md | Extract 2 | 2-start.md |
1-overview.md | Extract 1 | 5-components.md |
5-components.md | Extract 5 | 10-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:
| Variable | Type | Purpose | Example Value |
|---|---|---|---|
filename | String | Main page filename | 5-component-reference.md |
title | String | Main page title | Component Reference |
section_num | String | Numeric prefix | 5 |
section_dir | Path | Subsection directory | /workspace/wiki/section-5 |
subfilename | String | Subsection filename | 5.1-build-docs.md |
subtitle | String | Subsection title | build-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:
| Aspect | Implementation | Purpose |
|---|---|---|
| Indentation | echo " - <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 prefix | section-$section_num/$subfilename | Correct relative path for mdBook |
| Numeric sort | sort -t- -k1 -n | Same algorithm as main pages |
| Title extraction | `head -1 | sed ‘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
| Pattern | Location | SUMMARY.md Output |
|---|---|---|
*.md | Root directory | Main pages |
N-*.md | Root directory | Main section (if section-N/ exists) |
*.md | section-N/ directory | Subsections (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:
| Command | Purpose | Example Input | Example Output |
|---|---|---|---|
head -1 "$file" | Get first line | # Component Reference | # Component Reference |
sed 's/^# //' | Remove heading syntax | # Component Reference | Component Reference |
Sources: build-docs.sh120 build-docs.sh134 build-docs.sh150
Output Format
The generated SUMMARY.md follows mdBook’s syntax:
Format Rules:
| Element | Syntax | Purpose |
|---|---|---|
| Header | # Summary | Required 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 Name | Visual 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:
| Variable | Scope | Type | Initialization | Example Value |
|---|---|---|---|---|
WIKI_DIR | Global | Path | Line 28 | /workspace/wiki |
main_pages_list | Local | String | Line 135 | Multi-line list of paths |
overview_file | Local | String | Line 138 | Overview.md |
main_pages | Local | String | Line 147 | Sorted, newline-separated paths |
filename | Loop | String | Line 160 | 5-component-reference.md |
title | Loop | String | Line 163 | Component Reference |
section_num | Loop | String | Line 166 | 5 |
section_dir | Loop | Path | Line 167 | /workspace/wiki/section-5 |
subfilename | Nested Loop | String | Line 177 | 5.1-build-docs.md |
subtitle | Nested Loop | String | Line 178 | build-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):
- mdBook reads
src/SUMMARY.mdto determine book structure - For each entry, mdBook looks up the corresponding markdown file in
src/ - Files are processed in the order they appear in
SUMMARY.md - 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