Offer-motivated features: :hline defaults, ranged :hpos, @date :days, :bottom none

- @table: a writer's :hline/:vline replaces the default lines; new
  boundary name 'none' removes all lines
- @table: ranged :hpos argument overrides :cell_hpos per cell
  (\multicolumn{1} in tex; positions a colspan anchor's merged cell)
- @date/@datetime: :days offset argument (sks/date/date.py)
- @document: ":bottom none" suppresses the footer (\pagestyle{empty})

Also carries the escape-system generator/renderer fixes, per-cell-range
:format, and uppercase .TTF/.OTF font recognition from klammertext-dev.
This commit is contained in:
2026-07-24 21:37:58 +02:00
parent 8a2699a253
commit 4262fc6136
14 changed files with 657 additions and 146 deletions

View File

@@ -24,6 +24,18 @@
namespace fs = std::filesystem;
// A filesystem extension lowercased for case-insensitive matching, so a
// font named Foo.TTF or Foo.OTF is recognized like Foo.ttf / Foo.otf.
static std::string lower_extension(const fs::path& path)
{
std::string ext = path.extension();
for (char& c : ext) {
c = std::tolower(static_cast<unsigned char>(c));
}
return ext;
}
std::string name_to_dirname(std::string name)
{
std::string result {};
@@ -275,7 +287,10 @@ Font_file classify_font_file(const std::string& path)
{
Font_file file {};
file.path = path;
file.extension = fs::path(path).extension();
// Normalize to lowercase so the installed filename, its @font-face url,
// and the truetype/opentype format detection are uniform regardless of
// how the source file's extension was capitalized.
file.extension = lower_extension(path);
std::string d = read_binary_file(path);
if (d.size() < 12) {
@@ -372,7 +387,7 @@ std::vector<Font_file> classify_font_files(const std::string& directory)
"The font directory \"" + directory + "\" does not exist");
}
for (auto& entry : fs::recursive_directory_iterator(directory)) {
std::string ext = entry.path().extension();
std::string ext = lower_extension(entry.path());
if (entry.is_regular_file() && (ext == ".ttf" || ext == ".otf")) {
result.push_back(classify_font_file(entry.path()));
}