Skip to content

Commit

Permalink
Merge pull request #1 from develop
Browse files Browse the repository at this point in the history
Initial implementation
  • Loading branch information
fzankl committed Jan 5, 2019
2 parents 510119e + f35bce8 commit 94cab4e
Show file tree
Hide file tree
Showing 10 changed files with 417 additions and 1 deletion.
24 changes: 24 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Editor configuration, see http://editorconfig.org
root = true

[*]
charset = utf-8
indent_style = space

[*.js]
insert_final_newline = true
trim_trailing_whitespace = true
indent_size = 2

[*.md]
max_line_length = off
trim_trailing_whitespace = false
indent_size = 2

[{*.txt,*.json,*.xml}]
insert_final_newline = false
indent_size = 2

[*.yml]
insert_final_newline = true
indent_size = 2
6 changes: 6 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*
!book/**
!index.js
!package.json
!LICENSE
!README.md
11 changes: 11 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
language: node_js
node_js:
- "node"

deploy:
provider: npm
email: "$NPM_MAIL"
api_key: "$NPM_TOKEN"
on:
tags: true
branch: master
114 changes: 113 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,113 @@
# gitbook-plugin-intopic-toc
# GitBook Plugin: InTopic TOC

This GitBook Plugin adds an inline table of contents (TOC) to each page based on configurable selectors. Inline TOC can be enabled or disabled by default or on individual pages. TOC is placed on the right side and moves to top for smaller devices automatically.

Inline TOC stays at the top of the page when scrolling using a sticky effect. Current position is highlighted by a scrollspy effect.

![Inline TOC in desktop and mobile mode](https://user-images.githubusercontent.com/44210522/50728477-ab322680-112a-11e9-92da-4de20e17758d.png)

## Installation

### Step #1 - Update book.json file

1. In you gitbook's book.json file, add `intopic-toc` to plugins list.
2. In pluginsConfig, configure the plugin so it does fit your needs. A custom setup is not mandatory.

**Sample `book.json` file for gitbook version 2.0.0+**

```json
{
"plugins": [
"intopic-toc"
]
}
```

**Sample `book.json` file for gitbook version 2.0.0+ and custom heading**

```json
{
"plugins": [
"intopic-toc"
],
"pluginsConfig": {
"intopic-toc": {
"label": "Navigation"
}
}
}
```

**Sample `book.json` file for gitbook version 2.0.0+ and multilingual headings**

```json
{
"plugins": [
"intopic-toc"
],
"pluginsConfig": {
"intopic-toc": {
"label": {
"de": "In diesem Artikel",
"en": "In this article"
}
}
}
}
```

Note: Above snippets can be used as complete `book.json` file, if one of these matches your requirements and your book doesn't have one yet.

### Step #2 - gitbook commands

1. Run `gitbook install`. It will automatically install `intopic-toc` gitbook plugin for your book. This is needed only once.
2. Build your book (`gitbook build`) or serve (`gitbook serve`) as usual.

## Usage

For basic usage, the only thing you have to do is install the plugin. For advanced scenarios see following configuration sample.

```json
{
"plugins": [
"intopic-toc"
],
"pluginsConfig": {
"intopic-toc": {
"selector": ".markdown-section h2",
"visible": true,
"label": {
"de": "In diesem Artikel",
"en": "In this article"
},
}
}
}
```

* selector : Selector used to find elements to put anchors on.
* Default: .markdown-section h2
* visible: Defines whether to show the navigation on every page.
* Default: true.
* label: Label which is used as heading for the navigation. Could be a single string or an object for multilingual setups.
* Default: In this article

If `visible` parameter set to true and you want to hide the TOC on a single page, add the front matter item `isTocVisible: false` to the top of the Markdown file like this:

```markdown
---
isTocVisible: false
---
# My awesome documentation

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, ...
```

The specific front matter `isTocVisible` overrides the `visible` parameter from global configuration.

## Troubleshooting

If inline TOC does not look as expected, check if your `book.json` is valid according to this documentation.

## Changelog
01/05/2019 - Initial Release
7 changes: 7 additions & 0 deletions book/anchor.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

115 changes: 115 additions & 0 deletions book/plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
var selector;
var label;
var isVisibleByDefault;

require(["gitbook", "jQuery"], function(gitbook, $) {
anchors.options = {
placement: 'left'
};

gitbook.events.bind('start', function(e, config) {
var configuration = config['intopic-toc'];
selector = configuration.selector;
isVisibleByDefault = configuration.visible;
label = configuration.label;

// Label can be language specific and could be specified via user configuration
if (typeof label === 'object') {
var language = gitbook.state.innerLanguage;

if (language && label.hasOwnProperty(language)) {
label = label[language];
} else {
label = '';
}
}

// Hide navigation if a search is ative
$bookSearchResults = $('#book-search-results');

var observer = new MutationObserver(() => {
if ($bookSearchResults.hasClass('open')) {
$('.intopic-toc').hide();
}
else {
$('.intopic-toc').show();
}
});

observer.observe($bookSearchResults[0], { attributes: true });
});

gitbook.events.bind("page.change", function() {
anchors.removeAll();
anchors.add(selector);

var isVisible = (isVisibleByDefault || gitbook.state.page.isTocVisible) && gitbook.state.page.isTocVisible != false;

if (anchors.elements.length > 1 && isVisible) {
var navigation = buildNavigation(anchors.elements);

var section = document.body.querySelector('.page-wrapper');
section.appendChild(navigation, section.firstChild);

$(".book-body .body-inner").scroll(onScroll);
}
});
});

function buildNavigation(elements) {
var navigation = document.createElement('nav');
navigation.className = 'intopic-toc';

var heading = document.createElement('h3');
heading.innerText = label;
navigation.appendChild(heading);

var container = document.createElement('ol');
navigation.appendChild(container);

for (var i = 0; i < elements.length; i++) {
var text = elements[i].textContent;
var href = elements[i].querySelector('.anchorjs-link').getAttribute('href');

var item = document.createElement('li');

if (i === 0) {
item.classList.add('selected');
}

var anchor = document.createElement('a');
anchor.text = text;
anchor.href = href;

item.appendChild(anchor);
container.appendChild(item);
}

return navigation;
}

function onScroll(e) {
const currentPosition = $(e.target).scrollTop() + $('.book-header').height();

for (var i = 0; i < anchors.elements.length; i++) {
const section = anchors.elements[i];
const isInView = $(section).offset().top < currentPosition;

if (isInView) {
const menuItemID = section.getAttribute('id');
const activeItem = $(`.intopic-toc ol li`).has(`a[href="#${menuItemID}"]`);

if (!activeItem) {
return;
}

$('.intopic-toc ol li').each(function() {
$(this).attr('data-active', 'false');
$(this).removeClass('selected');
});

$(activeItem).attr('data-active', 'true');
$(activeItem).addClass('selected');
}
}
}
74 changes: 74 additions & 0 deletions book/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
.intopic-toc {
width: 20%;
padding: 20px 15px 40px 15px;
position: -webkit-sticky;
position: sticky;
top: 0;
}

.page-wrapper {
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: row;
}

.page-inner {
margin: 0 !important;
width: 80% !important;
}

.intopic-toc h3 {
margin-top: 0;
font-size:1.5em;
margin: 10px 0 0;
color: #000;
}

.intopic-toc ol {
margin: 10px 0 0;
list-style: none;
padding: 0!important;
list-style-type: none;
}

.intopic-toc ol {
list-style: none;
}

.intopic-toc li {
line-height: 1.3;
border: solid transparent;
border-width: 0 0 0 3px;
padding: 2px 0 2px 4px;
margin: 4px 0;
}

.intopic-toc li.selected {
font-weight: 600;
border-color: hsla(206, 100%, 35%, 1);
}

.intopic-toc li a {
color: hsla(206, 100%, 35%, 1);
}

@media (max-width: 1240px) {
.intopic-toc {
width: 100%;
padding-bottom: 0;
}

.intopic-toc li {
border-width: 0;
}

.intopic-toc li.selected {
border-color: transparent;
font-weight: normal;
}

.page-wrapper {
flex-direction: column-reverse;
}
}
12 changes: 12 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
book: {
assets: "./book",
js: [
"anchor.min.js",
"plugin.js"
],
css: [
"style.css"
]
}
};
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 94cab4e

Please sign in to comment.