11
11
12
12
namespace SymfonyDocsBuilder \Generator ;
13
13
14
+ use Doctrine \RST \Environment ;
14
15
use Doctrine \RST \Meta \MetaEntry ;
15
16
use Doctrine \RST \Meta \Metas ;
16
17
use Symfony \Component \Console \Helper \ProgressBar ;
19
20
use Symfony \Component \DomCrawler \Crawler ;
20
21
use Symfony \Component \Filesystem \Filesystem ;
21
22
use SymfonyDocsBuilder \BuildConfig ;
23
+ use function Symfony \Component \String \u ;
22
24
23
25
class JsonGenerator
24
26
{
@@ -65,15 +67,14 @@ public function generateJson(string $masterDocument = 'index'): array
65
67
66
68
$ crawler = new Crawler (file_get_contents ($ this ->buildConfig ->getOutputDir ().'/ ' .$ filename .'.html ' ));
67
69
68
- $ tocGenerator = new TocGenerator ($ metaEntry );
69
70
$ next = $ this ->determineNext ($ parserFilename , $ flattenedTocTree , $ masterDocument );
70
71
$ prev = $ this ->determinePrev ($ parserFilename , $ flattenedTocTree );
71
72
$ data = [
72
73
'title ' => $ metaEntry ->getTitle (),
73
74
'parents ' => $ this ->determineParents ($ parserFilename , $ tocTreeHierarchy ) ?: [],
74
75
'current_page_name ' => $ parserFilename ,
75
- 'toc ' => $ tocGenerator -> getToc ( ),
76
- 'toc_num_items ' => $ tocGenerator -> getNumItemsPerLevel ( ),
76
+ 'toc ' => $ toc = $ this -> generateToc ( $ metaEntry , current ( $ metaEntry -> getTitles ())[ 1 ] ),
77
+ 'toc_options ' => $ this -> getTocOptions ( $ toc ),
77
78
'next ' => $ next ,
78
79
'prev ' => $ prev ,
79
80
'body ' => $ crawler ->filter ('body ' )->html (),
@@ -98,6 +99,72 @@ public function setOutput(SymfonyStyle $output)
98
99
$ this ->output = $ output ;
99
100
}
100
101
102
+ private function generateToc (MetaEntry $ metaEntry , ?array $ titles , int $ level = 1 ): array
103
+ {
104
+ if (null === $ titles ) {
105
+ return [];
106
+ }
107
+
108
+ $ tocTree = [];
109
+
110
+ foreach ($ titles as $ title ) {
111
+ $ tocTree [] = [
112
+ 'level ' => $ level ,
113
+ 'url ' => sprintf ('%s#%s ' , $ metaEntry ->getUrl (), Environment::slugify ($ title [0 ])),
114
+ 'page ' => u ($ metaEntry ->getUrl ())->beforeLast ('.html ' ),
115
+ 'fragment ' => Environment::slugify ($ title [0 ]),
116
+ 'title ' => $ title [0 ],
117
+ 'children ' => $ this ->generateToc ($ metaEntry , $ title [1 ], $ level + 1 ),
118
+ ];
119
+ }
120
+
121
+ return $ tocTree ;
122
+ }
123
+
124
+ private function getTocOptions (array $ toc ): array
125
+ {
126
+ $ flattendToc = $ this ->flattenToc ($ toc );
127
+ $ maxDepth = 0 ;
128
+ $ numVisibleItems = 0 ;
129
+ foreach ($ flattendToc as $ tocItem ) {
130
+ $ maxDepth = max ($ maxDepth , $ tocItem ['level ' ]);
131
+ $ numVisibleItems ++;
132
+ }
133
+
134
+ return [
135
+ 'maxDepth ' => $ maxDepth ,
136
+ 'numVisibleItems ' => $ numVisibleItems ,
137
+ 'size ' => $ this ->getTocSize ($ numVisibleItems ),
138
+ ];
139
+ }
140
+
141
+ // If you change this method, make the same change in TocNodeRenderer too
142
+ private function getTocSize (int $ numVisibleItems ): string
143
+ {
144
+ if ($ numVisibleItems < 10 ) {
145
+ return 'md ' ;
146
+ }
147
+
148
+ if ($ numVisibleItems < 20 ) {
149
+ return 'lg ' ;
150
+ }
151
+
152
+ return 'xl ' ;
153
+ }
154
+
155
+ private function flattenToc (array $ toc , array &$ flattenedToc = []): array
156
+ {
157
+ foreach ($ toc as $ item ) {
158
+ $ flattenedToc [] = $ item ;
159
+
160
+ if ([] !== $ item ['children ' ]) {
161
+ $ this ->flattenToc ($ item ['children ' ], $ flattenedToc );
162
+ }
163
+ }
164
+
165
+ return $ flattenedToc ;
166
+ }
167
+
101
168
private function determineNext (string $ parserFilename , array $ flattenedTocTree ): ?array
102
169
{
103
170
$ foundCurrentFile = false ;
0 commit comments