-
Notifications
You must be signed in to change notification settings - Fork 336
[GenerateDocCReference] Improve filtering and categorization of arguments in documentation with sectionTitle #753
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
base: main
Are you sure you want to change the base?
Conversation
…ents in documentation with sectionTitle
@@ -218,7 +218,23 @@ public struct ArgumentInfoV0: Codable, Hashable { | |||
self.kind = kind | |||
|
|||
self.shouldDisplay = shouldDisplay | |||
self.sectionTitle = sectionTitle | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be part of ToolInfo. Instead the consumer of tool info can choose how to interpret the missing title. (the consumers of toolinfo are/will be: generate–docc-reference, generate-manual, generate-shell-completion, help-generation, usage-generation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your feedback dear Rauhul. I handled the logic in the generate-docc command.
…enerate-docc command instead of in toolinfo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this, @Chamepp! I think it would be great to focus this PR on just categorizing the arguments/options/flags, rather than also changing the subcommand display.
@@ -126,4 +153,19 @@ struct GenerateDoccReference: ParsableCommand { | |||
print(page) | |||
} | |||
} | |||
|
|||
func assignSectionTitle(to argument: ArgumentInfoV0) throws -> String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any errors that this function is throwing, which would eliminate the need for the new argumentAssignmentFailed
error above.
|
||
// Iterate through the grouped arguments, sorted by section title | ||
// Sorting ensures that the sections appear in a clear, predictable order in the final documentation. | ||
// The sections are listed alphabetically based on their title, enhancing readability. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this alphabetical sorting the same as used when printing help for the command-line tool?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way the documentation generation sorts this is: Arguments, Flags, Options.
If documentation generation sorts this without alphabetical sorting the placement of default section titles will not be consistent. We will get section titles sorted randomly every time.
When we are printing help for the repeat command, which includes all three types of values(arguments, flags and options), the output is sorted in this way: Arguments, Options. Then Options section include options listed first and then flags next.
I think with the addition of custom sectionTitles this is going to be a good implementation since it makes the documentation easier to work with. But as you mentioned I think it's important that we match the help output, and in some way we do.
I will wait for your feedback on this. If you think this is a good choice I will commit my changes. If not I will find another solution to make sure we list Arguments, Options and Flags in a consistent way that follows the help output pattern. Also I can implement alphabetical sorting for custom section titles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume you might be busy so I went ahead and committed my changes and will request for review. Let me know if you think we should change the sorting logic.
Another problem that arises if we don’t maintain a consistent section creation via sorting is that the snapshot and the generated document will always differ since the document generation produces random results. This will cause the tests to fail every time.
if let subcommands = self.subcommands, !subcommands.isEmpty { | ||
// Add a separate section for subcommands. | ||
// Subcommands are treated differently from regular arguments, so they deserve their own section in the documentation. | ||
// This helps to visually distinguish subcommands from regular arguments, enhancing readability. | ||
result += "## Subcommands\n\n" | ||
|
||
// Iterate through each subcommand and convert it to Markdown format | ||
// Each subcommand is processed and added to the documentation under the "Subcommands" section. | ||
// This ensures that users can easily identify and understand the subcommands available for the command. | ||
for subcommand in subcommands { | ||
result += subcommand.toMarkdown(path + [self.commandName]) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this change to how subcommands are listed is an improvement, since it ends up hard to see the hierarchy between commands (see the math
docs). Could you keep this PR focused on grouping the args/options/flags by section?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. The reason I changed this alongside the argument grouping was because after grouping the arguments, the subcommands started to feel a bit confusing. Since I was already organizing arguments into sections, I thought it might make sense to give subcommands their own section as well. And since both changes were aligned with the same purpose which is grouping by section, I thought it would be reasonable to include this small change in the same PR. I’ve now reverted the changes related to subcommands.
} | ||
if let discussion = arg.discussion { | ||
result += discussion + "\n\n" | ||
) { $0.sectionTitle ?? "General" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the "General"
fallback needed here? It looks like the section titles might only be added for the root-level command (see the subcommands in the math
docs for example).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason behind this fallback was that in case the property doesn’t have a custom sectionTitle and doesn’t fall into arguments default categories, it will be placed under the General category. I thought this will be great to handle this edge case and we can spot problems when the General section appears alongside throwing an error. I think I have developed a bad habit of over engineering. From now on I will focus on what's necessary and essential.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I checked the Math documentation output. This wasn’t an issue when I was assigning the default value in the ToolInfo. Since subcommands also uses the toMarkDown()
function from the GenerateDocC
extension, we should handle the default value of the section in the CommandInfoV0 extension. By doing this, every single command that uses the toMarkdown()
can benefit from this feature. I have implemented this and will commit my new changes soon.
// Add section title as a Markdown header to the result | ||
// Adding section titles as Markdown headers helps separate sections in the documentation, | ||
// making it easier for users to navigate and understand the structure of the arguments. | ||
result += "## \(section)\n\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is targeting markdown for use in DocC in particular, I'd recommend using ###
for section headers. DocC tends to preserve the 2nd level headers for a couple specific uses, and it doesn't always reflect arbitrary headers at the second level in the way you might expect. (the two common ones are ## Overview
and ## Topics
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great point, thank you. I will adjust it shortly.
for arg in arguments { | ||
// Add the argument identity in bold Markdown format | ||
// The argument identity is emphasized in bold to make it stand out in the documentation. | ||
result += "**`\(arg.identity())`**\n\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is for DocC consumption in particular, this pattern could benefit from using term lists. In DocC markdown, that looks something like:
- term `--hosting-base-path <hosting-base-path>`:
The base path where your will host your documentation.
^ the above example is a bit more focused on using it for flags, but figured I'd toss it out there.
Note that regular (GitHub-flavored) markdown doesn't respect this term
markup - so if you want to use this in both GH and DocC, this likely isn't a winner suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for taking the time to review this. I agree that using term lists is beneficial. I had actually noticed a separate issue related to this #721 and was planning to open a new pull request for it since the contribution guidelines emphasize the importance of making small focused changes that address a single goal. The same with the snapshot record issue. I saw that you already addressed it, appreciate that.
Summary
The recent modifications improve the readability and structure of documents generated using the GenerateDocC plugin. This update addresses #722 by enhancing how arguments are categorized within sections using the sectionTitle property.
Now, arguments—including required arguments, optionals, and flags—are grouped under their respective sectionTitles based on their type. Since sectionTitle is an optional value, some arguments may not have one explicitly provided. To handle this, we introduced logic that assigns a default section when no custom sectionTitle is specified. These default sections are:
Each argument is placed under its corresponding section based on its type. This ensures a well-structured and organized documentation format while allowing users to define their own custom sectionTitles when needed.
Changes
Listing arguments under custom sectionTitles
Default section titles for missing values
Better argument categorization and organization
Fixed missing dash in argument output
Updated unit tests and snapshot recordings
Re-ran and updated snapshot tests for:
Since section titles now have default values, output consistency has been verified.
Subcommands now have their own category
(Closes #722)"
Checklist