-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
448 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
|
||
#include <fmt/format.h> | ||
|
||
#include "color.h" | ||
|
||
namespace color { | ||
|
||
namespace impl { | ||
bool use = true; | ||
} | ||
|
||
void default_color() { | ||
// enable color by default | ||
set_color(true); | ||
|
||
// disable color if NO_COLOR env. variable is set | ||
if (std::getenv("NO_COLOR")) { | ||
set_color(false); | ||
} | ||
|
||
// disable color if stdout is not a terminal | ||
if (!isatty(fileno(stdout))) { | ||
set_color(false); | ||
} | ||
} | ||
|
||
void set_color(bool v) { | ||
impl::use = v; | ||
} | ||
|
||
bool use_color() { | ||
return impl::use; | ||
} | ||
|
||
} // namespace color |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#pragma once | ||
|
||
#include <fmt/color.h> | ||
|
||
#define MAKE_COLOR(color) \ | ||
static auto color() { \ | ||
return fmt::emphasis::bold | fg(fmt::terminal_color::color); \ | ||
} \ | ||
template <typename S> constexpr auto color(const S& s) { \ | ||
return use_color() ? fmt::format(color(), "{}", s) : std::string(s); \ | ||
} | ||
|
||
namespace color { | ||
|
||
void default_color(); | ||
void set_color(bool v); | ||
bool use_color(); | ||
|
||
MAKE_COLOR(black) | ||
MAKE_COLOR(red) | ||
MAKE_COLOR(green) | ||
MAKE_COLOR(yellow) | ||
MAKE_COLOR(blue) | ||
MAKE_COLOR(magenta) | ||
MAKE_COLOR(cyan) | ||
MAKE_COLOR(white) | ||
MAKE_COLOR(bright_black) | ||
MAKE_COLOR(bright_red) | ||
MAKE_COLOR(bright_green) | ||
MAKE_COLOR(bright_yellow) | ||
MAKE_COLOR(bright_blue) | ||
MAKE_COLOR(bright_magenta) | ||
MAKE_COLOR(bright_cyan) | ||
MAKE_COLOR(bright_white) | ||
|
||
} // namespace color |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#include <string> | ||
|
||
#include "fmt/format.h" | ||
|
||
#include "color.h" | ||
#include "help.h" | ||
|
||
namespace help { | ||
|
||
block::block(std::string msg) : kind(none), lines{std::move(msg)} { | ||
} | ||
|
||
std::string render(const linebreak&) { | ||
return ""; | ||
} | ||
|
||
std::string render(const block& b) { | ||
using enum help::block::admonition; | ||
std::string result{}; | ||
switch (b.kind) { | ||
case none: | ||
case code: | ||
break; | ||
case note: | ||
result += fmt::format("{} - ", ::color::cyan("Note")); | ||
break; | ||
case xmpl: | ||
result += fmt::format("{} - ", ::color::blue("Example")); | ||
break; | ||
case info: | ||
result += fmt::format("{} - ", ::color::green("Info")); | ||
break; | ||
case warn: | ||
result += fmt::format("{} - ", ::color::red("Warning")); | ||
break; | ||
case depr: | ||
result += fmt::format("{} - ", ::color::red("Deprecated")); | ||
} | ||
bool first = true; | ||
for (auto& l : b.lines) { | ||
if (!first) { | ||
result += "\n"; | ||
} | ||
if (b.kind == code) { | ||
result += fmt::format(" {}", ::color::white(l)); | ||
} else { | ||
result += l; | ||
} | ||
first = false; | ||
} | ||
|
||
return result; | ||
} | ||
|
||
} // namespace help |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include <fmt/color.h> | ||
#include <fmt/format.h> | ||
|
||
#include "color.h" | ||
|
||
namespace help { | ||
|
||
struct lst { | ||
std::string content; | ||
}; | ||
|
||
struct block { | ||
enum class admonition : std::uint32_t { | ||
none, | ||
note, | ||
xmpl, | ||
code, | ||
info, | ||
warn, | ||
depr | ||
}; | ||
using enum admonition; | ||
admonition kind = none; | ||
std::vector<std::string> lines; | ||
|
||
block() = default; | ||
block(std::string); | ||
template <typename... Args> | ||
block(admonition k, Args&&... args) | ||
: kind(k), lines{std::forward<Args>(args)...} { | ||
} | ||
}; | ||
std::string render(const block&); | ||
|
||
struct linebreak {}; | ||
std::string render(const linebreak&); | ||
|
||
// type erasure for items to print in a help message. | ||
// any type T for which the following is provided will be supported | ||
// std::string render(const T&) | ||
template <typename T> | ||
concept Renderable = requires(T v) { | ||
{ render(v) } -> std::convertible_to<std::string>; | ||
}; | ||
|
||
class item { | ||
public: | ||
template <Renderable T> | ||
item(T impl) : impl_(std::make_unique<wrap<T>>(std::move(impl))) { | ||
} | ||
|
||
item(item&& other) = default; | ||
|
||
item(const item& other) : impl_(other.impl_->clone()) { | ||
} | ||
|
||
item& operator=(item&& other) = default; | ||
item& operator=(const item& other) { | ||
return *this = item(other); | ||
} | ||
|
||
std::string render() const { | ||
return impl_->render(); | ||
} | ||
|
||
private: | ||
struct interface { | ||
virtual ~interface() { | ||
} | ||
virtual std::unique_ptr<interface> clone() = 0; | ||
virtual std::string render() const = 0; | ||
}; | ||
|
||
std::unique_ptr<interface> impl_; | ||
|
||
template <Renderable T> struct wrap : interface { | ||
explicit wrap(const T& impl) : wrapped(impl) { | ||
} | ||
explicit wrap(T&& impl) : wrapped(std::move(impl)) { | ||
} | ||
|
||
virtual std::unique_ptr<interface> clone() override { | ||
return std::unique_ptr<interface>(new wrap<T>(wrapped)); | ||
} | ||
|
||
virtual std::string render() const override { | ||
return help::render(wrapped); | ||
} | ||
|
||
T wrapped; | ||
}; | ||
}; | ||
|
||
} // namespace help | ||
|
||
template <> class fmt::formatter<help::item> { | ||
public: | ||
// parse format specification and store it: | ||
constexpr auto parse(format_parse_context& ctx) { | ||
return ctx.end(); | ||
} | ||
// format a value using stored specification: | ||
template <typename FmtContext> | ||
constexpr auto format(help::item const& item, FmtContext& ctx) const { | ||
return fmt::format_to(ctx.out(), "{}", item.render()); | ||
} | ||
}; | ||
|
||
template <> class fmt::formatter<help::lst> { | ||
public: | ||
// parse format specification and store it: | ||
constexpr auto parse(format_parse_context& ctx) { | ||
return ctx.end(); | ||
} | ||
// format a value using stored specification: | ||
template <typename FmtContext> | ||
constexpr auto format(help::lst const& l, FmtContext& ctx) const { | ||
return fmt::format_to(ctx.out(), "{}", ::color::yellow(l.content)); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.