aboutsummaryrefslogtreecommitdiffhomepage
path: root/org
diff options
context:
space:
mode:
Diffstat (limited to 'org')
-rw-r--r--org/default_paths.org12
-rw-r--r--org/out_metadata.org8
-rw-r--r--org/out_src_pod.org25
-rw-r--r--org/spine.org19
4 files changed, 55 insertions, 9 deletions
diff --git a/org/default_paths.org b/org/default_paths.org
index bbc0362..9bf56d5 100644
--- a/org/default_paths.org
+++ b/org/default_paths.org
@@ -718,8 +718,18 @@ template spinePathsSRC() {
#+NAME: template_paths_pods
#+BEGIN_SRC d
+/+ ↓ the pod archive's suffix, named once.
+ Previously a literal named at 4 locations, inviting mishaps on renaming.
+ (missing one meant a link that goes nowhere).
+ .
+ A .sisupod is the same archive as before inside one zstd frame. The legacy
+ spelling is also kept because the reader accepts both: every pod already
+ published carries it.
++/
+enum string pod_archive_suffix = ".sisupod";
+enum string pod_archive_suffix_legacy = ".zip";
template spinePathsPods() {
- string _suffix = ".zip";
+ string _suffix = pod_archive_suffix;
auto spinePathsPods(M)(M doc_matters) {
string _base_dir_pod = (doc_matters.output_path.length > 0)
? doc_matters.output_path ~ "/pod"
diff --git a/org/out_metadata.org b/org/out_metadata.org
index 8f3a946..b816dad 100644
--- a/org/out_metadata.org
+++ b/org/out_metadata.org
@@ -176,8 +176,8 @@ if (doc_matters.opt.action.html_link_text) {
metadata_ ~= "</p>";
if (doc_matters.opt.action.html_link_markup_source) {
metadata_ ~= "<hr /><p class=\"lev1\">source: " ~ doc_matters.src.filename_base ~ "</p>";
- metadata_ ~= "<p class=\"lev1\">●&nbsp;&nbsp;markup source:&nbsp;&nbsp;the&nbsppod&nbsp[<a href=\"../../" ~ pth_pod.internal_base ~ "/" ~ doc_matters.src.filename_base ~ ".zip\" class=\"lnkicon\">"
- ~ "&nbsp;🫛&nbsp;zipped&nbsp;</a>|&nbsp;"
+ metadata_ ~= "<p class=\"lev1\">●&nbsp;&nbsp;markup source:&nbsp;&nbsp;the&nbsppod&nbsp[<a href=\"../../" ~ pth_pod.internal_base ~ "/" ~ doc_matters.src.filename_base ~ pod_archive_suffix ~ "\" class=\"lnkicon\">"
+ ~ "&nbsp;🫛&nbsp;sisupod&nbsp;</a>|&nbsp;"
~ "<a href=\"../../" ~ pth_pod.internal_base ~ "/" ~ doc_matters.src.filename_base ~ "/\" class=\"lnkicon\">"
~ "&nbsp;🫛&nbsp;tree&nbsp;</a>]&nbsp;";
{
@@ -199,10 +199,10 @@ if (doc_matters.opt.action.html_link_markup_source) {
try { // get sha digest for pod
metadata_ ~= "<p class=\"lev2\">";
auto data = (cast(byte[]) (fn_pod).read); // prevents code from being safe
- metadata_ ~= "<tt>" ~ data.sha256Of.toHexString ~ "::" ~ data.length.to!string ~ "</tt> - " ~ doc_matters.src.filename_base ~ ".zip";
+ metadata_ ~= "<tt>" ~ data.sha256Of.toHexString ~ "::" ~ data.length.to!string ~ "</tt> - " ~ doc_matters.src.filename_base ~ pod_archive_suffix;
metadata_ ~= "</p>";
} catch (Exception ex) {
- writeln("WARNING, source doc_matters.src.filename_base not found: ", doc_matters.src.filename_base, ".zip\n ", fn_pod);
+ writeln("WARNING, source doc_matters.src.filename_base not found: ", doc_matters.src.filename_base, pod_archive_suffix, "\n ", fn_pod);
}
}
if (doc_matters.opt.action.ocda_db) {
diff --git a/org/out_src_pod.org b/org/out_src_pod.org
index eac9882..96f784f 100644
--- a/org/out_src_pod.org
+++ b/org/out_src_pod.org
@@ -579,16 +579,33 @@ void podArchive_directory_tree(M,P)(M doc_matters, P pths_pod) { // create direc
#+NAME: zip_archive
#+BEGIN_SRC d
void zipArchive(M,F,Z)(M doc_matters, F fn_pod, Z zip) {
+ import sisudoc.ocda.zstd : zstdCompress, ZstdException;
auto fn_src_in = doc_matters.src.filename;
if (doc_matters.opt.action.pod) {
if (exists(doc_matters.src.file_with_absolute_path)) {
try {
- createZipFile!()(fn_pod, zip.build());
+ /+ ↓ the archive is built exactly as before and then wrapped in one
+ zstd frame. The wrap is here and not in createZipFile, which
+ also writes every epub and every odt: those are real zips by
+ their own specifications.
+ .
+ The compression gain is in whole-stream rather than per-member
+ compression. A zip deflates each member on its own with a 32 KB
+ window, which sees none of the redundancy between multiple language
+ versions of a document and the catalogues that may repeat the
+ English (original language): (live-manual is 10.31x smaller this
+ way, where per-member deflate manages about 3x).
+ +/
+ auto _archive = cast(ubyte[]) zip.build();
+ createZipFile!()(fn_pod,
+ cast(void[]) zstdCompress(_archive, doc_matters.opt.action.pod_compression));
+ } catch (ZstdException ex) {
+ writeln("WARNING failed to compress pod archive: ", fn_pod, " - ", ex.msg);
} catch (ErrnoException ex) {
// Handle errors
}
} else { writeln("WARNING check missing source file(s): ", doc_matters.opt.action.pod); }
- if (!(exists(fn_pod))) { writeln("WARNING failed to create pod zip archive: ", fn_pod); }
+ if (!(exists(fn_pod))) { writeln("WARNING failed to create pod archive: ", fn_pod); }
}
}
#+END_SRC
@@ -617,9 +634,9 @@ void zipArchiveDigest(M,F,D)(M doc_matters, F fn_pod, D _digests) {
if (exists(fn_pod)) {
try {
auto data = (cast(byte[]) (fn_pod).read);
- // if (doc_matters.opt.action.vox_gt_2) { writeln(" ", doc_matters.src.filename, " > ", doc_matters.src.filename_base, ".zip"); }
+ // if (doc_matters.opt.action.vox_gt_2) { writeln(" ", doc_matters.src.filename, " > ", doc_matters.src.filename_base, pod_archive_suffix); }
if (doc_matters.opt.action.pod) {
- _zip_digest = (data.sha256Of.toHexString ~ "::" ~ data.length.to!string ~ " - " ~ doc_matters.src.filename_base ~ ".zip");
+ _zip_digest = (data.sha256Of.toHexString ~ "::" ~ data.length.to!string ~ " - " ~ doc_matters.src.filename_base ~ pod_archive_suffix);
if (doc_matters.opt.action.vox_gt_1) { writeln(" ", _zip_digest); }
if (doc_matters.opt.action.vox_gt_1) { writeln(" ", pths_pod.pod_dir_(), "/", doc_matters.src.filename_base, "/"); }
if (doc_matters.opt.action.vox_gt_1) { writeln(" ", _digest_fn); }
diff --git a/org/spine.org b/org/spine.org
index aa8b6df..cef324a 100644
--- a/org/spine.org
+++ b/org/spine.org
@@ -466,6 +466,7 @@ NOTES on configuration hierarchy: see meta_conf_make_meta.org
#+BEGIN_SRC d
string[string] settings = [
"output" : "",
+ "pod-compression" : "",
"ssp-round-trip" : "",
"db-round-trip" : "",
"abstraction-source" : "",
@@ -575,6 +576,7 @@ auto helpInfo = getopt(args,
"source", "document markup source", &opts["source"],
"silent", "output to terminal", &opts["vox_is0"],
"set-digest", "default hash digest type (e.g. sha256)", &settings["set-digest"],
+ "pod-compression", "pod archive compression level, zstd 1 to 19 (default 19)", &settings["pod-compression"],
"set-papersize", "default papersize (latex pdf eg. a4 or a5 or b4 or letter)", &settings["set-papersize"],
"set-textwrap", "default textwrap (e.g. 80 (characters)", &settings["set-textwrap"],
"skel", "skel (dummy outline)", &opts["skel"],
@@ -1071,6 +1073,23 @@ struct OptActions {
@trusted string text_wrap() {
return settings["set-textwrap"];
}
+ /+ ↓ the zstd level a pod archive is written at. 19 by default: a pod
+ is written once and fetched many times, and there is a significant gain
+ (live-manual 675970 bytes at 19 against 786683 at 9). Lower it where
+ build time matters more than the bytes do.
+ +/
+ @trusted int pod_compression() {
+ import std.conv : to;
+ if (settings["pod-compression"].length > 0) {
+ try {
+ return settings["pod-compression"].to!int;
+ } catch (Exception) {
+ writeln("WARNING --pod-compression is not a number, using 19: ",
+ settings["pod-compression"]);
+ }
+ }
+ return 19;
+ }
@trusted string latex_papersize() {
return settings["set-papersize"];
}