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.
@@ -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
+ });