Skip to content

Commit 5299740

Browse files
committed
rustdoc: eliminates raw markdown code (links, headers, etc.) from tooltips of sidebar
1 parent 0c06442 commit 5299740

File tree

2 files changed

+108
-5
lines changed

2 files changed

+108
-5
lines changed

src/librustdoc/html/markdown.rs

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,34 @@ type headerfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
7474

7575
#[repr(C)]
7676
struct hoedown_renderer {
77-
opaque: *mut hoedown_html_renderer_state,
77+
opaque: *mut libc::c_void,
78+
7879
blockcode: Option<blockcodefn>,
7980
blockquote: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
8081
*mut libc::c_void)>,
8182
blockhtml: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
8283
*mut libc::c_void)>,
8384
header: Option<headerfn>,
84-
other: [libc::size_t; 28],
85+
86+
other_block_level_callbacks: [libc::size_t, ..9],
87+
88+
/* span level callbacks - NULL or return 0 prints the span verbatim */
89+
other_span_level_callbacks_1: [libc::size_t, ..9],
90+
link: Option<extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
91+
*const hoedown_buffer, *const hoedown_buffer,
92+
*mut libc::c_void) -> libc::c_int>,
93+
other_span_level_callbacks_2: [libc::size_t, ..5],
94+
// hoedown will add `math` callback here, but we use an old version of it.
95+
96+
/* low level callbacks - NULL copies input directly into the output */
97+
entity: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
98+
*mut libc::c_void)>,
99+
normal_text: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
100+
*mut libc::c_void)>,
101+
102+
/* header and footer */
103+
doc_header: Option<extern "C" fn(*mut hoedown_buffer, *mut libc::c_void)>,
104+
doc_footer: Option<extern "C" fn(*mut hoedown_buffer, *mut libc::c_void)>,
85105
}
86106

87107
#[repr(C)]
@@ -134,6 +154,8 @@ extern {
134154
fn hoedown_document_free(md: *mut hoedown_document);
135155

136156
fn hoedown_buffer_new(unit: libc::size_t) -> *mut hoedown_buffer;
157+
fn hoedown_buffer_put(b: *mut hoedown_buffer, c: *const libc::c_char,
158+
n: libc::size_t);
137159
fn hoedown_buffer_puts(b: *mut hoedown_buffer, c: *const libc::c_char);
138160
fn hoedown_buffer_free(b: *mut hoedown_buffer);
139161

@@ -279,7 +301,8 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
279301
dfltblk: (*renderer).blockcode.unwrap(),
280302
toc_builder: if print_toc {Some(TocBuilder::new())} else {None}
281303
};
282-
(*(*renderer).opaque).opaque = &mut opaque as *mut _ as *mut libc::c_void;
304+
(*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
305+
= &mut opaque as *mut _ as *mut libc::c_void;
283306
(*renderer).blockcode = Some(block as blockcodefn);
284307
(*renderer).header = Some(header as headerfn);
285308

@@ -355,7 +378,8 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
355378
let renderer = hoedown_html_renderer_new(0, 0);
356379
(*renderer).blockcode = Some(block as blockcodefn);
357380
(*renderer).header = Some(header as headerfn);
358-
(*(*renderer).opaque).opaque = tests as *mut _ as *mut libc::c_void;
381+
(*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
382+
= tests as *mut _ as *mut libc::c_void;
359383

360384
let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
361385
hoedown_document_render(document, ob, doc.as_ptr(),
@@ -442,9 +466,59 @@ impl<'a> fmt::String for MarkdownWithToc<'a> {
442466
}
443467
}
444468

469+
pub fn plain_summary_line(md: &str) -> String {
470+
extern "C" fn link(_ob: *mut hoedown_buffer,
471+
_link: *const hoedown_buffer,
472+
_title: *const hoedown_buffer,
473+
content: *const hoedown_buffer,
474+
opaque: *mut libc::c_void) -> libc::c_int
475+
{
476+
unsafe {
477+
if !content.is_null() && (*content).size > 0 {
478+
// FIXME(liigo): I don't know why the parameter `_ob` is
479+
// not the value passed in by `hoedown_document_render`.
480+
// I have to manually pass in `ob` through `opaque` currently.
481+
let ob = opaque as *mut hoedown_buffer;
482+
hoedown_buffer_put(ob, (*content).data as *const libc::c_char,
483+
(*content).size);
484+
}
485+
}
486+
1
487+
}
488+
489+
extern "C" fn normal_text(_ob: *mut hoedown_buffer,
490+
text: *const hoedown_buffer,
491+
opaque: *mut libc::c_void)
492+
{
493+
unsafe {
494+
let ob = opaque as *mut hoedown_buffer;
495+
hoedown_buffer_put(ob, (*text).data as *const libc::c_char,
496+
(*text).size);
497+
}
498+
}
499+
500+
unsafe {
501+
let ob = hoedown_buffer_new(DEF_OUNIT);
502+
let mut plain_renderer: hoedown_renderer = ::std::mem::zeroed();
503+
let renderer = &mut plain_renderer as *mut hoedown_renderer;
504+
(*renderer).opaque = ob as *mut libc::c_void;
505+
(*renderer).link = Some(link);
506+
(*renderer).normal_text = Some(normal_text);
507+
508+
let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
509+
hoedown_document_render(document, ob, md.as_ptr(),
510+
md.len() as libc::size_t);
511+
hoedown_document_free(document);
512+
let plain = String::from_raw_buf_len((*ob).data, (*ob).size as uint);
513+
hoedown_buffer_free(ob);
514+
plain
515+
}
516+
}
517+
445518
#[cfg(test)]
446519
mod tests {
447520
use super::{LangString, Markdown};
521+
use super::plain_summary_line;
448522

449523
#[test]
450524
fn test_lang_string_parse() {
@@ -478,4 +552,18 @@ mod tests {
478552
let markdown = "# title";
479553
format!("{}", Markdown(markdown.as_slice()));
480554
}
555+
556+
#[test]
557+
fn test_plain_summary_line() {
558+
fn t(input: &str, expect: &str) {
559+
let output = plain_summary_line(input);
560+
assert_eq!(output, expect);
561+
}
562+
563+
t("hello [Rust](http://rust-lang.org) :)", "hello Rust :)");
564+
t("code `let x = i32;` ...", "code `let x = i32;` ...");
565+
t("type `Type<'static>` ...", "type `Type<'static>` ...");
566+
t("# top header", "top header");
567+
t("## header", "header");
568+
}
481569
}

src/librustdoc/html/render.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2197,6 +2197,21 @@ fn item_typedef(w: &mut fmt::Formatter, it: &clean::Item,
21972197
document(w, it)
21982198
}
21992199

2200+
fn escape_title(title: &str) -> String {
2201+
let title = markdown::plain_summary_line(title);
2202+
let mut result = String::with_capacity(title.len());
2203+
for c in title.chars() {
2204+
match c {
2205+
'<' => result.push_str("&lt;"),
2206+
'>' => result.push_str("&gt;"),
2207+
'"' => result.push_str("&quot;"),
2208+
'\'' => result.push_str("&#39;"),
2209+
_ => result.push(c),
2210+
}
2211+
}
2212+
result
2213+
}
2214+
22002215
impl<'a> fmt::String for Sidebar<'a> {
22012216
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
22022217
let cx = self.cx;
@@ -2236,7 +2251,7 @@ impl<'a> fmt::String for Sidebar<'a> {
22362251
} else {
22372252
format!("{}.{}.html", short, name.as_slice())
22382253
},
2239-
title = doc.as_ref().unwrap().as_slice(),
2254+
title = escape_title(doc.as_ref().unwrap().as_slice()),
22402255
name = name.as_slice()));
22412256
}
22422257
try!(write!(w, "</div>"));

0 commit comments

Comments
 (0)