Table of Contents Plus - Version 1108.1

Version Description

  • Released: 3 August 2011
  • Anchor targets (eg anything after #) are now limited to ASCII characters as some mobile user agents do not accept internationalised characters. This is also a recommendation in the HTML spec. A new advanced admin option has been added to specify the default prefix when no characters qualify.
  • Make TOC, Pages and Category labels compatible with UTF-8 characters.
  • Support ' " \ characters in labels as it was being escaped by WordPress before saving.
Download this release

Release Info

Developer conjur3r
Plugin Icon 128x128 Table of Contents Plus
Version 1108.1
Comparing to
See all releases

Code changes from version 1108 to 1108.1

Files changed (5) hide show
  1. admin.css +4 -0
  2. admin.js +5 -0
  3. readme.txt +15 -6
  4. screen.css +4 -2
  5. toc.php +49 -19
admin.css CHANGED
@@ -1,6 +1,10 @@
1
  div.tab_content table {
2
  margin-bottom: 1em;
3
  }
 
 
 
 
4
  ul#tabbed-nav {
5
  margin-top: 1em;
6
  }
1
  div.tab_content table {
2
  margin-bottom: 1em;
3
  }
4
+ div.tab_content ul li {
5
+ margin-left: 2em;
6
+ list-style-type: disc;
7
+ }
8
  ul#tabbed-nav {
9
  margin-top: 1em;
10
  }
admin.js CHANGED
@@ -40,6 +40,11 @@ jQuery(document).ready(function($) {
40
  width = width.replace(/[^0-9]/, '');
41
  $('input#width_custom').val(width);
42
  });
 
 
 
 
 
43
 
44
  if ( $.farbtastic ) {
45
  $('#background_colour_wheel').hide();
40
  width = width.replace(/[^0-9]/, '');
41
  $('input#width_custom').val(width);
42
  });
43
+ $('input#fragment_prefix').keyup(function() {
44
+ var fragment = $(this).val();
45
+ fragment = fragment.replace(/[^a-zA-Z0-9_\-]/g, '');
46
+ $('input#fragment_prefix').val(fragment);
47
+ });
48
 
49
  if ( $.farbtastic ) {
50
  $('#background_colour_wheel').hide();
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link:
4
  Tags: table of contents, indexes, toc, sitemap, cms, options, list, page listing, category listing
5
  Requires at least: 3.0
6
  Tested up to: 3.3
7
- Stable tag: 1108
8
 
9
  A powerful yet user friendly plugin that automatically creates a table of contents. Can also output a sitemap listing all pages and categories.
10
 
@@ -63,8 +63,15 @@ When parameters are left out, they will fallback to the default settings.
63
 
64
  == Changelog ==
65
 
66
- = 1108 - 1 August 2011 =
67
- * New: option to hide the title on top of the table of contents. Thanks to [http://dublue.com/plugins/toc/#comment-82](Andrew) for the suggestion.
 
 
 
 
 
 
 
68
  * New: option to preserve existing theme specified bullet images for unordered list elements.
69
  * New: option to set the width of the table of contents. You can select from a number of common widths, or define your own.
70
  * Allow 3 to be set as the minimum number of headings for auto insertion. The default stays at 4.
@@ -73,15 +80,17 @@ When parameters are left out, they will fallback to the default settings.
73
  * Now uses the heading as the anchor target rather than toc_index.
74
  * Adjusted CSS styles for lists to be a little more consistent across themes (eg list-style, margins & paddings).
75
  * Fixed: typo 'heirarchy' should be 'hierarchy'. Also thanks to Andrew.
76
- * Fixed: addressed an issue while saving on networked installs using sub directories. Thanks to [http://dublue.com/plugins/toc/#comment-79](Aubrey).
77
  * Fixed: closing of the last list item when deeply nested.
78
 
79
- = 1107.1 - 10 July 2011 =
 
80
  * New: added `[toc]` shortcode to generate the table of contents at the preferred position. Also useful for sites that only require a TOC on a small handful of pages.
81
  * New: smooth scroll effect added to animate to anchor rather than jump. It's off by default.
82
  * New: appearance options to match your theme a little bit more.
83
 
84
- = 1107 - 1 July 2011 =
 
85
  * First world release (functional & feature packed)
86
 
87
 
4
  Tags: table of contents, indexes, toc, sitemap, cms, options, list, page listing, category listing
5
  Requires at least: 3.0
6
  Tested up to: 3.3
7
+ Stable tag: 1108.1
8
 
9
  A powerful yet user friendly plugin that automatically creates a table of contents. Can also output a sitemap listing all pages and categories.
10
 
63
 
64
  == Changelog ==
65
 
66
+ = 1108.1 =
67
+ * Released: 3 August 2011
68
+ * Anchor targets (eg anything after #) are now limited to ASCII characters as some mobile user agents do not accept internationalised characters. This is also a recommendation in the [HTML spec](http://www.w3.org/TR/html4/struct/links.html#h-12.2.1). A new advanced admin option has been added to specify the default prefix when no characters qualify.
69
+ * Make TOC, Pages and Category labels compatible with UTF-8 characters.
70
+ * Support ' " \ characters in labels as it was being escaped by WordPress before saving.
71
+
72
+ = 1108 =
73
+ * Released: 1 August 2011
74
+ * New: option to hide the title on top of the table of contents. Thanks to [Andrew](http://dublue.com/plugins/toc/#comment-82) for the suggestion.
75
  * New: option to preserve existing theme specified bullet images for unordered list elements.
76
  * New: option to set the width of the table of contents. You can select from a number of common widths, or define your own.
77
  * Allow 3 to be set as the minimum number of headings for auto insertion. The default stays at 4.
80
  * Now uses the heading as the anchor target rather than toc_index.
81
  * Adjusted CSS styles for lists to be a little more consistent across themes (eg list-style, margins & paddings).
82
  * Fixed: typo 'heirarchy' should be 'hierarchy'. Also thanks to Andrew.
83
+ * Fixed: addressed an issue while saving on networked installs using sub directories. Thanks to [Aubrey](http://dublue.com/plugins/toc/#comment-79).
84
  * Fixed: closing of the last list item when deeply nested.
85
 
86
+ = 1107.1 =
87
+ * Released: 10 July 2011
88
  * New: added `[toc]` shortcode to generate the table of contents at the preferred position. Also useful for sites that only require a TOC on a small handful of pages.
89
  * New: smooth scroll effect added to animate to anchor rather than jump. It's off by default.
90
  * New: appearance options to match your theme a little bit more.
91
 
92
+ = 1107 =
93
+ * Released: 1 July 2011
94
  * First world release (functional & feature packed)
95
 
96
 
screen.css CHANGED
@@ -29,11 +29,13 @@
29
  #toc_container.toc_black {
30
  background: #000;
31
  }
32
- .toc_title {
33
  text-align: center;
34
  font-weight: bold;
 
 
35
  }
36
- #toc_container.toc_black .toc_title {
37
  color: #aaa;
38
  }
39
  .toc_wrap_left {
29
  #toc_container.toc_black {
30
  background: #000;
31
  }
32
+ #toc_container p.toc_title {
33
  text-align: center;
34
  font-weight: bold;
35
+ margin: 0 0 1em 0;
36
+ padding: 0;
37
  }
38
+ #toc_container.toc_black p.toc_title {
39
  color: #aaa;
40
  }
41
  .toc_wrap_left {
toc.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://dublue.com/plugins/toc/
5
  Description: A powerful yet user friendly plugin that automatically creates a table of contents. Can also output a sitemap listing all pages and categories.
6
  Author: Michael Tran
7
  Author URI: http://dublue.com/
8
- Version: 1108
9
  License: GPL2
10
  */
11
 
@@ -35,7 +35,7 @@ FOR CONSIDERATION:
35
  - highlight target css
36
  */
37
 
38
-
39
  define( 'TOC_POSITION_BEFORE_FIRST_HEADING', 1 );
40
  define( 'TOC_POSITION_TOP', 2 );
41
  define( 'TOC_POSITION_BOTTOM', 3 );
@@ -64,9 +64,10 @@ if ( !class_exists( 'toc' ) ) :
64
  $this->path = dirname( WP_PLUGIN_URL . '/' . plugin_basename( __FILE__ ) );
65
  $this->show_toc = true;
66
  $this->exclude_post_types = array( 'attachment', 'revision', 'nav_menu_item', 'safecss' );
67
-
68
  // get options
69
  $defaults = array( // default options
 
70
  'position' => TOC_POSITION_BEFORE_FIRST_HEADING,
71
  'start' => TOC_MIN_START,
72
  'show_heading_text' => true,
@@ -158,14 +159,14 @@ if ( !class_exists( 'toc' ) ) :
158
  $html = '<div class="toc_sitemap">';
159
  if ( $this->options['sitemap_show_page_listing'] )
160
  $html .=
161
- '<h' . $this->options['sitemap_heading_type'] . ' class="toc_sitemap_pages">' . $this->options['sitemap_pages'] . '</h' . $this->options['sitemap_heading_type'] . '>' .
162
  '<ul class="toc_sitemap_pages_list">' .
163
  wp_list_pages( array('title_li' => '', 'echo' => false ) ) .
164
  '</ul>'
165
  ;
166
  if ( $this->options['sitemap_show_category_listing'] )
167
  $html .=
168
- '<h' . $this->options['sitemap_heading_type'] . ' class="toc_sitemap_categories">' . $this->options['sitemap_categories'] . '</h' . $this->options['sitemap_heading_type'] . '>' .
169
  '<ul class="toc_sitemap_categories_list">' .
170
  wp_list_categories( array( 'title_li' => '', 'echo' => false ) ) .
171
  '</ul>'
@@ -181,7 +182,7 @@ if ( !class_exists( 'toc' ) ) :
181
  {
182
  extract( shortcode_atts( array(
183
  'heading' => $this->options['sitemap_heading_type'],
184
- 'label' => $this->options['sitemap_pages'],
185
  'no_label' => false,
186
  'exclude' => ''
187
  ), $atts )
@@ -207,7 +208,7 @@ if ( !class_exists( 'toc' ) ) :
207
  {
208
  extract( shortcode_atts( array(
209
  'heading' => $this->options['sitemap_heading_type'],
210
- 'label' => $this->options['sitemap_pages'],
211
  'no_label' => false,
212
  'exclude' => ''
213
  ), $atts )
@@ -281,12 +282,17 @@ if ( !class_exists( 'toc' ) ) :
281
  // require an administrator level to save
282
  if ( !current_user_can( 'manage_options', $post_id ) )
283
  return false;
 
 
 
 
284
 
285
  $this->options = array(
 
286
  'position' => intval($_POST['position']),
287
  'start' => intval($_POST['start']),
288
  'show_heading_text' => ($_POST['show_heading_text']) ? true : false,
289
- 'heading_text' => trim($_POST['heading_text']),
290
  'auto_insert_post_types' => (array)$_POST['auto_insert_post_types'],
291
  'show_heirarchy' => ($_POST['show_heirarchy']) ? true : false,
292
  'ordered_list' => ($_POST['ordered_list']) ? true : false,
@@ -300,8 +306,8 @@ if ( !class_exists( 'toc' ) ) :
300
  'sitemap_show_page_listing' => ($_POST['sitemap_show_page_listing']) ? true : false,
301
  'sitemap_show_category_listing' => ($_POST['sitemap_show_category_listing']) ? true : false,
302
  'sitemap_heading_type' => intval($_POST['sitemap_heading_type']),
303
- 'sitemap_pages' => trim($_POST['sitemap_pages']),
304
- 'sitemap_categories' => trim($_POST['sitemap_categories'])
305
  );
306
 
307
  // update_option will return false if no changes were made
@@ -369,7 +375,7 @@ if ( !class_exists( 'toc' ) ) :
369
  <td>
370
  <input type="checkbox" value="1" id="show_heading_text" name="show_heading_text"<?php if ( $this->options['show_heading_text'] ) echo ' checked="checked"'; ?> /><label for="show_heading_text"> <?php _e('Show title on top of the table of contents', 'toc+'); ?></label><br />
371
  <div class="more_toc_options<?php if ( !$this->options['show_heading_text'] ) echo ' disabled'; ?>">
372
- <input type="text" class="regular-text" value="<?php echo htmlentities($this->options['heading_text']); ?>" id="heading_text" name="heading_text" />
373
  <span class="description"><label for="heading_text"><?php _e('Eg: Contents, Table of Contents, Page Contents', 'toc+'); ?></label></span>
374
  </div>
375
  </td>
@@ -434,7 +440,7 @@ if ( !class_exists( 'toc' ) ) :
434
  </select>
435
  <div class="more_toc_options<?php if ( 'User defined' != $this->options['width'] ) echo ' disabled'; ?>">
436
  <label for="width_custom"><?php _e('Please enter a number and', 'toc+'); ?></label><label for="width_custom_units"> <?php _e('select its units, eg: 100px, 10em', 'toc+'); ?></label><br />
437
- <input type="text" class="regular-text" value="<?php echo htmlentities($this->options['width_custom']); ?>" id="width_custom" name="width_custom" />
438
  <select name="width_custom_units" id="width_custom_units">
439
  <option value="px"<?php if ( 'px' == $this->options['width_custom_units'] ) echo ' selected="selected"'; ?>>px</option>
440
  <option value="%"<?php if ( '%' == $this->options['width_custom_units'] ) echo ' selected="selected"'; ?>>%</option>
@@ -488,8 +494,24 @@ if ( !class_exists( 'toc' ) ) :
488
  <input type="text" name="background_colour" id="background_colour" value="#00ffff" /><div id="background_colour_wheel"></div>
489
  -->
490
 
491
- <h3>Advanced usage <span class="show_hide">(<a href="#toc_advanced_usage">show</a>)</span></h3>
492
  <div id="toc_advanced_usage">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
493
  <p>If you would like to fully customise the position of the table of contents, you can use the <code>[toc]</code> shortcode by placing it at the desired position of your post, page or custom post type. This method allows you to generate the table of contents despite having auto insertion disabled for its content type. Supports the following parameters:</p>
494
  <ul>
495
  <li><strong>label</strong> text, title of the table of contents</li>
@@ -529,13 +551,13 @@ if ( !class_exists( 'toc' ) ) :
529
  </tr>
530
  <tr>
531
  <th><label for="sitemap_pages"><?php _e('Pages label', 'toc+'); ?></label></th>
532
- <td><input type="text" class="regular-text" value="<?php echo htmlentities($this->options['sitemap_pages']); ?>" id="sitemap_pages" name="sitemap_pages" />
533
  <span class="description"><?php _e('Eg: Pages, Page List', 'toc+'); ?></span>
534
  </td>
535
  </tr>
536
  <tr>
537
  <th><label for="sitemap_categories"><?php _e('Categories label', 'toc+'); ?></label></th>
538
- <td><input type="text" class="regular-text" value="<?php echo htmlentities($this->options['sitemap_categories']); ?>" id="sitemap_categories" name="sitemap_categories" />
539
  <span class="description"><?php _e('Eg: Categories, Category List', 'toc+'); ?></span>
540
  </td>
541
  </tr>
@@ -623,10 +645,10 @@ if ( !class_exists( 'toc' ) ) :
623
  $return = trim( strip_tags($title) );
624
 
625
  // remove &amp;
626
- $return = str_replace('&amp;', '', $return);
627
 
628
- // remove punctuation
629
- $return = preg_replace('/[!"$%&\'()*+,.\/:;<=>?@[\]^`{|}~]/', '', $return);
630
 
631
  // convert spaces to _
632
  $return = str_replace(
@@ -634,6 +656,14 @@ if ( !class_exists( 'toc' ) ) :
634
  '_',
635
  $return
636
  );
 
 
 
 
 
 
 
 
637
  }
638
 
639
  return $return;
@@ -806,7 +836,7 @@ if ( !class_exists( 'toc' ) ) :
806
  $html .= ';"';
807
  }
808
  $html .= '>';
809
- if ( $this->options['show_heading_text'] ) $html .= '<p class="toc_title">' . htmlentities($this->options['heading_text']) . '</p>';
810
  $html .= '<ul>' . $items . '</ul></div>' . "\n";
811
 
812
  if ( $custom_toc_position !== false ) {
5
  Description: A powerful yet user friendly plugin that automatically creates a table of contents. Can also output a sitemap listing all pages and categories.
6
  Author: Michael Tran
7
  Author URI: http://dublue.com/
8
+ Version: 1108.1
9
  License: GPL2
10
  */
11
 
35
  - highlight target css
36
  */
37
 
38
+
39
  define( 'TOC_POSITION_BEFORE_FIRST_HEADING', 1 );
40
  define( 'TOC_POSITION_TOP', 2 );
41
  define( 'TOC_POSITION_BOTTOM', 3 );
64
  $this->path = dirname( WP_PLUGIN_URL . '/' . plugin_basename( __FILE__ ) );
65
  $this->show_toc = true;
66
  $this->exclude_post_types = array( 'attachment', 'revision', 'nav_menu_item', 'safecss' );
67
+
68
  // get options
69
  $defaults = array( // default options
70
+ 'fragment_prefix' => 'i',
71
  'position' => TOC_POSITION_BEFORE_FIRST_HEADING,
72
  'start' => TOC_MIN_START,
73
  'show_heading_text' => true,
159
  $html = '<div class="toc_sitemap">';
160
  if ( $this->options['sitemap_show_page_listing'] )
161
  $html .=
162
+ '<h' . $this->options['sitemap_heading_type'] . ' class="toc_sitemap_pages">' . htmlentities( $this->options['sitemap_pages'], ENT_COMPAT, 'UTF-8' ) . '</h' . $this->options['sitemap_heading_type'] . '>' .
163
  '<ul class="toc_sitemap_pages_list">' .
164
  wp_list_pages( array('title_li' => '', 'echo' => false ) ) .
165
  '</ul>'
166
  ;
167
  if ( $this->options['sitemap_show_category_listing'] )
168
  $html .=
169
+ '<h' . $this->options['sitemap_heading_type'] . ' class="toc_sitemap_categories">' . htmlentities( $this->options['sitemap_categories'], ENT_COMPAT, 'UTF-8' ) . '</h' . $this->options['sitemap_heading_type'] . '>' .
170
  '<ul class="toc_sitemap_categories_list">' .
171
  wp_list_categories( array( 'title_li' => '', 'echo' => false ) ) .
172
  '</ul>'
182
  {
183
  extract( shortcode_atts( array(
184
  'heading' => $this->options['sitemap_heading_type'],
185
+ 'label' => htmlentities( $this->options['sitemap_pages'], ENT_COMPAT, 'UTF-8' ),
186
  'no_label' => false,
187
  'exclude' => ''
188
  ), $atts )
208
  {
209
  extract( shortcode_atts( array(
210
  'heading' => $this->options['sitemap_heading_type'],
211
+ 'label' => htmlentities( $this->options['sitemap_pages'], ENT_COMPAT, 'UTF-8' ),
212
  'no_label' => false,
213
  'exclude' => ''
214
  ), $atts )
282
  // require an administrator level to save
283
  if ( !current_user_can( 'manage_options', $post_id ) )
284
  return false;
285
+
286
+ // use stripslashes on free text fields that can have ' " \
287
+ // WordPress automatically slashes these characters as part of
288
+ // wp-includes/load.php::wp_magic_quotes()
289
 
290
  $this->options = array(
291
+ 'fragment_prefix' => trim($_POST['fragment_prefix']),
292
  'position' => intval($_POST['position']),
293
  'start' => intval($_POST['start']),
294
  'show_heading_text' => ($_POST['show_heading_text']) ? true : false,
295
+ 'heading_text' => stripslashes( trim($_POST['heading_text']) ),
296
  'auto_insert_post_types' => (array)$_POST['auto_insert_post_types'],
297
  'show_heirarchy' => ($_POST['show_heirarchy']) ? true : false,
298
  'ordered_list' => ($_POST['ordered_list']) ? true : false,
306
  'sitemap_show_page_listing' => ($_POST['sitemap_show_page_listing']) ? true : false,
307
  'sitemap_show_category_listing' => ($_POST['sitemap_show_category_listing']) ? true : false,
308
  'sitemap_heading_type' => intval($_POST['sitemap_heading_type']),
309
+ 'sitemap_pages' => stripslashes( trim($_POST['sitemap_pages']) ),
310
+ 'sitemap_categories' => stripslashes( trim($_POST['sitemap_categories']) )
311
  );
312
 
313
  // update_option will return false if no changes were made
375
  <td>
376
  <input type="checkbox" value="1" id="show_heading_text" name="show_heading_text"<?php if ( $this->options['show_heading_text'] ) echo ' checked="checked"'; ?> /><label for="show_heading_text"> <?php _e('Show title on top of the table of contents', 'toc+'); ?></label><br />
377
  <div class="more_toc_options<?php if ( !$this->options['show_heading_text'] ) echo ' disabled'; ?>">
378
+ <input type="text" class="regular-text" value="<?php echo htmlentities( $this->options['heading_text'], ENT_COMPAT, 'UTF-8' ); ?>" id="heading_text" name="heading_text" />
379
  <span class="description"><label for="heading_text"><?php _e('Eg: Contents, Table of Contents, Page Contents', 'toc+'); ?></label></span>
380
  </div>
381
  </td>
440
  </select>
441
  <div class="more_toc_options<?php if ( 'User defined' != $this->options['width'] ) echo ' disabled'; ?>">
442
  <label for="width_custom"><?php _e('Please enter a number and', 'toc+'); ?></label><label for="width_custom_units"> <?php _e('select its units, eg: 100px, 10em', 'toc+'); ?></label><br />
443
+ <input type="text" class="regular-text" value="<?php echo intval($this->options['width_custom']); ?>" id="width_custom" name="width_custom" />
444
  <select name="width_custom_units" id="width_custom_units">
445
  <option value="px"<?php if ( 'px' == $this->options['width_custom_units'] ) echo ' selected="selected"'; ?>>px</option>
446
  <option value="%"<?php if ( '%' == $this->options['width_custom_units'] ) echo ' selected="selected"'; ?>>%</option>
494
  <input type="text" name="background_colour" id="background_colour" value="#00ffff" /><div id="background_colour_wheel"></div>
495
  -->
496
 
497
+ <h3><?php _e('Advanced', 'toc+'); ?> <span class="show_hide">(<a href="#toc_advanced_usage">show</a>)</span></h3>
498
  <div id="toc_advanced_usage">
499
+ <h4><?php _e('Power options', 'toc+'); ?></h4>
500
+ <table class="form-table">
501
+ <tbody>
502
+ <tr>
503
+ <th><label for="fragment_prefix"><?php _e('Default anchor prefix', 'toc+'); ?></label></th>
504
+ <td>
505
+ <input type="text" class="regular-text" value="<?php echo htmlentities( $this->options['fragment_prefix'] ); ?>" id="fragment_prefix" name="fragment_prefix" /><br />
506
+ <label for="fragment_prefix"><?php _e('Anchor targets are restricted to alphanumeric characters as per HTML specification (see readme for more detail). The default anchor prefix will be used when no characters qualify. When left blank, a number will be used instead.'); ?><br />
507
+ <?php _e('This option normally applies to content written in character sets other than ASCII.', 'toc+'); ?><br />
508
+ <span class="description"><?php _e('Eg: i, toc_index, index, _', 'toc+'); ?></span></label>
509
+ </td>
510
+ </tr>
511
+ </tbody>
512
+ </table>
513
+
514
+ <h4><?php _e('Usage', 'toc+'); ?></h4>
515
  <p>If you would like to fully customise the position of the table of contents, you can use the <code>[toc]</code> shortcode by placing it at the desired position of your post, page or custom post type. This method allows you to generate the table of contents despite having auto insertion disabled for its content type. Supports the following parameters:</p>
516
  <ul>
517
  <li><strong>label</strong> text, title of the table of contents</li>
551
  </tr>
552
  <tr>
553
  <th><label for="sitemap_pages"><?php _e('Pages label', 'toc+'); ?></label></th>
554
+ <td><input type="text" class="regular-text" value="<?php echo htmlentities( $this->options['sitemap_pages'], ENT_COMPAT, 'UTF-8' ); ?>" id="sitemap_pages" name="sitemap_pages" />
555
  <span class="description"><?php _e('Eg: Pages, Page List', 'toc+'); ?></span>
556
  </td>
557
  </tr>
558
  <tr>
559
  <th><label for="sitemap_categories"><?php _e('Categories label', 'toc+'); ?></label></th>
560
+ <td><input type="text" class="regular-text" value="<?php echo htmlentities( $this->options['sitemap_categories'], ENT_COMPAT, 'UTF-8' ); ?>" id="sitemap_categories" name="sitemap_categories" />
561
  <span class="description"><?php _e('Eg: Categories, Category List', 'toc+'); ?></span>
562
  </td>
563
  </tr>
645
  $return = trim( strip_tags($title) );
646
 
647
  // remove &amp;
648
+ $return = str_replace( '&amp;', '', $return );
649
 
650
+ // remove non alphanumeric chars
651
+ $return = preg_replace( '/[^a-zA-Z0-9 \-_]*/', '', $return );
652
 
653
  // convert spaces to _
654
  $return = str_replace(
656
  '_',
657
  $return
658
  );
659
+
660
+ // remove leading _- if any
661
+ $return = ltrim( $return, '_-' );
662
+
663
+ // if only a number, then prepend with the prefix to avoid any collisions with IDs
664
+ if ( is_numeric($return) ) {
665
+ $return = ( $this->options['fragment_prefix'] ) ? $this->options['fragment_prefix'] . '-' . $return : '_' . $return;
666
+ }
667
  }
668
 
669
  return $return;
836
  $html .= ';"';
837
  }
838
  $html .= '>';
839
+ if ( $this->options['show_heading_text'] ) $html .= '<p class="toc_title">' . htmlentities( $this->options['heading_text'], ENT_COMPAT, 'UTF-8' ) . '</p>';
840
  $html .= '<ul>' . $items . '</ul></div>' . "\n";
841
 
842
  if ( $custom_toc_position !== false ) {