@@ -66,18 +66,47 @@ pub struct MarkdownHtml<'a>(pub &'a str, pub RenderType);
6666/// A unit struct like `Markdown`, that renders only the first paragraph.
6767pub struct MarkdownSummaryLine < ' a > ( pub & ' a str ) ;
6868
69- /// Returns Some(code) if `s` is a line that should be stripped from
70- /// documentation but used in example code. `code` is the portion of
71- /// `s` that should be used in tests. (None for lines that should be
72- /// left as-is.)
73- fn stripped_filtered_line < ' a > ( s : & ' a str ) -> Option < & ' a str > {
69+ /// Controls whether a line will be hidden or shown in HTML output.
70+ ///
71+ /// All lines are used in documentation tests.
72+ enum Line < ' a > {
73+ Hidden ( & ' a str ) ,
74+ Shown ( & ' a str ) ,
75+ }
76+
77+ impl < ' a > Line < ' a > {
78+ fn for_html ( self ) -> Option < & ' a str > {
79+ match self {
80+ Line :: Shown ( l) => Some ( l) ,
81+ Line :: Hidden ( _) => None ,
82+ }
83+ }
84+
85+ fn for_code ( self ) -> & ' a str {
86+ match self {
87+ Line :: Shown ( l) |
88+ Line :: Hidden ( l) => l,
89+ }
90+ }
91+ }
92+
93+ // FIXME: There is a minor inconsistency here. For lines that start with ##, we
94+ // have no easy way of removing a potential single space after the hashes, which
95+ // is done in the single # case. This inconsistency seems okay, if non-ideal. In
96+ // order to fix it we'd have to iterate to find the first non-# character, and
97+ // then reallocate to remove it; which would make us return a String.
98+ fn map_line ( s : & str ) -> Line {
7499 let trimmed = s. trim ( ) ;
75- if trimmed == "#" {
76- Some ( "" )
100+ if trimmed. starts_with ( "##" ) {
101+ Line :: Shown ( & trimmed [ 1 .. ] )
77102 } else if trimmed. starts_with ( "# " ) {
78- Some ( & trimmed[ 2 ..] )
103+ // # text
104+ Line :: Hidden ( & trimmed[ 2 ..] )
105+ } else if trimmed == "#" {
106+ // We cannot handle '#text' because it could be #[attr].
107+ Line :: Hidden ( "" )
79108 } else {
80- None
109+ Line :: Shown ( s )
81110 }
82111}
83112
@@ -148,9 +177,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
148177 _ => { }
149178 }
150179 }
151- let lines = origtext. lines ( ) . filter ( |l| {
152- stripped_filtered_line ( * l) . is_none ( )
153- } ) ;
180+ let lines = origtext. lines ( ) . filter_map ( |l| map_line ( l) . for_html ( ) ) ;
154181 let text = lines. collect :: < Vec < & str > > ( ) . join ( "\n " ) ;
155182 PLAYGROUND . with ( |play| {
156183 // insert newline to clearly separate it from the
@@ -160,9 +187,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
160187 if url. is_empty ( ) {
161188 return None ;
162189 }
163- let test = origtext. lines ( ) . map ( |l| {
164- stripped_filtered_line ( l ) . unwrap_or ( l )
165- } ) . collect :: < Vec < & str > > ( ) . join ( "\n " ) ;
190+ let test = origtext. lines ( )
191+ . map ( |l| map_line ( l ) . for_code ( ) )
192+ . collect :: < Vec < & str > > ( ) . join ( "\n " ) ;
166193 let krate = krate. as_ref ( ) . map ( |s| & * * s) ;
167194 let test = test:: maketest ( & test, krate, false ,
168195 & Default :: default ( ) ) ;
@@ -543,9 +570,7 @@ pub fn render(w: &mut fmt::Formatter,
543570 }
544571 } ;
545572
546- let lines = origtext. lines ( ) . filter ( |l| {
547- stripped_filtered_line ( * l) . is_none ( )
548- } ) ;
573+ let lines = origtext. lines ( ) . filter_map ( |l| map_line ( l) . for_html ( ) ) ;
549574 let text = lines. collect :: < Vec < & str > > ( ) . join ( "\n " ) ;
550575 if rendered { return }
551576 PLAYGROUND . with ( |play| {
@@ -556,9 +581,9 @@ pub fn render(w: &mut fmt::Formatter,
556581 if url. is_empty ( ) {
557582 return None ;
558583 }
559- let test = origtext. lines ( ) . map ( |l| {
560- stripped_filtered_line ( l ) . unwrap_or ( l )
561- } ) . collect :: < Vec < & str > > ( ) . join ( "\n " ) ;
584+ let test = origtext. lines ( )
585+ . map ( |l| map_line ( l ) . for_code ( ) )
586+ . collect :: < Vec < & str > > ( ) . join ( "\n " ) ;
562587 let krate = krate. as_ref ( ) . map ( |s| & * * s) ;
563588 let test = test:: maketest ( & test, krate, false ,
564589 & Default :: default ( ) ) ;
@@ -734,9 +759,7 @@ pub fn old_find_testable_code(doc: &str, tests: &mut ::test::Collector, position
734759 let opaque = ( * data) . opaque as * mut hoedown_html_renderer_state ;
735760 let tests = & mut * ( ( * opaque) . opaque as * mut :: test:: Collector ) ;
736761 let text = str:: from_utf8 ( text) . unwrap ( ) ;
737- let lines = text. lines ( ) . map ( |l| {
738- stripped_filtered_line ( l) . unwrap_or ( l)
739- } ) ;
762+ let lines = text. lines ( ) . map ( |l| map_line ( l) . for_code ( ) ) ;
740763 let text = lines. collect :: < Vec < & str > > ( ) . join ( "\n " ) ;
741764 let filename = tests. get_filename ( ) ;
742765
@@ -827,9 +850,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp
827850 }
828851 }
829852 let offset = offset. unwrap_or ( 0 ) ;
830- let lines = test_s. lines ( ) . map ( |l| {
831- stripped_filtered_line ( l) . unwrap_or ( l)
832- } ) ;
853+ let lines = test_s. lines ( ) . map ( |l| map_line ( l) . for_code ( ) ) ;
833854 let text = lines. collect :: < Vec < & str > > ( ) . join ( "\n " ) ;
834855 nb_lines += doc[ prev_offset..offset] . lines ( ) . count ( ) ;
835856 let line = tests. get_line ( ) + ( nb_lines - 1 ) ;
0 commit comments