Skip to content

Commit dbb0391

Browse files
authored
Merge pull request #92 from javiereguiluz/toc_tweaks
Change TOC generation to make it more flexible
2 parents 06fbd81 + f3891bd commit dbb0391

File tree

9 files changed

+101
-13
lines changed

9 files changed

+101
-13
lines changed

src/Generator/JsonGenerator.php

+6-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\DomCrawler\Crawler;
2121
use Symfony\Component\Filesystem\Filesystem;
2222
use SymfonyDocsBuilder\BuildConfig;
23+
use SymfonyDocsBuilder\Twig\TocExtension;
2324
use function Symfony\Component\String\u;
2425

2526
class JsonGenerator
@@ -73,7 +74,8 @@ public function generateJson(string $masterDocument = 'index'): array
7374
'title' => $metaEntry->getTitle(),
7475
'parents' => $this->determineParents($parserFilename, $tocTreeHierarchy) ?: [],
7576
'current_page_name' => $parserFilename,
76-
'toc' => $this->generateToc($metaEntry, current($metaEntry->getTitles())[1]),
77+
'toc' => $toc = $this->generateToc($metaEntry, current($metaEntry->getTitles())[1]),
78+
'toc_options' => TocExtension::getOptions($toc),
7779
'next' => $next,
7880
'prev' => $prev,
7981
'body' => $crawler->filter('body')->html(),
@@ -98,7 +100,7 @@ public function setOutput(SymfonyStyle $output)
98100
$this->output = $output;
99101
}
100102

101-
private function generateToc(MetaEntry $metaEntry, ?array $titles): array
103+
private function generateToc(MetaEntry $metaEntry, ?array $titles, int $level = 1): array
102104
{
103105
if (null === $titles) {
104106
return [];
@@ -108,11 +110,12 @@ private function generateToc(MetaEntry $metaEntry, ?array $titles): array
108110

109111
foreach ($titles as $title) {
110112
$tocTree[] = [
113+
'level' => $level,
111114
'url' => sprintf('%s#%s', $metaEntry->getUrl(), Environment::slugify($title[0])),
112115
'page' => u($metaEntry->getUrl())->beforeLast('.html'),
113116
'fragment' => Environment::slugify($title[0]),
114117
'title' => $title[0],
115-
'children' => $this->generateToc($metaEntry, $title[1]),
118+
'children' => $this->generateToc($metaEntry, $title[1], $level + 1),
116119
];
117120
}
118121

src/KernelFactory.php

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use SymfonyDocsBuilder\Directive as SymfonyDirectives;
1818
use SymfonyDocsBuilder\Reference as SymfonyReferences;
1919
use SymfonyDocsBuilder\Twig\AssetsExtension;
20+
use SymfonyDocsBuilder\Twig\TocExtension;
2021
use function Symfony\Component\String\u;
2122

2223
/**
@@ -55,6 +56,7 @@ static function (string $path) use ($parseSubPath): bool {
5556

5657
$twig = $configuration->getTemplateEngine();
5758
$twig->addExtension(new AssetsExtension());
59+
$twig->addExtension(new TocExtension());
5860

5961
return new DocsKernel(
6062
$buildConfig,
+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{% apply spaceless %}
2-
<div class="toctree-wrapper">
2+
{% set toc_options = toc_options(tocItems) %}
3+
<div class="toctree-wrapper toc-size-{{ toc_options.size }}">
34
{% include "toc-level.html.twig" %}
45
</div>
56
{% endapply %}

src/Twig/TocExtension.php

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Docs Builder package.
5+
* (c) Ryan Weaver <[email protected]>
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
namespace SymfonyDocsBuilder\Twig;
11+
12+
use Twig\Extension\AbstractExtension;
13+
use Twig\TwigFunction;
14+
15+
class TocExtension extends AbstractExtension
16+
{
17+
public function getFunctions(): array
18+
{
19+
return [
20+
new TwigFunction('toc_options', [$this, 'getOptions']),
21+
];
22+
}
23+
24+
public static function getOptions(array $toc): array
25+
{
26+
$flattendToc = self::flattenToc($toc);
27+
$maxDepth = 0;
28+
$numVisibleItems = 0;
29+
foreach ($flattendToc as $tocItem) {
30+
$maxDepth = max($maxDepth, $tocItem['level']);
31+
$numVisibleItems++;
32+
}
33+
34+
return [
35+
'maxDepth' => $maxDepth,
36+
'numVisibleItems' => $numVisibleItems,
37+
'size' => self::getTocSize($numVisibleItems),
38+
];
39+
}
40+
41+
private static function flattenToc(array $toc, array &$flattenedToc = []): array
42+
{
43+
foreach ($toc as $item) {
44+
$flattenedToc[] = $item;
45+
46+
if ([] !== $item['children']) {
47+
self::flattenToc($item['children'], $flattenedToc);
48+
}
49+
}
50+
51+
return $flattenedToc;
52+
}
53+
54+
private static function getTocSize(int $numVisibleItems): string
55+
{
56+
if ($numVisibleItems < 10) {
57+
return 'md';
58+
}
59+
60+
if ($numVisibleItems < 20) {
61+
return 'lg';
62+
}
63+
64+
return 'xl';
65+
}
66+
}

tests/JsonIntegrationTest.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,12 @@ public function getJsonTests()
7474
'link' => 'crud.html',
7575
],
7676
'title' => 'Design',
77-
]
77+
'toc_options' => [
78+
'maxDepth' => 2,
79+
'numVisibleItems' => 3,
80+
'size' => 'md'
81+
],
82+
],
7883
];
7984

8085
yield 'crud' => [

tests/fixtures/expected/build-pdf/book.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<h1 id="book-index-book">Book</h1>
77
<img src="_images/symfony-logo.png">
88
<p>Here is a link to the <a href="#index" class="reference internal">main index</a></p>
9-
<div class="toctree-wrapper">
9+
<div class="toctree-wrapper toc-size-md">
1010
<ul class="toctree toctree-level-1 toctree-length-2">
1111
<li><a href="https://symfony.com/doc/4.0/book/first-page.html">First page</a></li>
1212
<li><a href="https://symfony.com/doc/4.0/book/second-page.html">Second page</a></li>

tests/fixtures/expected/main/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<div class="section">
1111
<h1 id="some-test-docs"><a class="headerlink" href="#some-test-docs" title="Permalink to this headline">Some Test Docs!</a></h1>
1212
<img src="_images/symfony-logo.png" />
13-
<div class="toctree-wrapper"><ul class="toctree toctree-level-1 toctree-length-2"><li><a href="datetime.html">DateTimeType Field</a><ul class="toctree toctree-level-2 toctree-length-4"><li><a href="datetime.html#field-options">Field Options</a></li><li><a href="datetime.html#overridden-options">Overridden Options</a></li><li><a href="datetime.html#field-variables">Field Variables</a></li><li><a href="datetime.html#url-checker-errors">Url checker errors</a></li></ul></li><li><a href="form/form_type.html">FormType Documentation</a></li></ul></div>
13+
<div class="toctree-wrapper toc-size-md"><ul class="toctree toctree-level-1 toctree-length-2"><li><a href="datetime.html">DateTimeType Field</a><ul class="toctree toctree-level-2 toctree-length-4"><li><a href="datetime.html#field-options">Field Options</a></li><li><a href="datetime.html#overridden-options">Overridden Options</a></li><li><a href="datetime.html#field-variables">Field Variables</a></li><li><a href="datetime.html#url-checker-errors">Url checker errors</a></li></ul></li><li><a href="form/form_type.html">FormType Documentation</a></li></ul></div>
1414
<span id="reference-forms-type-date-format"></span>
1515
<div class="section">
1616
<h2 id="a-header"><a class="headerlink" href="#a-header" title="Permalink to this headline">A header</a></h2>

tests/fixtures/expected/toctree/index.html

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
<body>
1010
<div class="section">
1111
<h1 id="toctree"><a class="headerlink" href="#toctree" title="Permalink to this headline">Toctree</a></h1>
12-
<div class="toctree-wrapper"><ul class="toctree toctree-level-1 toctree-length-1"><li><a href="file.html">Title</a><ul class="toctree toctree-level-2 toctree-length-1"><li><a href="file.html#sub-title">Sub title</a></li></ul></li></ul></div>
13-
<div class="toctree-wrapper"><ul class="toctree toctree-level-1 toctree-length-1"><li><a href="file.html">Title</a></li></ul></div>
14-
<div class="toctree-wrapper"><ul class="toctree toctree-level-1 toctree-length-1"><li><a href="directory/another_file.html">Another file</a></li></ul></div>
15-
<div class="toctree-wrapper"><ul class="toctree toctree-level-1 toctree-length-2"><li><a href="directory/another_file.html">Another file</a></li><li><a href="file.html">Title</a><ul class="toctree toctree-level-2 toctree-length-1"><li><a href="file.html#sub-title">Sub title</a></li></ul></li></ul></div>
16-
<div class="toctree-wrapper"><ul class="toctree toctree-level-1 toctree-length-2"><li><a href="file.html">Title</a><ul class="toctree toctree-level-2 toctree-length-1"><li><a href="file.html#sub-title">Sub title</a></li></ul></li><li><a href="directory/another_file.html">Another file</a></li></ul></div>
12+
<div class="toctree-wrapper toc-size-md"><ul class="toctree toctree-level-1 toctree-length-1"><li><a href="file.html">Title</a><ul class="toctree toctree-level-2 toctree-length-1"><li><a href="file.html#sub-title">Sub title</a></li></ul></li></ul></div>
13+
<div class="toctree-wrapper toc-size-md"><ul class="toctree toctree-level-1 toctree-length-1"><li><a href="file.html">Title</a></li></ul></div>
14+
<div class="toctree-wrapper toc-size-md"><ul class="toctree toctree-level-1 toctree-length-1"><li><a href="directory/another_file.html">Another file</a></li></ul></div>
15+
<div class="toctree-wrapper toc-size-md"><ul class="toctree toctree-level-1 toctree-length-2"><li><a href="directory/another_file.html">Another file</a></li><li><a href="file.html">Title</a><ul class="toctree toctree-level-2 toctree-length-1"><li><a href="file.html#sub-title">Sub title</a></li></ul></li></ul></div>
16+
<div class="toctree-wrapper toc-size-md"><ul class="toctree toctree-level-1 toctree-length-2"><li><a href="file.html">Title</a><ul class="toctree toctree-level-2 toctree-length-1"><li><a href="file.html#sub-title">Sub title</a></li></ul></li><li><a href="directory/another_file.html">Another file</a></li></ul></div>
1717

1818
</div>
1919

tests/fixtures/source/json/design.rst

+12-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,21 @@ Design
44
Something that should not be left to most programmers
55
to try to do.
66

7+
Section 1
8+
---------
9+
710
The toctree below should affects the next/prev. The
8-
first entry is effectively ignored, as it wasa already
11+
first entry is effectively ignored, as it was already
912
included by the toctree in index.rst (which is parsed first).
1013

14+
Subsection 1
15+
~~~~~~~~~~~~
16+
17+
This is a subsection of the first section. That's all.
18+
19+
Section 2
20+
---------
21+
1122
However, crud (which is ALSO included in the toctree in index.rst),
1223
WILL be read here, as the "crud" in index.rst has not been read
1324
yet (design comes first). Also, design/sub-page WILL be considered.

0 commit comments

Comments
 (0)