Add an embedded systems topic
All checks were successful
Build and deploy static pages / build-and-push (push) Successful in 14s

Eight conferences and six journals, curated for the computer-science side of
the field. EDA and circuit-design venues are deliberately excluded — DAC, DATE,
ICCAD and CODES+ISSS are canonical for embedded systems but not for the kind of
work this site tracks — and venues.yaml carries that rationale as a header
comment so the next person doesn't "helpfully" add them back.

Two curation calls worth recording. SenSys, IPSN and IoTDI merged in 2026 into
one conference, the ACM/IEEE International Conference on Embedded Artificial
Intelligence and Sensing Systems; it is tracked under the SenSys acronym, which
is what ICORE and DBLP still use, and IPSN and IoTDI are not listed separately.
RTCSA and ICCPS were dropped — the first is CORE B with no announced 2027
edition, the second carries no CORE rank at all.

Deadlines are all source: manual, verified against the official CFPs. Only EWSN
has a WikiCFP entry for its current edition; every other series there stops at
an edition that has already been held, so the rest are wikicfp_id: false. ECRTS
and LCTES have no announced next edition and sit under missing:, which renders
as TBD. With the stale-deadline handling from 5b06f48 this reads correctly:
only RTAS shows an open deadline, and the rest land in the elapsed-rounds table
rather than advertising passed dates as upcoming.

The topic also exposed three generator bugs that cloud-edge never hit:

_journals_section_body() read scimago_* straight off the venues.yaml entry, so
the journals index showed a dash for every journal without inline values, while
the journal pages resolved the same numbers from rankings/scimago.csv. Both now
share a _journal_ranks() helper, and gen_section_indexes() takes the SCImago
table to feed it. cloud-edge never saw this because all seven of its journals
carry inline values.

The SCImago CSV writes SJR with a decimal comma (0,864). Nothing consumed those
values before, so the loader now normalises them to a dot and CSV-derived
numbers render like the inline ones.

gen_digests() now writes digests/_index.md. Hugo only auto-creates a section
page when the section has a listable page, and a topic with no digests yet
holds nothing but build.list: never stubs, so the Digests nav link 404'd. It
preserves any existing body, leaving cloud-edge's file unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
khannurien
2026-08-18 13:33:53 +00:00
parent 5b06f484f5
commit ee78e30d17
41 changed files with 1206 additions and 22 deletions

View File

@@ -111,7 +111,7 @@ def load_scimago(path: str) -> dict[str, dict]:
if title:
journals[title] = {
"scimago_quartile": (row.get("SJR Best Quartile") or row.get("Best Quartile") or "").strip(),
"scimago_sjr": (row.get("SJR") or "").strip(),
"scimago_sjr": (row.get("SJR") or "").strip().replace(",", "."),
"scimago_h_index": (row.get("H index") or row.get("H Index") or "").strip(),
}
return journals
@@ -423,13 +423,25 @@ def _conferences_section_body(venues: dict, icore: dict, deadlines: dict,
return "\n".join(lines) + "\n"
def _journals_section_body(venues: dict, venue_digests: dict | None = None, base_path: str = "") -> str:
def _journal_ranks(journal: dict, scimago: dict[str, dict]) -> dict:
"""SCImago values for one journal: inline `scimago_*` fields win, CSV fills the gap."""
inline = {
k: journal[k]
for k in ("scimago_quartile", "scimago_sjr", "scimago_h_index")
if journal.get(k)
}
return inline or scimago_lookup(scimago, journal.get("full_name", ""), journal.get("issn", ""))
def _journals_section_body(venues: dict, scimago: dict[str, dict] | None = None,
venue_digests: dict | None = None, base_path: str = "") -> str:
rows = []
for j in venues.get("journals") or []:
acronym = j.get("acronym", "")
q = j.get("scimago_quartile") or ""
sjr = j.get("scimago_sjr") or ""
h = j.get("scimago_h_index") or ""
ranks = _journal_ranks(j, scimago or {})
q = ranks.get("scimago_quartile") or ""
sjr = ranks.get("scimago_sjr") or ""
h = ranks.get("scimago_h_index") or ""
model = (j.get("submission_model") or "rolling").title()
domains = ", ".join(f"`{d}`" for d in j.get("domain", []))
n_dig = len((venue_digests or {}).get(acronym, []))
@@ -750,12 +762,7 @@ def gen_journals(venues: dict, scimago: dict[str, dict], root: Path,
path = root / "venues" / "journals" / acronym / "_index.md"
existing_fm, _ = read_hugo_file(path)
inline_sjr = {
k: journal[k]
for k in ("scimago_quartile", "scimago_sjr", "scimago_h_index")
if journal.get(k)
}
sjr_data = inline_sjr or scimago_lookup(scimago, journal.get("full_name", ""), journal.get("issn", ""))
sjr_data = _journal_ranks(journal, scimago)
new_fm: dict = {
"title": acronym,
@@ -794,7 +801,8 @@ def gen_calendar(venues: dict, icore: dict, deadlines: dict, root: Path,
print(f" {path.relative_to(root.parent)}", file=sys.stderr)
def gen_section_indexes(venues: dict, icore: dict, deadlines: dict, root: Path,
def gen_section_indexes(venues: dict, icore: dict, scimago: dict[str, dict],
deadlines: dict, root: Path,
venue_digests: dict | None = None, base_path: str = "") -> None:
# venues/_index.md
p = root / "venues" / "_index.md"
@@ -815,7 +823,7 @@ def gen_section_indexes(venues: dict, icore: dict, deadlines: dict, root: Path,
n = len(venues.get("journals") or [])
fm = merge_fm(read_hugo_file(p)[0],
{"title": "Journals", "description": f"{n} tracked journals", "draft": False}, set())
write_hugo_file(p, fm, _journals_section_body(venues, venue_digests, base_path))
write_hugo_file(p, fm, _journals_section_body(venues, scimago, venue_digests, base_path))
print(f" {p.relative_to(root.parent)}", file=sys.stderr)
@@ -831,6 +839,16 @@ def gen_digests(papers_dir: Path, root: Path,
real_slugs: set[str] = set()
count = 0
# Section index. Hugo only auto-creates one when the section has a listable
# page, and a fresh topic holds nothing but `build.list: never` stubs — so
# without this file the Digests nav link 404s until the first real digest.
index_path = root / "digests" / "_index.md"
index_fm, index_body = read_hugo_file(index_path)
index_fm = merge_fm(index_fm, {"title": "Digests", "layout": "digests", "draft": False}, set())
write_hugo_file(index_path, index_fm,
f"\n{index_body.strip() or 'tl;drs for the top papers.'}\n")
print(f" {index_path.relative_to(root.parent)}", file=sys.stderr)
if papers_dir.exists():
for digest_file in sorted(papers_dir.glob("*-digest.yaml")):
with open(digest_file, encoding="utf-8") as f:
@@ -954,7 +972,7 @@ def main() -> None:
if deadlines: print(f"Loaded deadlines for {len(deadlines)} venues", file=sys.stderr)
print("\nGenerating venue section indexes …", file=sys.stderr)
gen_section_indexes(venues, icore, deadlines, content_root, venue_digests, base_path)
gen_section_indexes(venues, icore, scimago, deadlines, content_root, venue_digests, base_path)
print("\nGenerating conference pages …", file=sys.stderr)
n_conf = gen_conferences(venues, icore, deadlines, content_root, venue_digests, base_path)