@@ -283,15 +283,12 @@ impl<'i> Parser<'i> {
283283 . push ( error) ;
284284 }
285285 }
286- } else if self
287- . source
288- . contains ( ':' )
289- {
286+ } else if potential_procedure_declaration ( self . source ) {
290287 // It might be that we've encountered a malformed procedure
291288 // declaration, so we try parsing it anyway to get a more
292289 // specific error message.
293290 match self . take_block_lines (
294- |_| true , // Accept the line regardless
291+ potential_procedure_declaration ,
295292 |line| is_section ( line) || potential_procedure_declaration ( line) ,
296293 |inner| inner. read_procedure ( ) ,
297294 ) {
@@ -2580,24 +2577,37 @@ fn is_procedure_declaration(content: &str) -> bool {
25802577/// reporting what turns out to be a better error.
25812578fn potential_procedure_declaration ( content : & str ) -> bool {
25822579 match content. split_once ( ':' ) {
2583- Some ( ( before, _after ) ) => {
2580+ Some ( ( before, after ) ) => {
25842581 let before = before. trim_ascii ( ) ;
2585- // Check if it looks like an identifier (possibly with parameters)
2586- // Accept any single token that could be an attempted identifier
2587- if let Some ( ( name, params) ) = before. split_once ( '(' ) {
2588- // Has parameters: check if params end with ')'
2589- !name
2582+
2583+ // Empty before colon -> only a declaration if there's something after
2584+ if before. is_empty ( ) {
2585+ return !after
25902586 . trim_ascii ( )
2591- . is_empty ( )
2592- && params. ends_with ( ')' )
2593- } else {
2594- // No parameters: must be a single token (no spaces) that
2595- // looks identifier-ish This excludes sentences like "Ask
2596- // these questions: ..."
2597- !before. is_empty ( ) &&
2598- !before. contains ( ' ' ) && // Single token only
2599- before. chars ( ) . all ( |c| c. is_ascii_alphanumeric ( ) || c == '_' )
2587+ . is_empty ( ) ;
26002588 }
2589+
2590+ // Has parentheses -> likely trying to be a procedure with parameters
2591+ if before. contains ( '(' ) {
2592+ return true ;
2593+ }
2594+
2595+ // Check if it looks like prose vs an identifier attempt
2596+ // Prose typically: starts with capital, has multiple space-separated words
2597+ // Identifiers: lowercase, possibly with underscores
2598+ let first_char = before
2599+ . chars ( )
2600+ . next ( )
2601+ . unwrap ( ) ;
2602+ let has_spaces = before. contains ( ' ' ) ;
2603+
2604+ // If it starts with uppercase AND has spaces, it's probably prose
2605+ if first_char. is_uppercase ( ) && has_spaces {
2606+ return false ;
2607+ }
2608+
2609+ // Otherwise, could be a procedure declaration attempt
2610+ true
26012611 }
26022612 None => false ,
26032613 }
0 commit comments