| 553 | } |
| 554 | |
| 555 | fn codeblock_begin<'a, 'b>( |
| 556 | mut o: impl Write + 'b, |
| 557 | state: &'b mut ParseState, |
| 558 | ) -> impl FnMut(&mut Partial<&'a str>) -> PResult<(), Error<'a>> + 'b { |
| 559 | move |i| { |
| 560 | if !state.newline { |
| 561 | return Err(ErrMode::from_error_kind(i, ErrorKind::Fail)); |
| 562 | } |
| 563 | |
| 564 | // We don't want to do anything special to text inside codeblocks so we wait for all of it |
| 565 | // The alternative is to switch between parse rules at the top level but that's slightly involved |
| 566 | let language = preceded("```", till_line_ending).parse_next(i)?; |
| 567 | ascii::line_ending.parse_next(i)?; |
| 568 | |
| 569 | state.in_codeblock = true; |
| 570 | |
| 571 | if !language.is_empty() { |
| 572 | queue(&mut o, style::Print(format!("{}\n", language).bold()))?; |
| 573 | } |
| 574 | |
| 575 | queue(&mut o, StyledText::success_fg())?; |
| 576 | |
| 577 | Ok(()) |
| 578 | } |
| 579 | } |
| 580 | |
| 581 | fn codeblock_end<'a, 'b>( |
| 582 | mut o: impl Write + 'b, |