Files
gmipf 754aa6bc32 Add man page generation from the command-line model (#2)
* Add man page generation from the command-line model

Add CommandSet.OutputManPage (string and file overloads), a ManPageInfo
type for document-level metadata, a reference ManPage feature invoked as a
man command, and UserInput.FormatManPage which reuses FormatFlags so the
page cannot drift from --help. Output uses only portable man(7) macros and
validates warning-free under groff and mandoc -T lint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Address review feedback on man page generation

Rename the man page API to the single-word "Manpage" spelling throughout
(Manpage feature, ManpageInfo, CommandSet.OutputManpage,
UserInput.FormatManpage) for consistency with the "manpage" convention.

- Drop the redundant null check in OutputManpage; info is non-nullable
  under the enabled nullable context.
- Move the tests that exercise CommandSet.OutputManpage into
  CommandSetTests as a "Manpage Output" region, and relocate the Manpage
  feature test into a path-synced Features subfolder
  (SabreTools.CommandLine.Test.Features). Private test helpers now sit at
  the bottom of their classes.
- Fix the Manpage feature doc example to use the actual "man" command.

Builds clean across all target frameworks; the 235 tests pass and the
generated page still validates warning-free under groff -man -ww and
mandoc -T lint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 13:53:34 -04:00

70 lines
2.3 KiB
C#

namespace SabreTools.CommandLine
{
/// <summary>
/// Document-level metadata used when generating a man page
/// </summary>
/// <remarks>
/// These values populate the parts of a man page that cannot be
/// derived from the command-line model itself, such as the
/// <c>.TH</c> title line and the <c>NAME</c> section.
/// </remarks>
public class ManpageInfo
{
/// <summary>
/// Program name as invoked on the command line
/// </summary>
/// <remarks>
/// Used for the <c>.TH</c> title line, the <c>NAME</c> section,
/// and the <c>SYNOPSIS</c> section.
/// </remarks>
public string Name { get; set; }
/// <summary>
/// Manual section the page belongs to
/// </summary>
/// <remarks>Defaults to section 1 (user commands)</remarks>
public string Section { get; set; } = "1";
/// <summary>
/// Date used for the <c>.TH</c> title line
/// </summary>
/// <remarks>
/// When left null or empty, the field is emitted blank so that a
/// downstream packager can stamp it at build time.
/// </remarks>
public string? Date { get; set; }
/// <summary>
/// Version string used for the <c>.TH</c> title line
/// </summary>
public string? Version { get; set; }
/// <summary>
/// Manual title used for the <c>.TH</c> title line
/// </summary>
/// <remarks>Typically a value such as "User Commands"</remarks>
public string? Title { get; set; }
/// <summary>
/// Short description used for the <c>NAME</c> section
/// </summary>
/// <remarks>Should be a single printable line</remarks>
public string? Description { get; set; }
/// <summary>
/// Section heading used for the list of inputs
/// </summary>
/// <remarks>Defaults to "OPTIONS"</remarks>
public string OptionsHeading { get; set; } = "OPTIONS";
/// <summary>
/// Create a new <see cref="ManpageInfo"/> for the given program name
/// </summary>
/// <param name="name">Program name as invoked on the command line</param>
public ManpageInfo(string name)
{
Name = name;
}
}
}