@@ -69,7 +69,7 @@ public function generateJson(string $masterDocument = 'index'): array
69
69
$ crawler = new Crawler (file_get_contents ($ this ->buildConfig ->getOutputDir ().'/ ' .$ filename .'.html ' ));
70
70
71
71
// happens when some doc is a partial included in other doc an it doesn't have any titles
72
- $ toc = false === current ( $ metaEntry -> getTitles ()) ? [] : $ this ->generateToc ($ metaEntry , current ( $ metaEntry -> getTitles ())[ 1 ] );
72
+ $ toc = $ this ->generateToc ($ metaEntry , $ crawler );
73
73
$ next = $ this ->determineNext ($ parserFilename , $ flattenedTocTree , $ masterDocument );
74
74
$ prev = $ this ->determinePrev ($ parserFilename , $ flattenedTocTree );
75
75
$ data = [
@@ -102,26 +102,35 @@ public function setOutput(SymfonyStyle $output)
102
102
$ this ->output = $ output ;
103
103
}
104
104
105
- private function generateToc (MetaEntry $ metaEntry , ? array $ titles , int $ level = 1 ): array
105
+ private function generateToc (MetaEntry $ metaEntry , Crawler $ crawler ): array
106
106
{
107
- if (null === $ titles ) {
108
- return [];
107
+ $ flatTocTree = [];
108
+
109
+ foreach ($ crawler ->filter ('h2, h3 ' ) as $ heading ) {
110
+ $ headerId = $ heading ->getAttribute ('id ' ) ?? Environment::slugify ($ heading ->textContent );
111
+
112
+ // this tocTree stores items sequentially (h2, h2, h3, h3, h2, h3, etc.)
113
+ $ flatTocTree [] = [
114
+ 'level ' => 'h2 ' === $ heading ->tagName ? 1 : 2 ,
115
+ 'url ' => sprintf ('%s#%s ' , $ metaEntry ->getUrl (), $ headerId ),
116
+ 'page ' => u ($ metaEntry ->getUrl ())->beforeLast ('.html ' )->toString (),
117
+ 'fragment ' => $ headerId ,
118
+ 'title ' => $ heading ->textContent ,
119
+ 'children ' => [],
120
+ ];
109
121
}
110
122
111
- $ tocTree = [];
112
-
113
- foreach ($ titles as $ title ) {
114
- $ tocTree [] = [
115
- 'level ' => $ level ,
116
- 'url ' => sprintf ('%s#%s ' , $ metaEntry ->getUrl (), Environment::slugify ($ title [0 ])),
117
- 'page ' => u ($ metaEntry ->getUrl ())->beforeLast ('.html ' ),
118
- 'fragment ' => Environment::slugify ($ title [0 ]),
119
- 'title ' => $ title [0 ],
120
- 'children ' => $ this ->generateToc ($ metaEntry , $ title [1 ], $ level + 1 ),
121
- ];
123
+ // this tocTree stores items nested by level (h2, h2[h3, h3], h2[h3], etc.)
124
+ $ nestedTocTree = [];
125
+ foreach ($ flatTocTree as $ tocItem ) {
126
+ if (1 === $ tocItem ['level ' ]) {
127
+ $ nestedTocTree [] = $ tocItem ;
128
+ } else {
129
+ $ nestedTocTree [\count ($ nestedTocTree ) - 1 ]['children ' ][] = $ tocItem ;
130
+ }
122
131
}
123
132
124
- return $ tocTree ;
133
+ return $ nestedTocTree ;
125
134
}
126
135
127
136
private function determineNext (string $ parserFilename , array $ flattenedTocTree ): ?array
0 commit comments