├── .gitignore ├── CHANGELOG.md ├── Gruntfile.js ├── README.md ├── demo ├── more-indexing.html ├── number-indexing.html ├── sample.html ├── scroll.html └── style.html ├── dist ├── css │ ├── toc-scroll.css │ ├── toc-scroll.min.css │ ├── toc-scroll.scss │ ├── toc.css │ ├── toc.min.css │ └── toc.scss └── js │ ├── toc.js │ └── toc.min.js ├── img └── screenshot.png ├── package.json ├── src ├── css │ ├── toc-scroll.css │ ├── toc-scroll.scss │ ├── toc.css │ └── toc.scss └── js │ └── toc.js └── vendor ├── bootstrap ├── css │ ├── bootstrap-theme.css │ ├── bootstrap-theme.min.css │ ├── bootstrap.css │ └── bootstrap.min.css ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff └── js │ ├── bootstrap.js │ └── bootstrap.min.js └── jquery ├── jquery-1.10.2.min.js └── jquery-1.10.2.min.map /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | node_modules/* -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## v1.1.2 (2014/01/16) 4 | 5 | * Add shortcut definition for indexing format 6 | 7 | ## v1.1.1 (2013/10/21): 8 | 9 | * ^#2: Doesn't work when using the default indexing format 10 | 11 | ## v1.1.0 (2013/10/19) 12 | 13 | * +#1: Allow to define different format for each heading level 14 | 15 | ## v1.0.0 (2013/09/26) 16 | 17 | * Generate anchor link for heading 18 | * Automatically scroll to with the help of [Bootstrap ScrollSpy](http://getbootstrap.com/javascript/#scrollspy) plugin 19 | * Easy to customize look and feel -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | grunt.initConfig({ 3 | pkg: grunt.file.readJSON('package.json'), 4 | 5 | buildDir: 'dist', 6 | 7 | banner: [ 8 | '/**', 9 | ' * TocJS v<%= pkg.version %> (<%= pkg.homepage %>)', 10 | ' *', 11 | ' * Generate a table of contents based on headings', 12 | ' *', 13 | ' * @author http://twitter.com/nghuuphuoc', 14 | ' * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc', 15 | ' * @license MIT', 16 | ' */\n\n' 17 | ].join('\n'), 18 | 19 | // See https://github.com/gruntjs/grunt-contrib-copy 20 | copy: { 21 | main: { 22 | files: [ 23 | { cwd: 'src/css', src: '**', dest: '<%= buildDir %>/css', expand: true, flatten: true, filter: 'isFile' }, 24 | { cwd: 'src/js', src: '**', dest: '<%= buildDir %>/js', expand: true, flatten: true, filter: 'isFile' } 25 | ] 26 | } 27 | }, 28 | 29 | // https://github.com/gruntjs/grunt-contrib-cssmin 30 | cssmin: { 31 | minify: { expand: true, cwd: 'src/css/', src: ['*.css'], dest: '<%= buildDir %>/css/', ext: '.min.css' }, 32 | add_banner: { 33 | options: { 34 | banner: '<%= banner %>' 35 | }, 36 | files: { 37 | '<%= buildDir %>/css/toc.min.css': ['src/css/toc.css'], 38 | '<%= buildDir %>/css/toc-scroll.min.css': ['src/css/toc-scroll.css'] 39 | } 40 | } 41 | }, 42 | 43 | uglify: { 44 | options: { 45 | banner: '<%= banner %>' 46 | }, 47 | build: { 48 | src: ['src/js/toc.js'], 49 | dest: '<%= buildDir %>/js/toc.min.js' 50 | } 51 | } 52 | }); 53 | 54 | grunt.registerTask('default', 'build'); 55 | grunt.registerTask('build', ['copy', 'cssmin', 'uglify']); 56 | 57 | grunt.loadNpmTasks('grunt-contrib-copy'); 58 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 59 | grunt.loadNpmTasks('grunt-contrib-uglify'); 60 | }; 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TocJS 2 | 3 | TocJS is a jQuery plugin for generating table of contents based on headings. 4 | 5 | ![TocJS screen shot](img/screenshot.png) 6 | 7 | ## Demo 8 | 9 | * [Sample demo](https://rawgithub.com/nghuuphuoc/tocjs/master/demo/sample.html) 10 | * [Style with Bootstrap](https://rawgithub.com/nghuuphuoc/tocjs/master/demo/style.html) 11 | * [Scroll automatically](https://rawgithub.com/nghuuphuoc/tocjs/master/demo/scroll.html) 12 | * [Number indexing](https://rawgithub.com/nghuuphuoc/tocjs/master/demo/number-indexing.html) 13 | * [More indexing styles](https://rawgithub.com/nghuuphuoc/tocjs/master/demo/more-indexing.html) 14 | 15 | ## Features 16 | 17 | * Allow to define different format for each heading level 18 | * Generate anchor link for heading 19 | * Automatically scroll to with the help of [Bootstrap ScrollSpy](http://getbootstrap.com/javascript/#scrollspy) plugin 20 | * The table of contents are generated using nested ```ul``` elements 21 | * Easy to customize look and feel 22 | 23 | ## Download 24 | 25 | You can download TocJS from the [Github repository](https://github.com/nghuuphuoc/tocjs) directly or use [bower](http://bower.io): 26 | 27 | ```bash 28 | $ bower install tocjs 29 | ``` 30 | 31 | ## Usage 32 | 33 | By default, TocJS generates a table of contents based on the headings (```h1``` to ```h6```) found on page. 34 | 35 | In order to use this plugin: 36 | 37 | * Insert ```toc.js``` to your page, ensure that it is placed after jQuery: 38 | 39 | ```html 40 | 41 | 42 | ``` 43 | 44 | * Call the plugin when the document is ready: 45 | 46 | ```javascript 47 | 52 | ``` 53 | 54 | The plugin provides the following options: 55 | 56 | * ```selector``` (default value is _h1, h2, h3, h4, h5, h6_): Indicates which elements will be found and included in the table of contents 57 | * ```elementClass``` (_toc_): The CSS class which will be added to root element 58 | * ```rootUlClass``` (_toc-ul-root_): The CSS class which will be added to the root generated ```ul``` element 59 | * ```ulClass``` (_toc-ul_): The CSS class which will be added to all generated ```ul``` elements (including the root and sub ones) 60 | * ```prefixLinkClass``` (_toc-link-_): This option will be added as a prefix to CSS class of all generated ```a``` elements. The suffix is level of associating heading (1 to 6) 61 | * ```heading``` (_null_): The _Table of Contents_ heading label placed at the top. This heading is not shown by default. 62 | * ```indexingFormats``` (_{}_): Define the indexing formats for each heading level 63 | 64 | ```javascript 65 | $(element).toc({ 66 | indexingFormats: { 67 | : '' 68 | } 69 | }); 70 | ``` 71 | 72 | `````` can be 'h1', 'h2', ..., 'h6' 73 | 74 | `````` is a string and can be: 75 | 76 | Value | Description 77 | -----------------------------|------------ 78 | ```number``` or ```1``` | The headings will be prefixed with number (1, 2, 3, ...) 79 | ```upperAlphabet```, ```A``` | Prefix headings with uppercase alphabetical characters (A, B, C, ...) 80 | ```lowerAlphabet```, ```a``` | Prefix headings with lowercase alphabetical characters (a, b, c, ...) 81 | ```upperRoman```, ```I``` | Prefix headings with uppercase Roman numerals (I, II, III, ...) 82 | ```lowerRoman```, ```i``` | Prefix headings with lowercase Roman numerals (i, ii, iii, ...) 83 | 84 | You can define different formatter for each heading level, for example: 85 | 86 | ```javascript 87 | $(element).toc({ 88 | indexingFormats: { 89 | 'h1': 'upperAlphabet', 90 | 'h2': 'number', 91 | 'h3': 'lowerAlphabet' 92 | } 93 | }); 94 | 95 | $(element).toc({ 96 | indexingFormats: { 97 | 'h1': 'A', 98 | 'h2': '1', 99 | 'h3': 'a' 100 | } 101 | }); 102 | 103 | $(element).toc({ 104 | indexingFormats: 'A1a' 105 | }); 106 | ``` 107 | 108 | If you want to set indexing formats for all levels: 109 | 110 | ```javascript 111 | $(element).toc({ 112 | // can be 'number', 'upperAlphabet', 'lowerAlphabet', 'upperRoman', 'lowerRoman' 113 | indexingFormats: '' 114 | }); 115 | ``` 116 | 117 | ## Customize the look and feel 118 | 119 | Assume that ```
``` is the element containing the table of contents. 120 | By default, TocJS generates the following markup: 121 | 122 | ```html 123 |
124 | 136 |
137 | ``` 138 | 139 | To customize the styles of table of contents, you can customize the ```toc```, ```toc-ul-root```, ```toc-ul```, ```toc-heading```, and ```toc-link-[1..6]``` classes. 140 | Or create your own CSS classes and set them using the TocJS options which are described in the above section. 141 | 142 | ## Build 143 | 144 | TocJS uses [grunt](http://gruntjs.com) for building process. 145 | The process includes the following steps: 146 | 147 | * Copy entire ```src/css``` and ```src/js``` directories to ```dist``` directory 148 | * Compress the CSS files in ```src/css``` and save to ```dist/css``` 149 | * Compress the ```src/js/toc.js``` and save to ```dist/js/toc.min.js``` 150 | 151 | Grunt helps us simplify the process. 152 | 153 | First, you have to install the dependencies defined in ```package.json``` (the following commands might need the administrator permission to run): 154 | 155 | ``` 156 | $ cd 157 | $ npm install grunt --save-dev 158 | $ npm install grunt-contrib-copy --save-dev 159 | $ npm install grunt-contrib-cssmin --save-dev 160 | $ npm install grunt-contrib-uglify --save-dev 161 | ``` 162 | 163 | Then, run the command below from the TocJS directory: 164 | 165 | ``` 166 | $ grunt 167 | ``` 168 | 169 | ## Author 170 | 171 | Nguyen Huu Phuoc, aka @nghuuphuoc 172 | 173 | * [http://github.com/nghuuphuoc](http://github.com/nghuuphuoc) 174 | * [http://twitter.com/nghuuphuoc](http://twitter.com/nghuuphuoc) 175 | 176 | ## License 177 | 178 | ``` 179 | The MIT License (MIT) 180 | 181 | Copyright (c) 2013 - 2014 Nguyen Huu Phuoc 182 | 183 | Permission is hereby granted, free of charge, to any person obtaining a copy of 184 | this software and associated documentation files (the "Software"), to deal in 185 | the Software without restriction, including without limitation the rights to 186 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 187 | the Software, and to permit persons to whom the Software is furnished to do so, 188 | subject to the following conditions: 189 | 190 | The above copyright notice and this permission notice shall be included in all 191 | copies or substantial portions of the Software. 192 | 193 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 194 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 195 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 196 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 197 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 198 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 199 | ``` -------------------------------------------------------------------------------- /dist/css/toc-scroll.css: -------------------------------------------------------------------------------- 1 | /** 2 | * TocJS (https://github.com/nghuuphuoc/tocjs) 3 | * 4 | * Generate a table of contents based on headings 5 | * 6 | * @author http://twitter.com/nghuuphuoc 7 | * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc 8 | * @license MIT 9 | */ 10 | .toc { 11 | border: 1px solid #ddd; 12 | border-radius: 4px; } 13 | .toc.affix { 14 | position: static; } 15 | .toc .nav > .active > a, .toc .nav > .active:hover > a, 16 | .toc .nav > .active :focus > a { 17 | border-right: 2px solid #428bca; } 18 | .toc .nav .nav { 19 | /* 20 | * If you want to hide the sub UL elements, then add the following line 21 | * display: none; 22 | */ 23 | display: block; 24 | margin-bottom: 8px; } 25 | .toc .nav .nav > li > a { 26 | font-size: 90%; } 27 | .toc .toc-heading { 28 | color: #333333; 29 | background-color: #f5f5f5; 30 | border-bottom: 1px solid #dddddd; } 31 | .toc .toc-link-2 { 32 | padding-left: 25px; } 33 | .toc .toc-link-3 { 34 | padding-left: 50px; } 35 | .toc .toc-link-4 { 36 | padding-left: 75px; } 37 | .toc .toc-link-5 { 38 | padding-left: 100px; } 39 | .toc .toc-link-6 { 40 | padding-left: 125px; } 41 | 42 | @media screen and (min-width: 992px) and (min-height: 700px) { 43 | .toc.affix { 44 | position: fixed; } 45 | .toc .nav > .active > ul { 46 | display: block; } } 47 | .toc .nav .nav { 48 | display: none; } 49 | -------------------------------------------------------------------------------- /dist/css/toc-scroll.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * TocJS v1.1.2 (http://github.com/nghuuphuoc/tocjs) 3 | * 4 | * Generate a table of contents based on headings 5 | * 6 | * @author http://twitter.com/nghuuphuoc 7 | * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc 8 | * @license MIT 9 | */ 10 | 11 | 12 | .toc{border:1px solid #ddd;border-radius:4px}.toc.affix{position:static}.toc .nav>.active>a,.toc .nav>.active:hover>a,.toc .nav>.active :focus>a{border-right:2px solid #428bca}.toc .nav .nav{display:block;margin-bottom:8px}.toc .nav .nav>li>a{font-size:90%}.toc .toc-heading{color:#333;background-color:#f5f5f5;border-bottom:1px solid #ddd}.toc .toc-link-2{padding-left:25px}.toc .toc-link-3{padding-left:50px}.toc .toc-link-4{padding-left:75px}.toc .toc-link-5{padding-left:100px}.toc .toc-link-6{padding-left:125px}@media screen and (min-width:992px) and (min-height:700px){.toc.affix{position:fixed}.toc .nav>.active>ul{display:block}}.toc .nav .nav{display:none} -------------------------------------------------------------------------------- /dist/css/toc-scroll.scss: -------------------------------------------------------------------------------- 1 | @import "toc"; 2 | 3 | .toc { 4 | .nav .nav { 5 | display: none; 6 | } 7 | } -------------------------------------------------------------------------------- /dist/css/toc.css: -------------------------------------------------------------------------------- 1 | /** 2 | * TocJS (https://github.com/nghuuphuoc/tocjs) 3 | * 4 | * Generate a table of contents based on headings 5 | * 6 | * @author Nguyen Huu Phuoc 7 | * @copyright (c) 2013 Nguyen Huu Phuoc 8 | * @license MIT 9 | */ 10 | .toc { 11 | border: 1px solid #ddd; 12 | border-radius: 4px; } 13 | .toc.affix { 14 | position: static; } 15 | .toc .nav > .active > a, .toc .nav > .active:hover > a, 16 | .toc .nav > .active :focus > a { 17 | border-right: 2px solid #428bca; } 18 | .toc .nav .nav { 19 | /* 20 | * If you want to hide the sub UL elements, then add the following line 21 | * display: none; 22 | */ 23 | display: block; 24 | margin-bottom: 8px; } 25 | .toc .nav .nav > li > a { 26 | font-size: 90%; } 27 | .toc .toc-heading { 28 | color: #333333; 29 | background-color: #f5f5f5; 30 | border-bottom: 1px solid #dddddd; } 31 | .toc .toc-link-2 { 32 | padding-left: 25px; } 33 | .toc .toc-link-3 { 34 | padding-left: 50px; } 35 | .toc .toc-link-4 { 36 | padding-left: 75px; } 37 | .toc .toc-link-5 { 38 | padding-left: 100px; } 39 | .toc .toc-link-6 { 40 | padding-left: 125px; } 41 | 42 | @media screen and (min-width: 992px) and (min-height: 700px) { 43 | .toc.affix { 44 | position: fixed; } 45 | .toc .nav > .active > ul { 46 | display: block; } } 47 | -------------------------------------------------------------------------------- /dist/css/toc.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * TocJS v1.1.2 (http://github.com/nghuuphuoc/tocjs) 3 | * 4 | * Generate a table of contents based on headings 5 | * 6 | * @author http://twitter.com/nghuuphuoc 7 | * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc 8 | * @license MIT 9 | */ 10 | 11 | 12 | .toc{border:1px solid #ddd;border-radius:4px}.toc.affix{position:static}.toc .nav>.active>a,.toc .nav>.active:hover>a,.toc .nav>.active :focus>a{border-right:2px solid #428bca}.toc .nav .nav{display:block;margin-bottom:8px}.toc .nav .nav>li>a{font-size:90%}.toc .toc-heading{color:#333;background-color:#f5f5f5;border-bottom:1px solid #ddd}.toc .toc-link-2{padding-left:25px}.toc .toc-link-3{padding-left:50px}.toc .toc-link-4{padding-left:75px}.toc .toc-link-5{padding-left:100px}.toc .toc-link-6{padding-left:125px}@media screen and (min-width:992px) and (min-height:700px){.toc.affix{position:fixed}.toc .nav>.active>ul{display:block}} -------------------------------------------------------------------------------- /dist/css/toc.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * TocJS (https://github.com/nghuuphuoc/tocjs) 3 | * 4 | * Generate a table of contents based on headings 5 | * 6 | * @author http://twitter.com/nghuuphuoc 7 | * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc 8 | * @license MIT 9 | */ 10 | 11 | // Variable 12 | $tocPaddingLevel: 25px; 13 | 14 | // Table of content 15 | .toc { 16 | border: 1px solid #ddd; 17 | border-radius: 4px; 18 | 19 | // Used when you want the page to scroll to the table of content 20 | // For using with Bootstrap 3 21 | &.affix { 22 | position: static; 23 | } 24 | 25 | // For using with Bootstrap 3 26 | .nav > .active { 27 | > a, 28 | &:hover > a, 29 | :focus > a { 30 | border-right: 2px solid #428bca; 31 | } 32 | } 33 | 34 | // Second level 35 | .nav .nav { 36 | /* 37 | * If you want to hide the sub UL elements, then add the following line 38 | * display: none; 39 | */ 40 | display: block; 41 | margin-bottom: 8px; 42 | > li > a { 43 | font-size: 90%; 44 | } 45 | } 46 | 47 | // Heading (Table of Contents) 48 | .toc-heading { 49 | color: #333333; 50 | background-color: #f5f5f5; 51 | border-bottom: 1px solid #dddddd; 52 | } 53 | 54 | // Children links 55 | .toc-link-2 { 56 | padding-left: $tocPaddingLevel; 57 | } 58 | .toc-link-3 { 59 | padding-left: $tocPaddingLevel * 2; 60 | } 61 | .toc-link-4 { 62 | padding-left: $tocPaddingLevel * 3; 63 | } 64 | .toc-link-5 { 65 | padding-left: $tocPaddingLevel * 4; 66 | } 67 | .toc-link-6 { 68 | padding-left: $tocPaddingLevel * 5; 69 | } 70 | } 71 | 72 | // Responsive 73 | @media screen and (min-width: 992px) and (min-height: 700px) { 74 | .toc { 75 | &.affix { 76 | position: fixed; 77 | } 78 | .nav > .active > ul { 79 | display: block; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /dist/js/toc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TocJS (https://github.com/nghuuphuoc/tocjs) 3 | * 4 | * Generate a table of contents based on headings 5 | * 6 | * @author http://twitter.com/nghuuphuoc 7 | * @copyright (c) 2013 - 2014 Nguyen Huu Phuoc 8 | * @license MIT 9 | */ 10 | 11 | (function($) { 12 | var Toc = function(element, options) { 13 | this.$element = $(element); 14 | this.options = $.extend({}, Toc.DEFAULT_OPTIONS, options); 15 | this.headings = []; 16 | 17 | this.$element.addClass(this.options.elementClass); 18 | 19 | var that = this; 20 | $(this.options.selector).each(function(index, node) { 21 | $(node) 22 | .data('tagNumber', parseInt(node.tagName.substring(1))) // 1...6 23 | .data('index', 1) 24 | .data('numbering', '1'); 25 | that.headings.push(node); 26 | }); 27 | 28 | if (this.headings.length > 0) { 29 | this.render(); 30 | } 31 | }; 32 | 33 | /** 34 | * The default options 35 | */ 36 | Toc.DEFAULT_OPTIONS = { 37 | selector: 'h1, h2, h3, h4, h5, h6', 38 | elementClass: 'toc', 39 | rootUlClass: 'toc-ul-root', 40 | ulClass: 'toc-ul', 41 | prefixLinkClass: 'toc-link-', 42 | heading: null, 43 | 44 | /** 45 | * Define the indexing formats for each heading level 46 | * indexingFormats: { 47 | * headingLevel: formatter 48 | * } 49 | * 50 | * headingLevel can be 'h1', 'h2', ..., 'h6' 51 | * formatter can be: 52 | * - 'number', '1': The headings will be prefixed with number (1, 2, 3, ...) 53 | * - 'upperAlphabet', 'A': Prefix headings with uppercase alphabetical characters (A, B, C, ...) 54 | * - 'lowerAlphabet', 'a': Prefix headings with lowercase alphabetical characters (a, b, c, ...) 55 | * - 'upperRoman', 'I': Prefix headings with uppercase Roman numerals (I, II, III, ...) 56 | * - 'lowerRoman', 'i': Prefix headings with lowercase Roman numerals (i, ii, iii, ...) 57 | * 58 | * You can define different formatter for each heading level: 59 | * indexingFormats: { 60 | * 'h1': 'upperAlphabet', // 'A' 61 | * 'h2': 'number', // '1' 62 | * 'h3': 'lowerAlphabet' // 'a' 63 | * } 64 | * 65 | * If you want to set indexing formats for levels: 66 | * indexingFormats: formatter 67 | * 68 | * Example: 69 | * indexingFormats: 'number' => Prefix all headings by number 70 | * indexingFormats: '1AaIi' => Prefix 1st level heading by number 71 | * Prefix 2nd level heading by uppercase character, and so forth. 72 | */ 73 | indexingFormats: {} 74 | }; 75 | 76 | Toc.prototype = { 77 | constructor: Toc, 78 | 79 | /** 80 | * Render table of content 81 | */ 82 | render: function() { 83 | var h = {}, 84 | headings = this.headings, 85 | numHeadings = this.headings.length; 86 | 87 | for (var i = 0; i < numHeadings; i++) { 88 | var currTagNumber = $(headings[i]).data('tagNumber'); 89 | if (i == 0) { 90 | h[headings[0].tagName] = $(headings[0]); 91 | } else { 92 | var prevTagNumber = $(headings[i - 1]).data('tagNumber'), 93 | prevNumbering = String($(headings[i - 1]).data('numbering')).split('.'); 94 | 95 | switch (true) { 96 | // Case 1: 97 | // The current heading is at the same level with previous one 98 | // h3___________ <== previous heading 99 | // h3___________ <== current heading 100 | case (currTagNumber == prevTagNumber): 101 | var index = $(headings[i - 1]).data('index') + 1; 102 | $(headings[i]).data('index', index); 103 | if (prevNumbering.length == 1) { 104 | $(headings[i]).data('numbering', parseInt(prevNumbering[0]) + 1); 105 | } else { 106 | prevNumbering.pop(); 107 | prevNumbering.push(index); 108 | $(headings[i]).data('numbering', prevNumbering.join('.')); 109 | } 110 | h[headings[i].tagName] = $(headings[i]); 111 | break; 112 | 113 | // Case 2: 114 | // The current heading is child of the previous one 115 | // h3____________ <== previous heading 116 | // h4________ <== current heading 117 | case (currTagNumber > prevTagNumber): 118 | prevNumbering.push('1'); 119 | $(headings[i]).data('index', 1) 120 | .data('numbering', prevNumbering.join('.')); 121 | h[headings[i].tagName] = $(headings[i]); 122 | break; 123 | 124 | // Case 3: 125 | // h2____________ <== (*) the closest heading that is at the same level with current one 126 | // ... 127 | // h4________ <== previous heading 128 | // h2____________ <== current heading 129 | case (currTagNumber < prevTagNumber): 130 | // Get the cloest heading (*) 131 | var closestHeading = h[headings[i].tagName]; 132 | 133 | // Now I come back the case 1 134 | var closestNumbering = String($(closestHeading).data('numbering')).split('.'), 135 | index = $(closestHeading).data('index') + 1; 136 | $(headings[i]).data('index', index); 137 | if (closestNumbering.length == 1) { 138 | $(headings[i]).data('numbering', parseInt(closestNumbering[0]) + 1); 139 | } else { 140 | closestNumbering.pop(); 141 | closestNumbering.push(index); 142 | $(headings[i]).data('numbering', closestNumbering.join('.')); 143 | } 144 | 145 | h[headings[i].tagName] = $(headings[i]); 146 | break; 147 | 148 | default: 149 | break; 150 | } 151 | } 152 | } 153 | 154 | var numberingMap = {}, 155 | $toc = $('