draft-ietf-netmod-artwork-folding-09.txt   draft-ietf-netmod-artwork-folding-10.txt 
NETMOD Working Group K. Watsen NETMOD Working Group K. Watsen
Internet-Draft Watsen Networks Internet-Draft Watsen Networks
Intended status: Best Current Practice A. Farrel Intended status: Informational A. Farrel
Expires: March 1, 2020 Old Dog Consulting Expires: March 8, 2020 Old Dog Consulting
Q. Wu Q. Wu
Huawei Technologies Huawei Technologies
August 29, 2019 September 5, 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-09 draft-ietf-netmod-artwork-folding-10
Abstract Abstract
This document defines two strategies for handling long lines in This document defines two strategies for handling long lines in
width-bounded text content. One strategy is based on the historic width-bounded text content. One strategy is based on the historical
use of a single backslash ('\') character to indicate where line- use of a single backslash ('\') character to indicate where line-
folding has occurred, with the continuation occurring with the first folding has occurred, with the continuation occurring with the first
non-space (' ') character on the next line. The second strategy non-space (' ') character on the next line. The second strategy
extends the first strategy by adding a second backslash character to extends the first strategy by adding a second backslash character to
identify where the continuation begins and thereby able to handle identify where the continuation begins and thereby able to handle
cases not supported by the first strategy. Both strategies use a cases not supported by the first strategy. Both strategies use a
self-describing header enabling automated reconstitution of the self-describing header enabling automated reconstitution of the
original content. original content.
Editorial Note (To be removed by RFC Editor)
Please be aware that this document uses throughout the five-character
text seqeuence located between the following two double-quotes: "('
')". It has been observed that some renderings of this text sequence
produces a natural line break at the space character in the middle,
thus causing "('" to appear at the end of the first line and "')" to
appear at the beginning of the next line. Such a line-break is
confusing and should not occur in the RFC output formats.
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 March 1, 2020. This Internet-Draft will expire on March 8, 2020.
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 25 skipping to change at page 2, line 34
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Applicability Statement . . . . . . . . . . . . . . . . . . . 4 2. Applicability Statement . . . . . . . . . . . . . . . . . . . 4
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 . . 5 4.2. Automated Reconstitution of the Original Text Content . . 5
5. Limitations . . . . . . . . . . . . . . . . . . . . . . . . . 5 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 . . . . . 6
6. Two Folding Strategies . . . . . . . . . . . . . . . . . . . 6 6. Two Folding Strategies . . . . . . . . . . . . . . . . . . . 6
6.1. Comparison . . . . . . . . . . . . . . . . . . . . . . . 6 6.1. Comparison . . . . . . . . . . . . . . . . . . . . . . . 6
6.2. Recommendation . . . . . . . . . . . . . . . . . . . . . 6 6.2. Recommendation . . . . . . . . . . . . . . . . . . . . . 7
7. The Single Backslash Strategy ('\') . . . . . . . . . . . . . 6 7. The Single Backslash Strategy ('\') . . . . . . . . . . . . . 7
7.1. Folded Structure . . . . . . . . . . . . . . . . . . . . 6 7.1. Folded Structure . . . . . . . . . . . . . . . . . . . . 7
7.1.1. Header . . . . . . . . . . . . . . . . . . . . . . . 6 7.1.1. Header . . . . . . . . . . . . . . . . . . . . . . . 7
7.1.2. Body . . . . . . . . . . . . . . . . . . . . . . . . 7 7.1.2. Body . . . . . . . . . . . . . . . . . . . . . . . . 7
7.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 7 7.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 7
7.2.1. Folding . . . . . . . . . . . . . . . . . . . . . . . 7 7.2.1. Folding . . . . . . . . . . . . . . . . . . . . . . . 8
7.2.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . 9 7.2.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . 9
8. The Double Backslash Strategy ('\\') . . . . . . . . . . . . 9 8. The Double Backslash Strategy ('\\') . . . . . . . . . . . . 10
8.1. Folded Structure . . . . . . . . . . . . . . . . . . . . 9 8.1. Folded Structure . . . . . . . . . . . . . . . . . . . . 10
8.1.1. Header . . . . . . . . . . . . . . . . . . . . . . . 9 8.1.1. Header . . . . . . . . . . . . . . . . . . . . . . . 10
8.1.2. Body . . . . . . . . . . . . . . . . . . . . . . . . 10 8.1.2. Body . . . . . . . . . . . . . . . . . . . . . . . . 10
8.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 10 8.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 10
8.2.1. Folding . . . . . . . . . . . . . . . . . . . . . . . 10 8.2.1. Folding . . . . . . . . . . . . . . . . . . . . . . . 11
8.2.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . 12 8.2.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . 12
9. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 12 9. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 12
9.1. Example Showing Boundary Conditions . . . . . . . . . . . 12 9.1. Example Showing Boundary Conditions . . . . . . . . . . . 13
9.1.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 12 9.1.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 13
9.1.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 13 9.1.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 13
9.2. Example Showing Multiple Wraps of a Single Line . . . . . 13 9.2. Example Showing Multiple Wraps of a Single Line . . . . . 13
9.2.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 13 9.2.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 14
9.2.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 14 9.2.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 14
9.3. Example Showing "Smart" Folding . . . . . . . . . . . . . 14 9.3. Example Showing "Smart" Folding . . . . . . . . . . . . . 14
9.3.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 14 9.3.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 14
9.3.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 15 9.3.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 15
9.4. Example Showing "Forced" Folding . . . . . . . . . . . . 16 9.4. Example Showing "Forced" Folding . . . . . . . . . . . . 16
9.4.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 17 9.4.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 17
9.4.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 17 9.4.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 17
10. Security Considerations . . . . . . . . . . . . . . . . . . . 17 10. Security Considerations . . . . . . . . . . . . . . . . . . . 18
11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 18 11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 18
12. References . . . . . . . . . . . . . . . . . . . . . . . . . 18 12. References . . . . . . . . . . . . . . . . . . . . . . . . . 18
12.1. Normative References . . . . . . . . . . . . . . . . . . 18 12.1. Normative References . . . . . . . . . . . . . . . . . . 18
12.2. Informative References . . . . . . . . . . . . . . . . . 18 12.2. Informative References . . . . . . . . . . . . . . . . . 18
Appendix A. POSIX Shell Script: rfcfold . . . . . . . . . . . . 20 Appendix A. Bash Shell Script: rfcfold . . . . . . . . . . . . . 20
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 29 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 29
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 29 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 29
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. Many times the example text or code exceeds the 72 fragments. Many times the example text or code exceeds the 72
character line-length limit. The `xml2rfc` utility does not attempt character line-length limit. The `xml2rfc` [xml2rfc] utility, at the
to wrap the content of such inclusions, simply issuing a warning time of this document's publication, does not attempt to wrap the
whenever lines exceed 69 characters. According to the RFC Editor, content of such inclusions, simply issuing a warning whenever lines
there is currently no convention in place for how to handle long exceed 69 characters. Historically, there has been no RFC-Editor-
lines in such inclusions, other than advising authors to clearly recommended convention in place for how to handle long lines in such
indicate what manipulation has occurred. inclusions, other than advising authors to clearly indicate what
manipulation has occurred.
This document defines two strategies for handling long lines in This document defines two strategies for handling long lines in
width-bounded text content. One strategy is based on the historic width-bounded text content. One strategy is based on the historical
use of a single backslash ('\') character to indicate where line- use of a single backslash ('\') character to indicate where line-
folding has occurred, with the continuation occurring with the first folding has occurred, with the continuation occurring with the first
non-space (' ') character on the next line. The second strategy non-space (' ') character on the next line. The second strategy
extends the first strategy by adding a second backslash character to extends the first strategy by adding a second backslash character to
identify where the continuation begins and thereby able to handle identify where the continuation begins and thereby able to handle
cases not supported by the first strategy. Both strategies use a cases not supported by the first strategy. Both strategies use a
self-describing header enabling automated reconstitution of the self-describing header enabling automated reconstitution of the
original content. original content.
The strategies defined in this document work on any text content, but The strategies defined in this document work on any text content, but
skipping to change at page 4, line 33 skipping to change at page 4, line 45
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
capitals, as shown here. capitals, as shown here.
4. Goals 4. Goals
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 drafts
compilations that entail a) validation of source input files (e.g., that are dynamically compiled to include content with potentially
XML, JSON, ABNF, ASN.1) and/or b) dynamic generation of output, using unconstrained line lengths. For instance, the build process may wish
a tool that doesn't observe line lengths, that is stitched into the to include content from other local files or dynamically generated by
final document to be submitted. some external process. Both of these cases are discussed next.
Generally, in order for tooling to be able to process input files, Many drafts need to include the content from local files (e.g., XML,
the files must be in their original/natural state, which may entail JSON, ABNF, ASN.1). Prior to including a file's content, the build
them having some long lines. Thus, these source files need to be process SHOULD first validate these source files using format-
modified before inclusion in the document in order to satisfy the specific validators. In order for such tooling to be able to process
line length limits. This modification SHOULD be automated to reduce the files, the files must be in their original/natural state, which
effort and errors resulting from manual processing. may entail them having some long lines. Thus, these source files
need to be folded before inclusion into the XML document, in order to
satisfy `xml2rfc` line length limits.
Similarly, dynamically generated output (e.g., tree diagrams) must Similarly, drafts sometimes contain dynamically generated output,
also be modified, if necessary, in order for the resulting document typically from an external process operating on the same source files
to satisfy the line length limits. This work should also be discussed in the previous paragraph. For instance, such processes
automated to reduce effort and errors resulting from manual may translate the input format to another format or render a report
processing. over or a view of the input file. In some cases, the dynamically
generated output may contain lines exceeding the `xml2rfc` line
length limits.
In both cases, folding is required and SHOULD be automated to reduce
effort and errors resulting from manual processing.
4.2. Automated Reconstitution of the Original Text Content 4.2. Automated Reconstitution of the Original Text Content
Automated reconstitution of the exact original text content is needed Automated reconstitution of the exact original text content is needed
to support validation of text-based content extracted from documents. to support validation of text-based content extracted from documents.
For instance, already YANG [RFC7950] modules are extracted from For instance, already YANG [RFC7950] modules are extracted from
Internet-Drafts and validated as part of the draft-submission Internet-Drafts and validated as part of the draft-submission
process. Additionally, the desire to validate instance examples process. Additionally, the desire to validate instance examples
(i.e., XML/JSON documents) contained within Internet-Drafts has been (i.e., XML/JSON documents) contained within Internet-Drafts has been
skipping to change at page 7, line 27 skipping to change at page 7, line 46
readability. readability.
7.1.2. Body 7.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 are considered "folded". a line are considered "folded".
Really long lines may be folded multiple times. Exceptionally long lines may be folded multiple times.
7.2. Algorithm 7.2. Algorithm
This section describes a process for folding and unfolding long lines This section describes a process for folding and unfolding long lines
when they are encountered in text content. when they are encountered in text content.
The steps are complete, but implementations MAY achieve the same The steps are complete, but implementations MAY achieve the same
result in other ways. result in other ways.
When a larger document contains multiple instances of text content When a larger document contains multiple instances of text content
skipping to change at page 8, line 41 skipping to change at page 9, line 12
before or at the desired maximum column, and MUST NOT be chosen before or at the desired maximum column, and MUST NOT be chosen
such that the character immediately after the fold is a space (' such that the character immediately after the fold is a space ('
') character. For forced foldings, the location is between the ') character. For forced foldings, the location is between the
'\' and the end of line sequence. If no such location can be '\' and the end of line sequence. If no such location can be
found, then exit (this text content cannot be folded). found, then exit (this text content cannot be folded).
2. At the location where the fold is to occur, insert a backslash 2. At the location where the fold is to occur, insert a backslash
('\') character followed by the end of line character sequence. ('\') character followed by the end of line character sequence.
3. On the following line, insert any number of space (' ') 3. On the following line, insert any number of space (' ')
characters. characters, subject to the resulting line not exceeding the
desired maximum.
The result of the previous operation is that the next line starts The result of the previous operation is that the next line starts
with an arbitrary number of space (' ') characters, followed by the with an arbitrary number of space (' ') characters, followed by the
character that was previously occupying the position where the fold character that was previously occupying the position where the fold
occurred. 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.
skipping to change at page 10, line 18 skipping to change at page 10, line 40
8.1.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. Exceptionally long lines may be folded multiple times.
8.2. Algorithm 8.2. Algorithm
This section describes a process for folding and unfolding long lines This section describes a process for folding and unfolding long lines
when they are encountered in text content. when they are encountered in text content.
The steps are complete, but implementations MAY achieve the same The steps are complete, but implementations MAY achieve the same
result in other ways. result in other ways.
When a larger document contains multiple instances of text content When a larger document contains multiple instances of text content
skipping to change at page 11, line 36 skipping to change at page 12, line 6
1. Determine where the fold will occur. This location MUST be 1. Determine where the fold will occur. This location MUST be
before or at the desired maximum column. For forced foldings, before or at the desired maximum column. For forced foldings,
the location is between the '\' and the end of line sequence on the location is between the '\' and the end of line sequence on
the first line. the first line.
2. At the location where the fold is to occur, insert a first 2. At the location where the fold is to occur, insert a first
backslash ('\') character followed by the end of line character backslash ('\') character followed by the end of line character
sequence. sequence.
3. On the following line, insert any number of space (' ') 3. On the following line, insert any number of space (' ')
characters followed by a second backslash ('\') character. characters, subject to the resulting line not exceeding the
desired maximum, followed by a second backslash ('\') character.
The result of the previous operation is that the next line starts 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 occupying the position where the fold occurred. 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.
skipping to change at page 18, line 24 skipping to change at page 18, line 46
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>.
12.2. Informative References 12.2. Informative References
[bash] "GNU Bash Manual",
<https://www.gnu.org/software/bash/manual>.
[pyang] "An extensible YANG (RFC 6020/7950) validator.", [pyang] "An extensible YANG (RFC 6020/7950) validator.",
<https://pypi.org/project/pyang/>. <https://pypi.org/project/pyang/>.
[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>.
skipping to change at page 19, line 5 skipping to change at page 19, line 28
RFC 7994, DOI 10.17487/RFC7994, December 2016, RFC 7994, DOI 10.17487/RFC7994, December 2016,
<https://www.rfc-editor.org/info/rfc7994>. <https://www.rfc-editor.org/info/rfc7994>.
[RFC8340] Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams", [RFC8340] Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams",
BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018,
<https://www.rfc-editor.org/info/rfc8340>. <https://www.rfc-editor.org/info/rfc8340>.
[xiax] "The `xiax` Python Package", [xiax] "The `xiax` Python Package",
<https://pypi.org/project/xiax/>. <https://pypi.org/project/xiax/>.
[xml2rfc] "Xml2rfc generates RFCs and IETF drafts from document
source in XML according to the IETF xml2rfc v2 and v3
vocabularies.", <https://pypi.org/project/xml2rfc/>.
[yang-doctors-thread] [yang-doctors-thread]
"[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>.
[yanglint] [yanglint]
"A feature-rich tool for validation and conversion of the "A feature-rich tool for validation and conversion of the
schemas and YANG modeled data.", schemas and YANG modeled data.",
<https://github.com/CESNET/libyang#yanglint>. <https://github.com/CESNET/libyang#yanglint>.
Appendix A. POSIX Shell Script: rfcfold Appendix A. Bash Shell Script: rfcfold
This non-normative appendix section includes a shell script that can This non-normative appendix section includes a Bash [bash] shell
both fold and unfold text content using both the single and double script that can both fold and unfold text content using both the
backslash strategies described in Section 7 and Section 8 single and double backslash strategies described in Section 7 and
respectively. Section 8 respectively.
This script is intended to be applied to a single text content This script is intended to be applied to a single text content
instance. If it is desired to fold or unfold text content instances instance. If it is desired to fold or unfold text content instances
within a larger document (e.g., an Internet draft or RFC), then within a larger document (e.g., an Internet draft or RFC), then
another tool must be used to extract the content from the larger another tool must be used to extract the content from the larger
document before utilizing this script. document before utilizing this script.
For readability purposes, this script forces the minimally supported For readability purposes, this script forces the minimally supported
line length to be eight characters longer than the raw header text line length to be eight characters longer than the raw header text
defined in Section 7.1.1 and Section 8.1.1 so as to ensure that the defined in Section 7.1.1 and Section 8.1.1 so as to ensure that the
header can be wrapped by a space (' ') character and three equal header can be wrapped by a space (' ') character and three equal
('=') characters on each side of the raw header text. ('=') characters on each side of the raw header text.
This script does not implement the whitespace-avoidance logic This script does not implement the whitespace-avoidance logic
described in Section 7.2.1. In such case, the script will exit with described in Section 7.2.1. In such case, the script will exit with
one of the following message: one of the following message:
Error: infile has a space character occuring on the Error: infile has a space character occurring on the
folding column. This file cannot be folded using the folding column. This file cannot be folded using the
'\' strategy. '\' strategy.
While this script can unfold input that contains forced foldings, it While this script can unfold input that contains forced foldings, it
unable to fold files that would require forced foldings. Forced is unable to fold files that would require forced foldings. Forced
folding is described in Section 7.2.1 and Section 8.2.1. When being folding is described in Section 7.2.1 and Section 8.2.1. When being
asked to fold a file that would require forced folding, the script asked to fold a file that would require forced folding, the script
will instead exit with one of the following messages: will instead exit with one of the following messages:
Error: infile has a line ending with a '\' character. Error: infile has a line ending with a '\' character.
This file cannot be folded using the '\' strategy without This file cannot be folded using the '\' strategy without
there being false positives produced in the unfolding there being false positives produced in the unfolding
(i.e., this script does not attempt to proactively (i.e., this script does not force-fold such lines, as
force-fold such lines, as described in RFC XXXX). described in BCP XXX, RFC XXXX).
Error: infile has a line ending with a '\' character Error: infile has a line ending with a '\' character
followed by a '\' character as the first non-space followed by a '\' character as the first non-space
character on the next line. This script cannot fold character on the next line. This script cannot fold
this file using '\\' strategy without there being this file using '\\' strategy without there being
false positives produced in the unfolding (i.e., this false positives produced in the unfolding (i.e., this
script does not attempt to proactively force-fold such script does not force-fold such lines, as described
lines, as described in RFC XXXX). in BCP XXX, RFC XXXX).
Shell-level end-of-line backslash ('\') characters have been Shell-level end-of-line backslash ('\') characters have been
purposely added to the script so as to ensure that the script is purposely added to the script so as to ensure that the script is
itself not folded in this document, thus simplify the ability to itself not folded in this document, thus simplifying the ability to
copy/paste the script for local use. As should be evident by the copy/paste the script for local use. As should be evident by the
lack of the mandatory header described in Section 7.1.1, these lack of the mandatory header described in Section 7.1.1, these
backslashes do not designate a folded line, such as described in backslashes do not designate a folded line, such as described in
Section 7. Section 7.
<CODE BEGINS> <CODE BEGINS>
========== NOTE: '\\' line wrapping per BCP XXX (RFC XXXX) ==========
#!/bin/bash --posix #!/bin/bash --posix
# This script may need some adjustments to work on a given system. # This script may need some adjustments to work on a given system.
# For instance, the utilities `pcregrep` and `gsed` may need to # For instance, the utilities `pcregrep` and `gsed` may need to
# be installed. Also, please be advised that `bash` (not `sh`) # be installed. Also, please be advised that `bash` (not `sh`)
# must be used. # must be used.
# Copyright (c) 2019 IETF Trust, Kent Watsen, and Erik Auerswald. # Copyright (c) 2019 IETF Trust, Kent Watsen, and Erik Auerswald.
# All rights reserved. # All rights reserved.
# #
skipping to change at page 22, line 11 skipping to change at page 22, line 13
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
print_usage() { print_usage() {
printf "\n" printf "\n"
printf "Folds or unfolds the input text file according to BCP XXX" printf "Folds or unfolds the input text file according to BCP XXX"
printf " (RFC XXXX).\n" printf " (RFC XXXX).\n"
printf "\n" printf "\n"
printf "Usage: rfcfold [-s <strategy>] [-c <col>] [-r] -i <infile>" printf "Usage: rfcfold [-h] [-d] [-q] [-s <strategy>] [-c <col>]"
printf " -o <outfile>\n" printf " [-r] -i <infile> -o <outfile>\n"
printf "\n" printf "\n"
printf " -s: strategy to use, '1' or '2' (default: try 1," printf " -s: strategy to use, '1' or '2' (default: try 1,"
printf " else 2)\n" printf " else 2)\n"
printf " -c: column to fold on (default: 69)\n" printf " -c: column to fold on (default: 69)\n"
printf " -r: reverses the operation\n" printf " -r: reverses the operation\n"
printf " -i: the input filename\n" printf " -i: the input filename\n"
printf " -o: the output filename\n" printf " -o: the output filename\n"
printf " -d: show debug messages\n" printf " -d: show debug messages\n"
printf " -q: quiet (suppress error messages)\n" printf " -q: quiet (suppress error messages)\n"
printf " -h: show this message\n" printf " -h: show this message\n"
skipping to change at page 22, line 49 skipping to change at page 23, line 4
space_chars=" " space_chars=" "
temp_dir="" temp_dir=""
# determine name of [g]sed binary # determine name of [g]sed binary
type gsed > /dev/null 2>&1 && SED=gsed || SED=sed type gsed > /dev/null 2>&1 && SED=gsed || SED=sed
# warn if a non-GNU sed utility is used # warn if a non-GNU sed utility is used
"$SED" --version < /dev/null 2> /dev/null \ "$SED" --version < /dev/null 2> /dev/null \
| grep GNU >/dev/null 2>&1 || \ | grep GNU >/dev/null 2>&1 || \
echo 'Warning: not using GNU `sed` (likely cause if an error occurs)' echo 'Warning: not using GNU `sed` (likely cause if an error occurs)'
# verify the availability of pcregrep # verify the availability of pcregrep
type pcregrep > /dev/null 2>&1 || { type pcregrep >> /dev/null 2>&1 || {
printf '\nError: missing utility `pcregrep`\n' printf '\nError: missing utility `pcregrep`\n'
exit 1 exit 1
} }
cleanup() { cleanup() {
rm -rf "$temp_dir" rm -rf "$temp_dir"
} }
trap 'cleanup' EXIT trap 'cleanup' EXIT
fold_it_1() { fold_it_1() {
# 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 -q -M "\\\\\n" "$infile"
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
if [[ $quiet -eq 0 ]]; then if [[ $quiet -eq 0 ]]; then
echo echo
echo "Error: infile $infile has a line ending with a '\\'" echo "Error: infile has a line ending with a '\\' character."
echo "character. This file cannot be folded using the '\\'" echo "This file cannot be folded using the '\\' strategy"
echo "strategy without there being false positives produced" echo "without there being false positives produced in the"
echo "in the unfolding (i.e., this script does not attempt" echo "unfolding (i.e., this script does not force-fold"
echo "to proactively force-fold such lines, as described" echo "such lines, as described in BCP XXX, RFC XXXX)."
echo "in RFC XXXX)."
echo echo
fi fi
return 1 return 1
fi fi
# where to fold # where to fold
foldcol=`expr "$maxcol" - 1` # for the inserted '\' char foldcol=`expr "$maxcol" - 1` # for the inserted '\' char
# ensure input file doesn't contain whitespace on the fold column # ensure input file doesn't contain whitespace on the fold column
grep "^.\{$foldcol\} " $infile >> /dev/null 2>&1 grep -q "^.\{$foldcol\} " "$infile"
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
if [[ $quiet -eq 0 ]]; then if [[ $quiet -eq 0 ]]; then
echo echo
echo "Error: infile has a space character occuring on the" echo "Error: infile has a space character occurring on the"
echo "folding column. This file cannot be folded using the" echo "folding column. This file cannot be folded using the"
echo "'\\' strategy." echo "'\\' strategy."
echo echo
fi fi
return 1 return 1
fi fi
# center header text # center header text
length=`expr ${#hdr_txt_1} + 2` length=`expr ${#hdr_txt_1} + 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_1" "$right_sp" "$equal_chars"` "$hdr_txt_1" "$right_sp" "$equal_chars"`
# generate outfile # generate outfile
echo "$header" > $outfile echo "$header" > "$outfile"
echo "" >> $outfile echo "" >> "$outfile"
"$SED" 's/\(.\{'"$foldcol"'\}\)\(..\)/\1\\\n\2/;t M;b;:M;P;D;'\ "$SED" 's/\(.\{'"$foldcol"'\}\)\(..\)/\1\\\n\2/;t M;b;:M;P;D;'\
< $infile >> $outfile 2>/dev/null < "$infile" >> "$outfile" 2>/dev/null
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
return 1 return 1
fi fi
return 0 return 0
} }
fold_it_2() { fold_it_2() {
# where to fold # where to fold
foldcol=`expr "$maxcol" - 1` # for the inserted '\' char foldcol=`expr "$maxcol" - 1` # for the inserted '\' char
# 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 -q -M "\\\\\n[\ ]*\\\\" "$infile"
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
if [[ $quiet -eq 0 ]]; then if [[ $quiet -eq 0 ]]; then
echo echo
echo "Error: infile has a line ending with a '\\' character" echo "Error: 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 script cannot fold" echo "character on the next line. This script cannot fold"
echo "this file using '\\\\' strategy without there being" echo "this file using '\\\\' strategy without there being"
echo "false positives produced in the unfolding (i.e., this" echo "false positives produced in the unfolding (i.e., this"
echo "script does not attempt to proactively force-fold such" echo "script does not force-fold such lines, as described"
echo "lines, as described in RFC XXXX)." echo "in BCP XXX, RFC XXXX)."
echo echo
fi fi
return 1 return 1
fi fi
# center header text # center header text
length=`expr ${#hdr_txt_2} + 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_2" "$right_sp" "$equal_chars"` "$hdr_txt_2" "$right_sp" "$equal_chars"`
# generate outfile # generate outfile
echo "$header" > $outfile echo "$header" > "$outfile"
echo "" >> $outfile echo "" >> "$outfile"
"$SED" 's/\(.\{'"$foldcol"'\}\)\(..\)/\1\\\n\\\2/;t M;b;:M;P;D;'\ "$SED" 's/\(.\{'"$foldcol"'\}\)\(..\)/\1\\\n\\\2/;t M;b;:M;P;D;'\
< $infile >> $outfile 2>/dev/null < "$infile" >> "$outfile" 2>/dev/null
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
return 1 return 1
fi fi
return 0 return 0
} }
fold_it() { fold_it() {
# ensure input file doesn't contain a TAB # ensure input file doesn't contain a TAB
grep $'\t' $infile >> /dev/null 2>&1 grep -q $'\t' "$infile"
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
if [[ $quiet -eq 0 ]]; then if [[ $quiet -eq 0 ]]; then
echo echo
echo "Error: infile contains a TAB character, which is" echo "Error: infile contains a TAB character, which is"
echo "not allowed." echo "not allowed."
echo echo
fi fi
return 1 return 1
fi fi
# check if file needs folding # check if file needs folding
testcol=`expr "$maxcol" + 1` testcol=`expr "$maxcol" + 1`
grep ".\{$testcol\}" $infile >> /dev/null 2>&1 grep -q ".\{$testcol\}" "$infile"
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 if [[ $strategy -eq 1 ]]; then
fold_it_1 fold_it_1
return $? return $?
fi fi
if [[ $strategy -eq 2 ]]; then if [[ $strategy -eq 2 ]]; then
fold_it_2 fold_it_2
return $? return $?
skipping to change at page 26, line 4 skipping to change at page 26, line 6
quiet=$quiet_sav quiet=$quiet_sav
if [[ $result -ne 0 ]]; then if [[ $result -ne 0 ]]; then
if [[ $debug -eq 1 ]]; then if [[ $debug -eq 1 ]]; then
echo "Folding strategy 1 didn't succeed, trying strategy 2..." echo "Folding strategy 1 didn't succeed, trying strategy 2..."
fi fi
fold_it_2 fold_it_2
return $? return $?
fi fi
return 0 return 0
} }
unfold_it_1() { unfold_it_1() {
temp_dir=`mktemp -d` temp_dir=`mktemp -d`
# output all but the first two lines (the header) to wip file # output all but the first two lines (the header) to wip file
awk "NR>2" $infile > $temp_dir/wip awk "NR>2" "$infile" > "$temp_dir/wip"
# unfold wip file # unfold wip file
"$SED" '{H;$!d};x;s/^\n//;s/\\\n *//g' $temp_dir/wip > $outfile "$SED" '{H;$!d};x;s/^\n//;s/\\\n *//g' "$temp_dir/wip" > "$outfile"
return 0 return 0
} }
unfold_it_2() { unfold_it_2() {
temp_dir=`mktemp -d` temp_dir=`mktemp -d`
# output all but the first two lines (the header) to wip file # output all but the first two lines (the header) to wip file
awk "NR>2" $infile > $temp_dir/wip awk "NR>2" "$infile" > "$temp_dir/wip"
# unfold wip file # unfold wip file
"$SED" '{H;$!d};x;s/^\n//;s/\\\n *\\//g' $temp_dir/wip > $outfile "$SED" '{H;$!d};x;s/^\n//;s/\\\n *\\//g' "$temp_dir/wip" > "$outfi\
\le"
return 0 return 0
} }
unfold_it() { unfold_it() {
# check if file needs unfolding # check if file needs unfolding
line=`head -n 1 $infile` line=`head -n 1 "$infile"`
line2=`$SED -n '2p' $infile` line2=`$SED -n '2p' "$infile"`
result=`echo $line | fgrep "$hdr_txt_1"` result=`echo "$line" | fgrep "$hdr_txt_1"`
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
if [ -n "$line2" ]; then if [ -n "$line2" ]; then
if [[ $quiet -eq 0 ]]; then if [[ $quiet -eq 0 ]]; then
echo "Error: the second line is not empty." echo "Error: the second line is not empty."
fi fi
return 1 return 1
fi fi
unfold_it_1 unfold_it_1
return $? return $?
fi fi
skipping to change at page 26, line 48 skipping to change at page 27, line 4
return 1 return 1
fi fi
unfold_it_1 unfold_it_1
return $? return $?
fi fi
result=`echo $line | fgrep "$hdr_txt_2"` result=`echo $line | fgrep "$hdr_txt_2"`
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
if [ -n "$line2" ]; then if [ -n "$line2" ]; then
if [[ $quiet -eq 0 ]]; then if [[ $quiet -eq 0 ]]; then
echo "Error: the second line is not empty." echo "Error: the second line is not empty."
fi fi
return 1 return 1
fi fi
unfold_it_2 unfold_it_2
return $? return $?
fi fi
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
} }
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 0 exit 0
fi fi
if [ "$1" == "-d" ]; then if [ "$1" == "-d" ]; then
skipping to change at page 28, line 28 skipping to change at page 28, line 31
if [[ ! -f "$infile" ]]; then if [[ ! -f "$infile" ]]; then
if [[ $quiet -eq 0 ]]; then if [[ $quiet -eq 0 ]]; 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
fi fi
if [[ $strategy -eq 2 ]]; then if [[ $strategy -eq 2 ]]; then
min_supported=`expr ${#hdr_txt_2} + 8` min_supported=`expr ${#hdr_txt_2} + 9`
else else
min_supported=`expr ${#hdr_txt_1} + 8` min_supported=`expr ${#hdr_txt_1} + 9`
fi fi
if [[ $maxcol -lt $min_supported ]]; then if [[ $maxcol -lt $min_supported ]]; then
if [[ $quiet -eq 0 ]]; then if [[ $quiet -eq 0 ]]; then
echo printf "\nError: the folding column cannot be less than"
echo "Error: the folding column cannot be less than" printf " $min_supported.\n\n"
echo "$min_supported."
echo
fi fi
exit 1 exit 1
fi fi
# this is only because the code otherwise runs out of equal_chars # this is only because the code otherwise runs out of equal_chars
max_supported=`expr ${#equal_chars} + 1 + ${#hdr_txt_1} + 1\ 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
if [[ $quiet -eq 0 ]]; then if [[ $quiet -eq 0 ]]; then
echo printf "\nError: the folding column cannot be more than"
echo "Error: the folding column cannot be more than" printf " $max_supported.\n\n"
echo "$max_supported."
echo
fi fi
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
} }
main "$@" main "$@"
<CODE ENDS> <CODE ENDS>
Acknowledgements Acknowledgements
The authors thank the RFC Editor for confirming that there was The authors thank the RFC Editor for confirming that there was
previously no set convention for handling long lines in sourcecode previously no set convention, at the time of this document's
inclusions, thus instigating this work. publication, for handling long lines in source code inclusions, thus
instigating this work.
The authors thank the following folks for their various contributions The authors thank the following folks for their various contributions
while producing this document (sorted by first name): Benoit Claise, while producing this document (sorted by first name): Benoit Claise,
Erik Auerswald, Gianmarco Bruno, Italo Busi, Joel Jaeggli, Jonathan Erik Auerswald, Gianmarco Bruno, Italo Busi, Joel Jaeggli, Jonathan
Hansford, Lou Berger, Martin Bjorklund, and Rob Wilton. Hansford, Lou Berger, Martin Bjorklund, and Rob Wilton.
Special acknowledgement to Erik Auerswald for his contributions to Special acknowledgement to Erik Auerswald for his contributions to
the `rfcfold` script, especially for greatly improving the `sed` one- the `rfcfold` script, especially for greatly improving the `sed` one-
liners used therein. liners used therein.
 End of changes. 68 change blocks. 
113 lines changed or deleted 140 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/