Stage 3 proposal: Feature #106 Nest Steps

Allow the <steps> element to nest, in order to address one of our more common authoring pain points, simplify reuse, and reduce overall element count.

Champion

Robert D. Anderson

Tracking information

Event Date Links
Stage 1 proposal accepted 13 March 2018 https://lists.oasis-open.org/archives/dita/201803/msg00052.html
Stage 2 proposal submitted 19 March 2018 HTML, DITA
Stage 2 proposal discussed 20 March 2018 Meeting minutes
Stage 2 proposal approved 27 March 2018 Meeting minutes
Stage 3 proposal submitted to reviewers 17 April 2018 Nancy Harrison, Bob Thomas, Carsten Brennecke
Stage 3 proposal (this document) submitted to TC 4 September 2018 DITA version in SVN

Approved technical requirements

  1. Delete the <substeps> and <substep> elements.
  2. Add <steps> and <steps-unordered> to the content model of <step>, after the command (where <substeps> is currently allowed)

Dependencies or interrelated proposals

N/A

Modified grammar files

task.mod (before) task.mod (after)
<!ENTITY % substeps    "substeps"                                    >
<!ENTITY % substep     "substep"                                     >
<!ENTITY % substeps    "substeps"                                    >
<!ENTITY % substep     "substep"                                     >
<!ENTITY % step.content
                       "((%note;)*,
                         (%cmd;),
                         (%choices; |
                          %choicetable; |
                          %info; |
                          %itemgroup; |
                          %stepxmp; |
                          %substeps; |
                          %tutorialinfo;)*,
                         (%stepresult;)?,
                         (%steptroubleshooting;)?)"
>
<!ENTITY % step.content
                       "((%note;)*,
                         (%cmd;),
                         (%choices; |
                          %choicetable; |
                          %info; |
                          %itemgroup; |
                          %stepxmp; |
                          %substeps; |
                          %steps; |
                          %steps-unordered; |
                          %tutorialinfo;)*,
                         (%stepresult;)?,
                         (%steptroubleshooting;)?)"
>
<!--                    LONG NAME: Sub-steps                       -->
<!ENTITY % substeps.content
                       "((%data; |
                          %data-about;)*,
                         (%substep;)+)"
>
<!ENTITY % substeps.attributes
              "%univ-atts;
               outputclass
                          CDATA
                                    #IMPLIED"
>
<!ELEMENT  substeps %substeps.content;>
<!ATTLIST  substeps %substeps.attributes;>


<!--                    LONG NAME: Sub-step                        -->
<!ENTITY % substep.content
                       "((%note;)*,
                         (%cmd;),
                         (%info; |
                          %itemgroup; |
                          %stepxmp; |
                          %tutorialinfo;)*,
                         (%stepresult;)?)"
>
<!ENTITY % substep.attributes
              "importance
                          (optional |
                           required |
                           -dita-use-conref-target)
                                    #IMPLIED
               %univ-atts-no-importance-task;
               outputclass
                          CDATA
                                    #IMPLIED"
>
<!ELEMENT  substep %substep.content;>
<!ATTLIST  substep %substep.attributes;>
<!--                    LONG NAME: Sub-steps                       -->
<!ENTITY % substeps.content
                       "((%data; |
                          %data-about;)*,
                         (%substep;)+)"
>
<!ENTITY % substeps.attributes
              "%univ-atts;
               outputclass
                          CDATA
                                    #IMPLIED"
>
<!ELEMENT  substeps %substeps.content;>
<!ATTLIST  substeps %substeps.attributes;>


<!--                    LONG NAME: Sub-step                        -->
<!ENTITY % substep.content
                       "((%note;)*,
                         (%cmd;),
                         (%info; |
                          %itemgroup; |
                          %stepxmp; |
                          %tutorialinfo;)*,
                         (%stepresult;)?)"
>
<!ENTITY % substep.attributes
              "importance
                          (optional |
                           required |
                           -dita-use-conref-target)
                                    #IMPLIED
               %univ-atts-no-importance-task;
               outputclass
                          CDATA
                                    #IMPLIED"
>
<!ELEMENT  substep %substep.content;>
<!ATTLIST  substep %substep.attributes;>
<!ATTLIST  substeps     %global-atts;  class CDATA "- topic/ol task/substeps ">
<!ATTLIST  substep      %global-atts;  class CDATA "- topic/li task/substep ">
<!ATTLIST  substeps     %global-atts;  class CDATA "- topic/ol task/substeps ">
<!ATTLIST  substep      %global-atts;  class CDATA "- topic/li task/substep ">
taskMod.rng (before) taskMod.rng (after)
<define name="substeps">
      <ref name="substeps.element"/>
    </define>
    <define name="substep">
      <ref name="substep.element"/>
    </define>
<define name="substeps">
      <ref name="substeps.element"/>
    </define>
    <define name="substep">
      <ref name="substep.element"/>
    </define>
<define name="step.content">
        <zeroOrMore>
          <ref name="note"/>
        </zeroOrMore>
        <ref name="cmd"/>
        <zeroOrMore>
          <choice>
            <ref name="choices"/>
            <ref name="choicetable"/>
            <ref name="info"/>
            <ref name="itemgroup"/>
            <ref name="stepxmp"/>
            <ref name="substeps"/>
            <ref name="tutorialinfo"/>
          </choice>
        </zeroOrMore>
<define name="step.content">
        <zeroOrMore>
          <ref name="note"/>
        </zeroOrMore>
        <ref name="cmd"/>
        <zeroOrMore>
          <choice>
            <ref name="choices"/>
            <ref name="choicetable"/>
            <ref name="info"/>
            <ref name="itemgroup"/>
            <ref name="stepxmp"/>
            <ref name="substeps"/>
            <ref name="steps"/>
            <ref name="steps-unordered"/>
            <ref name="tutorialinfo"/>
          </choice>
        </zeroOrMore>
    <div>
      <a:documentation> LONG NAME: Sub-steps </a:documentation>
      <define name="substeps.content">
        <zeroOrMore dita:since="1.3">
          <choice>
            <ref name="data"/>
            <ref name="data-about"/>
          </choice>
        </zeroOrMore>
        <oneOrMore>
          <ref name="substep"/>
        </oneOrMore>
      </define>
      <define name="substeps.attributes">
        <ref name="univ-atts"/>
        <optional>
          <attribute name="outputclass"/>
        </optional>
      </define>
      <define name="substeps.element">
        <element name="substeps" dita:longName="Sub-steps">
          <a:documentation>
            <![CDATA[The <substeps> element allows you to break a step down
into a series of separate actions, and should be used only if necessary.
Try to describe the steps of a task in a single level of steps.
If you need to use more than one level of substep nesting, you should
probably rewrite the task to simplify it.
    Category: Task elements
  ]]></a:documentation>
          <ref name="substeps.attlist"/>
          <ref name="substeps.content"/>
        </element>
      </define>
      <define name="substeps.attlist" combine="interleave">
        <ref name="substeps.attributes"/>
      </define>
    </div>
    <div>
      <a:documentation> LONG NAME: Sub-step </a:documentation>
      <define name="substep.content">
        <zeroOrMore>
          <ref name="note"/>
        </zeroOrMore>
        <ref name="cmd"/>
        <zeroOrMore>
          <choice>
            <ref name="info"/>
            <ref name="itemgroup"/>
            <ref name="stepxmp"/>
            <ref name="tutorialinfo"/>
          </choice>
        </zeroOrMore>
        <optional>
          <ref name="stepresult"/>
        </optional>
      </define>
      <define name="substep.attributes">
        <optional>
          <attribute name="importance">
            <choice>
              <value>optional</value>
              <value>required</value>
              <value>-dita-use-conref-target</value>
            </choice>
          </attribute>
        </optional>
        <ref name="univ-atts-no-importance-task"/>
        <optional>
          <attribute name="outputclass"/>
        </optional>
      </define>
      <define name="substep.element">
        <element name="substep" dita:longName="Sub-step">
          <a:documentation>
            <![CDATA[A <substep> element has the same structure as a <step>, 
except that it does not allow lists of choices or substeps within it, 
in order to prevent unlimited nesting of steps.
    Category: Task elements
  ]]></a:documentation>
          <ref name="substep.attlist"/>
          <ref name="substep.content"/>
        </element>
      </define>
      <define name="substep.attlist" combine="interleave">
        <ref name="substep.attributes"/>
      </define>
    </div>
    <div>
      <a:documentation> LONG NAME: Sub-steps </a:documentation>
      <define name="substeps.content">
        <zeroOrMore dita:since="1.3">
          <choice>
            <ref name="data"/>
            <ref name="data-about"/>
          </choice>
        </zeroOrMore>
        <oneOrMore>
          <ref name="substep"/>
        </oneOrMore>
      </define>
      <define name="substeps.attributes">
        <ref name="univ-atts"/>
        <optional>
          <attribute name="outputclass"/>
        </optional>
      </define>
      <define name="substeps.element">
        <element name="substeps" dita:longName="Sub-steps">
          <a:documentation>
            <![CDATA[The <substeps> element allows you to break a step down
into a series of separate actions, and should be used only if necessary.
Try to describe the steps of a task in a single level of steps.
If you need to use more than one level of substep nesting, you should
probably rewrite the task to simplify it.
    Category: Task elements
  ]]></a:documentation>
          <ref name="substeps.attlist"/>
          <ref name="substeps.content"/>
        </element>
      </define>
      <define name="substeps.attlist" combine="interleave">
        <ref name="substeps.attributes"/>
      </define>
    </div>
    <div>
      <a:documentation> LONG NAME: Sub-step </a:documentation>
      <define name="substep.content">
        <zeroOrMore>
          <ref name="note"/>
        </zeroOrMore>
        <ref name="cmd"/>
        <zeroOrMore>
          <choice>
            <ref name="info"/>
            <ref name="itemgroup"/>
            <ref name="stepxmp"/>
            <ref name="tutorialinfo"/>
          </choice>
        </zeroOrMore>
        <optional>
          <ref name="stepresult"/>
        </optional>
      </define>
      <define name="substep.attributes">
        <optional>
          <attribute name="importance">
            <choice>
              <value>optional</value>
              <value>required</value>
              <value>-dita-use-conref-target</value>
            </choice>
          </attribute>
        </optional>
        <ref name="univ-atts-no-importance-task"/>
        <optional>
          <attribute name="outputclass"/>
        </optional>
      </define>
      <define name="substep.element">
        <element name="substep" dita:longName="Sub-step">
          <a:documentation>
            <![CDATA[A <substep> element has the same structure as a <step>,
except that it does not allow lists of choices or substeps within it,
in order to prevent unlimited nesting of steps.
    Category: Task elements
  ]]></a:documentation>
          <ref name="substep.attlist"/>
          <ref name="substep.content"/>
        </element>
      </define>
      <define name="substep.attlist" combine="interleave">
        <ref name="substep.attributes"/>
      </define>
    </div>
<define name="substeps.attlist" combine="interleave">
      <ref name="global-atts"/>
      <optional>
        <attribute name="class" a:defaultValue="- topic/ol task/substeps "/>
      </optional>
    </define>
    <define name="substep.attlist" combine="interleave">
      <ref name="global-atts"/>
      <optional>
        <attribute name="class" a:defaultValue="- topic/li task/substep "/>
      </optional>
    </define>
<define name="substeps.attlist" combine="interleave">
      <ref name="global-atts"/>
      <optional>
        <attribute name="class" a:defaultValue="- topic/ol task/substeps "/>
      </optional>
    </define>
    <define name="substep.attlist" combine="interleave">
      <ref name="global-atts"/>
      <optional>
        <attribute name="class" a:defaultValue="- topic/li task/substep "/>
      </optional>
    </define>

Modified terminology

N/A

Modified specification documentation

Content models will not be published in the same document as the specification with DITA 2.0, so there are no changes required based on the DITA 1.3 content model appendices.

Existing element reference topics for <substeps> and <substep> will be deleted.

The task table in topic B.6 Element-by-element recommendations for translators: Technical content edition needs to delete the rows for <substep> and <substeps>.

In addition, the following changes are required:

<step> element reference topic (before) <step> element reference topic (after)

Definition of @importance:

importance
Describes whether the current <step> or <substep> is optional or required. Output processors might highlight steps that are optional or required. Allowed values are "optional", "required", or -dita-use-conref-target.

Definition of @importance:

importance
Describes whether the current <step> or <substep> is optional or required. Output processors might highlight steps that are optional or required. Allowed values are "optional", "required", or -dita-use-conref-target.
Task topic (strict task) (before) Task topic (strict task) (after)

From topic 2.7.1.4 in DITA 1.3, the description of <steps>:

The <step> element represents an action that a user must follow to accomplish a task. Each <step> in a <task> must contain a command <cmd> element which describes the particular action the user must perform to accomplish the overall task. The <step> element can also contain information <info>, substeps <substeps>, tutorial information <tutorialinfo>, a step example <stepxmp>, choices <choices>, a step result <stepresult> , or troubleshooting <steptroubleshooting> , although these are optional.
The <step> element represents an action that a user must follow to accomplish a task. Each <step> in a <task> must contain a command <cmd> element which describes the particular action the user must perform to accomplish the overall task. The <step> element can also contain information <info>, substeps <substeps>, tutorial information <tutorialinfo>, a step example <stepxmp>, choices <choices>, a step result <stepresult> , or troubleshooting <steptroubleshooting> , although these are optional.

From topic 2.7.1.4 Task topic (strict task) in DITA 1.3, the description of <steps>:

Before After
The <step> element represents an action that a user must follow to accomplish a task. Each <step> in a <task> must contain a command <cmd> element which describes the particular action the user must perform to accomplish the overall task. The <step> element can also contain information <info>, substeps <substeps>, tutorial information <tutorialinfo>, a step example <stepxmp>, choices <choices>, a step result <stepresult> , or troubleshooting <steptroubleshooting> , although these are optional.
The <step> element represents an action that a user must follow to accomplish a task. Each <step> in a <task> must contain a command <cmd> element which describes the particular action the user must perform to accomplish the overall task. The <step> element can also contain information <info>, substeps <substeps>, tutorial information <tutorialinfo>, a step example <stepxmp>, choices <choices>, a step result <stepresult> , or troubleshooting <steptroubleshooting> , although these are optional.

The following changes are required in TroubleshootingElements.dita

Troubleshooting information concept topic (before) Troubleshooting information concept topic (after)

The <steptroubleshooting> element can occur following the <cmd> element in the <step> or <substep> element. The <steptroubleshooting>element ends the <step> or <substep> element. Another element, such as <info> or <stepxmp>, cannot be added after the <steptroubleshooting> element.

The <steptroubleshooting> element can occur following the <cmd> element in the <step> or <substep> element. The <steptroubleshooting>element ends the <step> or <substep> element. Another element, such as <info> or <stepxmp>, cannot be added after the <steptroubleshooting> element.

The following changes are required to the examples in the element reference topics for <choicetable>, <chrow>, <chdesc>, and <chhead>:

Example (before) Example (after)
<step><cmd>Then this</cmd>
        <substeps>
        <substep importance="optional"><cmd>which is done by doing this</cmd></substep>
        <substep importance="required"><cmd>and then this.</cmd></substep>
        </substeps>
        [choicetable elided]
      
<step><cmd>Then this</cmd>
        <steps>
        <step importance="optional"><cmd>which is done by doing this</cmd></step>
        <step importance="required"><cmd>and then this.</cmd></step>
        </steps>
        [choicetable elided]
      

Migration plans for backwards incompatibilities

  1. Because any element allowed in <substep> is already allowed in <step>, content migration is most easily handled with a search/replace tool to change element names.
    • Replace <substep with <step (this will change the start tag for <substeps> to <steps> and also change <substep> to <step>, regardless of what attributes are specified).
    • Replace </substep with </step (this will change the end tag for </substeps> to </steps> and also change </substep> to </step>)
  2. Because constraint or specialization modules may use these elements in ways that do not follow normal patterns, it is not possible to handle all possible extensions with a tool or common search/replace _expression_. The following incompatibilities are possible, though likely to be less common:
    • Specializations of <substeps> and <substep> will need to change ancestry in their @class attributes (replacing the token task/substeps with task/steps and task/substep with task/step)
    • Constraints or specialized elements that explicitly include either <substeps> or <substep> will need to be updated to use <steps> or <step>
  3. Rendering tools that automatically add headings to either <steps> or <steps-unordered> may need a conditional test to only render the heading when those elements appear as a child of <taskbody>. Rendering processes can be written in any number of tools or languages, so it is not possible to automate this migration; for tools that need this update, it should require a test such as "If @class of parent element contains task/taskbody " before generating any heading.