-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to customize man pages #3354
Comments
This is part of clap-rs#3354
This is part of clap-rs#3354
#3364 expanded I guess the question is if that is good enough or if we also want to allow people to inject their own data into our template. If so, what should that look like? An early version of /// Add a custom section to the man pages.
pub fn custom_section(
mut self,
title: impl Into<String>,
body: Vec<impl Into<String>>,
) -> Self;
|
@epage asked me in the discussion I made #3442 to post this here too: clap_mangen currently does not do much yet to generate man pages that can not directly be fully derived from the clap configuration. I think there are a couple of man page sections which are fairly standardized (as in a lot of CLI program man pages have them if applicable) but they are also highly modular. It might be useful to have some way to assemble these in clap_mangen from different sources to avoid duplicate effort on writing the same documentation over and over again. For the pieces from which these are assembled it might make sense to stick to standard types that require no dependencies so libraries could easily include a relevant snippet or two (e.g. database library could document the format of its DATABASE_URL variable or a logging library could document RUST_LOG). Since some libraries might want to include several related ones which should be displayed in a group in a specific order it would probably be useful to allow adding vectors of several such objects too. Potentially the type should also include section headings. Some of the sections might want to generate some content from clap config and the rest could be specified manually. The following sections come to mind (after using grep on my man1 folder) Environment VariablesUsually these list all the environment variables (besides the standard ones like PATH or HOME) that influence the functioning of the program. A good example for a long list of variables would be the git man page. FilesThe files section usually contains config files, some relative, some using variables like the XDG ones for their paths. Some common groups of files are those where several locations are tried in a specific order until a file is found or those where settings missing from one file are looked up in another (e.g. local, user-wide, system-wide). Usually the locations are listed, followed by a block of explanation Exit StatusThis section documents the various exit statuses and their meaning, each exit status is fairly independent though this is less likely than other sections to need inclusion of values provided by libraries. It might also make sense to allow the user to include some information on when the program might be expected to panic or have other abnormal exits, either in this or in a dedicated section rendered near this one. See Also / Further DocumentationThis section could easily include links for the main application but also for libraries used, e.g. when using sqlx for a server application one might want to link to the format for migrations and sqlx migrate run,... This is also where other man pages should be mentioned. Perhaps clap_mangen could automatically include the ones it generates here if a crate has multiple binaries or if support for generating config file man pages is added later. Reporting BugsThis usually includes information on how to report bugs, probably less modular than some of the other sections but could still benefit from modular assembly if there are libraries involved that require their bugs to be reported elsewhere. Copyright / Acknowledgements / LicenseThis could benefit from modularity to allow people to include snippets about libraries they use that require them to mention their use. Author / AuthorsThis might be similar to the above but more about the authors of the current program, not sure if it would benefit from modularity but it certainly couldn't hurt to be able to add independent snippets per author. Bugs / Known problems / CaveatsMaking this modular would allow library authors to just export a symbol that the CLI program author includes and the known bugs in the library change automatically without further work on the CLI program author's part. ExamplesThis is probably less about libraries but it could still be beneficial to assemble examples from different parts of the CLI program's codebase. HistoryThis section often seems to include less of a changelog and more bits and pieces about the historical context of a program, e.g. in which historic OS versions it first appeared (or the programs which inspired its creation) or in which standards it was influded ConclusionI think this could be done in a relatively simple way for most of these sections, most likely as a type similar to (Option, Vec<(String, String)>) where the first String would be a heading within the relevant section and the second would be a list of e.g. Environment Variable name and a string documenting it. Obviously for certain sections it would have to be modified, e.g. for the files section you might want the name to be a Vec instead. It might also be possible to use custom types from some light-weight crate most libraries interested in the feature wouldn't mind including. Ideally the format should not be too clap-specific or man page specific though to maximize adoption. So, after writing all of this I was wondering what others here think about the idea. |
@taladar could you elaborate more on your proposed solution, including how we should integrate that into our current processing? Example questions for us to be considering
Note: a valid answer can be "we won't support that" (e.g. custom ordering of commonly accepted sections). If so, be sure to give your reasoning. |
As another data point, I currently use the
I don't have a personal need to reorder these sections; I just want to generate manpage layouts that are familar to their consumers. The only one I specifically want to use (on top of what I'd also like to be able to have more control over the
I could potentially achieve these by replacing the |
Hi, based on the feedback of #5768 I'd like to join this conversation.
From my understanding it's possible to call the order of sections individually instead of using the let man = clap_mangen::Man::new(cmd);
let _ = man.render_title(&mut std::io::stdout());
let _ = man.render_name_section(&mut std::io::stdout());
let _ = man.render_synopsis_section(&mut std::io::stdout());
let _ = man.render_subcommands_section(&mut std::io::stdout());
let _ = man.render_options_section(&mut std::io::stdout());
let _ = man.render_custom_section(&mut std::io::stdout(), "SEE ALSO", SEE_ALSO_MAN); The approach below allows to change the desired order (subcommands before options) and also add a custom section wherever desired, in this case (boringly) at the end.
For this special case one could pass environment variables plus description as a list of dicts, let
For readability I'd accept strings as input which may contain Markdown, limited to roman, italic and bold, following the current capabilities of Roff.
See example above
One could define an enum for the allowed sections but then again, what's the advantage of that compared to allowing it freely?
See example above
See example above
A user could just call something like
Just don't call that specific section.
Since this discussion is open for more than two years, I'd find it helpful to add the low level function mentioned in #3354 (comment) and then continue the work for higher level "convenience" function, like the semi-automatic |
@aparcar I think something is missing about your post. It sounds like you are saying that calling individual sections on |
@epage Customizing man pages means in my understanding two things:
The former is possible via this commit 5d0ef1f (thanks), the latter would be possible with a "low level" API call like suggested in #5768 I implemented the above mentioned example again without the let mut roff = Roff::default();
let man = clap_mangen::Man::new(cmd);
let _ = man.render_title(&mut std::io::stdout());
let _ = man.render_name_section(&mut std::io::stdout());
let _ = man.render_synopsis_section(&mut std::io::stdout());
let _ = man.render_subcommands_section(&mut std::io::stdout());
let _ = man.render_options_section(&mut std::io::stdout());
roff.control("SH", ["EXIT STATUS"]);
roff.text([roman(EXIT_STATUS_MAN)]);
roff.control("SH", ["SEE ALSO"]);
roff.text([roman(SEE_ALSO_MAN)]);
roff.control("SH", ["STANDARDS"]);
roff.text([roman(STANDARDS_MAN)]);
roff.control("SH", ["AUTHORS"]);
roff.text([roman(AUTHORS_MAN)]);
roff.control("SH", ["BUGS"]);
roff.text([roman(BUGS_MAN)]);
let _ = roff.to_writer(&mut std::io::stdout()); I'm fine sticking to this approach, just thought the custom call would cover 99% of user cases. |
So the problem is not the ability to add custom content but the ergonomics (all of this assuming explicitly specifying all sections is accepted). I doubt we'd have a At that point, there won't be much of a difference between what you wrote and would would be done with a |
Regarding the ergonomics, would it make sense to allow basic markdown to allow some styling? The example code of |
A markdown -> roff converter could be made that people could use. If thats all thats done, then I don't think its worth building in. This becomes tricky if people want |
Please complete the following tasks
Clap Version
3.0
Describe your use case
We can't extract all man page sections from an
App
and need to allow the user specifying more sections.In addition, some sections won't be good enough
See #552 for ideas for sections
Describe the solution you'd like
I think there are two solutions
Alternatives, if applicable
No response
Additional Context
This was deferred out of #3174
The text was updated successfully, but these errors were encountered: