[READ-ONLY] Mirror of https://github.com/jmrplens/PyOctaveBand. [Python3] Octave-Band and Fractional Octave-Band filter. For signal in time domain. jmrplens.github.io/PyOctaveBand/
acoustics audio filter frequency frequency-analysis frequency-domain octave python3 signal time-domain
0

Configure Feed

Select the types of activity you want to include in your feed.

Add a page header chips run derived from the frontmatter bibliography

The same information the sidebar experiment has been trying to fit into the
tree, placed under the H1 where there is horizontal room and no navigation to
pollute: one quiet line naming the standards that govern the page, then the
works its methods are attributed to.

It is derived from each page's own typed `references` block rather than from
a second hand-maintained list, so the header and the References section at the
bottom cannot disagree, and every chip links to its full entry there, which
now carries a stable id and highlights when jumped to. Standard designations
collapse to their family (ISO 10140-2:2010 becomes ISO 10140) and books and
articles become author and year; five standards and three works fit on one
line, anything beyond that folds into a single "+N more" link. Pages without
references render nothing.

It rides on its own `data-page-chips` attribute so it can be compared against
any sidebar variant, and it supersedes the hand-derived subtitle of the clean
variant, which now yields whenever the run is on.

José M. Requena Plens (Jul 25, 2026, 11:53 PM +0200) 28ac8c71 9cd8264a

+182 -11
+9 -3
site/src/components/Head.astro
··· 98 98 {description && <meta name="twitter:description" content={description} />} 99 99 100 100 {/* TOC-info experiment (TOC-REDESIGN-NOTES.md): apply the persisted variant 101 - attributes before first paint, then mount the floating variant switcher. 102 - Prototype-only; remove both scripts when a variant is chosen. */} 101 + attributes (`data-page-chips`, `data-toc-style`, `data-api-style`) before 102 + first paint, then mount the floating variant switcher. Prototype-only; 103 + remove both scripts when a variant is chosen. */} 103 104 <script is:inline> 104 105 (() => { 105 106 const d = document.documentElement; 106 107 let toc = 'focus'; 107 108 let api = 'split'; 109 + let page = 'header'; 108 110 try { 109 111 toc = localStorage.getItem('tocStyle') || toc; 110 112 api = localStorage.getItem('apiStyle') || api; 113 + page = localStorage.getItem('pageChips') || page; 111 114 } catch {} 112 115 d.dataset.tocStyle = toc; 113 116 d.dataset.apiStyle = api; 117 + d.dataset.pageChips = page; 114 118 d.dataset.area = /\/reference\/api(\/|$)/.test(location.pathname) ? 'api' : 'guides'; 115 119 })(); 116 120 </script> ··· 119 123 const d = document.documentElement; 120 124 const TOC = ['focus', 'annotate', 'hover', 'clean', 'none']; 121 125 const API = ['split', 'collapsed', 'inline']; 126 + const PAGE = ['header', 'off']; 122 127 123 128 const radios = (name, values, current) => 124 129 values ··· 135 140 widget.innerHTML = 136 141 '<summary title="TOC experiment switcher">UX</summary>' + 137 142 '<div class="toc-switcher-panel">' + 138 - `<fieldset><legend>TOC info</legend>${radios('tocStyle', TOC, d.dataset.tocStyle)}</fieldset>` + 143 + `<fieldset><legend>Page chips</legend>${radios('pageChips', PAGE, d.dataset.pageChips)}</fieldset>` + 144 + `<fieldset><legend>Sidebar info</legend>${radios('tocStyle', TOC, d.dataset.tocStyle)}</fieldset>` + 139 145 `<fieldset><legend>API sidebar</legend>${radios('apiStyle', API, d.dataset.apiStyle)}</fieldset>` + 140 146 '</div>'; 141 147 document.body.appendChild(widget);
+71
site/src/components/PageChips.astro
··· 1 + --- 2 + /** 3 + * Page header chips: one quiet horizontal run under the H1 stating which 4 + * standards govern the page and which named works the methods are attributed 5 + * to (TOC-info experiment, `data-page-chips='header'`; see 6 + * TOC-REDESIGN-NOTES.md). 7 + * 8 + * Everything comes from the page's own `references` frontmatter through 9 + * src/lib/reference-chips.ts, so the header cannot disagree with the 10 + * References section at the bottom, and every chip links to its full entry 11 + * there. Pages without references render nothing. 12 + * 13 + * Always in the DOM, displayed only while the variant is active 14 + * (src/styles/toc-info.css), so switching costs no rebuild. 15 + */ 16 + import { pageChips } from '../lib/reference-chips'; 17 + 18 + const { entry, lang } = Astro.locals.starlightRoute; 19 + const isEs = lang.startsWith('es'); 20 + const { standards, references, hidden } = pageChips(entry.data.references, isEs); 21 + 22 + const labels = isEs 23 + ? { standards: 'Normas aplicables:', references: 'Referencias:', more: (n: number) => `+${n} más` } 24 + : { standards: 'Standards:', references: 'Key references:', more: (n: number) => `+${n} more` }; 25 + --- 26 + 27 + { 28 + (standards.length > 0 || references.length > 0) && ( 29 + <p class="page-chips"> 30 + {standards.length > 0 && ( 31 + <span class="chip-run chip-run-standard"> 32 + <span class="sr-only">{labels.standards} </span> 33 + {standards.map((chip) => ( 34 + <a class="page-chip chip-standard" href={`#${chip.anchor}`}> 35 + {chip.text} 36 + </a> 37 + ))} 38 + </span> 39 + )} 40 + {references.length > 0 && ( 41 + <span class="chip-run chip-run-reference"> 42 + <span class="sr-only">{labels.references} </span> 43 + {references.map((chip) => ( 44 + <a class="page-chip chip-theory" href={`#${chip.anchor}`}> 45 + {chip.text} 46 + </a> 47 + ))} 48 + </span> 49 + )} 50 + {hidden > 0 && ( 51 + <a class="page-chip chip-more" href="#references"> 52 + {labels.more(hidden)} 53 + </a> 54 + )} 55 + </p> 56 + ) 57 + } 58 + 59 + <style> 60 + .sr-only { 61 + position: absolute; 62 + width: 1px; 63 + height: 1px; 64 + padding: 0; 65 + margin: -1px; 66 + overflow: hidden; 67 + clip-path: inset(50%); 68 + white-space: nowrap; 69 + border: 0; 70 + } 71 + </style>
+7 -1
site/src/components/PageTitle.astro
··· 9 9 * and is identical in EN and ES (designations and author names are 10 10 * language-neutral; only the visually-hidden accessibility prefix is 11 11 * localized). It is always rendered and only displayed when 12 - * `data-toc-style='clean'` is active (toc-info.css). 12 + * `data-toc-style='clean'` is active and the page chips run is off 13 + * (toc-info.css), since both sit under the H1 and say the same thing. 14 + * 15 + * PageChips.astro is the successor of this line: the same idea, but derived 16 + * from the page's own `references` frontmatter and linked to the bibliography. 13 17 */ 14 18 import Default from '@astrojs/starlight/components/PageTitle.astro'; 15 19 import type { StarlightRouteData } from '@astrojs/starlight/route-data'; 20 + import PageChips from './PageChips.astro'; 16 21 17 22 type SidebarEntry = StarlightRouteData['sidebar'][number]; 18 23 type SidebarLink = Extract<SidebarEntry, { type: 'link' }>; ··· 51 56 --- 52 57 53 58 <Default><slot /></Default> 59 + <PageChips /> 54 60 { 55 61 chips.length > 0 && ( 56 62 <p class="page-standards">
+22 -6
site/src/components/References.astro
··· 11 11 * its own https://doi.org link with nothing after it, and the optional note 12 12 * follows as an annotation line, annotated-bibliography style. 13 13 */ 14 - import type { CollectionEntry } from 'astro:content'; 15 - 16 - type Reference = NonNullable<CollectionEntry<'docs'>['data']['references']>[number]; 14 + import { referenceAnchors, type Reference } from '../lib/reference-chips'; 17 15 18 16 /** One rendered fragment of a citation: plain, italicized or linked text. */ 19 17 interface Part { ··· 143 141 return `${who(ref)} ${year} ${ref.title}`.toLowerCase(); 144 142 } 145 143 146 - const sorted = [...references].sort((a, b) => 144 + /* 145 + Each entry carries a stable fragment id so the page header chips 146 + (PageChips.astro) can link straight to it. The ids are derived from the 147 + frontmatter order by the shared helper, so sorting for display here does not 148 + change them. 149 + */ 150 + const anchors = referenceAnchors(references); 151 + const sorted = [...references.entries()].sort(([, a], [, b]) => 147 152 sortKey(a).localeCompare(sortKey(b), lang, { sensitivity: 'base' }), 148 153 ); 149 154 --- ··· 167 172 </a> 168 173 </div> 169 174 <ul role="list"> 170 - {sorted.map((ref) => ( 171 - <li> 175 + {sorted.map(([index, ref]) => ( 176 + <li id={anchors[index]}> 172 177 {citationParts(ref).map((part) => { 173 178 const inner = 174 179 part.italic === 'cite' ? ( ··· 219 224 } 220 225 .page-references li + li { 221 226 margin-top: 0.75rem; 227 + } 228 + /* Landing spot for the page header chips: clear the sticky header, and 229 + mark the entry that was jumped to so the reader sees which of a long 230 + list answered the click. */ 231 + .page-references li { 232 + scroll-margin-top: calc(var(--sl-nav-height) + 1rem); 233 + } 234 + .page-references li:target { 235 + background: var(--sl-color-gray-6); 236 + border-radius: 0.25rem; 237 + box-shadow: 0 0 0 0.4rem var(--sl-color-gray-6); 222 238 } 223 239 /* <cite> carries the APA italics; keep the surrounding size and colour. */ 224 240 .page-references cite,
+73 -1
site/src/styles/toc-info.css
··· 367 367 display: none; 368 368 } 369 369 370 - :root[data-toc-style='clean'] .page-standards { 370 + :root[data-toc-style='clean']:not([data-page-chips='header']) .page-standards { 371 371 display: flex; 372 372 flex-wrap: wrap; 373 373 align-items: baseline; ··· 467 467 :root[data-toc-style='clean'] .section-standards td:empty { 468 468 display: none; 469 469 } 470 + } 471 + 472 + /* --------------------------------------------------------------------------- 473 + PAGE CHIPS (`data-page-chips='header'`), independent of the sidebar 474 + variants: one quiet run under the H1 naming the standards that govern the 475 + page and the works its methods are attributed to, every item a link into 476 + the References section at the bottom. Rendered by PageChips.astro from the 477 + page's own frontmatter bibliography. 478 + 479 + Deliberately not pills: at page level a run of tinted text with one leading 480 + dot per category reads as a dateline, while filled badges read as tags and 481 + compete with the H1. 482 + --------------------------------------------------------------------------- */ 483 + 484 + .page-chips { 485 + display: none; 486 + } 487 + 488 + :root[data-page-chips='header'] .page-chips { 489 + display: flex; 490 + flex-wrap: wrap; 491 + align-items: baseline; 492 + gap: 0.15rem 1.15rem; 493 + margin-block-start: 0.55rem; 494 + font-size: var(--sl-text-sm); 495 + line-height: 1.5; 496 + } 497 + 498 + .page-chips .chip-run { 499 + display: inline-flex; 500 + flex-wrap: wrap; 501 + align-items: baseline; 502 + gap: 0.15rem 0.7rem; 503 + } 504 + 505 + /* One leading dot per category run: teal for the governing standards, amber 506 + for the named references. Two marks per page, no legend needed, and the 507 + labels stay language neutral. */ 508 + .page-chips .chip-run::before { 509 + content: ''; 510 + flex: 0 0 auto; 511 + align-self: center; 512 + inline-size: 0.4rem; 513 + block-size: 0.4rem; 514 + margin-inline-end: 0.1rem; 515 + border-radius: 50%; 516 + } 517 + .page-chips .chip-run-standard::before { 518 + background: var(--chip-standard-accent); 519 + } 520 + .page-chips .chip-run-reference::before { 521 + background: var(--chip-theory-accent); 522 + } 523 + 524 + .page-chips .page-chip { 525 + font-weight: 500; 526 + white-space: nowrap; 527 + text-decoration: none; 528 + } 529 + .page-chips .page-chip:hover, 530 + .page-chips .page-chip:focus-visible { 531 + text-decoration: underline; 532 + text-underline-offset: 0.25em; 533 + } 534 + .page-chips .chip-standard { 535 + color: var(--chip-standard-ink); 536 + } 537 + .page-chips .chip-theory { 538 + color: var(--chip-theory-ink); 539 + } 540 + .page-chips .chip-more { 541 + color: var(--chip-ink-muted); 470 542 } 471 543 472 544 /* ---------------------------------------------------------------------------