Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ This file describes changes in the AutoDoc package.
- Only document the first declaration immediately following an AutoDoc
source comment block; later consecutive declarations now require their
own `#!` comment block
- When documenting an `InstallMethod`, we now use the item type `Meth`
instead of `Oper`

+ **New Features**
- Add `nopdf` as a global option, and document the existing `NOPDF`
Expand All @@ -19,6 +21,8 @@ This file describes changes in the AutoDoc package.
`@Chapter`/`@Section`/`@Subsection` in `.autodoc` files and doc comments
- Add support for documenting `DeclareSynonym` and
`DeclareSynonymAttr` declarations
- Add `@ItemType` to override the type of a declaration, which is
especially useful for `DeclareSynonym` or `DeclareGlobalName`
- Add fenced code blocks using triple backticks or tildes in
Markdown-like text; `@listing`, `@example`, and `@log` info strings
select the corresponding GAPDoc element
Expand All @@ -31,6 +35,9 @@ This file describes changes in the AutoDoc package.
nested source directories are picked up automatically

+ **Other Changes**
- Improve `DeclareGlobalName` handling: document it as a variable by
default, but switch to a function when `@Arguments` or `@Returns`
provides function-style documentation
- 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
Expand All @@ -53,12 +60,7 @@ This file describes changes in the AutoDoc package.
`@Command` does not start at column 1
- Normalize parsed `InstallMethod` names by stripping surrounding
quotes, matching `Declare...` handling
- Document `InstallMethod` support in declaration comments and add
`@ItemType` to override whether an installed method should be
documented as `Func`, `Oper`, `Attr`, or `Prop`
- Improve `DeclareGlobalName` handling: document it as a variable by
default, but switch to a function when `@Arguments` or `@Returns`
provides function-style documentation
- Document `InstallMethod` support in declaration comments
- Loosen requirements on `@Date` command: this used to allow free form,
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
Expand Down
34 changes: 18 additions & 16 deletions doc/Comments.autodoc
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,19 @@ function or a variable.

@Index "@ItemType" <C>@ItemType <A>kind</A></C>
Overrides the kind of manual item created for the following declaration or
installed method. The supported values are <C>Attr</C>, <C>Filt</C>,
<C>Func</C>, <C>Oper</C>, <C>Prop</C>, and <C>Var</C>.
installed method. The supported values are <C>Attr</C>, <C>Cat</C>,
<C>Coll</C>, <C>Constr</C>, <C>Fam</C>, <C>Filt</C>, <C>Func</C>,
<C>InfoClass</C>, <C>Meth</C>, <C>Oper</C>, <C>Prop</C>, <C>Repr</C>,
and <C>Var</C>.

This is mainly useful for <C>InstallMethod</C>, <C>DeclareGlobalName</C>, and
<C>DeclareSynonym</C>. For other declarations such as <C>DeclareAttribute</C>
or <C>DeclareProperty</C>, &AutoDoc; already knows the correct item type from
the declaration itself.
The values <C>Cat</C>, <C>Coll</C>, and <C>Repr</C> are &AutoDoc;-specific
aliases. They emit <C>Filt</C> entries with the corresponding &GAPDoc; filter
type.

But for <C>InstallMethod</C>, especially with one argument, the source code
alone does not reliably tell whether the method belongs to an operation, an
attribute, a property, or even a plain function. Without an override, such
entries default to <C>Oper</C>.
This is useful when the source code alone does not determine which manual item
kind should be emitted. For many declarations such as <C>DeclareAttribute</C>
or <C>DeclareProperty</C>, &AutoDoc; already knows the intended type from the
declaration itself.

It is useful for <C>DeclareGlobalName</C>, because that declaration can
refer to either a function or a variable. &AutoDoc; defaults such entries to
Expand All @@ -110,18 +111,19 @@ refer to either a function or a variable. &AutoDoc; defaults such entries to
<C>@ItemType</C> to override this explicitly.

It is useful for <C>DeclareSynonym</C>, because that declaration can
document a function synonym or a filter synonym. Use <C>@ItemType Filt</C> if
the synonym should be emitted as a filter-style manual entry.
document a function synonym or one of several filter-like synonyms. Use
<C>@ItemType Filt</C>, <C>Cat</C>, <C>Coll</C>, or <C>Repr</C> to control which
kind of filter entry should be emitted.

For example:

```@listing
#! @ItemType Attr
InstallMethod( SomeAttribute, [ IsGroup ], G -> G );
#! @ItemType Repr
DeclareSynonym( "IsSomethingRep", IsComponentObjectRep );
```

This makes &AutoDoc; emit an <C>&lt;Attr .../&gt;</C> manual entry instead of
the default <C>&lt;Oper .../&gt;</C>.
This makes &AutoDoc; emit a
<C>&lt;Filt Type="Representation" .../&gt;</C> manual entry.

@Subsection <C>@Group <A>grpname</A></C>
@SubsectionLabel @Group
Expand Down
8 changes: 6 additions & 2 deletions gap/AutoDocMainFunction.gi
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ InstallGlobalFunction( CreateDefaultChapterData,

chapter_name := Concatenation( pkgname, "_automatic_generated_documentation" );
default_chapter_record := rec();
list_of_types := [ "categories", "methods", "attributes", "properties",
"global_functions", "global_variables", "info_classes" ];
list_of_types := Set(
List(
RecNames( AUTODOC_ITEM_TYPE_INFO ),
n -> AUTODOC_ITEM_TYPE_INFO.( n ).chapter_bucket
)
);

for i in list_of_types do
default_chapter_record.(i) := [ chapter_name, Concatenation( chapter_name, "_of_", i ) ];
Expand Down
2 changes: 2 additions & 0 deletions gap/Parser.gd
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@
DeclareGlobalFunction( "Scan_for_AutoDoc_Part" );
DeclareGlobalFunction( "AutoDoc_Type_Of_Item" );

DeclareGlobalVariable( "AUTODOC_ITEM_TYPE_INFO" );

## Argument should be a filename
DeclareGlobalFunction( "AutoDoc_Parser_ReadFiles" );
189 changes: 118 additions & 71 deletions gap/Parser.gi
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,68 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later

##
InstallValue( AUTODOC_ITEM_TYPE_INFO, rec(
Attr := rec(
chapter_bucket := "attributes",
is_function_like := true
),
Cat := rec(
chapter_bucket := "categories",
filter_type := "Category",
item_type_override := "Filt",
is_function_like := true
),
Coll := rec(
chapter_bucket := "collections",
filter_type := "Collection",
item_type_override := "Filt",
is_function_like := true
),
Constr := rec(
chapter_bucket := "methods",
is_function_like := true
),
Fam := rec(
chapter_bucket := "global_variables",
is_function_like := false
),
Filt := rec(
chapter_bucket := "filters",
is_function_like := true
),
Func := rec(
chapter_bucket := "global_functions",
is_function_like := true
),
InfoClass := rec(
chapter_bucket := "info_classes",
is_function_like := false
),
Meth := rec(
chapter_bucket := "methods",
is_function_like := true
),
Oper := rec(
chapter_bucket := "methods",
is_function_like := true
),
Prop := rec(
chapter_bucket := "properties",
is_function_like := true
),
Repr := rec(
chapter_bucket := "representations",
filter_type := "Representation",
item_type_override := "Filt",
is_function_like := true
),
Var := rec(
chapter_bucket := "global_variables",
is_function_like := false
)
));

##
BindGlobal( "AUTODOC_PositionPrefixShebang",
function( line )
Expand Down Expand Up @@ -130,113 +192,93 @@ end );
##
InstallGlobalFunction( AutoDoc_Type_Of_Item,
function( current_item, type, default_chapter_data )
local item_rec, entries, filter_style, ret_val;
local item_rec, filter_style, default_type, item_type, item_type_info,
default_boolean_return;
item_rec := current_item;
default_boolean_return := "<K>true</K> or <K>false</K>";
if PositionSublist( type, "DeclareCategoryCollections") <> fail then
entries := [ "Filt", "categories" ];
ret_val := "<K>true</K> or <K>false</K>";
default_type := "Coll";
filter_style := "none";
if not IsBound( item_rec!.arguments ) then
item_rec!.arguments := "obj";
fi;
item_rec!.coll_suffix := true;
elif PositionSublist( type, "DeclareCategory" ) <> fail then
entries := [ "Filt", "categories" ];
ret_val := "<K>true</K> or <K>false</K>";
default_type := "Cat";
filter_style := "single";
elif PositionSublist( type, "DeclareRepresentation" ) <> fail then
entries := [ "Filt", "categories" ];
ret_val := "<K>true</K> or <K>false</K>";
default_type := "Repr";
filter_style := "single";
elif PositionSublist( type, "DeclareAttribute" ) <> fail then
entries := [ "Attr", "attributes" ];
default_type := "Attr";
filter_style := "single";
elif PositionSublist( type, "DeclareSynonymAttr" ) <> fail then
entries := [ "Attr", "attributes" ];
default_type := "Attr";
filter_style := "none";
if not IsBound( item_rec!.arguments ) then
item_rec!.arguments := "arg";
fi;
elif PositionSublist( type, "DeclareProperty" ) <> fail then
entries := [ "Prop", "properties" ];
ret_val := "<K>true</K> or <K>false</K>";
default_type := "Prop";
filter_style := "single";
elif PositionSublist( type, "DeclareSynonym" ) <> fail then
default_type := "Func";
filter_style := "none";
if IsBound( item_rec!.item_type ) and item_rec!.item_type = "Attr" then
entries := [ "Attr", "attributes" ];
elif IsBound( item_rec!.item_type ) and item_rec!.item_type = "Prop" then
entries := [ "Prop", "properties" ];
ret_val := "<K>true</K> or <K>false</K>";
elif IsBound( item_rec!.item_type ) and item_rec!.item_type = "Filt" then
entries := [ "Filt", "categories" ];
ret_val := "<K>true</K> or <K>false</K>";
elif IsBound( item_rec!.item_type ) and item_rec!.item_type = "Oper" then
entries := [ "Oper", "methods" ];
elif IsBound( item_rec!.item_type ) and item_rec!.item_type = "Var" then
entries := [ "Var", "global_variables" ];
item_rec!.arguments := fail;
item_rec!.return_value := false;
else
entries := [ "Func", "global_functions" ];
fi;
if entries[ 1 ] in [ "Func", "Oper", "Attr", "Prop", "Filt" ] and
not IsBound( item_rec!.arguments ) then
item_rec!.arguments := "arg";
fi;
elif PositionSublist( type, "DeclareOperation" ) <> fail then
entries := [ "Oper", "methods" ];
default_type := "Oper";
filter_style := "list";
elif PositionSublist( type, "DeclareConstructor" ) <> fail then
entries := [ "Constr", "methods" ];
default_type := "Constr";
filter_style := "list";
elif PositionSublist( type, "DeclareGlobalFunction" ) <> fail then
entries := [ "Func", "global_functions" ];
default_type := "Func";
filter_style := "none";
if not IsBound( item_rec!.arguments ) then
item_rec!.arguments := "arg";
fi;
elif PositionSublist( type, "DeclareGlobalVariable" ) <> fail then
entries := [ "Var", "global_variables" ];
default_type := "Var";
filter_style := "none";
item_rec!.arguments := fail;
item_rec!.return_value := false;
elif PositionSublist( type, "DeclareGlobalName" ) <> fail then
default_type := "Var";
filter_style := "none";
if ( IsBound( item_rec!.item_type ) and item_rec!.item_type <> "Var" ) or
( IsBound( item_rec!.declareglobalname_is_function ) and
item_rec!.declareglobalname_is_function ) then
entries := [ "Func", "global_functions" ];
if not IsBound( item_rec!.arguments ) then
item_rec!.arguments := "arg";
fi;
else
entries := [ "Var", "global_variables" ];
item_rec!.arguments := fail;
item_rec!.return_value := false;
if IsBound( item_rec!.declaration_is_function ) and
item_rec!.declaration_is_function then
default_type := "Func";
fi;
elif PositionSublist( type, "DeclareFilter" ) <> fail then
entries := [ "Filt", "properties" ];
default_type := "Filt";
filter_style := "none";
item_rec!.arguments := fail;
item_rec!.return_value := false;
elif PositionSublist( type, "DeclareInfoClass" ) <> fail then
entries := [ "InfoClass", "info_classes" ];
default_type := "InfoClass";
filter_style := "none";
item_rec!.arguments := fail;
item_rec!.return_value := false;
elif PositionSublist( type, "KeyDependentOperation" ) <> fail then
entries := [ "Oper", "methods" ];
default_type := "Oper";
filter_style := "pair";
else
return fail;
fi;
item_rec!.item_type := entries[ 1 ];

if IsBound( item_rec!.item_type ) then
item_type := StripBeginEnd( item_rec!.item_type, " \t\r\n" );
else
item_type := default_type;
fi;
if not IsBound( AUTODOC_ITEM_TYPE_INFO.( item_type ) ) then
return fail;
fi;
item_type_info := AUTODOC_ITEM_TYPE_INFO.( item_type );
item_rec!.item_type := item_type;

if not IsBound( item_rec!.chapter_info ) or item_rec!.chapter_info = [ ] then
item_rec!.chapter_info := default_chapter_data.( entries[ 2 ] );
item_rec!.chapter_info :=
default_chapter_data.( item_type_info.chapter_bucket );
fi;
if IsBound( ret_val ) and ( item_rec!.return_value = [ ] or item_rec!.return_value = false ) then
item_rec!.return_value := [ ret_val ];

if item_type in [ "Cat", "Coll", "Filt", "Prop", "Repr" ] and
( item_rec!.return_value = [ ] or item_rec!.return_value = false ) then
item_rec!.return_value := [ default_boolean_return ];
fi;
if filter_style = "none" and item_type_info.is_function_like and
not IsBound( item_rec!.arguments ) then
item_rec!.arguments := "arg";
elif filter_style = "none" and not item_type_info.is_function_like then
item_rec!.arguments := fail;
item_rec!.return_value := false;
fi;
return filter_style;
end );
Expand Down Expand Up @@ -462,14 +504,19 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles,
fi;
end;
NormalizeItemType := function( item_type )
local supported_types;
item_type := StripBeginEnd( item_type, " \t\r\n" );
if item_type in [ "Attr", "Filt", "Func", "Oper", "Prop", "Var" ] then
if IsBound( AUTODOC_ITEM_TYPE_INFO.( item_type ) ) then
return item_type;
fi;
supported_types := JoinStringsWithSeparator(
Set( RecNames( AUTODOC_ITEM_TYPE_INFO ) ),
", "
);
ErrorWithPos(
Concatenation(
"unknown @ItemType ", item_type,
"; expected one of Attr, Filt, Func, Oper, Prop, Var"
"; expected one of ", supported_types
)
);
end;
Expand Down Expand Up @@ -592,7 +639,7 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles,
local filter_string, name, pos;
CurrentOrNewManItem();
if not IsBound( CurrentItem()!.item_type ) then
CurrentItem()!.item_type := "Oper";
CurrentItem()!.item_type := "Meth";
else
CurrentItem()!.item_type := NormalizeItemType(
CurrentItem()!.item_type
Expand Down Expand Up @@ -857,7 +904,7 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles,
fi;
CurrentItem()!.return_value := [ ];
elif not IsBound( CurrentItem()!.item_type ) then
CurrentItem()!.declareglobalname_is_function := true;
CurrentItem()!.declaration_is_function := true;
fi;
if current_command[ 2 ] <> "" then
Add( CurrentItem(), current_command[ 2 ] );
Expand All @@ -868,7 +915,7 @@ InstallGlobalFunction( AutoDoc_Parser_ReadFiles,
if IsBound( CurrentItem()!.item_type ) and CurrentItem()!.item_type = "Var" then
CurrentItem()!.item_type := "Func";
elif not IsBound( CurrentItem()!.item_type ) then
CurrentItem()!.declareglobalname_is_function := true;
CurrentItem()!.declaration_is_function := true;
fi;
CurrentItem()!.arguments := current_command[ 2 ];
end,
Expand Down
Loading
Loading