]> git.lizzy.rs Git - rust.git/commitdiff
Move ID generator to a more suited location
authormitaa <mitaa.ceb@gmail.com>
Wed, 2 Dec 2015 23:06:26 +0000 (00:06 +0100)
committermitaa <mitaa.ceb@gmail.com>
Wed, 2 Dec 2015 23:07:59 +0000 (00:07 +0100)
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/markdown.rs

index f68e82501e91ea4d9123b85d25933553edf4da86..9496b7e2a6fbe3b3d868f30e2e7d6d4437de2c48 100644 (file)
@@ -14,7 +14,7 @@
 //! (bundled into the rust runtime). This module self-contains the C bindings
 //! and necessary legwork to render markdown, and exposes all of the
 //! functionality through a unit-struct, `Markdown`, which has an implementation
-//! of `fmt::String`. Example usage:
+//! of `fmt::Display`. Example usage:
 //!
 //! ```rust,ignore
 //! use rustdoc::html::markdown::Markdown;
 use libc;
 use std::ascii::AsciiExt;
 use std::cell::RefCell;
-use std::collections::HashMap;
 use std::default::Default;
 use std::ffi::CString;
 use std::fmt;
 use std::slice;
 use std::str;
 
+use html::render::{with_unique_id, reset_ids};
 use html::toc::TocBuilder;
 use html::highlight;
 use html::escape::Escape;
 use test;
 
-/// A unit struct which has the `fmt::String` trait implemented. When
+/// A unit struct which has the `fmt::Display` trait implemented. When
 /// formatted, this struct will emit the HTML corresponding to the rendered
 /// version of the contained markdown string.
 pub struct Markdown<'a>(pub &'a str);
@@ -210,10 +210,6 @@ fn collapse_whitespace(s: &str) -> String {
     s.split_whitespace().collect::<Vec<_>>().join(" ")
 }
 
-thread_local!(static USED_HEADER_MAP: RefCell<HashMap<String, usize>> = {
-    RefCell::new(HashMap::new())
-});
-
 thread_local!(pub static PLAYGROUND_KRATE: RefCell<Option<Option<String>>> = {
     RefCell::new(None)
 });
@@ -311,31 +307,22 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
         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 = match map.borrow_mut().get_mut(&id) {
-                None => id,
-                Some(a) => { *a += 1; format!("{}-{}", id, *a - 1) }
-            };
-            map.borrow_mut().insert(id.clone(), 1);
-            id
-        });
-
+        let text = with_unique_id(id, |id| {
+            let sec = opaque.toc_builder.as_mut().map_or("".to_owned(), |builder| {
+                format!("{} ", builder.push(level as u32, s.clone(), id.to_owned()))
+            });
 
-        let sec = opaque.toc_builder.as_mut().map_or("".to_owned(), |builder| {
-            format!("{} ", builder.push(level as u32, s.clone(), id.clone()))
+            // Render the HTML
+            format!("<h{lvl} id='{id}' class='section-header'>\
+                    <a href='#{id}'>{sec}{}</a></h{lvl}>",
+                    s, lvl = level, id = id, sec = sec)
         });
 
-        // Render the HTML
-        let text = format!("<h{lvl} id='{id}' class='section-header'>\
-                           <a href='#{id}'>{sec}{}</a></h{lvl}>",
-                           s, lvl = level, id = id, sec = sec);
-
         let text = CString::new(text).unwrap();
         unsafe { hoedown_buffer_puts(ob, text.as_ptr()) }
     }
 
-    reset_headers();
+    reset_ids();
 
     extern fn codespan(
         ob: *mut hoedown_buffer,
@@ -500,18 +487,6 @@ fn parse(string: &str) -> LangString {
     }
 }
 
-/// By default this markdown renderer generates anchors for each header in the
-/// rendered document. The anchor name is the contents of the header separated
-/// by hyphens, and a thread-local map is used to disambiguate among duplicate
-/// headers (numbers are appended).
-///
-/// This method will reset the local table for these headers. This is typically
-/// used at the beginning of rendering an entire HTML page to reset from the
-/// previous state (if any).
-pub fn reset_headers() {
-    USED_HEADER_MAP.with(|s| s.borrow_mut().clear());
-}
-
 impl<'a> fmt::Display for Markdown<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let Markdown(md) = *self;
index 574b9b599f5f8d35aded223a14aeda010fa69a3b..c4fb9d5d9e7d5337aa7ed6e9ad2bb568a2a8de43 100644 (file)
@@ -342,6 +342,35 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 thread_local!(static CACHE_KEY: RefCell<Arc<Cache>> = Default::default());
 thread_local!(pub static CURRENT_LOCATION_KEY: RefCell<Vec<String>> =
                     RefCell::new(Vec::new()));
+thread_local!(static USED_ID_MAP: RefCell<HashMap<String, usize>> =
+                    RefCell::new(HashMap::new()));
+
+/// This method resets the local table of used ID attributes. This is typically
+/// used at the beginning of rendering an entire HTML page to reset from the
+/// previous state (if any).
+pub fn reset_ids() {
+    USED_ID_MAP.with(|s| s.borrow_mut().clear());
+}
+
+pub fn with_unique_id<T, F: FnOnce(&str) -> T>(candidate: String, f: F) -> T {
+    USED_ID_MAP.with(|map| {
+        let (id, ret) = match map.borrow_mut().get_mut(&candidate) {
+            None => {
+                let ret = f(&candidate);
+                (candidate, ret)
+            },
+            Some(a) => {
+                let id = format!("{}-{}", candidate, *a);
+                let ret = f(&id);
+                *a += 1;
+                (id, ret)
+            }
+        };
+
+        map.borrow_mut().insert(id, 1);
+        ret
+    })
+}
 
 /// Generates the documentation for `crate` into the directory `dst`
 pub fn run(mut krate: clean::Crate,
@@ -1274,7 +1303,7 @@ fn render(w: File, cx: &Context, it: &clean::Item,
                 keywords: &keywords,
             };
 
-            markdown::reset_headers();
+            reset_ids();
 
             // We have a huge number of calls to write, so try to alleviate some
             // of the pain by using a buffered writer instead of invoking the
index a311b938e9609de758e1756e3de20828a0077b03..ac64fd3bec0e75d81c2d248378928a53e9eb5072 100644 (file)
 
 use externalfiles::ExternalHtml;
 
+use html::render::reset_ids;
 use html::escape::Escape;
 use html::markdown;
-use html::markdown::{Markdown, MarkdownWithToc, find_testable_code, reset_headers};
+use html::markdown::{Markdown, MarkdownWithToc, find_testable_code};
 use test::{TestOptions, Collector};
 
 /// Separate any lines at the start of the file that begin with `%`.
@@ -82,7 +83,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
     }
     let title = metadata[0];
 
-    reset_headers();
+    reset_ids();
 
     let rendered = if include_toc {
         format!("{}", MarkdownWithToc(text))