@@ -33,48 +33,80 @@ pub(crate) struct HrefContext<'a, 'b, 'c> {
3333
3434/// Decorations are represented as a map from CSS class to vector of character ranges.
3535/// Each range will be wrapped in a span with that class.
36+ #[ derive( Default ) ]
3637pub ( crate ) struct DecorationInfo ( pub ( crate ) FxHashMap < & ' static str , Vec < ( u32 , u32 ) > > ) ;
3738
38- /// Highlights `src`, returning the HTML output.
39- pub ( crate ) fn render_with_highlighting (
39+ #[ derive( Eq , PartialEq , Clone , Copy ) ]
40+ pub ( crate ) enum Tooltip {
41+ Ignore ,
42+ CompileFail ,
43+ ShouldPanic ,
44+ Edition ( Edition ) ,
45+ None ,
46+ }
47+
48+ /// Highlights `src` as an inline example, returning the HTML output.
49+ pub ( crate ) fn render_example_with_highlighting (
4050 src : & str ,
4151 out : & mut Buffer ,
42- class : Option < & str > ,
52+ tooltip : Tooltip ,
4353 playground_button : Option < & str > ,
44- tooltip : Option < ( Option < Edition > , & str ) > ,
45- edition : Edition ,
46- extra_content : Option < Buffer > ,
47- href_context : Option < HrefContext < ' _ , ' _ , ' _ > > ,
48- decoration_info : Option < DecorationInfo > ,
4954) {
50- debug ! ( "highlighting: ================\n {}\n ==============" , src) ;
51- if let Some ( ( edition_info, class) ) = tooltip {
55+ let class = match tooltip {
56+ Tooltip :: Ignore => " ignore" ,
57+ Tooltip :: CompileFail => " compile_fail" ,
58+ Tooltip :: ShouldPanic => " should_panic" ,
59+ Tooltip :: Edition ( _) => " edition" ,
60+ Tooltip :: None => "" ,
61+ } ;
62+
63+ if tooltip != Tooltip :: None {
5264 write ! (
5365 out,
54- "<div class='information'><div class='tooltip {}'{}>ⓘ</div></div>" ,
66+ "<div class='information'><div class='tooltip{}'{}>ⓘ</div></div>" ,
5567 class,
56- if let Some ( edition_info) = edition_info {
68+ if let Tooltip :: Edition ( edition_info) = tooltip {
5769 format!( " data-edition=\" {}\" " , edition_info)
5870 } else {
5971 String :: new( )
6072 } ,
6173 ) ;
6274 }
6375
64- write_header ( out, class, extra_content ) ;
65- write_code ( out, src, edition , href_context , decoration_info ) ;
76+ write_header ( out, & format ! ( "rust-example-rendered{}" , class) , None ) ;
77+ write_code ( out, src, None , None ) ;
6678 write_footer ( out, playground_button) ;
6779}
6880
69- fn write_header ( out : & mut Buffer , class : Option < & str > , extra_content : Option < Buffer > ) {
81+ /// Highlights `src` as a macro, returning the HTML output.
82+ pub ( crate ) fn render_macro_with_highlighting ( src : & str , out : & mut Buffer ) {
83+ write_header ( out, "macro" , None ) ;
84+ write_code ( out, src, None , None ) ;
85+ write_footer ( out, None ) ;
86+ }
87+
88+ /// Highlights `src` as a source code page, returning the HTML output.
89+ pub ( crate ) fn render_source_with_highlighting (
90+ src : & str ,
91+ out : & mut Buffer ,
92+ line_numbers : Buffer ,
93+ href_context : HrefContext < ' _ , ' _ , ' _ > ,
94+ decoration_info : DecorationInfo ,
95+ ) {
96+ write_header ( out, "" , Some ( line_numbers) ) ;
97+ write_code ( out, src, Some ( href_context) , Some ( decoration_info) ) ;
98+ write_footer ( out, None ) ;
99+ }
100+
101+ fn write_header ( out : & mut Buffer , class : & str , extra_content : Option < Buffer > ) {
70102 write ! ( out, "<div class=\" example-wrap\" >" ) ;
71103 if let Some ( extra) = extra_content {
72104 out. push_buffer ( extra) ;
73105 }
74- if let Some ( class) = class {
75- write ! ( out, "<pre class=\" rust {}\" >" , class) ;
76- } else {
106+ if class. is_empty ( ) {
77107 write ! ( out, "<pre class=\" rust\" >" ) ;
108+ } else {
109+ write ! ( out, "<pre class=\" rust {}\" >" , class) ;
78110 }
79111 write ! ( out, "<code>" ) ;
80112}
@@ -93,7 +125,6 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
93125fn write_code (
94126 out : & mut Buffer ,
95127 src : & str ,
96- edition : Edition ,
97128 href_context : Option < HrefContext < ' _ , ' _ , ' _ > > ,
98129 decoration_info : Option < DecorationInfo > ,
99130) {
@@ -102,7 +133,6 @@ fn write_code(
102133 let mut closing_tags: Vec < & ' static str > = Vec :: new ( ) ;
103134 Classifier :: new (
104135 & src,
105- edition,
106136 href_context. as_ref ( ) . map ( |c| c. file_span ) . unwrap_or ( DUMMY_SP ) ,
107137 decoration_info,
108138 )
@@ -220,7 +250,7 @@ impl<'a> Iterator for TokenIter<'a> {
220250}
221251
222252/// Classifies into identifier class; returns `None` if this is a non-keyword identifier.
223- fn get_real_ident_class ( text : & str , edition : Edition , allow_path_keywords : bool ) -> Option < Class > {
253+ fn get_real_ident_class ( text : & str , allow_path_keywords : bool ) -> Option < Class > {
224254 let ignore: & [ & str ] =
225255 if allow_path_keywords { & [ "self" , "Self" , "super" , "crate" ] } else { & [ "self" , "Self" ] } ;
226256 if ignore. iter ( ) . any ( |k| * k == text) {
@@ -229,7 +259,7 @@ fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool)
229259 Some ( match text {
230260 "ref" | "mut" => Class :: RefKeyWord ,
231261 "false" | "true" => Class :: Bool ,
232- _ if Symbol :: intern ( text) . is_reserved ( || edition ) => Class :: KeyWord ,
262+ _ if Symbol :: intern ( text) . is_reserved ( || Edition :: Edition2021 ) => Class :: KeyWord ,
233263 _ => return None ,
234264 } )
235265}
@@ -311,7 +341,6 @@ struct Classifier<'a> {
311341 in_attribute : bool ,
312342 in_macro : bool ,
313343 in_macro_nonterminal : bool ,
314- edition : Edition ,
315344 byte_pos : u32 ,
316345 file_span : Span ,
317346 src : & ' a str ,
@@ -321,20 +350,14 @@ struct Classifier<'a> {
321350impl < ' a > Classifier < ' a > {
322351 /// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
323352 /// file span which will be used later on by the `span_correspondance_map`.
324- fn new (
325- src : & str ,
326- edition : Edition ,
327- file_span : Span ,
328- decoration_info : Option < DecorationInfo > ,
329- ) -> Classifier < ' _ > {
353+ fn new ( src : & str , file_span : Span , decoration_info : Option < DecorationInfo > ) -> Classifier < ' _ > {
330354 let tokens = PeekIter :: new ( TokenIter { src } ) ;
331355 let decorations = decoration_info. map ( Decorations :: new) ;
332356 Classifier {
333357 tokens,
334358 in_attribute : false ,
335359 in_macro : false ,
336360 in_macro_nonterminal : false ,
337- edition,
338361 byte_pos : 0 ,
339362 file_span,
340363 src,
@@ -354,7 +377,6 @@ impl<'a> Classifier<'a> {
354377 let start = self . byte_pos as usize ;
355378 let mut pos = start;
356379 let mut has_ident = false ;
357- let edition = self . edition ;
358380
359381 loop {
360382 let mut nb = 0 ;
@@ -376,7 +398,7 @@ impl<'a> Classifier<'a> {
376398
377399 if let Some ( ( None , text) ) = self . tokens . peek ( ) . map ( |( token, text) | {
378400 if * token == TokenKind :: Ident {
379- let class = get_real_ident_class ( text, edition , true ) ;
401+ let class = get_real_ident_class ( text, true ) ;
380402 ( class, text)
381403 } else {
382404 // Doesn't matter which Class we put in here...
@@ -634,7 +656,7 @@ impl<'a> Classifier<'a> {
634656 sink ( Highlight :: Token { text, class : None } ) ;
635657 return ;
636658 }
637- TokenKind :: Ident => match get_real_ident_class ( text, self . edition , false ) {
659+ TokenKind :: Ident => match get_real_ident_class ( text, false ) {
638660 None => match text {
639661 "Option" | "Result" => Class :: PreludeTy ,
640662 "Some" | "None" | "Ok" | "Err" => Class :: PreludeVal ,
0 commit comments