Assembled from klammertext-dev f344a37d772c. The commands, the library,
the Standard Klammer Set, the reflection klammerset and the Python
binding build and run natively on Windows (MSYS2 UCRT64 gcc, python.org
Python), and both test tiers pass there. doc/install/windows_source_install.md
is the fifth install guide: a source install parallel to the Linux and
macOS ones, verified by following it on a pristine Windows 11.
Behaviour on every system: paths Klammertext prints use forward slashes;
output is LF; the command line is UTF-8 on Windows; @eval :shell is a
POSIX shell command everywhere -- on Windows it runs the sh Klammertext
ships, BusyBox for Windows (win/busybox/, GPLv2, with its licence and the
source pointer). KLAMMERTEXT_FONTS and KLAMMERTEXT_KLAMMERSETS are lists in
the system's PATH convention (';' on Windows). On Linux and macOS nothing
observable changes.
174 lines
5.5 KiB
C++
174 lines
5.5 KiB
C++
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include "error.h"
|
|
#include "util.h"
|
|
#include "katom.h"
|
|
#include "kutil.h"
|
|
#include "show.h"
|
|
|
|
#include <filesystem>
|
|
|
|
std::string read_file(const std::string& filename)
|
|
{
|
|
std::ifstream stream {};
|
|
std::ostringstream buffer {};
|
|
stream.open(filename);
|
|
if (stream.is_open()) {
|
|
stream >> buffer.rdbuf();
|
|
} else {
|
|
std::cout << "File not opened\n";
|
|
}
|
|
return buffer.str();
|
|
}
|
|
|
|
|
|
std::string klammertext_dir()
|
|
{
|
|
std::string khome { "KLAMMERTEXT_HOME" };
|
|
char* kdir = getenv(khome.c_str());
|
|
if (kdir == nullptr) {
|
|
std::stringstream ss {};
|
|
ss << "The environment variable " << q_(khome) << " is not defined";
|
|
throw Environment_error(ss.str());
|
|
}
|
|
return kdir;
|
|
}
|
|
|
|
bool in_subset(const std::string& base, const std::vector<std::string>& subset)
|
|
{
|
|
return subset.empty() ||
|
|
(std::find(subset.begin(), subset.end(), base) != subset.end());
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> sks_files_of_type(const std::string& extension, const std::vector<std::string>& subset)
|
|
{
|
|
bool dbg = false;
|
|
std::string kdir = klammertext_dir();
|
|
std::vector<std::string> result {};
|
|
if (dbg) msg() << "Extension: " << extension << "\n";
|
|
for (auto base : sks_basenames) {
|
|
std::string ext_dir { kdir + "/sks/" + base + "/" + extension };
|
|
if (file_exists(ext_dir)) {
|
|
std::string list_filename { ext_dir + "/list.txt" };
|
|
if (file_exists(list_filename)) {
|
|
if (dbg) msg() << " List: " << list_filename << "\n";
|
|
std::string list = string_from_file(list_filename);
|
|
for (auto s : regex_split(list, std::regex(R"(\n+)"), true)) { // split_lines(list)) {
|
|
if (s[0] == '#')
|
|
continue;
|
|
std::string ext_filename = { ext_dir + "/" + s };
|
|
if (!file_exists(ext_filename)) {
|
|
std::string msg = "File " + ext_filename + " in " + list_filename + " does not exist";
|
|
throw Internal_error(msg);
|
|
}
|
|
if (in_subset(fs::path(s).stem().string(), subset)) {
|
|
if (dbg) msg() << " Add: " << ext_filename << "\n";
|
|
result.push_back(ext_filename);
|
|
}
|
|
}
|
|
} else {
|
|
for (auto f : get_files_in_directory(ext_dir)) {
|
|
if (f[f.size()-1] != '~') {
|
|
if (in_subset(fs::path(f).stem().string(), subset)) {
|
|
result.push_back(ext_dir + "/" + f);
|
|
if (dbg) msg() << " Add: " << f << "\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
std::string find_kt_file(const std::string& filename)
|
|
{
|
|
std::string result {};
|
|
std::vector<std::string> prefix {"", "kt/"};
|
|
std::vector<std::string> suffix {"", ".kt"};
|
|
std::vector<std::string> all_possible {};
|
|
for (auto p : prefix) {
|
|
for (auto s : suffix) {
|
|
std::string possible { p + filename + s };
|
|
//std::cout << "Checking: " << possible << "\n";
|
|
if (file_exists(possible, false)) {
|
|
result = possible;
|
|
all_possible.push_back(possible);
|
|
break;
|
|
}
|
|
}
|
|
if (result.size() > 0) {
|
|
break;
|
|
}
|
|
}
|
|
if (result.size() == 0) {
|
|
std::cout << "Filename \"" << filename << "\" does not exist and\ndoes not match any of the default patterns:\n";
|
|
for (std::string f : all_possible) {
|
|
std::cout << " " << f << "\n";
|
|
}
|
|
exit(1);
|
|
}
|
|
//std::cout << " Found: " << result << "\n";
|
|
return result;
|
|
}
|
|
|
|
|
|
std::string caption_marker(const std::string& name, const std::string& caption, const std::string& delimiter)
|
|
{
|
|
std::string result {caption};
|
|
if (caption.size() > 0) {
|
|
result = delimiter + caption;
|
|
}
|
|
result = caption_delimiter + name + caption_delimiter + result + caption_delimiter;
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
std::string process(Machine& M, const std::string& target, const fs::path& source_filename,
|
|
bool post_process, bool unescape_chars)
|
|
{
|
|
// Text text(source_filename, false, false);
|
|
Source source;
|
|
source.read(source_filename
|
|
text.parse();
|
|
M.preserve_parse(text);
|
|
M.extract_definitions(text);
|
|
M.apply(target, text);
|
|
std::string processed = M.to_string(target, text, post_process, unescape_chars);
|
|
//processed = modify_whitespace_string(processed);
|
|
//M.restore_parse(text);
|
|
return processed;
|
|
}
|
|
|
|
std::string process(Machine& M, const std::string& target, const std::string& source_text,
|
|
bool post_process, bool unescape_chars)
|
|
{
|
|
Text text(source_text, false, false);
|
|
text.parse();
|
|
M.preserve_parse(text);
|
|
M.extract_definitions(text);
|
|
M.apply(target, text);
|
|
std::string processed = M.to_string(target, text, post_process, unescape_chars);
|
|
//M.restore_parse(text);
|
|
return processed;
|
|
}
|
|
|
|
std::string process(Machine& M, const std::string& target,
|
|
const std::string& source_text, const fs::path& source_filename,
|
|
bool post_process, bool unescape_chars)
|
|
{
|
|
Text text({source_text}, {source_filename}, false, false);
|
|
text.parse();
|
|
M.preserve_parse(text);
|
|
M.extract_definitions(text);
|
|
M.apply(target, text);
|
|
std::string processed = M.to_string(target, text, post_process, unescape_chars);
|
|
//M.restore_parse(text);
|
|
return processed;
|
|
}
|
|
*/
|