@@ -4,7 +4,7 @@ use crate::{
44 Monospace , Plain , ProcessedContent , StandaloneCurvedApostrophe , Subscript , Superscript ,
55} ;
66
7- use super :: document:: ParserState ;
7+ use super :: { document:: ParserState , marked_text :: WithLocationMappingContext } ;
88
99/// Context for location mapping operations
1010pub ( crate ) struct LocationMappingContext < ' a > {
@@ -13,197 +13,6 @@ pub(crate) struct LocationMappingContext<'a> {
1313 pub base_location : & ' a Location ,
1414}
1515
16- /// Trait for formatted inline elements that have form, content, and location
17- pub ( crate ) trait FormattedInline {
18- fn location ( & self ) -> & Location ;
19- fn location_mut ( & mut self ) -> & mut Location ;
20- fn content ( & self ) -> & Vec < InlineNode > ;
21- fn content_mut ( & mut self ) -> & mut Vec < InlineNode > ;
22- fn form ( & self ) -> & Form ;
23- }
24-
25- // Implementations for all formatted inline types
26- impl FormattedInline for Bold {
27- fn location ( & self ) -> & Location {
28- & self . location
29- }
30- fn location_mut ( & mut self ) -> & mut Location {
31- & mut self . location
32- }
33- fn content ( & self ) -> & Vec < InlineNode > {
34- & self . content
35- }
36- fn content_mut ( & mut self ) -> & mut Vec < InlineNode > {
37- & mut self . content
38- }
39- fn form ( & self ) -> & Form {
40- & self . form
41- }
42- }
43-
44- impl FormattedInline for Italic {
45- fn location ( & self ) -> & Location {
46- & self . location
47- }
48- fn location_mut ( & mut self ) -> & mut Location {
49- & mut self . location
50- }
51- fn content ( & self ) -> & Vec < InlineNode > {
52- & self . content
53- }
54- fn content_mut ( & mut self ) -> & mut Vec < InlineNode > {
55- & mut self . content
56- }
57- fn form ( & self ) -> & Form {
58- & self . form
59- }
60- }
61-
62- impl FormattedInline for Monospace {
63- fn location ( & self ) -> & Location {
64- & self . location
65- }
66- fn location_mut ( & mut self ) -> & mut Location {
67- & mut self . location
68- }
69- fn content ( & self ) -> & Vec < InlineNode > {
70- & self . content
71- }
72- fn content_mut ( & mut self ) -> & mut Vec < InlineNode > {
73- & mut self . content
74- }
75- fn form ( & self ) -> & Form {
76- & self . form
77- }
78- }
79-
80- impl FormattedInline for Highlight {
81- fn location ( & self ) -> & Location {
82- & self . location
83- }
84- fn location_mut ( & mut self ) -> & mut Location {
85- & mut self . location
86- }
87- fn content ( & self ) -> & Vec < InlineNode > {
88- & self . content
89- }
90- fn content_mut ( & mut self ) -> & mut Vec < InlineNode > {
91- & mut self . content
92- }
93- fn form ( & self ) -> & Form {
94- & self . form
95- }
96- }
97-
98- impl FormattedInline for Subscript {
99- fn location ( & self ) -> & Location {
100- & self . location
101- }
102- fn location_mut ( & mut self ) -> & mut Location {
103- & mut self . location
104- }
105- fn content ( & self ) -> & Vec < InlineNode > {
106- & self . content
107- }
108- fn content_mut ( & mut self ) -> & mut Vec < InlineNode > {
109- & mut self . content
110- }
111- fn form ( & self ) -> & Form {
112- & self . form
113- }
114- }
115-
116- impl FormattedInline for Superscript {
117- fn location ( & self ) -> & Location {
118- & self . location
119- }
120- fn location_mut ( & mut self ) -> & mut Location {
121- & mut self . location
122- }
123- fn content ( & self ) -> & Vec < InlineNode > {
124- & self . content
125- }
126- fn content_mut ( & mut self ) -> & mut Vec < InlineNode > {
127- & mut self . content
128- }
129- fn form ( & self ) -> & Form {
130- & self . form
131- }
132- }
133-
134- impl FormattedInline for CurvedQuotation {
135- fn location ( & self ) -> & Location {
136- & self . location
137- }
138- fn location_mut ( & mut self ) -> & mut Location {
139- & mut self . location
140- }
141- fn content ( & self ) -> & Vec < InlineNode > {
142- & self . content
143- }
144- fn content_mut ( & mut self ) -> & mut Vec < InlineNode > {
145- & mut self . content
146- }
147- fn form ( & self ) -> & Form {
148- & self . form
149- }
150- }
151-
152- impl FormattedInline for CurvedApostrophe {
153- fn location ( & self ) -> & Location {
154- & self . location
155- }
156- fn location_mut ( & mut self ) -> & mut Location {
157- & mut self . location
158- }
159- fn content ( & self ) -> & Vec < InlineNode > {
160- & self . content
161- }
162- fn content_mut ( & mut self ) -> & mut Vec < InlineNode > {
163- & mut self . content
164- }
165- fn form ( & self ) -> & Form {
166- & self . form
167- }
168- }
169-
170- /// Generic function for mapping formatted inline locations with form-awareness
171- pub ( crate ) fn map_formatted_inline_locations < T : FormattedInline > (
172- mut inline : T ,
173- mapping_ctx : & LocationMappingContext ,
174- ) -> T {
175- // Get the form first to avoid borrowing issues
176- let form = inline. form ( ) . clone ( ) ;
177- let content = inline. content ( ) . clone ( ) ;
178- let location = inline. location ( ) . clone ( ) ;
179-
180- // Create a form-aware location mapper - this provides more accurate location mapping!
181- let map_loc = create_location_mapper (
182- mapping_ctx. state ,
183- mapping_ctx. processed ,
184- mapping_ctx. base_location ,
185- Some ( & form) , // Pass the form information for precise mapping
186- ) ;
187-
188- // Map outer location with attribute extension
189- let mapped_outer = map_loc ( & location) ;
190- let extended_location =
191- extend_attribute_location_if_needed ( mapping_ctx. state , mapping_ctx. processed , mapped_outer) ;
192- * inline. location_mut ( ) = extended_location;
193-
194- // Map inner content locations
195- let mapped_content = map_inner_content_locations (
196- content,
197- map_loc. as_ref ( ) ,
198- mapping_ctx. state ,
199- mapping_ctx. processed ,
200- mapping_ctx. base_location ,
201- ) ;
202- * inline. content_mut ( ) = mapped_content;
203-
204- inline
205- }
206-
20716/// Location mapping coordinate transformations during inline processing.
20817///
20918/// # Location Mapping Overview
@@ -410,102 +219,52 @@ pub(crate) fn map_inner_content_locations(
410219 processed,
411220 base_location,
412221 } ;
413- marked_text. map_formatted_inline_locations ( & mapping_ctx)
222+ marked_text. with_location_mapping_context ( & mapping_ctx)
414223 }
415224 other => other,
416225 } )
417226 . collect ( )
418227}
419228
229+ /// Helper macro to remap locations for simple nodes (`PlainText`, etc.)
230+ macro_rules! remap_simple_location {
231+ ( $node: expr, $base_offset: expr) => { {
232+ $node. location. absolute_start += $base_offset;
233+ $node. location. absolute_end += $base_offset;
234+ $node. location. start. column += $base_offset;
235+ $node. location. end. column += $base_offset;
236+ } } ;
237+ }
238+
239+ /// Helper macro to remap locations for formatted nodes with content
240+ macro_rules! remap_formatted_location {
241+ ( $node: expr, $base_offset: expr) => { {
242+ remap_simple_location!( $node, $base_offset) ;
243+ // Recursively remap nested content
244+ for nested_node in & mut $node. content {
245+ remap_inline_node_location( nested_node, $base_offset) ;
246+ }
247+ } } ;
248+ }
249+
420250/// Remap the location of an inline node to final document coordinates
421251pub ( crate ) fn remap_inline_node_location ( node : & mut InlineNode , base_offset : usize ) {
422252 match node {
423- InlineNode :: PlainText ( plain) => {
424- plain. location . absolute_start += base_offset;
425- plain. location . absolute_end += base_offset;
426- plain. location . start . column += base_offset;
427- plain. location . end . column += base_offset;
428- }
429- InlineNode :: BoldText ( bold) => {
430- bold. location . absolute_start += base_offset;
431- bold. location . absolute_end += base_offset;
432- bold. location . start . column += base_offset;
433- bold. location . end . column += base_offset;
434- // Recursively remap nested content
435- for nested_node in & mut bold. content {
436- remap_inline_node_location ( nested_node, base_offset) ;
437- }
438- }
439- InlineNode :: ItalicText ( italic) => {
440- italic. location . absolute_start += base_offset;
441- italic. location . absolute_end += base_offset;
442- italic. location . start . column += base_offset;
443- italic. location . end . column += base_offset;
444- // Recursively remap nested content
445- for nested_node in & mut italic. content {
446- remap_inline_node_location ( nested_node, base_offset) ;
447- }
448- }
253+ InlineNode :: PlainText ( plain) => remap_simple_location ! ( plain, base_offset) ,
254+ InlineNode :: BoldText ( bold) => remap_formatted_location ! ( bold, base_offset) ,
255+ InlineNode :: ItalicText ( italic) => remap_formatted_location ! ( italic, base_offset) ,
449256 InlineNode :: SuperscriptText ( superscript) => {
450- superscript. location . absolute_start += base_offset;
451- superscript. location . absolute_end += base_offset;
452- superscript. location . start . column += base_offset;
453- superscript. location . end . column += base_offset;
454- // Recursively remap nested content
455- for nested_node in & mut superscript. content {
456- remap_inline_node_location ( nested_node, base_offset) ;
457- }
458- }
459- InlineNode :: SubscriptText ( subscript) => {
460- subscript. location . absolute_start += base_offset;
461- subscript. location . absolute_end += base_offset;
462- subscript. location . start . column += base_offset;
463- subscript. location . end . column += base_offset;
464- // Recursively remap nested content
465- for nested_node in & mut subscript. content {
466- remap_inline_node_location ( nested_node, base_offset) ;
467- }
257+ remap_formatted_location ! ( superscript, base_offset) ;
468258 }
259+ InlineNode :: SubscriptText ( subscript) => remap_formatted_location ! ( subscript, base_offset) ,
469260 InlineNode :: CurvedQuotationText ( curved_quotation) => {
470- curved_quotation. location . absolute_start += base_offset;
471- curved_quotation. location . absolute_end += base_offset;
472- curved_quotation. location . start . column += base_offset;
473- curved_quotation. location . end . column += base_offset;
474- // Recursively remap nested content
475- for nested_node in & mut curved_quotation. content {
476- remap_inline_node_location ( nested_node, base_offset) ;
477- }
261+ remap_formatted_location ! ( curved_quotation, base_offset) ;
478262 }
479263 InlineNode :: CurvedApostropheText ( curved_apostrophe) => {
480- curved_apostrophe. location . absolute_start += base_offset;
481- curved_apostrophe. location . absolute_end += base_offset;
482- curved_apostrophe. location . start . column += base_offset;
483- curved_apostrophe. location . end . column += base_offset;
484- // Recursively remap nested content
485- for nested_node in & mut curved_apostrophe. content {
486- remap_inline_node_location ( nested_node, base_offset) ;
487- }
488- }
489- InlineNode :: MonospaceText ( monospace) => {
490- monospace. location . absolute_start += base_offset;
491- monospace. location . absolute_end += base_offset;
492- monospace. location . start . column += base_offset;
493- monospace. location . end . column += base_offset;
494- // Recursively remap nested content
495- for nested_node in & mut monospace. content {
496- remap_inline_node_location ( nested_node, base_offset) ;
497- }
498- }
499- InlineNode :: HighlightText ( highlight) => {
500- highlight. location . absolute_start += base_offset;
501- highlight. location . absolute_end += base_offset;
502- highlight. location . start . column += base_offset;
503- highlight. location . end . column += base_offset;
504- // Recursively remap nested content
505- for nested_node in & mut highlight. content {
506- remap_inline_node_location ( nested_node, base_offset) ;
507- }
264+ remap_formatted_location ! ( curved_apostrophe, base_offset) ;
508265 }
266+ InlineNode :: MonospaceText ( monospace) => remap_formatted_location ! ( monospace, base_offset) ,
267+ InlineNode :: HighlightText ( highlight) => remap_formatted_location ! ( highlight, base_offset) ,
509268 // Add other inline node types as needed
510269 _ => { }
511270 }
@@ -616,7 +375,7 @@ pub(crate) fn map_inline_locations(
616375 processed,
617376 base_location : location,
618377 } ;
619- vec ! [ marked_text. clone( ) . map_formatted_inline_locations ( & mapping_ctx) ]
378+ vec ! [ marked_text. clone( ) . with_location_mapping_context ( & mapping_ctx) ]
620379 }
621380 InlineNode :: StandaloneCurvedApostrophe ( standalone) => {
622381 let mut mapped_standalone = standalone. clone ( ) ;
0 commit comments