idnits 2.17.1 draft-ietf-netmod-artwork-folding-11.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (November 3, 2019) is 1635 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Obsolete informational reference (is this intentional?): RFC 7749 (Obsoleted by RFC 7991) Summary: 0 errors (**), 0 flaws (~~), 1 warning (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 NETMOD Working Group K. Watsen 3 Internet-Draft Watsen Networks 4 Intended status: Informational E. Erik 5 Expires: May 6, 2020 Individual Contributor 6 A. Farrel 7 Old Dog Consulting 8 Q. Wu 9 Huawei Technologies 10 November 3, 2019 12 Handling Long Lines in Inclusions in Internet-Drafts and RFCs 13 draft-ietf-netmod-artwork-folding-11 15 Abstract 17 This document defines two strategies for handling long lines in 18 width-bounded text content. One strategy is based on the historical 19 use of a single backslash ('\') character to indicate where line- 20 folding has occurred, with the continuation occurring with the first 21 non-space (' ') character on the next line. The second strategy 22 extends the first strategy by adding a second backslash character to 23 identify where the continuation begins and is thereby able to handle 24 cases not supported by the first strategy. Both strategies use a 25 self-describing header enabling automated reconstitution of the 26 original content. 28 Editorial Note (To be removed by RFC Editor) 30 Please be aware that this document uses throughout the five-character 31 text sequence located between the following two double-quotes: "(' 32 ')". It has been observed that some renderings of this text sequence 33 produces a natural line break at the space character in the middle, 34 thus causing "('" to appear at the end of the first line and "')" to 35 appear at the beginning of the next line. Such a line-break is 36 confusing and should not occur in the RFC output formats. 38 Status of This Memo 40 This Internet-Draft is submitted in full conformance with the 41 provisions of BCP 78 and BCP 79. 43 Internet-Drafts are working documents of the Internet Engineering 44 Task Force (IETF). Note that other groups may also distribute 45 working documents as Internet-Drafts. The list of current Internet- 46 Drafts is at https://datatracker.ietf.org/drafts/current/. 48 Internet-Drafts are draft documents valid for a maximum of six months 49 and may be updated, replaced, or obsoleted by other documents at any 50 time. It is inappropriate to use Internet-Drafts as reference 51 material or to cite them other than as "work in progress." 53 This Internet-Draft will expire on May 6, 2020. 55 Copyright Notice 57 Copyright (c) 2019 IETF Trust and the persons identified as the 58 document authors. All rights reserved. 60 This document is subject to BCP 78 and the IETF Trust's Legal 61 Provisions Relating to IETF Documents 62 (https://trustee.ietf.org/license-info) in effect on the date of 63 publication of this document. Please review these documents 64 carefully, as they describe your rights and restrictions with respect 65 to this document. Code Components extracted from this document must 66 include Simplified BSD License text as described in Section 4.e of 67 the Trust Legal Provisions and are provided without warranty as 68 described in the Simplified BSD License. 70 Table of Contents 72 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 73 2. Applicability Statement . . . . . . . . . . . . . . . . . . . 4 74 3. Requirements Language . . . . . . . . . . . . . . . . . . . . 4 75 4. Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 76 4.1. Automated Folding of Long Lines in Text Content . . . . . 4 77 4.2. Automated Reconstitution of the Original Text Content . . 5 78 5. Limitations . . . . . . . . . . . . . . . . . . . . . . . . . 5 79 5.1. Not Recommended for Graphical Artwork . . . . . . . . . . 5 80 5.2. Doesn't Work as Well as Format-Specific Options . . . . . 6 81 6. Two Folding Strategies . . . . . . . . . . . . . . . . . . . 6 82 6.1. Comparison . . . . . . . . . . . . . . . . . . . . . . . 6 83 6.2. Recommendation . . . . . . . . . . . . . . . . . . . . . 7 84 7. The Single Backslash Strategy ('\') . . . . . . . . . . . . . 7 85 7.1. Folded Structure . . . . . . . . . . . . . . . . . . . . 7 86 7.1.1. Header . . . . . . . . . . . . . . . . . . . . . . . 7 87 7.1.2. Body . . . . . . . . . . . . . . . . . . . . . . . . 7 88 7.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 7 89 7.2.1. Folding . . . . . . . . . . . . . . . . . . . . . . . 8 90 7.2.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . 9 91 8. The Double Backslash Strategy ('\\') . . . . . . . . . . . . 10 92 8.1. Folded Structure . . . . . . . . . . . . . . . . . . . . 10 93 8.1.1. Header . . . . . . . . . . . . . . . . . . . . . . . 10 94 8.1.2. Body . . . . . . . . . . . . . . . . . . . . . . . . 10 95 8.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 10 96 8.2.1. Folding . . . . . . . . . . . . . . . . . . . . . . . 11 97 8.2.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . 12 98 9. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 12 99 9.1. Example Showing Boundary Conditions . . . . . . . . . . . 13 100 9.1.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 13 101 9.1.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 13 102 9.2. Example Showing Multiple Wraps of a Single Line . . . . . 13 103 9.2.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 14 104 9.2.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 14 105 9.3. Example Showing "Smart" Folding . . . . . . . . . . . . . 14 106 9.3.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 14 107 9.3.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 15 108 9.4. Example Showing "Forced" Folding . . . . . . . . . . . . 16 109 9.4.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 17 110 9.4.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 17 111 10. Security Considerations . . . . . . . . . . . . . . . . . . . 18 112 11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 18 113 12. References . . . . . . . . . . . . . . . . . . . . . . . . . 18 114 12.1. Normative References . . . . . . . . . . . . . . . . . . 18 115 12.2. Informative References . . . . . . . . . . . . . . . . . 19 116 Appendix A. Bash Shell Script: rfcfold . . . . . . . . . . . . . 20 117 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 29 118 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 30 120 1. Introduction 122 [RFC7994] sets out the requirements for plain-text RFCs and states 123 that each line of an RFC (and hence of an Internet-Draft) must be 124 limited to 72 characters followed by the character sequence that 125 denotes an end-of-line (EOL). 127 Internet-Drafts and RFCs often include example text or code 128 fragments. Many times the example text or code exceeds the 72 129 character line-length limit. The `xml2rfc` [xml2rfc] utility, at the 130 time of this document's publication, does not attempt to wrap the 131 content of such inclusions, simply issuing a warning whenever lines 132 exceed 69 characters. Historically, there has been no RFC-Editor- 133 recommended convention in place for how to handle long lines in such 134 inclusions, other than advising authors to clearly indicate what 135 manipulation has occurred. 137 This document defines two strategies for handling long lines in 138 width-bounded text content. One strategy is based on the historical 139 use of a single backslash ('\') character to indicate where line- 140 folding has occurred, with the continuation occurring with the first 141 non-space (' ') character on the next line. The second strategy 142 extends the first strategy by adding a second backslash character to 143 identify where the continuation begins and is thereby able to handle 144 cases not supported by the first strategy. Both strategies use a 145 self-describing header enabling automated reconstitution of the 146 original content. 148 The strategies defined in this document work on any text content, but 149 are primarily intended for a structured sequence of lines, such as 150 would be referenced by the element defined in 151 Section 2.48 of [RFC7991], rather than for two-dimensional imagery, 152 such as would be referenced by the element defined in 153 Section 2.5 of [RFC7991]. 155 Note that text files are represented as lines having their first 156 character in column 1, and a line length of N where the last 157 character is in the Nth column and is immediately followed by an end 158 of line character sequence. 160 2. Applicability Statement 162 The formats and algorithms defined in this document may be used in 163 any context, whether for IETF documents or in other situations where 164 structured folding is desired. 166 Within the IETF, this work primarily targets the xml2rfc v3 167 element (Section 2.48 of [RFC7991]) and the xml2rfc v2 168 element (Section 2.5 of [RFC7749]) that, for lack of a 169 better option, is currently used for both source code and artwork. 170 This work may also be used for the xml2rfc v3 element 171 (Section 2.5 of [RFC7991]) but, as described in Section 5.1, it is 172 generally not recommended. 174 3. Requirements Language 176 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 177 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 178 "OPTIONAL" in this document are to be interpreted as described in BCP 179 14 [RFC2119] [RFC8174] when, and only when, they appear in all 180 capitals, as shown here. 182 4. Goals 184 4.1. Automated Folding of Long Lines in Text Content 186 Automated folding of long lines is needed in order to support drafts 187 that are dynamically compiled to include content with potentially 188 unconstrained line lengths. For instance, the build process may wish 189 to include content from other local files or dynamically generated by 190 some external process. Both of these cases are discussed next. 192 Many drafts need to include the content from local files (e.g., XML, 193 JSON, ABNF, ASN.1). Prior to including a file's content, the build 194 process SHOULD first validate these source files using format- 195 specific validators. In order for such tooling to be able to process 196 the files, the files must be in their original/natural state, which 197 may entail them having some long lines. Thus, these source files 198 need to be folded before inclusion into the XML document, in order to 199 satisfy `xml2rfc` line length limits. 201 Similarly, drafts sometimes contain dynamically generated output, 202 typically from an external process operating on the same source files 203 discussed in the previous paragraph. For instance, such processes 204 may translate the input format to another format or render a report 205 over or a view of the input file. In some cases, the dynamically 206 generated output may contain lines exceeding the `xml2rfc` line 207 length limits. 209 In both cases, folding is required and SHOULD be automated to reduce 210 effort and errors resulting from manual processing. 212 4.2. Automated Reconstitution of the Original Text Content 214 Automated reconstitution of the exact original text content is needed 215 to support validation of text-based content extracted from documents. 217 For instance, already YANG [RFC7950] modules are extracted from 218 Internet-Drafts and validated as part of the draft-submission 219 process. Additionally, the desire to validate instance examples 220 (i.e., XML/JSON documents) contained within Internet-Drafts has been 221 discussed ([yang-doctors-thread]). 223 5. Limitations 225 5.1. Not Recommended for Graphical Artwork 227 While the solution presented in this document works on any kind of 228 text-based content, it is most useful on content that represents 229 source code (XML, JSON, etc.) or, more generally, on content that has 230 not been laid out in two dimensions (e.g., diagrams). 232 Fundamentally, the issue is whether the text content remains readable 233 once folded. Text content that is unpredictable is especially 234 susceptible to looking bad when folded; falling into this category 235 are most UML diagrams, YANG tree diagrams, and ASCII art in general. 237 It is NOT RECOMMENDED to use the solution presented in this document 238 on graphical artwork. 240 5.2. Doesn't Work as Well as Format-Specific Options 242 The solution presented in this document works generically for all 243 text-based content, as it only views content as plain text. However, 244 various formats sometimes have built-in mechanisms that are better 245 suited to prevent long lines. 247 For instance, both the `pyang` [pyang] and `yanglint` [yanglint] 248 utilities have the command line option "--tree-line-length" that can 249 be used to indicate a desired maximum line length for when generating 250 tree diagrams [RFC8340]. 252 In another example, some source formats (e.g., YANG [RFC7950]) allow 253 any quoted string to be broken up into substrings separated by a 254 concatenation character (e.g., '+'), any of which can be on a 255 different line. 257 It is RECOMMENDED that authors do as much as possible within the 258 selected format to avoid long lines. 260 6. Two Folding Strategies 262 This document defines two nearly identical strategies for folding 263 text-based content. 265 The Single Backslash Strategy ('\'): Uses a backslash ('\') 266 character at the end of the line where folding occurs, and 267 assumes that the continuation begins at the first character 268 that is not a space character (' ') on the following line. 270 The Double Backslash Strategy ('\\'): Uses a backslash ('\') 271 character at the end of the line where folding occurs, and 272 assumes that the continuation begins after a second backslash 273 ('\') character on the following line. 275 6.1. Comparison 277 The first strategy produces more readable output, however it is 278 significantly more likely to encounter unfoldable input (e.g., a long 279 line containing only space characters) and, for long lines that can 280 be folded, automation implementations may encounter scenarios that 281 will produce errors without special care. 283 The second strategy produces less readable output, but is unlikely to 284 encounter unfoldable input, there are no long lines that cannot be 285 folded, and no special care is required for when folding a long line. 287 6.2. Recommendation 289 It is RECOMMENDED for implementations to first attempt to fold 290 content using the single backslash strategy and, only in the unlikely 291 event that it cannot fold the input or the folding logic is unable to 292 cope with a contingency occurring on the desired folding column, then 293 fallback to the double backslash strategy. 295 7. The Single Backslash Strategy ('\') 297 7.1. Folded Structure 299 Text content that has been folded as specified by this strategy MUST 300 adhere to the following structure. 302 7.1.1. Header 304 The header is two lines long. 306 The first line is the following 46-character string that MAY be 307 surrounded by any number of printable characters. This first line 308 cannot itself be folded. 310 NOTE: '\' line wrapping per BCP XXX (RFC XXXX) 312 [Note to RFC Editor: Please replace XXX and XXXX with the numbers 313 assigned to this document and delete this note. Please make this 314 change in multiple places in this document.] 316 The second line is an empty line, containing only the end-of-line 317 character sequence. This line provides visual separation for 318 readability. 320 7.1.2. Body 322 The character encoding is the same as described in Section 2 of 323 [RFC7994], except that, per [RFC7991], tab characters are prohibited. 325 Lines that have a backslash ('\') occurring as the last character in 326 a line are considered "folded". 328 Exceptionally long lines may be folded multiple times. 330 7.2. Algorithm 332 This section describes a process for folding and unfolding long lines 333 when they are encountered in text content. 335 The steps are complete, but implementations MAY achieve the same 336 result in other ways. 338 When a larger document contains multiple instances of text content 339 that may need to be folded or unfolded, another process must insert/ 340 extract the individual text content instances to/from the larger 341 document prior to utilizing the algorithms described in this section. 342 For example, the `xiax` utility [xiax] does this. 344 7.2.1. Folding 346 Determine the desired maximum line length from input to the line- 347 wrapping process, such as from a command line parameter. If no value 348 is explicitly specified, the value "69" SHOULD be used. 350 Ensure that the desired maximum line length is not less than the 351 minimum header, which is 46 characters. If the desired maximum line 352 length is less than this minimum, exit (this text-based content 353 cannot be folded). 355 Scan the text content for horizontal tab characters. If any 356 horizontal tab characters appear, either resolve them to space 357 characters or exit, forcing the input provider to convert them to 358 space characters themselves first. 360 Scan the text content to ensure at least one line exceeds the desired 361 maximum. If no line exceeds the desired maximum, exit (this text 362 content does not need to be folded). 364 Scan the text content to ensure no existing lines already end with a 365 backslash ('\') character, as this could lead to an ambiguous result. 366 If such a line is found, and its width is less than the desired 367 maximum, then it SHOULD be flagged for forced folding (folding even 368 though unnecessary). If the folding implementation doesn't support 369 forced foldings, it MUST exit. 371 If this text content needs to and can be folded, insert the header 372 described in Section 7.1.1, ensuring that any additional printable 373 characters surrounding the header do not result in a line exceeding 374 the desired maximum. 376 For each line in the text content, from top-to-bottom, if the line 377 exceeds the desired maximum, or requires a forced folding, then fold 378 the line by: 380 1. Determine where the fold will occur. This location MUST be 381 before or at the desired maximum column, and MUST NOT be chosen 382 such that the character immediately after the fold is a space (' 383 ') character. For forced foldings, the location is between the 384 '\' and the end of line sequence. If no such location can be 385 found, then exit (this text content cannot be folded). 387 2. At the location where the fold is to occur, insert a backslash 388 ('\') character followed by the end of line character sequence. 390 3. On the following line, insert any number of space (' ') 391 characters, subject to the resulting line not exceeding the 392 desired maximum. 394 The result of the previous operation is that the next line starts 395 with an arbitrary number of space (' ') characters, followed by the 396 character that was previously occupying the position where the fold 397 occurred. 399 Continue in this manner until reaching the end of the text content. 400 Note that this algorithm naturally addresses the case where the 401 remainder of a folded line is still longer than the desired maximum, 402 and hence needs to be folded again, ad infinitum. 404 The process described in this section is illustrated by the 405 "fold_it_1()" function in Appendix A. 407 7.2.2. Unfolding 409 Scan the beginning of the text content for the header described in 410 Section 7.1.1. If the header is not present, exit (this text content 411 does not need to be unfolded). 413 Remove the 2-line header from the text content. 415 For each line in the text content, from top-to-bottom, if the line 416 has a backslash ('\') character immediately followed by the end of 417 line character sequence, then the line can be unfolded. Remove the 418 backslash ('\') character, the end of line character sequence, and 419 any leading space (' ') characters, which will bring up the next 420 line. Then continue to scan each line in the text content starting 421 with the current line (in case it was multiply folded). 423 Continue in this manner until reaching the end of the text content. 425 The process described in this section is illustrated by the 426 "unfold_it_1()" function in Appendix A. 428 8. The Double Backslash Strategy ('\\') 430 8.1. Folded Structure 432 Text content that has been folded as specified by this strategy MUST 433 adhere to the following structure. 435 8.1.1. Header 437 The header is two lines long. 439 The first line is the following 47-character string that MAY be 440 surrounded by any number of printable characters. This first line 441 cannot itself be folded. 443 NOTE: '\\' line wrapping per BCP XXX (RFC XXXX) 445 [Note to RFC Editor: Please replace XXX and XXXX with the numbers 446 assigned to this document and delete this note. Please make this 447 change in multiple places in this document.] 449 The second line is an empty line, containing only the end-of-line 450 character sequence. This line provides visual separation for 451 readability. 453 8.1.2. Body 455 The character encoding is the same as described in Section 2 of 456 [RFC7994], except that, per [RFC7991], tab characters are prohibited. 458 Lines that have a backslash ('\') occurring as the last character in 459 a line immediately followed by the end of line character sequence, 460 when the subsequent line starts with a backslash ('\') as the first 461 non-space (' ') character, are considered "folded". 463 Exceptionally long lines may be folded multiple times. 465 8.2. Algorithm 467 This section describes a process for folding and unfolding long lines 468 when they are encountered in text content. 470 The steps are complete, but implementations MAY achieve the same 471 result in other ways. 473 When a larger document contains multiple instances of text content 474 that may need to be folded or unfolded, another process must insert/ 475 extract the individual text content instances to/from the larger 476 document prior to utilizing the algorithms described in this section. 477 For example, the `xiax` utility [xiax] does this. 479 8.2.1. Folding 481 Determine the desired maximum line length from input to the line- 482 wrapping process, such as from a command line parameter. If no value 483 is explicitly specified, the value "69" SHOULD be used. 485 Ensure that the desired maximum line length is not less than the 486 minimum header, which is 47 characters. If the desired maximum line 487 length is less than this minimum, exit (this text-based content 488 cannot be folded). 490 Scan the text content for horizontal tab characters. If any 491 horizontal tab characters appear, either resolve them to space 492 characters or exit, forcing the input provider to convert them to 493 space characters themselves first. 495 Scan the text content to see if any line exceeds the desired maximum. 496 If no line exceeds the desired maximum, exit (this text content does 497 not need to be folded). 499 Scan the text content to ensure no existing lines already end with a 500 backslash ('\') character while the subsequent line starts with a 501 backslash ('\') character as the first non-space (' ') character, as 502 this could lead to an ambiguous result. If such a line is found, and 503 its width is less than the desired maximum, then it SHOULD be flagged 504 for forced folding (folding even though unnecessary). If the folding 505 implementation doesn't support forced foldings, it MUST exit. 507 If this text content needs to and can be folded, insert the header 508 described in Section 8.1.1, ensuring that any additional printable 509 characters surrounding the header do not result in a line exceeding 510 the desired maximum. 512 For each line in the text content, from top-to-bottom, if the line 513 exceeds the desired maximum, or requires a forced folding, then fold 514 the line by: 516 1. Determine where the fold will occur. This location MUST be 517 before or at the desired maximum column. For forced foldings, 518 the location is between the '\' and the end of line sequence on 519 the first line. 521 2. At the location where the fold is to occur, insert a first 522 backslash ('\') character followed by the end of line character 523 sequence. 525 3. On the following line, insert any number of space (' ') 526 characters, subject to the resulting line not exceeding the 527 desired maximum, followed by a second backslash ('\') character. 529 The result of the previous operation is that the next line starts 530 with an arbitrary number of space (' ') characters, followed by a 531 backslash ('\') character, immediately followed by the character that 532 was previously occupying the position where the fold occurred. 534 Continue in this manner until reaching the end of the text content. 535 Note that this algorithm naturally addresses the case where the 536 remainder of a folded line is still longer than the desired maximum, 537 and hence needs to be folded again, ad infinitum. 539 The process described in this section is illustrated by the 540 "fold_it_2()" function in Appendix A. 542 8.2.2. Unfolding 544 Scan the beginning of the text content for the header described in 545 Section 8.1.1. If the header is not present, exit (this text content 546 does not need to be unfolded). 548 Remove the 2-line header from the text content. 550 For each line in the text content, from top-to-bottom, if the line 551 has a backslash ('\') character immediately followed by the end of 552 line character sequence, and if the next line has a backslash ('\') 553 character as the first non-space (' ') character, then the lines can 554 be unfolded. Remove the first backslash ('\') character, the end of 555 line character sequence, any leading space (' ') characters, and the 556 second backslash ('\') character, which will bring up the next line. 557 Then continue to scan each line in the text content starting with the 558 current line (in case it was multiply folded). 560 Continue in this manner until reaching the end of the text content. 562 The process described in this section is illustrated by the 563 "unfold_it_2()" function in Appendix A. 565 9. Examples 567 The following self-documenting examples illustrate folded text-based 568 content. 570 The source text content cannot be presented here, as it would again 571 be folded. Alas, only the results can be provided. 573 9.1. Example Showing Boundary Conditions 575 This example illustrates boundary conditions. The input contains 576 seven lines, each line one character longer than the previous line. 577 Numbers for counting purposes. The default desired maximum column 578 value "69" is used. 580 9.1.1. Using '\' 582 ========== NOTE: '\' line wrapping per BCP XXX (RFC XXXX) =========== 584 123456789012345678901234567890123456789012345678901234567890123456 585 1234567890123456789012345678901234567890123456789012345678901234567 586 12345678901234567890123456789012345678901234567890123456789012345678 587 123456789012345678901234567890123456789012345678901234567890123456789 588 12345678901234567890123456789012345678901234567890123456789012345678\ 589 90 590 12345678901234567890123456789012345678901234567890123456789012345678\ 591 901 592 12345678901234567890123456789012345678901234567890123456789012345678\ 593 9012 595 9.1.2. Using '\\' 597 ========== NOTE: '\\' line wrapping per BCP XXX (RFC XXXX) ========== 599 123456789012345678901234567890123456789012345678901234567890123456 600 1234567890123456789012345678901234567890123456789012345678901234567 601 12345678901234567890123456789012345678901234567890123456789012345678 602 123456789012345678901234567890123456789012345678901234567890123456789 603 12345678901234567890123456789012345678901234567890123456789012345678\ 604 \90 605 12345678901234567890123456789012345678901234567890123456789012345678\ 606 \901 607 12345678901234567890123456789012345678901234567890123456789012345678\ 608 \9012 610 9.2. Example Showing Multiple Wraps of a Single Line 612 This example illustrates what happens when a very long line needs to 613 be folded multiple times. The input contains one line containing 280 614 characters. Numbers for counting purposes. The default desired 615 maximum column value "69" is used. 617 9.2.1. Using '\' 619 ========== NOTE: '\' line wrapping per BCP XXX (RFC XXXX) =========== 621 12345678901234567890123456789012345678901234567890123456789012345678\ 622 90123456789012345678901234567890123456789012345678901234567890123456\ 623 78901234567890123456789012345678901234567890123456789012345678901234\ 624 56789012345678901234567890123456789012345678901234567890123456789012\ 625 34567890 627 9.2.2. Using '\\' 629 ========== NOTE: '\\' line wrapping per BCP XXX (RFC XXXX) ========== 631 12345678901234567890123456789012345678901234567890123456789012345678\ 632 \9012345678901234567890123456789012345678901234567890123456789012345\ 633 \6789012345678901234567890123456789012345678901234567890123456789012\ 634 \3456789012345678901234567890123456789012345678901234567890123456789\ 635 \01234567890 637 9.3. Example Showing "Smart" Folding 639 This example illustrates how readability can be improved via "smart" 640 folding, whereby folding occurs at format-specific locations and 641 format-specific indentations are used. 643 The text content was manually folded, since the script in the 644 appendix does not implement smart folding. 646 Note that the headers are surrounded by different printable 647 characters than shown in the script-generated examples. 649 9.3.1. Using '\' 651 [NOTE: '\' line wrapping per BCP XXX (RFC XXXX)] 653 657 658 config-modules 659 660 ietf-interfaces 661 2018-02-20 662 \ 663 urn:ietf:params:xml:ns:yang:ietf-interfaces\ 664 665 666 ... 667 668 ... 669 671 Below is the equivalent to the above, but it was folded using the 672 script in the appendix. 674 ========== NOTE: '\' line wrapping per BCP XXX (RFC XXXX) =========== 676 680 681 config-modules 682 683 ietf-interfaces 684 2018-02-20 685 urn:ietf:params:xml:ns:yang:ietf-interfaces 687 688 ... 689 690 ... 691 693 9.3.2. Using '\\' 695 [NOTE: '\\' line wrapping per BCP XXX (RFC XXXX)] 697 701 702 config-modules 703 704 ietf-interfaces 705 2018-02-20 706 \ 707 \urn:ietf:params:xml:ns:yang:ietf-interfaces\ 708 \ 709 710 ... 711 712 ... 713 715 Below is the equivalent to the above, but it was folded using the 716 script in the appendix. 718 ========== NOTE: '\\' line wrapping per BCP XXX (RFC XXXX) ========== 720 724 725 config-modules 726 727 ietf-interfaces 728 2018-02-20 729 urn:ietf:params:xml:ns:yang:ietf-interfaces 731 732 ... 733 734 ... 735 737 9.4. Example Showing "Forced" Folding 739 This example illustrates how invalid sequences in lines that do not 740 have to be folded can be handled via forced folding, whereby the 741 folding occurs even though unnecessary. 743 The following line exceeds a 68-char max, thus demands folding 744 123456789012345678901234567890123456789012345678901234567890123456789 746 This line ends with a backslash \ 748 This line ends with a backslash \ 749 \ This line begins with a backslash 751 Following is an indented 3x3 block of backslashes: 752 \\\ 753 \\\ 754 \\\ 756 The samples below were manually folded, since the script in the 757 appendix does not implement forced folding. 759 Note that the headers are prefixed by a pound ('#') character, rather 760 than surrounded by equal ('=') characters as shown in the script- 761 generated examples. 763 9.4.1. Using '\' 765 # NOTE: '\' line wrapping per BCP XXX (RFC XXXX) 767 The following line exceeds a 68-char max, thus demands folding 768 1234567890123456789012345678901234567890123456789012345678901234567\ 769 89 771 This line ends with a backslash \\ 773 This line ends with a backslash \\ 775 \ This line begins with a backslash 777 Following is an indented 3x3 block of backslashes: 778 \\\\ 780 \\\\ 782 \\\ 784 9.4.2. Using '\\' 785 # NOTE: '\\' line wrapping per BCP XXX (RFC XXXX) 787 The following line exceeds a 68-char max, thus demands folding 788 1234567890123456789012345678901234567890123456789012345678901234567\ 789 \89 791 This line ends with a backslash \ 793 This line ends with a backslash \\ 794 \ 795 \ This line begins with a backslash 797 Following is an indented 3x3 block of backslashes: 798 \\\\ 799 \ 800 \\\\ 801 \ 802 \\\ 804 10. Security Considerations 806 This BCP has no Security Considerations. 808 11. IANA Considerations 810 This BCP has no IANA Considerations. 812 12. References 814 12.1. Normative References 816 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 817 Requirement Levels", BCP 14, RFC 2119, 818 DOI 10.17487/RFC2119, March 1997, 819 . 821 [RFC7991] Hoffman, P., "The "xml2rfc" Version 3 Vocabulary", 822 RFC 7991, DOI 10.17487/RFC7991, December 2016, 823 . 825 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 826 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 827 May 2017, . 829 12.2. Informative References 831 [bash] "GNU Bash Manual", 832 . 834 [pyang] "An extensible YANG (RFC 6020/7950) validator.", 835 . 837 [RFC7749] Reschke, J., "The "xml2rfc" Version 2 Vocabulary", 838 RFC 7749, DOI 10.17487/RFC7749, February 2016, 839 . 841 [RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", 842 RFC 7950, DOI 10.17487/RFC7950, August 2016, 843 . 845 [RFC7994] Flanagan, H., "Requirements for Plain-Text RFCs", 846 RFC 7994, DOI 10.17487/RFC7994, December 2016, 847 . 849 [RFC8340] Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams", 850 BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, 851 . 853 [xiax] "The `xiax` Python Package", 854 . 856 [xml2rfc] "Xml2rfc generates RFCs and IETF drafts from document 857 source in XML according to the IETF xml2rfc v2 and v3 858 vocabularies.", . 860 [yang-doctors-thread] 861 "[yang-doctors] automating yang doctor reviews", 862 . 865 [yanglint] 866 "A feature-rich tool for validation and conversion of the 867 schemas and YANG modeled data.", 868 . 870 Appendix A. Bash Shell Script: rfcfold 872 This non-normative appendix section includes a Bash [bash] shell 873 script that can both fold and unfold text content using both the 874 single and double backslash strategies described in Section 7 and 875 Section 8 respectively. 877 This script is intended to be applied to a single text content 878 instance. If it is desired to fold or unfold text content instances 879 within a larger document (e.g., an Internet draft or RFC), then 880 another tool must be used to extract the content from the larger 881 document before utilizing this script. 883 For readability purposes, this script forces the minimally supported 884 line length to be eight characters longer than the raw header text 885 defined in Section 7.1.1 and Section 8.1.1 so as to ensure that the 886 header can be wrapped by a space (' ') character and three equal 887 ('=') characters on each side of the raw header text. 889 When a TAB character is detected in the input file, this script exits 890 with the error message: 892 Error: infile contains a TAB character, which is not allowed. 894 This script tests for the availability of GNU awk (gawk), in order to 895 test for ASCII-based control characters and non-ASCII characters in 896 the input file (see below). Note that testing revealed flaws in the 897 default version of `awk` on some platforms. As the use of `gawk` is 898 only used to issue warning messages, if `gawk` of not found, this 899 script issues the debug message: 901 Debug: no GNU Awk, skipping checks for special characters. 903 When `gawk` is available (see above) and ASCII-based control 904 characters are detected in the input file, this script issues the 905 warning message: 907 Warning: infile contains ASCII control characters (unsupported). 909 When `gawk` is available (see above) and non-ASCII characters are 910 detected in the input file, this script issues the warning message: 912 Warning: infile contains non-ASCII characters (unsupported). 914 This script does not implement the whitespace-avoidance logic 915 described in Section 7.2.1. In such case, the script will exit with 916 the following message: 918 Error: infile has a space character occurring on the 919 folding column. This file cannot be folded using the 920 '\' strategy. 922 While this script can unfold input that contains forced foldings, it 923 is unable to fold files that would require forced foldings. Forced 924 folding is described in Section 7.2.1 and Section 8.2.1. When being 925 asked to fold a file that would require forced folding, the script 926 will instead exit with the following message: 928 For '\': 930 Error: infile has a line ending with a '\' character. 931 This file cannot be folded using the '\' strategy without 932 there being false positives produced in the unfolding 933 (i.e., this script does not force-fold such lines, as 934 described in BCP XXX, RFC XXXX). 936 For '\\': 938 Error: infile has a line ending with a '\' character 939 followed by a '\' character as the first non-space 940 character on the next line. This script cannot fold 941 this file using '\\' strategy without there being 942 false positives produced in the unfolding (i.e., this 943 script does not force-fold such lines, as described 944 in BCP XXX, RFC XXXX). 946 Shell-level end-of-line backslash ('\') characters have been 947 purposely added to the script so as to ensure that the script is 948 itself not folded in this document, thus simplifying the ability to 949 copy/paste the script for local use. As should be evident by the 950 lack of the mandatory header described in Section 7.1.1, these 951 backslashes do not designate a folded line, such as described in 952 Section 7. 954 956 #!/bin/bash --posix 958 # This script may need some adjustments to work on a given system. 959 # For instance, the utility `gsed` may need to be installed. 960 # Also, please be advised that `bash` (not `sh`) must be used. 962 # Copyright (c) 2019 IETF Trust, Kent Watsen, and Erik Auerswald. 963 # All rights reserved. 964 # 965 # Redistribution and use in source and binary forms, with or without 966 # modification, are permitted provided that the following conditions 967 # are met: 968 # 969 # * Redistributions of source code must retain the above copyright 970 # notice, this list of conditions and the following disclaimer. 971 # 972 # * Redistributions in binary form must reproduce the above 973 # copyright notice, this list of conditions and the following 974 # disclaimer in the documentation and/or other materials 975 # provided with the distribution. 976 # 977 # * Neither the name of Internet Society, IETF or IETF Trust, nor 978 # the names of specific contributors, may be used to endorse or 979 # promote products derived from this software without specific 980 # prior written permission. 981 # 982 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 983 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 984 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 985 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 986 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 987 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 988 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 989 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 990 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 991 # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 992 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 993 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 995 print_usage() { 996 printf "\n" 997 printf "Folds or unfolds the input text file according to BCP XXX" 998 printf " (RFC XXXX).\n" 999 printf "\n" 1000 printf "Usage: rfcfold [-h] [-d] [-q] [-s ] [-c ]" 1001 printf " [-r] -i -o \n" 1002 printf "\n" 1003 printf " -s: strategy to use, '1' or '2' (default: try 1," 1004 printf " else 2)\n" 1005 printf " -c: column to fold on (default: 69)\n" 1006 printf " -r: reverses the operation\n" 1007 printf " -i: the input filename\n" 1008 printf " -o: the output filename\n" 1009 printf " -d: show debug messages (unless -q is given)\n" 1010 printf " -q: quiet (suppress error and debug messages)\n" 1011 printf " -h: show this message\n" 1012 printf "\n" 1013 printf "Exit status code: 1 on error, 0 on success, 255 on no-op." 1014 printf "\n\n" 1015 } 1017 # global vars, do not edit 1018 strategy=0 # auto 1019 debug=0 1020 quiet=0 1021 reversed=0 1022 infile="" 1023 outfile="" 1024 maxcol=69 # default, may be overridden by param 1025 col_gvn=0 # maxcol overridden? 1026 hdr_txt_1="NOTE: '\\' line wrapping per BCP XXX (RFC XXXX)" 1027 hdr_txt_2="NOTE: '\\\\' line wrapping per BCP XXX (RFC XXXX)" 1028 equal_chars="=======================================================" 1029 space_chars=" " 1030 temp_dir="" 1031 prog_name='rfcfold' 1033 # functions for diagnostic messages 1034 prog_msg() { 1035 if [[ "$quiet" -eq 0 ]]; then 1036 format_string="${prog_name}: $1: %s\n" 1037 shift 1038 printf -- "$format_string" "$@" >&2 1039 fi 1040 } 1042 err() { 1043 prog_msg 'Error' "$@" 1044 } 1046 warn() { 1047 prog_msg 'Warning' "$@" 1048 } 1050 dbg() { 1051 if [[ "$debug" -eq 1 ]]; then 1052 prog_msg 'Debug' "$@" 1053 fi 1054 } 1056 # determine name of [g]sed binary 1057 type gsed > /dev/null 2>&1 && SED=gsed || SED=sed 1059 # warn if a non-GNU sed utility is used 1060 "$SED" --version < /dev/null 2> /dev/null \ 1061 | grep GNU > /dev/null 2>&1 || \ 1062 warn 'not using GNU `sed` (likely cause if an error occurs)' 1064 cleanup() { 1065 rm -rf "$temp_dir" 1066 } 1067 trap 'cleanup' EXIT 1069 fold_it_1() { 1070 # ensure input file doesn't contain the fold-sequence already 1071 if [[ -n "$("$SED" -n '/\\$/p' "$infile")" ]]; then 1072 err "infile has a line ending with a '\\' character."\ 1073 "This file cannot be folded using the '\\' strategy"\ 1074 "without there being false positives produced in the"\ 1075 "unfolding (i.e., this script does not force-fold"\ 1076 "such lines, as described in BCP XXX, RFC XXXX)." 1077 return 1 1078 fi 1080 # where to fold 1081 foldcol=$(expr "$maxcol" - 1) # for the inserted '\' char 1083 # ensure input file doesn't contain whitespace on the fold column 1084 grep -q "^\(.\{$foldcol\}\)\{1,\} " "$infile" 1085 if [[ $? -eq 0 ]]; then 1086 err "infile has a space character occurring on the"\ 1087 "folding column. This file cannot be folded using the"\ 1088 "'\\' strategy." 1089 return 1 1090 fi 1092 # center header text 1093 length=$(expr ${#hdr_txt_1} + 2) 1094 left_sp=$(expr \( "$maxcol" - "$length" \) / 2) 1095 right_sp=$(expr "$maxcol" - "$length" - "$left_sp") 1096 header=$(printf "%.*s %s %.*s" "$left_sp" "$equal_chars"\ 1097 "$hdr_txt_1" "$right_sp" "$equal_chars") 1099 # generate outfile 1100 echo "$header" > "$outfile" 1101 echo "" >> "$outfile" 1102 "$SED" 's/\(.\{'"$foldcol"'\}\)\(..\)/\1\\\n\2/;t M;b;:M;P;D;'\ 1103 < "$infile" >> "$outfile" 2> /dev/null 1104 if [[ $? -ne 0 ]]; then 1105 return 1 1106 fi 1107 return 0 1108 } 1109 fold_it_2() { 1110 # where to fold 1111 foldcol=$(expr "$maxcol" - 1) # for the inserted '\' char 1113 # ensure input file doesn't contain the fold-sequence already 1114 if [[ -n "$("$SED" -n '/\\$/{N;s/\\\n[ ]*\\/&/p}' "$infile")" ]] 1115 then 1116 err "infile has a line ending with a '\\' character"\ 1117 "followed by a '\\' character as the first non-space"\ 1118 "character on the next line. This script cannot fold"\ 1119 "this file using '\\\\' strategy without there being"\ 1120 "false positives produced in the unfolding (i.e., this"\ 1121 "script does not force-fold such lines, as described"\ 1122 "in BCP XXX, RFC XXXX)." 1123 return 1 1124 fi 1126 # center header text 1127 length=$(expr ${#hdr_txt_2} + 2) 1128 left_sp=$(expr \( "$maxcol" - "$length" \) / 2) 1129 right_sp=$(expr "$maxcol" - "$length" - "$left_sp") 1130 header=$(printf "%.*s %s %.*s" "$left_sp" "$equal_chars"\ 1131 "$hdr_txt_2" "$right_sp" "$equal_chars") 1133 # generate outfile 1134 echo "$header" > "$outfile" 1135 echo "" >> "$outfile" 1136 "$SED" 's/\(.\{'"$foldcol"'\}\)\(..\)/\1\\\n\\\2/;t M;b;:M;P;D;'\ 1137 < "$infile" >> "$outfile" 2> /dev/null 1138 if [[ $? -ne 0 ]]; then 1139 return 1 1140 fi 1141 return 0 1142 } 1144 fold_it() { 1145 # ensure input file doesn't contain a TAB 1146 grep -q $'\t' "$infile" 1147 if [[ $? -eq 0 ]]; then 1148 err "infile contains a TAB character, which is not allowed." 1149 return 1 1150 fi 1152 # folding of input containing ASCII control or non-ASCII characters 1153 # may result in a wrong folding column and is not supported 1154 if type gawk > /dev/null 2>&1; then 1155 env LC_ALL=C gawk '/[\000-\014\016-\037\177]/{exit 1}' "$infile"\ 1156 || warn 'infile contains ASCII control characters (unsupported).' 1157 env LC_ALL=C gawk '/[^\000-\177]/{exit 1}' "$infile"\ 1158 || warn 'infile contains non-ASCII characters (unsupported).' 1159 else 1160 dbg 'no GNU Awk, skipping checks for special characters.' 1161 fi 1163 # check if file needs folding 1164 testcol=$(expr "$maxcol" + 1) 1165 grep -q ".\{$testcol\}" "$infile" 1166 if [[ $? -ne 0 ]]; then 1167 dbg "nothing to do" 1168 cp "$infile" "$outfile" 1169 return 255 1170 fi 1172 if [[ "$strategy" -eq 1 ]]; then 1173 fold_it_1 1174 return $? 1175 fi 1176 if [[ "$strategy" -eq 2 ]]; then 1177 fold_it_2 1178 return $? 1179 fi 1180 quiet_sav="$quiet" 1181 quiet=1 1182 fold_it_1 1183 result=$? 1184 quiet="$quiet_sav" 1185 if [[ "$result" -ne 0 ]]; then 1186 dbg "Folding strategy 1 didn't succeed, trying strategy 2..." 1187 fold_it_2 1188 return $? 1189 fi 1190 return 0 1191 } 1193 unfold_it_1() { 1194 temp_dir=$(mktemp -d) 1196 # output all but the first two lines (the header) to wip file 1197 awk "NR>2" "$infile" > "$temp_dir/wip" 1199 # unfold wip file 1200 "$SED" '{H;$!d};x;s/^\n//;s/\\\n *//g' "$temp_dir/wip" > "$outfile" 1202 return 0 1203 } 1204 unfold_it_2() { 1205 temp_dir=$(mktemp -d) 1207 # output all but the first two lines (the header) to wip file 1208 awk "NR>2" "$infile" > "$temp_dir/wip" 1210 # unfold wip file 1211 "$SED" '{H;$!d};x;s/^\n//;s/\\\n *\\//g' "$temp_dir/wip"\ 1212 > "$outfile" 1214 return 0 1215 } 1217 unfold_it() { 1218 # check if file needs unfolding 1219 line=$(head -n 1 "$infile") 1220 line2=$("$SED" -n '2p' "$infile") 1221 result=$(echo "$line" | fgrep "$hdr_txt_1") 1222 if [[ $? -eq 0 ]]; then 1223 if [[ -n "$line2" ]]; then 1224 err "the second line is not empty." 1225 return 1 1226 fi 1227 unfold_it_1 1228 return $? 1229 fi 1230 result=$(echo "$line" | fgrep "$hdr_txt_2") 1231 if [[ $? -eq 0 ]]; then 1232 if [[ -n "$line2" ]]; then 1233 err "the second line is not empty." 1234 return 1 1235 fi 1236 unfold_it_2 1237 return $? 1238 fi 1239 dbg "nothing to do" 1240 cp "$infile" "$outfile" 1241 return 255 1242 } 1244 process_input() { 1245 while [[ "$1" != "" ]]; do 1246 if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then 1247 print_usage 1248 exit 0 1249 elif [[ "$1" == "-d" ]]; then 1250 debug=1 1251 elif [[ "$1" == "-q" ]]; then 1252 quiet=1 1253 elif [[ "$1" == "-s" ]]; then 1254 strategy="$2" 1255 shift 1256 elif [[ "$1" == "-c" ]]; then 1257 col_gvn=1 1258 maxcol="$2" 1259 shift 1260 elif [[ "$1" == "-r" ]]; then 1261 reversed=1 1262 elif [[ "$1" == "-i" ]]; then 1263 infile="$2" 1264 shift 1265 elif [[ "$1" == "-o" ]]; then 1266 outfile="$2" 1267 shift 1268 else 1269 warn "ignoring unknown option '$1'" 1270 fi 1271 shift 1272 done 1274 if [[ -z "$infile" ]]; then 1275 err "infile parameter missing (use -h for help)" 1276 exit 1 1277 fi 1279 if [[ -z "$outfile" ]]; then 1280 err "outfile parameter missing (use -h for help)" 1281 exit 1 1282 fi 1284 if [[ ! -f "$infile" ]]; then 1285 err "specified file \"$infile\" is does not exist." 1286 exit 1 1287 fi 1289 if [[ "$col_gvn" -eq 1 ]] && [[ "$reversed" -eq 1 ]]; then 1290 warn "'-c' option ignored when unfolding (option '-r')" 1291 fi 1293 if [[ "$strategy" -eq 0 ]] || [[ "$strategy" -eq 2 ]]; then 1294 min_supported=$(expr ${#hdr_txt_2} + 8) 1295 else 1296 min_supported=$(expr ${#hdr_txt_1} + 8) 1297 fi 1298 if [[ "$maxcol" -lt "$min_supported" ]]; then 1299 err "the folding column cannot be less than $min_supported." 1300 exit 1 1301 fi 1303 # this is only because the code otherwise runs out of equal_chars 1304 max_supported=$(expr ${#equal_chars} + 1 + ${#hdr_txt_1} + 1\ 1305 + ${#equal_chars}) 1306 if [[ "$maxcol" -gt "$max_supported" ]]; then 1307 err "the folding column cannot be more than $max_supported." 1308 exit 1 1309 fi 1310 } 1312 main() { 1313 if [[ "$#" -eq "0" ]]; then 1314 print_usage 1315 exit 1 1316 fi 1318 process_input "$@" 1320 if [[ "$reversed" -eq 0 ]]; then 1321 fold_it 1322 code=$? 1323 else 1324 unfold_it 1325 code=$? 1326 fi 1327 exit "$code" 1328 } 1330 main "$@" 1332 1334 Acknowledgements 1336 The authors thank the RFC Editor for confirming that there was 1337 previously no set convention, at the time of this document's 1338 publication, for handling long lines in source code inclusions, thus 1339 instigating this work. 1341 The authors thank the following folks for their various contributions 1342 while producing this document (sorted by first name): Benoit Claise, 1343 Gianmarco Bruno, Italo Busi, Joel Jaeggli, Jonathan Hansford, Lou 1344 Berger, Martin Bjorklund, and Rob Wilton. 1346 Special acknowledgement to Erik Auerswald for his contributions to 1347 the `rfcfold` script, especially for greatly improving the `sed` one- 1348 liners used therein. 1350 Authors' Addresses 1352 Kent Watsen 1353 Watsen Networks 1355 EMail: kent+ietf@watsen.net 1357 Erik Auerswald 1358 Individual Contributor 1360 EMail: auerswal@unix-ag.uni-kl.de 1362 Adrian Farrel 1363 Old Dog Consulting 1365 EMail: adrian@olddog.co.uk 1367 Qin Wu 1368 Huawei Technologies 1370 EMail: bill.wu@huawei.com