working now

v1
Brett 2023-11-30 19:56:45 -05:00
parent b248d9ef91
commit e2b278e8bd
2 changed files with 104 additions and 45 deletions

View File

@ -12,7 +12,9 @@
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include <optional>
#include <cctype> #include <cctype>
#include <unordered_set>
#include <blt/compatibility.h> #include <blt/compatibility.h>
namespace blt::string namespace blt::string
@ -120,6 +122,29 @@ namespace blt::string
#endif #endif
} }
static inline std::optional<std::vector<size_t>> containsAll(const std::string& string, const std::unordered_set<char>& search)
{
std::vector<size_t> pos;
for (size_t i = 0; i < string.length(); i++)
{
if (BLT_CONTAINS(search, string[i]))
pos.push_back(i);
}
if (!pos.empty())
return pos;
return {};
}
static inline size_t contains(const std::string& string, const std::unordered_set<char>& search)
{
for (size_t i = 0; i < string.length(); i++)
{
if (BLT_CONTAINS(search, string[i]))
return i;
}
return false;
}
static inline BLT_CPP20_CONSTEXPR bool contains(const std::string& string, const char search) static inline BLT_CPP20_CONSTEXPR bool contains(const std::string& string, const char search)
{ {
#if __cplusplus >= 202002L #if __cplusplus >= 202002L

View File

@ -4,6 +4,7 @@
* See LICENSE file for license detail * See LICENSE file for license detail
*/ */
#include <blt/std/format.h> #include <blt/std/format.h>
#include <blt/std/string.h>
#include <cmath> #include <cmath>
#include "blt/std/logging.h" #include "blt/std/logging.h"
#include "blt/std/assert.h" #include "blt/std/assert.h"
@ -169,6 +170,7 @@ std::vector<std::string> blt::string::TreeFormatter::construct()
// construct a stack of the highest node -> the lowest node. // construct a stack of the highest node -> the lowest node.
level_data currentLevel; level_data currentLevel;
currentLevel.depth = 0; currentLevel.depth = 0;
size_t maxLineLength = 0;
while (!bfs.empty()) while (!bfs.empty())
{ {
auto n = bfs.front(); auto n = bfs.front();
@ -182,6 +184,15 @@ std::vector<std::string> blt::string::TreeFormatter::construct()
{ {
auto box = generateBox(n.node); auto box = generateBox(n.node);
currentLevel.max_horizontal_length = std::max(currentLevel.max_horizontal_length, box[0].size()); currentLevel.max_horizontal_length = std::max(currentLevel.max_horizontal_length, box[0].size());
std::string replacement = "-";
// UGLY TODO: fix this
if (n.node->left != nullptr)
replacement = "$";
else if (n.node->right != nullptr)
replacement = "#";
if (replacement[0] == '$' && n.node->right != nullptr)
replacement = "@";
blt::string::replaceAll(box.front(), "%", replacement);
n.box = std::move(box); n.box = std::move(box);
} }
currentLevel.level.push_back(n); currentLevel.level.push_back(n);
@ -204,6 +215,7 @@ std::vector<std::string> blt::string::TreeFormatter::construct()
size_t lineLength = 0; size_t lineLength = 0;
const size_t lineHeight = format.verticalPadding * 2 + 3; const size_t lineHeight = format.verticalPadding * 2 + 3;
//std::cout << levels.size() << "\n"; //std::cout << levels.size() << "\n";
const size_t verticalSpacing = format.verticalSpacing % 2 == 0 ? format.verticalSpacing + 1 : format.verticalSpacing;
while (!levels.empty()) while (!levels.empty())
{ {
std::vector<std::string> currentLines; std::vector<std::string> currentLines;
@ -238,57 +250,79 @@ std::vector<std::string> blt::string::TreeFormatter::construct()
{ {
lineLength = std::max(lineLength, v.length()); lineLength = std::max(lineLength, v.length());
lines.push_back(createPadding(padLength) + v); lines.push_back(createPadding(padLength) + v);
maxLineLength = std::max(maxLineLength, lines.back().length());
} }
levels.pop(); levels.pop();
//if (!levels.empty()) if (!levels.empty())
// for (int i = 0; i < format.verticalSpacing; i++) for (size_t i = 0; i < verticalSpacing; i++)
// lines.emplace_back("&"); lines.emplace_back(" ");
} }
size_t index = 1; for (auto& line : lines)
size_t startLine = 0; if (line.length() < maxLineLength)
size_t endLine = 0; line += createPadding(maxLineLength - line.length());
while (index < lines.size() - 1)
{
auto& line = lines[index];
size_t beginMarkerIndex = 0;
size_t endMarkerIndex = 0;
startLine = index++;
beginMarkerIndex = line.find('%');
if (beginMarkerIndex != std::string::npos)
{
// find endLine we need to connect with
while (index < lines.size())
{
auto& line2 = lines[index];
endMarkerIndex = line2.find('%');
if (endMarkerIndex != std::string::npos)
{
endLine = index;
break;
}
index++;
}
while (true)
{
if (beginMarkerIndex == std::string::npos || endMarkerIndex == std::string::npos)
break;
BLT_TRACE(std::abs(static_cast<std::int64_t>(endMarkerIndex) - static_cast<std::int64_t>(beginMarkerIndex)));
auto connector = createPadding(std::abs(static_cast<std::int64_t>(endMarkerIndex) - static_cast<std::int64_t>(beginMarkerIndex)), '-');
auto frontPad = createPadding(std::min(beginMarkerIndex, endMarkerIndex));
lines.insert(lines.begin() + static_cast<std::int64_t>(startLine) + 1, frontPad += connector);
index++;
beginMarkerIndex = line.find('%', beginMarkerIndex + 1);
endMarkerIndex = line.find('%', endMarkerIndex + 1);
}
index++;
}
}
std::reverse(lines.begin(), lines.end()); std::reverse(lines.begin(), lines.end());
size_t index = 1;
while (index < lines.size())
{
if (auto poses = blt::string::containsAll(lines[index], std::unordered_set{'$', '#', '@'}))
{
const auto& nextLine = lines[index + verticalSpacing + 1];
auto poses2 = blt::string::containsAll(nextLine, std::unordered_set{'%'}).value();
size_t consume = 0;
for (auto p : poses.value())
{
char type = lines[index][p];
for (size_t n = 0; n < verticalSpacing / 2; n++)
lines[index + n + 1][p] = '|';
lines[index + (verticalSpacing / 2) + 1][p] = '+';
auto start = index + (verticalSpacing / 2) + 1;
switch (type)
{
case '@':
for (size_t i = poses2[consume] + 1; i < poses2[consume + 1]; i++)
lines[start][i] = '-';
lines[start][poses2[consume]] = '+';
lines[start][poses2[consume + 1]] = '+';
for (size_t n = 0; n < verticalSpacing / 2; n++)
{
lines[start + n + 1][poses2[consume]] = '|';
lines[start + n + 1][poses2[consume + 1]] = '|';
}
consume += 2;
break;
case '$':
for (size_t i = poses2[consume] + 1; i < p; i++)
lines[start][i] = '-';
lines[start][poses2[consume]] = '+';
lines[start][p] = '+';
for (size_t n = 0; n < verticalSpacing / 2; n++)
lines[start + n + 1][poses2[consume]] = '|';
consume++;
break;
case '#':
for (size_t i = p; i < poses2[consume]; i++)
lines[start][i] = '-';
lines[start][poses2[consume]] = '+';
lines[start][p] = '+';
for (size_t n = 0; n < verticalSpacing / 2; n++)
lines[start + n + 1][poses2[consume]] = '|';
consume++;
break;
default:
break;
}
}
}
blt::string::replaceAll(lines[index], "%", "+");
blt::string::replaceAll(lines[index], "#", "+");
blt::string::replaceAll(lines[index], "@", "+");
blt::string::replaceAll(lines[index], "$", "+");
index++;
}
blt::string::replaceAll(lines.front(), "%", "-");
return lines; return lines;
} }