#pragma once #include // #include "source.h" #include "katom_list.h" #include "klammer_registry.h" #include "klammerset_registry.h" #include "option_set_registry.h" #include "target_registry.h" #include "argtype_registry.h" #include "state.h" #include "error.h" class Machine { public: using input_sources_t = std::vector>; Machine(); // Copy constructor Machine(const Machine& other) : m_argtypes(other.m_argtypes) , m_state(other.m_state) , m_targets(other.m_targets) , m_klammers(other.m_klammers) , m_klammersets(other.m_klammersets) , m_option_sets(other.m_option_sets) , m_result(other.m_result) {} // Copy assignment operator Machine& operator=(const Machine& other) { if (this != &other) { m_argtypes = other.m_argtypes; m_state = other.m_state; m_targets = other.m_targets; m_klammers = other.m_klammers; m_klammersets = other.m_klammersets; m_option_sets = other.m_option_sets; m_result = other.m_result; } return *this; } // @cond is resolved at APPLICATION time, not read time (Andy, 2026-08-15, // deciding notes/Klammertext_improvements.md ยง4.2). mark_cond_content() // runs during process_katoms and makes every branch inert; // resolve_cond_katoms() runs inside the apply fold, selects a branch, and // processes only that one. The document then behaves like a klammer body: // its state variables are bound before its conditionals are decided. void mark_cond_content(std::vector& katoms); int resolve_cond_katoms(std::vector& katoms, const std::string& target); void process_eval_katoms(std::vector& katoms); void mark_literal_klammer_content(std::vector& katoms); void escape_target_characters(const Target& target, std::vector& katoms); // std::vector void process_katoms( std::vector& katoms, const std::string& source, bool nonascii=true, bool literal=true, bool ignore=true, bool whitespace=true, bool klammers=true, bool eval=true, bool cond=true, bool read=true); std::vector process( std::string text, const std::string& source, bool nonascii=true, bool literal=true, bool ignore=true, bool whitespace=true, bool klammers=true, bool eval=true, bool cond=true, bool read=true); void read(const fs::path& pathname); void read(const std::string& s); void expand_read_katoms( std::vector& katoms, std::string source_filename, bool nonascii=true, bool literal=true, bool ignore=true, bool ws=true, bool klammers=true, bool eval=true, bool cond=true, bool read=true); void expand_constant_klammers(katom_list& katoms, const Katom& op, const Katom& cl); void add_definition(katom_list& katoms, const Katom& op, const Katom& cl); void load_klammerset_files(const Klammerset& klammerset, katom_iter insert_at); // `tolerant` is for kdiag ONLY. It dissects the structure and typing of // the katom list, and allows modes of processing that would be errors in // ktext: run one definition tier without the other and a definition may // be unregisterable (a klammer names a target that "--system" would have // registered). Tolerant then SKIPS that definition instead of throwing, // leaving its katoms unconsumed and therefore visible -- which is the // report. ktext must keep throwing: there, a document naming an // undefined target is a genuine error, and skipping it silently would // render a wrong document. void add_machine_definition(const std::string& name, katom_iter begin, katom_iter end, bool& rescan); void extract_machine_definitions(bool tolerant = false); void extract_klammer_definitions(bool tolerant = false); void extract_klammer_definitions(katom_list katoms); void update_state(const std::map& arg_map); katom_list apply_klammer(Klammer& klammer, const std::string& target, katom_iter arguments_begin, katom_iter arguments_end); void apply_klammer_registry(Klammer_registry& klammer_registry, katom_list& katoms, const std::string& target, katom_iter begin, katom_iter end); // Returns the number of klammers applied in this pass. The top-level // fixed point loops while that count is nonzero: reduction is detected by // a redex having been reduced, not by the katom list having grown. int apply(Klammer_registry& klammer_registry, katom_list& katoms, const std::string& target); std::string run_phase_functions(); std::string apply(const std::string& target_name, bool final_processing=true, bool escape_characters=true); Argtype_registry m_argtypes {}; State m_state {}; Target_registry m_targets {}; Klammer_registry m_klammers {}; Klammerset_registry m_klammersets {}; Option_set_registry m_option_sets {}; input_sources_t m_sources {}; std::string m_result {}; std::vector m_katoms {}; // False on the sub-Machine that re-reads an @eval result (Eval::eval): // result text is machine-generated -- a renderer's raw target markup // (e.g. a LaTeX column spec "@{}...") legitimately fails katom parsing // and must not produce "Word not parsed" warnings. bool m_warn_unparsed = true; }; /* class Machine { private: std::string m_name; int m_id; std::vector m_sources; bool m_active; double m_value; public: // Default constructor Machine() : m_name(""), m_id(0), m_sources(), m_active(false), m_value(0.0) {} // Copy constructor Machine(const Machine& other) : m_name(other.m_name) // Copy name , m_id(other.m_id) // Copy id , m_sources() // Initialize m_sources as empty , m_active(other.m_active) // Copy active status , m_value(other.m_value) // Copy value { // m_sources is now empty, ready for new initialization } // Assignment operator (if needed) Machine& operator=(const Machine& other) { if (this != &other) { m_name = other.m_name; m_id = other.m_id; m_sources.clear(); // Clear and leave empty m_active = other.m_active; m_value = other.m_value; } return *this; } }; */