diff --git a/doc/Comments.xml b/doc/Comments.xml
index 5d738e54..79f48656 100644
--- a/doc/Comments.xml
+++ b/doc/Comments.xml
@@ -302,6 +302,25 @@ DeclareOperation( "GroupedOperation",
]]>
+
+@GroupTitle
+@GroupTitle title
+Sets the subsection heading for the current group to title. In the
+absence of any @GroupTitle command, the heading will be the name of the
+first entry in the group. See for more information.
+
+
+
+@GroupInitialArguments
+@GroupInitialArguments args
+Sets the common initial arguments for the entries in the current group to be
+args. The argument list for any function subsequently added to the
+group without any args specified will be args, and args will be
+prepended to any arguments specified for a particular function. The setting is
+cleared by an @EndGroup command. See for more
+information.
+
+
@Level
@Level lvl
@@ -556,8 +575,9 @@ a function, operation, etc., it is possible to group them into suitable chunks.
This can be particularly useful if there are several definitions of an operation
with several different argument types, all doing more or less the same to the arguments.
Then their manual items can be grouped, sharing the same description and return type information.
-Note that it is currently not possible to give a header to the Group in the manual,
-but the generated ManItem heading of the first entry will be used.
+You can give a heading to the Group in the manual with the @GroupTitle
+command; if that is not supplied, then the generated ManItem heading of the
+first entry will be used as the heading.
Note that group names are globally unique throughout the whole manual.
@@ -570,9 +590,19 @@ same group name, in different places, and these all will refer to the same group
Moreover, this means that you can add items to a group via the @Group command
in the &AutoDoc; comment of an arbitrary declaration, at any time.
+
+Since often the functions in a Group share common initial arguments, you can
+set a list of common arguments to be prepended to all declarations within a
+given @BeginGroup/@EndGroup pair with the @GroupInitialArguments
+command.
+
+
+
The following code
-
-
+ A family of operations
+
+
diff --git a/gap/DocumentationTree.gi b/gap/DocumentationTree.gi
index 30ed3337..69febebc 100644
--- a/gap/DocumentationTree.gi
+++ b/gap/DocumentationTree.gi
@@ -623,10 +623,15 @@ end );
##
InstallMethod( WriteDocumentation, [ IsTreeForDocumentationNodeForGroupRep, IsStream ],
function( node, filestream )
+ local head;
if node!.level > ValueOption( "level_value" ) then
return;
fi;
- AutoDoc_WriteDocEntry( filestream, node!.content );
+ head := fail;
+ if IsBound( node!.title_string ) then
+ head := node!.title_string;
+ fi;
+ AutoDoc_WriteDocEntry( filestream, node!.content, head );
end );
##
diff --git a/gap/Parser.gi b/gap/Parser.gi
index 5ea1fc50..b8306427 100644
--- a/gap/Parser.gi
+++ b/gap/Parser.gi
@@ -77,7 +77,11 @@ InstallGlobalFunction( AutoDoc_Type_Of_Item,
entries := [ "Func", "global_functions" ];
has_filters := "No";
if not IsBound( item_rec!.arguments ) then
- item_rec!.arguments := "arg";
+ if IsBound( item_rec!.initial_args ) then
+ item_rec!.arguments := item_rec!.initial_args;
+ else
+ item_rec!.arguments := "arg";
+ fi;
fi;
elif PositionSublist( type, "DeclareGlobalVariable" ) <> fail then
entries := [ "Var", "global_variables" ];
@@ -116,7 +120,7 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles,
function( filename_list, tree, default_chapter_data )
local current_item, flush_and_recover, chapter_info, current_string_list,
Scan_for_Declaration_part, flush_and_prepare_for_item, current_line, filestream,
- level_scope, scope_group, read_example, command_function_record, autodoc_read_line,
+ level_scope, scope_group, scope_initial_args, read_example, command_function_record, autodoc_read_line,
current_command, was_declaration, filename, system_scope, groupnumber, chunk_list, rest_of_file_skipped,
context_stack, new_man_item, add_man_item, Reset, read_code, title_item, title_item_list, plain_text_mode,
current_line_unedited,
@@ -159,6 +163,9 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles,
if IsBound( scope_group ) then
SetGroupName( man_item, scope_group );
fi;
+ if IsBound( scope_initial_args ) then
+ man_item!.initial_args := scope_initial_args;
+ fi;
man_item!.chapter_info := ShallowCopy( chapter_info );
man_item!.tester_names := fail;
return man_item;
@@ -267,7 +274,10 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles,
##Adjust arguments
if not IsBound( current_item!.arguments ) then
if IsInt( has_filters ) then
- if has_filters = 1 then
+ if IsBound( current_item!.initial_args ) then
+ current_item!.arguments :=
+ current_item!.initial_args;
+ elif has_filters = 1 then
current_item!.arguments := "arg";
else
current_item!.arguments := JoinStringsWithSeparator( List( [ 1 .. has_filters ], i -> Concatenation( "arg", String( i ) ) ), "," );
@@ -561,8 +571,14 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles,
fi;
scope_group := ReplacedString( current_command[ 2 ], " ", "_" );
end,
+ @GroupInitialArguments := function()
+ scope_initial_args := current_command[ 2 ];
+ current_item := new_man_item();
+ current_item!.initial_args := current_command[ 2 ];
+ end,
@EndGroup := function()
Unbind( scope_group );
+ Unbind( scope_initial_args );
end,
@Description := function()
current_item := new_man_item();
@@ -580,8 +596,16 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles,
fi;
end,
@Arguments := function()
+ local composed_arguments;
+ if IsBound( scope_initial_args ) and
+ Length( scope_initial_args ) > 0 then
+ composed_arguments :=
+ Concatenation( scope_initial_args, ", ", current_command[ 2 ] );
+ else
+ composed_arguments := current_command[ 2 ];
+ fi;
current_item := new_man_item();
- current_item!.arguments := current_command[ 2 ];
+ current_item!.arguments := composed_arguments;
end,
@Label := function()
current_item := new_man_item();
@@ -593,6 +617,28 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles,
group_name := ReplacedString( current_command[ 2 ], " ", "_" );
SetGroupName( current_item, group_name );
end,
+ @GroupTitle := function()
+ local group_name, chap_info, group_obj;
+ current_item := new_man_item();
+ if not HasGroupName( current_item ) then
+ ErrorWithPos( "found @GroupTitle with no Group set" );
+ fi;
+ group_name := GroupName( current_item );
+ chap_info := fail;
+ if HasChapterInfo( current_item ) then
+ chap_info := ChapterInfo( current_item );
+ elif IsBound( current_item!.chapter_info ) then
+ chap_info := current_item!.chapter_info;
+ fi;
+ if (chap_info = fail or chap_info = [ ]) then
+ chap_info := chapter_info;
+ fi;
+ if Length( chap_info ) <> 2 then
+ ErrorWithPos( "can only set @GroupTitle within a Chapter and Section.");
+ fi;
+ group_obj := DocumentationGroup( tree, group_name, chap_info );
+ group_obj!.title_string := current_command[ 2 ];
+ end,
@ChapterInfo := function()
local current_chapter_info;
current_item := new_man_item();
diff --git a/gap/ToolFunctions.gi b/gap/ToolFunctions.gi
index 5f35582f..0f9055f6 100644
--- a/gap/ToolFunctions.gi
+++ b/gap/ToolFunctions.gi
@@ -25,7 +25,7 @@ end );
##
InstallGlobalFunction( AutoDoc_WriteDocEntry,
- function( filestream, list_of_records )
+ function( filestream, list_of_records, maybe_heading... )
local return_value, description, current_description, labels, i;
# look for a good return value (it should be the same everywhere)
@@ -78,7 +78,15 @@ InstallGlobalFunction( AutoDoc_WriteDocEntry,
od;
AppendTo( filestream, ">\n" );
- # Function heades
+ # Next possibly the heading for the entry
+ if Length( maybe_heading ) > 0 then
+ maybe_heading := maybe_heading[ 1 ];
+ if IsString( maybe_heading ) then
+ AppendTo( filestream, "", maybe_heading, "\n" );
+ fi;
+ fi;
+
+ # Function headers
for i in list_of_records do
AppendTo( filestream, " <", i!.item_type, " " );
if i!.arguments <> fail and i!.item_type <> "Var" then