diff --git a/CHANGES.md b/CHANGES.md index 6cd9e2d7..000ebb37 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,10 @@ This file describes changes in the AutoDoc package. `...` for GAP keywords (as returned by `ALL_KEYWORDS()`), otherwise as before `...` - Allow XML-style comments in `.autodoc` files + - Ignore trailing blank lines after single-line worksheet title-page + commands such as `@Title`, `@Subtitle`, `@Version`, `@Author`, and + `@Date`, and trim trailing blank lines from generated title-page + content so they no longer leak into filenames or empty author entries - Greatly improve the package manual. - Convert the hand-written manual chapters from XML to `.autodoc` - Fix an unexpected and confusing error when mixing explicit diff --git a/gap/AutoDocMainFunction.gi b/gap/AutoDocMainFunction.gi index 62eedc2b..f6c3392b 100644 --- a/gap/AutoDocMainFunction.gi +++ b/gap/AutoDocMainFunction.gi @@ -224,7 +224,7 @@ end ); InstallGlobalFunction( CreateTitlePage, function( dir, argument_rec ) local indent, tag, names, filestream, entity_list, OutWithTag, Out, i, - parsed_date; + parsed_date, NormalizeTitlePageContent; filestream := AUTODOC_OutputTextFile( dir, "title.xml" ); indent := 0; @@ -255,19 +255,42 @@ InstallGlobalFunction( CreateTitlePage, AppendTo( filestream, s, "\n" ); end; + # Parser state can leave title-page fields as a list of lines. Normalize + # them here so trailing blank lines do not leak into output or filenames, + # while still preserving intentional internal line breaks for multiline fields. + NormalizeTitlePageContent := function( content ) + local normalized; + + if IsString( content ) then + content := [ content ]; + fi; + normalized := List( content, line -> StripBeginEnd( line, "\n\r" ) ); + while Length( normalized ) > 0 and + IsString( normalized[ Length( normalized ) ] ) and + StripBeginEnd( normalized[ Length( normalized ) ], " \t\r\n" ) = "" do + Remove( normalized ); + od; + if Length( normalized ) = 1 then + return normalized[ 1 ]; + fi; + return normalized; + end; + Out( AUTODOC_XML_HEADER ); Out( "\n" ); indent := indent + 1; for i in [ "Title", "Subtitle", "Version", "TitleComment" ] do if IsBound( argument_rec.( i ) ) then - OutWithTag( i, argument_rec.( i ) ); + OutWithTag( i, NormalizeTitlePageContent( argument_rec.( i ) ) ); fi; od; if IsBound( argument_rec.Author ) then - for i in argument_rec.Author do - OutWithTag( "Author", i ); + for i in List( argument_rec.Author, NormalizeTitlePageContent ) do + if not IsString( i ) or StripBeginEnd( i, " \t\r\n" ) <> "" then + OutWithTag( "Author", i ); + fi; od; fi; @@ -282,12 +305,12 @@ InstallGlobalFunction( CreateTitlePage, argument_rec.Date := AUTODOC_FormatDate( parsed_date ); fi; fi; - OutWithTag( "Date", argument_rec.Date ); + OutWithTag( "Date", NormalizeTitlePageContent( argument_rec.Date ) ); fi; for i in [ "Address", "Abstract", "Copyright", "Acknowledgements", "Colophon" ] do if IsBound( argument_rec.( i ) ) then - OutWithTag( i, StripBeginEnd( argument_rec.( i ), "\n\r" ) ); + OutWithTag( i, NormalizeTitlePageContent( argument_rec.( i ) ) ); fi; od; diff --git a/gap/Parser.gi b/gap/Parser.gi index 74defcce..e387b537 100644 --- a/gap/Parser.gi +++ b/gap/Parser.gi @@ -218,6 +218,7 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles, scope_group, read_example, command_function_record, autodoc_read_line, current_command, filename, groupnumber, rest_of_file_skipped, context_stack, new_man_item, add_man_item, Reset, read_code, title_item, title_item_list, plain_text_mode, + single_line_title_item_list, active_title_item_name, active_title_item_is_multiline, current_line_unedited, current_line_info, NormalizeInputLine, ReadLineWithLineCount, Normalized_ReadLine, line_number, ErrorWithPos, create_title_item_function, current_line_positition_for_filter, read_session_example, DeclarationDelimiterPosition, @@ -231,6 +232,8 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles, context_stack := [ ]; chapter_info := [ ]; line_number := 0; + active_title_item_name := fail; + active_title_item_is_multiline := false; ReadLineWithLineCount := function( stream ) line_number := line_number + 1; @@ -964,6 +967,10 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles, if not IsBound( current_item ) then return; fi; + if active_title_item_name <> fail and + active_title_item_is_multiline = false then + return; + fi; Add( current_item, current_command[ 2 ] ); end, @BeginLatexOnly := function() @@ -1022,13 +1029,17 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles, ## information directly into the document. title_item_list := [ "Title", "Subtitle", "Version", "TitleComment", "Author", "Date", "Address", "Abstract", "Copyright", "Acknowledgements", "Colophon" ]; - + single_line_title_item_list := [ "Title", "Subtitle", "Version", "Author", "Date" ]; + create_title_item_function := function( name ) return function() if not IsBound( tree!.TitlePage.( name ) ) then tree!.TitlePage.( name ) := [ ]; fi; current_item := tree!.TitlePage.( name ); + active_title_item_name := name; + active_title_item_is_multiline := + Position( single_line_title_item_list, name ) = fail; Add( current_item, current_command[ 2 ] ); end; end; @@ -1116,6 +1127,11 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles, fi; if current_command[ 1 ] <> false then autodoc_read_line := current_line_info.allows_declaration_scan; + if Position( title_item_list, current_command[ 1 ]{ [ 2 .. Length( current_command[ 1 ] ) ] } ) = fail and + current_command[ 1 ] <> "STRING" then + active_title_item_name := fail; + active_title_item_is_multiline := false; + fi; if not IsBound( command_function_record.(current_command[ 1 ]) ) then ErrorWithPos("unknown AutoDoc command ", current_command[ 1 ]); fi; diff --git a/tst/worksheets/paired-titlepage-autoplain.sheet/plain.autodoc b/tst/worksheets/paired-titlepage-autoplain.sheet/plain.autodoc index 50c1b7f7..e4ac1691 100644 --- a/tst/worksheets/paired-titlepage-autoplain.sheet/plain.autodoc +++ b/tst/worksheets/paired-titlepage-autoplain.sheet/plain.autodoc @@ -1,13 +1,23 @@ @Title Paired Titlepage Test + @Subtitle Comment mode title coverage + @Version 2.0 + @TitleComment Internal worksheet fixture + @Author Ada Example + @Date 2026-03-07 + @Address Example Street 7 + @Abstract This worksheet exercises title-page commands in plain-text mode. + @Copyright 2026 Example Authors + @Acknowledgements Thanks to the worksheet harness. + @Colophon Generated for AutoDoc regression coverage. @Chapter Titlepage Chapter @Section Titlepage Section