Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions themes/vfb-nova/assets/css/compat.css
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,35 @@
background: var(--surface);
translate: 0 -.15em;
}

/* --------------------------------------------------------------------------
Bootstrap `alert`, for the legacy Docsy shortcodes reimplemented in
layouts/shortcodes/{alert,pageinfo}.html. Superseded term pages call them,
and without a template the whole build fails; without these rules they
would render as unstyled text. Uses the theme's own tokens rather than
Bootstrap's palette so they sit with the rest of the page.
-------------------------------------------------------------------------- */
.prose .alert {
display: block;
padding: var(--sp-4) var(--sp-5);
margin: var(--sp-5) 0;
border: 1px solid var(--line);
border-left-width: 3px;
border-radius: var(--r-md);
background: var(--elev-1);
}
.prose .alert > :first-child { margin-top: 0; }
.prose .alert > :last-child { margin-bottom: 0; }
.prose .alert-heading {
margin: 0 0 var(--sp-2);
font-size: 1rem;
font-weight: 600;
}
.prose .alert-primary,
.prose .alert-info { border-left-color: rgba(76, 141, 255, .7); }
.prose .alert-success { border-left-color: rgba(64, 192, 128, .7); }
.prose .alert-warning { border-left-color: rgba(230, 168, 64, .7); }
.prose .alert-danger { border-left-color: rgba(230, 96, 96, .7); }
.prose .alert-secondary,
.prose .alert-light,
.prose .alert-dark { border-left-color: var(--line); }
18 changes: 18 additions & 0 deletions themes/vfb-nova/layouts/shortcodes/alert.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{{/*
Docsy's `alert`, reimplemented so legacy generated pages still render.

Term pages written by vfbterms.py version 6 and earlier used Docsy
shortcodes. Those files are superseded but survive in the corpus whenever a
term drops out of one run's ID list, and a single one aborts the entire
build — twice now, at 93 and 38 minutes a time. The cost of shipping this is
one small template; the cost of not shipping it is a lost build per orphan.

Same signature as Docsy: {{< alert title="..." color="..." >}} ... {{< /alert >}}
`.Inner | markdownify` matches Docsy's own implementation, so pages written
against it render as they did.
*/}}
{{- $color := .Get "color" | default "primary" -}}
<div class="alert alert-{{ $color }}" role="alert">
{{- with .Get "title" }}<h4 class="alert-heading">{{ . }}</h4>{{ end }}
{{ .Inner | markdownify }}
</div>
9 changes: 9 additions & 0 deletions themes/vfb-nova/layouts/shortcodes/pageinfo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{{/*
Docsy's `pageinfo`, for the same reason as alert.html: legacy generated pages
call it, and a missing shortcode template is a hard build error rather than a
warning. Shipped pre-emptively so the next orphan does not cost another build.
*/}}
{{- $color := .Get "color" | default "info" -}}
<div class="pageinfo pageinfo-{{ $color }} alert alert-{{ $color }}" role="note">
{{ .Inner | markdownify }}
</div>
46 changes: 39 additions & 7 deletions vfbterms.py
Original file line number Diff line number Diff line change
Expand Up @@ -757,12 +757,51 @@ def fetch_ids(label, query):
print(f" Retrieved {len(ids)} IDs for {label}")
return ids

_VERSION_SUFFIX = re.compile(r"_v(\d+)\.md$")


def prune_old_versions(label):
"""Delete superseded term pages in the current directory.

process_term() used to remove only version-1 after writing a page. A term
absent from a single run's ID list therefore kept its older file forever:
the corpus still held _v6 pages long after version reached 9. Those orphans
are live pages -- they can collide on URL with the current version, they
are walked and parsed on every build, and pages old enough to predate the
move off Docsy call shortcodes the theme no longer ships, which aborts the
whole build.

One directory scan rather than a stat per term per version. The per-term
form costs version-1 extra syscalls for every term, which at ~763k terms is
millions of round trips; on the NFS volume this corpus lives on, metadata
operations run at a few hundred per second, so that is hours. This also
removes one stat per term relative to the old code.
"""
removed = 0
try:
with os.scandir(".") as entries:
for entry in entries:
match = _VERSION_SUFFIX.search(entry.name)
if match and int(match.group(1)) < version:
try:
os.remove(entry.name)
removed += 1
except OSError:
pass
except OSError as e:
print(f"WARNING: could not prune {label}: {e}")
return
if removed:
print(f" pruned {removed} superseded pages from {label}")


def process_group(base_path, relative_dir, label, query):
"""Change directory, fetch IDs, and generate pages for one ontology group."""
target_dir = os.path.normpath(join(base_path, relative_dir))
print(f"\n[{label}] {target_dir}")
chdir(target_dir)
save_terms(fetch_ids(label, query))
prune_old_versions(label)

def process_term(term_id):
"""Fetch, render and write one term page. Returns a status string.
Expand All @@ -786,13 +825,6 @@ def process_term(term_id):
f.write(page_content)
os.replace(tmp, filename)

# Clean up previous version
old_filename = term_id + "_v" + str(version - 1) + ".md"
if os.path.isfile(old_filename):
try:
os.remove(old_filename)
except OSError:
pass
return "ok"

def save_terms(ids):
Expand Down
Loading