Home
Software
Utilities
About
Reader (night2.cpp)
https://www.centaur.pw/software/night/night2.cpp
[
Direct Link
]
/* Night (night2) * 1/30/2026 * Version 2.3 * Jon Siragusa <jon@centaur.pw> * https://www.centaur.pw/ * * Copyright (C) Centaur, 2026. All Rights Reserved. * * night2.cpp */ #include "night2.h" /* Function definitions */ int lines(string str) { int o = 1; for (unsigned int i = 0 ; i < str.length(); i++) { if (str[i] == 10) o++; } return o; } string* str2array(string str) { static string arraystr[MAX_LINES]; stringstream ss(str); int i = 0; for (string line; getline(ss, line); i++) { arraystr[i] = line; } return arraystr; } string box(string str) { int c = lines(str); if (c > MAX_LINES) return str; if (c == 1) { string r = ""; r += BOX_TOP_LEFT_CORNER; for (unsigned int i = 0; i < strip_night(str).length() + 2; i++) r += BOX_HORIZONTAL_LINE; r += BOX_TOP_RIGHT_CORNER; r += "\n"; r += BOX_VERTICAL_LINE; r += ' ' + night2(str) + ' ' + BOX_VERTICAL_LINE; r += "\n"; r += BOX_BOTTOM_LEFT_CORNER; for (unsigned int i = 0; i < strip_night(str).length() + 2; i++) r += BOX_HORIZONTAL_LINE; r += BOX_BOTTOM_RIGHT_CORNER; return r; } else { string* x; x = str2array(str); int numlines = lines(str); unsigned int longest = 0; for (int i = 0; i < numlines; i++) { if (strlen(strip_night(x[i]).c_str()) > longest) longest = strlen(strip_night(x[i]).c_str()); } string r = ""; r += BOX_TOP_LEFT_CORNER; for (unsigned int i = 0; i < longest + 2; i++) r += BOX_HORIZONTAL_LINE; r += BOX_TOP_RIGHT_CORNER; r += "\n"; for (int i = 0; i < numlines; i++) { string j = ""; j += BOX_VERTICAL_LINE; j += ' ' + night2(x[i]) + (strlen(strip_night(x[i]).c_str()) == longest ? "" : string(longest - strlen(strip_night(x[i]).c_str()), ' ')) + ' ' + BOX_VERTICAL_LINE; r += j; r += "\n"; } r += BOX_BOTTOM_LEFT_CORNER; for (unsigned int i = 0; i < longest + 2; i++) r += BOX_HORIZONTAL_LINE; r += BOX_BOTTOM_RIGHT_CORNER; r += "\n"; return r; } } string readtag(string str, string begin_str, string end_str) { string a = str; a = replace(a, begin_str, ""); a = replace(a, end_str, ""); return a; } string center(string str) { try { int control_chars = 0; for (unsigned int i = 0; i < str.length(); i++) if (str[i] == '\e') control_chars++; string output = ""; int v = console_size.ws_col - str.length(); output.append(control_chars * 2, ' '); output.append(v / 2, ' '); output += str; return output; } catch (...) { return str; } } string replace(string str, const string f, const string r) { if (f.empty()) return str; string a = str; size_t b = 0; while ((b = a.find(f, b)) != string::npos) { a.replace(b, f.length(), r); b += r.length(); } return a; } string strip_ansi(string str) { string b = str; for (int i = 0; i < ansi_array_count; i++) if (!strcmp(ansi_array[i].c_str(), NEWLINE)) continue; else b = replace(b, ansi_array[i], ""); return b; } string strip_night(string str) { string b = str; for (int i = 0; i < night2_array_count; i++) b = replace(b, night2_array[i], ""); b = replace(b, Code_BeginCenter, ""); b = replace(b, Code_EndCenter, ""); b = replace(b, Code_BeginBox, ""); b = replace(b, Code_EndBox, ""); #if (defined(SUPPORT_OLD_CODES) && SUPPORT_OLD_CODES == 1) for (int j = 0; j < night1_array_count; j++) b = replace(b, night1_array[j], ""); #endif /* SUPPORT_OLD_CODES */ return b; } string night2(const string str) { string bc = Code_BeginCenter; string ec = Code_EndCenter; string bb = Code_BeginBox; string eb = Code_EndBox; string b = str; b = replace(b, Code_None, NONE); b = replace(b, Code_NewLine, NEWLINE); if (b.length() >= bb.length() && b.find(bb) != string::npos) return box(readtag(b, bb, eb)); for (int i = 0; i < ansi_array_count; i++) b = replace(b, night2_array[i], ansi_array[i]); #if (defined(SUPPORT_OLD_CODES) && SUPPORT_OLD_CODES == 1) for (int j = 0; j < night1_array_count; j++) b = replace(b, night1_array[j], old_ansi_array[j]); #endif /* SUPPORT_OLD_CODES */ if (b.length() >= bc.length() && b.find(bc) != string::npos) return center(readtag(b, bc, ec)); else return b; } void night2file(char file[]) { ifstream ifile(file); if (!ifile) { cout << file << ": " << strerror(errno) << endl; return; } else { for (string line; getline(ifile, line);) { if (line[0] == '#') continue; cout << night2(line) << endl; } ifile.close(); } return; } string filecontents(char file[]) { string c; ifstream ifile(file); if (!ifile) { cout << file << ": " << strerror(errno) << endl; return ""; } else { for (string line; getline(ifile, line);) { c.append(line); c.append("\n"); } ifile.close(); } return c; } /* Main function */ int main(int argc, char **argv) { if (argc < 2) { for (string line; getline(cin, line);) { cout << night2(line) << endl; } return 0; } else if (argc > 1 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0)) { cout << "Centaur Night version " << NIGHT_VERSION << endl << endl; cout << "Usage: " << argv[0] << " <file> ..." << endl; cout << " " << argv[0] << " \"`cat file`\" | \"$(cat file)\"" << endl; cout << " " << "cat file | " << argv[0] << endl; cout << " " << argv[0] << " -s | --string <string> ..." << endl; cout << " " << argv[0] << " -a | --remove-ansi <file> ..." << endl; cout << " " << argv[0] << " -n | --remove-night <file> ..." << endl; cout << " " << argv[0] << " -t | --test" << endl; cout << " " << argv[0] << " -h | --help" << endl << endl; cout << PROGRAM_HELP << endl; return 0; } else if (argc > 1 && (!strcmp(argv[1], "--test") || !strcmp(argv[1], "-t"))) { cout << night2(TEST_PATTERN) << endl; cout << night2(":center:Centered Text:.center:") << endl; return 0; } else if (argc >= 2 && (strcmp(argv[1], "--string") == 0 || strcmp(argv[1], "-s") == 0)) { string input = ""; for (int i = 2; i < argc; i++) { input = input + argv[i]; if (i + 1 != argc) input = input + " "; } cout << night2(input) << endl; return 0; } else if (argc > 1) { bool RemoveANSI = false; bool RemoveNight = false; if (!strcmp(argv[1], "--remove-ansi") || !strcmp(argv[1], "-a")) RemoveANSI = true; if (!strcmp(argv[1], "--remove-night") || !strcmp(argv[1], "-n")) RemoveNight = true; int shift = (RemoveANSI || RemoveNight) ? 1 : 0; for (int i = 1 + shift; i < argc; i++) { if (!strcmp(argv[i], "-a") || !strcmp(argv[i], "-n") || !strcmp(argv[i], "--remove-ansi") || !strcmp(argv[i], "--remove-night")) continue; if (!RemoveANSI && !RemoveNight) night2file(argv[i]); else if (RemoveANSI) cout << strip_ansi(filecontents(argv[i])); else if (RemoveNight) cout << strip_night(filecontents(argv[i])); } return 0; } }