Skip to content

Commit

Permalink
Auto-Generated Table of Contents in Sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
ilexp committed Feb 4, 2019
1 parent 4025d7c commit e7e3e17
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 61 deletions.
108 changes: 53 additions & 55 deletions _includes/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,21 @@
{% assign pageUrlWithoutExt = page.url | split: '.html' | first %}
{% assign childPages = site.pages | where: 'version', targetVersion | where: 'parent', pageUrlWithoutExt %}
{% assign siblingPages = site.pages | where: 'version', targetVersion | where: 'parent', page.parent %}
<!-- Debug Output -->
<ul class="debug">
<li>Path: {{ page.path | jsonify }}</li>
<li>URL: {{ page.url | jsonify }}</li>
<li>URL (no ext): {{ pageUrlWithoutExt | jsonify }}</li>
<li>Version: {{ page.version | jsonify }}</li>
<li>Category: {{ page.category | jsonify }}</li>
<li>Children: {{ childPages.size | jsonify }}</li>
<li>Siblings: {{ siblingPages.size | jsonify }}</li>
<li>Parent: {% if parentPage %} {{ parentPage.url | jsonify }} {% else %} null {% endif %}</li>
</ul>

<a id="addPage" class="button" href="{{ site.github.repository_url }}">Add Page</a>
<!-- If we have either, only display parent and child pages -->
{% if parentPage or childPages.size > 0 %}
{% if parentPage %}
<a class="contentLink" href="{{ site.baseurl }}{{ parentPage.url }}#mainContent">&lt; Go Back</a>
<a class="pageLink" href="{{ site.baseurl }}{{ parentPage.url }}">&lt; Go Back</a>
{% else %}
<a href="{{ site.baseurl }}/">&lt; Go Back</a>

<div class="sidebarcontent">
<!-- If we are displaying anything but the top level page overview, display a back button -->
{% if parentPage or childPages.size > 0 or page.notoc != true %}
{% if parentPage %}
<a class="contentLink" href="{{ site.baseurl }}{{ parentPage.url }}#mainContent">&lt; Go Back</a>
<a class="pageLink" href="{{ site.baseurl }}{{ parentPage.url }}">&lt; Go Back</a>
{% else %}
<a href="{{ site.baseurl }}/">&lt; Go Back</a>
{% endif %}
{% endif %}

<!-- If we have child pages, display an overview of them -->
{% if childPages.size > 0 %}
<h4>{{ page.title }}</h4>
<ul>
Expand All @@ -36,6 +31,11 @@ <h4>{{ page.title }}</h4>
</li>
{% endfor %}
</ul>
<!-- If we have a page-local table of contents, display that one -->
{% elsif page.notoc != true %}
<h4>{{ page.title }}</h4>
{% include toc.html html=content h_max=3 sanitize=true %}
<!-- If we have sibling pages, display links to them -->
{% elsif siblingPages.size > 0 %}
<h4>{{ parentPage.title }}</h4>
<ul>
Expand All @@ -46,48 +46,46 @@ <h4>{{ parentPage.title }}</h4>
</li>
{% endfor %}
</ul>
<!-- Otherwise, display top-level manual pages grouped by category. -->
{% else %}
<h4>{{ page.title }}</h4>
{% assign sortedPages = site.pages | where: 'version', targetVersion | sort: 'displayOrder' %}
{% for category in site.topLevelCategories %}
<h4>{{ category.title }}</h4>
<ul>
{% for pageItem in sortedPages %}
{% if pageItem.category and pageItem.category == category.id %}
<li>
<a class="contentLink" href="{{ site.baseurl }}{{ pageItem.url }}#mainContent">{{ pageItem.title }}</a>
<a class="pageLink" href="{{ site.baseurl }}{{ pageItem.url }}">{{ pageItem.title }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}
{% endif %}
<!-- Otherwise, display top-level manual pages grouped by category. -->
{% else %}
{% assign sortedPages = site.pages | where: 'version', targetVersion | sort: 'displayOrder' %}
{% for category in site.topLevelCategories %}
<h4>{{ category.title }}</h4>
<!-- Display available versions of this page -->
{% assign versionPath = page.version | prepend: '/' %}
{% assign urlAfterVersion = page.url | split: versionPath | last %}
{% assign versionPages = "" | split: "" %}
{% for pageItem in site.pages %}
{% assign itemVersionPath = pageItem.version | prepend: '/' %}
{% assign itemUrlAfterVersion = pageItem.url | split: itemVersionPath | last %}
{% if itemUrlAfterVersion == urlAfterVersion %}
{% assign versionPages = versionPages | push: pageItem %}
{% endif %}
{% endfor %}
{% assign sortedVersionPages = versionPages | sort:"version" %}
<div class="versionList">
<h4>Versions:</h4>
<ul>
{% for pageItem in sortedPages %}
{% if pageItem.category and pageItem.category == category.id %}
<li>
<a class="contentLink" href="{{ site.baseurl }}{{ pageItem.url }}#mainContent">{{ pageItem.title }}</a>
<a class="pageLink" href="{{ site.baseurl }}{{ pageItem.url }}">{{ pageItem.title }}</a>
</li>
{% for pageItem in sortedVersionPages %}
{% if pageItem.version == targetVersion %}
<li id="activeVersion">{{ pageItem.version }}</li>
{% else %}
<li><a href="{{ site.baseurl }}{{ pageItem.url }}">{{ pageItem.version }}</a></li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}
{% endif %}
<!-- Display available versions of this page -->
{% assign versionPath = page.version | prepend: '/' %}
{% assign urlAfterVersion = page.url | split: versionPath | last %}
{% assign versionPages = "" | split: "" %}
{% for pageItem in site.pages %}
{% assign itemVersionPath = pageItem.version | prepend: '/' %}
{% assign itemUrlAfterVersion = pageItem.url | split: itemVersionPath | last %}
{% if itemUrlAfterVersion == urlAfterVersion %}
{% assign versionPages = versionPages | push: pageItem %}
{% endif %}
{% endfor %}
{% assign sortedVersionPages = versionPages | sort:"version" %}
<div class="versionList">
<h4>Versions:</h4>
<ul>
{% for pageItem in sortedVersionPages %}
{% if pageItem.version == targetVersion %}
<li id="activeVersion">{{ pageItem.version }}</li>
{% else %}
<li><a href="{{ site.baseurl }}{{ pageItem.url }}">{{ pageItem.version }}</a></li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</nav>
87 changes: 87 additions & 0 deletions _includes/toc.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{% capture tocWorkspace %}
{% comment %}
Version 1.0.6
https://github.com/allejo/jekyll-toc

"...like all things liquid - where there's a will, and ~36 hours to spare, there's usually a/some way" ~jaybe

Usage:
{% include toc.html html=content sanitize=true class="inline_toc" id="my_toc" h_min=2 h_max=3 %}

Parameters:
* html (string) - the HTML of compiled markdown generated by kramdown in Jekyll

Optional Parameters:
* sanitize (bool) : false - when set to true, the headers will be stripped of any HTML in the TOC
* class (string) : '' - a CSS class assigned to the TOC
* id (string) : '' - an ID to assigned to the TOC
* h_min (int) : 1 - the minimum TOC header level to use; any header lower than this value will be ignored
* h_max (int) : 6 - the maximum TOC header level to use; any header greater than this value will be ignored
* ordered (bool) : false - when set to true, an ordered list will be outputted instead of an unordered list
* item_class (string) : '' - add custom class(es) for each list item; has support for '%level%' placeholder, which is the current heading level
* baseurl (string) : '' - add a base url to the TOC links for when your TOC is on another page than the actual content
* anchor_class (string) : '' - add custom class(es) for each anchor element

Output:
An ordered or unordered list representing the table of contents of a markdown block. This snippet will only
generate the table of contents and will NOT output the markdown given to it
{% endcomment %}

{% capture my_toc %}{% endcapture %}
{% assign orderedList = include.ordered | default: false %}
{% assign minHeader = include.h_min | default: 1 %}
{% assign maxHeader = include.h_max | default: 6 %}
{% assign nodes = include.html | split: '<h' %}
{% assign firstHeader = true %}

{% capture listModifier %}{% if orderedList %}1.{% else %}-{% endif %}{% endcapture %}

{% for node in nodes %}
{% if node == "" %}
{% continue %}
{% endif %}

{% assign headerLevel = node | replace: '"', '' | slice: 0, 1 | times: 1 %}

{% if headerLevel < minHeader or headerLevel > maxHeader %}
{% continue %}
{% endif %}

{% if firstHeader %}
{% assign firstHeader = false %}
{% assign minHeader = headerLevel %}
{% endif %}

{% assign indentAmount = headerLevel | minus: minHeader | add: 1 %}
{% assign _workspace = node | split: '</h' %}

{% assign _idWorkspace = _workspace[0] | split: 'id="' %}
{% assign _idWorkspace = _idWorkspace[1] | split: '"' %}
{% assign html_id = _idWorkspace[0] %}

{% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %}
{% assign header = _workspace[0] | replace: _hAttrToStrip, '' %}

{% assign space = '' %}
{% for i in (1..indentAmount) %}
{% assign space = space | prepend: ' ' %}
{% endfor %}

{% unless include.item_class == blank %}
{% capture listItemClass %}{:.{{ include.item_class | replace: '%level%', headerLevel }}}{% endcapture %}
{% endunless %}

{% capture my_toc %}{{ my_toc }}
{{ space }}{{ listModifier }} {{ listItemClass }} [{% if include.sanitize %}{{ header | strip_html }}{% else %}{{ header }}{% endif %}]({% if include.baseurl %}{{ include.baseurl }}{% endif %}#{{ html_id }}){% if include.anchor_class %}{:.{{ include.anchor_class }}}{% endif %}{% endcapture %}
{% endfor %}

{% if include.class %}
{% capture my_toc %}{:.{{ include.class }}}
{{ my_toc | lstrip }}{% endcapture %}
{% endif %}

{% if include.id %}
{% capture my_toc %}{: #{{ include.id }}}
{{ my_toc | lstrip }}{% endcapture %}
{% endif %}
{% endcapture %}{% assign tocWorkspace = '' %}{{ my_toc | markdownify | strip }}
1 change: 1 addition & 0 deletions index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "Home"
category: "introduction"
displayOrder: -100
version: "v3"
notoc: true
---

Welcome to the Duality docs pages! If you're looking for a **developer manual**, check the side bar to your left.
Expand Down
4 changes: 1 addition & 3 deletions pages/v2/Choosing-Duality.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ title: "Should You Use Duality?"
category: "introduction"
displayOrder: 10
version: "v2"
notoc: true
---

Someone once said: "Every game engine sucks - but each in its own, unique way". Choosing an engine is not about going through a shopping list of billboard features, it's not even about deciding which one is "better". It's about setting priorities and identifying requirements: What does your game need, and what do _you_ need, as a developer? What do you value? This guide is here to help you decide whether your next project should be made with Duality.

_If you haven't read the info page yet, [head over here](https://www.duality2d.net) first._

* TOC
{:toc}

# About Duality

So let's take a close, honest look. If you're with us by the end of this chapter, Duality and you have a solid chance.
Expand Down
1 change: 1 addition & 0 deletions pages/v2/List-of-Community-Projects.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "List of Community Projects"
category: "development"
displayOrder: 0
version: "v2"
notoc: true
---

The following is a list of projects that are maintained and published by the community. Feel free to add your own if you think that it could be useful to others!
Expand Down
1 change: 1 addition & 0 deletions pages/v2/Requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "Requirements"
category: "introduction"
displayOrder: 0
version: "v2"
notoc: true
---

To launch a Duality application, the end user needs the [.Net Framework 4.5](https://www.google.de/#hl=en&q=.net+framework+4.5) on Windows machines, or the equivalent [Mono](http://www.mono-project.com/) version on non-Windows machines. The actual hardware minimum to launch a Duality application depends on the application itself.
Expand Down
4 changes: 1 addition & 3 deletions pages/v3/Choosing-Duality.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ title: "Should You Use Duality?"
category: "introduction"
displayOrder: 10
version: "v3"
notoc: true
---

Someone once said: "Every game engine sucks - but each in its own, unique way". Choosing an engine is not about going through a shopping list of billboard features, it's not even about deciding which one is "better". It's about setting priorities and identifying requirements: What does your game need, and what do _you_ need, as a developer? What do you value? This guide is here to help you decide whether your next project should be made with Duality.

_If you haven't read the info page yet, [head over here](https://www.duality2d.net) first._

* TOC
{:toc}

# About Duality

So let's take a close, honest look. If you're with us by the end of this chapter, Duality and you have a solid chance.
Expand Down
1 change: 1 addition & 0 deletions pages/v3/List-of-Community-Projects.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "List of Community Projects"
category: "development"
displayOrder: 0
version: "v3"
notoc: true
---

The following is a list of projects that are maintained and published by the community. Feel free to add your own if you think that it could be useful to others!
Expand Down
1 change: 1 addition & 0 deletions pages/v3/Requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "Requirements"
category: "introduction"
displayOrder: 0
version: "v3"
notoc: true
---

To launch a Duality application, the end user needs the [.Net Framework 4.5](https://www.google.de/#hl=en&q=.net+framework+4.5) on Windows machines, or the equivalent [Mono](http://www.mono-project.com/) version on non-Windows machines. The actual hardware minimum to launch a Duality application depends on the application itself, but graphics support for OpenGL 3.0 or OpenGL ES 2.0 is a common baseline.
Expand Down

0 comments on commit e7e3e17

Please sign in to comment.