@@ -7,6 +7,7 @@ use std::borrow::Cow;
77
88use cow_utils:: CowUtils ;
99
10+ use oxc_formatter_core:: arena_cow_str;
1011use oxc_markdown_parser:: {
1112 Span ,
1213 ast:: { CodeSpan , Emphasis , HardBreakKind , Inline , LinkKind , Strong } ,
@@ -23,15 +24,15 @@ use super::{
2324 HTML_WHITESPACE , MarkdownFormatter , backticks, escape, is_split_whitespace, join_pieces,
2425 line_shape:: {
2526 is_line_shape_start, line_from, line_opens_block, line_or_prefix_opens_block, line_shape,
26- printed_line_opens_block, source_line_at,
27+ printed_line_at , printed_line_opens_block, source_line_at,
2728 } ,
2829 link,
2930 parts:: { Atom , Parts , Sep } ,
3031 text as words, with_depth,
3132} ;
3233
3334/// Where the inline children hang; a few rules depend on the immediate parent.
34- #[ derive( Clone , Copy ) ]
35+ #[ derive( Clone , Copy , Default ) ]
3536pub struct InlineParent {
3637 /// The children are a paragraph's (its first / last text gets trimmed).
3738 pub paragraph : bool ,
@@ -48,22 +49,6 @@ pub struct InlineParent {
4849 pub first_in_document : bool ,
4950 /// The paragraph follows a task list checkbox on its line: its first line is not a line start.
5051 pub after_checkbox : bool ,
51- /// Nothing follows the parent node on its source line (its last child ends the line).
52- pub ends_line : bool ,
53- }
54-
55- impl Default for InlineParent {
56- fn default ( ) -> Self {
57- Self {
58- paragraph : false ,
59- delimiter : None ,
60- strong_neighbor : None ,
61- first_in_container : false ,
62- first_in_document : false ,
63- after_checkbox : false ,
64- ends_line : true ,
65- }
66- }
6752}
6853
6954/// Paragraph or heading content as one fill.
@@ -375,7 +360,6 @@ pub fn collect_inlines<'a>(
375360 ) ,
376361 after_liquid : follows_liquid ( children, i) ,
377362 before_soft_break : matches ! ( children. get( i + 1 ) , Some ( Inline :: SoftBreak ( _) ) ) ,
378- ends_line : ends_line ( children, i, parent. ends_line ) ,
379363 next_word : next_word_of ( children, i, parent. delimiter , f) ,
380364 glued_last_word : glued_last_word ( children, i, raw, f) ,
381365 cj_spaces,
@@ -432,7 +416,6 @@ pub fn collect_inlines<'a>(
432416 parts. push_str ( style) ;
433417 let inner = InlineParent {
434418 delimiter : Some ( style. as_bytes ( ) [ 0 ] ) ,
435- ends_line : ends_line ( children, i, parent. ends_line ) ,
436419 ..InlineParent :: default ( )
437420 } ;
438421 with_depth ( f, MarkdownFormatContext :: emphasis_depth, |f| {
@@ -450,7 +433,6 @@ pub fn collect_inlines<'a>(
450433 let inner = InlineParent {
451434 delimiter : Some ( style. as_bytes ( ) [ 0 ] ) ,
452435 strong_neighbor : Some ( has_word_neighbor ( children, i, f) ) ,
453- ends_line : ends_line ( children, i, parent. ends_line ) ,
454436 ..InlineParent :: default ( )
455437 } ;
456438 with_depth ( f, MarkdownFormatContext :: delimiter_depth, |f| {
@@ -463,10 +445,7 @@ pub fn collect_inlines<'a>(
463445 let style = & "~~" [ ..usize:: from ( s. tildes ) ] ;
464446 let open = parts. len ( ) ;
465447 parts. push_str ( style) ;
466- let inner = InlineParent {
467- ends_line : ends_line ( children, i, parent. ends_line ) ,
468- ..InlineParent :: default ( )
469- } ;
448+ let inner = InlineParent :: default ( ) ;
470449 collect_inlines ( & s. children , inner, parts, f) ;
471450 mark_delimiter ( open, parts, false ) ;
472451 parts. push_str ( style) ;
@@ -596,12 +575,10 @@ fn next_word_of<'a>(
596575 if matches ! ( next, Inline :: SoftBreak ( _) | Inline :: HardBreak ( _) ) {
597576 return None ;
598577 }
599- // The word runs across nodes (`[^1]:` is a footnote reference and a text)
600- let ( mut word, alone_on_line) = first_word_at ( children, next. span ( ) . start , f) ?;
601- // A code span's fence is recomputed: the page shows the printed one, not the source's
602- if let Inline :: CodeSpan ( c) = next {
603- word = print_code_span ( c, f) . split ( is_split_whitespace) . next ( ) . unwrap_or ( word) ;
604- }
578+ // The word runs across nodes (`[^1]:` is a footnote reference and a text);
579+ // a code span's fence is recomputed, so the line is taken as it prints
580+ let line: & ' a str = arena_cow_str ( & printed_line_at ( children, i + 1 , f) . text , f) ;
581+ let word = first_word ( line) ?;
605582 // A text's leading run after a soft break is escaped inside emphasis
606583 // (as `push_text` decides: a space before it, and after it the text's next character or the node edge)
607584 let escaped = matches ! ( next, Inline :: Text ( _) )
@@ -612,29 +589,11 @@ fn next_word_of<'a>(
612589 Some ( ' ' ) ,
613590 edge_char ( children, i + 1 , delimiter, false , f) ,
614591 ) ;
615- Some ( words:: NextWord { word, alone_on_line , escaped } )
592+ Some ( words:: NextWord { word, line , escaped } )
616593}
617594
618- /// The first word of the source line starting at `start`, and whether it is the line's only one.
619- fn first_word_at < ' a > (
620- children : & [ Inline < ' _ > ] ,
621- start : u32 ,
622- f : & MarkdownFormatter < ' _ , ' a > ,
623- ) -> Option < ( & ' a str , bool ) > {
624- let ( _, line) = source_line_at ( children, start, f) ;
625- let mut it = line. split ( is_split_whitespace) . filter ( |w| !w. is_empty ( ) ) ;
626- let word = it. next ( ) ?;
627- Some ( ( word, it. next ( ) . is_none ( ) ) )
628- }
629-
630- /// Nothing follows node `i` on its source line (a node glued after it would be part of the line);
631- /// past the last sibling, whether the parent ends its line.
632- fn ends_line ( children : & [ Inline < ' _ > ] , i : usize , parent_ends_line : bool ) -> bool {
633- match children. get ( i + 1 ) {
634- None => parent_ends_line,
635- Some ( Inline :: SoftBreak ( _) | Inline :: HardBreak ( _) ) => true ,
636- Some ( _) => false ,
637- }
595+ fn first_word ( line : & str ) -> Option < & str > {
596+ line. split ( is_split_whitespace) . find ( |w| !w. is_empty ( ) )
638597}
639598
640599/// The character right before (`before`) or after the text at `i`, as it will be printed:
@@ -663,13 +622,13 @@ fn edge_char<'a>(
663622}
664623
665624/// The last word of text `i` (its printed `raw`) extended by the nodes glued after it
666- /// on its source line (a backslash hard break's `\` included), and whether it is the line's last word .
625+ /// on its source line (a backslash hard break's `\` included).
667626fn glued_last_word < ' a > (
668627 children : & ' a [ Inline < ' a > ] ,
669628 i : usize ,
670629 raw : & str ,
671630 f : & MarkdownFormatter < ' _ , ' a > ,
672- ) -> Option < ( & ' a str , bool ) > {
631+ ) -> Option < & ' a str > {
673632 // Nothing glues after whitespace, a line end, or a two-space hard break
674633 match children. get ( i + 1 ) {
675634 None | Some ( Inline :: SoftBreak ( _) ) => return None ,
@@ -679,7 +638,7 @@ fn glued_last_word<'a>(
679638 }
680639 let last = raw. rsplit ( is_split_whitespace) . next ( ) ?;
681640 let start = children[ i] . span ( ) . end - u32:: try_from ( last. len ( ) ) . unwrap_or ( 0 ) ;
682- first_word_at ( children, start, f) . filter ( |( word, _ ) | word. len ( ) != last. len ( ) )
641+ first_word ( source_line_at ( children, start, f) . 1 ) . filter ( |word| word. len ( ) != last. len ( ) )
683642}
684643
685644/// The last word of the text before node `i`.
0 commit comments