NCurses.BrowseGeneric
NCurses.BrowseGeneric
This chapter introduces the operation Browse (6.1-1) and lists several examples how the function NCurses.BrowseGeneric (4.3-1) can be utilized for rendering GAP related data or for playing games. Each section describes the relevant GAP functions and briefly sketches the technical aspects of the implementation; more details can be found in the GAP files, in the app directory of the package.
Only Section 6.4 describes a standard application in the sense of the introduction to Chapter 4, perhaps except for a special function that is needed to compare table entries. The other examples in this chapter require some of the programming described in Chapter 5.
The GAP examples in this chapter use the replay
feature of NCurses.BrowseGeneric (4.3-1), see Section 4.1. This means that the NCurses.BrowseGeneric (4.3-1) based function is called between two calls of BrowseData.SetReplay (5.4-2). If you want to paste these examples into the GAP session with the mouse then do not paste the final BrowseData.SetReplay (5.4-2) call, since NCurses.BrowseGeneric (4.3-1) would regard the additional input as a user interrupt.
Browse‣ Browse( obj[, arec] ) | ( operation ) |
This operation displays the GAP object obj in a nice, formatted way, similar to the operation Display (Reference: Display). The difference is that Browse is intended to use ncurses facilities.
Currently there are methods for matrices (see Browse (6.2-2)), for character tables (see Browse (6.3-1)) and for tables of marks (see Browse (6.4-1)).
The GAP library provides several Display (Reference: Display) methods for matrices. In order to cover the functionality of these methods, Browse provides the function NCurses.BrowseDenseList (6.2-1) that uses the standard facilities of the function NCurses.BrowseGeneric (4.3-1), i. e., one can scroll in the matrix, searching and sorting are provided etc.
The idea is to customize this function for different special cases, and to install corresponding Browse (6.1-1) methods. Examples are methods for matrices over finite fields and residue class rings of the rational integers, see Browse (6.2-2).
The code can be found in the file app/matdisp.g of the package.
‣ NCurses.BrowseDenseList( list, arec ) | ( function ) |
Returns: nothing.
Let list be a dense list whose entries are lists, for example a matrix, and let arec be a record. This function displays list in a window, as a two-dimensional array with row and column positions as row and column labels, respectively.
The following components of arec are supported.
headerIf bound, the value must be a valid value of the work.header component of a browse table, see BrowseData.IsBrowseTable (4.2-3); for example, the value can be a list of strings. If this component is not bound then the browse table has no header.
footerIf bound, the value must be a valid value of the work.footer component of a browse table, see BrowseData.IsBrowseTable (4.2-3); for example, the value can be a list of strings. If this component is not bound then the browse table has no footer.
convertEntryIf bound, the value must be a unary function that returns a string describing its argument. The default is the operation String (Reference: String). Another possible value is NCurses.ReplaceZeroByDot, which returns the string "." if the argument is a zero element in the sense of IsZero (Reference: IsZero), and returns the String (Reference: String) value otherwise. For each entry in a row of list, the convertEntry value is shown in the browse table.
labelsRowIf bound, the value must be a list of row label rows for list, as described in Section BrowseData.IsBrowseTable (4.2-3). The default is [ [ "1" ], [ "2" ], ... ].
labelsColIf bound, the value must be a list of column label rows for list, as described in Section BrowseData.IsBrowseTable (4.2-3). The default is [ [ "1", "2", ... ] ].
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is available.
‣ Browse( list ) | ( method ) |
Returns: nothing.
Several methods for the operation Browse (6.1-1) are installed for the case that the argument is a list of lists. These methods cover a default method for lists of lists and the Display (Reference: Display) methods for matrices over finite fields and residue class rings of the rational integers. Note that matrices over finite prime fields, small extension fields, and large extension fields are displayed differently, and the same holds for the corresponding Browse (6.1-1) methods.
gap> n:= [ 14, 14, 14, 14 ];; gap> input:= Concatenation( n, n, n, "Q" );; # ``do nothing and quit'' gap> BrowseData.SetReplay( input ); gap> Browse( RandomMat( 10, 10, Integers ) ); gap> BrowseData.SetReplay( input ); gap> Browse( RandomMat( 10, 10, GF(3) ) ); gap> BrowseData.SetReplay( input ); gap> Browse( RandomMat( 10, 10, GF(4) ) ); gap> BrowseData.SetReplay( input ); gap> Browse( RandomMat( 10, 10, Integers mod 6 ) ); gap> BrowseData.SetReplay( input ); gap> Browse( RandomMat( 10, 10, GF( NextPrimeInt( 2^16 ) ) ) ); gap> BrowseData.SetReplay( input ); gap> Browse( RandomMat( 10, 10, GF( 2^20 ) ) ); gap> BrowseData.SetReplay( false );
The GAP library provides a Display (Reference: Display) method for character tables that breaks the table into columns fitting on the screen. Browse provides an alternative, using the standard facilities of the function NCurses.BrowseGeneric (4.3-1), i. e., one can scroll in the matrix of character values, searching and sorting are provided etc.
The Browse (6.1-1) method for character tables can be called instead of Display (Reference: Display). For convenience, one can additionally make this function the default Display (Reference: Display) method for character tables, by assigning it to the Display component in the global record CharacterTableDisplayDefaults.User, see Reference: Printing Character Tables; for example, one can do this in one's gaprc file, see Reference: The gap.ini and gaprc files. (This can be undone by unbinding the component CharacterTableDisplayDefaults.User.Display.)
The function BrowseDecompositionMatrix (6.3-2) can be used to display decomposition matrices for Brauer character tables.
‣ Browse( tbl[, options] ) | ( method ) |
This method displays the character table tbl in a window. The optional record options describes what shall be displayed, the supported components and the default values are described in Reference: Printing Character Tables.
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is available.
gap> if TestPackageAvailability( "CTblLib" ) = true then > BrowseData.SetReplay( Concatenation( > # scroll in the table > "DRULdddddrrrrrlluu", > # select an entry and move it around > "seddrruuuddlll", > # search for the pattern 135 (six times) > "/135", [ NCurses.keys.ENTER ], "nnnnn", > # deselect the entry, select the first column > "qLsc", > # sort and categorize by this column > "sc", > # select the first row, move down the selection > "srdddd", > # expand the selected category, scroll the selection down > "xd", > # and quit the application > "Q" ) ); > Browse( CharacterTable( "HN" ) ); > BrowseData.SetReplay( false ); > fi;
Implementation remarks: The first part of the code in the Browse (6.1-1) method for character tables is almost identical with the code for extracting the data to be displayed from the input data in the GAP library function CharacterTableDisplayDefault. The second part of the code transforms these data into a browse table. Character names and (if applicable) indicator values are used as row labels, and centralizer orders, power maps, and class names are used as column labels. The identifier of the table is used as the static header. When an irrational entry is selected, a description of this entry is shown in the dynamic footer.
The standard modes in BrowseData (5.4-1) (except the help mode) have been extended by three new actions. The first two of them open pagers giving an overview of all irrationalities in the table, or of all those irrationalities that have been shown on the screen in the current call, respectively. The corresponding user inputs are the I and the i key. (The names assigned to the irrationalities are generated column-wise. If one just scrolls through the table, without jumping, then these names coincide with the names generated by the default Display (Reference: Display) method for character tables; this is in general not the case, for example when a row-wise search in the table is performed.) The third new action, which is associated with the p key, toggles the visibility status of the column label rows for centralizer orders and power maps.
An individual minyx function does not only check whether the desired table fits into the window but also whether a table with too high column labels (centralizer orders and power maps) would fit if these labels get collapsed via the p key. In this case, the labels are automatically collapsed, and the p key is disabled.
In order to keep the required space small also for large character tables, caching of formatted matrix entries is disabled, and the strings to be displayed are computed on demand with a Main function in the work component of the browse table. For the same reason, the constant height one for all table rows is set in advance, so one need not inspect a whole character if only a few values of it shall be shown.
Special functions are provided for sorting (concerning the comparison of character values, which can be integers or irrationalities) and categorizing the table by a column (the value in the category row involves the class name of the column in question).
The code can be found in the file app/ctbldisp.g of the package.
‣ BrowseDecompositionMatrix( modtbl[, b][, options] ) | ( function ) |
This method displays the decomposition matrix of (the b-th block of) the Brauer character table modtbl in a window. The arguments are the same as for LaTeXStringDecompositionMatrix (Reference: LaTeXStringDecompositionMatrix).
The positions of the ordinary and modular irreducible characters are shown in the labels of the rows and columns, respectively, that are indexed by these characters. When an entry in the decomposition matrix is selected then information about the degrees of these characters is shown in the table footer.
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is available.
gap> BrowseData.SetReplay( Concatenation( > # select the first entry > "se", > # scroll in the table > "drrrr", > # keep the table open for a while > [ 14, 14, 14, 14, 14 ], > # and quit the application > "Q" ) ); gap> BrowseDecompositionMatrix( CharacterTable( "J1" ) mod 2 ); gap> BrowseData.SetReplay( false );
The code can be found in the file app/ctbldisp.g of the package.
The GAP library provides a Display (Reference: Display) method for tables of marks that breaks the table into columns fitting on the screen. Similar to the situation with character tables, see Section 6.3, but with a much simpler implementation, Browse provides an alternative based on the function NCurses.BrowseGeneric (4.3-1).
Browse (6.1-1) can be called instead of Display (Reference: Display) for tables of marks, cf. Reference: Printing Tables of Marks.
‣ Browse( tom[, options] ) | ( method ) |
This method displays the table of marks tom in a window. The optional record options describes what shall be displayed, the supported components and the default values are described in Reference: Printing Tables of Marks.
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is available.
gap> if TestPackageAvailability( "TomLib" ) = true then > BrowseData.SetReplay( Concatenation( > # scroll in the table > "DDRRR", > # search for the (exact) value 100 (three times) > "/100", > [ NCurses.keys.DOWN, NCurses.keys.DOWN, NCurses.keys.RIGHT ], > [ NCurses.keys.DOWN, NCurses.keys.DOWN, NCurses.keys.DOWN ], > [ NCurses.keys.RIGHT, NCurses.keys.ENTER ], "nn", > # no more occurrences of 100, confirm > [ NCurses.keys.ENTER ], > # and quit the application > "Q" ) ); > Browse( TableOfMarks( "A10" ) ); > BrowseData.SetReplay( false ); > fi;
Implementation remarks: Rows and columns are indexed by their positions. The identifier of the table is used as the static header, there is no footer.
In order to keep the required space small also for large tables of marks, caching of formatted matrix entries is disabled, and the strings to be displayed are computed on demand with a Main function in the work component of the browse table. For the same reason, the constant height one for the table rows is set in advance. (For example, the table of marks of the group with identifier "O8+(2)", with 11171 rows and columns, can be shown with Browse (6.1-1) in a GAP session requiring about 100 MB.)
The code can be found in the file app/tomdisp.g of the package.
The GAP package AtlasRep (see [WPN+19]) is an interface to a database of representations and related data. The table of contents of this database can be displayed via the function DisplayAtlasInfo (AtlasRep: DisplayAtlasInfo) of this package. The Browse package provides an alternative based on the function NCurses.BrowseGeneric (4.3-1); one can scroll, search, and fetch data for later use.
‣ BrowseAtlasInfo( [listofnames][,] ["contents", sources][,] [...] ) | ( function ) |
‣ BrowseAtlasInfo( gapname[, std][, ...] ) | ( function ) |
Returns: the list of clicked
info records.
This function shows the information available via the GAP package AtlasRep in a browse table, cf. Section AtlasRep: Accessing Data via AtlasRep in the AtlasRep manual.
The optional arguments can be used to restrict the table to core data or data extensions, or to show an overview for one particular group. The arguments are the same as for DisplayAtlasInfo (AtlasRep: DisplayAtlasInfo), see the documentation of this function for details. (Note that additional conditions such as IsPermGroup (Reference: IsPermGroup) can be entered also in the case that no gapname is given. In this situation, the additional conditions are evaluated for the second level tables
that are opened by clicking
on a table row or entry.)
When one clicks
on one of the table rows or entries then a browse table with an overview of the information available for this group is shown, and clicking
on one of the rows in these tables adds the corresponding info record (see OneAtlasGeneratingSetInfo (AtlasRep: OneAtlasGeneratingSetInfo)) to the list of return values of BrowseAtlasInfo.
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is available.
The following example shows how BrowseAtlasInfo can be used to fetch info records about permutation representations of the alternating groups A_5 and A_6: We search for the group name "A5" in the overview table, and the first cell in the table row for A_5 becomes selected; hitting the Enter key causes a new window to be opened, with an overview of the data available for A_5; moving down two rows and hitting the Enter key again causes the second representation to be added to the result list; hitting Q closes the second window, and we are back in the overview table; we move the selection down twice (to the row for the group A_6), and choose the first representation for this group; finally we leave the table, and the return value is the list with the data for the two representations.
gap> d:= [ NCurses.keys.DOWN ];; r:= [ NCurses.keys.RIGHT ];; gap> c:= [ NCurses.keys.ENTER ];; gap> BrowseData.SetReplay( Concatenation( > "/A5", # Find the string A5 ... > d, d, r, # ... such that just the word matches, > c, # start the search, > c, # click the table entry A5, > d, d, # move down two rows, > c, # click the row for this representation, > "Q", # quit the second level table, > d, d, # move down two rows, > c, # click the table entry A6, > d, # move down one row, > c, # click the first row, > "Q", # quit the second level table, > "Q" ) ); # and quit the application. gap> if IsBound( BrowseAtlasInfo ) and IsBound( AtlasProgramInfo ) then > SetUserPreference( "AtlasRep", "AtlasRepMarkNonCoreData", "" ); > tworeps:= BrowseAtlasInfo(); > else > tworeps:= [ fail ]; > fi; gap> BrowseData.SetReplay( false ); gap> if fail in tworeps then > Print( "no access to the Web ATLAS\n" ); > else > Print( List( tworeps, x -> x.identifier[1] ), "\n" ); > fi; [ "A5", "A6" ]
Implementation remarks: The first browse table shown has a static header, no footer and row labels, one row of column labels describing the type of data summarized in the columns.
Row and column separators are drawn as grids (cf. NCurses.Grid (2.2-8)) composed from the special characters described in Section 2.1-6, using the component work.SpecialGrid of the browse table, see BrowseData (5.4-1).
When a row is selected, the click
functionality opens a new window (via a second level call to NCurses.BrowseGeneric (4.3-1)), in which a browse table with the list of available data for the given group is shown; in this table, click
results in adding the info for the selected row to the result list, and a message about this addition is shown in the footer row. One can choose further data, return to the first browse table, and perhaps iterate the process for other groups. When the first level table is left, the list of info records for the chosen data is returned.
For the two kinds of browse tables, the standard modes in BrowseData (5.4-1) (except the help mode) have been extended by a new action that opens a pager giving an overview of all data that have been chosen in the current call. The corresponding user input is the Y key.
This function is available only if the GAP package AtlasRep is available.
The code can be found in the file app/atlasbrowse.g of the package.
A Browse adapted way to access several manuals is to show the hierarchy of books, chapters, sections, and subsections as collapsible category rows, and to regard the contents of each subsection as a data row of a matrix with only one column.
This application is mainly intended as an example with table cells that exceed the screen, and as an example with several category levels.
‣ BrowseGapManuals( [start] ) | ( function ) |
This function displays the contents of the GAP manuals (the main GAP manuals as well as the loaded package manuals) in a window. The optional argument start describes the initial status, admissible values are the strings "inline/collapsed", "inline/expanded", "pager/collapsed", and "pager/expanded".
In the inline cases, the parts of the manuals are shown in the browse table, and in the pager case, the parts of the manuals are shown in a different window when they are clicked
, using the user's favourite help viewer, see Reference: Changing the Help Viewer.
In the collapsed cases, all category rows are collapsed, and the first row is selected; typical next steps are moving down the selection and expanding single category rows. In the expanded cases, all category rows are expanded, and nothing is selected; a typical next step in the inline/expanded case is a search for a string in the manuals. (Note that searching in quite slow: For viewing a part of a manual, the file with the corresponding section is read into GAP, the text is formatted, the relevant part is cut out from the section, perhaps markup is stripped off, and finally the search is performed in the resulting strings.)
If no argument is given then the user is asked for selecting an initial status, using NCurses.Select (3.1-2).
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is available.
gap> n:= [ 14, 14, 14 ];; # ``do nothing'' gap> BrowseData.SetReplay( Concatenation( > "xdxd", # expand a Tutorial section > n, "Q" ) ); # and quit gap> BrowseGapManuals( "inline/collapsed" ); gap> BrowseData.SetReplay( Concatenation( > "/Browse", [ NCurses.keys.ENTER ], # search for "Browse" > "xdxddxd", # expand a section > n, "Q" ) ); # and quit gap> BrowseGapManuals( "inline/collapsed" ); gap> BrowseData.SetReplay( false );
Implementation remarks: The browse table has a dynamic header showing the name of the currently selected manual, no footer, no row or column labels, and exactly one column of fixed width equal to the screen width. The category rows are precomputed, i. e., they do not arise from a table column; this way, the contents of each data cell can be computed on demand, as soon as it is shown on the screen, in particular the category hierarchy is computed without reading the manuals into GAP. Also, the data rows are not cached. There is no return value. The heights of many cells are bigger than the screen height, so scrolling is a mixture of scrolling to the next cell and scrolling inside a cell. The different initial states are realized via executing different initial steps before the table is shown to the user.
For the variants that show the manuals in a pager, the code temporarily replaces the show function of the default viewer "screen" (see Reference: Changing the Help Viewer) by a function that uses NCurses.Pager (3.1-4). Note that in the case that the manual bit in question fits into one screen, the default show function writes this text directly to the screen, but this is used already by the browse table.
The implementation should be regarded as a sketch.
For example, the markup available in the text file format of GAPDoc manuals (using Esc sequences) is stripped off instead of being transferred to the attribute lines that arise, because of the highlighting problem mentioned in Section 2.2-3.
Some heuristics used in the code are due to deficiencies of the manual formats.
For the inline variant of the browse table, the titles of chapters, sections, and subsections are not regarded as parts of the actual text since they appear already as category rows; however, the functions of the GAP help system deliver the text together with these titles, so these lines must be stripped off afterwards.
The category hierarchy representing the tables of contents is created from the manual.six files of the manuals. These files do not contain enough information for determining whether several functions define the same subsection, in the sense that there is a common description text after a series of manual lines introducing different functions. In such cases, the browse table contains a category row for each of these functions (with its own number), but the corresponding text appears only under the last of these category rows, the data rows for the others are empty. (This problem does not occur in the GAPDoc manual format because this introduces explicit subsection titles, involving only the first of several function definitions.)
Also, index entries and sectioning entries in manual.six files of manuals in GAPDoc format are not explicitly distinguished.
The code can be found in the file app/manual.g of the package.
The function BrowseBibliography (6.7-1) can be used to turn the contents of bibliography files in BibTeX or BibXMLext format (see GAPDoc: The BibXMLext Format) into a Browse table, such that one can scroll in the list, search for entries, sort by year, sort and categorize by authors etc.
The default bibliography used by BrowseBibliography (6.7-1) is the bibliography of GAP related publications, see [GAP]. The Browse package contains a (perhaps outdated) version of this bibliography. One can get an updated version as follows.
wget -N http://www.gap-system.org/Doc/Bib/gap-publishednicer.bib
The columns of the Browse table that is shown by BrowseBibliography (6.7-1) can be customized, two examples for that are given by the functions BrowseBibliographySporadicSimple (AtlasRep: BrowseBibliographySporadicSimple) and BrowseBibliographyGapPackages (6.7-2).
The function BrowseMSC (6.7-3) shows an overview of the AMS Mathematics Subject Classification codes.
‣ BrowseBibliography( [bibfiles] ) | ( function ) |
Returns: a record as returned by ParseBibXMLExtFiles (GAPDoc: ParseBibXMLextFiles).
This function shows the list of bibliography entries in the files given by bibfiles, which may be a string or a list of strings (denoting a filename or a list of filenames, respectively) or a record (see below for the supported components).
If no argument is given then the file bibl/gap-publishednicer.bib in the Browse package directory is taken, and "GAP Bibliography" is used as the header.
Unfortunately bibl/gap-publishednicer.bib does does not have a copyright statement saying it can be distributed under a free license. Therefore it can not be distributed by the debian free distribution. You can however retrieve the file using the script /usr/share/gap/pkg/Browse/bibl/getnewestbibfile. Copying the retrieved file to /usr/share/gap/pkg/Browse/bibl/gap-publishednicer.bib will enable the functionality.
Another perhaps interesting data file that should be available in the GAP distribution is doc/manualbib.xml. This file can be located as follows.
gap> file:= Filename( DirectoriesLibrary( "doc" ), "manualbib.xml" );;
Both BibTeX format and the XML based extended format provided by the GAPDoc package are supported by BrowseBibliography, see Chapter GAPDoc: Utilities for Bibliographies.
In the case of BibTeX format input, first a conversion to the extended format takes place, via StringBibAsXMLext (GAPDoc: StringBibAsXMLext) and ParseBibXMLextString (GAPDoc: ParseBibXMLextString). Note that syntactically incorrect entries are rejected in this conversion –this is signaled with InfoBibTools (GAPDoc: InfoBibTools) warnings– and that only a subset of the possible LaTeX markup is recognized –other markup appears in the browse table except that the leading backslash is removed.
In both cases of input, the problem arises that in visual mode, currently we can show only ASCII characters (and the symbols in NCurses.lineDraw, but these are handled differently, see Section 2.1-6). Therefore, we use the function SimplifiedUnicodeString (GAPDoc: SimplifiedUnicodeString) for replacing other unicode characters by ASCII text.
The return value is a record as returned by ParseBibXMLExtFiles (GAPDoc: ParseBibXMLextFiles), its entries component corresponds to the bibliography entries that have been clicked
in visual mode. This record can be used as input for WriteBibFile (GAPDoc: WriteBibFile) or WriteBibXMLextFile (GAPDoc: WriteBibXMLextFile), in order to produce a bibliography file, or it can be used as input for StringBibXMLEntry (GAPDoc: StringBibXMLEntry), in order to produce strings from the entries, in various formats.
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is available.
gap> # sort and categorize by year, scroll down, expand a category row gap> BrowseData.SetReplay( "scrrscsedddddxdddddQ" ); gap> BrowseBibliography();; gap> # sort & categorize by authors, expand all category rows, scroll down gap> BrowseData.SetReplay( "scscXseddddddQ" ); gap> BrowseBibliography();; gap> # sort and categorize by journal, search for a journal name, expand gap> BrowseData.SetReplay( Concatenation( "scrrrsc/J. Algebra", > [ NCurses.keys.ENTER ], "nxdddQ" ) ); gap> BrowseBibliography();; gap> BrowseData.SetReplay( false );
Implementation remarks: The browse table has a dynamic header (showing the number of entries, which can vary when the table is restricted), no footer and row labels; one row of column labels is given by the descriptions of the table columns (authors, title, year, journal, MSC code).
Row and column separators are drawn as grids (cf. NCurses.Grid (2.2-8)) composed from the special characters described in Section 2.1-6, using the component work.SpecialGrid of the browse table, see BrowseData (5.4-1).
For categorizing by authors (or by MSC codes), the sort parameter "split rows on categorizing" is set to "yes", so the authors (codes) are distributed to different category rows, hence each entry appears once for each of its authors (or its MSC codes) in the categorized table. When a data row or an entry in a data row is selected, click
adds the corresponding bibliographhy entry to the result.
The width of the title column is pr