Skip to content

Section Attributes

Sections and headings in your specification can be enhanced with special classes and data attributes to control TOC numbering and requirement subject inheritance.

The relevant properties are defined on Section and BlockHeading nodes:

interface Section {
type: "section";
id?: string;
heading?: BlockHeading;
unnumbered?: boolean;
dataCopConcept?: string;
children: (Section | Block)[];
}

The data-cop-concept attribute specifies the class of products that requirements in a section apply to. This enables machine-readable categorization of requirements.

<section data-cop-concept="client">
<h2>Client Requirements</h2>
<!-- All spec-statements inherit data-cop-concept="client" -->
<spec-statement>The client MUST authenticate.</spec-statement>
<spec-statement>The client SHOULD cache tokens.</spec-statement>
</section>

Use the {data-cop=value} suffix:

## Client Requirements {data-cop-concept=client #client}
<spec-statement>The client MUST authenticate.</spec-statement>

data-cop-concept cascades down to all nested sections and statements:

<section id="server" data-cop-concept="server">
<h2>Server Requirements</h2>
<!-- Inherits server -->
<spec-statement>The server MUST validate tokens.</spec-statement>
<section data-cop-concept="client">
<h3>Client-Server Interaction</h3>
<!-- Overridden to client -->
<spec-statement>The client MUST retry on 503.</spec-statement>
</section>
</section>

NOTE: to make this referenceable, the section must get the same id attribute as the data-cop-concept value.

Individual statements can override the inherited value:

<section data-cop-concept="server">
<h2>Server Section</h2>
<!-- Uses inherited "server" -->
<spec-statement>The server MUST respond with JSON.</spec-statement>
<!-- Overridden to "client" -->
<spec-statement data-cop-concept="client"
>The client MUST parse JSON.</spec-statement
>
</section>

When data-cop-concept is set, statements include spec:requirementSubject in the JSON-LD:

{
"@context": { ... },
"@graph": [
{
"id": "https://example.org/spec",
"type": "spec:Specification",
{
"id": "https://example.org/spec",
"type": "spec:Specification",
"spec:classesOfProducts": {
"id": "https://example.org/spec#classes-of-products",
"type": "skos:ConceptScheme",
"skos:hasTopConcept": [
{ "id": "https://example.org/spec#client" }
]
},
"spec:requirement": [
{ "id": "https://example.org/spec#stmt-1" }
]
},
{
"id": "https://example.org/spec#client",
"type": "skos:Concept",
"skos:inScheme": { "id": "https://example.org/spec#classes-of-products" },
"skos:topConceptOf": { "id": "https://example.org/spec#classes-of-products" }
},
{
"id": "https://example.org/spec#stmt-1",
"type": "spec:Requirement",
"spec:statement": "the client must authenticate.",
"spec:requirementSubject": { "id": "https://example.org/spec#client" }
}
]
}

See Spec Statements for more on JSON-LD output.


Some sections—like Abstract and Status of This Document (SOTD)—should appear in the Table of Contents without a section number.

When a section is marked as unnumbered:

  1. It appears in the TOC without a number
  2. Subsequent numbered sections continue from where numbering left off
  3. The section is not included in document.computed.headingNumbers

Add one of the following CSS classes to your <section> element:

<!-- Using 'unnumbered' class -->
<section id="abstract" class="unnumbered">
<h1>Abstract</h1>
<p>This section is unnumbered in the TOC.</p>
</section>
<!-- Using 'informative' class (implies unnumbered) -->
<section id="sotd" class="informative">
<h1>Status of This Document</h1>
</section>
<!-- Using 'introductory' class (implies unnumbered) -->
<section id="intro-note" class="introductory">
<h1>About This Spec</h1>
</section>

Use the {.unnumbered} suffix on headings:

# Abstract {.unnumbered}
This is an unnumbered abstract.
# Introduction
This should be numbered as "1".

The {.unnumbered} suffix is automatically stripped from the heading text in the output.

ClassEffect
unnumberedExplicitly marks section as unnumbered
informativeNon-normative section (also unnumbered)
introductoryIntroductory content (also unnumbered)

When a parent section is marked as unnumbered, all child sections automatically inherit the unnumbered status.