Closed Intelligent2013 closed 1 month ago
Sadly, ISO historically did different and daft things, and for reasons that I do not comprehend or approve of, we are graverobbing old ISO standards.
It looks like the Metanorma code dealing with boilerplate for reference clauses is expecting them to be top-level clauses, and I can see why it would. Investigating.
Yeah, this is... bad.
The code was structured from the beginning with the presupposition that bibliographies would be banished to back material, under //bibliography/references, even if the normative references were to appear as clause 2. When the bibliography is embedded in a subclause like this, Metanorma still recognises it as a bibliography, but it is no longer located where it expects to find it, in back matter. So I need to allow Metanorma to find bibliographies anywhere in the document. We already are dealing with that in NIST, which puts bibliographies in annexes.
This is disrupting my existing code structure, and it is forcing code redesign. Which means you are not going to get it immediately, @Intelligent2013
The structure at the moment of the elements is:
references
can only contain bibitem
: they are the leaf node of references sectionsclause
: /bibliography/clause/clause/.../references
clause
containing a references
But if bibliographies can be shoved into an arbitrary subclause, we can't do that: in the example above, "General" is not a bibliographic clause.
Instead, we need a rationalised way of inferring boilerplate location, and ways of overriding it, as we pretty much already have with Terms and definitions.
references
or clause[@type = 'boilerplate']
and no other clause
or terms
.Per https://github.com/metanorma/metanorma-plateau/issues/32, which also does this clause embedding, for terms:
I am therefore retracting the ISO inference that the closest ancestor clause of terms is where the boilerplate goes. If authors want to get creative with clauses containing both terms and non-term clauses, they are going to have to signal themselves where they want the boilerplate to go explicitly, with an "insert the default boilerplate text here" directive.
So: universally, in Metanorma,
terms
or clause[@type = 'boilerplate']
or and no other clause type (including definitions
)references
or clause[@type = 'boilerplate']
and no other clause typenote[@type = 'boilerplate']
, and has been since metanorma-standoc 2.3.0note[@type = 'boilerplate']
or clause[@type = 'boilerplate']
communicates that no boilerplate text will be suppliednote[@type = 'boilerplate']
or clause[@type = 'boilerplate']
containing the text (default)
communicates that the boilerplate text supplied by default by the flavour needs to appear here. Any normal logic applied to the boilerplate, e.g. modifying it based on the presence of external terms, is applied in generating that text.Done for standoc, will now need to adjust iso code to integrate the changes.
There's an idiosyncratic rule in standoc: "places single terms boilerplate at root if there are clauses preceding the terms collection, other than boilerplate". So
== Terms and definitions
[.nonterm]
=== Terms0
Boilerplate
=== Terms
==== term
=== Symbols
<sections>
<clause>
<-- BOILERPLATE
<clause/>
<terms/>
</clause>
</sections>
That rule is not going to withstand what is happening with nested terms within other clauses, and needs to be dispensed with. We will need a new override rule: if we know a terms clause to be a terms clause because of its heading, we will retain that information, and still make it the default destination of boilerplate, so long as it contains clauses and terms, but not if it also contains symbols. That can now be overridden, but we will have:
== Terms and definitions
<-- Boilerplate
=== Clause
=== Term 1
== Terms, definitions and Symbols
=== Clause
=== Terms
<-- Boilerplate
==== Term 1
=== Symbols
So the default algorithm now becomes:
That means:
== General
=== Terms
<-- boilerplate
but
== General
=== Terms
<-- boilerplate
=== Preamble
==== Normal Terms
==== Other Terms
This is horrific, but we do need a default that can cope with Plateau and old ISO, and the existing default won't. And at least now we can override the default behaviour.
To do this, assign type=terms on clauses that are recognised as terms containers
And we do not rename to Terms and definitions clauses that are not recognised as terms containers (i.e. heading=Terms and definitions)
Issue 1 now resolved:
it "places boilerplate in Normative References subclause" do
input = <<~INPUT
#{ASCIIDOC_BLANK_HDR}
[type=section]
== General
[heading=scope]
=== Scope
This part of ISO 7005 for a single of flanges specifies requirements
for circular grey, malleable and ductile cast iron
flanges in the following nominal pressure ratings: ...
[bibliography,heading=normative references]
=== Normative references
INPUT
output = <<~OUTPUT
#{BLANK_HDR}
<sections>
<clause id="_" type="section" inline-header="false" obligation="normative">
<title>General</title>
<clause id="_" type="scope" inline-header="false" obligation="normative">
<title>Scope</title>
<p id="_">This part of ISO 7005 for a single of flanges specifies requirements
for circular grey, malleable and ductile cast iron
flanges in the following nominal pressure ratings: …<200b></p>
</clause>
<references id="_" normative="true" obligation="informative">
<title>Normative references</title>
<p id="_">There are no normative references in this document.</p>
</references>
</clause>
</sections>
</iso-standard>
OUTPUT
expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
.to be_equivalent_to xmlpp(output)
end
Issue 2 now also resolved:
it "places user-defined boilerplate in Normative References subclause" do
input = <<~INPUT
#{ASCIIDOC_BLANK_HDR}
[type=section]
== General
[heading=scope]
=== Scope
This part of ISO 7005 for a single of flanges
[bibliography,heading=normative references]
=== Normative references
[.boilerplate]
--
The following standards contain provisions
--
INPUT
output = <<~OUTPUT
#{BLANK_HDR}
<sections>
<clause id="_" type="section" inline-header="false" obligation="normative">
<title>General</title>
<clause id="_" type="scope" inline-header="false" obligation="normative">
<title>Scope</title>
<p id="_">This part of ISO 7005 for a single of flanges</p>
</clause>
<references id="_" normative="true" obligation="informative">
<title>Normative references</title>
<p id="_">The following standards contain provisions</p>
</references>
</clause>
</sections>
</iso-standard>
OUTPUT
expect(xmlpp(strip_guid(Asciidoctor.convert(input, *OPTIONS))))
.to be_equivalent_to xmlpp(output)
end
Source issue: https://github.com/metanorma/metanorma-iso/issues/1091#issuecomment-2120820053
The source document (ISO_7005_2_1988.zip) contains
Normative references
as sub-clause in the SectionGeneral
:Issue 1: The presentation XML doesn't contain the default predefined text in the
Normative references
sub-clause:If I add the user-defined boilerplate text:
then
Issue 2: the presentation XML contains the user-defined boilerplate text in the element
note
(type="boilerplate"
):instead of just
p
.If I remove the top-level Section:
(and, sure, remove
=
before each sub-clause title), then the boilerplate text generates correctly in the both cases.