1010use anyhow:: Context ;
1111use lazy_static:: lazy_static;
1212use mdbook:: book:: BookItem ;
13- use mdbook:: errors:: { Error , Result } ;
13+ use mdbook:: errors:: Result ;
1414use mdbook:: renderer:: { HtmlHandlebars , RenderContext , Renderer } ;
1515use regex:: Regex ;
1616use std:: fs:: { self , File } ;
@@ -63,20 +63,16 @@ impl Renderer for GbAsmTut {
6363 BookItem :: Chapter ( chapter) if !chapter. is_draft_chapter ( ) => {
6464 let mut path = ctx. destination . join ( chapter. path . as_ref ( ) . unwrap ( ) ) ;
6565 path. set_extension ( "html" ) ;
66- render ( & mut path, & chapter . name , i)
66+ post_process ( & mut path, i)
6767 . context ( format ! ( "Failed to render {}" , & chapter. name) ) ?;
6868 }
6969
7070 _ => ( ) ,
7171 }
7272 }
7373 // Post-process the print page as well
74- render (
75- & mut ctx. destination . join ( "print.html" ) ,
76- "<print>" ,
77- usize:: MAX ,
78- )
79- . context ( "Failed to render print page" ) ?;
74+ post_process ( & mut ctx. destination . join ( "print.html" ) , usize:: MAX )
75+ . context ( "Failed to render print page" ) ?;
8076
8177 // Take the "ANCHOR" lines out of `hello_world.asm`
8278 let path = ctx. destination . join ( "assets" ) . join ( "hello-world.asm" ) ;
@@ -94,13 +90,7 @@ impl Renderer for GbAsmTut {
9490 }
9591}
9692
97- #[ derive( Debug ) ]
98- enum BoxType {
99- Plain ,
100- Decorated ,
101- }
102-
103- fn render ( path : & mut PathBuf , name : & str , index : usize ) -> Result < ( ) > {
93+ fn post_process ( path : & mut PathBuf , index : usize ) -> Result < ( ) > {
10494 // Since we are about to edit the file in-place, we must buffer it into memory
10595 let html = fs:: read_to_string ( & path) ?;
10696 // Open the output file, and possibly the output "index.html" file
@@ -125,104 +115,18 @@ fn render(path: &mut PathBuf, name: &str, index: usize) -> Result<()> {
125115 } ;
126116 }
127117
128- let mut cur_box = None ;
129118 let mut in_console = false ; // Are we in a "console" code block?
130- for ( i, mut line) in html. lines ( ) . enumerate ( ) {
131- let line_no = i + 1 ;
119+ for mut line in html. lines ( ) {
132120 lazy_static ! {
133121 static ref CONSOLE_CODE_RE : Regex =
134122 Regex :: new( r#"^<pre><code class="(?:\S*\s+)*language-console(?:\s+\S*)*">"# )
135123 . unwrap( ) ;
136124 }
137125
138- // Yes, this relies on how the HTML renderer outputs paragraphs, i.e.
139- // that tags are flush with the content.
126+ // Yes, this relies on how the HTML renderer outputs HTML, i.e. that the above tags are flush with each-other.
140127 // Yes, this sucks, and yes, I hate it.
141128 // If you have a better idea, please tell us! x_x
142-
143- if let Some ( line) = line. strip_prefix ( "<p>:::" ) {
144- if let Some ( line) = line. strip_suffix ( "</p>" ) {
145- let line = line. trim ( ) ;
146-
147- if let Some ( box_type) = line. split_whitespace ( ) . next ( ) {
148- // This is a box start marker
149- if cur_box. is_some ( ) {
150- return Err ( Error :: msg ( format ! (
151- "{}:{}: Attempting to open box inside of one" ,
152- path. display( ) ,
153- line_no
154- ) ) ) ;
155- }
156-
157- let ( box_type_name, decoration) = match box_type. find ( ':' ) {
158- Some ( n) => ( & box_type[ ..n] , Some ( & box_type[ n + 1 ..] ) ) ,
159- None => ( box_type, None ) ,
160- } ;
161-
162- let box_type_name = if [ "tip" , "warning" , "danger" ] . contains ( & box_type_name) {
163- box_type_name
164- } else {
165- let mut stderr = StandardStream :: stderr ( ColorChoice :: Auto ) ;
166- stderr
167- . set_color ( ColorSpec :: new ( ) . set_fg ( Some ( Color :: Yellow ) ) . set_bold ( true ) )
168- . unwrap ( ) ;
169- write ! ( & mut stderr, "warning" ) . unwrap ( ) ;
170- stderr. reset ( ) . unwrap ( ) ;
171- eprintln ! (
172- " ({}): unknown box type \" {}\" , defaulting to \" tip\" " ,
173- name, box_type_name
174- ) ;
175- "tip"
176- } ;
177- output ! ( format!(
178- "<div class=\" box {}{}\" >\n " ,
179- box_type_name,
180- decoration. map_or( "" , |_| " decorated" )
181- ) ) ;
182-
183- cur_box = if let Some ( decoration) = decoration {
184- output ! ( format!( "<div><p>{}</p></div>\n <div>\n " , decoration) ) ;
185- Some ( BoxType :: Decorated )
186- } else {
187- Some ( BoxType :: Plain )
188- } ;
189-
190- let title = & line[ box_type. len ( ) ..] . trim_start ( ) ;
191- if !title. is_empty ( ) {
192- output ! ( format!( "<p class=\" box-title\" >{}</p>" , title) ) ;
193- }
194- } else {
195- // This is a box ending marker
196- match cur_box {
197- None => {
198- return Err ( Error :: msg ( format ! (
199- "{}:{}: Attempting to close box outside of one" ,
200- path. display( ) ,
201- line_no
202- ) ) )
203- }
204- Some ( BoxType :: Decorated ) => {
205- output ! ( "</div>\n " ) ; // Close the `box-inner
206- }
207- Some ( BoxType :: Plain ) => ( ) ,
208- }
209- cur_box = None ;
210-
211- output ! ( "</div>\n " ) ;
212- }
213-
214- // Prevent normal output
215- continue ;
216- } else {
217- let mut stderr = StandardStream :: stderr ( ColorChoice :: Auto ) ;
218- stderr
219- . set_color ( ColorSpec :: new ( ) . set_fg ( Some ( Color :: Yellow ) ) . set_bold ( true ) )
220- . unwrap ( ) ;
221- write ! ( & mut stderr, "warning" ) . unwrap ( ) ;
222- stderr. reset ( ) . unwrap ( ) ;
223- eprintln ! ( " ({}): ignoring \" :::{}\" ; box start/end tags must be alone in their paragraph" , name, line) ;
224- }
225- } else if let Some ( match_info) = CONSOLE_CODE_RE . find ( line) {
129+ if let Some ( match_info) = CONSOLE_CODE_RE . find ( line) {
226130 output ! ( "<pre><code>" ) ; // Disable the highlighting
227131 in_console = true ;
228132 debug_assert_eq ! ( match_info. start( ) , 0 ) ;
@@ -248,9 +152,5 @@ fn render(path: &mut PathBuf, name: &str, index: usize) -> Result<()> {
248152 output ! ( "\n " ) ;
249153 }
250154
251- if cur_box. is_some ( ) {
252- return Err ( Error :: msg ( format ! ( "{}: Unclosed box" , path. display( ) ) ) ) ;
253- }
254-
255155 Ok ( ( ) )
256156}
0 commit comments