Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <functional>
- #include <iostream>
- #include <numeric>
- #include <queue>
- #include <stack>
- #include <string>
- #include <vector>
- using namespace std;
- string substring(const string& s, string::size_type begin, string::size_type end) {
- return s.substr(begin, (end == string::npos ? s.size() : end) - begin);
- }
- string joined(const vector<string>& stringList, const char* joiner = "\n")
- {
- assert(!stringList.empty());
- return accumulate(next(stringList.cbegin()), stringList.cend(), stringList.front(), [&](const string& s1, const string& s2) {
- return s1 + joiner + s2;
- });
- }
- vector<string> split(const string& s, const string& separator = "\n", const function<string(string)>& lineTransform = [](string&& s){ return s; })
- {
- vector<string> lines;
- assert(!separator.empty());
- string::size_type findPos = 0;
- for (;;) {
- auto separatorPos = s.find(separator, findPos);
- lines.emplace_back(lineTransform(substring(s, findPos, separatorPos)));
- if (separatorPos == string::npos)
- break;
- findPos = separatorPos + separator.size();
- }
- return lines;
- }
- string buildColoredString(const string& s, const string& color)
- {
- return "<span style='color: " + color + "'>" + s + "</span>";
- }
- struct ColoredEntry {
- string text;
- string color;
- bool addLineBreak;
- };
- int main(int argc, char const *argv[])
- {
- for (int i = 1; i < argc; ++i) {
- string text = argv[i];
- string::size_type findPos = 0;
- string color = "white";
- vector<pair<string, string>> coloredParts;
- for (;;) {
- auto colorStartPos = text.find('\\', findPos);
- coloredParts.emplace_back(color, substring(text, findPos, colorStartPos));
- if (colorStartPos == string::npos) {
- break;
- }
- // TODO: handle npos
- auto colorEndPos = text.find(';', ++colorStartPos);
- // if (colorEndPos == string::npos) {
- // continue;
- // }
- findPos = colorEndPos + 1;
- color = substring(text, colorStartPos, colorEndPos);
- }
- assert(!coloredParts.empty());
- stack<queue<ColoredEntry>> entries;
- decltype(entries)::value_type* lastEntry = nullptr;
- for (const auto& it : coloredParts) {
- auto color = it.first;
- auto lines = split(it.second);
- for (const auto& line : lines) {
- ColoredEntry e;
- e.text = line;
- e.color = color;
- auto moveToQueue = [&](decltype(entries)::value_type& queue) {
- queue.emplace(std::move(e));
- };
- if (lastEntry) {
- assert(!lastEntry->empty());
- // prevents adding useless items with empty text that won't have line break
- if (lastEntry->front().text.empty())
- lastEntry->pop();
- moveToQueue(*lastEntry);
- lastEntry = nullptr;
- } else {
- decltype(entries)::value_type q;
- moveToQueue(q);
- entries.emplace(std::move(q));
- }
- }
- lastEntry = &entries.top();
- }
- assert(!entries.empty());
- vector<ColoredEntry> output;
- do {
- auto& q = entries.top();
- do {
- auto& e = q.front();
- e.addLineBreak = false;
- output.emplace_back(std::move(e));
- q.pop();
- } while (!q.empty());
- output.back().addLineBreak = true;
- entries.pop();
- } while (!entries.empty());
- assert(!output.empty());
- output.back().addLineBreak = false;
- // JSON
- cout << "[\n";
- for (const auto& it : output) {
- cout << "\t{\n";
- cout << "\t\t\"text\": " << "\"" << it.text << "\",\n";
- cout << "\t\t\"color\": " << "\"" << it.color << "\",\n";
- cout << "\t\t\"addLineBreak\": " << (it.addLineBreak ? "true" : "false") << "\n";
- cout << "\t},\n";
- }
- cout << "]\n\n";
- /*
- // HTML
- cout << "<<br />\n";
- for (const auto& it : output) {
- if (!it.text.empty())
- cout << buildColoredString(it.text, it.color);
- if (it.addLineBreak)
- cout << "<br />\n";
- }
- cout << "\n<br />><br /><br /><br />\n\n";
- // plain text
- for (const auto& it : output) {
- cout << it.text;
- if (it.addLineBreak)
- cout << "\n";
- }
- cout << "\n";
- */
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement