Browse Source

Fix missing headings in sidebar

shalvah 3 years ago
parent
commit
9f94ee122c

+ 78 - 1
resources/views/themes/default/sidebar.blade.php

@@ -22,8 +22,47 @@
     </div>
 
     <div id="toc">
+        @php
+            $previousH1 = null;
+            $inSubHeading = false;
+            $headingsCount = 0;
+        @endphp
+        @foreach($headingsBeforeEndpoints as $heading)
+            @if($heading['level'] === 1)
+                @if($previousH1)
+                    </ul>
+                @endif
+                @if($inSubHeading)
+                    @php($inSubHeading = false)
+                    </ul>
+                @endif
+                <ul id="tocify-header-{{ $headingsCount }}" class="tocify-header">
+                    <li class="tocify-item level-1" data-unique="{!! $heading['slug'] !!}">
+                        <a href="#{!! $heading['slug'] !!}">{!! $heading['text'] !!}</a>
+                    </li>
+                @php($previousH1 = $heading)
+                @php($headingsCount += 1)
+            @elseif ($heading['level'] === 2 && $previousH1)
+                @if(!$inSubHeading)
+                    <ul id="tocify-subheader-{!! $previousH1['slug'] !!}" class="tocify-subheader">
+                    @php($inSubHeading = true)
+                @endif
+                    <li class="tocify-item level-2"
+                        data-unique="{!! $previousH1['slug'] !!}-{!! $heading['slug'] !!}">
+                        <a href="#{!! $heading['slug'] !!}">{{ $heading['text'] }}</a>
+                    </li>
+            @endif
+
+            @if($loop->last)
+                    @if($inSubHeading)
+                    </ul>
+                    @endif
+                </ul>
+            @endif
+        @endforeach
+
         @foreach($groupedEndpoints as $group)
-            <ul id="tocify-header-{{ $loop->index }}" class="tocify-header">
+            <ul id="tocify-header-{{ $loop->index + $headingsCount }}" class="tocify-header">
                 <li class="tocify-item level-1" data-unique="{!! Str::slug($group['name']) !!}">
                     <a href="#{!! Str::slug($group['name']) !!}">{!! $group['name'] !!}</a>
                 </li>
@@ -40,6 +79,44 @@
                 @endif
             </ul>
         @endforeach
+
+        @php($previousH1 = null)
+        @php($inSubHeading = false)
+        @php($headingsCount += count($groupedEndpoints))
+
+        @foreach($headingsAfterEndpoints as $heading)
+            @if($heading['level'] === 1)
+                @if($previousH1)
+                    </ul>
+                @endif
+                @if($inSubHeading)
+                    @php($inSubHeading = false)
+                    </ul>
+                @endif
+                <ul id="tocify-header-{{ $headingsCount }}" class="tocify-header">
+                    <li class="tocify-item level-1" data-unique="{!! $heading['slug'] !!}">
+                        <a href="#{!! $heading['slug'] !!}">{!! $heading['text'] !!}</a>
+                    </li>
+                @php($previousH1 = $heading)
+                @php($headingsCount += 1)
+            @elseif ($heading['level'] === 2 && $previousH1)
+                @if(!$inSubHeading)
+                    <ul id="tocify-subheader-{!! $previousH1['slug'] !!}" class="tocify-subheader">
+                    @php($inSubHeading = true)
+                @endif
+                    <li class="tocify-item level-2"
+                        data-unique="{!! $previousH1['slug'] !!}-{!! $heading['slug'] !!}">
+                        <a href="#{!! $heading['slug'] !!}">{{ $heading['text'] }}</a>
+                    </li>
+            @endif
+
+            @if($loop->last)
+                    @if($inSubHeading)
+                    </ul>
+                    @endif
+                </ul>
+            @endif
+        @endforeach
     </div>
 
     @if(isset($metadata['links']))

+ 28 - 0
src/Tools/MarkdownParser.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace Knuckles\Scribe\Tools;
+
+use Illuminate\Support\Str;
+use Parsedown;
+
+class MarkdownParser extends Parsedown
+{
+    public array $headings = [];
+
+    protected function blockHeader($Line)
+    {
+        $block = parent::blockHeader($Line);
+        if (isset($block['element']['name'])) {
+            $level = (int) trim($block['element']['name'], 'h');
+            $slug = Str::slug($block['element']['text']);
+            $block['element']['attributes']['id'] = $slug;
+            $this->headings[] = [
+                'text' => $block['element']['text'],
+                'level' => $level,
+                'slug' => $slug,
+            ];
+        }
+
+        return $block;
+    }
+}

+ 8 - 4
src/Writing/HtmlWriter.php

@@ -4,10 +4,9 @@ namespace Knuckles\Scribe\Writing;
 
 use Illuminate\Support\Facades\View;
 use Knuckles\Scribe\Tools\DocumentationConfig;
-use Knuckles\Scribe\Tools\Globals;
+use Knuckles\Scribe\Tools\MarkdownParser;
 use Knuckles\Scribe\Tools\Utils;
 use Knuckles\Scribe\Tools\WritingUtils;
-use Parsedown;
 
 /**
  * Transforms the extracted data (endpoints YAML, API details Markdown) into a HTML site
@@ -17,12 +16,12 @@ class HtmlWriter
     protected DocumentationConfig $config;
     protected string $baseUrl;
     protected string $assetPathPrefix;
-    protected Parsedown $markdownParser;
+    protected MarkdownParser $markdownParser;
 
     public function __construct(DocumentationConfig $config = null)
     {
         $this->config = $config ?: new DocumentationConfig(config('scribe', []));
-        $this->markdownParser = new Parsedown();
+        $this->markdownParser = new MarkdownParser();
         $this->baseUrl = $this->config->get('base_url') ?? config('app.url');
         // If they're using the default static path,
         // then use '../docs/{asset}', so assets can work via Laravel app or via index.html
@@ -38,9 +37,12 @@ class HtmlWriter
     {
         $intro = $this->transformMarkdownFileToHTML($sourceFolder . '/intro.md');
         $auth = $this->transformMarkdownFileToHTML($sourceFolder . '/auth.md');
+        $headingsBeforeEndpoints = $this->markdownParser->headings;
 
+        $this->markdownParser->headings = [];
         $appendFile = rtrim($sourceFolder, '/') . '/' . 'append.md';
         $append = file_exists($appendFile) ? $this->transformMarkdownFileToHTML($appendFile) : '';
+        $headingsAfterEndpoints = $this->markdownParser->headings;
 
         $theme = $this->config->get('theme') ?? 'default';
         $output = View::make("scribe::themes.$theme.index", [
@@ -52,6 +54,8 @@ class HtmlWriter
             'groupedEndpoints' => $groupedEndpoints,
             'append' => $append,
             'assetPathPrefix' => $this->assetPathPrefix,
+            'headingsBeforeEndpoints' => $headingsBeforeEndpoints,
+            'headingsAfterEndpoints' => $headingsAfterEndpoints,
         ])->render();
 
         if (!is_dir($destinationFolder)) {