diff options
| author | Ralph Amissah <ralph.amissah@gmail.com> | 2026-09-23 07:18:52 -0400 |
|---|---|---|
| committer | Ralph Amissah <ralph.amissah@gmail.com> | 2026-09-23 08:19:53 -0400 |
| commit | 26aba525c0c55cb0ec77cf3a788cb59de2683cee (patch) | |
| tree | c49c119f157c67b39746157c1851f595749911ac /org | |
| parent | help: what spine takes, what an artefact carries (diff) | |
uid and paths separator "~" in place of ":"
need a character to split filenames on in certain circumstances.
there problems with use of a colon in filenames, which is legal on posix
but not on Windows."~" fits the bill better being legal on every
filesystem of interest and is unreserved in rfc 3986, needing no escaping in a url.
The reference abstraction is renamed, its content unchanged. Over
the sample collection two filenames move and nothing else does: the
abstraction and database digests are identical, the archive's
members and their sizes are unchanged, and only the member order
shifts, "~" collating after letters where ":" sorted before them. The
document's epub dc:identifier is a v5 uuid derived from the uid, so it
changes for those filenames.
Every document's uid changes in the search database (spine.search.db).
(assisted by Claude-Code)
Diffstat (limited to 'org')
| -rw-r--r-- | org/default_misc.org | 2 | ||||
| -rw-r--r-- | org/default_regex.org | 20 | ||||
| -rw-r--r-- | org/in_markup_source_files.org | 11 | ||||
| -rw-r--r-- | org/in_zip_pod.org | 6 |
4 files changed, 23 insertions, 16 deletions
diff --git a/org/default_misc.org b/org/default_misc.org index 87ca048..947d7bc 100644 --- a/org/default_misc.org +++ b/org/default_misc.org @@ -252,7 +252,7 @@ template InternalMarkup() { string tc_p = "┆"; string img = "☼"; string sep = "␣"; // "~";"␣"; // "~"; - string uid_sep = ":"; + string uid_sep = "~"; string on_o = "「"; string on_c = "」"; string mk_bullet = "● "; static string indent_by_spaces_provided(int indent, string _indent_spaces ="░░") { diff --git a/org/default_regex.org b/org/default_regex.org index b7454cb..cba4e9d 100644 --- a/org/default_regex.org +++ b/org/default_regex.org @@ -703,17 +703,17 @@ static template spineRgxFiles() { #+NAME: prgmkup_rgx_filename_and_path #+BEGIN_SRC d -static src_pth_sst_or_ssm = ctRegex!(`^(?P<path>[/]?(?:[a-zA-Z0-9._-]+/)*)(?P<filename>[a-zA-Z0-9._-]+[.](?P<extension>ss[tm]))$`); -static src_pth_pod_sst_or_ssm = ctRegex!(`^(?P<podpath>[/]?(?:[a-zA-Z0-9._-]+/)*)media/text/[a-z]{2}/(?P<filename>[a-zA-Z0-9][a-zA-Z0-9._-]*?[.]ss[tm])$`); -static src_pth_contents = ctRegex!(`^(?P<path>[/]?(?:[a-zA-Z0-9._-]+/)*)(?P<filename>[a-zA-Z0-9][a-zA-Z0-9._-]*)/pod[.]manifest$`); -static src_pth_zip = ctRegex!(`^(?P<path>[/]?(?:[a-zA-Z0-9._-]+/)*)(?P<filename>[a-zA-Z0-9._-]+(?:[.]zip|[.]sisupod))$`); -static src_pth_types = ctRegex!(`^(?P<path>[/]?[a-zA-Z0-9._-]+/)*(?P<gotfile>(?P<filename>[a-zA-Z0-9._-]+[.]ss[tm])|(?P<filelist>[a-zA-Z0-9._-]+/pod[.]manifest)|(?P<filezip>[a-zA-Z0-9._-]+(?:[.]zip|[.]sisupod)))$`); -static src_fn = ctRegex!(`^([/]?(?:[a-zA-Z0-9._-]+/)*)(?P<fn_src>(?P<fn_base>[a-zA-Z0-9._-]+)[.](?P<fn_src_suffix>ss[tm]))$`); -static src_fn_master = ctRegex!(`^(?P<path>/?(?:[a-zA-Z0-9._-]+/)*)(?P<filename>[a-zA-Z0-9._-]+[.]ssm)$`); -static src_fn_find_inserts = ctRegex!(`^(?P<path>/?(?:[a-zA-Z0-9._-]+/)*)(?P<filename>[a-zA-Z0-9._-]+[.]ss[im])$`); +static src_pth_sst_or_ssm = ctRegex!(`^(?P<path>[/]?(?:[a-zA-Z0-9._:~-]+/)*)(?P<filename>[a-zA-Z0-9._-]+[.](?P<extension>ss[tm]))$`); +static src_pth_pod_sst_or_ssm = ctRegex!(`^(?P<podpath>[/]?(?:[a-zA-Z0-9._:~-]+/)*)media/text/[a-z]{2}/(?P<filename>[a-zA-Z0-9][a-zA-Z0-9._-]*?[.]ss[tm])$`); +static src_pth_contents = ctRegex!(`^(?P<path>[/]?(?:[a-zA-Z0-9._:~-]+/)*)(?P<filename>[a-zA-Z0-9][a-zA-Z0-9._-]*)/pod[.]manifest$`); +static src_pth_zip = ctRegex!(`^(?P<path>[/]?(?:[a-zA-Z0-9._:~-]+/)*)(?P<filename>[a-zA-Z0-9._-]+(?:[.]zip|[.]sisupod))$`); +static src_pth_types = ctRegex!(`^(?P<path>[/]?[a-zA-Z0-9._:~-]+/)*(?P<gotfile>(?P<filename>[a-zA-Z0-9._-]+[.]ss[tm])|(?P<filelist>[a-zA-Z0-9._-]+/pod[.]manifest)|(?P<filezip>[a-zA-Z0-9._-]+(?:[.]zip|[.]sisupod)))$`); +static src_fn = ctRegex!(`^([/]?(?:[a-zA-Z0-9._:~-]+/)*)(?P<fn_src>(?P<fn_base>[a-zA-Z0-9._-]+)[.](?P<fn_src_suffix>ss[tm]))$`); +static src_fn_master = ctRegex!(`^(?P<path>/?(?:[a-zA-Z0-9._:~-]+/)*)(?P<filename>[a-zA-Z0-9._-]+[.]ssm)$`); +static src_fn_find_inserts = ctRegex!(`^(?P<path>/?(?:[a-zA-Z0-9._:~-]+/)*)(?P<filename>[a-zA-Z0-9._-]+[.]ss[im])$`); static insert_src_fn_ssi_or_sst = ctRegex!(`^<<\s*(?P<path>[a-zA-Z0-9._-]+/)*(?P<filename>[a-zA-Z0-9._-]+[.]ss[ti])$`); -static src_base_parent_dir_name = ctRegex!(`[/](?P<dir>(?:[a-zA-Z0-9._-]+))(?:/media/text/[a-z]{2})$`); // formalizes dir structure -static src_formalised_file_path_parts = ctRegex!(`(?P<pth>(?:[/a-zA-Z0-9._-]+?)(?P<dir>[a-zA-Z0-9._-]+))(?:/media/text/[a-z]{2})$`); // formalizes dir structure +static src_base_parent_dir_name = ctRegex!(`[/](?P<dir>(?:[a-zA-Z0-9._:~-]+))(?:/media/text/[a-z]{2})$`); // formalizes dir structure +static src_formalised_file_path_parts = ctRegex!(`(?P<pth>(?:[/a-zA-Z0-9._:~-]+?)(?P<dir>[a-zA-Z0-9._:~-]+))(?:/media/text/[a-z]{2})$`); // formalizes dir structure #+END_SRC ** _module template yaml tags diff --git a/org/in_markup_source_files.org b/org/in_markup_source_files.org index 68de6fb..f4ab434 100644 --- a/org/in_markup_source_files.org +++ b/org/in_markup_source_files.org @@ -925,9 +925,14 @@ template spineCarriedNames() { enum size_t MAX_CARRIED_NAME_LENGTH = 255; /+ one path component +/ enum size_t MAX_CARRIED_PATH_LENGTH = 1024; /+ the whole path +/ enum size_t MAX_CARRIED_PATH_DEPTH = 10; /+ as read_zip_pod.d +/ - /+ ↓ allowed characters: a filename has no separator, a path has "/" +/ - static auto rgx_safe_carried_name = ctRegex!(`^[a-zA-Z0-9._ -]+$`); - static auto rgx_safe_carried_path = ctRegex!(`^[a-zA-Z0-9._/ -]+$`); + /+ ↓ allowed characters: a filename has no separator, a path has "/". + "~" is here because it is spine's own uid separator (InlineMarkup.uid_sep), + which joins a pod name to a document name where the two differ, as in + sisu-manual~sisu_markup.en.ssp. It cannot occur in either half, every + filesystem of interest takes it, and it is unreserved in rfc 3986. + +/ + static auto rgx_safe_carried_name = ctRegex!(`^[a-zA-Z0-9._ ~-]+$`); + static auto rgx_safe_carried_path = ctRegex!(`^[a-zA-Z0-9._/ ~-]+$`); /+ ↓ the checks both rules share, "" when the name is acceptable +/ private string _carriedNameCommon(string _name) { if (_name.length == 0) { diff --git a/org/in_zip_pod.org b/org/in_zip_pod.org index 2672155..330a6dd 100644 --- a/org/in_zip_pod.org +++ b/org/in_zip_pod.org @@ -51,8 +51,10 @@ template spineExtractZipPod() { alias MAX_ENTRY_COUNT = MAX_POD_ENTRY_COUNT; enum size_t MAX_PATH_DEPTH = 10; /+ max path components +/ - /+ allowed entry name pattern: alphanumeric, dots, dashes, underscores, forward slashes +/ - static auto rgx_safe_entry_name = ctRegex!(`^[a-zA-Z0-9._/ -]+$`); + /+ allowed entry name pattern: alphanumeric, dots, dashes, underscores, + forward slashes, and "~", spine's own uid separator (as carried_names.d) + +/ + static auto rgx_safe_entry_name = ctRegex!(`^[a-zA-Z0-9._/ ~-]+$`); struct ZipPodResult { string tmp_dir; /+ temp directory containing extracted pod +/ |
