Skip to content

Change TOC generation to make it more flexible #92

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/Generator/JsonGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\Filesystem\Filesystem;
use SymfonyDocsBuilder\BuildConfig;
use SymfonyDocsBuilder\Twig\TocExtension;
use function Symfony\Component\String\u;

class JsonGenerator
Expand Down Expand Up @@ -73,7 +74,8 @@ public function generateJson(string $masterDocument = 'index'): array
'title' => $metaEntry->getTitle(),
'parents' => $this->determineParents($parserFilename, $tocTreeHierarchy) ?: [],
'current_page_name' => $parserFilename,
'toc' => $this->generateToc($metaEntry, current($metaEntry->getTitles())[1]),
'toc' => $toc = $this->generateToc($metaEntry, current($metaEntry->getTitles())[1]),
'toc_options' => TocExtension::getOptions($toc),
'next' => $next,
'prev' => $prev,
'body' => $crawler->filter('body')->html(),
Expand All @@ -98,7 +100,7 @@ public function setOutput(SymfonyStyle $output)
$this->output = $output;
}

private function generateToc(MetaEntry $metaEntry, ?array $titles): array
private function generateToc(MetaEntry $metaEntry, ?array $titles, int $level = 1): array
{
if (null === $titles) {
return [];
Expand All @@ -108,11 +110,12 @@ private function generateToc(MetaEntry $metaEntry, ?array $titles): array

foreach ($titles as $title) {
$tocTree[] = [
'level' => $level,
'url' => sprintf('%s#%s', $metaEntry->getUrl(), Environment::slugify($title[0])),
'page' => u($metaEntry->getUrl())->beforeLast('.html'),
'fragment' => Environment::slugify($title[0]),
'title' => $title[0],
'children' => $this->generateToc($metaEntry, $title[1]),
'children' => $this->generateToc($metaEntry, $title[1], $level + 1),
];
}

Expand Down
2 changes: 2 additions & 0 deletions src/KernelFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use SymfonyDocsBuilder\Directive as SymfonyDirectives;
use SymfonyDocsBuilder\Reference as SymfonyReferences;
use SymfonyDocsBuilder\Twig\AssetsExtension;
use SymfonyDocsBuilder\Twig\TocExtension;
use function Symfony\Component\String\u;

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

$twig = $configuration->getTemplateEngine();
$twig->addExtension(new AssetsExtension());
$twig->addExtension(new TocExtension());

return new DocsKernel(
$buildConfig,
Expand Down
3 changes: 2 additions & 1 deletion src/Templates/default/html/toc.html.twig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{% apply spaceless %}
<div class="toctree-wrapper">
{% set toc_options = toc_options(tocItems) %}
<div class="toctree-wrapper toc-size-{{ toc_options.size }}">
{% include "toc-level.html.twig" %}
</div>
{% endapply %}
66 changes: 66 additions & 0 deletions src/Twig/TocExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

/*
* This file is part of the Docs Builder package.
* (c) Ryan Weaver <ryan@symfonycasts.com>
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace SymfonyDocsBuilder\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class TocExtension extends AbstractExtension
{
public function getFunctions(): array
{
return [
new TwigFunction('toc_options', [$this, 'getOptions']),
];
}

public static function getOptions(array $toc): array
{
$flattendToc = self::flattenToc($toc);
$maxDepth = 0;
$numVisibleItems = 0;
foreach ($flattendToc as $tocItem) {
$maxDepth = max($maxDepth, $tocItem['level']);
$numVisibleItems++;
}

return [
'maxDepth' => $maxDepth,
'numVisibleItems' => $numVisibleItems,
'size' => self::getTocSize($numVisibleItems),
];
}

private static function flattenToc(array $toc, array &$flattenedToc = []): array
{
foreach ($toc as $item) {
$flattenedToc[] = $item;

if ([] !== $item['children']) {
self::flattenToc($item['children'], $flattenedToc);
}
}

return $flattenedToc;
}

private static function getTocSize(int $numVisibleItems): string
{
if ($numVisibleItems < 10) {
return 'md';
}

if ($numVisibleItems < 20) {
return 'lg';
}

return 'xl';
}
}
7 changes: 6 additions & 1 deletion tests/JsonIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ public function getJsonTests()
'link' => 'crud.html',
],
'title' => 'Design',
]
'toc_options' => [
'maxDepth' => 2,
'numVisibleItems' => 3,
'size' => 'md'
],
],
];

yield 'crud' => [
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/expected/build-pdf/book.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<h1 id="book-index-book">Book</h1>
<img src="_images/symfony-logo.png">
<p>Here is a link to the <a href="#index" class="reference internal">main index</a></p>
<div class="toctree-wrapper">
<div class="toctree-wrapper toc-size-md">
<ul class="toctree toctree-level-1 toctree-length-2">
<li><a href="https://symfony.com/doc/4.0/book/first-page.html">First page</a></li>
<li><a href="https://symfony.com/doc/4.0/book/second-page.html">Second page</a></li>
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/expected/main/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<div class="section">
<h1 id="some-test-docs"><a class="headerlink" href="#some-test-docs" title="Permalink to this headline">Some Test Docs!</a></h1>
<img src="_images/symfony-logo.png" />
<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>
<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>
<span id="reference-forms-type-date-format"></span>
<div class="section">
<h2 id="a-header"><a class="headerlink" href="#a-header" title="Permalink to this headline">A header</a></h2>
Expand Down
10 changes: 5 additions & 5 deletions tests/fixtures/expected/toctree/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
<body>
<div class="section">
<h1 id="toctree"><a class="headerlink" href="#toctree" title="Permalink to this headline">Toctree</a></h1>
<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>
<div class="toctree-wrapper"><ul class="toctree toctree-level-1 toctree-length-1"><li><a href="file.html">Title</a></li></ul></div>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>

</div>

Expand Down
13 changes: 12 additions & 1 deletion tests/fixtures/source/json/design.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@ Design
Something that should not be left to most programmers
to try to do.

Section 1
---------

The toctree below should affects the next/prev. The
first entry is effectively ignored, as it wasa already
first entry is effectively ignored, as it was already
included by the toctree in index.rst (which is parsed first).

Subsection 1
~~~~~~~~~~~~

This is a subsection of the first section. That's all.

Section 2
---------

However, crud (which is ALSO included in the toctree in index.rst),
WILL be read here, as the "crud" in index.rst has not been read
yet (design comes first). Also, design/sub-page WILL be considered.
Expand Down