#pragma once #include #include #include #include "klammerset.h" #include "argument_set.h" #include "katom.h" class Klammerset_registry { public: Klammerset_registry(); void add(Klammerset klammerset); // Parse a @@@klammerset span. Returns the new Klammerset so the // Machine can load its files, or nullopt when the symbol is already // registered: a klammerset is loaded once, and a repeated declaration // (typically reached through :requires) is skipped, not an error. std::optional add(std::vector::iterator begin, std::vector::iterator end, std::vector& katoms); void check_symbol(const std::string& symbol, const Locator& loc) const; // Symbol X must be declared in X/X.k, so that the symbol is a function of // the path and the already-loaded guard can run before a file is read. void check_declaring_file(const std::string& symbol, const Locator& loc) const; bool has(const std::string& symbol) const; Klammerset get(const std::string& symbol, const Locator& loc) const; std::string describe(int margin=2, bool long_format=false) const; // Record what a set actually opened (see Klammerset::m_loaded_files). void set_loaded_files(const std::string& symbol, const strings_t& files); // Every file every registered klammerset read. A klammer whose // definitions all come from these was supplied by a klammerset; one with // a definition elsewhere was defined by the input -- which is the // distinction "kdesc -i" needs, since it loads a klammerset in order to // analyse a file without wanting to LIST the klammerset's own klammers. strings_t loaded_files() const; std::map m_klammersets {}; std::vector m_symbols {}; Parameter_set m_parameters {}; }; // --- The klammerset search path (symbol -> declaration file) --- // A bare identifier (letters, digits, underscores; starts with a letter) // names a klammerset symbol; anything else -- a path component, an // extension, a space -- is a filename used as given. bool is_klammerset_symbol(const std::string& name); // The directories searched for a klammerset symbol, most specific first: // 1. local_dir -- the directory of whatever names the symbol: the input // document's directory (ktext -k), the declaring file's directory // (:requires), or the cwd when there is no document // 2. the KLAMMERTEXT_KLAMMERSETS directories (colon-separated; default // ~/.klammertext/klammersets), in listed order // 3. $KLAMMERTEXT_HOME (the distribution's sets, e.g. sks/sks.k) // A symbol x resolves to the first /x/x.k found, so a document-local // set shadows an installed one, which shadows a distributed one. (This is // deliberately the OPPOSITE order from the @eval module path, which puts // the SKS directories first: a stray util.py next to a document shadowing // an SKS module is an everyday accident, while a directory named sks/ // holding an sks.k next to a manuscript is not.) std::vector klammerset_search_dirs(const std::string& local_dir); // Resolve a symbol to its declaration file; first hit wins. Throws a // Klammerset_error naming the searched directories when nothing matches. fs::path resolve_klammerset_symbol( const std::string& symbol, const std::string& local_dir, const Locator& loc); // The symbols available on the search path, with provenance; a symbol // found again in a later directory is marked as shadowed. For // kdesc --klammersets. std::string describe_klammerset_search(const std::string& local_dir, int margin=2);