diff --git a/.gitmodules b/.gitmodules index d2e1fb868a9..53d17874924 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,10 +5,6 @@ [submodule "src/compiler-rt"] path = src/compiler-rt url = https://github.com/rust-lang/compiler-rt.git -[submodule "src/rt/hoedown"] - path = src/rt/hoedown - url = https://github.com/rust-lang/hoedown.git - branch = rust-2015-09-21-do-not-delete [submodule "src/jemalloc"] path = src/jemalloc url = https://github.com/rust-lang/jemalloc.git diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 2222077aae8..ff18daa7aa0 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -2,7 +2,6 @@ authors = ["The Rust Project Developers"] name = "rustdoc" version = "0.0.0" -build = "build.rs" [lib] name = "rustdoc" diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs deleted file mode 100644 index 9fa6406c1d8..00000000000 --- a/src/librustdoc/build.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate build_helper; -extern crate gcc; - -fn main() { - let src_dir = std::path::Path::new("../rt/hoedown/src"); - build_helper::rerun_if_changed_anything_in_dir(src_dir); - let mut cfg = gcc::Config::new(); - cfg.file("../rt/hoedown/src/autolink.c") - .file("../rt/hoedown/src/buffer.c") - .file("../rt/hoedown/src/document.c") - .file("../rt/hoedown/src/escape.c") - .file("../rt/hoedown/src/html.c") - .file("../rt/hoedown/src/html_blocks.c") - .file("../rt/hoedown/src/html_smartypants.c") - .file("../rt/hoedown/src/stack.c") - .file("../rt/hoedown/src/version.c") - .include(src_dir) - .compile("libhoedown.a"); -} diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index a36e99e80df..9ae6c443f9e 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -26,7 +26,7 @@ #![allow(non_camel_case_types)] -use libc; +//use libc; use std::ascii::AsciiExt; use std::cell::RefCell; use std::default::Default; @@ -43,158 +43,19 @@ use html::highlight; use html::escape::Escape; use test; -use pulldown_cmark::{self, Event, Parser}; +use pulldown_cmark::{self, Event, Parser, Tag}; /// 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); +// The second parameter is whether we need a shorter version or not. +pub struct Markdown<'a>(pub &'a str, pub bool); /// A unit struct like `Markdown`, that renders the markdown with a /// table of contents. pub struct MarkdownWithToc<'a>(pub &'a str); /// A unit struct like `Markdown`, that renders the markdown escaping HTML tags. pub struct MarkdownHtml<'a>(pub &'a str); -/*const DEF_OUNIT: libc::size_t = 64; -const HOEDOWN_EXT_NO_INTRA_EMPHASIS: libc::c_uint = 1 << 11; -const HOEDOWN_EXT_TABLES: libc::c_uint = 1 << 0; -const HOEDOWN_EXT_FENCED_CODE: libc::c_uint = 1 << 1; -const HOEDOWN_EXT_AUTOLINK: libc::c_uint = 1 << 3; -const HOEDOWN_EXT_STRIKETHROUGH: libc::c_uint = 1 << 4; -const HOEDOWN_EXT_SUPERSCRIPT: libc::c_uint = 1 << 8; -const HOEDOWN_EXT_FOOTNOTES: libc::c_uint = 1 << 2; -const HOEDOWN_HTML_ESCAPE: libc::c_uint = 1 << 1; - -const HOEDOWN_EXTENSIONS: libc::c_uint = - HOEDOWN_EXT_NO_INTRA_EMPHASIS | HOEDOWN_EXT_TABLES | - HOEDOWN_EXT_FENCED_CODE | HOEDOWN_EXT_AUTOLINK | - HOEDOWN_EXT_STRIKETHROUGH | HOEDOWN_EXT_SUPERSCRIPT | - HOEDOWN_EXT_FOOTNOTES; - -enum hoedown_document {} - -type blockcodefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer, - *const hoedown_buffer, *const hoedown_renderer_data, - libc::size_t); - -type blockquotefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer, - *const hoedown_renderer_data, libc::size_t); - -type headerfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer, - libc::c_int, *const hoedown_renderer_data, - libc::size_t); - -type blockhtmlfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer, - *const hoedown_renderer_data, libc::size_t); - -type codespanfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer, - *const hoedown_renderer_data, libc::size_t) -> libc::c_int; - -type linkfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer, - *const hoedown_buffer, *const hoedown_buffer, - *const hoedown_renderer_data, libc::size_t) -> libc::c_int; - -type entityfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer, - *const hoedown_renderer_data, libc::size_t); - -type normaltextfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer, - *const hoedown_renderer_data, libc::size_t); - -#[repr(C)] -struct hoedown_renderer_data { - opaque: *mut libc::c_void, -} - -#[repr(C)] -struct hoedown_renderer { - opaque: *mut libc::c_void, - - blockcode: Option, - blockquote: Option, - header: Option, - - other_block_level_callbacks: [libc::size_t; 11], - - blockhtml: Option, - - /* span level callbacks - NULL or return 0 prints the span verbatim */ - autolink: libc::size_t, // unused - codespan: Option, - other_span_level_callbacks_1: [libc::size_t; 7], - link: Option, - other_span_level_callbacks_2: [libc::size_t; 6], - - /* low level callbacks - NULL copies input directly into the output */ - entity: Option, - normal_text: Option, - - /* header and footer */ - other_callbacks: [libc::size_t; 2], -} - -#[repr(C)] -struct hoedown_html_renderer_state { - opaque: *mut libc::c_void, - toc_data: html_toc_data, - flags: libc::c_uint, - link_attributes: Option, -} - -#[repr(C)] -struct html_toc_data { - header_count: libc::c_int, - current_level: libc::c_int, - level_offset: libc::c_int, - nesting_level: libc::c_int, -} - -struct MyOpaque { - dfltblk: extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer, - *const hoedown_buffer, *const hoedown_renderer_data, - libc::size_t), - toc_builder: Option, -} - -#[repr(C)] -struct hoedown_buffer { - data: *const u8, - size: libc::size_t, - asize: libc::size_t, - unit: libc::size_t, -} - -extern { - fn hoedown_html_renderer_new(render_flags: libc::c_uint, - nesting_level: libc::c_int) - -> *mut hoedown_renderer; - fn hoedown_html_renderer_free(renderer: *mut hoedown_renderer); - - fn hoedown_document_new(rndr: *const hoedown_renderer, - extensions: libc::c_uint, - max_nesting: libc::size_t) -> *mut hoedown_document; - fn hoedown_document_render(doc: *mut hoedown_document, - ob: *mut hoedown_buffer, - document: *const u8, - doc_size: libc::size_t); - fn hoedown_document_free(md: *mut hoedown_document); - - fn hoedown_buffer_new(unit: libc::size_t) -> *mut hoedown_buffer; - /*fn hoedown_buffer_put(b: *mut hoedown_buffer, c: *const libc::c_char, - n: libc::size_t);*/ - fn hoedown_buffer_puts(b: *mut hoedown_buffer, c: *const libc::c_char); - fn hoedown_buffer_free(b: *mut hoedown_buffer); - -} - -// hoedown_buffer helpers -impl hoedown_buffer { - fn as_bytes(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.data, self.size as usize) } - } -}*/ - /// Returns Some(code) if `s` is a line that should be stripped from /// documentation but used in example code. `code` is the portion of /// `s` that should be used in tests. (None for lines that should be @@ -228,213 +89,15 @@ thread_local!(pub static PLAYGROUND: RefCell, String)>> = pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool, - _html_flags: libc::c_uint) -> fmt::Result { - /*extern fn block(ob: *mut hoedown_buffer, orig_text: *const hoedown_buffer, - lang: *const hoedown_buffer, data: *const hoedown_renderer_data, - line: libc::size_t) { - unsafe { - if orig_text.is_null() { return } - - let opaque = (*data).opaque as *mut hoedown_html_renderer_state; - let my_opaque: &MyOpaque = &*((*opaque).opaque as *const MyOpaque); - let text = (*orig_text).as_bytes(); - let origtext = str::from_utf8(text).unwrap(); - let origtext = origtext.trim_left(); - debug!("docblock: ==============\n{:?}\n=======", text); - let rendered = if lang.is_null() || origtext.is_empty() { - false - } else { - let rlang = (*lang).as_bytes(); - let rlang = str::from_utf8(rlang).unwrap(); - if !LangString::parse(rlang).rust { - (my_opaque.dfltblk)(ob, orig_text, lang, - opaque as *const hoedown_renderer_data, - line); - true - } else { - false - } - }; - - let lines = origtext.lines().filter(|l| { - stripped_filtered_line(*l).is_none() - }); - let text = lines.collect::>().join("\n"); - if rendered { return } - PLAYGROUND.with(|play| { - // insert newline to clearly separate it from the - // previous block so we can shorten the html output - let mut s = String::from("\n"); - let playground_button = play.borrow().as_ref().and_then(|&(ref krate, ref url)| { - if url.is_empty() { - return None; - } - let test = origtext.lines().map(|l| { - stripped_filtered_line(l).unwrap_or(l) - }).collect::>().join("\n"); - let krate = krate.as_ref().map(|s| &**s); - let test = test::maketest(&test, krate, false, - &Default::default()); - let channel = if test.contains("#![feature(") { - "&version=nightly" - } else { - "" - }; - // These characters don't need to be escaped in a URI. - // FIXME: use a library function for percent encoding. - fn dont_escape(c: u8) -> bool { - (b'a' <= c && c <= b'z') || - (b'A' <= c && c <= b'Z') || - (b'0' <= c && c <= b'9') || - c == b'-' || c == b'_' || c == b'.' || - c == b'~' || c == b'!' || c == b'\'' || - c == b'(' || c == b')' || c == b'*' - } - let mut test_escaped = String::new(); - for b in test.bytes() { - if dont_escape(b) { - test_escaped.push(char::from(b)); - } else { - write!(test_escaped, "%{:02X}", b).unwrap(); - } - } - Some(format!( - r#"Run"#, - url, test_escaped, channel - )) - }); - s.push_str(&highlight::render_with_highlighting( - &text, - Some("rust-example-rendered"), - None, - playground_button.as_ref().map(String::as_str))); - let output = CString::new(s).unwrap(); - hoedown_buffer_puts(ob, output.as_ptr()); - }) - } - } - - extern fn header(ob: *mut hoedown_buffer, text: *const hoedown_buffer, - level: libc::c_int, data: *const hoedown_renderer_data, - _: libc::size_t) { - // hoedown does this, we may as well too - unsafe { hoedown_buffer_puts(ob, "\n\0".as_ptr() as *const _); } - - // Extract the text provided - let s = if text.is_null() { - "".to_owned() - } else { - let s = unsafe { (*text).as_bytes() }; - str::from_utf8(&s).unwrap().to_owned() - }; - - // Discard '', '' 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!["", "", "", "", - "", "", - "<", ">", "&", "'", """]; - 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::(); - - let opaque = unsafe { (*data).opaque as *mut hoedown_html_renderer_state }; - let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) }; - - let id = derive_id(id); - - 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 - let text = format!("\ - {sec}{}", - s, lvl = level, id = id, sec = sec); - - let text = CString::new(text).unwrap(); - unsafe { hoedown_buffer_puts(ob, text.as_ptr()) } - } - - extern fn codespan( - ob: *mut hoedown_buffer, - text: *const hoedown_buffer, - _: *const hoedown_renderer_data, - _: libc::size_t - ) -> libc::c_int { - let content = if text.is_null() { - "".to_owned() - } else { - let bytes = unsafe { (*text).as_bytes() }; - let s = str::from_utf8(bytes).unwrap(); - collapse_whitespace(s) - }; - - let content = format!("{}", Escape(&content)); - let element = CString::new(content).unwrap(); - unsafe { hoedown_buffer_puts(ob, element.as_ptr()); } - // Return anything except 0, which would mean "also print the code span verbatim". - 1 - } - - unsafe { - let ob = hoedown_buffer_new(DEF_OUNIT); - let renderer = hoedown_html_renderer_new(html_flags, 0); - let mut opaque = MyOpaque { - dfltblk: (*renderer).blockcode.unwrap(), - toc_builder: if print_toc {Some(TocBuilder::new())} else {None} - }; - (*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque - = &mut opaque as *mut _ as *mut libc::c_void; - (*renderer).blockcode = Some(block); - (*renderer).header = Some(header); - (*renderer).codespan = Some(codespan); - - let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16); - hoedown_document_render(document, ob, s.as_ptr(), - s.len() as libc::size_t); - hoedown_document_free(document); - - hoedown_html_renderer_free(renderer); - - let mut ret = opaque.toc_builder.map_or(Ok(()), |builder| { - write!(w, "", builder.into_toc()) - }); - - if ret.is_ok() { - let buf = (*ob).as_bytes(); - ret = w.write_str(str::from_utf8(buf).unwrap()); - } - hoedown_buffer_free(ob); - ret - }*/ - - fn block(parser: &mut Parser, lang: &str, buffer: &mut String) { + shorter: bool) -> fmt::Result { + fn block(parser: &mut Parser, buffer: &mut String, lang: &str) { let mut origtext = String::new(); loop { let event = parser.next(); if let Some(event) = event { match event { - pulldown_cmark::Event::End( - pulldown_cmark::Tag::CodeBlock(_)) => break, - pulldown_cmark::Event::Text(ref s) => { + Event::End(Tag::CodeBlock(_)) => break, + Event::Text(ref s) => { origtext.push_str(s); } _ => {} @@ -445,25 +108,21 @@ pub fn render(w: &mut fmt::Formatter, } let origtext = origtext.trim_left(); debug!("docblock: ==============\n{:?}\n=======", origtext); - let rendered = if lang.is_empty() || origtext.is_empty() { - false - } else { - if !LangString::parse(lang).rust { - /*(my_opaque.dfltblk)(ob, orig_text, lang, - opaque as *const hoedown_renderer_data, - line);*/ - // true - false - } else { - false - } - }; let lines = origtext.lines().filter(|l| { stripped_filtered_line(*l).is_none() }); let text = lines.collect::>().join("\n"); - if rendered { return } + let block_info = if lang.is_empty() { + LangString::all_false() + } else { + LangString::parse(lang) + }; + if !block_info.rust { + buffer.push_str(&format!("
{}
", + lang, text)); + return + } PLAYGROUND.with(|play| { // insert newline to clearly separate it from the // previous block so we can shorten the html output @@ -521,9 +180,8 @@ pub fn render(w: &mut fmt::Formatter, let event = parser.next(); if let Some(event) = event { match event { - pulldown_cmark::Event::End( - pulldown_cmark::Tag::Header(_)) => break, - pulldown_cmark::Event::Text(ref s) => { + Event::End(Tag::Header(_)) => break, + Event::Text(ref s) => { ret.push_str(s); } _ => {} @@ -561,8 +219,8 @@ pub fn render(w: &mut fmt::Formatter, }); // Render the HTML - buffer.push_str(&format!("\ - {sec}{}", + buffer.push_str(&format!("\ + {sec}{}", ret, lvl = level, id = id, sec = sec)); } @@ -572,9 +230,8 @@ pub fn render(w: &mut fmt::Formatter, let event = parser.next(); if let Some(event) = event { match event { - pulldown_cmark::Event::End( - pulldown_cmark::Tag::Code) => break, - pulldown_cmark::Event::Text(ref s) => { + Event::End(Tag::Code) => break, + Event::Text(ref s) => { content.push_str(s); } _ => {} @@ -591,9 +248,8 @@ pub fn render(w: &mut fmt::Formatter, let event = parser.next(); if let Some(event) = event { match event { - pulldown_cmark::Event::End( - pulldown_cmark::Tag::Link(_, _)) => break, - pulldown_cmark::Event::Text(ref s) => { + Event::End(Tag::Link(_, _)) => break, + Event::Text(ref s) => { title.push_str(s); } _ => {} @@ -605,19 +261,19 @@ pub fn render(w: &mut fmt::Formatter, buffer.push_str(&format!("{}", url, title)); } - fn paragraph(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option) { + fn paragraph(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option, + shorter: bool) { let mut content = String::new(); loop { let event = parser.next(); if let Some(event) = event { match event { - pulldown_cmark::Event::End( - pulldown_cmark::Tag::Paragraph) => break, - pulldown_cmark::Event::Text(ref s) => { + Event::End(Tag::Paragraph) => break, + Event::Text(ref s) => { content.push_str(s); } x => { - looper(parser, &mut content, Some(x), toc_builder); + looper(parser, &mut content, Some(x), toc_builder, shorter); } } } else { @@ -627,28 +283,135 @@ pub fn render(w: &mut fmt::Formatter, buffer.push_str(&format!("

{}

", content)); } + fn cell(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option, + shorter: bool) { + let mut content = String::new(); + loop { + let event = parser.next(); + if let Some(event) = event { + match event { + Event::End(Tag::TableHead) | + Event::End(Tag::Table(_)) | + Event::End(Tag::TableRow) | + Event::End(Tag::TableCell) => break, + Event::Text(ref s) => { + content.push_str(s); + } + x => { + looper(parser, &mut content, Some(x), toc_builder, shorter); + } + } + } else { + break + } + } + buffer.push_str(&format!("{}", content.trim())); + } + + fn row(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option, + shorter: bool) { + let mut content = String::new(); + loop { + let event = parser.next(); + if let Some(event) = event { + match event { + Event::End(Tag::TableHead) | + Event::End(Tag::Table(_)) | + Event::End(Tag::TableRow) => break, + Event::Start(Tag::TableCell) => { + cell(parser, &mut content, toc_builder, shorter); + } + x => { + looper(parser, &mut content, Some(x), toc_builder, shorter); + } + } + } else { + break + } + } + buffer.push_str(&format!("{}", content)); + } + + fn head(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option, + shorter: bool) { + let mut content = String::new(); + loop { + let event = parser.next(); + if let Some(event) = event { + match event { + Event::End(Tag::TableHead) | Event::End(Tag::Table(_)) => break, + Event::Start(Tag::TableCell) => { + cell(parser, &mut content, toc_builder, shorter); + } + x => { + looper(parser, &mut content, Some(x), toc_builder, shorter); + } + } + } else { + break + } + } + if content.is_empty() { + return + } + buffer.push_str(&format!("{}", content.replace("td>", "th>"))); + } + + fn table(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option, + shorter: bool) { + let mut content = String::new(); + let mut rows = String::new(); + loop { + let event = parser.next(); + if let Some(event) = event { + match event { + Event::End(Tag::Table(_)) => break, + Event::Start(Tag::TableHead) => { + head(parser, &mut content, toc_builder, shorter); + } + Event::Start(Tag::TableRow) => { + row(parser, &mut rows, toc_builder, shorter); + } + _ => {} + } + } else { + break + } + } + buffer.push_str(&format!("{}{}
", + content, + if shorter || rows.is_empty() { + String::new() + } else { + format!("{}", rows) + })); + } + fn looper<'a>(parser: &'a mut Parser, buffer: &mut String, next_event: Option>, - toc_builder: &mut Option) -> bool { + toc_builder: &mut Option, shorter: bool) -> bool { if let Some(event) = next_event { match event { - pulldown_cmark::Event::Start(pulldown_cmark::Tag::CodeBlock(s)) => { - block(parser, &*s, buffer); + Event::Start(Tag::CodeBlock(lang)) => { + block(parser, buffer, &*lang); } - pulldown_cmark::Event::Start(pulldown_cmark::Tag::Header(level)) => { + Event::Start(Tag::Header(level)) => { header(parser, level, toc_builder, buffer); } - pulldown_cmark::Event::Start(pulldown_cmark::Tag::Code) => { + Event::Start(Tag::Code) => { codespan(parser, buffer); } - pulldown_cmark::Event::Start(pulldown_cmark::Tag::Paragraph) => { - paragraph(parser, buffer, toc_builder); + Event::Start(Tag::Paragraph) => { + paragraph(parser, buffer, toc_builder, shorter); } - pulldown_cmark::Event::Start(pulldown_cmark::Tag::Link(ref url, ref t)) => { + Event::Start(Tag::Link(ref url, ref t)) => { link(parser, buffer, url, t.as_ref().to_owned()); } + Event::Start(Tag::Table(_)) => { + table(parser, buffer, toc_builder, shorter); + } _ => {} } - true + shorter == false } else { false } @@ -660,10 +423,10 @@ pub fn render(w: &mut fmt::Formatter, None }; let mut buffer = String::new(); - let mut parser = Parser::new(s); + let mut parser = Parser::new_ext(s, pulldown_cmark::OPTION_ENABLE_TABLES); loop { let next_event = parser.next(); - if !looper(&mut parser, &mut buffer, next_event, &mut toc_builder) { + if !looper(&mut parser, &mut buffer, next_event, &mut toc_builder, shorter) { break } } @@ -684,67 +447,64 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp let mut prev_offset = 0; let mut nb_lines = 0; let mut register_header = None; - 'main: loop { - let next_event = parser.next(); - if let Some(event) = next_event { - match event { - pulldown_cmark::Event::Start(pulldown_cmark::Tag::CodeBlock(s)) => { - let block_info = if s.is_empty() { - LangString::all_false() - } else { - LangString::parse(&*s) - }; - let mut test_s = String::new(); - let mut offset = None; - loop { - let event = parser.next(); - if let Some(event) = event { - match event { - pulldown_cmark::Event::End( - pulldown_cmark::Tag::CodeBlock(_)) => break, - pulldown_cmark::Event::Text(ref s) => { - test_s.push_str(s); - if offset.is_none() { - offset = Some(parser.get_offset()); - } + 'main: while let Some(event) = parser.next() { + match event { + Event::Start(Tag::CodeBlock(s)) => { + let block_info = if s.is_empty() { + LangString::all_false() + } else { + LangString::parse(&*s) + }; + if !block_info.rust { + continue + } + let mut test_s = String::new(); + let mut offset = None; + loop { + let event = parser.next(); + if let Some(event) = event { + match event { + Event::End(Tag::CodeBlock(_)) => break, + Event::Text(ref s) => { + test_s.push_str(s); + if offset.is_none() { + offset = Some(parser.get_offset()); } - _ => {} } - } else { - break 'main; + _ => {} } - } - let offset = offset.unwrap_or(0); - let lines = test_s.lines().map(|l| { - stripped_filtered_line(l).unwrap_or(l) - }); - let text = lines.collect::>().join("\n"); - nb_lines += doc[prev_offset..offset].lines().count(); - let line = tests.get_line() + (nb_lines - 1); - let filename = tests.get_filename(); - tests.add_test(text.to_owned(), - block_info.should_panic, block_info.no_run, - block_info.ignore, block_info.test_harness, - block_info.compile_fail, block_info.error_codes, - line, filename); - prev_offset = offset; - } - pulldown_cmark::Event::Start(pulldown_cmark::Tag::Header(level)) => { - register_header = Some(level as u32); - } - pulldown_cmark::Event::Text(ref s) if register_header.is_some() => { - let level = register_header.unwrap(); - if s.is_empty() { - tests.register_header("", level); } else { - tests.register_header(s, level); + break 'main; } - register_header = None; } - _ => {} + let offset = offset.unwrap_or(0); + let lines = test_s.lines().map(|l| { + stripped_filtered_line(l).unwrap_or(l) + }); + let text = lines.collect::>().join("\n"); + nb_lines += doc[prev_offset..offset].lines().count(); + let line = tests.get_line() + (nb_lines - 1); + let filename = tests.get_filename(); + tests.add_test(text.to_owned(), + block_info.should_panic, block_info.no_run, + block_info.ignore, block_info.test_harness, + block_info.compile_fail, block_info.error_codes, + line, filename); + prev_offset = offset; } - } else { - break + Event::Start(Tag::Header(level)) => { + register_header = Some(level as u32); + } + Event::Text(ref s) if register_header.is_some() => { + let level = register_header.unwrap(); + if s.is_empty() { + tests.register_header("", level); + } else { + tests.register_header(s, level); + } + register_header = None; + } + _ => {} } } } @@ -824,17 +584,17 @@ impl LangString { impl<'a> fmt::Display for Markdown<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let Markdown(md) = *self; + let Markdown(md, shorter) = *self; // This is actually common enough to special-case if md.is_empty() { return Ok(()) } - render(fmt, md, false, 0) + render(fmt, md, false, shorter) } } impl<'a> fmt::Display for MarkdownWithToc<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let MarkdownWithToc(md) = *self; - render(fmt, md, true, 0) + render(fmt, md, true, false) } } @@ -843,7 +603,7 @@ impl<'a> fmt::Display for MarkdownHtml<'a> { let MarkdownHtml(md) = *self; // This is actually common enough to special-case if md.is_empty() { return Ok(()) } - render(fmt, md, false, /*HOEDOWN_HTML_ESCAPE*/0) + render(fmt, md, false, false) } } @@ -864,12 +624,13 @@ pub fn plain_summary_line(md: &str) -> String { } let next_event = next_event.unwrap(); let (ret, is_in) = match next_event { - pulldown_cmark::Event::Start(pulldown_cmark::Tag::Paragraph) => (None, 1), - pulldown_cmark::Event::Start( - pulldown_cmark::Tag::Link(_, ref t)) if !self.is_first => (Some(t.as_ref().to_owned()), 1), - pulldown_cmark::Event::Text(ref s) if self.is_in > 0 => (Some(s.as_ref().to_owned()), 0), - pulldown_cmark::Event::End(pulldown_cmark::Tag::Link(_, ref t)) => (Some(t.as_ref().to_owned()), -1), - pulldown_cmark::Event::End(pulldown_cmark::Tag::Paragraph) => (None, -1), + Event::Start(Tag::Paragraph) => (None, 1), + Event::Start(Tag::Link(_, ref t)) if !self.is_first => { + (Some(t.as_ref().to_owned()), 1) + } + Event::Text(ref s) if self.is_in > 0 => (Some(s.as_ref().to_owned()), 0), + Event::End(Tag::Link(_, ref t)) => (Some(t.as_ref().to_owned()), -1), + Event::End(Tag::Paragraph) => (None, -1), _ => (None, 0), }; if is_in > 0 || (is_in < 0 && self.is_in > 0) { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5c94032c6b9..8c1416b8097 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1650,7 +1650,7 @@ fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLin } else { format!("{}", &plain_summary_line(Some(s))) }; - write!(w, "
{}
", Markdown(&markdown))?; + write!(w, "
{}
", Markdown(&markdown, false))?; } Ok(()) } @@ -1683,7 +1683,7 @@ fn get_doc_value(item: &clean::Item) -> Option<&str> { fn document_full(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result { if let Some(s) = get_doc_value(item) { write!(w, "
{}
", - Markdown(&format!("{}{}", md_render_assoc_item(item), s)))?; + Markdown(&format!("{}{}", md_render_assoc_item(item), s), false))?; } Ok(()) } @@ -1871,7 +1871,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, ", name = *myitem.name.as_ref().unwrap(), stab_docs = stab_docs, - docs = shorter(Some(&Markdown(doc_value).to_string())), + docs = shorter(Some(&Markdown(doc_value, true).to_string())), class = myitem.type_(), stab = myitem.stability_class().unwrap_or("".to_string()), unsafety_flag = unsafety_flag, @@ -2901,7 +2901,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi write!(w, "")?; write!(w, "\n")?; if let Some(ref dox) = i.impl_item.doc_value() { - write!(w, "
{}
", Markdown(dox))?; + write!(w, "
{}
", Markdown(dox, false))?; } } diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index c67e2fdc2b0..a048750279e 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -94,7 +94,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches, let rendered = if include_toc { format!("{}", MarkdownWithToc(text)) } else { - format!("{}", Markdown(text)) + format!("{}", Markdown(text, false)) }; let err = write!( diff --git a/src/rt/hoedown b/src/rt/hoedown deleted file mode 160000 index da282f1bb72..00000000000 --- a/src/rt/hoedown +++ /dev/null @@ -1 +0,0 @@ -Subproject commit da282f1bb7277b4d30fa1599ee29ad8eb4dd2a92