Skip to content
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

Support for markdown output in help messages #30

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions example/src/clic_ex-commands-subsub.adb
Original file line number Diff line number Diff line change
@@ -23,11 +23,11 @@ package body CLIC_Ex.Commands.Subsub is
Put_Line => Ada.Text_IO.Put_Line,
Put_Error => Ada.Text_IO.Put_Line,
Error_Exit => GNAT.OS_Lib.OS_Exit,
TTY_Chapter => CLIC.TTY.Info,
TTY_Description => CLIC.TTY.Description,
TTY_Version => CLIC.TTY.Version,
TTY_Underline => CLIC.TTY.Underline,
TTY_Emph => CLIC.TTY.Emph);
TTY_Chapter => CLIC.Formatter.Chapter,
TTY_Description => CLIC.Formatter.Description,
TTY_Version => CLIC.Formatter.Version,
TTY_Underline => CLIC.Formatter.Underline,
TTY_Emph => CLIC.Formatter.Emph);
begin
Sub.Register (new Sub.Builtin_Help);
Sub.Register (new CLIC_Ex.Commands.TTY.Instance);
20 changes: 17 additions & 3 deletions example/src/clic_ex-commands.adb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
with AAA.Strings;

with CLIC.TTY;
with CLIC.Formatter;
with CLIC.User_Input;
with CLIC.Config.Load;

@@ -22,6 +22,9 @@ package body CLIC_Ex.Commands is
No_TTY : aliased Boolean := False;
-- Used to disable control characters in output

Markdown_Help : aliased Boolean := False;
-- Used to enable help display in markdown format

-------------------------
-- Set_Global_Switches --
-------------------------
@@ -50,6 +53,13 @@ package body CLIC_Ex.Commands is
No_TTY'Access,
Long_Switch => "--no-tty",
Help => "Disables control characters in output");

Define_Switch (Config,
Markdown_Help'Access,
Long_Switch => "--markdown",
Help =>
"Enables output of markdown format for help");

end Set_Global_Switches;

-------------
@@ -61,11 +71,15 @@ package body CLIC_Ex.Commands is
Sub_Cmd.Parse_Global_Switches;

if No_TTY then
CLIC.TTY.Force_Disable_TTY;
CLIC.Formatter.Force_Disable_TTY;
end if;

if Markdown_Help then
CLIC.Formatter.Enable_Markdown;
end if;

if not No_Color and then not No_TTY then
CLIC.TTY.Enable_Color (Force => False);
CLIC.Formatter.Enable_Color (Force => False);
-- This may still not enable color if TTY is detected to be incapable
end if;

12 changes: 6 additions & 6 deletions example/src/clic_ex-commands.ads
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
private with Ada.Text_IO;
private with GNAT.OS_Lib;
private with CLIC.Subcommand.Instance;
private with CLIC.TTY;
private with CLIC.Formatter;
private with CLIC.Config;

package CLIC_Ex.Commands is
@@ -24,9 +24,9 @@ private
Put_Line => Ada.Text_IO.Put_Line,
Put_Error => Ada.Text_IO.Put_Line,
Error_Exit => GNAT.OS_Lib.OS_Exit,
TTY_Chapter => CLIC.TTY.Info,
TTY_Description => CLIC.TTY.Description,
TTY_Version => CLIC.TTY.Version,
TTY_Underline => CLIC.TTY.Underline,
TTY_Emph => CLIC.TTY.Emph);
TTY_Chapter => CLIC.Formatter.Chapter,
TTY_Description => CLIC.Formatter.Description,
TTY_Version => CLIC.Formatter.Version,
TTY_Underline => CLIC.Formatter.Underline,
TTY_Emph => CLIC.Formatter.Emph);
end CLIC_Ex.Commands;
2 changes: 1 addition & 1 deletion src/clic-config.ads
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ package CLIC.Config with Preelaborate is
access function (Key : Config_Key; Value : TOML.TOML_Value)
return Boolean;
-- Return False when a Key/Value combination is not valid. Can be used to
-- check formating of string value like email address for instance.
-- check formatting of string value like email address for instance.

procedure Import (This : in out Instance;
Table : TOML.TOML_Value;
49 changes: 49 additions & 0 deletions src/clic-formatter.adb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
with CLIC.TTY;
with CLIC.Markdown;

package body CLIC.Formatter is

Markdown_Enabled : Boolean := False;

procedure Enable_Markdown is
begin
Markdown_Enabled := True;
end Enable_Markdown;

procedure Force_Disable_TTY renames TTY.Force_Disable_TTY;
procedure Enable_Color (Force : Boolean := False)
renames TTY.Enable_Color;

function Chapter (Str : String) return String is
(if Markdown_Enabled
then Markdown.Chapter (Str)
else TTY.Bold (Str));

function Description (Str : String) return String is
(if Markdown_Enabled
then Markdown.Code (Str)
else TTY.Description (Str));

function Version (Str : String) return String is
(if Markdown_Enabled
then Markdown.Italic (Str)
else TTY.Version (Str));

function Underline (Str : String) return String is
(if Markdown_Enabled
then Str
else TTY.Underline (Str));

-- Emph is used to highlight switches, so we use Code for the markdown
-- version.
function Emph (Str : String) return String is
(if Markdown_Enabled
then Markdown.Code (Str)
else TTY.Emph (Str));

function Terminal (Str : String) return String is
(if Markdown_Enabled
then Markdown.Code (Str)
else TTY.Terminal (Str));

end CLIC.Formatter;
23 changes: 23 additions & 0 deletions src/clic-formatter.ads
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package CLIC.Formatter
with Preelaborate
is

-- Provides markdown or TTY formatting for displaying help pages.

procedure Force_Disable_TTY;

procedure Enable_Markdown;
-- Enables markdown output of formatting functions.

procedure Enable_Color (Force : Boolean := False);
-- Prepares colors for the terminal output. Unless Force, will do nothing
-- if a console redirection is detected.

function Chapter (Str : String) return String;
function Description (Str : String) return String;
function Version (Str : String) return String;
function Underline (Str : String) return String;
function Emph (Str : String) return String;
function Terminal (Str : String) return String;

end CLIC.Formatter;
20 changes: 20 additions & 0 deletions src/clic-markdown.adb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
with AAA.Strings;

package body CLIC.Markdown is

function Chapter (Str : String) return String is
("### " & Str);

function Plain_Text (Str : String) return String is
(Str);

function Code (Str : String) return String is
('`' & Str & '`');

function Bold (Str : String) return String is
('*' & Str & '*');

function Italic (Str : String) return String is
('_' & Str & '_');

end CLIC.Markdown;
12 changes: 12 additions & 0 deletions src/clic-markdown.ads
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

package CLIC.Markdown
with Preelaborate
is

function Chapter (Str : String) return String;
function Plain_Text (Str : String) return String;
function Code (Str : String) return String;
function Bold (Str : String) return String;
function Italic (Str : String) return String;

end CLIC.Markdown;
67 changes: 55 additions & 12 deletions src/clic-subcommand-instance.adb
Original file line number Diff line number Diff line change
@@ -389,14 +389,15 @@ package body CLIC.Subcommand.Instance is
return;
end if;

Put_Line ("");
Put_Line (TTY_Chapter ("ALIASES"));

for Elt in Registered_Aliases.Iterate loop
Table.New_Row;
Table.Append (Tab);
Table.Append (TTY_Description (To_String (Key (Elt))));
Table.Append (Tab);
Table.Append (Element (Elt).Flatten);
Table.Append (TTY_Terminal (Element (Elt).Flatten));
end loop;

Table.Print (Separator => " ", Put_Line => Put_Line_For_Access'Access);
@@ -418,11 +419,11 @@ package body CLIC.Subcommand.Instance is
Put_Line (TTY_Chapter ("USAGE"));
Put (" ");
Put_Line
(TTY_Underline (Main_Command_Name) &
(TTY_Terminal (TTY_Underline (Main_Command_Name) &
" " &
TTY_Underline (Cmd.Name) &
" [options] " &
Cmd.Usage_Custom_Parameters);
Cmd.Usage_Custom_Parameters));

-- We use the following two canaries to detect if a command is adding
-- its own switches, in which case we need to show their specific help.
@@ -472,13 +473,13 @@ package body CLIC.Subcommand.Instance is
end if;

Put_Line (TTY_Chapter ("USAGE"));
Put_Line (" " & TTY_Underline (Main_Command_Name) &
Put_Line (" " & TTY_Terminal (TTY_Underline (Main_Command_Name) &
" [global options] " &
"<command> [command options] [<arguments>]");
"<command> [command options] [<arguments>]"));
Put_Line ("");
Put_Line (" " & TTY_Underline (Main_Command_Name) & " " &
Put_Line (" " & TTY_Terminal (TTY_Underline (Main_Command_Name) & " " &
TTY_Underline ("help") &
" [<command>|<topic>]");
" [<command>|<topic>]"));

Put_Line ("");
Put_Line (TTY_Chapter ("ARGUMENTS"));
@@ -496,7 +497,7 @@ package body CLIC.Subcommand.Instance is
Table.Append (TTY_Description ("<arguments>"));
Table.Append ("List of arguments for the command");

Table.Print (Separator => " ",
Table.Print (Separator => " ",
Put_Line => Put_Line_For_Access'Access);
end;

@@ -877,14 +878,16 @@ package body CLIC.Subcommand.Instance is

if Has_Short and Has_Long then
Table.Append (TTY_Description (Without_Arg (Short_Switch)) &
" (" & With_Arg (Long_Switch, Arg) & ")");
" (" & TTY_Description (With_Arg (Long_Switch, Arg)) & ")");
elsif not Has_Short and Has_Long then
Table.Append (TTY_Description (With_Arg (Long_Switch, Arg)));
elsif Has_Short and not Has_Long then
Table.Append (TTY_Description (With_Arg (Short_Switch, Arg)));
end if;

Table.Append (Help);
-- Adding two spaces at the end will ensure a new line when printing in
-- markdown format.
Table.Append (Help & " ");

Has_Printable_Rows := True;
end Print_Row;
@@ -956,6 +959,46 @@ package body CLIC.Subcommand.Instance is
end if;
end Display_Help;

----------------------
-- Iterate_Commands --
----------------------

procedure Iterate_Commands
(Process : not null access procedure (Group : Ada.Strings.Unbounded.Unbounded_String;
Cmd : not null Command_Access)) is
use Command_Maps;
use Group_Maps;
begin

for Iter in Registered_Groups.Iterate loop

declare
Group : constant Unbounded_String := Key (Iter);
begin

for Name of Element (Iter) loop
Process (Group, Registered_Commands (To_Unbounded_String (Name)));
end loop;
end;
end loop;

end Iterate_Commands;

--------------------
-- Iterate_Topics --
--------------------

procedure Iterate_Topics
(Process : not null access procedure (Cmd : not null Help_Topic_Access)) is
begin

for Topic of Registered_Topics loop
Process (Topic);
end loop;

end Iterate_Topics;


-------------
-- Execute --
-------------
@@ -973,8 +1016,8 @@ package body CLIC.Subcommand.Instance is
end if;

Put_Line (TTY_Chapter ("USAGE"));
Put_Line (" " & TTY_Underline (Main_Command_Name) & " " &
TTY_Underline ("help") & " [<command>|<topic>]");
Put_Line (" " & TTY_Terminal (TTY_Underline (Main_Command_Name) & " " &
TTY_Underline ("help") & " [<command>|<topic>]"));

Put_Line ("");
Put_Line (TTY_Chapter ("ARGUMENTS"));
23 changes: 19 additions & 4 deletions src/clic-subcommand-instance.ads
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
-- Instantiate this package to create a sub-command parser/executor

with Ada.Strings.Unbounded;

with CLIC.Config;

generic
@@ -20,13 +22,16 @@ generic
-- Used to signal that the program should terminate with the give error
-- code. Typicaly use GNAT.OS_Lib.OS_Exit.

-- The procedures below are used to format the output such as usage and
-- help. Use CLIC.Subcommand.No_TTY if you don't want or need formating.
-- The functions below are used to format the output such as usage and
-- help. Use CLIC.Subcommand.No_TTY if you don't want or need formatting.
-- CLIC also provides ready implementations in CLIC.Formatter, CLIC.TTY
-- and CLIC.Markdown.
with function TTY_Chapter (Str : String) return String;
with function TTY_Description (Str : String) return String;
with function TTY_Version (Str : String) return String;
with function TTY_Underline (Str : String) return String;
with function TTY_Emph (Str : String) return String;
with function TTY_Terminal (Str : String) return String;

Global_Options_In_subcommand_help : Boolean := True;
-- When listing help for a subcommand, also include a section on global
@@ -89,6 +94,16 @@ package CLIC.Subcommand.Instance is

procedure Display_Help (Keyword : String);

procedure Iterate_Commands
(Process : not null access procedure (Group : Ada.Strings.Unbounded.Unbounded_String;
Cmd : not null Command_Access));
-- Iterate over all registered commands sorted by group applying Process

procedure Iterate_Topics
(Process : not null access procedure (Cmd : not null Help_Topic_Access));
-- Iterate all registered topics applying Process


Error_No_Command : exception;
Command_Already_Defined : exception;

@@ -121,9 +136,9 @@ private
is (AAA.Strings.Empty_Vector
.Append ("Shows information about commands and topics.")
.Append ("See available commands with '" &
Main_Command_Name & " help commands'")
TTY_Terminal (Main_Command_Name & " help commands") & "'")
.Append ("See available topics with '" &
Main_Command_Name & " help topics'."));
TTY_Terminal (Main_Command_Name & " help topics") & "'."));

overriding
procedure Setup_Switches
4 changes: 2 additions & 2 deletions src/clic-subcommand.ads
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ package CLIC.Subcommand is
-----------------

type Help_Topic is limited interface;
-- This type encapsulate the content of an "help topic", i.e. a piece of
-- This type encapsulates the content of an "help topic", i.e. a piece of
-- documentation that can displayed from the command line.

type Help_Topic_Access is access all Help_Topic'Class;
@@ -165,7 +165,7 @@ package CLIC.Subcommand is
function No_TTY (Str : String) return String
is (Str);
-- Use this function for the TTY_* generic parameters of
-- CLIC.Subcommand.Instance if you don't want or need TTY formating.
-- CLIC.Subcommand.Instance if you don't want or need TTY formatting.

private

2 changes: 1 addition & 1 deletion src/clic-tty.ads
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ is

procedure Force_Disable_TTY
with Post => not Is_TTY;
-- Disable TTY support even if availabe
-- Disable TTY support even if available

--------------------
-- Color enabling --