about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSimon Mazur <semmaz.box@gmail.com>2015-09-18 15:05:35 +0300
committerSimon Mazur <semmaz.box@gmail.com>2015-09-20 13:12:27 +0300
commitb8cfa59be0a6b5200e525ff68390ede34698e909 (patch)
tree4d02bd2829244ffa878943457330af46125b941b
parentfd38a75077a4c5efc87413b7f9f7f1b6bc9db9af (diff)
downloadrust-b8cfa59be0a6b5200e525ff68390ede34698e909.tar.gz
rust-b8cfa59be0a6b5200e525ff68390ede34698e909.zip
rustdoc: Changed section headers anchor rendering
-rw-r--r--src/librustdoc/html/markdown.rs28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index c98a54e4514..e5dbe534af8 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -283,19 +283,37 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
             str::from_utf8(s).unwrap().to_string()
         };
 
-        // Transform the contents of the header into a hyphenated string
-        let id = s.split_whitespace().map(|s| s.to_ascii_lowercase())
-            .collect::<Vec<String>>().join("-");
-
+        // Discard '<em>', '<code>' tags and some escaped characters,
+        // transform the contents of the header into a hyphenated string
+        // without non-alphanumeric characters other than '-' and '_'.
+        //
         // This is a terrible hack working around how hoedown gives us rendered
         // html for text rather than the raw text.
+        let mut id = s.clone();
+        let repl_sub = vec!["<em>", "</em>", "<code>", "</code>",
+                            "&lt;", "&gt;", "&amp;", "&#39;", "&quot;"];
+        for sub in repl_sub {
+            id = id.replace(sub, "");
+        }
+        let id = id.chars().filter_map(|c| {
+            if c.is_alphanumeric() || c == '-' || c == '_' {
+                if c.is_ascii() {
+                    Some(c.to_ascii_lowercase())
+                } else {
+                    Some(c)
+                }
+            } else if c.is_whitespace() && c.is_ascii() {
+                Some('-')
+            } else {
+                None
+            }
+        }).collect::<String>();
 
         let opaque = unsafe { (*data).opaque as *mut hoedown_html_renderer_state };
         let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) };
 
         // Make sure our hyphenated ID is unique for this page
         let id = USED_HEADER_MAP.with(|map| {
-            let id = id.replace("<code>", "").replace("</code>", "").to_string();
             let id = match map.borrow_mut().get_mut(&id) {
                 None => id,
                 Some(a) => { *a += 1; format!("{}-{}", id, *a - 1) }