about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorFlorian Gilcher <florian.gilcher@asquera.de>2014-06-01 00:33:32 +0200
committerFlorian Gilcher <florian.gilcher@asquera.de>2014-06-02 00:16:48 +0200
commit3fef7a74ca9a642f51cdf8ec4f148916580b34ce (patch)
tree4bf285d2deb05d0cf8dcc85672a9b4bd24920cc6 /src
parent1527dab9980bf1f94419dcb8482ff1f0228a6f4b (diff)
downloadrust-3fef7a74ca9a642f51cdf8ec4f148916580b34ce.tar.gz
rust-3fef7a74ca9a642f51cdf8ec4f148916580b34ce.zip
rustdoc: make langstring parsing more robust
This changes the parsing of the language string
in code examples so that unrecognized examples
are not considered Rust code. This was, for example,
the case when a code example was marked `sh` for shell
code.

This relieves authors of having to mark those samples
as `notrust`.

Also adds recognition of the positive marker `rust`.

By default, unmarked examples are still considered rust.

If any rust-specific tags are seen, code is considered
rust unless marked as "notrust".

Adds test cases for the detection logic.
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/html/markdown.rs53
1 files changed, 49 insertions, 4 deletions
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index cafbbaa828b..48393db3b7d 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -287,10 +287,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
                 slice::raw::buf_as_slice((*lang).data,
                                        (*lang).size as uint, |lang| {
                     let s = str::from_utf8(lang).unwrap();
-                    (s.contains("should_fail"),
-                     s.contains("no_run"),
-                     s.contains("ignore"),
-                     s.contains("notrust"))
+                    parse_lang_string(s)
                 })
             };
             if notrust { return }
@@ -340,6 +337,35 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
     }
 }
 
+fn parse_lang_string(string: &str) -> (bool,bool,bool,bool) {
+    let mut seen_rust_tags = false;
+    let mut seen_other_tags = false;
+    let mut should_fail = false;
+    let mut no_run = false;
+    let mut ignore = false;
+    let mut notrust = false;
+
+    let mut tokens = string.as_slice().split(|c: char|
+      !(c == '_' || c == '-' || c.is_alphanumeric())
+    );
+
+    for token in tokens {
+        match token {
+            "" => {},
+            "should_fail" => { should_fail = true; seen_rust_tags = true; },
+            "no_run" => { no_run = true; seen_rust_tags = true; },
+            "ignore" => { ignore = true; seen_rust_tags = true; },
+            "notrust" => { notrust = true; seen_rust_tags = true; },
+            "rust" => { notrust = false; seen_rust_tags = true; },
+            _ => { seen_other_tags = true }
+        }
+    }
+
+    let notrust = notrust || (seen_other_tags && !seen_rust_tags);
+
+    (should_fail, no_run, ignore, notrust)
+}
+
 /// By default this markdown renderer generates anchors for each header in the
 /// rendered document. The anchor name is the contents of the header spearated
 /// by hyphens, and a task-local map is used to disambiguate among duplicate
@@ -367,3 +393,22 @@ impl<'a> fmt::Show for MarkdownWithToc<'a> {
         render(fmt, md.as_slice(), true)
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::parse_lang_string;
+
+    #[test]
+    fn test_parse_lang_string() {
+        assert_eq!(parse_lang_string(""), (false,false,false,false))
+        assert_eq!(parse_lang_string("rust"), (false,false,false,false))
+        assert_eq!(parse_lang_string("sh"), (false,false,false,true))
+        assert_eq!(parse_lang_string("notrust"), (false,false,false,true))
+        assert_eq!(parse_lang_string("ignore"), (false,false,true,false))
+        assert_eq!(parse_lang_string("should_fail"), (true,false,false,false))
+        assert_eq!(parse_lang_string("no_run"), (false,true,false,false))
+        assert_eq!(parse_lang_string("{.no_run .example}"), (false,true,false,false))
+        assert_eq!(parse_lang_string("{.sh .should_fail}"), (true,false,false,false))
+        assert_eq!(parse_lang_string("{.example .rust}"), (false,false,false,false))
+    }
+}
\ No newline at end of file