4646
4747SIDEBAR = [
4848 ("Getting Started" , [
49- ("index" , "Home" ),
50- ("decorators" , "Decorators" ),
51- ("exceptions" , "Exceptions" ),
52- ("examples" , "Examples" ),
49+ ("getting_started/ index" , "Home" ),
50+ ("getting_started/ decorators" , "Decorators" ),
51+ ("getting_started/ exceptions" , "Exceptions" ),
52+ ("getting_started/ examples" , "Examples" ),
5353 ]),
5454 ("Core" , [
55- ("server" , "Server" ),
56- ("event" , "Event" ),
57- ("entity" , "Entity" ),
58- ("player" , "Player" ),
55+ ("core/server" , "Server" ),
56+ ("core/event" , "Event" ),
57+ ("core/entity" , "Entity" ),
58+ ("core/entitysubtypes" , "Entity Subtypes" ),
59+ ("core/player" , "Player" ),
5960 ]),
6061 ("World & Space" , [
61- ("world" , "World" ),
62- ("location" , "Location" ),
63- ("block" , "Block" ),
64- ("chunk" , "Chunk" ),
65- ("vector" , "Vector" ),
62+ ("world/world" , "World" ),
63+ ("world/location" , "Location" ),
64+ ("world/block" , "Block" ),
65+ ("world/blocksnapshot" , "BlockSnapshot" ),
66+ ("world/chunk" , "Chunk" ),
67+ ("world/vector" , "Vector" ),
6668 ]),
6769 ("Items & Inventory" , [
68- ("item" , "Item" ),
69- ("itembuilder" , "ItemBuilder" ),
70- ("inventory" , "Inventory" ),
71- ("recipe" , "Recipe" ),
70+ ("items/ item" , "Item" ),
71+ ("items/ itembuilder" , "ItemBuilder" ),
72+ ("items/ inventory" , "Inventory" ),
73+ ("items/ recipe" , "Recipe" ),
7274 ]),
7375 ("Effects & Attributes" , [
74- ("effect" , "Effect" ),
75- ("potion" , "Potion" ),
76- ("attribute" , "Attribute" ),
77- ("advancement" , "Advancement" ),
78- ("firework" , "Firework" ),
76+ ("effects/effect" , "Effect" ),
77+ ("effects/potion" , "Potion" ),
78+ ("effects/attribute" , "Attribute" ),
79+ ("effects/advancement" , "Advancement" ),
80+ ("effects/firework" , "Firework" ),
81+ ("effects/textcomponent" , "TextComponent" ),
82+ ("effects/bookbuilder" , "BookBuilder" ),
7983 ]),
8084 ("Scoreboards & UI" , [
81- ("menu" , "Menu" ),
82- ("menuitem" , "MenuItem" ),
83- ("sidebar" , "Sidebar" ),
84- ("actionbardisplay" , "ActionBarDisplay" ),
85- ("bossbardisplay" , "BossBarDisplay" ),
86- ("bossbar" , "BossBar" ),
87- ("scoreboard" , "Scoreboard" ),
88- ("objective" , "Objective" ),
89- ("team" , "Team" ),
85+ ("ui/ menu" , "Menu" ),
86+ ("ui/ menuitem" , "MenuItem" ),
87+ ("ui/ sidebar" , "Sidebar" ),
88+ ("ui/ actionbardisplay" , "ActionBarDisplay" ),
89+ ("ui/ bossbardisplay" , "BossBarDisplay" ),
90+ ("ui/ bossbar" , "BossBar" ),
91+ ("ui/ scoreboard" , "Scoreboard" ),
92+ ("ui/ objective" , "Objective" ),
93+ ("ui/ team" , "Team" ),
9094 ]),
9195 ("Helpers" , [
92- ("npc" , "NPC" ),
93- ("config" , "Config" ),
94- ("state" , "State" ),
95- ("cooldown" , "Cooldown" ),
96- ("paginator" , "Paginator" ),
97- ("enums" , "Enums" ),
98- ("enumvalue" , "EnumValue" ),
96+ ("helpers/ npc" , "NPC" ),
97+ ("helpers/ config" , "Config" ),
98+ ("helpers/ state" , "State" ),
99+ ("helpers/ cooldown" , "Cooldown" ),
100+ ("helpers/ paginator" , "Paginator" ),
101+ ("helpers/ enums" , "Enums" ),
102+ ("helpers/ enumvalue" , "EnumValue" ),
99103 ]),
100104 ("Display Entities" , [
101- ("hologram" , "Hologram" ),
102- ("blockdisplay" , "BlockDisplay" ),
103- ("itemdisplay" , "ItemDisplay" ),
105+ ("display/ hologram" , "Hologram" ),
106+ ("display/ blockdisplay" , "BlockDisplay" ),
107+ ("display/ itemdisplay" , "ItemDisplay" ),
104108 ]),
105109 ("Extensions" , [
106- ("imagedisplay" , "ImageDisplay" ),
107- ("meshdisplay" , "MeshDisplay" ),
108- ("quest" , "Quest" ),
109- ("dialog" , "Dialog" ),
110- ("bank" , "Bank" ),
111- ("shop" , "Shop" ),
112- ("trade" , "TradeWindow" ),
113- ("ability" , "Ability" ),
114- ("mana" , "ManaStore" ),
115- ("combat" , "CombatSystem" ),
116- ("levels" , "LevelSystem" ),
117- ("region" , "Region" ),
118- ("party" , "Party" ),
119- ("guild" , "Guild" ),
120- ("customitem" , "CustomItem" ),
121- ("leaderboard" , "Leaderboard" ),
122- ("visualeffect" , "VisualEffect" ),
123- ("playerdatastore" , "PlayerDataStore" ),
124- ("dungeon" , "Dungeon" ),
110+ ("extensions/imagedisplay" , "ImageDisplay" ),
111+ ("extensions/meshdisplay" , "MeshDisplay" ),
112+ ("extensions/quest" , "Quest" ),
113+ ("extensions/dialog" , "Dialog" ),
114+ ("extensions/bank" , "Bank" ),
115+ ("extensions/shop" , "Shop" ),
116+ ("extensions/trade" , "TradeWindow" ),
117+ ("extensions/ability" , "Ability" ),
118+ ("extensions/mana" , "ManaStore" ),
119+ ("extensions/combat" , "CombatSystem" ),
120+ ("extensions/levels" , "LevelSystem" ),
121+ ("extensions/region" , "Region" ),
122+ ("extensions/party" , "Party" ),
123+ ("extensions/guild" , "Guild" ),
124+ ("extensions/customitem" , "CustomItem" ),
125+ ("extensions/leaderboard" , "Leaderboard" ),
126+ ("extensions/visualeffect" , "VisualEffect" ),
127+ ("extensions/playerdatastore" , "PlayerDataStore" ),
128+ ("extensions/dungeon" , "Dungeon" ),
129+ ("extensions/tablist" , "TabList" ),
130+ ("extensions/statemachine" , "StateMachine" ),
131+ ("extensions/scheduler" , "Scheduler" ),
132+ ("extensions/placeholder" , "Placeholder" ),
133+ ("extensions/loottable" , "LootTable" ),
125134 ]),
126135 ("Utilities" , [
127- ("raycast" , "Raycast" ),
128- ("chat" , "Chat" ),
129- ("reflect" , "Reflect" ),
136+ ("utilities/ raycast" , "Raycast" ),
137+ ("utilities/ chat" , "Chat" ),
138+ ("utilities/ reflect" , "Reflect" ),
130139 ]),
131140 ("Internals" , [
132- ("bridge" , "Bridge" ),
133- ("events_internal" , "Events" ),
134- ("execution" , "Execution" ),
135- ("serialization" , "Serialization" ),
136- ("lifecycle" , "Lifecycle" ),
137- ("debugging" , "Debugging" )
141+ ("internals/ bridge" , "Bridge" ),
142+ ("internals/ events_internal" , "Events" ),
143+ ("internals/ execution" , "Execution" ),
144+ ("internals/ serialization" , "Serialization" ),
145+ ("internals/ lifecycle" , "Lifecycle" ),
146+ ("internals/ debugging" , "Debugging" )
138147 ]),
139148]
140149
150+
151+ def slug_basename (slug ):
152+ """Extract the filename part from a possibly prefixed slug (e.g. 'core/entity' → 'entity')."""
153+ return slug .rsplit ("/" , 1 )[- 1 ]
154+
141155# ── Frontmatter parser ──────────────────────────────────────────────────────
142156
143157def parse_frontmatter (text ):
@@ -223,7 +237,7 @@ def convert_markdown(text):
223237 TocExtension (permalink = False , toc_depth = "2-3" ),
224238 ])
225239 html = md .convert (text )
226- toc_tokens = md . toc_tokens
240+ toc_tokens = getattr ( md , " toc_tokens" , [])
227241 md .reset ()
228242 return html , toc_tokens
229243
@@ -285,8 +299,9 @@ def build_sidebar_html(current_slug):
285299 )
286300 is_ext = section_name == "Extensions"
287301 for slug , label in pages :
302+ base = slug_basename (slug )
288303 active = ' class="active"' if slug == current_slug else ''
289- href = "index.html" if slug == "index" else f"{ slug } .html"
304+ href = "index.html" if base == "index" else f"{ base } .html"
290305 display = f'{ label } <span class="ext-tag">ext</span>' if is_ext else label
291306 parts .append (f' <li><a href="{ href } "{ active } >{ display } </a></li>' )
292307
@@ -443,7 +458,7 @@ def build_page(slug):
443458 search_index_zstd_b64 = _search_index_zstd_b64 ,
444459 )
445460
446- out_name = "index.html" if slug == "index" else f"{ slug } .html"
461+ out_name = "index.html" if slug_basename ( slug ) == "index" else f"{ slug_basename ( slug ) } .html"
447462 out_path = os .path .join (OUT_DIR , out_name )
448463 with open (out_path , "w" , encoding = "utf-8" ) as f :
449464 f .write (out_html )
@@ -470,11 +485,13 @@ def main():
470485
471486 # Also check for any .md files not in the sidebar
472487 if os .path .isdir (SRC_DIR ):
473- for fname in os .listdir (SRC_DIR ):
474- if fname .endswith (".md" ):
475- s = fname [:- 3 ]
476- if s not in slugs :
477- slugs .append (s )
488+ for dirpath , _dirnames , filenames in os .walk (SRC_DIR ):
489+ for fname in filenames :
490+ if fname .endswith (".md" ):
491+ rel = os .path .relpath (os .path .join (dirpath , fname ), SRC_DIR )
492+ s = rel [:- 3 ] # strip .md, keeps subfolder prefix
493+ if s not in slugs :
494+ slugs .append (s )
478495
479496 built = 0
480497 search_index = []
@@ -528,8 +545,8 @@ def main():
528545 # Flush any remaining table
529546 if table_first_cols :
530547 sections .append ({"heading" : current_heading , "text" : ", " .join (table_first_cols )})
531- url = "index.html" if slug == "index" else f"{ slug } .html"
532- search_index .append ({"slug" : slug , "title" : title , "url" : url , "sections" : sections })
548+ url = "index.html" if slug_basename ( slug ) == "index" else f"{ slug_basename ( slug ) } .html"
549+ search_index .append ({"slug" : slug_basename ( slug ) , "title" : title , "url" : url , "sections" : sections })
533550
534551 import json
535552 search_json = json .dumps (search_index , separators = (',' , ':' ))
@@ -546,7 +563,7 @@ def main():
546563 src = os .path .join (SRC_DIR , f"{ slug } .md" )
547564 if os .path .exists (src ):
548565 build_page (slug )
549- print (f" ✓ { slug } .html" )
566+ print (f" ✓ { slug_basename ( slug ) } .html" )
550567 built += 1
551568
552569 print (f"\n ✅ Built { built } pages" )
0 commit comments