|
27 | 27 | use rustc::session::config::get_unstable_features_setting;
|
28 | 28 | use std::borrow::Cow;
|
29 | 29 | use std::cell::RefCell;
|
30 |
| -use std::fmt; |
| 30 | +use std::fmt::{self, Write}; |
31 | 31 | use syntax::feature_gate::UnstableFeatures;
|
32 | 32 |
|
33 |
| -use maud_pulldown_cmark::Markdown as CMarkMaudAda; |
34 |
| -use pulldown_cmark::{Parser, Event, Tag}; |
| 33 | +use cmark::{Parser, Event as CmEvent, Tag}; |
| 34 | +use hamlet::Token as HmToken; |
| 35 | +use cmark_hamlet; |
35 | 36 |
|
36 | 37 | //use html::render::derive_id;
|
37 | 38 | //use html::toc::TocBuilder;
|
@@ -76,63 +77,80 @@ thread_local!(pub static PLAYGROUND_KRATE: RefCell<Option<Option<String>>> = {
|
76 | 77 | });
|
77 | 78 |
|
78 | 79 | pub fn render(w: &mut fmt::Formatter, md: &str, _: bool) -> fmt::Result {
|
79 |
| - let mut rust_block = None; |
80 |
| - let events = Parser::new(md).map(|ev| match ev { |
81 |
| - Event::Start(Tag::CodeBlock(lang)) => { |
82 |
| - info!("lang: {}", lang); |
83 |
| - if LangString::parse(&*lang).rust { |
84 |
| - rust_block = Some(String::from("")); |
85 |
| - Event::Html(Cow::Borrowed("")) |
86 |
| - } else { |
87 |
| - Event::Start(Tag::CodeBlock(lang)) |
| 80 | + let mut rust_block = false; |
| 81 | + for hm_tok in cmark_hamlet::Adapter::new(Parser::new(md), true) { |
| 82 | + match hm_tok { |
| 83 | + HmToken::StartTag { ref name, .. } | |
| 84 | + HmToken::EndTag { ref name } if rust_block && name.as_ref() == "code" => (), |
| 85 | + HmToken::StartTag { name: Cow::Borrowed("pre"), ref attrs, .. } => { |
| 86 | + let is_rust = attrs.get("data-lang") |
| 87 | + .map(|lang| LangString::parse(lang).rust); |
| 88 | + if let Some(true) = is_rust { |
| 89 | + rust_block = true; |
| 90 | + } else { |
| 91 | + try!(write!(w, "{}", hm_tok)); |
| 92 | + } |
88 | 93 | }
|
89 |
| - }, |
90 |
| - Event::End(Tag::CodeBlock(_)) => { |
91 |
| - if rust_block.is_some() { |
92 |
| - let code = rust_block.take().unwrap(); |
93 |
| - let mut s = String::from("\n"); |
| 94 | + HmToken::Text(ref text) if rust_block => { |
| 95 | + let code = text.as_ref(); |
| 96 | + // insert newline to clearly separate it from the |
| 97 | + // previous block so we can shorten the html output |
| 98 | + let mut out = String::from("\n"); |
94 | 99 | PLAYGROUND_KRATE.with(|krate| {
|
95 |
| - // insert newline to clearly separate it from the |
96 |
| - // previous block so we can shorten the html output |
97 | 100 | krate.borrow().as_ref().map(|krate| {
|
98 | 101 | let test = code.lines().map(|l| {
|
99 | 102 | stripped_filtered_line(l).unwrap_or(l)
|
100 | 103 | }).collect::<Vec<&str>>().join("\n");
|
101 | 104 | let krate = krate.as_ref().map(|s| &**s);
|
102 | 105 | let test = test::maketest(&test, krate, false,
|
103 | 106 | &Default::default());
|
104 |
| - s.push_str(&format!("<span class='rusttest'>{}</span>", Escape(&test))); |
| 107 | + out.push_str(&format!("<span class='rusttest'>{}</span>", Escape(&test))); |
105 | 108 | });
|
106 |
| - let text = code.lines().filter(|l| { |
| 109 | + let filtered_code = code.lines().filter(|l| { |
107 | 110 | stripped_filtered_line(l).is_none()
|
108 | 111 | }).collect::<Vec<&str>>().join("\n");
|
109 |
| - s.push_str(&highlight::highlight(&text, |
110 |
| - Some("rust-example-rendered"), |
111 |
| - None)); |
| 112 | + out.push_str(&highlight::highlight(&filtered_code, |
| 113 | + Some("rust-example-rendered"), |
| 114 | + None)); |
112 | 115 | });
|
113 |
| - Event::Html(Cow::Owned(s)) |
114 |
| - } else { |
115 |
| - ev |
| 116 | + try!(write!(w, "{}", out)); |
116 | 117 | }
|
117 |
| - }, |
118 |
| - Event::Text(text) => { |
119 |
| - if let Some(code) = rust_block.as_mut() { |
120 |
| - code.push_str(&*text); |
121 |
| - Event::Html(Cow::Borrowed("")) |
122 |
| - } else { |
123 |
| - Event::Text(text) |
| 118 | + HmToken::EndTag{name: Cow::Borrowed("pre")} if rust_block => { |
| 119 | + rust_block = false; |
124 | 120 | }
|
125 |
| - }, |
126 |
| - _ => ev, |
127 |
| - }); |
128 |
| - |
129 |
| - html!(*w, { |
130 |
| - ^CMarkMaudAda::from_events(events) |
131 |
| - }) |
| 121 | + _ => try!(write!(w, "{}", hm_tok)), |
| 122 | + } |
| 123 | + } |
| 124 | + Ok(()) |
132 | 125 | }
|
133 | 126 |
|
134 |
| -pub fn find_testable_code(_: &str, _: &mut ::test::Collector) { |
135 |
| - unimplemented!() |
| 127 | +pub fn find_testable_code(md: &str, tests: &mut ::test::Collector) { |
| 128 | + let mut block_info = None; |
| 129 | + for hm_tok in cmark_hamlet::Adapter::new(Parser::new(md), true) { |
| 130 | + match hm_tok { |
| 131 | + HmToken::StartTag { name: Cow::Borrowed("pre"), attrs, .. } => { |
| 132 | + block_info = attrs.get("data-lang") |
| 133 | + .map(|lang| LangString::parse(lang)); |
| 134 | + } |
| 135 | + HmToken::Text(ref text) if block_info.is_some() => { |
| 136 | + let block_info = block_info.as_ref().unwrap(); |
| 137 | + if block_info.rust { |
| 138 | + let lines = text.lines().map(|l| { |
| 139 | + stripped_filtered_line(l).unwrap_or(l) |
| 140 | + }); |
| 141 | + let clean_code = lines.collect::<Vec<&str>>().join("\n"); |
| 142 | + tests.add_test(clean_code, |
| 143 | + block_info.should_panic, block_info.no_run, |
| 144 | + block_info.ignore, block_info.test_harness, |
| 145 | + block_info.compile_fail); |
| 146 | + } |
| 147 | + } |
| 148 | + HmToken::EndTag{name: Cow::Borrowed("pre")} if block_info.is_some() => { |
| 149 | + block_info = None; |
| 150 | + } |
| 151 | + _ => (), |
| 152 | + } |
| 153 | + } |
136 | 154 | }
|
137 | 155 |
|
138 | 156 | #[derive(Eq, PartialEq, Clone, Debug)]
|
@@ -211,22 +229,21 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
|
211 | 229 |
|
212 | 230 | pub fn plain_summary_line(md: &str) -> String {
|
213 | 231 | let events = Parser::new(md).map(|ev| match ev {
|
214 |
| - Event::Start(Tag::Code) => Event::Text(Cow::Borrowed("`")), |
215 |
| - Event::End(Tag::Code) => Event::Text(Cow::Borrowed("`")), |
216 |
| - Event::Start(Tag::Link(_, text)) => Event::Text(text), |
217 |
| - Event::Start(Tag::Image(_, text)) => Event::Text(text), |
218 |
| - Event::Html(html) | Event::InlineHtml(html) => Event::Text(html), |
219 |
| - ev @ Event::Text(_) => ev, |
220 |
| - _ => Event::Html(Cow::Borrowed("")), |
| 232 | + CmEvent::Start(Tag::Code) => CmEvent::Text(Cow::Borrowed("`")), |
| 233 | + CmEvent::End(Tag::Code) => CmEvent::Text(Cow::Borrowed("`")), |
| 234 | + CmEvent::Start(Tag::Link(_, text)) => CmEvent::Text(text), |
| 235 | + CmEvent::Start(Tag::Image(_, text)) => CmEvent::Text(text), |
| 236 | + CmEvent::Html(html) | CmEvent::InlineHtml(html) => CmEvent::Text(html), |
| 237 | + ev @ CmEvent::Text(_) => ev, |
| 238 | + _ => CmEvent::Html(Cow::Borrowed("")), |
221 | 239 | });
|
222 | 240 |
|
223 |
| - let mut buf = String::new(); |
224 |
| - |
225 |
| - html!(buf, { |
226 |
| - ^CMarkMaudAda::from_events(events) |
227 |
| - }).unwrap(); |
228 |
| - |
229 |
| - buf |
| 241 | + let hm_toks = cmark_hamlet::Adapter::new(events, false); |
| 242 | + let mut ret = String::from(""); |
| 243 | + for tok in hm_toks { |
| 244 | + write!(ret, "{}", tok).unwrap(); |
| 245 | + } |
| 246 | + ret |
230 | 247 | }
|
231 | 248 |
|
232 | 249 | #[cfg(test)]
|
|
0 commit comments