]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*! |
2 | * jQuery TOC Plugin v1.1.x based on | |
3 | * samaxesJS JavaScript Library | |
4 | * http://code.google.com/p/samaxesjs/ | |
5 | * | |
6 | * Copyright (c) 2008 samaxes.com | |
7 | * | |
8 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
9 | * you may not use this file except in compliance with the License. | |
10 | * You may obtain a copy of the License at | |
11 | * | |
12 | * http://www.apache.org/licenses/LICENSE-2.0 | |
13 | * | |
14 | * Unless required by applicable law or agreed to in writing, software | |
15 | * distributed under the License is distributed on an "AS IS" BASIS, | |
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
17 | * See the License for the specific language governing permissions and | |
18 | * limitations under the License. | |
19 | * | |
20 | * 2009-10-04, guwi17: modified and extended to meet uBLAS' needs | |
21 | */ | |
22 | ||
23 | (function($) { | |
24 | /* | |
25 | * The TOC plugin dynamically builds a table of contents from the headings in | |
26 | * a document and prepends legal-style section numbers to each of the headings. | |
27 | */ | |
28 | $.fn.toc = function(options) { | |
29 | var opts = $.extend({}, $.fn.toc.defaults, options); | |
30 | ||
31 | return this.each(function() { | |
32 | var toc = $(this).append('<ul></ul>').children('ul'); | |
33 | var headers = {h1: 0, h2: 0, h3: 0, h4: 0, h5: 0, h6: 0}; | |
34 | var index = 0; | |
35 | var indexes = { | |
36 | h1: (opts.exclude.match('h1') == null && $('h1').length > 0) ? ++index : 0, | |
37 | h2: (opts.exclude.match('h2') == null && $('h2').length > 0) ? ++index : 0, | |
38 | h3: (opts.exclude.match('h3') == null && $('h3').length > 0) ? ++index : 0, | |
39 | h4: (opts.exclude.match('h4') == null && $('h4').length > 0) ? ++index : 0, | |
40 | h5: (opts.exclude.match('h5') == null && $('h5').length > 0) ? ++index : 0, | |
41 | h6: (opts.exclude.match('h6') == null && $('h6').length > 0) ? ++index : 0 | |
42 | }; | |
43 | ||
44 | $(':header').not(opts.exclude).each(function() { | |
45 | var linkId = ""; | |
46 | if ($(this).is('h6')) { | |
47 | checkContainer(headers.h6, toc); | |
48 | updateNumeration(headers, 'h6'); | |
49 | $(this).text(addNumeration(headers, 'h6', $(this).text())); | |
50 | linkId = fixAnchor($(this)); | |
51 | appendToTOC(toc, indexes.h6, linkId, $(this).text(), headers); | |
52 | } else if ($(this).is('h5')) { | |
53 | checkContainer(headers.h5, toc); | |
54 | updateNumeration(headers, 'h5'); | |
55 | $(this).text(addNumeration(headers, 'h5', $(this).text())); | |
56 | linkId = fixAnchor($(this)); | |
57 | appendToTOC(toc, indexes.h5, linkId, $(this).text(), headers); | |
58 | } else if ($(this).is('h4')) { | |
59 | checkContainer(headers.h4, toc); | |
60 | updateNumeration(headers, 'h4'); | |
61 | $(this).text(addNumeration(headers, 'h4', $(this).text())); | |
62 | linkId = fixAnchor($(this)); | |
63 | appendToTOC(toc, indexes.h4, linkId, $(this).text(), headers); | |
64 | } else if ($(this).is('h3')) { | |
65 | checkContainer(headers.h3, toc); | |
66 | updateNumeration(headers, 'h3'); | |
67 | $(this).text(addNumeration(headers, 'h3', $(this).text())); | |
68 | linkId = fixAnchor($(this)); | |
69 | appendToTOC(toc, indexes.h3, linkId, $(this).text(), headers); | |
70 | } else if ($(this).is('h2')) { | |
71 | checkContainer(headers.h2, toc); | |
72 | updateNumeration(headers, 'h2'); | |
73 | $(this).text(addNumeration(headers, 'h2', $(this).text())); | |
74 | linkId = fixAnchor($(this)); | |
75 | appendToTOC(toc, indexes.h2, linkId, $(this).text(), headers); | |
76 | } else if ($(this).is('h1')) { | |
77 | updateNumeration(headers, 'h1'); | |
78 | $(this).text(addNumeration(headers, 'h1', $(this).text())); | |
79 | linkId = fixAnchor($(this)); | |
80 | appendToTOC(toc, indexes.h1, linkId, $(this).text(), headers); | |
81 | } | |
82 | }); | |
83 | }); | |
84 | }; | |
85 | ||
86 | /* | |
87 | * Checks if the last node is an 'ul' element. | |
88 | * If not, a new one is created. | |
89 | */ | |
90 | function checkContainer(header, toc) { | |
91 | if (header == 0 && !toc.find(':last').is('ul')) { | |
92 | toc.find('li:last').append('<ul></ul>'); | |
93 | } | |
94 | }; | |
95 | ||
96 | /* | |
97 | * Updates headers numeration. | |
98 | */ | |
99 | function updateNumeration(headers, header) { | |
100 | $.each(headers, function(i, val) { | |
101 | if (i == header) { | |
102 | ++headers[i]; | |
103 | } else if (i > header) { | |
104 | headers[i] = 0; | |
105 | } | |
106 | }); | |
107 | }; | |
108 | ||
109 | /* | |
110 | * Prepends the numeration to a heading. | |
111 | */ | |
112 | function addNumeration(headers, header, text) { | |
113 | var numeration = ''; | |
114 | ||
115 | $.each(headers, function(i, val) { | |
116 | if (i <= header && headers[i] > 0) { | |
117 | numeration += headers[i] + '.'; | |
118 | } | |
119 | }); | |
120 | ||
121 | return removeFinalDot(numeration) + ' ' + text; | |
122 | }; | |
123 | ||
124 | function removeFinalDot(text) { | |
125 | return (text||"").replace(/\.$/g, "" ) | |
126 | } | |
127 | ||
128 | function fixAnchor(element) { | |
129 | // use existing id by default | |
130 | var linkId = element.attr('id'); | |
131 | // next, look for an anchor and use its id or name | |
132 | if ( !linkId ) { | |
133 | element.find('> a:first').each( function() { | |
134 | linkId = $(this).attr('id') || $(this).attr('name'); | |
135 | }); | |
136 | } | |
137 | // next, use the text content as last resort | |
138 | if ( !linkId ) { | |
139 | linkId = (element.text()||"unknown").replace(/[^a-zA-Z0-9]/g,""); | |
140 | } | |
141 | ||
142 | element.attr('id',linkId); | |
143 | return linkId; | |
144 | } | |
145 | ||
146 | /* | |
147 | * Appends a new node to the TOC. | |
148 | */ | |
149 | function appendToTOC(toc, index, id, text, headers) { | |
150 | var parent = toc; | |
151 | ||
152 | for (var i = 1; i < index; i++) { | |
153 | if (parent.find('> li:last > ul').length == 0) { | |
154 | parent = parent.append('<li><ul></ul></li>'); | |
155 | } | |
156 | parent = parent.find('> li:last > ul'); | |
157 | } | |
158 | if (id) { | |
159 | parent.append('<li><a href="#' + id + '">' + text + '</a></li>'); | |
160 | } else { | |
161 | parent.append('<li>' + text + '</li>'); | |
162 | } | |
163 | }; | |
164 | ||
165 | $.fn.toc.defaults = {exclude: 'h1, h5, h6'} | |
166 | })(jQuery); |