kdesc --typeface from the reflection klammerset; a missing font directory is a row, not an error
Assembled from klammertext-dev daad6273483a. The font-store listing is rendered from ref/ (one table per search directory, in search order, with the styles each typeface holds); the search path is described, not validated, so a KLAMMERTEXT_FONTS directory that does not exist -- the default ~/.klammertext/fonts on a fresh install -- is a row saying so and the command exits 0. A typeface an earlier directory also holds is marked shadowed, with the winning directory, in a column present only when needed. The store's layout convention has one reader, fonts_in_directory(). Six kdesc suite cases pin the listing.
This commit is contained in:
1 parent
c016b3e5f3
commit
f9af1ff869
7 files changed
+188
-103
No files matched your search
@@ -1,4 +1,6 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "machine.h"
|
||||
#include "character.h"
|
||||
@@ -335,3 +337,85 @@ std::string katom_rewrite_patterns([[maybe_unused]] Machine& machine)
|
||||
kt << "table@\n";
|
||||
return kt.str();
|
||||
}
|
||||
|
||||
// A path written into generated Klammertext: the six specials and the
|
||||
// txt target's nbsp marker ~ quoted with ^, which any ASCII punctuation
|
||||
// accepts. A font directory is the user's to name, so it may hold any of them.
|
||||
static std::string kt_literal(const std::string& text)
|
||||
{
|
||||
static const std::string quoted = "@|#^:*~";
|
||||
std::string result {};
|
||||
for (char c : text) {
|
||||
if (quoted.find(c) != std::string::npos) {
|
||||
result += '^';
|
||||
}
|
||||
result += c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// The font store as a table per search directory, in search order. The
|
||||
// search path is DESCRIBED here, not validated: a directory that does not
|
||||
// exist is a row saying so, never an error, because resolve_font() skips
|
||||
// one silently (a document renders fine with it) and a fresh install has no
|
||||
// ~/.klammertext/fonts yet -- the default entry would fail every new user.
|
||||
// kdesc --klammersets treats a missing search directory the same way.
|
||||
extern "C"
|
||||
std::string klammertext_fonts([[maybe_unused]] Machine& machine)
|
||||
{
|
||||
std::stringstream kt {};
|
||||
kt << "@s2 Klammertext typefaces and font styles @\n\n";
|
||||
|
||||
// The directory each dir_name was FIRST seen in: the store searches in
|
||||
// this order and stops at the first hit, so a later one is shadowed.
|
||||
std::map<std::string, std::string> first_seen {};
|
||||
strings_t bases = installed_font_dirs();
|
||||
bases.push_back(default_font_dir());
|
||||
|
||||
for (size_t i = 0; i < bases.size(); i++) {
|
||||
const std::string& base = bases[i];
|
||||
bool is_default = (i == bases.size() - 1);
|
||||
std::string caption = is_default
|
||||
? "Klammertext default typefaces: " + kt_literal(symbolic_klammertext_filename(base))
|
||||
: "Installed typeface directory: " + kt_literal(base);
|
||||
|
||||
// Rows before the header: the "Shadowed by" column exists only in a
|
||||
// table that has something to put in it.
|
||||
struct Row { std::string family, styles, shadowed_by; };
|
||||
std::vector<Row> rows {};
|
||||
bool any_shadowed = false;
|
||||
for (const Resolved_font& font : fonts_in_directory(base)) {
|
||||
strings_t styles {};
|
||||
if (!font.regular.empty()) styles.push_back("Regular");
|
||||
if (!font.bold.empty()) styles.push_back("Bold");
|
||||
if (!font.italic.empty()) styles.push_back("Italic");
|
||||
if (!font.bold_italic.empty()) styles.push_back("BoldItalic");
|
||||
Row row { kt_literal(font.family_name), join(styles, ", "), "" };
|
||||
if (first_seen.contains(font.dir_name)) {
|
||||
row.shadowed_by = kt_literal(first_seen[font.dir_name]);
|
||||
any_shadowed = true;
|
||||
} else {
|
||||
first_seen[font.dir_name] = base;
|
||||
}
|
||||
rows.push_back(row);
|
||||
}
|
||||
|
||||
kt << "\n@table :caption " << caption << " |\n"
|
||||
<< "Typeface name | Font styles" << (any_shadowed ? " | Shadowed by" : "")
|
||||
<< " ||\n";
|
||||
if (!fs::is_directory(base)) {
|
||||
kt << "[directory does not exist] ||\n";
|
||||
} else if (rows.empty()) {
|
||||
kt << "[no fonts] ||\n";
|
||||
}
|
||||
for (const Row& row : rows) {
|
||||
kt << row.family << " | " << row.styles;
|
||||
if (any_shadowed) {
|
||||
kt << " | " << row.shadowed_by;
|
||||
}
|
||||
kt << " ||\n";
|
||||
}
|
||||
kt << "table@\n\n";
|
||||
}
|
||||
return kt.str();
|
||||
}
|
||||
Reference in new issue
Block a user