From 08a741eabf3c223650bb29c5df30c8fd414cd86a Mon Sep 17 00:00:00 2001
From: Guillaume Gomez
Date: Wed, 29 Mar 2017 19:48:06 -0600
Subject: [PATCH 1/5] Add support for image, rules and footnotes
---
src/librustdoc/html/markdown.rs | 139 ++++++++++++++----
src/test/rustdoc/check-rule-image-footnote.rs | 35 +++++
2 files changed, 146 insertions(+), 28 deletions(-)
create mode 100644 src/test/rustdoc/check-rule-image-footnote.rs
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 117cfbabb52f7..6c82dab94bcb3 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -133,11 +133,37 @@ macro_rules! event_loop_break {
}}
}
+struct ParserWrapper<'a> {
+ parser: Parser<'a>,
+ footnotes: Vec,
+ current_footnote_id: u16,
+}
+
+impl<'a> ParserWrapper<'a> {
+ pub fn new(s: &'a str) -> ParserWrapper<'a> {
+ ParserWrapper {
+ parser: Parser::new_ext(s, pulldown_cmark::OPTION_ENABLE_TABLES |
+ pulldown_cmark::OPTION_ENABLE_FOOTNOTES),
+ footnotes: Vec::new(),
+ current_footnote_id: 1,
+ }
+ }
+ pub fn next(&mut self) -> Option> {
+ self.parser.next()
+ }
+
+ pub fn get_next_footnote_id(&mut self) -> u16 {
+ let tmp = self.current_footnote_id;
+ self.current_footnote_id += 1;
+ tmp
+ }
+}
+
pub fn render(w: &mut fmt::Formatter,
s: &str,
print_toc: bool,
shorter: MarkdownOutputStyle) -> fmt::Result {
- fn code_block(parser: &mut Parser, buffer: &mut String, lang: &str) {
+ fn code_block(parser: &mut ParserWrapper, buffer: &mut String, lang: &str) {
let mut origtext = String::new();
while let Some(event) = parser.next() {
match event {
@@ -215,8 +241,8 @@ pub fn render(w: &mut fmt::Formatter,
});
}
- fn heading(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
- shorter: MarkdownOutputStyle, level: i32) {
+ fn heading(parser: &mut ParserWrapper, buffer: &mut String,
+ toc_builder: &mut Option, shorter: MarkdownOutputStyle, level: i32) {
let mut ret = String::new();
let mut id = String::new();
event_loop_break!(parser, toc_builder, shorter, ret, true, &mut Some(&mut id),
@@ -249,32 +275,48 @@ pub fn render(w: &mut fmt::Formatter,
ret, lvl = level, id = id, sec = sec));
}
- fn inline_code(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
- shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
+ fn inline_code(parser: &mut ParserWrapper, buffer: &mut String,
+ toc_builder: &mut Option, shorter: MarkdownOutputStyle,
+ id: &mut Option<&mut String>) {
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, false, id, Event::End(Tag::Code));
buffer.push_str(&format!("{}
",
Escape(&collapse_whitespace(content.trim_right()))));
}
- fn link(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
+ fn link(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
+ shorter: MarkdownOutputStyle, url: &str, title: &str,
+ id: &mut Option<&mut String>) {
+ let mut content = String::new();
+ event_loop_break!(parser, toc_builder, shorter, content, true, id,
+ Event::End(Tag::Link(_, _)));
+ if title.is_empty() {
+ buffer.push_str(&format!("{} ", url, content));
+ } else {
+ buffer.push_str(&format!("{} ",
+ url, Escape(title), content));
+ }
+ }
+
+ fn image(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
shorter: MarkdownOutputStyle, url: &str, mut title: String,
id: &mut Option<&mut String>) {
event_loop_break!(parser, toc_builder, shorter, title, true, id,
- Event::End(Tag::Link(_, _)));
- buffer.push_str(&format!("{} ", url, title));
+ Event::End(Tag::Image(_, _)));
+ buffer.push_str(&format!(" ", url, title));
}
- fn paragraph(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
- shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
+ fn paragraph(parser: &mut ParserWrapper, buffer: &mut String,
+ toc_builder: &mut Option, shorter: MarkdownOutputStyle,
+ id: &mut Option<&mut String>) {
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, true, id,
Event::End(Tag::Paragraph));
buffer.push_str(&format!("{}
", content.trim_right()));
}
- fn table_cell(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
- shorter: MarkdownOutputStyle) {
+ fn table_cell(parser: &mut ParserWrapper, buffer: &mut String,
+ toc_builder: &mut Option, shorter: MarkdownOutputStyle) {
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, true, &mut None,
Event::End(Tag::TableHead) |
@@ -284,8 +326,8 @@ pub fn render(w: &mut fmt::Formatter,
buffer.push_str(&format!("{} ", content.trim()));
}
- fn table_row(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
- shorter: MarkdownOutputStyle) {
+ fn table_row(parser: &mut ParserWrapper, buffer: &mut String,
+ toc_builder: &mut Option, shorter: MarkdownOutputStyle) {
let mut content = String::new();
while let Some(event) = parser.next() {
match event {
@@ -303,8 +345,8 @@ pub fn render(w: &mut fmt::Formatter,
buffer.push_str(&format!("{} ", content));
}
- fn table_head(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
- shorter: MarkdownOutputStyle) {
+ fn table_head(parser: &mut ParserWrapper, buffer: &mut String,
+ toc_builder: &mut Option, shorter: MarkdownOutputStyle) {
let mut content = String::new();
while let Some(event) = parser.next() {
match event {
@@ -322,7 +364,7 @@ pub fn render(w: &mut fmt::Formatter,
}
}
- fn table(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
+ fn table(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
shorter: MarkdownOutputStyle) {
let mut content = String::new();
let mut rows = String::new();
@@ -347,16 +389,16 @@ pub fn render(w: &mut fmt::Formatter,
}));
}
- fn blockquote(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
- shorter: MarkdownOutputStyle) {
+ fn blockquote(parser: &mut ParserWrapper, buffer: &mut String,
+ toc_builder: &mut Option, shorter: MarkdownOutputStyle) {
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, true, &mut None,
Event::End(Tag::BlockQuote));
buffer.push_str(&format!("{} ", content.trim_right()));
}
- fn list_item(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
- shorter: MarkdownOutputStyle) {
+ fn list_item(parser: &mut ParserWrapper, buffer: &mut String,
+ toc_builder: &mut Option, shorter: MarkdownOutputStyle) {
let mut content = String::new();
while let Some(event) = parser.next() {
match event {
@@ -372,7 +414,7 @@ pub fn render(w: &mut fmt::Formatter,
buffer.push_str(&format!("{} ", content));
}
- fn list(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
+ fn list(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
shorter: MarkdownOutputStyle) {
let mut content = String::new();
while let Some(event) = parser.next() {
@@ -389,15 +431,16 @@ pub fn render(w: &mut fmt::Formatter,
buffer.push_str(&format!("", content));
}
- fn emphasis(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
- shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
+ fn emphasis(parser: &mut ParserWrapper, buffer: &mut String,
+ toc_builder: &mut Option, shorter: MarkdownOutputStyle,
+ id: &mut Option<&mut String>) {
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, false, id,
Event::End(Tag::Emphasis));
buffer.push_str(&format!("{} ", content));
}
- fn strong(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option,
+ fn strong(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, false, id,
@@ -405,7 +448,23 @@ pub fn render(w: &mut fmt::Formatter,
buffer.push_str(&format!("{} ", content));
}
- fn looper<'a>(parser: &'a mut Parser, buffer: &mut String, next_event: Option>,
+ fn footnote(parser: &mut ParserWrapper, buffer: &mut String,
+ toc_builder: &mut Option, shorter: MarkdownOutputStyle,
+ mut definition: String, id: &mut Option<&mut String>) {
+ event_loop_break!(parser, toc_builder, shorter, definition, true, id,
+ Event::End(Tag::FootnoteDefinition(_)));
+ buffer.push_str(&definition);
+ }
+
+ fn rule(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
+ shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
+ let mut content = String::new();
+ event_loop_break!(parser, toc_builder, shorter, content, true, id,
+ Event::End(Tag::Rule));
+ buffer.push_str(" ");
+ }
+
+ fn looper<'a>(parser: &'a mut ParserWrapper, buffer: &mut String, next_event: Option>,
toc_builder: &mut Option, shorter: MarkdownOutputStyle,
id: &mut Option<&mut String>) -> bool {
if let Some(event) = next_event {
@@ -423,7 +482,10 @@ pub fn render(w: &mut fmt::Formatter,
paragraph(parser, buffer, toc_builder, shorter, id);
}
Event::Start(Tag::Link(ref url, ref t)) => {
- link(parser, buffer, toc_builder, shorter, url, t.as_ref().to_owned(), id);
+ link(parser, buffer, toc_builder, shorter, url, t.as_ref(), id);
+ }
+ Event::Start(Tag::Image(ref url, ref t)) => {
+ image(parser, buffer, toc_builder, shorter, url, t.as_ref().to_owned(), id);
}
Event::Start(Tag::Table(_)) => {
table(parser, buffer, toc_builder, shorter);
@@ -440,6 +502,23 @@ pub fn render(w: &mut fmt::Formatter,
Event::Start(Tag::Strong) => {
strong(parser, buffer, toc_builder, shorter, id);
}
+ Event::Start(Tag::Rule) => {
+ rule(parser, buffer, toc_builder, shorter, id);
+ }
+ Event::Start(Tag::FootnoteDefinition(ref def)) => {
+ let mut content = String::new();
+ footnote(parser, &mut content, toc_builder, shorter, def.as_ref().to_owned(),
+ id);
+ let cur_len = parser.footnotes.len() + 1;
+ parser.footnotes.push(format!("{}↩ ",
+ cur_len, content));
+ }
+ Event::FootnoteReference(_) => {
+ buffer.push_str(&format!("{0} \
+ ",
+ parser.get_next_footnote_id()));
+ }
Event::Html(h) | Event::InlineHtml(h) => {
buffer.push_str(&*h);
}
@@ -457,13 +536,17 @@ pub fn render(w: &mut fmt::Formatter,
None
};
let mut buffer = String::new();
- let mut parser = Parser::new_ext(s, pulldown_cmark::OPTION_ENABLE_TABLES);
+ let mut parser = ParserWrapper::new(s);
loop {
let next_event = parser.next();
if !looper(&mut parser, &mut buffer, next_event, &mut toc_builder, shorter, &mut None) {
break
}
}
+ if !parser.footnotes.is_empty() {
+ buffer.push_str(&format!("",
+ parser.footnotes.join("")));
+ }
let mut ret = toc_builder.map_or(Ok(()), |builder| {
write!(w, "{} ", builder.into_toc())
});
diff --git a/src/test/rustdoc/check-rule-image-footnote.rs b/src/test/rustdoc/check-rule-image-footnote.rs
new file mode 100644
index 0000000000000..629e1a64e6fd0
--- /dev/null
+++ b/src/test/rustdoc/check-rule-image-footnote.rs
@@ -0,0 +1,35 @@
+// Copyright 2017 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.
+
+#![crate_name = "foo"]
+
+// @has foo/fn.f.html
+// @has - 'hard break: after hard break
'
+// @has - ' '
+// @has - ''
+// @has - '1 '
+/// markdown test
+///
+/// this is a [link].
+///
+/// [link]: https://example.com "this is a title"
+///
+/// hard break:
+/// after hard break
+///
+/// -----------
+///
+/// a footnote[^footnote].
+///
+/// [^footnote]: Thing
+///
+/// 
+#[deprecated(note = "Struct")]
+pub fn f() {}
From 36b15f0409fae948b3de7dee1d6b2cb995c5784d Mon Sep 17 00:00:00 2001
From: Guillaume Gomez
Date: Thu, 30 Mar 2017 17:29:54 -0600
Subject: [PATCH 2/5] Fix multiple footnotes and improve testing
---
src/librustdoc/html/markdown.rs | 54 +++++++++++--------
src/test/rustdoc/check-rule-image-footnote.rs | 13 +++--
2 files changed, 42 insertions(+), 25 deletions(-)
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 6c82dab94bcb3..e8acabde4081a 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -27,6 +27,7 @@
use std::ascii::AsciiExt;
use std::cell::RefCell;
+use std::collections::HashMap;
use std::default::Default;
use std::fmt::{self, Write};
use std::str;
@@ -135,8 +136,8 @@ macro_rules! event_loop_break {
struct ParserWrapper<'a> {
parser: Parser<'a>,
- footnotes: Vec,
- current_footnote_id: u16,
+ // The key is the footnote reference. The value is the footnote definition and the id.
+ footnotes: HashMap,
}
impl<'a> ParserWrapper<'a> {
@@ -144,18 +145,18 @@ impl<'a> ParserWrapper<'a> {
ParserWrapper {
parser: Parser::new_ext(s, pulldown_cmark::OPTION_ENABLE_TABLES |
pulldown_cmark::OPTION_ENABLE_FOOTNOTES),
- footnotes: Vec::new(),
- current_footnote_id: 1,
+ footnotes: HashMap::new(),
}
}
+
pub fn next(&mut self) -> Option> {
self.parser.next()
}
- pub fn get_next_footnote_id(&mut self) -> u16 {
- let tmp = self.current_footnote_id;
- self.current_footnote_id += 1;
- tmp
+ pub fn get_entry(&mut self, key: &str) -> &mut (String, u16) {
+ let new_id = self.footnotes.keys().count() + 1;
+ let key = key.to_owned();
+ self.footnotes.entry(key).or_insert((String::new(), new_id as u16))
}
}
@@ -450,10 +451,11 @@ pub fn render(w: &mut fmt::Formatter,
fn footnote(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle,
- mut definition: String, id: &mut Option<&mut String>) {
- event_loop_break!(parser, toc_builder, shorter, definition, true, id,
+ id: &mut Option<&mut String>) {
+ let mut content = String::new();
+ event_loop_break!(parser, toc_builder, shorter, content, true, id,
Event::End(Tag::FootnoteDefinition(_)));
- buffer.push_str(&definition);
+ buffer.push_str(&content);
}
fn rule(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
@@ -507,17 +509,24 @@ pub fn render(w: &mut fmt::Formatter,
}
Event::Start(Tag::FootnoteDefinition(ref def)) => {
let mut content = String::new();
- footnote(parser, &mut content, toc_builder, shorter, def.as_ref().to_owned(),
- id);
- let cur_len = parser.footnotes.len() + 1;
- parser.footnotes.push(format!("{}↩ ",
- cur_len, content));
- }
- Event::FootnoteReference(_) => {
+ let def = def.as_ref();
+ footnote(parser, &mut content, toc_builder, shorter, id);
+ let entry = parser.get_entry(def);
+ let cur_id = (*entry).1;
+ (*entry).0.push_str(&format!("{} ↩
",
+ cur_id,
+ if content.ends_with("") {
+ &content[..content.len() - 4]
+ } else {
+ &content
+ }));
+ }
+ Event::FootnoteReference(ref reference) => {
+ let entry = parser.get_entry(reference.as_ref());
buffer.push_str(&format!("{0} \
",
- parser.get_next_footnote_id()));
+ (*entry).1));
}
Event::Html(h) | Event::InlineHtml(h) => {
buffer.push_str(&*h);
@@ -545,7 +554,10 @@ pub fn render(w: &mut fmt::Formatter,
}
if !parser.footnotes.is_empty() {
buffer.push_str(&format!("",
- parser.footnotes.join("")));
+ parser.footnotes.values()
+ .map(|&(ref s, _)| s.as_str())
+ .collect::>()
+ .join("")));
}
let mut ret = toc_builder.map_or(Ok(()), |builder| {
write!(w, "{} ", builder.into_toc())
diff --git a/src/test/rustdoc/check-rule-image-footnote.rs b/src/test/rustdoc/check-rule-image-footnote.rs
index 629e1a64e6fd0..4d3bea20ba895 100644
--- a/src/test/rustdoc/check-rule-image-footnote.rs
+++ b/src/test/rustdoc/check-rule-image-footnote.rs
@@ -10,11 +10,10 @@
#![crate_name = "foo"]
+// ignore-tidy-linelength
+
// @has foo/fn.f.html
-// @has - 'hard break: after hard break
'
-// @has - ' '
-// @has - ''
-// @has - '1 '
+// @has - 'markdown test
this is a link .
hard break: after hard break
a footnote1 .
another footnote2 .
'
/// markdown test
///
/// this is a [link].
@@ -28,8 +27,14 @@
///
/// a footnote[^footnote].
///
+/// another footnote[^footnotebis].
+///
/// [^footnote]: Thing
///
+///
+/// [^footnotebis]: Another Thing
+///
+///
/// 
#[deprecated(note = "Struct")]
pub fn f() {}
From 51d3cec38794beb644f67e80b1e7718ee14facf0 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez
Date: Fri, 31 Mar 2017 11:02:46 -0600
Subject: [PATCH 3/5] Fix hard break issue
---
src/librustdoc/html/markdown.rs | 36 ++++++++++++++++++++--
src/librustdoc/passes/unindent_comments.rs | 13 +++++++-
src/test/rustdoc/check-hard-break.rs | 19 ++++++++++++
3 files changed, 65 insertions(+), 3 deletions(-)
create mode 100644 src/test/rustdoc/check-hard-break.rs
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index e8acabde4081a..d1f2948bc2532 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -116,6 +116,7 @@ macro_rules! event_loop_break {
match event {
$($end_event)|* => break,
Event::Text(ref s) => {
+ debug!("Text");
inner($id, s);
if $escape {
$buf.push_str(&format!("{}", Escape(s)));
@@ -123,8 +124,11 @@ macro_rules! event_loop_break {
$buf.push_str(s);
}
}
- Event::SoftBreak | Event::HardBreak if !$buf.is_empty() => {
- $buf.push(' ');
+ Event::SoftBreak => {
+ debug!("SoftBreak");
+ if !$buf.is_empty() {
+ $buf.push(' ');
+ }
}
x => {
looper($parser, &mut $buf, Some(x), $toc_builder, $shorter, $id);
@@ -165,6 +169,7 @@ pub fn render(w: &mut fmt::Formatter,
print_toc: bool,
shorter: MarkdownOutputStyle) -> fmt::Result {
fn code_block(parser: &mut ParserWrapper, buffer: &mut String, lang: &str) {
+ debug!("CodeBlock");
let mut origtext = String::new();
while let Some(event) = parser.next() {
match event {
@@ -244,6 +249,7 @@ pub fn render(w: &mut fmt::Formatter,
fn heading(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle, level: i32) {
+ debug!("Heading");
let mut ret = String::new();
let mut id = String::new();
event_loop_break!(parser, toc_builder, shorter, ret, true, &mut Some(&mut id),
@@ -279,6 +285,7 @@ pub fn render(w: &mut fmt::Formatter,
fn inline_code(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle,
id: &mut Option<&mut String>) {
+ debug!("InlineCode");
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, false, id, Event::End(Tag::Code));
buffer.push_str(&format!("{}
",
@@ -288,6 +295,7 @@ pub fn render(w: &mut fmt::Formatter,
fn link(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
shorter: MarkdownOutputStyle, url: &str, title: &str,
id: &mut Option<&mut String>) {
+ debug!("Link");
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, true, id,
Event::End(Tag::Link(_, _)));
@@ -302,6 +310,7 @@ pub fn render(w: &mut fmt::Formatter,
fn image(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
shorter: MarkdownOutputStyle, url: &str, mut title: String,
id: &mut Option<&mut String>) {
+ debug!("Image");
event_loop_break!(parser, toc_builder, shorter, title, true, id,
Event::End(Tag::Image(_, _)));
buffer.push_str(&format!(" ", url, title));
@@ -310,6 +319,7 @@ pub fn render(w: &mut fmt::Formatter,
fn paragraph(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle,
id: &mut Option<&mut String>) {
+ debug!("Paragraph");
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, true, id,
Event::End(Tag::Paragraph));
@@ -318,6 +328,7 @@ pub fn render(w: &mut fmt::Formatter,
fn table_cell(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle) {
+ debug!("TableCell");
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, true, &mut None,
Event::End(Tag::TableHead) |
@@ -329,6 +340,7 @@ pub fn render(w: &mut fmt::Formatter,
fn table_row(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle) {
+ debug!("TableRow");
let mut content = String::new();
while let Some(event) = parser.next() {
match event {
@@ -348,6 +360,7 @@ pub fn render(w: &mut fmt::Formatter,
fn table_head(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle) {
+ debug!("TableHead");
let mut content = String::new();
while let Some(event) = parser.next() {
match event {
@@ -367,6 +380,7 @@ pub fn render(w: &mut fmt::Formatter,
fn table(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
shorter: MarkdownOutputStyle) {
+ debug!("Table");
let mut content = String::new();
let mut rows = String::new();
while let Some(event) = parser.next() {
@@ -392,6 +406,7 @@ pub fn render(w: &mut fmt::Formatter,
fn blockquote(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle) {
+ debug!("BlockQuote");
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, true, &mut None,
Event::End(Tag::BlockQuote));
@@ -400,6 +415,7 @@ pub fn render(w: &mut fmt::Formatter,
fn list_item(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle) {
+ debug!("ListItem");
let mut content = String::new();
while let Some(event) = parser.next() {
match event {
@@ -417,6 +433,7 @@ pub fn render(w: &mut fmt::Formatter,
fn list(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
shorter: MarkdownOutputStyle) {
+ debug!("List");
let mut content = String::new();
while let Some(event) = parser.next() {
match event {
@@ -435,6 +452,7 @@ pub fn render(w: &mut fmt::Formatter,
fn emphasis(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle,
id: &mut Option<&mut String>) {
+ debug!("Emphasis");
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, false, id,
Event::End(Tag::Emphasis));
@@ -443,6 +461,7 @@ pub fn render(w: &mut fmt::Formatter,
fn strong(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
+ debug!("Strong");
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, false, id,
Event::End(Tag::Strong));
@@ -452,6 +471,7 @@ pub fn render(w: &mut fmt::Formatter,
fn footnote(parser: &mut ParserWrapper, buffer: &mut String,
toc_builder: &mut Option, shorter: MarkdownOutputStyle,
id: &mut Option<&mut String>) {
+ debug!("FootnoteDefinition");
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, true, id,
Event::End(Tag::FootnoteDefinition(_)));
@@ -460,6 +480,7 @@ pub fn render(w: &mut fmt::Formatter,
fn rule(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option,
shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
+ debug!("Rule");
let mut content = String::new();
event_loop_break!(parser, toc_builder, shorter, content, true, id,
Event::End(Tag::Rule));
@@ -508,6 +529,7 @@ pub fn render(w: &mut fmt::Formatter,
rule(parser, buffer, toc_builder, shorter, id);
}
Event::Start(Tag::FootnoteDefinition(ref def)) => {
+ debug!("FootnoteDefinition");
let mut content = String::new();
let def = def.as_ref();
footnote(parser, &mut content, toc_builder, shorter, id);
@@ -523,12 +545,22 @@ pub fn render(w: &mut fmt::Formatter,
}));
}
Event::FootnoteReference(ref reference) => {
+ debug!("FootnoteReference");
let entry = parser.get_entry(reference.as_ref());
buffer.push_str(&format!("{0} \
",
(*entry).1));
}
+ Event::HardBreak => {
+ debug!("HardBreak");
+ if shorter.is_fancy() {
+ buffer.push_str(" ");
+ } else if !buffer.is_empty() {
+ buffer.push(' ');
+ }
+ }
Event::Html(h) | Event::InlineHtml(h) => {
+ debug!("Html/InlineHtml");
buffer.push_str(&*h);
}
_ => {}
diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs
index 4d94c30847852..59fef8d20271b 100644
--- a/src/librustdoc/passes/unindent_comments.rs
+++ b/src/librustdoc/passes/unindent_comments.rs
@@ -82,7 +82,7 @@ fn unindent(s: &str) -> String {
});
if !lines.is_empty() {
- let mut unindented = vec![ lines[0].trim().to_string() ];
+ let mut unindented = vec![ lines[0].trim_left().to_string() ];
unindented.extend_from_slice(&lines[1..].iter().map(|&line| {
if line.chars().all(|c| c.is_whitespace()) {
line.to_string()
@@ -160,4 +160,15 @@ mod unindent_tests {
let r = unindent(&s);
assert_eq!(r, "line1\nline2");
}
+
+ #[test]
+ fn should_not_trim() {
+ let s = "\t line1 \n\t line2".to_string();
+ let r = unindent(&s);
+ assert_eq!(r, "line1 \nline2");
+
+ let s = " \tline1 \n \tline2".to_string();
+ let r = unindent(&s);
+ assert_eq!(r, "line1 \nline2");
+ }
}
diff --git a/src/test/rustdoc/check-hard-break.rs b/src/test/rustdoc/check-hard-break.rs
new file mode 100644
index 0000000000000..4604639c3c8d5
--- /dev/null
+++ b/src/test/rustdoc/check-hard-break.rs
@@ -0,0 +1,19 @@
+// Copyright 2017 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.
+
+#![crate_name = "foo"]
+
+// ignore-tidy-linelength
+
+// @has foo/fn.f.html
+// @has - 'hard break: after hard break
'
+/// hard break:
+/// after hard break
+pub fn f() {}
From 4de4a955052febfbcd28fd156a7585b90b5dd184 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez
Date: Fri, 31 Mar 2017 12:08:31 -0600
Subject: [PATCH 4/5] Add end whitespace ignore flag for tidy
---
src/test/rustdoc/check-hard-break.rs | 2 +-
src/tools/tidy/src/style.rs | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/test/rustdoc/check-hard-break.rs b/src/test/rustdoc/check-hard-break.rs
index 4604639c3c8d5..5c5e3f8136c73 100644
--- a/src/test/rustdoc/check-hard-break.rs
+++ b/src/test/rustdoc/check-hard-break.rs
@@ -10,7 +10,7 @@
#![crate_name = "foo"]
-// ignore-tidy-linelength
+// ignore-tidy-end-whitespace
// @has foo/fn.f.html
// @has - 'hard break: after hard break
'
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 2233f8c352974..012301299e0c5 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -110,6 +110,7 @@ pub fn check(path: &Path, bad: &mut bool) {
let skip_cr = contents.contains("ignore-tidy-cr");
let skip_tab = contents.contains("ignore-tidy-tab");
let skip_length = contents.contains("ignore-tidy-linelength");
+ let skip_end_whitespace = contents.contains("ignore-tidy-end-whitespace");
for (i, line) in contents.split("\n").enumerate() {
let mut err = |msg: &str| {
println!("{}:{}: {}", file.display(), i + 1, msg);
@@ -122,7 +123,7 @@ pub fn check(path: &Path, bad: &mut bool) {
if line.contains("\t") && !skip_tab {
err("tab character");
}
- if line.ends_with(" ") || line.ends_with("\t") {
+ if !skip_end_whitespace && (line.ends_with(" ") || line.ends_with("\t")) {
err("trailing whitespace");
}
if line.contains("\r") && !skip_cr {
From ef01ae7fe0652c050ec9af8f70990bb01309ffbc Mon Sep 17 00:00:00 2001
From: Guillaume Gomez
Date: Sat, 1 Apr 2017 00:31:37 -0600
Subject: [PATCH 5/5] Force footnote references to be sorted by id
---
src/librustdoc/html/markdown.rs | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index d1f2948bc2532..0b098fb14f190 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -585,11 +585,13 @@ pub fn render(w: &mut fmt::Formatter,
}
}
if !parser.footnotes.is_empty() {
+ let mut v: Vec<_> = parser.footnotes.values().collect();
+ v.sort_by(|a, b| a.1.cmp(&b.1));
buffer.push_str(&format!("",
- parser.footnotes.values()
- .map(|&(ref s, _)| s.as_str())
- .collect::>()
- .join("")));
+ v.iter()
+ .map(|s| s.0.as_str())
+ .collect::>()
+ .join("")));
}
let mut ret = toc_builder.map_or(Ok(()), |builder| {
write!(w, "{} ", builder.into_toc())