draft-ietf-netmod-artwork-folding-01.txt | draft-ietf-netmod-artwork-folding-02.txt | |||
---|---|---|---|---|
NETMOD Working Group K. Watsen | NETMOD Working Group K. Watsen | |||
Internet-Draft Watsen Networks | Internet-Draft Watsen Networks | |||
Intended status: Best Current Practice Q. Wu | Intended status: Best Current Practice A. Farrel | |||
Expires: September 11, 2019 Huawei Technologies | Expires: October 8, 2019 Old Dog Consulting | |||
A. Farrel | Q. Wu | |||
Old Dog Consulting | Huawei Technologies | |||
B. Claise | April 6, 2019 | |||
Cisco Systems, Inc. | ||||
March 10, 2019 | ||||
Handling Long Lines in Inclusions in Internet-Drafts and RFCs | Handling Long Lines in Inclusions in Internet-Drafts and RFCs | |||
draft-ietf-netmod-artwork-folding-01 | draft-ietf-netmod-artwork-folding-02 | |||
Abstract | Abstract | |||
This document introduces a simple and yet time-proven strategy for | This document defines a simple and yet time-proven strategy for | |||
handling long lines in inclusions in drafts using a backslash ('\') | handling long lines in inclusions in internet drafts and RFCs using a | |||
character where line-folding has occurred. The strategy works on any | backslash ('\') character to indicate where line-folding has | |||
text-based content, but is primarily intended for a structured | occurred. The strategy works on any text-based content, but is | |||
sequence of lines, such as would be referenced by the <sourcecode> | primarily intended for a structured sequence of lines rather than for | |||
element defined in Section 2.48 of RFC 7991, rather than for two- | two-dimensional imagery. The approach produces consistent results, | |||
dimensional imagery, such as would be referenced by the <artwork> | regardless of the content, that is both self-documenting and enables | |||
element defined in Section 2.5 of RFC 7991. The approach produces | automated reconstitution of the original content. | |||
consistent results, regardless of the content, that is both self- | ||||
documenting and enables automated reconstitution of the original | ||||
content. | ||||
Status of This Memo | Status of This Memo | |||
This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on September 11, 2019. | This Internet-Draft will expire on October 8, 2019. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2019 IETF Trust and the persons identified as the | Copyright (c) 2019 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
(https://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
publication of this document. Please review these documents | publication of this document. Please review these documents | |||
skipping to change at page 2, line 28 ¶ | skipping to change at page 2, line 19 ¶ | |||
described in the Simplified BSD License. | described in the Simplified BSD License. | |||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
2. Applicability Statement . . . . . . . . . . . . . . . . . . . 3 | 2. Applicability Statement . . . . . . . . . . . . . . . . . . . 3 | |||
3. Requirements Language . . . . . . . . . . . . . . . . . . . . 4 | 3. Requirements Language . . . . . . . . . . . . . . . . . . . . 4 | |||
4. Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 | 4. Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
4.1. Automated Folding of Long Lines in Text Content . . . . . 4 | 4.1. Automated Folding of Long Lines in Text Content . . . . . 4 | |||
4.2. Automated Reconstitution of the Original Text Content . . 4 | 4.2. Automated Reconstitution of the Original Text Content . . 4 | |||
5. Limitations . . . . . . . . . . . . . . . . . . . . . . . . . 4 | 5. Limitations . . . . . . . . . . . . . . . . . . . . . . . . . 5 | |||
5.1. Not Recommended for Graphical Artwork . . . . . . . . . . 5 | 5.1. Not Recommended for Graphical Artwork . . . . . . . . . . 5 | |||
5.2. Doesn't Work as Well as Format-Specific Options . . . . . 5 | 5.2. Doesn't Work as Well as Format-Specific Options . . . . . 5 | |||
6. Folded Structure . . . . . . . . . . . . . . . . . . . . . . 5 | 6. Two Folding Strategies . . . . . . . . . . . . . . . . . . . 5 | |||
6.1. Header . . . . . . . . . . . . . . . . . . . . . . . . . 6 | 6.1. Comparison . . . . . . . . . . . . . . . . . . . . . . . 6 | |||
6.2. Body . . . . . . . . . . . . . . . . . . . . . . . . . . 6 | 6.2. Recommendation . . . . . . . . . . . . . . . . . . . . . 6 | |||
7. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . 6 | 7. The Single Backslash Strategy ('\') . . . . . . . . . . . . . 6 | |||
7.1. Automated Folding . . . . . . . . . . . . . . . . . . . . 6 | 7.1. Folded Structure . . . . . . . . . . . . . . . . . . . . 6 | |||
7.1.1. Manual Folding . . . . . . . . . . . . . . . . . . . 7 | 7.1.1. Header . . . . . . . . . . . . . . . . . . . . . . . 6 | |||
7.2. Automated Unfolding . . . . . . . . . . . . . . . . . . . 8 | 7.1.2. Body . . . . . . . . . . . . . . . . . . . . . . . . 7 | |||
8. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 8 | 7.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 7 | |||
8.1. Simple Example Showing Boundary Conditions . . . . . . . 9 | 7.2.1. Folding . . . . . . . . . . . . . . . . . . . . . . . 7 | |||
8.2. Example Showing Multiple Wraps of a Single Line . . . . . 9 | 7.2.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . 8 | |||
8.3. Example With Native Backslash . . . . . . . . . . . . . . 10 | 8. The Double Backslash Strategy ('\\') . . . . . . . . . . . . 9 | |||
8.4. Example With Native Whitespace . . . . . . . . . . . . . 10 | 8.1. Folded Structure . . . . . . . . . . . . . . . . . . . . 9 | |||
8.5. Example of Manual Wrapping . . . . . . . . . . . . . . . 10 | 8.1.1. Header . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
9. Security Considerations . . . . . . . . . . . . . . . . . . . 13 | 8.1.2. Body . . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 13 | 8.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
11. References . . . . . . . . . . . . . . . . . . . . . . . . . 13 | 8.2.1. Folding . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
11.1. Normative References . . . . . . . . . . . . . . . . . . 13 | 8.2.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . 11 | |||
11.2. Informative References . . . . . . . . . . . . . . . . . 13 | 9. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
Appendix A. POSIX Shell Script . . . . . . . . . . . . . . . . . 15 | 9.1. Example Showing Boundary Conditions . . . . . . . . . . . 12 | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 19 | 9.1.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 12 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20 | 9.1.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 12 | |||
9.2. Example Showing Multiple Wraps of a Single Line . . . . . 13 | ||||
9.2.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 13 | ||||
9.2.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 13 | ||||
9.3. Example Showing Smart Folding . . . . . . . . . . . . . . 13 | ||||
9.3.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 13 | ||||
9.3.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 14 | ||||
10. Security Considerations . . . . . . . . . . . . . . . . . . . 15 | ||||
11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16 | ||||
12. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 | ||||
12.1. Normative References . . . . . . . . . . . . . . . . . . 16 | ||||
12.2. Informative References . . . . . . . . . . . . . . . . . 16 | ||||
Appendix A. POSIX Shell Script . . . . . . . . . . . . . . . . . 17 | ||||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 23 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 23 | ||||
1. Introduction | 1. Introduction | |||
[RFC7994] sets out the requirements for plain-text RFCs and states | [RFC7994] sets out the requirements for plain-text RFCs and states | |||
that each line of an RFC (and hence of an Internet-Draft) must be | that each line of an RFC (and hence of an Internet-Draft) must be | |||
limited to 72 characters followed by the character sequence that | limited to 72 characters followed by the character sequence that | |||
denotes an end-of-line (EOL). | denotes an end-of-line (EOL). | |||
Internet-Drafts and RFCs often include example text or code | Internet-Drafts and RFCs often include example text or code | |||
fragments. In order to render the formatting of such text it is | fragments. Many times the example text or code exceeds the 72 | |||
usually presented as a figure using the "<sourcecode>" element in the | character line-length limit. The `xml2rfc` utility does not attempt | |||
source XML. Many times the example text or code exceeds the 72 | to wrap the content of such inclusions, simply issuing a warning | |||
character line-length limit and the `xml2rfc` utility does not | whenever lines exceed 69 characters. According to the RFC Editor, | |||
attempt to wrap the content of such inclusions, simply issuing a | there is currently no convention in place for how to handle long | |||
warning whenever lines exceed 69 characters. According to the RFC | lines in such inclusions, other than advising authors to clearly | |||
Editor, there is currently no convention in place for how to handle | indicate what manipulation has occurred. | |||
long lines, other than advising authors to clearly indicate what | ||||
manipulation has occurred. | ||||
This document introduces a simple and yet time-proven strategy for | This document introduces a simple and yet time-proven strategy for | |||
handling long lines in inclusions in drafts using a backslash ('\') | handling long lines using a backslash ('\') character to indicate | |||
character where line-folding has occurred. The strategy works on any | where line-folding has occurred. The strategy works on any text | |||
text based inclusion, but is primarily intended for a structured | based inclusion, but is primarily intended for a structured sequence | |||
sequence of lines, such as would be referenced by the <sourcecode> | of lines, such as would be referenced by the <sourcecode> element | |||
element defined in Section 2.48 of [RFC7991], rather than for two- | defined in Section 2.48 of [RFC7991], rather than for two-dimensional | |||
dimensional imagery, such as would be referenced by the <artwork> | imagery, such as would be referenced by the <artwork> element defined | |||
element defined in Section 2.5 of [RFC7991]. The approach produces | in Section 2.5 of [RFC7991]. The approach produces consistent | |||
consistent results, regardless of the content, that is both self- | results, regardless of the content, that is both self-documenting and | |||
documenting and enables automated reconstitution of the original | enables automated reconstitution of the original content. | |||
content. | ||||
Note that text files are represent as lines having their first | Note that text files are represented as lines having their first | |||
character in column 1, and a line length of N where the last | character in column 1, and a line length of N where the last | |||
character is in the Nth column and is immediately followed by an end | character is in the Nth column and is immediately followed by an end | |||
of line character sequence. | of line character sequence. | |||
2. Applicability Statement | 2. Applicability Statement | |||
The format and algorithm defined in this document may be used in any | The format and algorithm defined in this document may be used in any | |||
context, whether for IETF documents or in other situations where | context, whether for IETF documents or in other situations where | |||
structured folding is desired. | structured folding is desired. | |||
Within the IETF, this work is primarily targeted to xml2rfc v3 | Within the IETF, this work primarily targets the xml2rfc v3 | |||
<sourcecode> element (Section 2.48 of [RFC7991]) and xml2rfc v2 | <sourcecode> element (Section 2.48 of [RFC7991]) and the xml2rfc v2 | |||
<artwork> element (Section 2.5 of [RFC7749]) that, for lack of a | <artwork> element (Section 2.5 of [RFC7749]) that, for lack of a | |||
better option, is currently used for both source code and artwork. | better option, is currently used for both source code and artwork. | |||
This work may be also be used for the xml2rfc v3 <artwork> element | This work may be also be used for the xml2rfc v3 <artwork> element | |||
(Section 2.5 of [RFC7991]) but, as described in Section 5.1, it is | (Section 2.5 of [RFC7991]) but, as described in Section 5.1, it is | |||
generally not recommended. | generally not recommended. | |||
3. Requirements Language | 3. Requirements Language | |||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
"OPTIONAL" in this document are to be interpreted as described in BCP | "OPTIONAL" in this document are to be interpreted as described in BCP | |||
14 [RFC2119] [RFC8174] when, and only when, they appear in all | 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
skipping to change at page 4, line 24 ¶ | skipping to change at page 4, line 28 ¶ | |||
4.1. Automated Folding of Long Lines in Text Content | 4.1. Automated Folding of Long Lines in Text Content | |||
Automated folding of long lines is needed in order to support draft | Automated folding of long lines is needed in order to support draft | |||
compilations that entail a) validation of source input files (e.g., | compilations that entail a) validation of source input files (e.g., | |||
XML, JSON, ABNF, ASN.1) and/or b) dynamic generation of output, using | XML, JSON, ABNF, ASN.1) and/or b) dynamic generation of output, using | |||
a tool that doesn't observe line lengths, that is stitched into the | a tool that doesn't observe line lengths, that is stitched into the | |||
final document to be submitted. | final document to be submitted. | |||
Generally, in order for tooling to be able to process input files, | Generally, in order for tooling to be able to process input files, | |||
the files must be in their original/natural state, which may include | the files must be in their original/natural state, which may entail | |||
having some long lines. Thus, these source files need to be modified | them having some long lines. Thus, these source files need to be | |||
before inclusion in the document in order to satisfy the line length | modified before inclusion in the document in order to satisfy the | |||
limits. This modification SHOULD be automated to reduce effort and | line length limits. This modification SHOULD be automated to reduce | |||
errors resulting from manual effort. | effort and errors resulting from manual processing. | |||
Similarly, dynamically generated output (e.g., tree diagrams) must | Similarly, dynamically generated output (e.g., tree diagrams) must | |||
also be modified, if necessary, in order for the resulting document | also be modified, if necessary, in order for the resulting document | |||
to satisfy the line length limits. When needed, this effort again | to satisfy the line length limits. When needed, this effort again | |||
SHOULD be automated to reduce effort and errors resulting from manual | SHOULD be automated to reduce effort and errors resulting from manual | |||
effort. | processing. | |||
4.2. Automated Reconstitution of the Original Text Content | 4.2. Automated Reconstitution of the Original Text Content | |||
Automated reconstitution of the original content is needed to support | Automated reconstitution of the original content is needed to support | |||
validation of artwork extracted from documents. YANG [RFC7950] | validation of text-based inclusions extracted from documents. YANG | |||
modules are already extracted from Internet-Drafts and validated as | [RFC7950] modules are already extracted from Internet-Drafts and | |||
part of the draft-submission process. Additionally, there has been | validated as part of the draft-submission process. Additionally, | |||
some discussion regarding needing to do the same for instance | there has been some discussion regarding needing to also validate | |||
examples (i.e., XML/JSON documents) contained within Internet-Drafts | instance examples (i.e., XML/JSON documents) contained within | |||
([yang-doctors-thread]). Thus, it SHOULD be possible to mechanically | Internet-Drafts ([yang-doctors-thread]). Thus, it SHOULD be possible | |||
reconstitute the original text content in order to satisfy tooling | to mechanically reconstitute the original text content in order to | |||
input parsers. | utilize such tooling. | |||
5. Limitations | 5. Limitations | |||
5.1. Not Recommended for Graphical Artwork | 5.1. Not Recommended for Graphical Artwork | |||
While the solution presented in this document will work on any kind | While the solution presented in this document will work on any kind | |||
of text-based content, it is most useful on content that represents | of text-based content, it is most useful on content that represents | |||
source code (XML, JSON, etc.) or, more generally, on content that has | source code (XML, JSON, etc.) or, more generally, on content that has | |||
not been laid out in two dimensions (e.g., diagrams). | not been laid out in two dimensions (e.g., diagrams). | |||
Fundamentally, the issue is whether the text content remains readable | Fundamentally, the issue is whether the text content remains readable | |||
once folded. Text content that is unpredictable is especially | once folded. Text content that is unpredictable is especially | |||
susceptible to looking bad when folded; falling into this category | susceptible to looking bad when folded; falling into this category | |||
skipping to change at page 5, line 44 ¶ | skipping to change at page 5, line 47 ¶ | |||
different line. | different line. | |||
In yet another example, some languages allow factoring blocks of code | In yet another example, some languages allow factoring blocks of code | |||
into call outs, such as functions. Using such call outs is | into call outs, such as functions. Using such call outs is | |||
especially helpful when in some deeply-nested code, as they typically | especially helpful when in some deeply-nested code, as they typically | |||
reset the indentation back to the first column. | reset the indentation back to the first column. | |||
It is RECOMMENDED that authors do as much as possible within the | It is RECOMMENDED that authors do as much as possible within the | |||
selected format to avoid long lines. | selected format to avoid long lines. | |||
6. Folded Structure | 6. Two Folding Strategies | |||
Text content that has been folded as specified by this document MUST | This document defines two nearly identical strategies for folding | |||
contain the following structure. | text-based content. | |||
6.1. Header | The Single Backslash Strategy ('\'): Uses a backslash ('\') | |||
character at the end of the line where folding occurs, and | ||||
assumes that the continuation begins at the first non- | ||||
whitespace character on the following line. | ||||
The Double Backslash Strategy ('\\'): Uses a backslash ('\') | ||||
character at the end of the line where folding occurs, and | ||||
assumes that the continuation begins after a second backslash | ||||
('\') character on the following line. | ||||
6.1. Comparison | ||||
The first strategy produces more readable output, however it is | ||||
significantly more likely to encounter unfoldable input (e.g., there | ||||
is exists a line anywhere in the input ending with a backslash | ||||
character, or there exists a long line containing only space and | ||||
backslash characters) and, for long lines that can be folded, | ||||
automation implementations are likely to encounter scenarios that | ||||
will produce errors without special care. | ||||
The second strategy produces less readable output, but is unlikely to | ||||
encounter unfoldable input, there are no long lines that cannot be | ||||
folded, and no special care is required for when folding a long line. | ||||
6.2. Recommendation | ||||
It is RECOMMENDED for implementations to first attempt to fold | ||||
content using the single backslash strategy and, only in the unlikely | ||||
event that it cannot fold the input or the folding logic is unable to | ||||
cope with a contingency occurring on the desired folding column, then | ||||
fallback to the double backslash strategy. | ||||
7. The Single Backslash Strategy ('\') | ||||
7.1. Folded Structure | ||||
Text content that has been folded as specified by this strategy MUST | ||||
adhere to the following structure. | ||||
7.1.1. Header | ||||
The header is two lines long. | ||||
The first line is the following 45-character string that MAY be | ||||
surrounded by any number of printable characters. This first line | ||||
cannot itself be folded. | ||||
NOTE: '\' line wrapping per BCP XX (RFC XXXX) | ||||
[Note to RFC Editor: Please replace XX and XXXX with the numbers | ||||
assigned to this document and delete this note. Please make this | ||||
change in multiple places in this document.] | ||||
The second line is a blank line. This line provides visual | ||||
separation for readability. | ||||
7.1.2. Body | ||||
The character encoding is the same as described in Section 2 of | ||||
[RFC7994], except that, per [RFC7991], tab characters are prohibited. | ||||
Lines that have a backslash ('\') occurring as the last character in | ||||
a line are considered "folded". | ||||
Really long lines may be folded multiple times. | ||||
7.2. Algorithm | ||||
This section describes the process for folding and unfolding long | ||||
lines when they are encountered in a single instance of text content. | ||||
It is assumed that another process inserts/extracts the individual | ||||
text content instances to/from an Internet-Draft or RFC. For | ||||
example, the `xiax` utility [xiax] does this. | ||||
7.2.1. Folding | ||||
Folding is assumed to be automated although authors may perform the | ||||
folding steps manually. | ||||
Determine the desired maximum line length from input to the automated | ||||
line-wrapping process, such as from a command line parameter. If no | ||||
value is explicitly specified, the value "69" SHOULD be used. | ||||
Ensure that the desired maximum line length is not less than the | ||||
minimum header, which is 46 characters. If the desired maximum line | ||||
length is less than this minimum, exit (this text-based content | ||||
cannot be folded). | ||||
Scan the text content for horizontal tab characters. If any | ||||
horizontal tab characters appear, either resolve them to space | ||||
characters or exit, forcing the input provider to convert them to | ||||
space characters themselves first. | ||||
Scan the text content to see if any line exceeds the desired maximum. | ||||
If no line exceeds the desired maximum, exit (this text content does | ||||
not need to be folded). | ||||
Scan the text content to ensure no existing lines already end with a | ||||
backslash ('\') character, as this would lead to an ambiguous result. | ||||
If such a line is found, exit (this text content cannot be folded). | ||||
If this text content needs to and can be folded, insert the header | ||||
described in Section 7.1.1, ensuring that any additional printable | ||||
characters surrounding the header does not result in a line exceeding | ||||
the desired maximum.. | ||||
For each line in the text content, from top-to-bottom, if the line | ||||
exceeds the desired maximum, then fold the line by: | ||||
1. Determine where the fold will occur. This location MUST be | ||||
before or at the desired maximum column, and MUST NOT precede a | ||||
space (' ') character. | ||||
2. At the location where the fold is to occur, insert a backslash | ||||
('\') character followed by the end of line character sequence. | ||||
3. On the following line, insert any number of space (' ') | ||||
characters. | ||||
The result of the previous operation is that the next line starts | ||||
with an arbitrary number of space (' ') characters, followed by the | ||||
character that was previously occupying the position where the fold | ||||
occurred. | ||||
Continue in this manner until reaching the end of the text content. | ||||
Note that this algorithm naturally addresses the case where the | ||||
remainder of a folded line is still longer than the desired maximum, | ||||
and hence needs to be folded again, ad infinitum. | ||||
The process described in this section is illustrated by the | ||||
"fold_it_1()" function in Appendix A. | ||||
7.2.2. Unfolding | ||||
All unfolding is assumed to be automated, although a reader will | ||||
mentally perform the act of unfolding the text to understand the true | ||||
nature of the original text content. | ||||
Scan the beginning of the text content for the header described in | ||||
Section 7.1.1. If the header is not present, starting on the first | ||||
line of the text content, exit (this text contents does not need to | ||||
be unfolded). | ||||
Remove the 2-line header from the text content. | ||||
For each line in the text content, from top-to-bottom, if the line | ||||
has a backslash ('\') character immediately followed by the end of | ||||
line character sequence, then the line can be unfolded. Remove the | ||||
backslash ('\') character, the end of line character sequence, and | ||||
any leading space (' ') characters, which will bring up the next | ||||
line. Then continue to scan each line in the text content starting | ||||
with the current line (in case it was multiply folded). | ||||
Continue in this manner until reaching the end of the text content. | ||||
The process described in this section is illustrated by the | ||||
"unfold_it_1()" function in Appendix A. | ||||
8. The Double Backslash Strategy ('\\') | ||||
8.1. Folded Structure | ||||
Text content that has been folded as specified by this strategy MUST | ||||
adhere to the following structure. | ||||
8.1.1. Header | ||||
The header is two lines long. | The header is two lines long. | |||
The first line is the following 46-character string that MAY be | The first line is the following 46-character string that MAY be | |||
surrounded by any number of printable characters. This first line | surrounded by any number of printable characters. This first line | |||
cannot itself be folded. | cannot itself be folded. | |||
NOTE: '\\' line wrapping per BCP XX (RFC XXXX) | NOTE: '\\' line wrapping per BCP XX (RFC XXXX) | |||
[Note to RFC Editor: Please replace XX and XXXX with the numbers | [Note to RFC Editor: Please replace XX and XXXX with the numbers | |||
assigned to this document and delete this note. Please make this | assigned to this document and delete this note. Please make this | |||
change in multiple places in this document.] | change in multiple places in this document.] | |||
The second line is a blank line. This line provides visual | The second line is a blank line. This line provides visual | |||
separation for readability. | separation for readability. | |||
6.2. Body | 8.1.2. Body | |||
The character encoding is the same as described in Section 2 of | The character encoding is the same as described in Section 2 of | |||
[RFC7994], except that, per [RFC7991], tab characters are prohibited. | [RFC7994], except that, per [RFC7991], tab characters are prohibited. | |||
Lines that have a backslash ('\') occurring as the last character in | Lines that have a backslash ('\') occurring as the last character in | |||
a line immediately followed by the end of line character sequence, | a line immediately followed by the end of line character sequence, | |||
when the subsequent line starts with a backslash ('\') as the first | when the subsequent line starts with a backslash ('\') as the first | |||
non-space (' ') character, are considered "folded". | non-space (' ') character, are considered "folded". | |||
Really long lines may be folded multiple times. | Really long lines may be folded multiple times. | |||
7. Algorithm | 8.2. Algorithm | |||
This section describes the processes for folding and unfolding long | This section describes the process for folding and unfolding long | |||
lines when they are encountered in a single instance of text content. | lines when they are encountered in a single instance of text content. | |||
It is assumed that another process inserts/extracts the individual | It is assumed that another process inserts/extracts the individual | |||
text content instances to/from an Internet-Draft or RFC. For | text content instances to/from an Internet-Draft or RFC. For | |||
example, the `xiax` utility [xiax] does just this. | example, the `xiax` utility [xiax] does this. | |||
7.1. Automated Folding | 8.2.1. Folding | |||
Folding is assumed to be automated, although authors may perform the | ||||
folding steps manually. | ||||
Determine the desired maximum line length from input to the automated | Determine the desired maximum line length from input to the automated | |||
line-wrapping process, such as from a command line parameter. If no | line-wrapping process, such as from a command line parameter. If no | |||
value is explicitly specified, the value "69" SHOULD be used. | value is explicitly specified, the value "69" SHOULD be used. | |||
Ensure that the desired maximum line length is not less than the | Ensure that the desired maximum line length is not less than the | |||
minimum header, which is 46 characters. If the desired maximum line | minimum header, which is 45 characters. If the desired maximum line | |||
length is less than this minimum, exit (this text-based content | length is less than this minimum, exit (this text-based content | |||
cannot be folded). | cannot be folded). | |||
Scan the text content for horizontal tab characters. If any | Scan the text content for horizontal tab characters. If any | |||
horizontal tab characters appear, either resolve them to space | horizontal tab characters appear, either resolve them to space | |||
characters or exit, forcing the input provider to convert them to | characters or exit, forcing the input provider to convert them to | |||
space characters themselves first. | space characters themselves first. | |||
Scan the text content to see if any line exceeds the desired maximum. | Scan the text content to see if any line exceeds the desired maximum. | |||
If no line exceeds the desired maximum, exit (this text content does | If no line exceeds the desired maximum, exit (this text content does | |||
not need to be folded). | not need to be folded). | |||
Scan the text content to ensure no existing lines already end with a | Scan the text content to ensure no existing lines already end with a | |||
backslash ('\') character when the subsequent line starts with a | backslash ('\') character while the subsequent line starts with a | |||
backslash ('\') character as the first non-space (' ') character, as | backslash ('\') character as the first non-space (' ') character, as | |||
this would lead to an ambiguous result. If such a line is found, | this would lead to an ambiguous result. If such a line is found, | |||
exit (this text content cannot be folded). | exit (this text content cannot be folded). | |||
If this text content needs to and can be folded, insert the header as | If this text content needs to and can be folded, insert the header | |||
described in Section 6.1. | described in Section 8.1.1, ensuring that any additional printable | |||
characters surrounding the header does not result in a line exceeding | ||||
the desired maximum.. | ||||
For each line in the text content, from top-to-bottom, if the line | For each line in the text content, from top-to-bottom, if the line | |||
exceeds the desired maximum, then fold the line at the desired | exceeds the desired maximum, then fold the line by: | |||
maximum column by 1) inserting the character backslash ('\') | ||||
character at the maximum column, 2) inserting the end of line | ||||
character sequence, inserting any number of space (' ') characters, | ||||
and 4) inserting a further backslash ('\') character. | ||||
The result of this previous operation is that the next line starts | 1. Determine where the fold will occur. This location MUST be | |||
before or at the desired maximum column. | ||||
2. At the location where the fold is to occur, insert a first | ||||
backslash ('\') character followed by the end of line character | ||||
sequence. | ||||
3. On the following line, insert any number of space (' ') | ||||
characters followed by a second backslash ('\') character. | ||||
The result of the previous operation is that the next line starts | ||||
with an arbitrary number of space (' ') characters, followed by a | with an arbitrary number of space (' ') characters, followed by a | |||
backslash ('\') character, immediately followed by the character that | backslash ('\') character, immediately followed by the character that | |||
was previously in the maximum column. | was previously occupying the position where the fold occurred. | |||
Continue in this manner until reaching the end of the text content. | Continue in this manner until reaching the end of the text content. | |||
Note that this algorithm naturally addresses the case where the | Note that this algorithm naturally addresses the case where the | |||
remainder of a folded line is still longer than the desired maximum, | remainder of a folded line is still longer than the desired maximum, | |||
and hence needs to be folded again, ad infinitum. | and hence needs to be folded again, ad infinitum. | |||
The process described in this section is illustrated by the | The process described in this section is illustrated by the | |||
"fold_it()" function in Appendix A. | "fold_it_2()" function in Appendix A. | |||
7.1.1. Manual Folding | ||||
Authors may choose to fold text examples and source code by hand to | ||||
produce a text content that is more pleasant for a human reader but | ||||
which can still be automatically unfolded (as described in | ||||
Section 7.2) to produce single lines that are longer than the maximum | ||||
document line length. | ||||
For example, an author may choose to make the fold at convenient gaps | ||||
between words such that the backslash is placed in a lower column | ||||
number than the text content's maximum column value. | ||||
Additionally, an author may choose to indent the start of a | ||||
continuation line by inserting space characters before the line | ||||
continuation marker backslash character. | ||||
Manual folding may also help handle the cases that cannot be | ||||
automatically folded as described in Section 7. | ||||
Authors MUST produce a result that adheres to the structure described | ||||
in Section 6. | ||||
7.2. Automated Unfolding | 8.2.2. Unfolding | |||
All unfolding is assumed to be automated although a reader will | All unfolding is assumed to be automated although a reader will | |||
mentally perform the act of unfolding the text to understand the true | mentally perform the act of unfolding the text to understand the true | |||
nature of the original text content. | nature of the original text content. | |||
Scan the beginning of the text content for the header described in | Scan the beginning of the text content for the header described in | |||
Section 6.1. If the header is not present, starting on the first | Section 8.1.1. If the header is not present, starting on the first | |||
line of the text content, exit (this artwork does not need to be | line of the text content, exit (this text content does not need to be | |||
unfolded). | unfolded). | |||
Remove the 2-line header from the text content. | Remove the 2-line header from the text content. | |||
For each line in the text content, from top-to-bottom, if the line | For each line in the text content, from top-to-bottom, if the line | |||
has a backslash ('\') character immediately followed by the end of | has a backslash ('\') character immediately followed by the end of | |||
line character sequence, and if the next line has a backslash ('\') | line character sequence, and if the next line has a backslash ('\') | |||
character as the first non-space (' ') character, then the lines can | character as the first non-space (' ') character, then the lines can | |||
be unfolded. Remove the first backslash ('\') character, the end of | be unfolded. Remove the first backslash ('\') character, the end of | |||
line character sequence, any leading space (' ') characters, and the | line character sequence, any leading space (' ') characters, and the | |||
second backslash ('\') character, which will bring up the next line. | second backslash ('\') character, which will bring up the next line. | |||
Then continue to scan each line in the text content starting with the | Then continue to scan each line in the text content starting with the | |||
current line (in case it was multiply folded). | current line (in case it was multiply folded). | |||
Continue in this manner until reaching the end of the text content. | Continue in this manner until reaching the end of the text content. | |||
The process described in this section is illustrated by the | The process described in this section is illustrated by the | |||
"unfold_it()" function in Appendix A. | "unfold_it_2()" function in Appendix A. | |||
8. Examples | 9. Examples | |||
The following self-documenting examples illustrate folded text-based | The following self-documenting examples illustrate folded text-based | |||
content. | content. | |||
The source text content cannot be presented here, as it would again | The source text content cannot be presented here, as it would again | |||
need to be folded. Alas, only the result can be provided. | be folded. Alas, only the results can be provided. | |||
The examples in Sections 8.1 through 8.4 were automatically folded on | 9.1. Example Showing Boundary Conditions | |||
column 69, the default value. Section 8.5 shows an example of manual | ||||
folding. | ||||
8.1. Simple Example Showing Boundary Conditions | This example illustrates boundary condition. The input contains | |||
seven lines, each line one character longer than the previous line. | ||||
Numbers for counting purposes. The default desired maximum column | ||||
value "69" is used. | ||||
This example illustrates a boundary condition test using numbers for | 9.1.1. Using '\' | |||
counting purposes. The input contains 5 lines, each line one | ||||
character longer than the previous. | ||||
Any printable character (including ' ' and '\') can be used as a | =========== NOTE: '\' line wrapping per BCP XX (RFC XXXX) =========== | |||
substitute for any number, except for on the 4th row, the trailing | ||||
'9' is not allowed to be a '\' character if the first non-space | 123456789012345678901234567890123456789012345678901234567890123456 | |||
character of the next line is a '\' character, as that would lead to | 1234567890123456789012345678901234567890123456789012345678901234567 | |||
an ambiguous result. | 12345678901234567890123456789012345678901234567890123456789012345678 | |||
123456789012345678901234567890123456789012345678901234567890123456789 | ||||
12345678901234567890123456789012345678901234567890123456789012345678\ | ||||
90 | ||||
12345678901234567890123456789012345678901234567890123456789012345678\ | ||||
901 | ||||
12345678901234567890123456789012345678901234567890123456789012345678\ | ||||
9012 | ||||
9.1.2. Using '\\' | ||||
========== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) =========== | ========== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) =========== | |||
123456789012345678901234567890123456789012345678901234567890123456 | 123456789012345678901234567890123456789012345678901234567890123456 | |||
1234567890123456789012345678901234567890123456789012345678901234567 | 1234567890123456789012345678901234567890123456789012345678901234567 | |||
12345678901234567890123456789012345678901234567890123456789012345678 | 12345678901234567890123456789012345678901234567890123456789012345678 | |||
123456789012345678901234567890123456789012345678901234567890123456789 | 123456789012345678901234567890123456789012345678901234567890123456789 | |||
12345678901234567890123456789012345678901234567890123456789012345678\ | 12345678901234567890123456789012345678901234567890123456789012345678\ | |||
\90 | \90 | |||
12345678901234567890123456789012345678901234567890123456789012345678\ | 12345678901234567890123456789012345678901234567890123456789012345678\ | |||
\901 | \901 | |||
12345678901234567890123456789012345678901234567890123456789012345678\ | 12345678901234567890123456789012345678901234567890123456789012345678\ | |||
\9012 | \9012 | |||
8.2. Example Showing Multiple Wraps of a Single Line | 9.2. Example Showing Multiple Wraps of a Single Line | |||
This example illustrates one very long line (280 characters). | This example illustrates what happens when very long line needs to be | |||
folded multiple times. The input contains one line containing 280 | ||||
characters. Numbers for counting purposes. The default desired | ||||
maximum column value "69" is used. | ||||
Any printable character (including ' ' and '\') can be used as a | 9.2.1. Using '\' | |||
substitute for any number. | ||||
=========== NOTE: '\' line wrapping per BCP XX (RFC XXXX) =========== | ||||
12345678901234567890123456789012345678901234567890123456789012345678\ | ||||
90123456789012345678901234567890123456789012345678901234567890123456\ | ||||
78901234567890123456789012345678901234567890123456789012345678901234\ | ||||
56789012345678901234567890123456789012345678901234567890123456789012\ | ||||
34567890 | ||||
9.2.2. Using '\\' | ||||
========== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) =========== | ========== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) =========== | |||
12345678901234567890123456789012345678901234567890123456789012345678\ | 12345678901234567890123456789012345678901234567890123456789012345678\ | |||
\9012345678901234567890123456789012345678901234567890123456789012345\ | \9012345678901234567890123456789012345678901234567890123456789012345\ | |||
\6789012345678901234567890123456789012345678901234567890123456789012\ | \6789012345678901234567890123456789012345678901234567890123456789012\ | |||
\3456789012345678901234567890123456789012345678901234567890123456789\ | \3456789012345678901234567890123456789012345678901234567890123456789\ | |||
\01234567890 | \01234567890 | |||
8.3. Example With Native Backslash | 9.3. Example Showing Smart Folding | |||
This example has a '\' character in the wrapping column. The native | This example illustrates how readability can be improved via "smart" | |||
text includes the sequence "fish\fowl" with the '\' character | folding, whereby folding occurs at format-specific locations and | |||
occurring on the 69th column. | format-specific indentations are used. | |||
string1="The quick brown dog jumps over the lazy dog which is a fish\ | The text content was manually folded, since the script in the | |||
\\fowl as appropriate" | appendix does not implement smart folding. | |||
8.4. Example With Native Whitespace | Note that the header is surrounded by different printable characters | |||
then shown in the script-generated examples. | ||||
This example has whitespace spanning the wrapping column. The native | 9.3.1. Using '\' | |||
input contains 15 space (' ') characters between "like" and "white". | ||||
========== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) =========== | [NOTE: '\' line wrapping per BCP XX (RFC XXXX)] | |||
Sometimes our strings include multiple spaces such as "We like \ | <yang-library | |||
\ white space." | xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library" | |||
xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"> | ||||
8.5. Example of Manual Wrapping | <module-set> | |||
<name>config-modules</name> | ||||
<module> | ||||
<name>ietf-interfaces</name> | ||||
<revision>2018-02-20</revision> | ||||
<namespace>\ | ||||
urn:ietf:params:xml:ns:yang:ietf-interfaces\ | ||||
</namespace> | ||||
</module> | ||||
... | ||||
</module-set> | ||||
... | ||||
</yang-library> | ||||
This example was manually wrapped to cause the folding to occur after | Below is the equivalent to the above, but it was folded using the | |||
each term, putting each term on its own line. Indentation is used to | script in the appendix. | |||
additionally improve readability. Also note that the mandatory | ||||
header is surrounded by different printable characters than shown in | ||||
the other examples. | ||||
===== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) ===== | =========== NOTE: '\' line wrapping per BCP XX (RFC XXXX) =========== | |||
<yang-library | <yang-library | |||
xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library" | xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library" | |||
xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"> | xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"> | |||
<module-set> | <module-set> | |||
<name>config-modules</name> | <name>config-modules</name> | |||
<module> | <module> | |||
<name>ietf-interfaces</name> | <name>ietf-interfaces</name> | |||
<revision>2018-02-20</revision> | <revision>2018-02-20</revision> | |||
<namespace>\ | <namespace>urn:ietf:params:xml:ns:yang:ietf-interfaces</namesp\ | |||
\urn:ietf:params:xml:ns:yang:ietf-interfaces\ | ace> | |||
\</namespace> | ||||
</module> | </module> | |||
... | ||||
</module-set> | ||||
... | ||||
</yang-library> | ||||
9.3.2. Using '\\' | ||||
[NOTE: '\\' line wrapping per BCP XX (RFC XXXX)] | ||||
<yang-library | ||||
xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library" | ||||
xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"> | ||||
<module-set> | ||||
<name>config-modules</name> | ||||
<module> | <module> | |||
<name>ietf-ip</name> | <name>ietf-interfaces</name> | |||
<revision>2018-02-22</revision> | <revision>2018-02-20</revision> | |||
<namespace>\ | <namespace>\ | |||
\urn:ietf:params:xml:ns:yang:ietf-ip\ | \urn:ietf:params:xml:ns:yang:ietf-interfaces\ | |||
\</namespace> | \</namespace> | |||
</module> | </module> | |||
<import-only-module> | ... | |||
<name>ietf-yang-types</name> | ||||
<revision>2013-07-15</revision> | ||||
<namespace>\ | ||||
\urn:ietf:params:xml:ns:yang:ietf-yang-types\ | ||||
\</namespace> | ||||
</import-only-module> | ||||
<import-only-module> | ||||
<name>ietf-inet-types</name> | ||||
<revision>2013-07-15</revision> | ||||
<namespace>\ | ||||
\urn:ietf:params:xml:ns:yang:ietf-inet-types\ | ||||
\</namespace> | ||||
</import-only-module> | ||||
</module-set> | </module-set> | |||
... | ||||
<schema> | ||||
<name>config-schema</name> | ||||
<module-set>config-modules</module-set> | ||||
</schema> | ||||
<schema> | ||||
<name>state-schema</name> | ||||
<module-set>config-modules</module-set> | ||||
<module-set>state-modules</module-set> | ||||
</schema> | ||||
<datastore> | ||||
<name>ds:startup</name> | ||||
<schema>config-schema</schema> | ||||
</datastore> | ||||
<datastore> | ||||
<name>ds:running</name> | ||||
<schema>config-schema</schema> | ||||
</datastore> | ||||
<datastore> | ||||
<name>ds:operational</name> | ||||
<schema>state-schema</schema> | ||||
</datastore> | ||||
<content-id>75a43df9bd56b92aacc156a2958fbe12312fb285</content-id> | ||||
</yang-library> | </yang-library> | |||
The manual folding produces a more readable result than the following | Below is the equivalent to the above, but it was folded using the | |||
equivalent folding that contains no indentation. | script in the appendix. | |||
========== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) =========== | ========== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) =========== | |||
<yang-library | <yang-library | |||
xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library" | xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library" | |||
xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"> | xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"> | |||
<module-set> | <module-set> | |||
<name>config-modules</name> | <name>config-modules</name> | |||
<module> | <module> | |||
<name>ietf-interfaces</name> | <name>ietf-interfaces</name> | |||
<revision>2018-02-20</revision> | <revision>2018-02-20</revision> | |||
<namespace>urn:ietf:params:xml:ns:yang:ietf-interfaces</namesp\ | <namespace>urn:ietf:params:xml:ns:yang:ietf-interfaces</namesp\ | |||
skipping to change at page 12, line 16 ¶ | skipping to change at page 15, line 42 ¶ | |||
xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"> | xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"> | |||
<module-set> | <module-set> | |||
<name>config-modules</name> | <name>config-modules</name> | |||
<module> | <module> | |||
<name>ietf-interfaces</name> | <name>ietf-interfaces</name> | |||
<revision>2018-02-20</revision> | <revision>2018-02-20</revision> | |||
<namespace>urn:ietf:params:xml:ns:yang:ietf-interfaces</namesp\ | <namespace>urn:ietf:params:xml:ns:yang:ietf-interfaces</namesp\ | |||
\ace> | \ace> | |||
</module> | </module> | |||
<module> | ... | |||
<name>ietf-ip</name> | ||||
<revision>2018-02-22</revision> | ||||
<namespace>urn:ietf:params:xml:ns:yang:ietf-ip</namespace> | ||||
</module> | ||||
<import-only-module> | ||||
<name>ietf-yang-types</name> | ||||
<revision>2013-07-15</revision> | ||||
<namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namesp\ | ||||
\ace> | ||||
</import-only-module> | ||||
<import-only-module> | ||||
<name>ietf-inet-types</name> | ||||
<revision>2013-07-15</revision> | ||||
<namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</namesp\ | ||||
\ace> | ||||
</import-only-module> | ||||
</module-set> | </module-set> | |||
... | ||||
<schema> | ||||
<name>config-schema</name> | ||||
<module-set>config-modules</module-set> | ||||
</schema> | ||||
<schema> | ||||
<name>state-schema</name> | ||||
<module-set>config-modules</module-set> | ||||
<module-set>state-modules</module-set> | ||||
</schema> | ||||
<datastore> | ||||
<name>ds:startup</name> | ||||
<schema>config-schema</schema> | ||||
</datastore> | ||||
<datastore> | ||||
<name>ds:running</name> | ||||
<schema>config-schema</schema> | ||||
</datastore> | ||||
<datastore> | ||||
<name>ds:operational</name> | ||||
<schema>state-schema</schema> | ||||
</datastore> | ||||
<content-id>75a43df9bd56b92aacc156a2958fbe12312fb285</content-id> | ||||
</yang-library> | </yang-library> | |||
9. Security Considerations | 10. Security Considerations | |||
This BCP has no Security Considerations. | This BCP has no Security Considerations. | |||
10. IANA Considerations | 11. IANA Considerations | |||
This BCP has no IANA Considerations. | This BCP has no IANA Considerations. | |||
11. References | 12. References | |||
11.1. Normative References | 12.1. Normative References | |||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
<https://www.rfc-editor.org/info/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
May 2017, <https://www.rfc-editor.org/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
11.2. Informative References | 12.2. Informative References | |||
[RFC7749] Reschke, J., "The "xml2rfc" Version 2 Vocabulary", | [RFC7749] Reschke, J., "The "xml2rfc" Version 2 Vocabulary", | |||
RFC 7749, DOI 10.17487/RFC7749, February 2016, | RFC 7749, DOI 10.17487/RFC7749, February 2016, | |||
<https://www.rfc-editor.org/info/rfc7749>. | <https://www.rfc-editor.org/info/rfc7749>. | |||
[RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", | [RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", | |||
RFC 7950, DOI 10.17487/RFC7950, August 2016, | RFC 7950, DOI 10.17487/RFC7950, August 2016, | |||
<https://www.rfc-editor.org/info/rfc7950>. | <https://www.rfc-editor.org/info/rfc7950>. | |||
[RFC7991] Hoffman, P., "The "xml2rfc" Version 3 Vocabulary", | [RFC7991] Hoffman, P., "The "xml2rfc" Version 3 Vocabulary", | |||
skipping to change at page 15, line 11 ¶ | skipping to change at page 17, line 11 ¶ | |||
"[yang-doctors] automating yang doctor reviews", | "[yang-doctors] automating yang doctor reviews", | |||
<https://mailarchive.ietf.org/arch/msg/yang-doctors/ | <https://mailarchive.ietf.org/arch/msg/yang-doctors/ | |||
DCfBqgfZPAD7afzeDFlQ1Xm2X3g>. | DCfBqgfZPAD7afzeDFlQ1Xm2X3g>. | |||
Appendix A. POSIX Shell Script | Appendix A. POSIX Shell Script | |||
This non-normative appendix section includes a shell script that can | This non-normative appendix section includes a shell script that can | |||
both fold and unfold text content. Note that this script is applied | both fold and unfold text content. Note that this script is applied | |||
only to single text content instances. | only to single text content instances. | |||
#!/bin/bash | #!/bin/bash --posix # must be `bash` (not `sh`) | |||
print_usage() { | print_usage() { | |||
echo | echo | |||
echo "Folds the text file, only if needed, at the specified" | echo "Folds the text file, only if needed, at the specified" | |||
echo "column, according to BCP XX." | echo "column, according to BCP XX." | |||
echo | echo | |||
echo "Usage: $0 [-c <col>] [-r] -i <infile> -o <outfile>" | echo "Usage: $0 [-s <strategy>] [-c <col>] [-r] -i <infile>" | |||
echo " -o <outfile>" | ||||
echo | echo | |||
echo " -s: strategy to use, '1' or '2' (default: try 1, else 2)" | ||||
echo " -c: column to fold on (default: 69)" | echo " -c: column to fold on (default: 69)" | |||
echo " -r: reverses the operation" | echo " -r: reverses the operation" | |||
echo " -i: the input filename" | echo " -i: the input filename" | |||
echo " -o: the output filename" | echo " -o: the output filename" | |||
echo " -d: show debug messages" | echo " -d: show debug messages" | |||
echo " -h: show this message" | echo " -h: show this message" | |||
echo | echo | |||
echo "Exit status code: zero on success, non-zero otherwise." | echo "Exit status code: zero on success, non-zero otherwise." | |||
echo | echo | |||
} | } | |||
# global vars, do not edit | # global vars, do not edit | |||
strategy=0 # auto | ||||
debug=0 | debug=0 | |||
reversed=0 | reversed=0 | |||
infile="" | infile="" | |||
outfile="" | outfile="" | |||
maxcol=69 # default, may be overridden by param | maxcol=69 # default, may be overridden by param | |||
hdr_txt="NOTE: '\\\\' line wrapping per BCP XX (RFC XXXX)" | hdr_txt_1="NOTE: '\\' line wrapping per BCP XX (RFC XXXX)" | |||
hdr_txt_2="NOTE: '\\\\' line wrapping per BCP XX (RFC XXXX)" | ||||
equal_chars="==============================================" | equal_chars="==============================================" | |||
space_chars=" " | space_chars=" " | |||
fold_it() { | fold_it_1() { | |||
# since upcomming tests are >= (not >) | # ensure input file doesn't contain the fold-sequence already | |||
testcol=`expr "$maxcol" + 1` | pcregrep -M "\\\\\n" $infile >> /dev/null 2>&1 | |||
if [ $? -eq 0 ]; then | ||||
# check if file needs folding | echo | |||
grep ".\{$testcol\}" $infile >> /dev/null 2>&1 | echo "Error1: infile $infile has a line ending with a '\\'" | |||
if [ $? -ne 0 ]; then | echo "character. This file cannot be folded." | |||
if [[ $debug -eq 1 ]]; then | echo | |||
echo "nothing to do" | return 1 | |||
fi | ||||
cp $infile $outfile | ||||
return -1 | ||||
fi | fi | |||
# stash some vars | ||||
testcol=`expr "$maxcol" + 1` | ||||
foldcol=`expr "$maxcol" - 1` # for the inserted '\' char | foldcol=`expr "$maxcol" - 1` # for the inserted '\' char | |||
# ensure input file doesn't contain a TAB | # ensure input file doesn't contain whitespace on the fold column | |||
grep $'\t' $infile >> /dev/null 2>&1 | grep "^.\{$foldcol\} " $infile >> /dev/null 2>&1 | |||
if [ $? -eq 0 ]; then | if [ $? -eq 0 ]; then | |||
echo | echo | |||
echo "Error: infile contains a TAB character, which is not" | echo "Error: infile has a space character occuring after the" | |||
echo "allowed." | echo "folding column. This file cannot be folded." | |||
echo | echo | |||
return 1 | return 1 | |||
fi | fi | |||
# center header text | ||||
length=`expr ${#hdr_txt_1} + 2` | ||||
left_sp=`expr \( "$maxcol" - "$length" \) / 2` | ||||
right_sp=`expr "$maxcol" - "$length" - "$left_sp"` | ||||
header=`printf "%.*s %s %.*s" "$left_sp" "$equal_chars"\ | ||||
"$hdr_txt_1" "$right_sp" "$equal_chars"` | ||||
# generate outfile | ||||
echo "$header" > $outfile | ||||
echo "" >> $outfile | ||||
gsed "/.\{$testcol\}/s/\(.\{$foldcol\}\)/\1\\\\\n/g"\ | ||||
< $infile >> $outfile | ||||
return 0 | ||||
} | ||||
fold_it_2() { | ||||
# ensure input file doesn't contain the fold-sequence already | # ensure input file doesn't contain the fold-sequence already | |||
pcregrep -M "\\\\\n[\ ]*\\\\" $infile >> /dev/null 2>&1 | pcregrep -M "\\\\\n[\ ]*\\\\" $infile >> /dev/null 2>&1 | |||
if [ $? -eq 0 ]; then | if [ $? -eq 0 ]; then | |||
echo | echo | |||
echo "Error: infile has a line ending with a '\' character" | echo "Error2: infile has a line ending with a '\\' character" | |||
echo " followed by a '\' character as the first non-space" | echo "followed by a '\\' character as the first non-space" | |||
echo " character on the next line. This file cannot be" | echo "character on the next line. This file cannot be folded." | |||
echo " folded." | ||||
echo | echo | |||
return 1 | return 1 | |||
fi | fi | |||
# center header text | # center header text | |||
length=`expr ${#hdr_txt} + 2` | length=`expr ${#hdr_txt_2} + 2` | |||
left_sp=`expr \( "$maxcol" - "$length" \) / 2` | left_sp=`expr \( "$maxcol" - "$length" \) / 2` | |||
right_sp=`expr "$maxcol" - "$length" - "$left_sp"` | right_sp=`expr "$maxcol" - "$length" - "$left_sp"` | |||
header=`printf "%.*s %s %.*s" "$left_sp" "$equal_chars"\ | header=`printf "%.*s %s %.*s" "$left_sp" "$equal_chars"\ | |||
"$hdr_txt" "$right_sp" "$equal_chars"` | "$hdr_txt_2" "$right_sp" "$equal_chars"` | |||
# fold using recursive passes ('g' didn't work) | # fold using recursive passes ('g' used in fold_it_1 didn't work) | |||
if [ -z "$1" ]; then | if [ -z "$1" ]; then | |||
# init recursive env | # init recursive env | |||
cp $infile /tmp/wip | cp $infile /tmp/wip | |||
fi | fi | |||
testcol=`expr "$maxcol" + 1` | ||||
foldcol=`expr "$maxcol" - 1` # for the inserted '\' char | ||||
gsed "/.\{$testcol\}/s/\(.\{$foldcol\}\)/\1\\\\\n\\\\/" < /tmp/wip\ | gsed "/.\{$testcol\}/s/\(.\{$foldcol\}\)/\1\\\\\n\\\\/" < /tmp/wip\ | |||
>> /tmp/wip2 | >> /tmp/wip2 | |||
diff /tmp/wip /tmp/wip2 > /dev/null 2>&1 | diff /tmp/wip /tmp/wip2 > /dev/null 2>&1 | |||
if [ $? -eq 1 ]; then | if [ $? -eq 1 ]; then | |||
mv /tmp/wip2 /tmp/wip | mv /tmp/wip2 /tmp/wip | |||
fold_it "recursing" | fold_it_2 "recursing" | |||
else | else | |||
echo "$header" > $outfile | echo "$header" > $outfile | |||
echo "" >> $outfile | echo "" >> $outfile | |||
cat /tmp/wip2 >> $outfile | cat /tmp/wip2 >> $outfile | |||
rm /tmp/wip* | rm /tmp/wip* | |||
fi | fi | |||
## following two lines represent a non-functional variant to the | ||||
## recursive logic presented in the block above. It used to work | ||||
## before the '\' on the next line was added to the format (i.e., | ||||
## the trailing '\\\\' in the substitution below), but now there | ||||
## is an off-by-one error. Leaving here in case anyone can fix it. | ||||
#echo "$header" > $outfile | ||||
#echo "" >> $outfile | ||||
#gsed "/.\{$testcol\}/s/\(.\{$foldcol\}\)/\1\\\\\n\\\\/g"\ | ||||
< $infile >> $outfile | ||||
return 0 | return 0 | |||
} | } | |||
unfold_it() { | fold_it() { | |||
# check if file needs unfolding | # ensure input file doesn't contain a TAB | |||
line=`head -n 1 $infile | fgrep "$hdr_txt"` | grep $'\t' $infile >> /dev/null 2>&1 | |||
if [ $? -eq 0 ]; then | ||||
echo | ||||
echo "Error: infile contains a TAB character, which is not" | ||||
echo "allowed." | ||||
echo | ||||
return 1 | ||||
fi | ||||
# check if file needs folding | ||||
testcol=`expr "$maxcol" + 1` | ||||
grep ".\{$testcol\}" $infile >> /dev/null 2>&1 | ||||
if [ $? -ne 0 ]; then | if [ $? -ne 0 ]; then | |||
if [[ $debug -eq 1 ]]; then | if [[ $debug -eq 1 ]]; then | |||
echo "nothing to do" | echo "nothing to do" | |||
fi | fi | |||
cp $infile $outfile | cp $infile $outfile | |||
return -1 | return -1 | |||
fi | fi | |||
if [[ $strategy -eq 1 ]]; then | ||||
fold_it_1 | ||||
return $? | ||||
fi | ||||
if [[ $strategy -eq 2 ]]; then | ||||
fold_it_2 | ||||
return $? | ||||
fi | ||||
fold_it_1 | ||||
if [ $? -ne 0 ]; then | ||||
fold_it_2 | ||||
return $? | ||||
fi | ||||
return 0 | ||||
} | ||||
# output all but the first two lines (the header) to wip (work | unfold_it_1() { | |||
# in progress) file | # output all but the first two lines (the header) to wip file | |||
awk "NR>2" $infile > /tmp/wip | awk "NR>2" $infile > /tmp/wip | |||
# unfold wip file | # unfold wip file | |||
gsed ":x; /.*\\\\\$/N; s/\\\\\n[ ]*\\\\//; tx; s/\t//g" /tmp/wip\ | gsed ":x; /.*\\\\$/N; s/\\\\\n[ ]*//; tx" /tmp/wip > $outfile | |||
> $outfile | ||||
# clean up and return | ||||
rm /tmp/wip | ||||
return 0 | ||||
} | ||||
unfold_it_2() { | ||||
# output all but the first two lines (the header) to wip file | ||||
awk "NR>2" $infile > /tmp/wip | ||||
# unfold wip file | ||||
gsed ":x; /.*\\\\$/N; s/\\\\\n[ ]*\\\\//; tx" /tmp/wip > $outfile | ||||
# clean up and return | # clean up and return | |||
rm /tmp/wip | rm /tmp/wip | |||
return 0 | return 0 | |||
} | } | |||
unfold_it() { | ||||
# check if file needs unfolding | ||||
line=`head -n 1 $infile` | ||||
result=`echo $line | fgrep "$hdr_txt_1"` | ||||
if [ $? -eq 0 ]; then | ||||
unfold_it_1 | ||||
return $? | ||||
fi | ||||
result=`echo $line | fgrep "$hdr_txt_2"` | ||||
if [ $? -eq 0 ]; then | ||||
unfold_it_2 | ||||
return $? | ||||
fi | ||||
if [[ $debug -eq 1 ]]; then | ||||
echo "nothing to do" | ||||
fi | ||||
cp $infile $outfile | ||||
return -1 | ||||
} | ||||
process_input() { | process_input() { | |||
while [ "$1" != "" ]; do | while [ "$1" != "" ]; do | |||
if [ "$1" == "-h" -o "$1" == "--help" ]; then | if [ "$1" == "-h" -o "$1" == "--help" ]; then | |||
print_usage | print_usage | |||
exit 1 | exit 1 | |||
fi | fi | |||
if [ "$1" == "-d" ]; then | if [ "$1" == "-d" ]; then | |||
debug=1 | debug=1 | |||
fi | fi | |||
if [ "$1" == "-s" ]; then | ||||
strategy="$2" | ||||
shift | ||||
fi | ||||
if [ "$1" == "-c" ]; then | if [ "$1" == "-c" ]; then | |||
maxcol="$2" | maxcol="$2" | |||
shift | shift | |||
fi | fi | |||
if [ "$1" == "-r" ]; then | if [ "$1" == "-r" ]; then | |||
reversed=1 | reversed=1 | |||
fi | fi | |||
if [ "$1" == "-i" ]; then | if [ "$1" == "-i" ]; then | |||
infile="$2" | infile="$2" | |||
shift | shift | |||
skipping to change at page 18, line 48 ¶ | skipping to change at page 22, line 21 ¶ | |||
exit 1 | exit 1 | |||
fi | fi | |||
if [ ! -f "$infile" ]; then | if [ ! -f "$infile" ]; then | |||
echo | echo | |||
echo "Error: specified file \"$infile\" is does not exist." | echo "Error: specified file \"$infile\" is does not exist." | |||
echo | echo | |||
exit 1 | exit 1 | |||
fi | fi | |||
min_supported=`expr ${#hdr_txt} + 8` | if [[ $strategy -eq 2 ]]; then | |||
min_supported=`expr ${#hdr_txt_2} + 8` | ||||
else | ||||
min_supported=`expr ${#hdr_txt_1} + 8` | ||||
fi | ||||
if [ $maxcol -lt $min_supported ]; then | if [ $maxcol -lt $min_supported ]; then | |||
echo | echo | |||
echo "Error: the folding column cannot be less than" | echo "Error: the folding column cannot be less than" | |||
echo "$min_supported" | echo "$min_supported." | |||
echo | echo | |||
exit 1 | exit 1 | |||
fi | fi | |||
max_supported=`expr ${#equal_chars} + 1 + ${#hdr_txt} + 1\ | # this is only because the code otherwise runs out of equal_chars | |||
max_supported=`expr ${#equal_chars} + 1 + ${#hdr_txt_1} + 1\ | ||||
+ ${#equal_chars}` | + ${#equal_chars}` | |||
if [ $maxcol -gt $max_supported ]; then | if [ $maxcol -gt $max_supported ]; then | |||
echo | echo | |||
echo "Error: the folding column cannot be more than" | echo "Error: the folding column cannot be more than" | |||
echo "$max_supported" | echo "$max_supported." | |||
echo | echo | |||
exit 1 | exit 1 | |||
fi | fi | |||
} | } | |||
main() { | main() { | |||
if [ "$#" == "0" ]; then | if [ "$#" == "0" ]; then | |||
print_usage | print_usage | |||
exit 1 | exit 1 | |||
fi | fi | |||
process_input $@ | process_input $@ | |||
if [[ $reversed -eq 0 ]]; then | if [[ $reversed -eq 0 ]]; then | |||
fold_it | fold_it | |||
code=$? | code=$? | |||
else | else | |||
unfold_it | unfold_it | |||
code=$? | code=$? | |||
fi | fi | |||
exit $code | exit $code | |||
} | } | |||
skipping to change at page 19, line 43 ¶ | skipping to change at page 23, line 19 ¶ | |||
code=$? | code=$? | |||
fi | fi | |||
exit $code | exit $code | |||
} | } | |||
main "$@" | main "$@" | |||
Acknowledgements | Acknowledgements | |||
The authors thank the following folks for their various contributions | The authors thank the following folks for their various contributions | |||
(sorted by first name): Gianmarco Bruno, Italo Busi, Jonathan | (sorted by first name): Benoit Claise, Gianmarco Bruno, Italo Busi, | |||
Hansford, Joel Jaeggli, Lou Berger, Martin Bjorklund, Italo Busi, and | Joel Jaeggli, Jonathan Hansford, Lou Berger, Martin Bjorklund, and | |||
Rob Wilton. | Rob Wilton. | |||
The authors additionally thank the RFC Editor for confirming that | The authors additionally thank the RFC Editor for confirming that | |||
there is no set convention today for handling long lines in artwork/ | there is no set convention today for handling long lines in artwork/ | |||
sourcecode inclusions. | sourcecode inclusions. | |||
Authors' Addresses | Authors' Addresses | |||
Kent Watsen | Kent Watsen | |||
Watsen Networks | Watsen Networks | |||
EMail: kent+ietf@watsen.net | EMail: kent+ietf@watsen.net | |||
Qin Wu | ||||
Huawei Technologies | ||||
EMail: bill.wu@huawei.com | ||||
Adrian Farrel | Adrian Farrel | |||
Old Dog Consulting | Old Dog Consulting | |||
EMail: adrian@olddog.co.uk | EMail: adrian@olddog.co.uk | |||
Benoit Claise | Qin Wu | |||
Cisco Systems, Inc. | Huawei Technologies | |||
EMail: bclaise@cisco.com | EMail: bill.wu@huawei.com | |||
End of changes. 101 change blocks. | ||||
319 lines changed or deleted | 515 lines changed or added | |||
This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |