Stage 3: #670 Add impose-role attribute to topic references
Define a new attribute @impose-role
that can be used on topicref
elements. When specified on a topicref element with a value of "impose", and
the topicref element is a reference to a map, this indicates that the role of the topicref
overrides the role of the referenced map or topicref.
Champion
Provide information about the champion. If the proposal is submitted by a subcommittee, include the name of the point person. He or she should have prepared this proposal and thoroughly understand all of the content. The point person must be present at the TC calls when this proposal is discussed.
Tracking information: Stage two
Event | Date | Links |
---|---|---|
Initial suggestion | 01 March 2022 | Minutes, 01 March 2022 |
Stage 1 proposal accepted | 15 March 2022 | |
Stage 2 proposal submitted to TC for early feedback (not applicable to all proposals) | 24 June 2022 | https://lists.oasis-open.org/archives/dita/202206/msg00057.html |
Stage 2 proposal submitted to reviewers | 28 June 2022 |
|
Stage 2 proposal submitted to TC | 15 August 2022 | |
Stage 2 proposal discussed by TC | 16 August 2022 | https://lists.oasis-open.org/archives/dita/202208/msg00033.html |
Stage 2 proposal approved by TC | 23 August 2022 | https://lists.oasis-open.org/archives/dita/202208/msg00050.html |
Tracking information: Stage three
In the following table, insert cross references to e-mails to the TC list or meeting minutes:
- Be sure to use the public URL as the value of the
@href
attribute - For link text for the cross references, use
E-mail, date month year
,GitHub issue
, orMinutes, date month year
Event | Date | Links |
---|---|---|
Stage 3 proposal submitted to reviewers | Nov 7 2022 | https://lists.oasis-open.org/archives/dita/202211/msg00013.html |
Stage 3 proposal submitted to TC | Dec 6 2022 | |
Stage 3 proposal discussed | <Date> | <xref to meeting minutes where discussed> |
Stage 3 proposal approved | <Date> | <xref to meeting minutes where discussed> |
Approved technical requirements
- Define a new
@impose-role
attribute that is available on<topicref>
and its specializations. - Processing expectations that are associated with the new attribute:
- When set to "impose", it declares the processing that is already described in 2.2.4.6.3 Cascading of roles from map to map.
- When set to "keeptarget", processors do not change the role of
the referenced map or
<topicref>
.
- The attribute will typically have a default value set by the specialization.
Dependencies or interrelated proposals
N/A
Modified grammar files
This proposal will add the @impose-role
attribute to
<topicref>
and every specialization of
@topicref
.
- Adds attribute to
map
module as an entity for easy reuse, with default set to "keeptarget" - Fix the attribute as "keeptarget" for elements where
"impose" makes no sense:
<ditavalref>
,<topicsubject>
,<topicapply>
,<subjectref>
,<keydef>
,<mapref>
- As above, adds attribute to
map
module as a definition for easy reuse, with default set to "keeptarget" - Fix the attribute as "keeptarget" for elements where
"impose" makes no sense:
<ditavalref>
,<topicsubject>
,<topicapply>
,<subjectref>
,<keydef>
,<mapref>
Modified terminology
n/a
Modified specification documentation
- The "attribute list" topic in the language reference will have a new entry for the
@impose-role
attribute. It will be grouped with "other" attributes (it is not a "common topicref attribute" as those generally inherit and are also used on containers like<map>
and<reltable>
. See commit, definition list entry copied here:@impose-role
- Specifies whether this element will impose its role on elements in a referenced
map. The attribute is ignored if the target of the reference is not a map or
branch of a map. The following values are valid:
- keeptarget
- The role of the current reference is not imposed on the target of the
reference. This is the default for the unspecialized
<topicref>
element and for many convenience elements such as<keydef>
. - impose
- The role of the current reference is imposed on the target of the
reference. For example, if a specialized topic
reference
<chapter>
uses this value and references a map, a topic reference that resolves in place of the<chapter>
will be treated as if it were a chapter. - -dita-use-conref-target
- See Using the -dita-use-conref-target value for more information.
- Add the attribute into the attribute section for topicref and each specialization. For most of these, add to the "attribute exception" section to list the fixed value of "keeptarget": https://github.com/oasis-tcs/dita/commit/6330f5c26913e933e1971ab24cb3b16adf640bd5
Migration plans for backwards incompatibilities
n/a
New architectural topic (not specifically for a new element)
Ideally the <example>
sections in the main architectural topic
here would be moved to example topics; however that's a little difficult to integrate
before we rework the "dita maps and their usage" section so they are currently part of the
overview topic.
Imposing roles when referencing a map
When specialized <topicref>
elements reference a map, they
might imply a semantic role for the referenced content. The @impose-role
attribute provides a mechanism to declare that such references impose their original role
on referenced content.
In many cases the <topicref>
element is specialized in order to
create a specific role for the reference. For example, the
<keydef>
element creates a new role for the reference, but
does not create a role for the target of the reference. In other cases, the
element is specialized to create a role for the target of the reference. For example, in the Bookmap specialization from the DITA
Technical Communication specializations, the <chapter>
element
creates a role for the target of the reference: it declares that the referenced
content is a chapter in the context of this map.
The declaration of roles can be harder to follow when the target of a reference is a
map or branch of a map. In such cases, a <topicref>
element can
reference a map, which in turn references content. When resolving those references,
processors need to know which roles created by the <topicref>
elements need to be preserved for the content.
For example, assume a <setupProject>
element that is specialized
from <topicref>
indicates that the referenced content plays the
"setup a project" role in a publication. This might result in special formatting or
generated headings when the content is rendered. If that element refers to a map instead
of a topic, that specialized role still needs to be passed on to topics in the
referenced map - regardless of what <topicref>
elements might be
used in that referenced map.
The @impose-role
attribute provides a way for specialized elements to
declare whether processors should use this behavior. This attribute is only evaluated
when a <topicref>
element refers to a map or branch of a map. In
that case, it indicates whether the element provides a role for content that should be
passed on to content in the referenced map.
The role created by a <topicref>
is reflected by the
@class
hierarchy of the element. Processors that need to do something
with the role do it based on that @class
attribute. In the
<setupProject>
example above, that might be a
@class
attribute like "- map/topicref taskmap/setupProject
"
. Processors working with the reference know to render the referenced
content based on that value. When <setupProject>
instead pulls in
content from another map, processors need to preserve that intent. Effectively, they
need to preserve awareness of that @class
attribute value for topics
that are indirectly referenced through the other map.
Specialized topic references achieve this behavior by setting up a default value for
the @impose-role
attribute on the new element:
impose-role="impose"
.
When a role is imposed in this manner, it does not apply to all content referenced by
the element. If a <topicref>
refers to a branch of a map, the
role is imposed only on the root element of that branch. If a
<topicref>
refers to an entire map, the role is imposed only on
the highest-level topic references within that map. The role does not cascade to other
nested referencs within the map. For example, if a <chapter>
element applied that role to every reference in another map, that map would be made up
only of chapters nested within chapters.
For elements that do not create a role for the referenced content, the
@impose-role
attribute is defined with a default value indicating that
the target of the reference keeps its original role:
impose-role="keeptarget"
. For example, the
<mapref>
element is a convenience element used to simplify
references to other maps. It does not force the content in other maps to be treated as
<mapref>
- no special role is created for the referenced
content. For this reason, it is defined in the grammar file with a fixed value of
"keeptarget".
In some cases, preserving the role of a referencing element might result in
out-of-context content. For example, a <chapter>
element in one
bookmap could pull in a <part>
element from another bookmap,
where that referenced <part>
also contains nested
<chapter>
elements. Treating the <part>
element as a <chapter>
will result in a chapter that nests other
chapters, which is not valid in bookmap and might not be understandable by processors.
The result is implementation specific. Processors MAY choose to treat this as an error, issue a warning, or simply assign new
roles to the problematic elements.
Defining a fixed role for a specialized element
In the Bookmap specialization from the OASIS DITA Technical Communications
specializations, the <chapter>
element creates a role for the
referenced topic. In many contexts (such as a PDF version of the map), this will
result in special formatting that identifies the topic as the start of a chapter.
When a chapter element refers to another map, topic references in that other map need
to be treated as chapters in order to retain the structure of the book. The
@impose-role
attribute is set to a fixed value of
"impose", which lets processors know that the role needs to be
preserved for content in the other map.
<optional>
<attribute name="impose-role" a:defaultValue="keeptarget">
<value>keeptarget</value>
</attribute>
</optional>
impose-role
(impose)
'impose'
With these fixed values, a <chapter>
element that refers to a
map will impose the role of "chapter" as expected.
Imposing a role on a branch of a map
<chapter>
element refers to a
branch of another map. The chapter element does not need to set the
@impose-role
attribute directly, because it is defined with a
default value in the XML grammar files. The element itself refers to a specific branch
of the map, setting the @format
attribute to indicate this is a map
reference:<bookmap>
<!-- ... title, front matter, and other chapters -->
<chapter href="" format="ditamap"/>
<!-- additional content -->
</bookmap>
<map>
<title>Reusable map branches</title>
<topicref> <!-- ... --> </topicref>
<topicref href="" id="examplebranch">
<topicref href=""/>
<topicref href="">
<!-- more children -->
</topicref>
</topicref>
<!-- ... more reusable branches -->
</map>
<chapter>
element is defined with a fixed value of
"impose" for the @impose-role
attribute, processors
will impose the "chapter" role on the reference to parent.dita at
the root of the referenced branch. The "chapter" role is not imposed on the child
topics in that branch. While processors do not need to literally resolve the content
in a normal map, the effective result is similar to this merged
map:<bookmap>
<!-- ... title, front matter, and other chapters -->
<chapter href="">
<topicref href=""/>
<topicref href="">
<!-- more children -->
</topicref>
</chapter>
<!-- additional content -->
</bookmap>
Imposing a role on a referenced map
<chapter>
element refers to an
entire submap. The chapter element does not need to set the
@impose-role
attribute directly, because it is defined with a
default value in the XML grammar files. The element itself sets the
@format
attribute to indicate this is a map
reference:<bookmap>
<!-- ... title, front matter, and other chapters -->
<chapter href="" format="ditamap"/>
<!-- additional content -->
</bookmap>
<map>
element:<map>
<title>Reusable map branches</title>
<topicref href=""> <!-- ... --> </topicref>
<topicref href="">
<topicref href=""/>
<topicref href="">
<!-- more children -->
</topicref>
</topicref>
<topicref href=""> <!-- ... --> </topicref>
</map>
<chapter>
element is defined with a fixed value of
"impose" for the @impose-role
attribute, processors
will impose the "chapter" role on the highest-level references within the nested map.
This means the processors imposes the role of "chapter" on all three branches in the
nested map. As with the previous example, the "chapter" role is not imposed on the
child topics in each branch. While processors do not need to literally resolve the
content in a normal map, the effective result is similar to this merged
map:<bookmap>
<!-- ... title, front matter, and other chapters -->
<chapter href=""> <!-- ... --> </chapter>
<chapter href="">
<topicref href=""/>
<topicref href="">
<!-- more children -->
</topicref>
</chapter>
<chapter href=""> <!-- ... --> </chapter>
<!-- additional content -->
</bookmap>
Example: How <topicref>
roles are imposed on referenced maps
In this scenario, a specialized <topicref>
element
references content in another map.
<chapter>
element from the Bookmap
specialization that references a DITA map. This scenario could take several forms:- Referenced map contains a single top-level
<topicref>
element - The entire branch functions as if it were included in the bookmap. The "chapter" role is imposed on the branch, with the
result that the top-level
<topicref>
element is processed as if it were the<chapter>
element. - Referenced map contains multiple top-level
<topicref>
elements - The "chapter" role is imposed on each top-level element in the referenced map.
Each top-level
<topicref>
element is processed as if it were a<chapter>
element. - Referenced map contains a single
<appendix>
element - The "chapter" role is imposed on the
<appendix>
element, which is processed as it were a<chapter>
element. - Referenced map contains a single
<part>
element, with nested<chapter>
elements - The "chapter" role is imposed on the
<part>
element, which is processed as it were a<chapter>
element. Nested<chapter>
elements might not be understandable by processors, which can treat this as an error or recover as they are able. <chapter>
element references a single<topicref>
element rather than a map- The "chapter" role is imposed on the referenced
<topicref>
element, which is processed as if it were a<chapter>
element.