#pragma once #include #include #include "locator.h" #include "katom.h" #include "argtype.h" #include "argument.h" #include "klammer.h" #include "klammer_registry.h" #include "klammerset_registry.h" #include "state.h" #include "target_registry.h" #include "machine.h" #include "file.h" using namespace std::string_literals; const std::string middle_dot { "\uFF65" }; const std::string broken_bar { "\u00A6" }; const std::string right_arrow { "\uFFEB" }; const std::string sp_arrow { " \u2192 " }; const std::string right_bracket { "\u27E9" }; const std::string left_bracket { "\u27E8" }; const std::string bbar { "¦" }; const std::string left_double_bracket { "\u27E6" }; const std::string right_double_bracket { "\u27E7" }; const std::string left_square_bracket { "\u2045" }; const std::string right_square_bracket { "\u2046" }; const std::string check { "\u2713" }; // A colour is a STREAM-AWARE object, not a string, because the same name is // written to two streams whose destinations differ: "ktext -d > doc.txt" has a // file on stdout and a terminal on stderr at the same time, so one global // on/off cannot be right for both. Inserting a Color emits its escape // sequence only when THAT stream is a terminal, so escape codes can never // reach a redirected document, a pipe, or a captured log. // // Streams other than std::cout/std::cerr -- a stringstream building an error // message, a file -- are never coloured. That is the conservative reading and // it also stops escapes from being baked into strings whose length is then // measured (abbreviate() in util.cpp counted them). class Color { public: explicit Color(const std::string& code) : m_code(code) {} // The raw sequence, for the rare place that needs a string rather than an // insertion. Prefer inserting the Color: this form cannot be suppressed. const std::string& code() const { return m_code; } private: std::string m_code {}; }; // True when colour should be emitted on this stream: it is a terminal and the // NO_COLOR environment variable is unset. NO_COLOR (https://no-color.org) is // honoured for ANY non-empty value, which is what the convention specifies; it // is the escape hatch for the case isatty cannot see, such as a pager or a CI // capture that does want, or does not want, colour. bool color_enabled(const std::ostream& os); std::ostream& operator<<(std::ostream& os, const Color& color); const Color black("\033[0;30m"); const Color boldblack("\033[1;30m"); const Color green("\033[0;32m"); const Color boldgreen("\033[1;32m"); const Color cyan("\033[0;36m"); const Color blue("\033[0;34m"); const Color boldblue("\033[1;34m"); const Color magenta("\033[0;35m"); const Color red("\033[31m"); const Color yellow("\033[0;33m"); const Color reset("\033[0m"); const auto seqout = [](auto x) { std::cout << "seq: " << x << "\n"; }; //const auto mapout = [](auto m) { auto const& key std::cout << m.first << sp_arrow << m.second << "\n"; }; const auto mapout = [](auto const& kv){ auto const& [k, v] = kv; std::cout << k << sp_arrow << v << "\n"; }; inline const std::set sks_commands = { "ktext"s, "kdesc"s, "kdiag"s, "argument_test"s, "argtype_test"s }; std::ostream& msg(Locator loc=Locator()); std::ostream& fmsg(Locator loc=Locator()); std::vector abbrev(const std::vector& ks, unsigned int max_length=16); // std::vector std::ostream& operator<<(std::ostream& os, const std::vector& ns); // std::vector std::ostream& operator<<(std::ostream& os, const std::vector& ss); // std::vector std::ostream& operator<<(std::ostream& os, const std::vector& pp); // std::map std::ostream& operator<<(std::ostream& os, const std::map& sm); // Katom iterator pair std::ostream& operator<<( std::ostream& os, const std::pair::iterator, std::vector::iterator>& iters); // Locator std::ostream& operator<<(std::ostream& os, const Locator& loc); // Katom std::ostream& operator<<(std::ostream& os, const Katom& k); std::ostream& operator<<(std::ostream& os, const std::vector>& ks); std::ostream& operator<<(std::ostream& os, const std::shared_ptr& k); std::ostream& operator<<(std::ostream& os, const std::vector::iterator& k); std::ostream& operator<<(std::ostream& os, const std::vector& ks); std::ostream& operator<<(std::ostream& os, const std::vector::iterator>& ks); std::ostream& kindex(std::ostream& os); std::ostream& ktype(std::ostream& os); std::ostream& klevel(std::ostream& os); // std::ostream& kspans(std::ostream& os); std::ostream& kws(std::ostream& os); std::ostream& kall(std::ostream& os); std::ostream& kreplaced(std::ostream& os); std::ostream& kignored(std::ostream& os); std::ostream& kreset(std::ostream& os); inline static std::string newline_symbol = "/"; std::ostream& operator<<(std::ostream& os, const std::vector& ks); std::ostream& operator<<(std::ostream& os, const std::vector& ks); // Argtype std::ostream& operator<<(std::ostream& os, const Argtype& a); // Parameter (aliased as Argument at application sites) std::ostream& operator<<(std::ostream& os, const Parameter& p); // Parameter_set (aliased as Argument_set at application sites) std::ostream& operator<<(std::ostream& os, const Parameter_set& as); // std::vector std::ostream& operator<<(std::ostream& os, const std::vector& as); // Var std::ostream& operator<<(std::ostream& os, const Var& v); // Frame std::ostream& operator<<(std::ostream& os, const Frame& f); // State std::ostream& operator<<(std::ostream& os, const State& s); // Klammer std::ostream& operator<<(std::ostream& os, const Klammer& k); // Klammer::variable_map_t std::ostream& operator<<(std::ostream& os, const Klammer::variable_map_t& vm); // Klammer::components std::ostream& operator<<(std::ostream& os, const Klammer::components& kc); // Klammer_registry std::ostream& operator<<(std::ostream& os, const Klammer_registry& ks); // Target std::ostream& operator<<(std::ostream& os, const Target& t); // Target_registry std::ostream& operator<<(std::ostream& os, const Target_registry& ts); // Klammerset std::ostream& operator<<(std::ostream& os, const Klammerset& ks); // Klammerset_registry std::ostream& operator<<(std::ostream& os, const Klammerset_registry& kr); // Machine std::ostream& operator<<(std::ostream& os, const Machine& m); void modify_stream(const std::string& name);