Typed arguments, calculated tables, spans, closed-world fonts, top-level fnt/ and env/
Sync with klammertext-dev through b90b0e09: - Argument types end to end: :python_cast values are applied (Python @eval receives real bools/numbers/lists), argument values are validated against their argtype patterns with the argtype's description as the error message, argtypes can declare :default (overridable per declaration), and parameterized type families are supported: rest(N) casts a rest argument to an N-dimensional list (bar-count = dimension). - Unified indexed_range syntax (selector with parenthesized subsets, composable mnemonic names) for table lines and spans. - Table klammer: caption fonts fixed in both targets, :column_width / :leading / :colsep wired, :colspan and :rowspan render (HTML attributes; \multicolumn / \multirow), calculated cell values (:calc) with prefix operators, display-precision semantics, :calc_format and :decimal period|comma. - Fonts: closed-world resolution on the Klammertext font store (infrastructure in mac/font_store; no Google Fonts links or fetch). Default fonts live in the top-level fnt/; additional fonts install into KLAMMERTEXT_FONTS directories via kdesc --font (list, samples, preview, install — classification by font metadata). CSS font family names are quoted (digit-initial families were silently lost). - Environment files moved from mac/env/ to the top-level env/; shell profiles source env/runtime.env. Dead per-host variants removed. - Container: fnt/ ships in the image; curl removed (no network use).
This commit is contained in:
@@ -5,12 +5,12 @@ K := $(KLAMMERTEXT_HOME)
|
||||
KS := $(K)/sks
|
||||
KM := $(K)/mac
|
||||
|
||||
include $(KM)/env/makefile.env
|
||||
include $(K)/env/makefile.env
|
||||
|
||||
# Source files
|
||||
SOURCES := html_util.cpp latex_util.cpp font_resolve.cpp
|
||||
OBJECTS := html_util.o latex_util.o font_resolve.o
|
||||
DEPFILES := html_util.d latex_util.d font_resolve.d
|
||||
SOURCES := html_util.cpp latex_util.cpp
|
||||
OBJECTS := html_util.o latex_util.o
|
||||
DEPFILES := html_util.d latex_util.d
|
||||
|
||||
# Additional include paths
|
||||
LOCAL_CPPFLAGS := -I$(KM) -I$(KS)/kutil
|
||||
|
||||
@@ -1,329 +0,0 @@
|
||||
#include "font_resolve.h"
|
||||
#include "file.h"
|
||||
#include "util.h"
|
||||
#include "error.h"
|
||||
#include "log.h"
|
||||
#include "show.h"
|
||||
#include "kutil.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <filesystem>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
|
||||
std::string name_to_dirname(std::string name)
|
||||
{
|
||||
std::string result {};
|
||||
for (char c : name) {
|
||||
if (c == ' ')
|
||||
result += '-';
|
||||
else
|
||||
result += std::tolower(c);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::string name_to_google_query(std::string name)
|
||||
{
|
||||
std::string result {};
|
||||
for (char c : name) {
|
||||
if (c == ' ')
|
||||
result += '+';
|
||||
else
|
||||
result += c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void classify_from_css(Resolved_font& font, std::string css_path)
|
||||
{
|
||||
// Parse the @font-face blocks in the CSS to determine variant → filename mapping
|
||||
std::string css = string_from_file(css_path);
|
||||
std::regex face_rgx(
|
||||
R"(@font-face\s*\{[^}]*font-style:\s*(\w+);[^}]*font-weight:\s*(\w+);[^}]*url\('([^']+\.ttf)'\)[^}]*\})",
|
||||
std::regex::multiline);
|
||||
auto begin = std::sregex_iterator(css.begin(), css.end(), face_rgx);
|
||||
auto end = std::sregex_iterator();
|
||||
for (auto it = begin; it != end; ++it) {
|
||||
std::string style = (*it)[1];
|
||||
std::string weight = (*it)[2];
|
||||
std::string url_path = (*it)[3];
|
||||
// URL is like 'dir-name/Filename.ttf' — extract just the filename
|
||||
std::string filename = url_path.substr(url_path.rfind('/') + 1);
|
||||
bool is_bold = (weight == "700" || weight == "bold");
|
||||
bool is_italic = (style == "italic" || style == "oblique");
|
||||
if (is_bold && is_italic)
|
||||
font.bold_italic = filename;
|
||||
else if (is_bold)
|
||||
font.bold = filename;
|
||||
else if (is_italic)
|
||||
font.italic = filename;
|
||||
else
|
||||
font.regular = filename;
|
||||
}
|
||||
}
|
||||
|
||||
static Resolved_font resolve_bundled(std::string family_name, std::string dir_name)
|
||||
{
|
||||
std::string bundled_dir = klammertext_dir() + "/sks/font/fonts/" + dir_name;
|
||||
std::string bundled_css = bundled_dir + ".css";
|
||||
if (fs::exists(bundled_dir) && fs::exists(bundled_css)) {
|
||||
Resolved_font font {};
|
||||
font.family_name = family_name;
|
||||
font.dir_name = dir_name;
|
||||
font.font_dir = bundled_dir;
|
||||
font.css_file = bundled_css;
|
||||
font.from_cache = false;
|
||||
classify_from_css(font, bundled_css);
|
||||
return font;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
static Resolved_font resolve_cached(std::string family_name, std::string dir_name)
|
||||
{
|
||||
std::string cache_base = cache_directory("_fonts");
|
||||
std::string cache_dir = cache_base + "/" + dir_name;
|
||||
std::string cache_css = cache_base + "/" + dir_name + ".css";
|
||||
if (fs::exists(cache_dir) && fs::exists(cache_css)) {
|
||||
Resolved_font font {};
|
||||
font.family_name = family_name;
|
||||
font.dir_name = dir_name;
|
||||
font.font_dir = cache_dir;
|
||||
font.css_file = cache_css;
|
||||
font.from_cache = true;
|
||||
classify_from_css(font, cache_css);
|
||||
return font;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
static Resolved_font fetch_google_font(std::string family_name, std::string dir_name)
|
||||
{
|
||||
(void)K::log(1, "Fetching font \"" + family_name + "\" from Google Fonts");
|
||||
|
||||
std::string query = name_to_google_query(family_name);
|
||||
std::string url =
|
||||
"https://fonts.googleapis.com/css2?family=" + query +
|
||||
":ital,wght@0,400;0,700;1,400;1,700&display=swap";
|
||||
|
||||
std::string cmd = "curl -s -H 'User-Agent: Mozilla/4.0' '" + url + "'";
|
||||
std::string css_response = exec(cmd.c_str());
|
||||
|
||||
if (css_response.empty() || css_response.find("@font-face") == std::string::npos) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Parse @font-face blocks to extract style, weight, and .ttf URL
|
||||
struct Font_variant {
|
||||
std::string style; // "normal" or "italic"
|
||||
std::string weight; // "400" or "700"
|
||||
std::string url;
|
||||
};
|
||||
std::vector<Font_variant> variants {};
|
||||
|
||||
std::regex face_rgx(
|
||||
R"(@font-face\s*\{[^}]*font-style:\s*(\w+);[^}]*font-weight:\s*(\d+);[^}]*src:\s*url\((https?://[^)]+\.ttf)\)[^}]*\})",
|
||||
std::regex::multiline);
|
||||
|
||||
auto begin = std::sregex_iterator(css_response.begin(), css_response.end(), face_rgx);
|
||||
auto end = std::sregex_iterator();
|
||||
|
||||
for (auto it = begin; it != end; ++it) {
|
||||
Font_variant v {};
|
||||
v.style = (*it)[1];
|
||||
v.weight = (*it)[2];
|
||||
v.url = (*it)[3];
|
||||
variants.push_back(v);
|
||||
}
|
||||
|
||||
if (variants.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Create cache directory
|
||||
std::string cache_base = cache_directory("_fonts");
|
||||
if (!fs::exists(cache_base))
|
||||
fs::create_directories(cache_base);
|
||||
|
||||
std::string cache_dir = cache_base + "/" + dir_name;
|
||||
if (!fs::exists(cache_dir))
|
||||
fs::create_directory(cache_dir);
|
||||
|
||||
Resolved_font font {};
|
||||
font.family_name = family_name;
|
||||
font.dir_name = dir_name;
|
||||
font.font_dir = cache_dir;
|
||||
font.from_cache = true;
|
||||
|
||||
// Download each .ttf file with descriptive names
|
||||
for (auto& v : variants) {
|
||||
std::string local_name;
|
||||
if (v.style == "normal" && v.weight == "400")
|
||||
local_name = "Regular.ttf";
|
||||
else if (v.style == "normal" && v.weight == "700")
|
||||
local_name = "Bold.ttf";
|
||||
else if (v.style == "italic" && v.weight == "400")
|
||||
local_name = "Italic.ttf";
|
||||
else if (v.style == "italic" && v.weight == "700")
|
||||
local_name = "BoldItalic.ttf";
|
||||
else
|
||||
continue;
|
||||
|
||||
std::string ttf_path = cache_dir + "/" + local_name;
|
||||
|
||||
if (!fs::exists(ttf_path)) {
|
||||
std::string dl_cmd = "curl -s -o '" + ttf_path + "' '" + v.url + "'";
|
||||
(void)exec(dl_cmd.c_str());
|
||||
if (!fs::exists(ttf_path)) {
|
||||
(void)K::log(1, "Failed to download font file: " + v.url);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (local_name == "Regular.ttf")
|
||||
font.regular = local_name;
|
||||
else if (local_name == "Bold.ttf")
|
||||
font.bold = local_name;
|
||||
else if (local_name == "Italic.ttf")
|
||||
font.italic = local_name;
|
||||
else if (local_name == "BoldItalic.ttf")
|
||||
font.bold_italic = local_name;
|
||||
}
|
||||
|
||||
// Generate @font-face CSS file
|
||||
std::string css_file = cache_base + "/" + dir_name + ".css";
|
||||
std::stringstream css {};
|
||||
auto emit_face = [&](std::string style, std::string weight, std::string filename) {
|
||||
if (filename.empty())
|
||||
return;
|
||||
css << "\n@font-face {\n"
|
||||
<< " font-family: '" << family_name << "';\n"
|
||||
<< " font-style: " << style << ";\n"
|
||||
<< " font-weight: " << weight << ";\n"
|
||||
<< " src: url('" << dir_name << "/" << filename << "') format('truetype');\n"
|
||||
<< "}\n";
|
||||
};
|
||||
emit_face("normal", "400", font.regular);
|
||||
emit_face("normal", "700", font.bold);
|
||||
emit_face("italic", "400", font.italic);
|
||||
emit_face("italic", "700", font.bold_italic);
|
||||
|
||||
string_to_file(css_file, css.str());
|
||||
font.css_file = css_file;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
static void extract_font_metrics(Resolved_font& font)
|
||||
{
|
||||
if (font.regular.empty() || font.font_dir.empty())
|
||||
return;
|
||||
std::string ttf_path = font.font_dir + "/" + font.regular;
|
||||
if (!fs::exists(ttf_path))
|
||||
return;
|
||||
// Extract both x-height and cap-height ratios from OS/2 table
|
||||
std::string script =
|
||||
"python3 -c \""
|
||||
"import struct; "
|
||||
"f = open('" + ttf_path + "', 'rb'); "
|
||||
"_, n = struct.unpack('>IH', f.read(6)); "
|
||||
"f.read(6); "
|
||||
"t = {};\n"
|
||||
"for _ in range(n):\n"
|
||||
" tag = f.read(4).decode('latin-1').strip('\\\\x00'); "
|
||||
" _, o, l = struct.unpack('>III', f.read(12)); "
|
||||
" t[tag] = o\n"
|
||||
"f.seek(t['head'] + 18); "
|
||||
"upm = struct.unpack('>H', f.read(2))[0]; "
|
||||
"f.seek(t['OS/2']); "
|
||||
"ver = struct.unpack('>H', f.read(2))[0]; "
|
||||
"f.seek(t['OS/2'] + 86); "
|
||||
"xh, ch = struct.unpack('>hh', f.read(4)); "
|
||||
"print(f'{xh/upm:.4f} {ch/upm:.4f}') if ver >= 2 else None; "
|
||||
"f.close()\"";
|
||||
std::string result = trim(exec(script.c_str()));
|
||||
if (!result.empty()) {
|
||||
try {
|
||||
auto pos = result.find(' ');
|
||||
if (pos != std::string::npos) {
|
||||
font.xheight_ratio = std::stof(result.substr(0, pos));
|
||||
font.capheight_ratio = std::stof(result.substr(pos + 1));
|
||||
}
|
||||
} catch (...) {}
|
||||
}
|
||||
}
|
||||
|
||||
Resolved_font resolve_font(std::string family_name)
|
||||
{
|
||||
if (family_name.empty())
|
||||
return {};
|
||||
|
||||
std::string dir_name = name_to_dirname(family_name);
|
||||
|
||||
// 1. Check bundled fonts
|
||||
Resolved_font font = resolve_bundled(family_name, dir_name);
|
||||
if (!font.family_name.empty()) {
|
||||
extract_font_metrics(font);
|
||||
return font;
|
||||
}
|
||||
|
||||
// 2. Check font cache
|
||||
font = resolve_cached(family_name, dir_name);
|
||||
if (!font.family_name.empty()) {
|
||||
extract_font_metrics(font);
|
||||
return font;
|
||||
}
|
||||
|
||||
// 3. Fetch from Google Fonts
|
||||
font = fetch_google_font(family_name, dir_name);
|
||||
if (!font.family_name.empty()) {
|
||||
extract_font_metrics(font);
|
||||
return font;
|
||||
}
|
||||
|
||||
// 4. Error
|
||||
throw Argument_error(
|
||||
"Font \"" + family_name + "\" not found.\n"
|
||||
" Not bundled in sks/font/fonts/" + dir_name + "/,\n"
|
||||
" not cached, and not available from Google Fonts.\n"
|
||||
" Check the font name or install it locally.");
|
||||
}
|
||||
|
||||
|
||||
// Font assets are copied with copy_file_stream() (mac/file.h) rather than
|
||||
// std::filesystem::copy_file, which fails on Apple `container` virtiofs mounts
|
||||
// — see the note on copy_file_stream() in file.cpp for the full rationale.
|
||||
|
||||
|
||||
void install_resolved_font(const Resolved_font& font, std::string output_dir)
|
||||
{
|
||||
if (font.family_name.empty())
|
||||
return;
|
||||
|
||||
std::string output_font_dir = output_dir + "/fonts";
|
||||
if (!fs::exists(output_font_dir))
|
||||
fs::create_directory(output_font_dir);
|
||||
|
||||
// Copy .css file and font directory to output
|
||||
std::string dest_css = output_font_dir + "/" + font.dir_name + ".css";
|
||||
std::string dest_dir = output_font_dir + "/" + font.dir_name;
|
||||
|
||||
copy_file_stream(font.css_file, dest_css);
|
||||
|
||||
if (!fs::exists(dest_dir)) {
|
||||
fs::create_directory(dest_dir);
|
||||
for (auto& entry : fs::directory_iterator(font.font_dir)) {
|
||||
copy_file_stream(entry.path(),
|
||||
dest_dir + "/" + entry.path().filename().string());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct Resolved_font {
|
||||
std::string family_name {}; // "Crimson Pro"
|
||||
std::string dir_name {}; // "crimson-pro"
|
||||
std::string font_dir {}; // Full path to font directory
|
||||
std::string css_file {}; // Full path to .css file
|
||||
bool from_cache = false;
|
||||
// .ttf filenames for each variant (empty if variant not available):
|
||||
std::string regular {};
|
||||
std::string bold {};
|
||||
std::string italic {};
|
||||
std::string bold_italic {};
|
||||
float xheight_ratio = 0.0f; // x-height / unitsPerEm from OS/2 table
|
||||
float capheight_ratio = 0.0f; // cap-height / unitsPerEm from OS/2 table
|
||||
};
|
||||
|
||||
std::string name_to_dirname(std::string name);
|
||||
std::string name_to_google_query(std::string name);
|
||||
Resolved_font resolve_font(std::string family_name);
|
||||
void install_resolved_font(const Resolved_font& font, std::string output_dir);
|
||||
@@ -254,25 +254,6 @@ namespace html {
|
||||
return result;
|
||||
}
|
||||
|
||||
elements_t google_font_elements(strings_t fontnames)
|
||||
{
|
||||
elements_t result {};
|
||||
if (fontnames.size() > 0) {
|
||||
result.push_back(elt("link")
|
||||
.attr("rel", "preconnect")
|
||||
.attr("href", "https://fonts.googleapis.com"));
|
||||
result.push_back(elt("link")
|
||||
.attr("rel", "preconnect")
|
||||
.attr("href", "https://fonts.gstatic.com"));
|
||||
}
|
||||
for (auto name : fontnames)
|
||||
result.push_back(
|
||||
elt("link")
|
||||
.attr("href", "https://fonts.googleapis.com/css2?family=" + name + "&display=swap")
|
||||
.attr("rel", "stylesheet"));
|
||||
return result;
|
||||
}
|
||||
|
||||
elements_t javascript(std::string output_dir, strings_t js_filenames)
|
||||
{
|
||||
//elements_t result { jquery_elements() };
|
||||
@@ -298,15 +279,12 @@ namespace html {
|
||||
HTML head(std::string title,
|
||||
std::string css,
|
||||
strings_t css_filenames,
|
||||
strings_t local_fonts, strings_t google_fonts)
|
||||
strings_t local_fonts)
|
||||
{
|
||||
elements_t elts = meta_elements();
|
||||
// msg() << "ELTS sks: " << elts << "\n";
|
||||
for (auto e : local_font_elements(local_fonts))
|
||||
elts.push_back(e);
|
||||
for (auto e : google_font_elements(google_fonts))
|
||||
elts.push_back(e);
|
||||
//elts += google_font_prolog();
|
||||
|
||||
//std::string css_dir = output_dir + "/css/";
|
||||
// No; a single file at the top level...?
|
||||
@@ -471,55 +449,6 @@ namespace html {
|
||||
return result;
|
||||
}
|
||||
|
||||
void install_local_fonts(strings_t font_dirs, strings_t names, std::string output_dir)
|
||||
{
|
||||
std::string output_font_dir = output_dir + "/fonts";
|
||||
//std::cout << "Font directory for website: " << output_font_dir << "\n";
|
||||
if (!file_exists(output_font_dir)) {
|
||||
fs::create_directory(output_font_dir);
|
||||
//std::cout << " Font directory created: " << output_font_dir << "\n";
|
||||
}
|
||||
|
||||
for (auto name : names) {
|
||||
//std::cout << "Font search for " << name << ": " << klammertext_dir() << "/sks/font/fonts/\n";
|
||||
std::string src_font_dir = klammertext_dir() + "/sks/font/fonts/" + name;
|
||||
if (!file_exists(src_font_dir)) {
|
||||
bool found = false;
|
||||
for (std::string font_dir : font_dirs) {
|
||||
src_font_dir = font_dir + "/" + name;
|
||||
//std::cout << "Font search for " << name << ": " << font_dir << "/\n";
|
||||
if (file_exists(src_font_dir)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw Argument_error(
|
||||
"Local font directory \"" + src_font_dir + "\" does not exist");
|
||||
}
|
||||
}
|
||||
//std::cout << "Font " << name << ": " << src_font_dir << "\n";
|
||||
|
||||
std::string src_font_css = src_font_dir + ".css";
|
||||
if (!fs::exists(src_font_css)) {
|
||||
throw Argument_error(
|
||||
"Local font CSS file \"" + src_font_css + "\" does not exist");
|
||||
}
|
||||
std::string font_copy =
|
||||
"cp -r " + src_font_css + " " + src_font_dir + " " + output_font_dir;
|
||||
|
||||
//std::string files_copy = "cp -r " + basename + " " + font_dir;
|
||||
//cout << css_copy << "\n" << files_copy << "\n";
|
||||
//std::cout << system(css_copy.c_str()) << "\n";
|
||||
//std::cout << system(files_copy.c_str()) << "\n";
|
||||
|
||||
if (system(font_copy.c_str()) != 0) {
|
||||
std::cout << "Font copy command: " << font_copy << "\n";
|
||||
throw Argument_error("Local font \"" + name + "\" not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elements_t status(std::string date, std::string version, std::string copyright)
|
||||
{
|
||||
elements_t result {};
|
||||
@@ -550,7 +479,6 @@ namespace html {
|
||||
strings_t css_filenames,
|
||||
strings_t js_filenames,
|
||||
strings_t local_fonts,
|
||||
strings_t google_fonts,
|
||||
std::string logo)
|
||||
{
|
||||
if (page_title.empty())
|
||||
@@ -601,7 +529,7 @@ namespace html {
|
||||
page_title = title;
|
||||
result.push_back(
|
||||
elt("html",
|
||||
{ head(page_title, css, css_filenames, local_fonts, google_fonts),
|
||||
{ head(page_title, css, css_filenames, local_fonts),
|
||||
elt("body", body)
|
||||
}).attr("lang", "en"));
|
||||
return result;
|
||||
@@ -666,12 +594,12 @@ namespace html {
|
||||
elements_t make_page(
|
||||
elements_t body,
|
||||
std::string page_title, std::string css,
|
||||
strings_t css_filenames, strings_t local_fonts, strings_t google_fonts)
|
||||
strings_t css_filenames, strings_t local_fonts)
|
||||
{
|
||||
elements_t page { preamble() };
|
||||
page.push_back(
|
||||
elt("html",
|
||||
{ head(page_title, css, css_filenames, local_fonts, google_fonts),
|
||||
{ head(page_title, css, css_filenames, local_fonts),
|
||||
elt("body", body)
|
||||
}).attr("lang", "en"));
|
||||
return page;
|
||||
|
||||
@@ -76,8 +76,6 @@ namespace html {
|
||||
//HTML preamble();
|
||||
//HTML head(strings_t css_filenames, strings_t js_filenames);
|
||||
|
||||
void install_local_fonts(strings_t font_dirs, strings_t names, std::string output_dir);
|
||||
|
||||
elements_t page(
|
||||
std::string title,
|
||||
std::string page_title,
|
||||
@@ -93,7 +91,6 @@ namespace html {
|
||||
strings_t css_filenames = {},
|
||||
strings_t js_filenames = {},
|
||||
strings_t local_fonts = {},
|
||||
strings_t google_fonts = {},
|
||||
std::string logo = {});
|
||||
|
||||
void add_title(elements_t& body, std::string title, std::string logo="");
|
||||
@@ -108,8 +105,7 @@ namespace html {
|
||||
elements_t body,
|
||||
std::string page_title, std::string css,
|
||||
std::vector<std::string> css_filenames,
|
||||
std::vector<std::string> local_fonts,
|
||||
std::vector<std::string> google_fonts);
|
||||
std::vector<std::string> local_fonts);
|
||||
|
||||
bool tag_is_block_element(std::string tag);
|
||||
std::string make_paragraphs(std::string html_text);
|
||||
|
||||
@@ -198,7 +198,7 @@ def add_caption(element, caption_label, number, caption_text,
|
||||
tag = element_tag(element)
|
||||
# Caption
|
||||
caption = ""
|
||||
if number == "true":
|
||||
if number:
|
||||
caption = kutil.caption_marker(caption_label, caption_text)
|
||||
elif caption_text:
|
||||
caption = caption_text
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "util.h"
|
||||
#include "log.h"
|
||||
#include "show.h"
|
||||
#include "font_resolve.h"
|
||||
#include "font_store.h"
|
||||
|
||||
namespace latex {
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "font_resolve.h"
|
||||
#include "font_store.h"
|
||||
|
||||
namespace latex {
|
||||
|
||||
|
||||
@@ -73,9 +73,8 @@ def make_caption_text(number, label, text, font_symbol, font_size):
|
||||
# caption = text # f"{{\\small \\it \\par {caption_text}}}"
|
||||
caption = text
|
||||
|
||||
font_symbol = "r"
|
||||
font_size = 1.2
|
||||
|
||||
if caption is None:
|
||||
return ""
|
||||
caption = font.tex_fontify(caption, font_symbol, font_size)
|
||||
return caption
|
||||
|
||||
@@ -108,9 +107,9 @@ def add_caption(element, caption_label, number, caption_text, latex_width,
|
||||
# minipage(caption),
|
||||
latex_width, vertical="t")
|
||||
elif side == "top":
|
||||
element = minipage(caption + "\n" + element,
|
||||
# minipage(caption, vertical="t") +
|
||||
# caption_margin + "\n" +
|
||||
# minipage(element),
|
||||
# A depth strut: the bottom-caption case uses \vstrut (height)
|
||||
# above the caption; a top caption needs the mirror image,
|
||||
# space below its line.
|
||||
element = minipage(caption + "\\rule[-0.75\\baselineskip]{0pt}{0pt}\n" + element,
|
||||
latex_width, vertical="t")
|
||||
return caption_wrapper(element, hpos)
|
||||
|
||||
Reference in New Issue
Block a user