@@ -283,19 +283,37 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
283
283
str:: from_utf8 ( s) . unwrap ( ) . to_string ( )
284
284
} ;
285
285
286
- // Transform the contents of the header into a hyphenated string
287
- let id = s . split_whitespace ( ) . map ( |s| s . to_ascii_lowercase ( ) )
288
- . collect :: < Vec < String > > ( ) . join ( "-" ) ;
289
-
286
+ // Discard '<em>', '<code>' tags and some escaped characters,
287
+ // transform the contents of the header into a hyphenated string
288
+ // without non-alphanumeric characters other than '-' and '_'.
289
+ //
290
290
// This is a terrible hack working around how hoedown gives us rendered
291
291
// html for text rather than the raw text.
292
+ let mut id = s. clone ( ) ;
293
+ let repl_sub = vec ! [ "<em>" , "</em>" , "<code>" , "</code>" ,
294
+ "<" , ">" , "&" , "'" , """ ] ;
295
+ for sub in repl_sub {
296
+ id = id. replace ( sub, "" ) ;
297
+ }
298
+ let id = id. chars ( ) . filter_map ( |c| {
299
+ if c. is_alphanumeric ( ) || c == '-' || c == '_' {
300
+ if c. is_ascii ( ) {
301
+ Some ( c. to_ascii_lowercase ( ) )
302
+ } else {
303
+ Some ( c)
304
+ }
305
+ } else if c. is_whitespace ( ) && c. is_ascii ( ) {
306
+ Some ( '-' )
307
+ } else {
308
+ None
309
+ }
310
+ } ) . collect :: < String > ( ) ;
292
311
293
312
let opaque = unsafe { ( * data) . opaque as * mut hoedown_html_renderer_state } ;
294
313
let opaque = unsafe { & mut * ( ( * opaque) . opaque as * mut MyOpaque ) } ;
295
314
296
315
// Make sure our hyphenated ID is unique for this page
297
316
let id = USED_HEADER_MAP . with ( |map| {
298
- let id = id. replace ( "<code>" , "" ) . replace ( "</code>" , "" ) . to_string ( ) ;
299
317
let id = match map. borrow_mut ( ) . get_mut ( & id) {
300
318
None => id,
301
319
Some ( a) => { * a += 1 ; format ! ( "{}-{}" , id, * a - 1 ) }
0 commit comments