@@ -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 [];
109
- }
107
+ $ flatTocTree = [];
110
108
111
- $ tocTree = [];
109
+ foreach ($ crawler ->filter ('h2, h3 ' ) as $ heading ) {
110
+ $ headerId = $ heading ->getAttribute ('id ' ) ?? Environment::slugify ($ heading ->textContent );
112
111
113
- foreach ( $ titles as $ title ) {
114
- $ tocTree [] = [
115
- 'level ' => $ level ,
116
- 'url ' => sprintf ('%s#%s ' , $ metaEntry ->getUrl (), Environment:: slugify ( $ title [ 0 ]) ),
112
+ // this tocTree stores items sequentially (h2, h2, h3, h3, h2, h3, etc.)
113
+ $ flatTocTree [] = [
114
+ 'level ' => ' h2 ' === $ heading -> tagName ? 2 : 3 ,
115
+ 'url ' => sprintf ('%s#%s ' , $ metaEntry ->getUrl (), $ headerId ),
117
116
'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 ) ,
117
+ 'fragment ' => $ headerId ,
118
+ 'title ' => $ heading -> textContent ,
119
+ 'children ' => [] ,
121
120
];
122
121
}
123
122
124
- return $ tocTree ;
123
+ // this tocTree stores items nested by level (h2, h2[h3, h3], h2[h3], etc.)
124
+ $ nestedTocTree = [];
125
+ foreach ($ flatTocTree as $ tocItem ) {
126
+ if (2 === $ tocItem ['level ' ]) {
127
+ $ nestedTocTree [] = $ tocItem ;
128
+ } else {
129
+ $ nestedTocTree [\count ($ nestedTocTree ) - 1 ]['children ' ][] = $ tocItem ;
130
+ }
131
+ }
132
+
133
+ return $ nestedTocTree ;
125
134
}
126
135
127
136
private function determineNext (string $ parserFilename , array $ flattenedTocTree ): ?array
0 commit comments