Added alias resolution for PlantUML annotations

This commit is contained in:
Bartek Kryza
2021-05-27 00:31:44 +02:00
parent eec8057fc0
commit ce02432178
6 changed files with 77 additions and 4 deletions

View File

@@ -327,8 +327,18 @@ public:
{ {
ostr << "@startuml" << std::endl; ostr << "@startuml" << std::endl;
for (const auto &b : m_config.puml.before) for (const auto &b : m_config.puml.before) {
ostr << b << std::endl; std::string note{b};
std::tuple<std::string, size_t, size_t> alias_match;
while (util::find_element_alias(note, alias_match)) {
auto alias = m_model.to_alias(m_config.using_namespace,
ns_relative(
m_config.using_namespace, std::get<0>(alias_match)));
note.replace(
std::get<1>(alias_match), std::get<2>(alias_match), alias);
}
ostr << note << std::endl;
}
if (m_config.should_include_entities("classes")) { if (m_config.should_include_entities("classes")) {
for (const auto &c : m_model.classes) { for (const auto &c : m_model.classes) {
@@ -353,8 +363,19 @@ public:
ostr << std::endl; ostr << std::endl;
} }
for (const auto &b : m_config.puml.after) // Process aliases in any of the puml directives
ostr << b << std::endl; for (const auto &b : m_config.puml.after) {
std::string note{b};
std::tuple<std::string, size_t, size_t> alias_match;
while (util::find_element_alias(note, alias_match)) {
auto alias = m_model.to_alias(m_config.using_namespace,
ns_relative(
m_config.using_namespace, std::get<0>(alias_match)));
note.replace(
std::get<1>(alias_match), std::get<2>(alias_match), alias);
}
ostr << note << std::endl;
}
ostr << "@enduml" << std::endl; ostr << "@enduml" << std::endl;
} }

View File

@@ -20,10 +20,18 @@
#include <stdexcept> #include <stdexcept>
namespace clanguml::error { namespace clanguml::error {
struct uml_alias_missing : public virtual std::runtime_error { struct uml_alias_missing : public virtual std::runtime_error {
uml_alias_missing(const std::string &message) uml_alias_missing(const std::string &message)
: std::runtime_error(message) : std::runtime_error(message)
{ {
} }
}; };
struct substring_delimiter_not_found : public virtual std::runtime_error {
substring_delimiter_not_found(const std::string &message)
: std::runtime_error(message)
{
}
};
} }

View File

@@ -19,6 +19,8 @@
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <regex>
namespace clanguml { namespace clanguml {
namespace util { namespace util {
@@ -101,5 +103,28 @@ std::string unqualify(const std::string &s)
return fmt::format("{}", fmt::join(toks, " ")); return fmt::format("{}", fmt::join(toks, " "));
} }
bool find_element_alias(
const std::string &input, std::tuple<std::string, size_t, size_t> &result)
{
std::regex alias_regex("(@A\\([^\\).]+\\))");
auto alias_it =
std::sregex_iterator(input.begin(), input.end(), alias_regex);
auto end_it = std::sregex_iterator();
if (alias_it == end_it)
return false;
std::smatch match = *alias_it;
std::string alias = match.str().substr(3, match.str().size() - 4);
std::get<0>(result) = alias;
std::get<1>(result) = match.position();
std::get<2>(result) = match.length();
return true;
}
} }
} }

View File

@@ -91,5 +91,18 @@ std::string ns_relative(
* @return Unqualified type spelling. * @return Unqualified type spelling.
*/ */
std::string unqualify(const std::string &s); std::string unqualify(const std::string &s);
/**
* @brief Find element alias in Puml note
*
* Finds aliases of the form @A(entity_name) in the Puml notes
* or directives.
* The match, if any, is returned in the result tuple:
* (entity_name, offset, length)
*
* @return True if match was found
*/
bool find_element_alias(
const std::string &input, std::tuple<std::string, size_t, size_t> &result);
} }
} }

View File

@@ -10,3 +10,6 @@ diagrams:
include: include:
namespaces: namespaces:
- clanguml::t00002 - clanguml::t00002
plantuml:
after:
- 'note left of @A(A) : Base abstract interface.'

View File

@@ -10,3 +10,6 @@ diagrams:
include: include:
namespaces: namespaces:
- clanguml::t00012 - clanguml::t00012
plantuml:
after:
- 'note right of @A(C<std::map<int,std::vector<std::vector<std::vector<std::string>>>>,3,3,3>) : Long template annotation'