2023-04-22 19:06:48 -04:00
use nom ::branch ::alt ;
use nom ::bytes ::complete ::tag ;
2023-04-22 20:57:30 -04:00
use nom ::character ::complete ::anychar ;
2023-04-22 22:34:37 -04:00
use nom ::character ::complete ::multispace1 ;
2023-04-22 20:02:51 -04:00
use nom ::character ::complete ::one_of ;
2023-12-08 15:51:38 -05:00
use nom ::character ::complete ::space1 ;
2023-10-09 20:36:38 -04:00
use nom ::combinator ::all_consuming ;
2023-12-08 15:51:38 -05:00
use nom ::combinator ::consumed ;
2023-04-22 20:48:01 -04:00
use nom ::combinator ::map ;
2023-10-09 20:36:38 -04:00
use nom ::combinator ::map_parser ;
2023-04-22 22:34:37 -04:00
use nom ::combinator ::not ;
2023-12-08 15:51:38 -05:00
use nom ::combinator ::opt ;
2023-04-22 19:34:13 -04:00
use nom ::combinator ::peek ;
2023-04-22 20:02:51 -04:00
use nom ::combinator ::recognize ;
2023-04-22 19:34:13 -04:00
use nom ::combinator ::verify ;
2023-10-09 20:36:38 -04:00
use nom ::multi ::many1 ;
2023-04-22 19:34:13 -04:00
use nom ::multi ::many_till ;
use nom ::sequence ::terminated ;
2023-08-10 20:04:59 -04:00
#[ cfg(feature = " tracing " ) ]
2023-04-24 17:16:07 -04:00
use tracing ::span ;
2023-04-22 19:06:48 -04:00
2023-09-02 23:16:02 -04:00
use super ::object_parser ::standard_set_object ;
2023-08-23 00:30:26 -04:00
use super ::org_source ::OrgSource ;
2023-07-14 17:37:46 -04:00
use super ::radio_link ::RematchObject ;
2023-10-09 20:36:38 -04:00
use super ::util ::confine_context ;
2023-08-31 15:44:44 -04:00
use super ::util ::maybe_consume_object_trailing_whitespace_if_not_exiting ;
2023-10-09 16:44:59 -04:00
use super ::util ::org_line_ending ;
2023-09-16 14:06:31 -04:00
use super ::util ::start_of_line ;
2023-10-09 20:36:38 -04:00
use super ::util ::text_until_exit ;
2023-09-02 23:16:02 -04:00
use crate ::context ::parser_with_context ;
2023-10-09 20:36:38 -04:00
use crate ::context ::Context ;
2023-09-02 23:16:02 -04:00
use crate ::context ::ContextElement ;
2023-09-03 15:44:18 -04:00
use crate ::context ::ContextMatcher ;
2023-09-02 23:16:02 -04:00
use crate ::context ::ExitClass ;
use crate ::context ::ExitMatcherNode ;
2023-10-09 20:36:38 -04:00
use crate ::context ::List ;
2023-09-02 23:16:02 -04:00
use crate ::context ::RefContext ;
2023-04-22 19:06:48 -04:00
use crate ::error ::CustomError ;
2023-04-22 18:54:19 -04:00
use crate ::error ::Res ;
2023-07-14 17:37:46 -04:00
use crate ::parser ::radio_link ::rematch_target ;
2023-04-22 19:34:13 -04:00
use crate ::parser ::util ::exit_matcher_parser ;
use crate ::parser ::util ::get_consumed ;
2023-04-24 16:19:48 -04:00
use crate ::parser ::util ::preceded_by_whitespace ;
2023-09-02 23:16:02 -04:00
use crate ::types ::Bold ;
use crate ::types ::Code ;
use crate ::types ::Italic ;
use crate ::types ::Object ;
use crate ::types ::StrikeThrough ;
use crate ::types ::Underline ;
use crate ::types ::Verbatim ;
2023-04-22 18:54:19 -04:00
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-11 13:13:28 -04:00
pub ( crate ) fn text_markup < ' b , ' g , ' r , ' s > (
2023-09-03 15:44:18 -04:00
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Object < ' s > > {
2023-04-22 20:48:01 -04:00
alt ( (
map ( parser_with_context! ( bold ) ( context ) , Object ::Bold ) ,
map ( parser_with_context! ( italic ) ( context ) , Object ::Italic ) ,
map ( parser_with_context! ( underline ) ( context ) , Object ::Underline ) ,
map (
parser_with_context! ( strike_through ) ( context ) ,
Object ::StrikeThrough ,
) ,
2023-04-22 20:57:30 -04:00
map ( parser_with_context! ( verbatim ) ( context ) , Object ::Verbatim ) ,
map ( parser_with_context! ( code ) ( context ) , Object ::Code ) ,
2023-04-22 20:48:01 -04:00
) ) ( input )
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-11 13:13:28 -04:00
fn bold < ' b , ' g , ' r , ' s > (
2023-09-03 15:44:18 -04:00
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Bold < ' s > > {
2023-12-08 15:51:38 -05:00
let ( remaining , ( contents , children , post_blank ) ) = text_markup_object ( " * " ) ( context , input ) ? ;
2023-04-22 20:48:01 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Bold {
source : source . into ( ) ,
2023-12-08 15:51:38 -05:00
contents : contents . into ( ) ,
post_blank : post_blank . map ( Into ::< & str > ::into ) ,
2023-08-23 00:30:26 -04:00
children ,
} ,
) )
2023-04-22 20:48:01 -04:00
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-11 13:13:28 -04:00
fn italic < ' b , ' g , ' r , ' s > (
2023-09-03 15:44:18 -04:00
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Italic < ' s > > {
2023-12-08 15:51:38 -05:00
let ( remaining , ( contents , children , post_blank ) ) = text_markup_object ( " / " ) ( context , input ) ? ;
2023-04-22 20:48:01 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Italic {
source : source . into ( ) ,
2023-12-08 15:51:38 -05:00
contents : contents . into ( ) ,
post_blank : post_blank . map ( Into ::< & str > ::into ) ,
2023-08-23 00:30:26 -04:00
children ,
} ,
) )
2023-04-22 20:48:01 -04:00
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-11 13:13:28 -04:00
fn underline < ' b , ' g , ' r , ' s > (
2023-09-03 15:44:18 -04:00
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Underline < ' s > > {
2023-12-08 15:51:38 -05:00
let ( remaining , ( contents , children , post_blank ) ) = text_markup_object ( " _ " ) ( context , input ) ? ;
2023-04-22 20:48:01 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Underline {
source : source . into ( ) ,
2023-12-08 15:51:38 -05:00
contents : contents . into ( ) ,
post_blank : post_blank . map ( Into ::< & str > ::into ) ,
2023-08-23 00:30:26 -04:00
children ,
} ,
) )
2023-04-22 20:48:01 -04:00
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-11 13:13:28 -04:00
fn strike_through < ' b , ' g , ' r , ' s > (
2023-09-03 15:44:18 -04:00
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , StrikeThrough < ' s > > {
2023-12-08 15:51:38 -05:00
let ( remaining , ( contents , children , post_blank ) ) = text_markup_object ( " + " ) ( context , input ) ? ;
2023-04-22 20:48:01 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
StrikeThrough {
source : source . into ( ) ,
2023-12-08 15:51:38 -05:00
contents : contents . into ( ) ,
post_blank : post_blank . map ( Into ::< & str > ::into ) ,
2023-08-23 00:30:26 -04:00
children ,
} ,
) )
2023-04-22 20:48:01 -04:00
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-11 13:13:28 -04:00
fn verbatim < ' b , ' g , ' r , ' s > (
2023-09-03 15:44:18 -04:00
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Verbatim < ' s > > {
2023-12-08 16:04:18 -05:00
let ( remaining , ( contents , post_blank ) ) = text_markup_string ( " = " ) ( context , input ) ? ;
2023-04-22 20:57:30 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Verbatim {
source : source . into ( ) ,
contents : contents . into ( ) ,
2023-12-08 16:04:18 -05:00
post_blank : post_blank . map ( Into ::< & str > ::into ) ,
2023-08-23 00:30:26 -04:00
} ,
) )
2023-04-22 20:57:30 -04:00
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-11 13:13:28 -04:00
fn code < ' b , ' g , ' r , ' s > (
2023-09-03 15:44:18 -04:00
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Code < ' s > > {
2023-12-08 16:04:18 -05:00
let ( remaining , ( contents , post_blank ) ) = text_markup_string ( " ~ " ) ( context , input ) ? ;
2023-04-22 20:57:30 -04:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Code {
source : source . into ( ) ,
contents : contents . into ( ) ,
2023-12-08 16:04:18 -05:00
post_blank : post_blank . map ( Into ::< & str > ::into ) ,
2023-08-23 00:30:26 -04:00
} ,
) )
2023-04-22 20:57:30 -04:00
}
2023-10-16 17:03:16 -04:00
fn text_markup_object (
marker_symbol : & str ,
2023-09-03 15:44:18 -04:00
) -> impl for < ' b , ' g , ' r , ' s > Fn (
RefContext < ' b , ' g , ' r , ' s > ,
2023-09-02 23:16:02 -04:00
OrgSource < ' s > ,
2023-12-08 15:51:38 -05:00
) -> Res <
OrgSource < ' s > ,
( OrgSource < ' s > , Vec < Object < ' s > > , Option < OrgSource < ' s > > ) ,
> + '_ {
2023-09-21 22:35:09 -04:00
move | context , input : OrgSource < '_ > | _text_markup_object ( context , input , marker_symbol )
2023-04-22 20:48:01 -04:00
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-03 15:44:18 -04:00
fn _text_markup_object < ' b , ' g , ' r , ' s , ' c > (
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
2023-09-03 15:44:18 -04:00
marker_symbol : & ' c str ,
2023-12-08 15:51:38 -05:00
) -> Res < OrgSource < ' s > , ( OrgSource < ' s > , Vec < Object < ' s > > , Option < OrgSource < ' s > > ) > {
2023-04-22 19:06:48 -04:00
let ( remaining , _ ) = pre ( context , input ) ? ;
2023-04-22 21:01:29 -04:00
let ( remaining , open ) = tag ( marker_symbol ) ( remaining ) ? ;
2023-09-07 01:23:15 -04:00
let ( remaining , _peek_not_whitespace ) =
peek ( verify ( anychar , | c | ! c . is_whitespace ( ) & & * c ! = '\u{200B}' ) ) ( remaining ) ? ;
2023-09-21 23:00:28 -04:00
let text_markup_end_specialized = text_markup_end ( open . into ( ) , remaining . get_byte_offset ( ) ) ;
2023-10-09 20:36:38 -04:00
let contexts = [ ContextElement ::ExitMatcherNode ( ExitMatcherNode {
class : ExitClass ::Gamma ,
exit_matcher : & text_markup_end_specialized ,
} ) ] ;
2023-09-07 02:01:34 -04:00
let parser_context = context . with_additional_node ( & contexts [ 0 ] ) ;
2023-04-22 19:06:48 -04:00
2023-10-09 20:36:38 -04:00
let initial_context = ContextElement ::document_context ( ) ;
let initial_context = Context ::new ( context . get_global_settings ( ) , List ::new ( & initial_context ) ) ;
2023-12-08 15:51:38 -05:00
let ( remaining , ( contents , children ) ) = consumed ( map_parser (
2023-10-09 20:36:38 -04:00
verify (
parser_with_context! ( text_until_exit ) ( & parser_context ) ,
| text | text . len ( ) > 0 ,
2023-04-22 19:34:13 -04:00
) ,
2023-10-09 20:36:38 -04:00
confine_context ( | i | {
all_consuming ( many1 ( parser_with_context! ( standard_set_object ) (
& initial_context ,
) ) ) ( i )
} ) ,
2023-12-08 15:51:38 -05:00
) ) ( remaining ) ? ;
2023-04-22 19:34:13 -04:00
2023-04-24 17:16:07 -04:00
{
2023-08-10 20:04:59 -04:00
#[ cfg(feature = " tracing " ) ]
2023-04-24 17:16:07 -04:00
let span = span! ( tracing ::Level ::DEBUG , " Checking parent exit. " ) ;
2023-08-10 20:04:59 -04:00
#[ cfg(feature = " tracing " ) ]
2023-04-24 17:16:07 -04:00
let _enter = span . enter ( ) ;
if exit_matcher_parser ( context , remaining ) . is_ok ( ) {
2023-10-17 10:09:37 -04:00
return Err ( nom ::Err ::Error ( CustomError ::Static (
2023-10-16 17:03:16 -04:00
" Parent exit matcher is triggering. " ,
2023-10-17 10:09:37 -04:00
) ) ) ;
2023-04-24 17:16:07 -04:00
}
2023-04-24 16:48:33 -04:00
}
2023-04-22 20:04:35 -04:00
let ( remaining , _close ) = text_markup_end_specialized ( context , remaining ) ? ;
2023-12-08 15:51:38 -05:00
let ( remaining , post_blank ) =
2023-08-31 15:44:44 -04:00
maybe_consume_object_trailing_whitespace_if_not_exiting ( context , remaining ) ? ;
2023-12-08 15:51:38 -05:00
Ok ( ( remaining , ( contents , children , post_blank ) ) )
2023-04-22 18:54:19 -04:00
}
2023-04-22 19:06:48 -04:00
2023-10-16 17:03:16 -04:00
fn text_markup_string (
marker_symbol : & str ,
2023-09-03 15:44:18 -04:00
) -> impl for < ' b , ' g , ' r , ' s > Fn (
RefContext < ' b , ' g , ' r , ' s > ,
2023-09-02 23:16:02 -04:00
OrgSource < ' s > ,
2023-12-08 16:04:18 -05:00
) -> Res < OrgSource < ' s > , ( OrgSource < ' s > , Option < OrgSource < ' s > > ) >
2023-10-16 17:03:16 -04:00
+ '_ {
2023-09-02 23:16:02 -04:00
move | context , input : OrgSource < '_ > | _text_markup_string ( context , input , marker_symbol )
2023-04-22 20:57:30 -04:00
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-03 15:44:18 -04:00
fn _text_markup_string < ' b , ' g , ' r , ' s , ' c > (
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
2023-09-03 15:44:18 -04:00
marker_symbol : & ' c str ,
2023-12-08 16:04:18 -05:00
) -> Res < OrgSource < ' s > , ( OrgSource < ' s > , Option < OrgSource < ' s > > ) > {
2023-04-22 20:57:30 -04:00
let ( remaining , _ ) = pre ( context , input ) ? ;
2023-04-22 21:01:29 -04:00
let ( remaining , open ) = tag ( marker_symbol ) ( remaining ) ? ;
2023-09-06 13:56:27 -04:00
let ( remaining , _peek_not_whitespace ) =
peek ( verify ( anychar , | c | ! c . is_whitespace ( ) & & * c ! = '\u{200B}' ) ) ( remaining ) ? ;
2023-09-21 23:00:28 -04:00
let text_markup_end_specialized = text_markup_end ( open . into ( ) , remaining . get_byte_offset ( ) ) ;
2023-10-09 20:36:38 -04:00
let contexts = [ ContextElement ::ExitMatcherNode ( ExitMatcherNode {
class : ExitClass ::Gamma ,
exit_matcher : & text_markup_end_specialized ,
} ) ] ;
2023-09-07 02:01:34 -04:00
let parser_context = context . with_additional_node ( & contexts [ 0 ] ) ;
2023-04-22 20:57:30 -04:00
let ( remaining , contents ) = recognize ( verify (
many_till (
anychar ,
parser_with_context! ( exit_matcher_parser ) ( & parser_context ) ,
) ,
| ( children , _exit_contents ) | ! children . is_empty ( ) ,
) ) ( remaining ) ? ;
2023-04-24 17:16:07 -04:00
{
2023-08-10 20:04:59 -04:00
#[ cfg(feature = " tracing " ) ]
2023-04-24 17:16:07 -04:00
let span = span! ( tracing ::Level ::DEBUG , " Checking parent exit. " ) ;
2023-08-10 20:04:59 -04:00
#[ cfg(feature = " tracing " ) ]
2023-04-24 17:16:07 -04:00
let _enter = span . enter ( ) ;
if exit_matcher_parser ( context , remaining ) . is_ok ( ) {
2023-10-17 10:09:37 -04:00
return Err ( nom ::Err ::Error ( CustomError ::Static (
2023-10-16 17:03:16 -04:00
" Parent exit matcher is triggering. " ,
2023-10-17 10:09:37 -04:00
) ) ) ;
2023-04-24 17:16:07 -04:00
}
2023-04-24 16:48:33 -04:00
}
2023-04-22 20:57:30 -04:00
let ( remaining , _close ) = text_markup_end_specialized ( context , remaining ) ? ;
2023-12-08 16:04:18 -05:00
let ( remaining , post_blank ) =
2023-08-31 15:44:44 -04:00
maybe_consume_object_trailing_whitespace_if_not_exiting ( context , remaining ) ? ;
2023-12-08 16:04:18 -05:00
Ok ( ( remaining , ( contents , post_blank ) ) )
2023-04-22 20:57:30 -04:00
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( _context ) )
) ]
2023-09-11 13:13:28 -04:00
fn pre < ' b , ' g , ' r , ' s > (
2023-10-09 16:44:59 -04:00
_context : RefContext < ' b , ' g , ' r , ' s > ,
2023-09-02 23:16:02 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , ( ) > {
2023-09-16 14:06:31 -04:00
if start_of_line ( input ) . is_ok ( ) {
return Ok ( ( input , ( ) ) ) ;
}
if preceded_by_whitespace ( true ) ( input ) . is_ok ( ) {
return Ok ( ( input , ( ) ) ) ;
}
2023-08-24 16:55:56 -04:00
let preceding_character = input . get_preceding_character ( ) ;
2023-04-22 19:06:48 -04:00
match preceding_character {
// If None, we are at the start of the file which is technically the beginning of a line.
2023-09-16 14:06:31 -04:00
Some ( '-' ) | Some ( '(' ) | Some ( '{' ) | Some ( '\'' ) | Some ( '"' ) = > { }
2023-04-22 19:06:48 -04:00
Some ( _ ) = > {
2023-10-17 10:09:37 -04:00
return Err ( nom ::Err ::Error ( CustomError ::Static (
2023-10-16 17:03:16 -04:00
" Not a valid pre character for text markup. " ,
2023-10-17 10:09:37 -04:00
) ) ) ;
2023-04-22 19:06:48 -04:00
}
2023-09-16 14:06:31 -04:00
None = > unreachable! ( ) , // None is for start of file, which should already be handled by the start_of_line matcher above.
2023-04-22 19:06:48 -04:00
} ;
Ok ( ( input , ( ) ) )
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( _context ) )
) ]
2023-09-11 13:13:28 -04:00
fn post < ' b , ' g , ' r , ' s > (
2023-09-03 15:44:18 -04:00
_context : RefContext < ' b , ' g , ' r , ' s > ,
2023-09-02 23:16:02 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , ( ) > {
2023-10-09 16:44:59 -04:00
let ( remaining , _ ) =
alt ( ( recognize ( one_of ( " \r \n \t -.,;:!?')}[ \" \\ " ) ) , org_line_ending ) ) ( input ) ? ;
2023-04-22 20:02:51 -04:00
Ok ( ( remaining , ( ) ) )
2023-04-22 19:34:13 -04:00
}
2023-10-16 17:03:16 -04:00
fn text_markup_end ( marker_symbol : & str , contents_start_offset : usize ) -> impl ContextMatcher + '_ {
2023-09-21 23:00:28 -04:00
move | context , input : OrgSource < '_ > | {
_text_markup_end ( context , input , marker_symbol , contents_start_offset )
}
2023-04-22 19:34:13 -04:00
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-03 15:44:18 -04:00
fn _text_markup_end < ' b , ' g , ' r , ' s , ' c > (
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
2023-09-03 15:44:18 -04:00
marker_symbol : & ' c str ,
2023-09-21 23:00:28 -04:00
contents_start_offset : usize ,
2023-08-23 00:30:26 -04:00
) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-09-21 23:00:28 -04:00
if input . get_byte_offset ( ) = = contents_start_offset {
2023-10-17 10:09:37 -04:00
return Err ( nom ::Err ::Error ( CustomError ::Static (
2023-10-16 17:03:16 -04:00
" Text markup cannot be empty " ,
2023-10-17 10:09:37 -04:00
) ) ) ;
2023-09-21 23:00:28 -04:00
}
2023-09-07 02:27:55 -04:00
not ( preceded_by_whitespace ( false ) ) ( input ) ? ;
2023-04-22 19:34:13 -04:00
let ( remaining , _marker ) = terminated (
tag ( marker_symbol ) ,
peek ( parser_with_context! ( post ) ( context ) ) ,
) ( input ) ? ;
let source = get_consumed ( input , remaining ) ;
Ok ( ( remaining , source ) )
}
2023-07-14 17:37:46 -04:00
2023-07-14 18:04:01 -04:00
impl < ' x > RematchObject < ' x > for Bold < ' x > {
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( _context ) )
) ]
2023-09-03 15:44:18 -04:00
fn rematch_object < ' b , ' g , ' r , ' s > (
2023-07-14 18:04:01 -04:00
& ' x self ,
2023-09-03 15:44:18 -04:00
_context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Object < ' s > > {
2023-12-08 15:51:38 -05:00
let ( remaining , ( contents , children , post_blank ) ) =
2023-07-14 17:37:46 -04:00
_rematch_text_markup_object ( _context , input , " * " , & self . children ) ? ;
let source = get_consumed ( input , remaining ) ;
2023-08-23 00:30:26 -04:00
Ok ( (
remaining ,
Object ::Bold ( Bold {
source : source . into ( ) ,
2023-12-08 15:51:38 -05:00
contents : contents . into ( ) ,
post_blank : post_blank . map ( Into ::< & str > ::into ) ,
2023-08-23 00:30:26 -04:00
children ,
} ) ,
) )
2023-07-14 17:37:46 -04:00
}
}
2023-09-19 23:25:49 -04:00
impl < ' x > RematchObject < ' x > for Italic < ' x > {
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( _context ) )
) ]
2023-09-19 23:25:49 -04:00
fn rematch_object < ' b , ' g , ' r , ' s > (
& ' x self ,
_context : RefContext < ' b , ' g , ' r , ' s > ,
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Object < ' s > > {
2023-12-08 15:51:38 -05:00
let ( remaining , ( contents , children , post_blank ) ) =
2023-09-19 23:25:49 -04:00
_rematch_text_markup_object ( _context , input , " / " , & self . children ) ? ;
let source = get_consumed ( input , remaining ) ;
Ok ( (
remaining ,
Object ::Italic ( Italic {
source : source . into ( ) ,
2023-12-08 15:51:38 -05:00
contents : contents . into ( ) ,
post_blank : post_blank . map ( Into ::< & str > ::into ) ,
2023-09-19 23:25:49 -04:00
children ,
} ) ,
) )
}
}
impl < ' x > RematchObject < ' x > for Underline < ' x > {
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( _context ) )
) ]
2023-09-19 23:25:49 -04:00
fn rematch_object < ' b , ' g , ' r , ' s > (
& ' x self ,
_context : RefContext < ' b , ' g , ' r , ' s > ,
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Object < ' s > > {
2023-12-08 15:51:38 -05:00
let ( remaining , ( contents , children , post_blank ) ) =
2023-09-19 23:25:49 -04:00
_rematch_text_markup_object ( _context , input , " _ " , & self . children ) ? ;
let source = get_consumed ( input , remaining ) ;
Ok ( (
remaining ,
Object ::Underline ( Underline {
source : source . into ( ) ,
2023-12-08 15:51:38 -05:00
contents : contents . into ( ) ,
post_blank : post_blank . map ( Into ::< & str > ::into ) ,
2023-09-19 23:25:49 -04:00
children ,
} ) ,
) )
}
}
impl < ' x > RematchObject < ' x > for StrikeThrough < ' x > {
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( _context ) )
) ]
2023-09-19 23:25:49 -04:00
fn rematch_object < ' b , ' g , ' r , ' s > (
& ' x self ,
_context : RefContext < ' b , ' g , ' r , ' s > ,
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Object < ' s > > {
2023-12-08 15:51:38 -05:00
let ( remaining , ( contents , children , post_blank ) ) =
2023-09-19 23:25:49 -04:00
_rematch_text_markup_object ( _context , input , " + " , & self . children ) ? ;
let source = get_consumed ( input , remaining ) ;
Ok ( (
remaining ,
Object ::StrikeThrough ( StrikeThrough {
source : source . into ( ) ,
2023-12-08 15:51:38 -05:00
contents : contents . into ( ) ,
post_blank : post_blank . map ( Into ::< & str > ::into ) ,
2023-09-19 23:25:49 -04:00
children ,
} ) ,
) )
}
}
2023-10-09 18:00:48 -04:00
#[ cfg_attr(
feature = " tracing " ,
tracing ::instrument ( ret , level = " debug " , skip ( context ) )
) ]
2023-09-03 15:44:18 -04:00
fn _rematch_text_markup_object < ' b , ' g , ' r , ' s , ' x > (
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 00:30:26 -04:00
input : OrgSource < ' s > ,
2023-07-14 17:37:46 -04:00
marker_symbol : & 'static str ,
2023-07-14 18:04:01 -04:00
original_match_children : & ' x Vec < Object < ' x > > ,
2023-12-08 15:51:38 -05:00
) -> Res < OrgSource < ' s > , ( OrgSource < ' s > , Vec < Object < ' s > > , Option < OrgSource < ' s > > ) > {
2023-07-14 17:37:46 -04:00
let ( remaining , _ ) = pre ( context , input ) ? ;
let ( remaining , open ) = tag ( marker_symbol ) ( remaining ) ? ;
let ( remaining , _peek_not_whitespace ) = peek ( not ( multispace1 ) ) ( remaining ) ? ;
2023-09-21 23:00:28 -04:00
let text_markup_end_specialized = text_markup_end ( open . into ( ) , remaining . get_byte_offset ( ) ) ;
2023-09-02 23:16:02 -04:00
let parser_context = ContextElement ::ExitMatcherNode ( ExitMatcherNode {
class : ExitClass ::Gamma ,
exit_matcher : & text_markup_end_specialized ,
} ) ;
let parser_context = context . with_additional_node ( & parser_context ) ;
2023-07-14 17:37:46 -04:00
2023-12-08 15:51:38 -05:00
let contents_begin = remaining ;
2023-07-14 17:37:46 -04:00
let ( remaining , children ) =
// TODO: This doesn't really check the exit matcher between each object. I think it may be possible to construct an org document that parses incorrectly with the current code.
rematch_target ( & parser_context , original_match_children , remaining ) ? ;
{
2023-08-10 20:04:59 -04:00
#[ cfg(feature = " tracing " ) ]
2023-07-14 17:37:46 -04:00
let span = span! ( tracing ::Level ::DEBUG , " Checking parent exit. " ) ;
2023-08-10 20:04:59 -04:00
#[ cfg(feature = " tracing " ) ]
2023-07-14 17:37:46 -04:00
let _enter = span . enter ( ) ;
if exit_matcher_parser ( context , remaining ) . is_ok ( ) {
2023-10-17 10:09:37 -04:00
return Err ( nom ::Err ::Error ( CustomError ::Static (
2023-10-16 17:03:16 -04:00
" Parent exit matcher is triggering. " ,
2023-10-17 10:09:37 -04:00
) ) ) ;
2023-07-14 17:37:46 -04:00
}
}
2023-12-08 15:51:38 -05:00
let contents_end = remaining ;
let contents = contents_begin . get_until ( contents_end ) ;
2023-07-14 17:37:46 -04:00
let ( remaining , _close ) = text_markup_end_specialized ( context , remaining ) ? ;
2023-12-08 15:51:38 -05:00
let ( remaining , post_blank ) = opt ( space1 ) ( remaining ) ? ;
Ok ( ( remaining , ( contents , children , post_blank ) ) )
2023-07-14 17:37:46 -04:00
}