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:
+
+ - Definition: the first
dd element shall be the definition of the term. This element is required.
+ - 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.
+ - Examples: the next
dd element(s), if present, shall each have a class
+ attribute containing example.
+ - Notes: the next
dd element(s), if present, shall each have a class
+ attribute containing note.
+ - Source: the last
dd element, if present, shall contain a single reference to a
+ bibliographic entry and serves as the source of the definition.
+
+
@@ -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.
+