2023-04-23 01:45:18 +00:00
use nom ::branch ::alt ;
use nom ::combinator ::map ;
2023-04-21 23:02:16 +00:00
use super ::clock ::clock ;
2023-04-21 20:10:56 +00:00
use super ::comment ::comment ;
2023-09-11 16:28:15 +00:00
use super ::comment ::detect_comment ;
use super ::diary_sexp ::detect_diary_sexp ;
2023-04-22 00:22:31 +00:00
use super ::diary_sexp ::diary_sexp ;
2023-04-21 20:10:56 +00:00
use super ::drawer ::drawer ;
use super ::dynamic_block ::dynamic_block ;
2023-09-11 16:28:15 +00:00
use super ::fixed_width_area ::detect_fixed_width_area ;
2023-04-22 02:04:22 +00:00
use super ::fixed_width_area ::fixed_width_area ;
2023-09-11 16:28:15 +00:00
use super ::footnote_definition ::detect_footnote_definition ;
2023-04-21 20:10:56 +00:00
use super ::footnote_definition ::footnote_definition ;
use super ::greater_block ::greater_block ;
2023-04-22 02:23:59 +00:00
use super ::horizontal_rule ::horizontal_rule ;
2023-08-29 20:56:07 +00:00
use super ::keyword ::affiliated_keyword ;
2023-09-06 22:04:53 +00:00
use super ::keyword ::babel_call_keyword ;
2023-04-22 02:33:10 +00:00
use super ::keyword ::keyword ;
2023-04-22 20:56:36 +00:00
use super ::latex_environment ::latex_environment ;
2023-04-21 21:40:49 +00:00
use super ::lesser_block ::comment_block ;
use super ::lesser_block ::example_block ;
use super ::lesser_block ::export_block ;
use super ::lesser_block ::src_block ;
use super ::lesser_block ::verse_block ;
2023-08-23 04:30:26 +00:00
use super ::org_source ::OrgSource ;
2023-04-21 20:10:56 +00:00
use super ::paragraph ::paragraph ;
2023-08-25 04:48:34 +00:00
use super ::plain_list ::detect_plain_list ;
2023-04-21 20:10:56 +00:00
use super ::plain_list ::plain_list ;
2023-09-11 16:28:15 +00:00
use super ::table ::detect_table ;
2023-04-22 03:54:54 +00:00
use super ::util ::get_consumed ;
use super ::util ::maybe_consume_trailing_whitespace_if_not_exiting ;
2023-09-03 16:23:18 +00:00
use crate ::context ::parser_with_context ;
use crate ::context ::RefContext ;
2023-08-25 04:48:34 +00:00
use crate ::error ::CustomError ;
use crate ::error ::MyError ;
2023-04-21 22:36:01 +00:00
use crate ::error ::Res ;
2023-04-21 20:10:56 +00:00
use crate ::parser ::table ::org_mode_table ;
2023-09-03 16:23:18 +00:00
use crate ::types ::Element ;
use crate ::types ::SetSource ;
2023-04-21 20:10:56 +00:00
2023-09-11 17:13:28 +00:00
pub ( crate ) const fn element (
2023-04-22 04:55:31 +00:00
can_be_paragraph : bool ,
2023-09-03 19:44:18 +00:00
) -> impl for < ' b , ' g , ' r , ' s > Fn (
RefContext < ' b , ' g , ' r , ' s > ,
OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Element < ' s > > {
2023-09-03 16:23:18 +00:00
move | context , input : OrgSource < '_ > | _element ( context , input , can_be_paragraph )
2023-04-22 23:15:29 +00:00
}
2023-08-11 00:04:59 +00:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-09-03 19:44:18 +00:00
fn _element < ' b , ' g , ' r , ' s > (
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-23 04:30:26 +00:00
input : OrgSource < ' s > ,
2023-04-22 23:15:29 +00:00
can_be_paragraph : bool ,
2023-08-23 04:30:26 +00:00
) -> Res < OrgSource < ' s > , Element < ' s > > {
2023-04-22 23:15:29 +00:00
let plain_list_matcher = parser_with_context! ( plain_list ) ( context ) ;
let greater_block_matcher = parser_with_context! ( greater_block ) ( context ) ;
let dynamic_block_matcher = parser_with_context! ( dynamic_block ) ( context ) ;
let footnote_definition_matcher = parser_with_context! ( footnote_definition ) ( context ) ;
let comment_matcher = parser_with_context! ( comment ) ( context ) ;
let drawer_matcher = parser_with_context! ( drawer ) ( context ) ;
let table_matcher = parser_with_context! ( org_mode_table ) ( context ) ;
let verse_block_matcher = parser_with_context! ( verse_block ) ( context ) ;
let comment_block_matcher = parser_with_context! ( comment_block ) ( context ) ;
let example_block_matcher = parser_with_context! ( example_block ) ( context ) ;
let export_block_matcher = parser_with_context! ( export_block ) ( context ) ;
let src_block_matcher = parser_with_context! ( src_block ) ( context ) ;
let clock_matcher = parser_with_context! ( clock ) ( context ) ;
let diary_sexp_matcher = parser_with_context! ( diary_sexp ) ( context ) ;
let fixed_width_area_matcher = parser_with_context! ( fixed_width_area ) ( context ) ;
let horizontal_rule_matcher = parser_with_context! ( horizontal_rule ) ( context ) ;
let keyword_matcher = parser_with_context! ( keyword ) ( context ) ;
2023-08-29 20:56:07 +00:00
let affiliated_keyword_matcher = parser_with_context! ( affiliated_keyword ) ( context ) ;
2023-09-06 22:04:53 +00:00
let babel_keyword_matcher = parser_with_context! ( babel_call_keyword ) ( context ) ;
2023-04-22 23:15:29 +00:00
let paragraph_matcher = parser_with_context! ( paragraph ) ( context ) ;
let latex_environment_matcher = parser_with_context! ( latex_environment ) ( context ) ;
2023-04-22 20:56:36 +00:00
2023-04-22 23:15:29 +00:00
let ( remaining , mut element ) = match alt ( (
map ( plain_list_matcher , Element ::PlainList ) ,
2023-10-03 02:21:24 +00:00
greater_block_matcher ,
2023-04-22 23:15:29 +00:00
map ( dynamic_block_matcher , Element ::DynamicBlock ) ,
map ( footnote_definition_matcher , Element ::FootnoteDefinition ) ,
map ( comment_matcher , Element ::Comment ) ,
map ( drawer_matcher , Element ::Drawer ) ,
map ( table_matcher , Element ::Table ) ,
map ( verse_block_matcher , Element ::VerseBlock ) ,
map ( comment_block_matcher , Element ::CommentBlock ) ,
map ( example_block_matcher , Element ::ExampleBlock ) ,
map ( export_block_matcher , Element ::ExportBlock ) ,
map ( src_block_matcher , Element ::SrcBlock ) ,
map ( clock_matcher , Element ::Clock ) ,
map ( diary_sexp_matcher , Element ::DiarySexp ) ,
map ( fixed_width_area_matcher , Element ::FixedWidthArea ) ,
map ( horizontal_rule_matcher , Element ::HorizontalRule ) ,
map ( latex_environment_matcher , Element ::LatexEnvironment ) ,
2023-09-06 22:04:53 +00:00
map ( babel_keyword_matcher , Element ::BabelCall ) ,
2023-10-05 00:01:09 +00:00
map ( keyword_matcher , Element ::Keyword ) ,
) ) ( input )
2023-04-22 23:15:29 +00:00
{
the_ok @ Ok ( _ ) = > the_ok ,
Err ( _ ) = > {
if can_be_paragraph {
2023-10-05 00:01:09 +00:00
match map ( paragraph_matcher , Element ::Paragraph ) ( input ) {
2023-04-22 23:15:29 +00:00
the_ok @ Ok ( _ ) = > the_ok ,
Err ( _ ) = > {
2023-09-24 05:59:26 +00:00
// TODO: Because this function expects a single element, if there are multiple affiliated keywords before an element that cannot have affiliated keywords, we end up re-parsing the affiliated keywords many times.
2023-08-29 21:19:13 +00:00
map ( affiliated_keyword_matcher , Element ::Keyword ) ( input )
2023-04-22 05:34:34 +00:00
}
}
2023-04-22 23:15:29 +00:00
} else {
2023-08-29 21:19:13 +00:00
map ( affiliated_keyword_matcher , Element ::Keyword ) ( input )
2023-04-22 04:55:31 +00:00
}
2023-04-22 23:15:29 +00:00
}
} ? ;
2023-04-21 20:10:56 +00:00
2023-04-22 23:15:29 +00:00
let ( remaining , _trailing_ws ) =
maybe_consume_trailing_whitespace_if_not_exiting ( context , remaining ) ? ;
2023-04-22 03:54:54 +00:00
2023-04-22 23:15:29 +00:00
let source = get_consumed ( input , remaining ) ;
2023-08-23 04:30:26 +00:00
element . set_source ( source . into ( ) ) ;
2023-04-22 03:54:54 +00:00
2023-04-22 23:15:29 +00:00
Ok ( ( remaining , element ) )
2023-04-21 20:10:56 +00:00
}
2023-08-25 04:48:34 +00:00
2023-09-11 17:13:28 +00:00
pub ( crate ) const fn detect_element (
2023-08-25 04:48:34 +00:00
can_be_paragraph : bool ,
2023-09-03 19:44:18 +00:00
) -> impl for < ' b , ' g , ' r , ' s > Fn ( RefContext < ' b , ' g , ' r , ' s > , OrgSource < ' s > ) -> Res < OrgSource < ' s > , ( ) >
{
2023-09-03 16:23:18 +00:00
move | context , input : OrgSource < '_ > | _detect_element ( context , input , can_be_paragraph )
2023-08-25 04:48:34 +00:00
}
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-09-03 19:44:18 +00:00
fn _detect_element < ' b , ' g , ' r , ' s > (
context : RefContext < ' b , ' g , ' r , ' s > ,
2023-08-25 04:48:34 +00:00
input : OrgSource < ' s > ,
can_be_paragraph : bool ,
) -> Res < OrgSource < ' s > , ( ) > {
2023-10-05 00:01:09 +00:00
// TODO: What about affiliated keywords in the detect_* functions?
2023-09-11 16:28:15 +00:00
if alt ( (
2023-09-14 04:27:54 +00:00
parser_with_context! ( detect_plain_list ) ( context ) ,
2023-09-11 16:28:15 +00:00
detect_footnote_definition ,
detect_diary_sexp ,
detect_comment ,
detect_fixed_width_area ,
detect_table ,
) ) ( input )
. is_ok ( )
{
2023-08-25 04:48:34 +00:00
return Ok ( ( input , ( ) ) ) ;
}
if _element ( context , input , can_be_paragraph ) . is_ok ( ) {
return Ok ( ( input , ( ) ) ) ;
}
return Err ( nom ::Err ::Error ( CustomError ::MyError ( MyError (
" No element detected. " . into ( ) ,
) ) ) ) ;
}