Requirement, Recommendation, and Permission blocks

Requirements, Recommendations, and Permissions are encoded using AsciiDoc markup for example blocks, prepended with an role attribute containing the type of the block (i.e., its obligation)—one of “requirement”, “recommendation”, or “permission”. For example:

Most basic example
[.permission]
====
I recommend this
====

(Below, "requirement" is used to refer to any of these three block types.)

Attributes

In addition to block type described above, following attributes are supported (see usage example below):

subject

Indicates the subject of the requirement. Does not get rendered in final output.

label

Indicates conventional label assigned to the requirement. If present, it will be rendered in final output.

classification

May be used to give an arbitrary number of key-value pairs of tags describing the requirement. Key and value are separated by a colon, multiple values are delimited by comma, and key-value pairs are delimited by semicolon. Both key and value are expected to be tokens containing no punctuation.

obligation

Can contain one or more of "requirement", "permission", "recommendation", comma-delimited. Using this attribute will override the obligation of the blog.

inherit

May be used to reference the label of a requirement that is imported or presupposed by this requirement.

An exhaustive attribute example
[.recommendation,label="/ogc/recommendation/wfs/2",subject="user",inherit="/ss/584/2015/level/1",classification="control-class:Technical;priority:P0;family:System and Communications Protection,System and Communications Protocols",obligation="permission,recommendation"]
====
I recommend this
====

Nested blocks

Requirements can be nested, as is the case with any delimited block in Asciidoctor, by adding one more delimiter symbol than its containing block; that means that nested requirements are marked up as nested examples.

Nesting example
[.permission]
====
I permit this
=====
Example 2
=====
[.permission]
=====
I also permit this
=====
====

Named blocks and descriptions

You can mark up the internal structure of a requirement to make it machine-readable, although this is not expected to be reflected in rendering.

The internal structure of requirements is marked up with open blocks, which are marked up with a succession of two or more hyphens, rather than equals signs. Each open block needs to be named with the kind of component it contains as a role attribute; the recognised values for Metanorma are:

  • specification (a formal statement, which may be considered the object of the requirement)

  • measurement-target (for quantitative requirements)

  • verification (verification steps for the requirement)

  • import (code stubs)

For example:

An example of a requirement with four components
[.requirement]
====
[.specification]
--
This is a formal specification
--

[.measurement-target]
--
This is a measurement target
--

[.verification]
--
This is a verification step
--

[.import]
--
This is a code stub
--

====

The combination of example markup and open block markup allows us to combine nested requirements with internal structure for the nested requirements:

An example of nested requirements with components
[.requirement,label="requirement A"]
====

[.requirement,label="requirement A1"]
=====

[.specification]
--
This is a formal specification
--

=====

[.requirement,label="requirement A2"]
=====

[.measurement-target]
--
This is a measurement target
--

=====

====

Any text not wrapped in a named open block is considered to be part of a description.

Any text in a named open block allowed under Metanorma is considered to be a separate subpart of the requirement. These blocks can have types, referring to the conventions or computer frameworks that they follow. They are given by setting the type attribute on the open block:

An example of mixed descriptions and typed open blocks
[.requirement,label="requirement A"]
====

This is some descriptive text.

[.specification,type=EBNF]
--
This is a formal specification in EBNF
--

This is some more descriptive text.

====

Text in a named open block may be include or consist of machine readable code; any such code needs to be wrapped in turn in a source code element, which is expected to contain an attribute giving the computer language the block is expressed in. (The notion of "language" may be expanded to include a particular computer framework that the code is to be run under.) [sourcecode,text] is taken as meaning that the block is still human readable. The language of a source code block is likely to be distinct from the type of named block it is contained in.

An example of machine readable code in a specification
[.requirement,label="requirement A"]
====

This is some descriptive text.

[.verification,type=heuristic]
--
[source,ruby]
----
instances.each do |i|
  warn "uh-oh" if i > 5
end
----
--

====

By default, both named blocks and descriptions will be included in final output. Often, though not always, named blocks contain machine-readable code which is not intended to be included in the output, but is supplemental to the human-readable description. That is signalled through the options attribute exclude on the named block.

An example of a complex recommendation with named blocks
[.recommendation,label="/ogc/recommendation/wfs/2",subject="user"]
====
I recommend _this_.
[.specification,type="tabular"]
--
This is the object of the recommendation:
|===
|Object |Value
|Mission | Accomplished
|===
--
As for the measurement targets,
[.measurement-target]
--
The measurement target shall be measured as:
[stem]
++++
r/1 = 0
++++
--
[.verification,type="comprehensive"]
--
The following code will be run for verification:
[source,CoreRoot]
----
CoreRoot(success): HttpResponse
if (success)
  recommendation(label: success-response)
end
----
--

[.import%exclude]
--
[source,CoreRoot]
----
success-response()
----
--
====