Updated code for Doxygen documentation

This commit is contained in:
Bartek Kryza
2023-06-23 19:39:25 +02:00
parent d8ef12d1c6
commit 321fb177a9
148 changed files with 579 additions and 204 deletions

View File

@@ -90,4 +90,10 @@ void decorated_element::append(const decorated_element &de)
std::optional<comment_t> decorated_element::comment() const { return comment_; }
void decorated_element::set_comment(const comment_t &c) { comment_ = c; }
std::optional<std::string> decorated_element::doxygen_link() const
{
return std::nullopt;
}
} // namespace clanguml::common::model

View File

@@ -47,6 +47,8 @@ using comment_t = inja::json;
*/
class decorated_element {
public:
virtual ~decorated_element() = default;
/**
* Whether this element should be skipped from the diagram.
*
@@ -125,6 +127,13 @@ public:
*/
void set_comment(const comment_t &c);
/**
* Return Doxygen HTML documentation link for the element.
*
* @return Element context.
*/
virtual std::optional<std::string> doxygen_link() const;
private:
std::vector<std::shared_ptr<decorators::decorator>> decorators_;
std::optional<comment_t> comment_;

View File

@@ -68,12 +68,12 @@ bool diagram::should_include(const element &e) const
filter_->should_include(dynamic_cast<const source_location &>(e));
}
bool diagram::should_include(const std::string &name) const
bool diagram::should_include(const namespace_ &ns) const
{
if (filter_.get() == nullptr)
return true;
return filter_->should_include(name);
return filter_->should_include(ns);
}
bool diagram::should_include(const relationship_t r) const

View File

@@ -132,7 +132,7 @@ public:
// TODO: refactor to a template method
bool should_include(const element &e) const;
bool should_include(const std::string &e) const;
bool should_include(const namespace_ &ns) const;
bool should_include(const source_file &path) const;
bool should_include(relationship r) const;
bool should_include(relationship_t r) const;

View File

@@ -73,8 +73,12 @@ inja::json diagram_element::context() const
{
inja::json ctx;
ctx["name"] = name();
ctx["type"] = type_name();
ctx["alias"] = alias();
ctx["full_name"] = full_name(false);
auto maybe_doxygen_link = doxygen_link();
if (maybe_doxygen_link)
ctx["doxygen_link"] = maybe_doxygen_link.value();
return ctx;
}

View File

@@ -186,60 +186,100 @@ tvl::value_t namespace_filter::match(
if (ns.is_empty())
return {};
return tvl::any_of(
namespaces_.begin(), namespaces_.end(), [&ns](const auto &nsit) {
return tvl::any_of(namespaces_.begin(), namespaces_.end(),
[&ns, is_inclusive = is_inclusive()](const auto &nsit) {
if (std::holds_alternative<namespace_>(nsit.value())) {
const auto &ns_pattern = std::get<namespace_>(nsit.value());
return ns.starts_with(ns_pattern) || ns == ns_pattern;
if (is_inclusive)
return ns.starts_with(ns_pattern) ||
ns_pattern.starts_with(ns);
return ns.starts_with(ns_pattern);
}
const auto &regex = std::get<common::regex>(nsit.value());
return regex == ns.to_string();
return regex %= ns.to_string();
});
}
tvl::value_t namespace_filter::match(
const diagram & /*d*/, const element &e) const
tvl::value_t namespace_filter::match(const diagram &d, const element &e) const
{
if (dynamic_cast<const package *>(&e) != nullptr) {
return tvl::any_of(namespaces_.begin(), namespaces_.end(),
if (d.type() != diagram_t::kPackage &&
dynamic_cast<const package *>(&e) != nullptr) {
auto result = tvl::any_of(namespaces_.begin(), namespaces_.end(),
[&e, is_inclusive = is_inclusive()](const auto &nsit) {
if (std::holds_alternative<namespace_>(nsit.value())) {
const auto &ns_pattern = std::get<namespace_>(nsit.value());
auto element_full_name_starts_with_namespace =
(e.get_namespace() | e.name()).starts_with(ns_pattern);
namespace_{e.name_and_ns()}.starts_with(ns_pattern);
auto element_full_name_equals_pattern =
(e.get_namespace() | e.name()) == ns_pattern;
namespace_{e.name_and_ns()} == ns_pattern;
auto namespace_starts_with_element_qualified_name =
ns_pattern.starts_with(e.get_namespace());
auto pattern_starts_with_element_full_name =
ns_pattern.starts_with(namespace_{e.name_and_ns()});
auto result = element_full_name_starts_with_namespace ||
element_full_name_equals_pattern;
if (is_inclusive)
result = result ||
namespace_starts_with_element_qualified_name;
result =
result || pattern_starts_with_element_full_name;
return result;
}
return std::get<common::regex>(nsit.value()) ==
return std::get<common::regex>(nsit.value()) %=
e.full_name(false);
});
if (tvl::is_false(result))
LOG_DBG("Element {} rejected by namespace_filter 1",
e.full_name(false));
return result;
}
return tvl::any_of(
if (d.type() == diagram_t::kPackage) {
auto result = tvl::any_of(namespaces_.begin(), namespaces_.end(),
[&e, is_inclusive = is_inclusive()](const auto &nsit) {
if (std::holds_alternative<namespace_>(nsit.value())) {
auto e_ns = namespace_{e.full_name(false)};
auto nsit_ns = std::get<namespace_>(nsit.value());
if (is_inclusive)
return e_ns.starts_with(nsit_ns) ||
nsit_ns.starts_with(e_ns) || e_ns == nsit_ns;
else
return e_ns.starts_with(nsit_ns) || e_ns == nsit_ns;
}
return std::get<common::regex>(nsit.value()) %=
e.full_name(false);
});
if (tvl::is_false(result))
LOG_DBG("Element {} rejected by namespace_filter (package diagram)",
e.full_name(false));
return result;
}
auto result = tvl::any_of(
namespaces_.begin(), namespaces_.end(), [&e](const auto &nsit) {
if (std::holds_alternative<namespace_>(nsit.value())) {
return e.get_namespace().starts_with(
std::get<namespace_>(nsit.value()));
}
return std::get<common::regex>(nsit.value()) == e.full_name(false);
return std::get<common::regex>(nsit.value()) %= e.full_name(false);
});
if (tvl::is_false(result))
LOG_DBG("Element {} rejected by namespace_filter", e.full_name(false));
return result;
}
element_filter::element_filter(
@@ -249,9 +289,12 @@ element_filter::element_filter(
{
}
tvl::value_t element_filter::match(
const diagram & /*d*/, const element &e) const
tvl::value_t element_filter::match(const diagram &d, const element &e) const
{
// Do not apply element filter to packages in class diagrams
if (d.type() == diagram_t::kClass && e.type_name() == "package")
return std::nullopt;
return tvl::any_of(
elements_.begin(), elements_.end(), [&e](const auto &el) {
return ((el == e.full_name(false)) ||

View File

@@ -34,11 +34,7 @@ const namespace_ &element::using_namespace() const { return using_namespace_; }
inja::json element::context() const
{
inja::json ctx;
ctx["name"] = name();
ctx["type"] = type_name();
ctx["alias"] = alias();
ctx["full_name"] = full_name(false);
inja::json ctx = diagram_element::context();
ctx["namespace"] = get_namespace().to_string();
if (const auto maybe_comment = comment(); maybe_comment.has_value()) {
ctx["comment"] = maybe_comment.value();

View File

@@ -40,4 +40,11 @@ bool package::is_deprecated() const { return is_deprecated_; }
void package::set_deprecated(bool deprecated) { is_deprecated_ = deprecated; }
std::optional<std::string> package::doxygen_link() const
{
auto name = full_name(false);
util::replace_all(name, "_", "__");
util::replace_all(name, "::", "_1_1");
return fmt::format("namespace{}.html", name);
}
} // namespace clanguml::common::model

View File

@@ -67,11 +67,14 @@ public:
void set_deprecated(bool deprecated);
/**
* Add subpackage.
* @brief Generate Doxygen style HTML link for the class.
*
* @param p Package.
* This method generates a link, which can be used in SVG diagrams to
* create links from classes to Doxygen documentation pages.
*
* @return Doxygen-style HTML link for the class.
*/
void add_package(std::unique_ptr<common::model::package> &&p);
std::optional<std::string> doxygen_link() const override;
private:
bool is_deprecated_{false};

View File

@@ -150,7 +150,7 @@ inline value_t any_of(InputIterator first, InputIterator last, Predicate pred)
if (m.has_value()) {
if (m.value()) {
res = true;
break;
return res;
}
res = false;
}