diff --git a/CHANGES.md b/CHANGES.md index 1994d57b..fef0b72b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,12 @@ This file describes changes in the AutoDoc package. +## 2026.05.03 + - Make `AutoDoc()` infer the package directory from `INPUT_FILENAME()` + when called from a `makedoc.g` file outside the package root + - Deprecate calling `AutoDoc()` with a package name + - Deprecate using GAP global options to pass settings to `AutoDoc()`, + suggest using option records instead + ## 2026.03.18 - Fix running the test suite via `TestPackage("AutoDoc")` when the current working directory is not the package root diff --git a/doc/Tutorials.autodoc b/doc/Tutorials.autodoc index 339c1e8f..6bb4ec71 100644 --- a/doc/Tutorials.autodoc +++ b/doc/Tutorials.autodoc @@ -23,15 +23,16 @@ then adopt additional features when useful. Suppose your package is already up and running, but so far has no manual. Then you can rapidly generate a scaffold for a package manual -using the command like this, -while running ⪆ from within your package's directory (the -one containing the PackageInfo.g file): +using the command like this: ```@listing LoadPackage( "AutoDoc" ); AutoDoc( rec( scaffold := true ) ); ``` -This first reads the PackageInfo.g file from the current -directory. It extracts information about the package from it +When called from a file such as makedoc.g, &AutoDoc; uses the +directory containing that file as the package directory. Otherwise, it +falls back to the current directory. In either case it then reads the +PackageInfo.g file from that package directory. It extracts information +about the package from it (such as its name and version, see Section ). It then creates two XML files doc/_main.xml and doc/title.xml inside the package directory. Finally, it runs @@ -84,7 +85,7 @@ AutoDoc( rec( autodoc := true ) ); QUIT; ``` Then you can regenerate the package manual from the command line with the -following command, executed from within the package directory: +following command: ```@listing gap makedoc.g ``` diff --git a/gap/Magic.gd b/gap/Magic.gd index 48a2f025..756e4785 100644 --- a/gap/Magic.gd +++ b/gap/Magic.gd @@ -49,27 +49,29 @@ #! The parameters have the following meanings: #! #! -#! packageOrDirectory +#! pkgdir #! -#! The purpose of this parameter is twofold: to determine the package +#! This optional parameter is used to determine the package #! directory in which &AutoDoc; will operate, and to find the metadata -#! concerning the package being documented. The parameter is either a -#! string, an IsDirectory object, or omitted. -#! If it is a string, &AutoDoc; interprets it as the name of a -#! package, uses the metadata of the first package known to ⪆ -#! with that name, and uses the InstallationPath specified in that -#! metadata as the package directory. If packageOrDirectory is -#! an IsDirectory object, this is used as package directory; -#! if the argument is omitted, then the current directory is used. -#! In the last two cases, the specified directory must contain a +#! concerning the package being documented. If given, it should be +#! an IsDirectory object. If the argument is omitted, then &AutoDoc; +#! checks if it was called from a makedoc.g file or similar, and if so, +#! uses the directory this is contained in. Otherwise the current +#! directory is used. In both cases, the specified directory must contain a #! PackageInfo.g file, and &AutoDoc; extracts all needed metadata #! from that. The IsDirectory form is for example useful if you #! have multiple versions of the package around and want to make sure the #! documentation of the correct version is built. #!

+#! For backwards compatibility, it is also possible to pass a package name +#! as this argument, which then is resolved to the package directory of +#! the first instance of this package ⪆ knows about. However, this is +#! deprecated, as it is unreliable in the presence of multiple copies of a +#! package. +#!

#! Note that when using AutoDocWorksheet (see #! ), there is -#! no parameter corresponding to packageOrDirectory and so the +#! no parameter corresponding to pkgdir and so the #! package directory is always the current directory, and #! there is no metadata. #! @@ -461,7 +463,7 @@ #! call inside makedoc.g. #! #! @Returns nothing -#! @Arguments [packageOrDirectory], [optrec] +#! @Arguments [pkgdir], [optrec] DeclareGlobalFunction( "AutoDoc" ); DeclareGlobalFunction( "AutoDoc_INTERN" ); diff --git a/gap/Magic.gi b/gap/Magic.gi index 59d65c91..402ca291 100644 --- a/gap/Magic.gi +++ b/gap/Magic.gi @@ -8,7 +8,8 @@ # InstallGlobalFunction( AutoDoc, function( arg ) - local pkgname, pkginfo, pkgdir, opt, file; + local pkgname, pkginfo, pkgdir, opt, file, + input_filename, path_positions; if Length( arg ) >= 3 then Error( "too many arguments" ); @@ -23,9 +24,24 @@ function( arg ) # check the first argument if Length(arg) = 0 then - pkgdir := DirectoryCurrent( ); + input_filename := INPUT_FILENAME(); + if IsString( input_filename ) and + input_filename <> "*stdin*" and + IsReadableFile( input_filename ) then + path_positions := PositionsProperty( input_filename, x -> x = '/' ); + if IsEmpty( path_positions ) then + pkgdir := DirectoryCurrent( ); + else + pkgdir := Directory( + input_filename{ [ 1 .. Last( path_positions ) - 1 ] } + ); + fi; + else + pkgdir := DirectoryCurrent( ); + fi; elif IsString( arg[1] ) then pkgname := Remove( arg, 1 ); + Print("#W AutoDoc: passing pkgname as first argument to AutoDoc is deprecated"); elif IsDirectory( arg[1] ) then pkgdir := Remove( arg, 1 ); fi; @@ -74,19 +90,25 @@ function( is_worksheet, pkgname, pkginfo, pkgdir, opt ) pkgdirstr, docdirstr, title_page, tree, position_document_class, - args; + args, used_legacy_value_options; # - # Check for user supplied options. If present, they take - # precedence over any defaults as well as the opt record. + # Deprecated feature: Check for user supplied global options. If present, + # they take precedence over any defaults as well as the opt record. # + used_legacy_value_options := false; for key in [ "dir", "scaffold", "autodoc", "gapdoc", "extract_examples" ] do val := ValueOption( key ); if val <> fail then opt.(key) := val; + used_legacy_value_options := true; fi; od; + if used_legacy_value_options then + Print("#W passing options via GAP's global options system is deprecated; use an option record instead\n"); + fi; + # # Setup the output directory # diff --git a/tst/autodoctest-manual.tst b/tst/autodoctest-manual.tst index 381d3cdd..fe5eb8f8 100644 --- a/tst/autodoctest-manual.tst +++ b/tst/autodoctest-manual.tst @@ -35,6 +35,12 @@ gap> AUTODOC_RunPackageScenario( pkgdir, olddir, rec( > makedoc := "makedoc.g", > doc_expected := "tst/manual.expected", > ) ); +gap> AUTODOC_RunPackageScenario( pkgdir, olddir, rec( +> name := "manual-parent-relative", +> makedoc := "../../makedoc.g", +> workdir := "doc/build", +> doc_expected := "tst/manual.expected", +> ) ); # entities option variants gap> AUTODOC_RunPackageScenario( pkgdir, olddir, rec( diff --git a/tst/manual.expected/_Chapter_Reference.xml b/tst/manual.expected/_Chapter_Reference.xml index 681aaf97..9faf6370 100644 --- a/tst/manual.expected/_Chapter_Reference.xml +++ b/tst/manual.expected/_Chapter_Reference.xml @@ -37,7 +37,7 @@ The AutoDoc() function - + nothing @@ -79,27 +79,29 @@

The parameters have the following meanings: - packageOrDirectory + pkgdir - The purpose of this parameter is twofold: to determine the package + This optional parameter is used to determine the package directory in which &AutoDoc; will operate, and to find the metadata - concerning the package being documented. The parameter is either a - string, an IsDirectory object, or omitted. - If it is a string, &AutoDoc; interprets it as the name of a - package, uses the metadata of the first package known to &GAP; - with that name, and uses the InstallationPath specified in that - metadata as the package directory. If packageOrDirectory is - an IsDirectory object, this is used as package directory; - if the argument is omitted, then the current directory is used. - In the last two cases, the specified directory must contain a + concerning the package being documented. If given, it should be + an IsDirectory object. If the argument is omitted, then &AutoDoc; + checks if it was called from a makedoc.g file or similar, and if so, + uses the directory this is contained in. Otherwise the current + directory is used. In both cases, the specified directory must contain a PackageInfo.g file, and &AutoDoc; extracts all needed metadata from that. The IsDirectory form is for example useful if you have multiple versions of the package around and want to make sure the documentation of the correct version is built.

+ For backwards compatibility, it is also possible to pass a package name + as this argument, which then is resolved to the package directory of + the first instance of this package &GAP; knows about. However, this is + deprecated, as it is unreliable in the presence of multiple copies of a + package. +

Note that when using AutoDocWorksheet (see ), there is - no parameter corresponding to packageOrDirectory and so the + no parameter corresponding to pkgdir and so the package directory is always the current directory, and there is no metadata. diff --git a/tst/manual.expected/_Chapter_Tutorials.xml b/tst/manual.expected/_Chapter_Tutorials.xml index 2108a631..ec3bb577 100644 --- a/tst/manual.expected/_Chapter_Tutorials.xml +++ b/tst/manual.expected/_Chapter_Tutorials.xml @@ -38,15 +38,16 @@ then adopt additional features when useful.

Suppose your package is already up and running, but so far has no manual. Then you can rapidly generate a scaffold for a package manual -using the command like this, -while running &GAP; from within your package's directory (the -one containing the PackageInfo.g file): +using the command like this:

-This first reads the PackageInfo.g file from the current -directory. It extracts information about the package from it +When called from a file such as makedoc.g, &AutoDoc; uses the +directory containing that file as the package directory. Otherwise, it +falls back to the current directory. In either case it then reads the +PackageInfo.g file from that package directory. It extracts information +about the package from it (such as its name and version, see Section ). It then creates two XML files doc/_main.xml and doc/title.xml inside the package directory. Finally, it runs @@ -99,7 +100,7 @@ AutoDoc( rec( autodoc := true ) ); QUIT; ]]> Then you can regenerate the package manual from the command line with the -following command, executed from within the package directory: +following command: diff --git a/tst/utils.g b/tst/utils.g index e64d625c..bd68e35a 100644 --- a/tst/utils.g +++ b/tst/utils.g @@ -7,6 +7,7 @@ # olddir caller's original working directory, restored on exit # scenario record describing the scenario to run; it must contain # `name` and `makedoc`, and may additionally specify: +# - `workdir := "subdir"` to run Read(makedoc) from a nested cwd # - `stub_gapdoc := true` to skip the expensive GAPDoc post-pass # - `doc_expected := "tst/...expected"` for full doc-file diffs # - `tst_expected := "tst/...expected"` for extracted-test diffs @@ -16,7 +17,7 @@ AUTODOC_RunPackageScenario := function( pkgdir, olddir, scenario ) local tempdir, docdir, tstdir, ex_dir, files, expected, actual, old_makegapdocdoc, old_copyhtmlstylefiles, old_manuallab, old_autodoc_level, old_gapdoc_level, old_warning_level, f, - source_doc_files, source_tst_files; + source_doc_files, source_tst_files, workdir; tempdir := Filename( DirectoryTemporary(), @@ -88,6 +89,11 @@ AUTODOC_RunPackageScenario := function( pkgdir, olddir, scenario ) SetInfoLevel( InfoAutoDoc, 0 ); SetInfoLevel( InfoGAPDoc, 0 ); SetInfoLevel( InfoWarning, 0 ); + if IsBound( scenario.workdir ) then + workdir := Filename( Directory( tempdir ), scenario.workdir ); + AUTODOC_CreateDirIfMissing( workdir ); + ChangeDirectoryCurrent( workdir ); + fi; Read( scenario.makedoc : nopdf ); SetInfoLevel( InfoAutoDoc, old_autodoc_level ); SetInfoLevel( InfoGAPDoc, old_gapdoc_level );