@@ -6,6 +6,7 @@ use crate::renderer::{RenderContext, Renderer};
6
6
use crate :: theme:: { self , playpen_editor, Theme } ;
7
7
use crate :: utils;
8
8
9
+ use std:: borrow:: Cow ;
9
10
use std:: collections:: BTreeMap ;
10
11
use std:: collections:: HashMap ;
11
12
use std:: fs;
@@ -584,6 +585,7 @@ fn fix_code_blocks(html: &str) -> String {
584
585
}
585
586
586
587
fn add_playpen_pre ( html : & str , playpen_config : & Playpen ) -> String {
588
+ let boring_line_regex = Regex :: new ( r"^(\s*)#(#|.)(.*)$" ) . unwrap ( ) ;
587
589
let regex = Regex :: new ( r##"((?s)<code[^>]?class="([^"]+)".*?>(.*?)</code>)"## ) . unwrap ( ) ;
588
590
regex
589
591
. replace_all ( html, |caps : & Captures < ' _ > | {
@@ -597,21 +599,51 @@ fn add_playpen_pre(html: &str, playpen_config: &Playpen) -> String {
597
599
|| classes. contains ( "mdbook-runnable" )
598
600
{
599
601
// wrap the contents in an external pre block
600
- if playpen_config. editable && classes. contains ( "editable" )
601
- || text. contains ( "fn main" )
602
- || text. contains ( "quick_main!" )
603
- {
604
- format ! ( "<pre class=\" playpen\" >{}</pre>" , text)
605
- } else {
606
- // we need to inject our own main
607
- let ( attrs, code) = partition_source ( code) ;
608
-
609
- format ! (
610
- "<pre class=\" playpen\" ><code class=\" {}\" >\n # \
611
- #![allow(unused_variables)]\n {}#fn main() {{\n {}#}}</code></pre>",
612
- classes, attrs, code
613
- )
614
- }
602
+ format ! (
603
+ "<pre class=\" playpen\" ><code class=\" {}\" >{}</code></pre>" ,
604
+ classes,
605
+ {
606
+ let content: Cow <' _, str > = if playpen_config. editable
607
+ && classes. contains( "editable" )
608
+ || text. contains( "fn main" )
609
+ || text. contains( "quick_main!" )
610
+ {
611
+ code. into( )
612
+ } else {
613
+ // we need to inject our own main
614
+ let ( attrs, code) = partition_source( code) ;
615
+
616
+ format!(
617
+ "\n # #![allow(unused_variables)]\n {}#fn main() {{\n {}#}}" ,
618
+ attrs, code
619
+ )
620
+ . into( )
621
+ } ;
622
+ let mut prev_line_hidden = false ;
623
+ let mut result = String :: with_capacity( content. len( ) ) ;
624
+ for line in content. lines( ) {
625
+ if let Some ( caps) = boring_line_regex. captures( line) {
626
+ if !prev_line_hidden && & caps[ 2 ] != "#" {
627
+ result += "<span class=\" boring\" >" ;
628
+ prev_line_hidden = true ;
629
+ }
630
+ result += & caps[ 1 ] ;
631
+ if & caps[ 2 ] != " " {
632
+ result += & caps[ 2 ] ;
633
+ }
634
+ result += & caps[ 3 ] ;
635
+ } else {
636
+ if prev_line_hidden {
637
+ result += "</span>" ;
638
+ prev_line_hidden = false ;
639
+ }
640
+ result += line;
641
+ }
642
+ result += "\n " ;
643
+ }
644
+ result
645
+ }
646
+ )
615
647
} else {
616
648
// not language-rust, so no-op
617
649
text. to_owned ( )
@@ -687,4 +719,28 @@ mod tests {
687
719
assert_eq ! ( got, should_be) ;
688
720
}
689
721
}
722
+
723
+ #[ test]
724
+ fn add_playpen ( ) {
725
+ let inputs = [
726
+ ( "<code class=\" language-rust\" >x()</code>" ,
727
+ "<pre class=\" playpen\" ><code class=\" language-rust\" >\n <span class=\" boring\" >#![allow(unused_variables)]\n fn main() {\n </span>x()\n <span class=\" boring\" >}\n </code></pre>" ) ,
728
+ ( "<code class=\" language-rust\" >fn main() {}</code>" ,
729
+ "<pre class=\" playpen\" ><code class=\" language-rust\" >fn main() {}\n </code></pre>" ) ,
730
+ ( "<code class=\" language-rust editable\" >let s = \" foo\n # bar\n \" ;</code>" ,
731
+ "<pre class=\" playpen\" ><code class=\" language-rust editable\" >let s = \" foo\n <span class=\" boring\" > bar\n </span>\" ;\n </code></pre>" ) ,
732
+ ( "<code class=\" language-rust editable\" >let s = \" foo\n ## bar\n \" ;</code>" ,
733
+ "<pre class=\" playpen\" ><code class=\" language-rust editable\" >let s = \" foo\n # bar\n \" ;\n </code></pre>" ) ,
734
+ ] ;
735
+ for ( src, should_be) in & inputs {
736
+ let got = add_playpen_pre (
737
+ src,
738
+ & Playpen {
739
+ editable : true ,
740
+ ..Playpen :: default ( )
741
+ } ,
742
+ ) ;
743
+ assert_eq ! ( & * got, * should_be) ;
744
+ }
745
+ }
690
746
}
0 commit comments