sanskrit-documentation-theme 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -2
- data/_includes/head.html +15 -11
- data/_includes/jekyll_vars_to_js.html +27 -0
- data/_includes/sidebar.html +4 -14
- data/_includes/topnav.html +8 -18
- data/_layouts/default.html +8 -66
- data/_layouts/page.html +12 -13
- data/assets/css/class-styles-general.scss +44 -21
- data/assets/css/element-styles-general.scss +7 -3
- data/assets/css/embeds.scss +19 -0
- data/assets/css/navbar-toc.scss +31 -153
- data/assets/css/topnav.scss +86 -0
- data/assets/js/navgoco.js +314 -0
- data/assets/js/on_doc_ready/audio_embed.js +45 -0
- data/assets/js/on_doc_ready/handle_includes.js +175 -0
- data/assets/js/on_doc_ready/main.js +0 -0
- data/assets/js/on_doc_ready/sidebar.js +119 -0
- data/assets/js/on_doc_ready/toc.js +159 -0
- data/assets/js/on_doc_ready/video_embed.js +52 -0
- metadata +12 -8
- data/_includes/functions/recursive_item_to_list.html +0 -29
- data/_includes/toc.html +0 -38
- data/assets/css/theme-blue.scss +0 -140
- data/assets/js/customscripts.js +0 -54
- data/assets/js/jquery.navgoco.min.js +0 -8
- data/assets/js/toc.js +0 -73
@@ -0,0 +1,45 @@
|
|
1
|
+
function mp3Embed(audioEmbedTag) {
|
2
|
+
var src = audioEmbedTag.getAttribute( "src" );
|
3
|
+
var caption = audioEmbedTag.getAttribute( "caption" );
|
4
|
+
if(src.indexOf('.mp3') !== -1) {
|
5
|
+
var srcParts = src.split('?');
|
6
|
+
if(srcParts.length == 1) srcParts[1] = '';
|
7
|
+
var unrecognizedParameterString = srcParts[1];
|
8
|
+
unrecognizedParameterString = unrecognizedParameterString.replace('&','').replace('&','');
|
9
|
+
unrecognizedParameterString = unrecognizedParameterString.replace('autoplay=1','').replace('autoplay=0','');
|
10
|
+
unrecognizedParameterString = unrecognizedParameterString.replace('loop=1','').replace('loop=0','');
|
11
|
+
unrecognizedParameterString = unrecognizedParameterString.replace('controls=0','').replace('controls=1','');
|
12
|
+
|
13
|
+
if (srcParts[0].lastIndexOf('.mp3', srcParts[0].length - 4) === srcParts[0].length - 4 && unrecognizedParameterString.length == 0) {
|
14
|
+
if(srcParts[1].indexOf('autoplay=1') !== -1) var autoplay=1; else var autoplay=0;
|
15
|
+
if(srcParts[1].indexOf('loop=1') !== -1) var loop=1; else var loop=0;
|
16
|
+
if(srcParts[1].indexOf('controls=0') !== -1) var controls=0; else var controls=1;
|
17
|
+
var newInnerHTML = '<audio';
|
18
|
+
if(autoplay==1) newInnerHTML += ' autoplay';
|
19
|
+
if(loop==1) newInnerHTML += ' loop';
|
20
|
+
if(controls==1) newInnerHTML += ' controls';
|
21
|
+
newInnerHTML += '><source src="'+srcParts[0]+'" type="audio/mpeg">Your browser does not support the audio element, but here is <a href="' + srcParts[0] + '">a link.</a></audio>';
|
22
|
+
if(caption) {
|
23
|
+
newInnerHTML += `(${caption})`;
|
24
|
+
}
|
25
|
+
audioEmbedTag.innerHTML = newInnerHTML;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
function fillAudioEmbeds() {
|
31
|
+
var audioEmbedTags = document.querySelectorAll('.audioEmbed');
|
32
|
+
audioEmbedTags.forEach(function (audioEmbedTag) {
|
33
|
+
mp3Embed(audioEmbedTag);
|
34
|
+
});
|
35
|
+
document.addEventListener('play', function(e){
|
36
|
+
var audios = document.getElementsByTagName('audio');
|
37
|
+
for(var i = 0, len = audios.length; i < len;i++){
|
38
|
+
if(audios[i] != e.target){
|
39
|
+
audios[i].pause();
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}, true);
|
43
|
+
}
|
44
|
+
|
45
|
+
$(document).ready(fillAudioEmbeds);
|
@@ -0,0 +1,175 @@
|
|
1
|
+
|
2
|
+
/*
|
3
|
+
Example: absoluteUrl("../subfolder1/divaspari.md", "images/forest-fire.jpg") == "../subfolder1/images/forest-fire.jpg"
|
4
|
+
*/
|
5
|
+
function absoluteUrl(base, relative) {
|
6
|
+
// console.debug(base, relative);
|
7
|
+
if (relative.startsWith("http") || relative.startsWith("file")) {
|
8
|
+
return relative;
|
9
|
+
}
|
10
|
+
if (relative.startsWith("/") && !base.startsWith("http") && !base.startsWith("file")) {
|
11
|
+
return relative;
|
12
|
+
}
|
13
|
+
var stack = base.toString().split("/"),
|
14
|
+
parts = relative.split("/");
|
15
|
+
stack.pop(); // remove current file name (or empty string)
|
16
|
+
// (omit if "base" is the current folder without trailing slash)
|
17
|
+
for (var i=0; i<parts.length; i++) {
|
18
|
+
if (parts[i] == ".")
|
19
|
+
continue;
|
20
|
+
if (parts[i] == "..")
|
21
|
+
stack.pop();
|
22
|
+
else
|
23
|
+
stack.push(parts[i]);
|
24
|
+
}
|
25
|
+
return stack.join("/");
|
26
|
+
}
|
27
|
+
|
28
|
+
// WHen you include html from one page within another, you need to fix image urls, anchor urls etc..
|
29
|
+
function fixIncludedHtml(url, html, newLevelForH1) {
|
30
|
+
// We want to use jquery to parse html, but without loading images. Hence this.
|
31
|
+
// Tip from: https://stackoverflow.com/questions/15113910/jquery-parse-html-without-loading-images
|
32
|
+
var virtualDocument = document.implementation.createHTMLDocument('virtual');
|
33
|
+
var jqueryElement = $(html, virtualDocument);
|
34
|
+
|
35
|
+
// console.debug(jqueryElement.html());
|
36
|
+
// Remove some tags.
|
37
|
+
jqueryElement.find("script").remove();
|
38
|
+
jqueryElement.find("footer").remove();
|
39
|
+
jqueryElement.find("#disqus_thread").remove();
|
40
|
+
jqueryElement.find("#toc").remove();
|
41
|
+
jqueryElement.find("#toc_header").remove();
|
42
|
+
jqueryElement.find(".back-to-top").remove();
|
43
|
+
// console.debug(jqueryElement.html());
|
44
|
+
|
45
|
+
// Deal with includes within includes. Do this before fixing images urls etc.. because there may be images within the newly included html.
|
46
|
+
jqueryElement.find('.js_include').each(function() {
|
47
|
+
if (newLevelForH1 < 1) {
|
48
|
+
console.error("Ignoring invalid newLevelForH1: %d, using 6", newLevelForH1);
|
49
|
+
newLevelForH1 = 6;
|
50
|
+
}
|
51
|
+
var jsIncludeElement = $(this);
|
52
|
+
var includedPageNewLevelForH2 = parseInt(jsIncludeJqueryElement.attr("newLevelForH1"));
|
53
|
+
if (includedPageNewLevelForH2 == undefined) {
|
54
|
+
includedPageNewLevelForH2 = 6;
|
55
|
+
}
|
56
|
+
includedPageNewLevelForH2 = Math.min(6, ((includedPageNewLevelForH2 - 2) + newLevelForH1));
|
57
|
+
fillJsInclude($(this), includedPageNewLevelForH2);
|
58
|
+
});
|
59
|
+
|
60
|
+
/*
|
61
|
+
Fix headers in the included html so as to not mess up the table of contents
|
62
|
+
of the including page.
|
63
|
+
Adjusting the heading levels to retain substructure seems more complicated -
|
64
|
+
getting the heading "under" which jsIncludeJqueryElement falls seems non-trivial.
|
65
|
+
*/
|
66
|
+
var headers = jqueryElement.find(":header");
|
67
|
+
if (headers.length > 0) {
|
68
|
+
var id_prefix = headers[0].id;
|
69
|
+
headers.replaceWith(function() {
|
70
|
+
var headerElement = $(this);
|
71
|
+
// console.debug(headerElement);
|
72
|
+
var hLevel = parseInt(headerElement.prop("tagName").substring(1));
|
73
|
+
var hLevelNew = Math.min(6, newLevelForH1 - 1 + hLevel);
|
74
|
+
var newId = id_prefix + "_" + headerElement[0].id;
|
75
|
+
return $("<h" + hLevelNew +" id='" + newId + "'/>").append(headerElement.contents());
|
76
|
+
});
|
77
|
+
}
|
78
|
+
|
79
|
+
// Fix image urls.
|
80
|
+
jqueryElement.find("img").each(function() {
|
81
|
+
// console.log(absoluteUrl(url, $(this).attr("src")));
|
82
|
+
// console.log($(this).attr("src"))
|
83
|
+
$(this).attr("src", absoluteUrl(url, $(this).attr("src")));
|
84
|
+
// console.log($(this).attr("src"))
|
85
|
+
});
|
86
|
+
|
87
|
+
// Fix links.
|
88
|
+
jqueryElement.find("a").each(function() {
|
89
|
+
// console.debug($(this).html());
|
90
|
+
var href = $(this).attr("href");
|
91
|
+
if (href.startsWith("#")) {
|
92
|
+
var headers = jqueryElement.find(":header");
|
93
|
+
var new_href = href;
|
94
|
+
if (headers.length > 0) {
|
95
|
+
var id_prefix = headers[0].id;
|
96
|
+
new_href = id_prefix + "_" + href.substr(1);
|
97
|
+
// console.debug(new_href, id_prefix, href);
|
98
|
+
jqueryElement.find(href).each(function () {
|
99
|
+
$(this).attr("id", new_href.substr(1));
|
100
|
+
});
|
101
|
+
}
|
102
|
+
$(this).attr("href", new_href);
|
103
|
+
} else {
|
104
|
+
$(this).attr("href", absoluteUrl(url, href));
|
105
|
+
}
|
106
|
+
});
|
107
|
+
|
108
|
+
return jqueryElement;
|
109
|
+
}
|
110
|
+
|
111
|
+
function fillJsInclude(jsIncludeJqueryElement, includedPageNewLevelForH1) {
|
112
|
+
var includedPageUrl = jsIncludeJqueryElement.attr("url").replace(".md", ".html");
|
113
|
+
if (includedPageNewLevelForH1 == undefined) {
|
114
|
+
includedPageNewLevelForH1 = parseInt(jsIncludeJqueryElement.attr("newLevelForH1"));
|
115
|
+
}
|
116
|
+
if (includedPageNewLevelForH1 == undefined) {
|
117
|
+
includedPageNewLevelForH1 = 6;
|
118
|
+
}
|
119
|
+
$.ajax(includedPageUrl,{
|
120
|
+
success: function(responseHtml) {
|
121
|
+
// We want to use jquery to parse html, but without loading images. Hence this.
|
122
|
+
// Tip from: https://stackoverflow.com/questions/15113910/jquery-parse-html-without-loading-images
|
123
|
+
var virtualDocument = document.implementation.createHTMLDocument('virtual');
|
124
|
+
|
125
|
+
var titleElements = $(responseHtml, virtualDocument).find(".post-title-main");
|
126
|
+
var title = "";
|
127
|
+
if (titleElements.length > 0) {
|
128
|
+
// console.debug(titleElements[0]);
|
129
|
+
title = titleElements[0].textContent;
|
130
|
+
}
|
131
|
+
|
132
|
+
var contentElements = $(responseHtml, virtualDocument).find(".post-content");
|
133
|
+
// console.log(contentElements);
|
134
|
+
if (contentElements.length == 0) {
|
135
|
+
console.warn("Could not get \"post-content\" class element.");
|
136
|
+
console.log(responseHtml);
|
137
|
+
} else {
|
138
|
+
// We don't want multiple post-content divs, hence we replace with an included-post-content div.
|
139
|
+
var elementToInclude = $("<div class='included-post-content'/>")
|
140
|
+
var titleHtml = "";
|
141
|
+
if (jsIncludeJqueryElement.attr("includeTitle")) {
|
142
|
+
titleHtml = "<h1 id='" + title + "'>" + title + "</h1>" +
|
143
|
+
"<a class='btn btn-default' href='" + absoluteUrl(document.location, includedPageUrl) + "'>See separately</a>";
|
144
|
+
}
|
145
|
+
elementToInclude.html(titleHtml + contentElements[0].innerHTML);
|
146
|
+
var contentElement = fixIncludedHtml(includedPageUrl, elementToInclude, includedPageNewLevelForH1);
|
147
|
+
jsIncludeJqueryElement.html(contentElement);
|
148
|
+
fillAudioEmbeds();
|
149
|
+
fillVideoEmbeds();
|
150
|
+
updateToc();
|
151
|
+
}
|
152
|
+
},
|
153
|
+
error: function(xhr, error){
|
154
|
+
var titleHtml = "";
|
155
|
+
var title = "Missing page.";
|
156
|
+
if (jsIncludeJqueryElement.attr("includeTitle")) {
|
157
|
+
titleHtml = "<h1 id='" + title + "'>" + title + "</h1>";
|
158
|
+
}
|
159
|
+
jsIncludeJqueryElement.html(titleHtml + "Could not get: " + includedPageUrl + " See debug messages in console for details.");
|
160
|
+
console.debug(xhr); console.debug(error);
|
161
|
+
}
|
162
|
+
});
|
163
|
+
}
|
164
|
+
|
165
|
+
// Process includes of the form:
|
166
|
+
// <div class="js_include" url="index.md"/>
|
167
|
+
$( document ).ready(function() {
|
168
|
+
$('.js_include').each(function() {
|
169
|
+
console.debug("Inserting include for " + $(this).html());
|
170
|
+
var jsIncludeJqueryElement = $(this);
|
171
|
+
// The actual filling happens in a separate thread!
|
172
|
+
fillJsInclude(jsIncludeJqueryElement);
|
173
|
+
});
|
174
|
+
});
|
175
|
+
|
File without changes
|
@@ -0,0 +1,119 @@
|
|
1
|
+
$('#displayed_sidebar').height($(".nav").height());
|
2
|
+
|
3
|
+
function getSidebarItemHtml(sidebarItem) {
|
4
|
+
var item_url_stripped = sidebarItem.url || "#";
|
5
|
+
item_url_stripped = item_url_stripped.replace("index.html", "").replace(".md", ".html");
|
6
|
+
|
7
|
+
var urlTarget = "";
|
8
|
+
if (item_url_stripped.startsWith("http://") || item_url_stripped.startsWith("https://") || item_url_stripped.startsWith("ftp://")) {
|
9
|
+
urlTarget = "_newTab";
|
10
|
+
}
|
11
|
+
var list_item_css_class = "inactive";
|
12
|
+
if (pageSettings.url.replace("#[^/]*$", "") == item_url_stripped) {
|
13
|
+
list_item_css_class = "active";
|
14
|
+
}
|
15
|
+
// console.debug(sidebarItem);
|
16
|
+
if(sidebarItem.hasOwnProperty("contents")) {
|
17
|
+
var contentHtml = "";
|
18
|
+
for(let subitem of sidebarItem.contents) {
|
19
|
+
contentHtml = `${contentHtml}\n ${getSidebarItemHtml(subitem)}`;
|
20
|
+
}
|
21
|
+
var title = sidebarItem.title || pageUrlToTitle[item_url_stripped];
|
22
|
+
var itemHtml = `<li><a href="${item_url_stripped}"> ${title}</a>\n<ul>${contentHtml}\n</ul>\n</li>\n`;
|
23
|
+
} else if (sidebarItem.url.startsWith("dir://")) {
|
24
|
+
var dirUrl = sidebarItem.url.replace("dir://", "/");
|
25
|
+
if (dirUrl.endsWith("/")) {
|
26
|
+
dirUrl = dirUrl.slice(0,-1);
|
27
|
+
}
|
28
|
+
if (dirUrl in pageDirectoryToUrl) {
|
29
|
+
var itemHtml = "";
|
30
|
+
// console.debug(dirUrl);
|
31
|
+
for (let contentUrl of pageDirectoryToUrl[dirUrl]) {
|
32
|
+
var subitem = {"url": contentUrl};
|
33
|
+
itemHtml = `${itemHtml}\n ${getSidebarItemHtml(subitem)}`;
|
34
|
+
}
|
35
|
+
} else {
|
36
|
+
console.error(`No such directory ${dirUrl}`)
|
37
|
+
}
|
38
|
+
}
|
39
|
+
else {
|
40
|
+
var title = sidebarItem.title || pageUrlToTitle[item_url_stripped];
|
41
|
+
var itemHtml = `<li class="${list_item_css_class}"><a href="${siteBaseurl + item_url_stripped }" target="">${title}</a></li>`;
|
42
|
+
}
|
43
|
+
return itemHtml;
|
44
|
+
}
|
45
|
+
|
46
|
+
function insertSidebarItems() {
|
47
|
+
var sidebar = siteData.sidebars[pageSettings.sidebar];
|
48
|
+
$("#displayed_sidebar .sidebarTitle").html(sidebar.title);
|
49
|
+
// console.debug(sidebar);
|
50
|
+
for (let sidebarItem of sidebar.contents) {
|
51
|
+
$("#displayed_sidebar").append(getSidebarItemHtml(sidebarItem));
|
52
|
+
}
|
53
|
+
// this highlights the active parent class in the navgoco sidebar. this is critical so that the parent expands when you're viewing a page.
|
54
|
+
$("li.active").parents('li').addClass("active");
|
55
|
+
$("li.active").parents('li').removeClass("inactive");
|
56
|
+
}
|
57
|
+
|
58
|
+
function insertTopnavDropdownItems() {
|
59
|
+
var topnavDropdown = siteData.sidebars[pageSettings.topnav];
|
60
|
+
// console.debug(topnavDropdown);
|
61
|
+
for (let item of topnavDropdown.contents) {
|
62
|
+
$("#topnav_dropdown").append(getSidebarItemHtml(item));
|
63
|
+
}
|
64
|
+
// this highlights the active parent class in the navgoco sidebar. this is critical so that the parent expands when you're viewing a page.
|
65
|
+
$("li.active").parents('li').addClass("active");
|
66
|
+
$("li.active").parents('li').removeClass("inactive");
|
67
|
+
}
|
68
|
+
|
69
|
+
$(document).ready(function() {
|
70
|
+
insertSidebarItems();
|
71
|
+
insertTopnavDropdownItems();
|
72
|
+
// Initialize navgoco sidebar with default options
|
73
|
+
$("#displayed_sidebar").navgoco({
|
74
|
+
caretHtml: '',
|
75
|
+
accordion: true,
|
76
|
+
openClass: 'active', // open
|
77
|
+
save: true,
|
78
|
+
cookie: {
|
79
|
+
name: 'navgoco_sidebar',
|
80
|
+
expires: false,
|
81
|
+
path: '/'
|
82
|
+
},
|
83
|
+
slide: {
|
84
|
+
duration: 400,
|
85
|
+
easing: 'swing'
|
86
|
+
}
|
87
|
+
});
|
88
|
+
});
|
89
|
+
|
90
|
+
$( document ).ready(function() {
|
91
|
+
|
92
|
+
//this script says, if the height of the viewport is greater than 800px, then insert affix class, which makes the nav bar float in a fixed
|
93
|
+
// position as your scroll. if you have a lot of nav items, this height may not work for you.
|
94
|
+
var h = $(window).height();
|
95
|
+
//console.log (h);
|
96
|
+
if (h > 800) {
|
97
|
+
$( "#displayed_sidebar" ).attr("class", "nav affix");
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* AnchorJS
|
102
|
+
*/
|
103
|
+
anchors.add('h2,h3,h4,h5');
|
104
|
+
|
105
|
+
});
|
106
|
+
|
107
|
+
// Code to make the "Nav" button, which toggles the sidebar.
|
108
|
+
var toggleSidebar = function() {
|
109
|
+
$("#tg-sb-sidebar").toggle();
|
110
|
+
$("#tg-sb-icon").toggleClass('fa-toggle-on');
|
111
|
+
$("#tg-sb-icon").toggleClass('fa-toggle-off');
|
112
|
+
$("#tg-sb-icon-content-pane").toggleClass('fa-toggle-on');
|
113
|
+
$("#tg-sb-icon-content-pane").toggleClass('fa-toggle-off');
|
114
|
+
};
|
115
|
+
|
116
|
+
$(document).ready(function() {
|
117
|
+
$("#tg-sb-link").click(toggleSidebar);
|
118
|
+
$("#hide-sb-link").click(toggleSidebar);
|
119
|
+
});
|
@@ -0,0 +1,159 @@
|
|
1
|
+
function get_toc_item_id(header_id) {
|
2
|
+
return "toc_item_" + header_id;
|
3
|
+
}
|
4
|
+
|
5
|
+
// https://github.com/ghiculescu/jekyll-table-of-contents
|
6
|
+
// This is how a jquery plugin is defined - https://stackoverflow.com/questions/2937227/what-does-function-jquery-mean .
|
7
|
+
$.fn.toc = function(options) {
|
8
|
+
console.debug("Setting up TOC for " + document.location);
|
9
|
+
var defaults = {
|
10
|
+
noBackToTopLinks: false,
|
11
|
+
title: '',
|
12
|
+
minimumHeaders: 3,
|
13
|
+
headers: 'h1, h2, h3, h4',
|
14
|
+
listType: 'ol', // values: [ol|ul]
|
15
|
+
},
|
16
|
+
settings = $.extend(defaults, options);
|
17
|
+
|
18
|
+
// console.debug($(settings.headers));
|
19
|
+
var headers = $(settings.headers).filter(function() {
|
20
|
+
// get all headers with an ID
|
21
|
+
var previousSiblingName = $(this).prev().attr( "name" );
|
22
|
+
if (!this.id && previousSiblingName) {
|
23
|
+
this.id = $(this).attr( "id", previousSiblingName.replace(/\./g, "-") );
|
24
|
+
}
|
25
|
+
return this.id;
|
26
|
+
}), output = $(this);
|
27
|
+
if (!headers.length || headers.length < settings.minimumHeaders || !output.length) {
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
// console.debug(headers);
|
31
|
+
|
32
|
+
var get_level = function(ele) { return parseInt(ele.nodeName.replace("H", ""), 10); }
|
33
|
+
var highest_level = headers.map(function(_, ele) { return get_level(ele); }).get().sort()[0];
|
34
|
+
|
35
|
+
var level = get_level(headers[0]),
|
36
|
+
this_level,
|
37
|
+
html = settings.title + " <"+settings.listType+" id=\"toc_ul\" class=\"nav\">";
|
38
|
+
headers.on('click', function() {
|
39
|
+
if (!settings.noBackToTopLinks) {
|
40
|
+
window.location.hash = this.id;
|
41
|
+
}
|
42
|
+
})
|
43
|
+
.addClass('clickable-header')
|
44
|
+
.each(function(_, header) {
|
45
|
+
this_level = get_level(header);
|
46
|
+
if (!settings.noBackToTopLinks && this_level === highest_level) {
|
47
|
+
$(header).addClass('top-level-header');
|
48
|
+
}
|
49
|
+
var toc_item_id = get_toc_item_id(header.id);
|
50
|
+
if (this_level === level) // same level as before; same indenting
|
51
|
+
html += "<li id='" + toc_item_id + "'><a href='#" + header.id + "'>" + header.innerText + "</a>";
|
52
|
+
else if (this_level <= level){ // higher level than before; end parent ol
|
53
|
+
for(i = this_level; i < level; i++) {
|
54
|
+
html += "</li></"+settings.listType+">"
|
55
|
+
}
|
56
|
+
html += "<li id='" + toc_item_id + "'><a href='#" + header.id + "'>" + header.innerText + "</a>";
|
57
|
+
}
|
58
|
+
else if (this_level > level) { // lower level than before; expand the previous to contain a ol
|
59
|
+
for(i = this_level; i > level; i--) {
|
60
|
+
html += "<"+settings.listType+">";
|
61
|
+
if(i == level + 1) {
|
62
|
+
html += "<li id='" + toc_item_id + "'>";
|
63
|
+
} else {
|
64
|
+
html += "<li>";
|
65
|
+
}
|
66
|
+
}
|
67
|
+
html += "<a href='#" + header.id + "'>" + header.innerText + "</a>";
|
68
|
+
}
|
69
|
+
level = this_level; // update for the next one
|
70
|
+
});
|
71
|
+
html += "</"+settings.listType+">";
|
72
|
+
|
73
|
+
headers.each(function () {
|
74
|
+
var header = $(this);
|
75
|
+
if (!header.next().hasClass("back-to-top")){
|
76
|
+
// There is a javascript click listener (defined later in this file) for the below to scroll up.
|
77
|
+
var return_to_top = $('<div id="toc_up_' + header.attr('id') + '" class="icon-arrow-up back-to-top" style="text-align:right;">Up↑</div>');
|
78
|
+
var toc_item_id = get_toc_item_id(header.attr('id'));
|
79
|
+
return_to_top.click(function () {
|
80
|
+
// First, set up the right selections in the table-of-contents menu.
|
81
|
+
// So, the user can follow the trail of highlights menu items and expand the menu items till he reaches the appropriate level.
|
82
|
+
// On 20181119, I spent close to a working day messing with the menu getting it to expand to the right spot; but on realizing that the above is good enough, gave up.
|
83
|
+
var itemToActivate = undefined;
|
84
|
+
$("#toc_ul").find("li").each(function (liIndex, liElement) {
|
85
|
+
// console.debug(liIndex, liElement);
|
86
|
+
if (liElement.id == toc_item_id) {
|
87
|
+
itemToActivate = $(this);
|
88
|
+
} else {
|
89
|
+
$(this).removeClass("active");
|
90
|
+
}
|
91
|
+
});
|
92
|
+
itemToActivate.addClass("active");
|
93
|
+
itemToActivate.parents("li").addClass("active"); // This call is ineffective for some reason.
|
94
|
+
|
95
|
+
// Now scroll up.
|
96
|
+
$([document.documentElement, document.body]).animate({
|
97
|
+
scrollTop: $("[id='" + toc_item_id + "']").offset().top
|
98
|
+
}, 100);
|
99
|
+
});
|
100
|
+
header.after(return_to_top);
|
101
|
+
}
|
102
|
+
})
|
103
|
+
|
104
|
+
output.html(html);
|
105
|
+
resetNavgocoMenu();
|
106
|
+
// Finally, set up navgoco options.
|
107
|
+
};
|
108
|
+
|
109
|
+
function resetNavgocoMenu() {
|
110
|
+
$('#toc_ul').navgoco({
|
111
|
+
accordion: true,
|
112
|
+
openClass: 'active', // open
|
113
|
+
save: false,
|
114
|
+
caretHtml: '...', // Make it easier to expand the drawers by increasing click-capture area.
|
115
|
+
cookie: {
|
116
|
+
name: 'navgoco_toc',
|
117
|
+
expires: false,
|
118
|
+
path: '/'
|
119
|
+
},
|
120
|
+
slide: {
|
121
|
+
duration: 0, // 400ms was causing screen shakes with scrolling to the top by pressing the Up bottons.
|
122
|
+
easing: 'swing'
|
123
|
+
}
|
124
|
+
});
|
125
|
+
// console.debug("Set up navgoco.");
|
126
|
+
$("#toc_ul").navgoco('toggle', false);
|
127
|
+
}
|
128
|
+
|
129
|
+
function updateToc() {
|
130
|
+
$('#toc').toc({minimumHeaders: 0, listType: 'ul', headers: 'h2,h3,h4,h5,h6'});
|
131
|
+
}
|
132
|
+
|
133
|
+
// Update table of contents (To be called whenever page contents are updated).
|
134
|
+
$( document ).ready(updateToc);
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
// Code to make the "Nav" button, which toggles the table of contents.
|
139
|
+
// Not to be confused with toggling sub-items in that menu.
|
140
|
+
var toggleToc = function() {
|
141
|
+
$("#toc").toggle();
|
142
|
+
$("#toggle-toc-icon").toggleClass('fa-toggle-on');
|
143
|
+
$("#toggle-toc-icon").toggleClass('fa-toggle-off');
|
144
|
+
};
|
145
|
+
|
146
|
+
function toggleTocExpansion() {
|
147
|
+
$("#toggle-toc-expansion-icon").toggleClass('fa-toggle-on');
|
148
|
+
$("#toggle-toc-expansion-icon").toggleClass('fa-toggle-off');
|
149
|
+
if($("#toggle-toc-expansion-icon").hasClass('fa-toggle-on')) {
|
150
|
+
$("#toc_ul").navgoco('toggle', true);
|
151
|
+
} else {
|
152
|
+
$("#toc_ul").navgoco('toggle', false);
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
$(document).ready(function() {
|
157
|
+
$("#toggle-toc-icon").click(toggleToc);
|
158
|
+
$("#toggle-toc-expansion-icon").click(toggleTocExpansion);
|
159
|
+
});
|