From 94d62ce009c0d39f2234aba8c53d6ea005fca2df Mon Sep 17 00:00:00 2001 From: Steve LLamb <38917682+SteveLLamb@users.noreply.github.com> Date: Thu, 19 Mar 2026 10:35:36 -0700 Subject: [PATCH] Update terms for Examples --- css/smpte.css | 2 +- doc/main.html | 25 ++++++--- js/validate.mjs | 53 +++++++++++++++++-- scripts/build.mjs | 6 ++- smpte.js | 13 +++++ .../terms-note-to-entry-2-valid.html | 2 +- .../html/validation/terms-valid.html | 2 +- test/src/testValidation.mjs | 2 +- 8 files changed, 88 insertions(+), 17 deletions(-) diff --git a/css/smpte.css b/css/smpte.css index 280b1eb..03f8fd4 100644 --- a/css/smpte.css +++ b/css/smpte.css @@ -209,7 +209,7 @@ blockquote { /* note and example */ -.note, .example { +.note, .example, .deprecated { font-size: 0.9rem; margin-left: 1rem; } diff --git a/doc/main.html b/doc/main.html index 834d7d3..cd6ba08 100644 --- a/doc/main.html +++ b/doc/main.html @@ -662,13 +662,20 @@

Terms and definitions section

  • Each dt element contains a single term, abbreviation or symbol. Zero or more additional dt elements can follow the first dt element, in which case all the terms, abbreviations and symbols in the immediately preceding dt elements are synonyms.
  • -
  • The first dd element immediately following the last dt element, if present, shall be - a definition.
  • -
  • The next dd element, if present, shall contain a single reference to a bibliographic entry, - in which case the entry is the source of the definition of the term.
  • -
  • The remaining dd elements, if present, - shall have a class attribute that contains the value note, in which case the - elements are notes to the entry.
  • +
  • The dd elements following the dt element(s) shall appear in the following + order — each group is optional, but if present, it shall appear in this sequence: +
      +
    1. Definition: the first dd element shall be the definition of the term. This element is required.
    2. +
    3. Deprecated: the next dd element, if present, shall have a class + attribute containing deprecated, indicating the term is deprecated. At most one such element is permitted.
    4. +
    5. Examples: the next dd element(s), if present, shall each have a class + attribute containing example.
    6. +
    7. Notes: the next dd element(s), if present, shall each have a class + attribute containing note.
    8. +
    9. Source: the last dd element, if present, shall contain a single reference to a + bibliographic entry and serves as the source of the definition.
    10. +
    +
  • @@ -683,8 +690,10 @@

    Terms and definitions section

    <dt><dfn>key number</dfn></dt> <dd>number that is printed with ink or exposed onto the film at the time of manufacture at regular intervals, typically one foot.</dd> - <dd><a href="#bib-key-number-spec"></a></dd> + <dd class="deprecated">deprecated term</dd> + <dd class="example">An example of a key number is 12345.</dd> <dd class="note">Key number shall not be confused with key frame.</dd> + <dd><a href="#bib-key-number-spec"></a></dd> </dl> </section> diff --git a/js/validate.mjs b/js/validate.mjs index 039193e..7cc5627 100644 --- a/js/validate.mjs +++ b/js/validate.mjs @@ -269,6 +269,36 @@ class DefinitionSourceMatcher { } } +class DefinitionExampleMatcher { + static match(element, logger) { + if (element.localName !== "dd" || !element.classList.contains("example")) + return false; + + for (const child of element.children) { + if (!AnyPhrasingMatcher.match(child, logger)) { + logger.error(`Note to entry contains non-phrasing element`, child); + } + } + + return true; + } +} + +class DefinitionDeprecatedMatcher { + static match(element, logger) { + if (element.localName !== "dd" || !element.classList.contains("deprecated")) + return false; + + for (const child of element.children) { + if (!AnyPhrasingMatcher.match(child, logger)) { + logger.error(`Deprecated entry contains non-phrasing element`, child); + } + } + + return true; + } +} + class DefinitionNoteMatcher { static match(element, logger) { if (element.localName !== "dd" || !element.classList.contains("note")) @@ -652,7 +682,8 @@ class InternalDefinitionsMatcher { } if (count === 0) { - logger.error(`Invalid definition`, element); + const next = children[0]; + logger.error(`Out of order or unrecognized element in definition${next ? `: ${next.localName}${next.className ? `.${next.className}` : ""}` : ""}
    Required order is: definition, deprecated, example, note, source`, element); break; } @@ -664,10 +695,20 @@ class InternalDefinitionsMatcher { children.shift(); } - /* look for definition source */ + /* look for deprecated marker (at most one) */ - if (children.length > 0 && DefinitionSourceMatcher.match(children[0], logger)) { + if (children.length > 0 && DefinitionDeprecatedMatcher.match(children[0], logger)) { + children.shift(); + if (children.length > 0 && DefinitionDeprecatedMatcher.match(children[0], logger)) + logger.error(`Only one dd.deprecated is permitted per term`, children[0]); + } + + /* look for examples to entry */ + count = 0; + + while (children.length > 0 && DefinitionExampleMatcher.match(children[0], logger)) { children.shift(); + count++; } /* look for notes to entry */ @@ -678,6 +719,12 @@ class InternalDefinitionsMatcher { count++; } + /* look for definition source (must be last) */ + + if (children.length > 0 && DefinitionSourceMatcher.match(children[0], logger)) { + children.shift(); + } + } return true; diff --git a/scripts/build.mjs b/scripts/build.mjs index 46c315b..5b8de88 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -730,8 +730,10 @@ async function main() { const docMetadata = smpteValidate(dom.window.document, logger); - if (logger.hasFailed()) - throw Error(`SMPTE schema validation failed:\n${logger.errorList().join("\n")}`); + if (logger.hasFailed()) { + const errors = logger.errorList().map(e => ` ${e.message}`).join("\n"); + throw Error(`SMPTE schema validation failed:\n${errors}`); + } /* collect elements */ diff --git a/smpte.js b/smpte.js index 408fe2a..a93b075 100644 --- a/smpte.js +++ b/smpte.js @@ -1194,6 +1194,18 @@ function numberExamples() { } } +function markDeprecated() { + const terms = document.getElementById("terms-int-defs"); + if (!terms) return; + + for (const el of terms.querySelectorAll("dd.deprecated")) { + const label = document.createElement("span"); + label.className = "heading-label"; + label.appendChild(document.createTextNode("DEPRECATED: ")); + el.insertBefore(label, el.firstChild); + } +} + function numberTerms() { const termsSection = document.getElementById("sec-terms-and-definitions"); const terms = document.getElementById("terms-int-defs"); @@ -1487,6 +1499,7 @@ async function render() { numberFormulae(); numberNotes(); numberExamples(); + markDeprecated(); numberTerms(); resolveLinks(docMetadata); insertTOC(docMetadata); diff --git a/test/resources/html/validation/terms-note-to-entry-2-valid.html b/test/resources/html/validation/terms-note-to-entry-2-valid.html index ee25b48..936dd33 100644 --- a/test/resources/html/validation/terms-note-to-entry-2-valid.html +++ b/test/resources/html/validation/terms-note-to-entry-2-valid.html @@ -31,9 +31,9 @@
    Clear
    CLR
    something that is clean
    -
    The term shall not be used to refer to clarity of mind.
    The term is not intended to be used ever.
    +
    Medium
    something that is not large as defined in
    diff --git a/test/resources/html/validation/terms-valid.html b/test/resources/html/validation/terms-valid.html index 19b83b2..153dd81 100644 --- a/test/resources/html/validation/terms-valid.html +++ b/test/resources/html/validation/terms-valid.html @@ -31,8 +31,8 @@
    Clear
    CLR
    When something is clean
    -
    The term shall not be used to refer to clarity of mind.
    +
    diff --git a/test/src/testValidation.mjs b/test/src/testValidation.mjs index 4d811a0..10c38e0 100644 --- a/test/src/testValidation.mjs +++ b/test/src/testValidation.mjs @@ -57,7 +57,7 @@ async function _test(path) { } console.log(`**** ${path} failed.`); - logger.errorList().map(msg => console.log(` ${msg.message}`)) + logger.errorList().map(msg => console.log(` ${msg.message}`)); return false; }