Added comment support to inja templates in links and tooltips

This commit is contained in:
Bartek Kryza
2022-03-23 21:59:02 +01:00
parent 8c0486240f
commit eed9fcaf66
7 changed files with 145 additions and 22 deletions

View File

@@ -35,16 +35,18 @@ void generator::generate_link(
if (e.file().empty())
return;
auto context = element_context(e);
if (!m_config.generate_links().link.empty()) {
ostr << " [[[";
inja::render_to(
ostr, m_config.generate_links().link, element_context(e));
ostr << env().render(
std::string_view{m_config.generate_links().link}, context);
}
if (!m_config.generate_links().tooltip.empty()) {
ostr << "{";
inja::render_to(
ostr, m_config.generate_links().tooltip, element_context(e));
ostr << env().render(
std::string_view{m_config.generate_links().tooltip}, context);
ostr << "}";
}
ostr << "]]]";

View File

@@ -248,6 +248,9 @@ void translation_unit_visitor::process_namespace(
p->set_name(e.name());
p->set_namespace(package_parent);
if (e.comment().has_value())
p->set_comment(e.comment().value());
if (e.location().has_value()) {
p->set_file(e.location().value().file);
p->set_line(e.location().value().line);
@@ -290,6 +293,9 @@ void translation_unit_visitor::process_enum_declaration(
e.set_name(enm.name());
e.set_namespace(ctx.get_namespace());
if (enm.comment().has_value())
e.set_comment(enm.comment().value());
if (enm.location().has_value()) {
e.set_file(enm.location().value().file);
e.set_line(enm.location().value().line);
@@ -347,8 +353,10 @@ void translation_unit_visitor::process_class_declaration(
c.set_name(cls.name());
c.set_namespace(ctx.get_namespace());
if (cls.comment().has_value())
if (cls.comment().has_value()) {
c.set_comment(cls.comment().value());
c.add_decorators(decorators::parse(cls.comment().value()));
}
// Process class documentation comment
if (cppast::is_templated(cls)) {
@@ -879,6 +887,9 @@ void translation_unit_visitor::process_method(
m.is_defaulted(false);
m.is_static(false);
if (mf.comment().has_value())
m.set_comment(mf.comment().value());
if (mf.location().has_value()) {
m.set_file(mf.location().value().file);
m.set_line(mf.location().value().line);
@@ -920,6 +931,9 @@ void translation_unit_visitor::process_template_method(
m.is_defaulted(false);
m.is_static(false);
if (mf.comment().has_value())
m.set_comment(mf.comment().value());
if (mf.location().has_value()) {
m.set_file(mf.location().value().file);
m.set_line(mf.location().value().line);
@@ -956,6 +970,9 @@ void translation_unit_visitor::process_static_method(
m.is_defaulted(false);
m.is_static(true);
if (mf.comment().has_value())
m.set_comment(mf.comment().value());
if (mf.location().has_value()) {
m.set_file(mf.location().value().file);
m.set_line(mf.location().value().line);
@@ -987,6 +1004,9 @@ void translation_unit_visitor::process_constructor(
m.is_defaulted(false);
m.is_static(true);
if (mf.comment().has_value())
m.set_comment(mf.comment().value());
if (mf.location().has_value()) {
m.set_file(mf.location().value().file);
m.set_line(mf.location().value().line);
@@ -1016,6 +1036,9 @@ void translation_unit_visitor::process_destructor(
m.is_defaulted(false);
m.is_static(true);
if (mf.comment().has_value())
m.set_comment(mf.comment().value());
if (mf.location().has_value()) {
m.set_file(mf.location().value().file);
m.set_line(mf.location().value().line);

View File

@@ -45,6 +45,7 @@ public:
, m_model{model}
{
init_context();
init_env();
}
virtual ~generator() = default;
@@ -64,17 +65,23 @@ public:
void generate_link(std::ostream &ostr, const model::element &e) const;
protected:
const inja::json &context() const;
inja::Environment &env() const;
template <typename E> inja::json element_context(const E &e) const;
private:
void init_context();
void init_env();
protected:
ConfigType &m_config;
DiagramType &m_model;
inja::json m_context;
mutable inja::Environment m_env;
};
template <typename C, typename D>
@@ -90,17 +97,10 @@ const inja::json &generator<C, D>::context() const
return m_context;
}
template <typename C, typename D> void generator<C, D>::init_context()
template <typename C, typename D>
inja::Environment &generator<C, D>::env() const
{
if (m_config.git) {
m_context["git"]["branch"] = m_config.git().branch;
m_context["git"]["revision"] = m_config.git().revision;
m_context["git"]["commit"] = m_config.git().commit;
m_context["git"]["toplevel"] = m_config.git().toplevel;
}
m_context["diagram"]["name"] = m_config.name;
m_context["diagram"]["type"] = to_string(m_config.type());
return m_env;
}
template <typename C, typename D>
@@ -125,6 +125,13 @@ inja::json generator<C, D>::element_context(const E &e) const
ctx["element"]["source"]["line"] = e.line();
}
if (e.comment().has_value()) {
std::string c = e.comment().value();
if (!c.empty()) {
ctx["element"]["comment"] = util::trim(c);
}
}
return ctx;
}
@@ -197,16 +204,18 @@ void generator<C, D>::generate_link(
if (!m_config.generate_links().link.empty()) {
ostr << " [[";
inja::render_to(
ostr, m_config.generate_links().link, element_context(e));
ostr << env().render(std::string_view{m_config.generate_links().link},
element_context(e));
}
if (!m_config.generate_links().tooltip.empty()) {
ostr << "{";
inja::render_to(
ostr, m_config.generate_links().tooltip, element_context(e));
ostr << env().render(
std::string_view{m_config.generate_links().tooltip},
element_context(e));
ostr << "}";
}
ostr << "]]";
}
@@ -244,4 +253,53 @@ DiagramModel generate(const cppast::libclang_compilation_database &db,
return std::move(d);
}
template <typename C, typename D> void generator<C, D>::init_context()
{
if (m_config.git) {
m_context["git"]["branch"] = m_config.git().branch;
m_context["git"]["revision"] = m_config.git().revision;
m_context["git"]["commit"] = m_config.git().commit;
m_context["git"]["toplevel"] = m_config.git().toplevel;
}
m_context["diagram"]["name"] = m_config.name;
m_context["diagram"]["type"] = to_string(m_config.type());
}
template <typename C, typename D> void generator<C, D>::init_env()
{
// Add basic string functions to inja environment
m_env.add_callback("empty", 1, [](inja::Arguments &args) {
return args.at(0)->get<std::string>().empty();
});
m_env.add_callback("ltrim", 1, [](inja::Arguments &args) {
return util::ltrim(args.at(0)->get<std::string>());
});
m_env.add_callback("rtrim", 1, [](inja::Arguments &args) {
return util::rtrim(args.at(0)->get<std::string>());
});
m_env.add_callback("trim", 1, [](inja::Arguments &args) {
return util::trim(args.at(0)->get<std::string>());
});
m_env.add_callback("abbrv", 2, [](inja::Arguments &args) {
return util::abbreviate(
args.at(0)->get<std::string>(), args.at(1)->get<unsigned>());
});
m_env.add_callback("replace", 3, [](inja::Arguments &args) {
std::string result = args[0]->get<std::string>();
std::regex pattern(args[1]->get<std::string>());
return std::regex_replace(result, pattern, args[2]->get<std::string>());
});
m_env.add_callback("split", 2, [](inja::Arguments &args) {
return util::split(
args[0]->get<std::string>(), args[1]->get<std::string>());
});
}
}

View File

@@ -87,4 +87,11 @@ void decorated_element::append(const decorated_element &de)
decorators_.push_back(d);
}
}
std::optional<std::string> decorated_element::comment() const
{
return comment_;
}
void decorated_element::set_comment(const std::string &c) { comment_ = c; }
}

View File

@@ -22,6 +22,7 @@
#include "decorators/decorators.h"
#include <memory>
#include <optional>
#include <string>
#include <vector>
@@ -45,8 +46,13 @@ public:
void append(const decorated_element &de);
std::optional<std::string> comment() const;
void set_comment(const std::string &c);
private:
std::vector<std::shared_ptr<decorators::decorator>> decorators_;
std::optional<std::string> comment_;
};
}

View File

@@ -3,30 +3,50 @@
namespace clanguml {
namespace t00002 {
/// This is class A
class A {
public:
/// Abstract foo_a
virtual void foo_a() = 0;
/// Abstract foo_c
virtual void foo_c() = 0;
};
/// This is class B
class B : public A {
public:
virtual void foo_a() override { }
};
/// @brief This is class C - class C has a long comment
///
/// Vivamus integer non suscipit taciti mus etiam at primis tempor sagittis sit,
/// euismod libero facilisi aptent elementum felis blandit cursus gravida sociis
/// erat ante, eleifend lectus nullam dapibus netus feugiat curae curabitur est
/// ad.
class C : public A {
public:
/// Do nothing unless override is provided
virtual void foo_c() override { }
};
/// This is class D
/// which is a little like B
/// and a little like C
class D : public B, public C {
public:
/**
* Forward foo_a
*/
void foo_a() override
{
for (auto a : as)
a->foo_a();
}
/**
* Forward foo_c
*/
void foo_c() override
{
for (auto a : as)
@@ -34,6 +54,7 @@ public:
}
private:
/// All the A pointers
std::vector<A *> as;
};
@@ -44,12 +65,18 @@ private:
//
class E : virtual public B, virtual public C {
public:
///
/// Forward foo_a
///
void foo_a() override
{
for (auto a : as)
a->foo_a();
}
///
/// Forward foo_c
///
void foo_c() override
{
for (auto a : as)
@@ -57,6 +84,7 @@ public:
}
private:
/// All the A pointers
std::vector<A *> as;
};
}

View File

@@ -24,9 +24,8 @@ void inject_diagram_options(std::shared_ptr<clanguml::config::diagram> diagram)
{
// Inject links config to all test cases
clanguml::config::generate_links_config links_config{
"https://github.com/bkryza/clang-uml/blob/{{ git.commit }}/{{ "
"element.source.path }}#L{{ element.source.line }}",
"{{ element.name }}"};
R"(https://github.com/bkryza/clang-uml/blob/{{ git.commit }}/{{ element.source.path }}#L{{ element.source.line }})",
R"({% if "comment" in element %}{{ abbrv(trim(replace(element.comment, "\n+", " ")), 256) }}{% else %}{{ element.name }}{% endif %})"};
diagram->generate_links.set(links_config);
}