diff options
| author | mitaa <mitaa.ceb@gmail.com> | 2015-12-03 00:06:26 +0100 |
|---|---|---|
| committer | mitaa <mitaa.ceb@gmail.com> | 2015-12-03 00:07:59 +0100 |
| commit | 538689ddc7fe9a7176d6722b6c37e2e082e5fd08 (patch) | |
| tree | 6ad4aaae096d0850d860107ffc767078d14987d6 | |
| parent | d5321f2abe7f6fadf8a3993b113ebb8ce9266fe9 (diff) | |
| download | rust-538689ddc7fe9a7176d6722b6c37e2e082e5fd08.tar.gz rust-538689ddc7fe9a7176d6722b6c37e2e082e5fd08.zip | |
Move ID generator to a more suited location
| -rw-r--r-- | src/librustdoc/html/markdown.rs | 49 | ||||
| -rw-r--r-- | src/librustdoc/html/render.rs | 31 | ||||
| -rw-r--r-- | src/librustdoc/markdown.rs | 5 |
3 files changed, 45 insertions, 40 deletions
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index f68e82501e9..9496b7e2a6f 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -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; @@ -29,19 +29,19 @@ 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 @@ impl 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; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 574b9b599f5..c4fb9d5d9e7 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -342,6 +342,35 @@ impl fmt::Display for IndexItemFunctionType { 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 @@ impl Context { 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 diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index a311b938e96..ac64fd3bec0 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -21,9 +21,10 @@ use rustc::session::search_paths::SearchPaths; 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)) |
