diff --git a/CHANGES.md b/CHANGES.md index 583df9e4..1511fd05 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -65,6 +65,8 @@ This file describes changes in the AutoDoc package. but in recent versions was restricted to dates of the form YYYY-MM-DD or DD/MM/YYYY; now we again allow any text, but text in those specific formats is still parsed and formatted (e.g. 2026-03-08 as 8 March 2026) + - Require `@BeginExample`, `@BeginLog`, `@BeginExampleSession`, and + `@BeginLogSession` blocks to use their matching `@End...` markers - Improve parser robustness by reporting clear EOF errors for unterminated declaration headers and filter lists - Make tests work when the package directory is read-only by writing diff --git a/gap/Parser.gi b/gap/Parser.gi index 2c08bfde..7306e2f3 100644 --- a/gap/Parser.gi +++ b/gap/Parser.gi @@ -725,14 +725,14 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles, end; ReadExample := function( element_name ) local temp_string_list, temp_curr_line, temp_pos_comment, is_following_line, - item_temp, example_node; + item_temp, example_node, end_command; example_node := DocumentationExample( element_name ); temp_string_list := example_node!.content; + end_command := Concatenation( "@End", element_name ); is_following_line := false; while true do temp_curr_line := Chomp( ReadLineWithLineCount( filestream ) ); - if PositionSublist( temp_curr_line, "@EndExample" ) <> fail or - PositionSublist( temp_curr_line, "@EndLog" ) <> fail then + if PositionSublist( temp_curr_line, end_command ) <> fail then break; fi; ##if is comment, simply remove comments. @@ -764,13 +764,13 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles, ReadSessionExample := function( element_name, plain_text_mode ) local temp_string_list, temp_curr_line, temp_pos_comment, is_following_line, item_temp, example_node, - incorporate_this_line; + incorporate_this_line, end_command; example_node := DocumentationExample( element_name ); temp_string_list := example_node!.content; + end_command := Concatenation( "@End", element_name, "Session" ); while true do temp_curr_line := Chomp( ReadLineWithLineCount( filestream ) ); - if PositionSublist( temp_curr_line, "@EndExampleSession" ) <> fail or - PositionSublist( temp_curr_line, "@EndLogSession" ) <> fail then + if PositionSublist( temp_curr_line, end_command ) <> fail then break; fi; incorporate_this_line := plain_text_mode; diff --git a/tst/misc.tst b/tst/misc.tst index f0ab7ee7..55657804 100644 --- a/tst/misc.tst +++ b/tst/misc.tst @@ -364,5 +364,44 @@ gap> item!.description; gap> RemoveDirectoryRecursively(tmpdir); true +# +# example and log blocks require matching end markers +# +gap> tmpdir := Filename(DirectoryTemporary(), "autodoc-example-end-marker-test");; +gap> if IsDirectoryPath(tmpdir) then RemoveDirectoryRecursively(tmpdir); fi; +gap> AUTODOC_CreateDirIfMissing(tmpdir); +true +gap> tmpdir_obj := Directory(tmpdir);; +gap> file1 := Filename(tmpdir_obj, "example-end-markers.gd");; +gap> stream := OutputTextFile(file1, false);; +gap> AppendTo(stream, "#! @Chapter Parser\n");; +gap> AppendTo(stream, "#! @Section End Markers\n");; +gap> AppendTo(stream, "#! @BeginExample\n");; +gap> AppendTo(stream, "1 + 1;\n");; +gap> AppendTo(stream, "#! @EndLog\n");; +gap> AppendTo(stream, "#! still example output\n");; +gap> AppendTo(stream, "#! @EndExample\n");; +gap> AppendTo(stream, "#! @BeginExampleSession\n");; +gap> AppendTo(stream, "#! gap> 2 + 2;\n");; +gap> AppendTo(stream, "#! @EndLogSession\n");; +gap> AppendTo(stream, "#! 4\n");; +gap> AppendTo(stream, "#! @EndExampleSession\n");; +gap> CloseStream(stream); +gap> tree7 := DocumentationTree();; +gap> AutoDoc_Parser_ReadFiles([file1], tree7, rec()); +gap> section := SectionInTree(tree7, "Parser", "End_Markers");; +gap> example := section!.content[1];; +gap> example!.element_name; +"Example" +gap> example!.content; +[ "gap> 1 + 1;", "@EndLog", "still example output" ] +gap> session_example := section!.content[2];; +gap> session_example!.element_name; +"Example" +gap> session_example!.content; +[ "gap> 2 + 2;", "@EndLogSession", "4" ] +gap> RemoveDirectoryRecursively(tmpdir); +true + # gap> STOP_TEST( "misc.tst" );