);
}
void write_branch_table(
std::ostream& ost, const repository& repo, const std::string& branch_name
hemplate::element branch_table(
const repository& repo, const std::string& branch_name
)
{
using namespace hemplate::html; // NOLINT
ost << h2("Branches");
wtable(
ost,
{" ", "Name", "Last commit date", "Author"},
repo.get_branches(),
[&](const auto& branch)
{
const auto& last = branch.get_last_commit();
const auto url = branch.get_name() != branch_name
? std::format("../{}/refs.html", branch.get_name())
: "";
const auto name = branch.get_name() == branch_name ? "*" : " ";
return tr {
td {name},
td {a {{{"href", url}}, branch.get_name()}},
td {last.get_time()},
td {last.get_author_name()},
};
}
);
return transparent {
h2 {"Branches"},
wtable(
{" ", "Name", "Last commit date", "Author"},
repo.get_branches(),
[&](const auto& branch)
{
const auto& last = branch.get_last_commit();
const auto url = branch.get_name() != branch_name
? std::format("../{}/refs.html", branch.get_name())
: "";
const auto name = branch.get_name() == branch_name ? "*" : " ";
return tr {
td {name},
td {a {{{"href", url}}, branch.get_name()}},
td {last.get_time()},
td {last.get_author_name()},
};
}
),
};
}
void write_tag_table(std::ostream& ost, const repository& repo)
hemplate::element tag_table(const repository& repo)
{
using namespace hemplate::html; // NOLINT
ost << h2("Tags");
wtable(
ost,
{" ", "Name", "Last commit date", "Author"},
repo.get_tags(),
[&](const auto& tag)
{
return tr {
td {" "},
td {tag.get_name()},
td {tag.get_time()},
td {tag.get_author()},
};
}
);
return transparent {
h2 {"Tags"},
wtable(
{" ", "Name", "Last commit date", "Author"},
repo.get_tags(),
[&](const auto& tag)
{
return tr {
td {" "},
td {tag.get_name()},
td {tag.get_time()},
td {tag.get_author()},
};
}
),
};
}
void write_file_changes(std::ostream& ost, const diff& diff)
hemplate::element file_changes(const diff& diff)
{
using namespace hemplate::html; // NOLINT
ost << b("Diffstat:");
wtable(
ost,
{},
diff.get_deltas(),
[&](const auto& delta)
{
static const char* marker = " ADMRC T ";
return transparent {
b {"Diffstat:"},
wtable(
{},
diff.get_deltas(),
[&](const auto& delta)
{
static const char* marker = " ADMRC T ";
const std::string link = std::format("#{}", delta->new_file.path);
const std::string link = std::format("#{}", delta->new_file.path);
uint32_t add = delta.get_adds();
uint32_t del = delta.get_dels();
const uint32_t changed = add + del;
const uint32_t total = 80;
if (changed > total) {
const double percent = 1.0 * total / changed;
uint32_t add = delta.get_adds();
uint32_t del = delta.get_dels();
const uint32_t changed = add + del;
const uint32_t total = 80;
if (changed > total) {
const double percent = 1.0 * total / changed;
if (add > 0) {
add = static_cast<uint32_t>(std::lround(percent * add) + 1);
}
if (add > 0) {
add = static_cast<uint32_t>(std::lround(percent * add) + 1);
}
if (del > 0) {
del = static_cast<uint32_t>(std::lround(percent * del) + 1);
if (del > 0) {
del = static_cast<uint32_t>(std::lround(percent * del) + 1);
}
}
return tr {
td {std::string(1, marker[delta->status])}, // NOLINT
td {a {{{"href", link}}, delta->new_file.path}},
td {"|"},
td {
span {{{"class", "add"}}, std::string(add, '+')},
span {{{"class", "del"}}, std::string(del, '-')},
},
};
}
}
),
return tr {
td {std::string(1, marker[delta->status])}, // NOLINT
td {a {{{"href", link}}, delta->new_file.path}},
td {"|"},
td {
span {{{"class", "add"}}, std::string(add, '+')},
span {{{"class", "del"}}, std::string(del, '-')},
},
};
}
);
p {
std::format(
"{} files changed, {} insertions(+), {} deletions(-)",
diff.get_files_changed(),
diff.get_insertions(),
diff.get_deletions()
),
},
};
}
ost << p {
std::format(
"{} files changed, {} insertions(+), {} deletions(-)",
diff.get_files_changed(),
diff.get_insertions(),
diff.get_deletions()
),
hemplate::element diff_hunk(const hunk& hunk)
{
using namespace hemplate::html; // NOLINT
const std::string header(hunk->header); // NOLINT
return transparent {
h4 {
text {
std::format(
"@@ -{},{} +{},{} @@ ",
hunk->old_start,
hunk->old_lines,
hunk->new_start,
hunk->new_lines
),
},
text {
xmlencode(header.substr(header.rfind('@') + 2)),
},
span {
{{"style", "white-space: pre"}},
transform(
hunk.get_lines(),
[](const auto& line) -> element
{
using hemplate::html::div;
if (line.is_add()) {
return div {
{{"class", "add"}},
xmlencode(line.get_content()),
};
}
if (line.is_del()) {
return div {
{{"class", "del"}},
xmlencode(line.get_content()),
};
}
return text {
xmlencode(line.get_content()),
};
}
),
},
},
};
}
void write_file_diffs(std::ostream& ost, const diff& diff)
hemplate::element file_diffs(const diff& diff)
{
using namespace hemplate::html; // NOLINT
ost << transform(
return transform(
diff.get_deltas(),
[&](const auto& delta)
[](const auto& delta)
{
const auto& new_file = delta->new_file.path;
const auto& old_file = delta->new_file.path;