@@ -33,48 +33,80 @@ pub(crate) struct HrefContext<'a, 'b, 'c> {
33
33
34
34
/// Decorations are represented as a map from CSS class to vector of character ranges.
35
35
/// Each range will be wrapped in a span with that class.
36
+ #[ derive( Default ) ]
36
37
pub ( crate ) struct DecorationInfo ( pub ( crate ) FxHashMap < & ' static str , Vec < ( u32 , u32 ) > > ) ;
37
38
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 (
40
50
src : & str ,
41
51
out : & mut Buffer ,
42
- class : Option < & str > ,
52
+ tooltip : Tooltip ,
43
53
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 > ,
49
54
) {
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 {
52
64
write ! (
53
65
out,
54
- "<div class='information'><div class='tooltip {}'{}>ⓘ</div></div>" ,
66
+ "<div class='information'><div class='tooltip{}'{}>ⓘ</div></div>" ,
55
67
class,
56
- if let Some ( edition_info) = edition_info {
68
+ if let Tooltip :: Edition ( edition_info) = tooltip {
57
69
format!( " data-edition=\" {}\" " , edition_info)
58
70
} else {
59
71
String :: new( )
60
72
} ,
61
73
) ;
62
74
}
63
75
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 ) ;
66
78
write_footer ( out, playground_button) ;
67
79
}
68
80
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 > ) {
70
102
write ! ( out, "<div class=\" example-wrap\" >" ) ;
71
103
if let Some ( extra) = extra_content {
72
104
out. push_buffer ( extra) ;
73
105
}
74
- if let Some ( class) = class {
75
- write ! ( out, "<pre class=\" rust {}\" >" , class) ;
76
- } else {
106
+ if class. is_empty ( ) {
77
107
write ! ( out, "<pre class=\" rust\" >" ) ;
108
+ } else {
109
+ write ! ( out, "<pre class=\" rust {}\" >" , class) ;
78
110
}
79
111
write ! ( out, "<code>" ) ;
80
112
}
@@ -93,7 +125,6 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
93
125
fn write_code (
94
126
out : & mut Buffer ,
95
127
src : & str ,
96
- edition : Edition ,
97
128
href_context : Option < HrefContext < ' _ , ' _ , ' _ > > ,
98
129
decoration_info : Option < DecorationInfo > ,
99
130
) {
@@ -102,7 +133,6 @@ fn write_code(
102
133
let mut closing_tags: Vec < & ' static str > = Vec :: new ( ) ;
103
134
Classifier :: new (
104
135
& src,
105
- edition,
106
136
href_context. as_ref ( ) . map ( |c| c. file_span ) . unwrap_or ( DUMMY_SP ) ,
107
137
decoration_info,
108
138
)
@@ -220,7 +250,7 @@ impl<'a> Iterator for TokenIter<'a> {
220
250
}
221
251
222
252
/// 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 > {
224
254
let ignore: & [ & str ] =
225
255
if allow_path_keywords { & [ "self" , "Self" , "super" , "crate" ] } else { & [ "self" , "Self" ] } ;
226
256
if ignore. iter ( ) . any ( |k| * k == text) {
@@ -229,7 +259,7 @@ fn get_real_ident_class(text: &str, edition: Edition, allow_path_keywords: bool)
229
259
Some ( match text {
230
260
"ref" | "mut" => Class :: RefKeyWord ,
231
261
"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 ,
233
263
_ => return None ,
234
264
} )
235
265
}
@@ -311,7 +341,6 @@ struct Classifier<'a> {
311
341
in_attribute : bool ,
312
342
in_macro : bool ,
313
343
in_macro_nonterminal : bool ,
314
- edition : Edition ,
315
344
byte_pos : u32 ,
316
345
file_span : Span ,
317
346
src : & ' a str ,
@@ -321,20 +350,14 @@ struct Classifier<'a> {
321
350
impl < ' a > Classifier < ' a > {
322
351
/// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
323
352
/// 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 < ' _ > {
330
354
let tokens = PeekIter :: new ( TokenIter { src } ) ;
331
355
let decorations = decoration_info. map ( Decorations :: new) ;
332
356
Classifier {
333
357
tokens,
334
358
in_attribute : false ,
335
359
in_macro : false ,
336
360
in_macro_nonterminal : false ,
337
- edition,
338
361
byte_pos : 0 ,
339
362
file_span,
340
363
src,
@@ -354,7 +377,6 @@ impl<'a> Classifier<'a> {
354
377
let start = self . byte_pos as usize ;
355
378
let mut pos = start;
356
379
let mut has_ident = false ;
357
- let edition = self . edition ;
358
380
359
381
loop {
360
382
let mut nb = 0 ;
@@ -376,7 +398,7 @@ impl<'a> Classifier<'a> {
376
398
377
399
if let Some ( ( None , text) ) = self . tokens . peek ( ) . map ( |( token, text) | {
378
400
if * token == TokenKind :: Ident {
379
- let class = get_real_ident_class ( text, edition , true ) ;
401
+ let class = get_real_ident_class ( text, true ) ;
380
402
( class, text)
381
403
} else {
382
404
// Doesn't matter which Class we put in here...
@@ -634,7 +656,7 @@ impl<'a> Classifier<'a> {
634
656
sink ( Highlight :: Token { text, class : None } ) ;
635
657
return ;
636
658
}
637
- TokenKind :: Ident => match get_real_ident_class ( text, self . edition , false ) {
659
+ TokenKind :: Ident => match get_real_ident_class ( text, false ) {
638
660
None => match text {
639
661
"Option" | "Result" => Class :: PreludeTy ,
640
662
"Some" | "None" | "Ok" | "Err" => Class :: PreludeVal ,
0 commit comments