idnits 2.17.1 draft-ietf-netmod-artwork-folding-02.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 (April 6, 2019) is 1846 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: Best Current Practice ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Missing Reference: '-r' is mentioned on line 766, but not defined -- Obsolete informational reference (is this intentional?): RFC 7749 (Obsoleted by RFC 7991) Summary: 0 errors (**), 0 flaws (~~), 2 warnings (==), 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: Best Current Practice A. Farrel 5 Expires: October 8, 2019 Old Dog Consulting 6 Q. Wu 7 Huawei Technologies 8 April 6, 2019 10 Handling Long Lines in Inclusions in Internet-Drafts and RFCs 11 draft-ietf-netmod-artwork-folding-02 13 Abstract 15 This document defines a simple and yet time-proven strategy for 16 handling long lines in inclusions in internet drafts and RFCs using a 17 backslash ('\') character to indicate where line-folding has 18 occurred. The strategy works on any text-based content, but is 19 primarily intended for a structured sequence of lines rather than for 20 two-dimensional imagery. The approach produces consistent results, 21 regardless of the content, that is both self-documenting and enables 22 automated reconstitution of the original content. 24 Status of This Memo 26 This Internet-Draft is submitted in full conformance with the 27 provisions of BCP 78 and BCP 79. 29 Internet-Drafts are working documents of the Internet Engineering 30 Task Force (IETF). Note that other groups may also distribute 31 working documents as Internet-Drafts. The list of current Internet- 32 Drafts is at https://datatracker.ietf.org/drafts/current/. 34 Internet-Drafts are draft documents valid for a maximum of six months 35 and may be updated, replaced, or obsoleted by other documents at any 36 time. It is inappropriate to use Internet-Drafts as reference 37 material or to cite them other than as "work in progress." 39 This Internet-Draft will expire on October 8, 2019. 41 Copyright Notice 43 Copyright (c) 2019 IETF Trust and the persons identified as the 44 document authors. All rights reserved. 46 This document is subject to BCP 78 and the IETF Trust's Legal 47 Provisions Relating to IETF Documents 48 (https://trustee.ietf.org/license-info) in effect on the date of 49 publication of this document. Please review these documents 50 carefully, as they describe your rights and restrictions with respect 51 to this document. Code Components extracted from this document must 52 include Simplified BSD License text as described in Section 4.e of 53 the Trust Legal Provisions and are provided without warranty as 54 described in the Simplified BSD License. 56 Table of Contents 58 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 59 2. Applicability Statement . . . . . . . . . . . . . . . . . . . 3 60 3. Requirements Language . . . . . . . . . . . . . . . . . . . . 4 61 4. Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 62 4.1. Automated Folding of Long Lines in Text Content . . . . . 4 63 4.2. Automated Reconstitution of the Original Text Content . . 4 64 5. Limitations . . . . . . . . . . . . . . . . . . . . . . . . . 5 65 5.1. Not Recommended for Graphical Artwork . . . . . . . . . . 5 66 5.2. Doesn't Work as Well as Format-Specific Options . . . . . 5 67 6. Two Folding Strategies . . . . . . . . . . . . . . . . . . . 5 68 6.1. Comparison . . . . . . . . . . . . . . . . . . . . . . . 6 69 6.2. Recommendation . . . . . . . . . . . . . . . . . . . . . 6 70 7. The Single Backslash Strategy ('\') . . . . . . . . . . . . . 6 71 7.1. Folded Structure . . . . . . . . . . . . . . . . . . . . 6 72 7.1.1. Header . . . . . . . . . . . . . . . . . . . . . . . 6 73 7.1.2. Body . . . . . . . . . . . . . . . . . . . . . . . . 7 74 7.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 7 75 7.2.1. Folding . . . . . . . . . . . . . . . . . . . . . . . 7 76 7.2.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . 8 77 8. The Double Backslash Strategy ('\\') . . . . . . . . . . . . 9 78 8.1. Folded Structure . . . . . . . . . . . . . . . . . . . . 9 79 8.1.1. Header . . . . . . . . . . . . . . . . . . . . . . . 9 80 8.1.2. Body . . . . . . . . . . . . . . . . . . . . . . . . 9 81 8.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 10 82 8.2.1. Folding . . . . . . . . . . . . . . . . . . . . . . . 10 83 8.2.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . 11 84 9. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 12 85 9.1. Example Showing Boundary Conditions . . . . . . . . . . . 12 86 9.1.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 12 87 9.1.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 12 88 9.2. Example Showing Multiple Wraps of a Single Line . . . . . 13 89 9.2.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 13 90 9.2.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 13 91 9.3. Example Showing Smart Folding . . . . . . . . . . . . . . 13 92 9.3.1. Using '\' . . . . . . . . . . . . . . . . . . . . . . 13 93 9.3.2. Using '\\' . . . . . . . . . . . . . . . . . . . . . 14 94 10. Security Considerations . . . . . . . . . . . . . . . . . . . 15 95 11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16 96 12. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 97 12.1. Normative References . . . . . . . . . . . . . . . . . . 16 98 12.2. Informative References . . . . . . . . . . . . . . . . . 16 99 Appendix A. POSIX Shell Script . . . . . . . . . . . . . . . . . 17 100 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 23 101 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 23 103 1. Introduction 105 [RFC7994] sets out the requirements for plain-text RFCs and states 106 that each line of an RFC (and hence of an Internet-Draft) must be 107 limited to 72 characters followed by the character sequence that 108 denotes an end-of-line (EOL). 110 Internet-Drafts and RFCs often include example text or code 111 fragments. Many times the example text or code exceeds the 72 112 character line-length limit. The `xml2rfc` utility does not attempt 113 to wrap the content of such inclusions, simply issuing a warning 114 whenever lines exceed 69 characters. According to the RFC Editor, 115 there is currently no convention in place for how to handle long 116 lines in such inclusions, other than advising authors to clearly 117 indicate what manipulation has occurred. 119 This document introduces a simple and yet time-proven strategy for 120 handling long lines using a backslash ('\') character to indicate 121 where line-folding has occurred. The strategy works on any text 122 based inclusion, but is primarily intended for a structured sequence 123 of lines, such as would be referenced by the element 124 defined in Section 2.48 of [RFC7991], rather than for two-dimensional 125 imagery, such as would be referenced by the element defined 126 in Section 2.5 of [RFC7991]. The approach produces consistent 127 results, regardless of the content, that is both self-documenting and 128 enables automated reconstitution of the original content. 130 Note that text files are represented as lines having their first 131 character in column 1, and a line length of N where the last 132 character is in the Nth column and is immediately followed by an end 133 of line character sequence. 135 2. Applicability Statement 137 The format and algorithm defined in this document may be used in any 138 context, whether for IETF documents or in other situations where 139 structured folding is desired. 141 Within the IETF, this work primarily targets the xml2rfc v3 142 element (Section 2.48 of [RFC7991]) and the xml2rfc v2 143 element (Section 2.5 of [RFC7749]) that, for lack of a 144 better option, is currently used for both source code and artwork. 146 This work may be also be used for the xml2rfc v3 element 147 (Section 2.5 of [RFC7991]) but, as described in Section 5.1, it is 148 generally not recommended. 150 3. Requirements Language 152 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 153 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 154 "OPTIONAL" in this document are to be interpreted as described in BCP 155 14 [RFC2119] [RFC8174] when, and only when, they appear in all 156 capitals, as shown here. 158 4. Goals 160 4.1. Automated Folding of Long Lines in Text Content 162 Automated folding of long lines is needed in order to support draft 163 compilations that entail a) validation of source input files (e.g., 164 XML, JSON, ABNF, ASN.1) and/or b) dynamic generation of output, using 165 a tool that doesn't observe line lengths, that is stitched into the 166 final document to be submitted. 168 Generally, in order for tooling to be able to process input files, 169 the files must be in their original/natural state, which may entail 170 them having some long lines. Thus, these source files need to be 171 modified before inclusion in the document in order to satisfy the 172 line length limits. This modification SHOULD be automated to reduce 173 effort and errors resulting from manual processing. 175 Similarly, dynamically generated output (e.g., tree diagrams) must 176 also be modified, if necessary, in order for the resulting document 177 to satisfy the line length limits. When needed, this effort again 178 SHOULD be automated to reduce effort and errors resulting from manual 179 processing. 181 4.2. Automated Reconstitution of the Original Text Content 183 Automated reconstitution of the original content is needed to support 184 validation of text-based inclusions extracted from documents. YANG 185 [RFC7950] modules are already extracted from Internet-Drafts and 186 validated as part of the draft-submission process. Additionally, 187 there has been some discussion regarding needing to also validate 188 instance examples (i.e., XML/JSON documents) contained within 189 Internet-Drafts ([yang-doctors-thread]). Thus, it SHOULD be possible 190 to mechanically reconstitute the original text content in order to 191 utilize such tooling. 193 5. Limitations 195 5.1. Not Recommended for Graphical Artwork 197 While the solution presented in this document will work on any kind 198 of text-based content, it is most useful on content that represents 199 source code (XML, JSON, etc.) or, more generally, on content that has 200 not been laid out in two dimensions (e.g., diagrams). 202 Fundamentally, the issue is whether the text content remains readable 203 once folded. Text content that is unpredictable is especially 204 susceptible to looking bad when folded; falling into this category 205 are most UML diagrams, YANG tree diagrams, and ASCII art in general. 207 It is NOT RECOMMENDED to use the solution presented in this document 208 on graphical artwork. 210 5.2. Doesn't Work as Well as Format-Specific Options 212 The solution presented in this document works generically for all 213 text-based content, as it only views content as plain text. However, 214 various formats sometimes have built-in mechanisms that are better 215 suited to prevent long lines. 217 For instance, both the `pyang` and `yanglint` utilities have the 218 command line option "--tree-line-length" that can be used to indicate 219 a desired maximum line length for when generating tree diagrams 220 [RFC8340]. 222 In another example, some source formats (e.g., YANG [RFC7950]) allow 223 any quoted string to be broken up into substrings separated by a 224 concatenation character (e.g., '+'), any of which can be on a 225 different line. 227 In yet another example, some languages allow factoring blocks of code 228 into call outs, such as functions. Using such call outs is 229 especially helpful when in some deeply-nested code, as they typically 230 reset the indentation back to the first column. 232 It is RECOMMENDED that authors do as much as possible within the 233 selected format to avoid long lines. 235 6. Two Folding Strategies 237 This document defines two nearly identical strategies for folding 238 text-based content. 240 The Single Backslash Strategy ('\'): Uses a backslash ('\') 241 character at the end of the line where folding occurs, and 242 assumes that the continuation begins at the first non- 243 whitespace character on the following line. 245 The Double Backslash Strategy ('\\'): Uses a backslash ('\') 246 character at the end of the line where folding occurs, and 247 assumes that the continuation begins after a second backslash 248 ('\') character on the following line. 250 6.1. Comparison 252 The first strategy produces more readable output, however it is 253 significantly more likely to encounter unfoldable input (e.g., there 254 is exists a line anywhere in the input ending with a backslash 255 character, or there exists a long line containing only space and 256 backslash characters) and, for long lines that can be folded, 257 automation implementations are likely to encounter scenarios that 258 will produce errors without special care. 260 The second strategy produces less readable output, but is unlikely to 261 encounter unfoldable input, there are no long lines that cannot be 262 folded, and no special care is required for when folding a long line. 264 6.2. Recommendation 266 It is RECOMMENDED for implementations to first attempt to fold 267 content using the single backslash strategy and, only in the unlikely 268 event that it cannot fold the input or the folding logic is unable to 269 cope with a contingency occurring on the desired folding column, then 270 fallback to the double backslash strategy. 272 7. The Single Backslash Strategy ('\') 274 7.1. Folded Structure 276 Text content that has been folded as specified by this strategy MUST 277 adhere to the following structure. 279 7.1.1. Header 281 The header is two lines long. 283 The first line is the following 45-character string that MAY be 284 surrounded by any number of printable characters. This first line 285 cannot itself be folded. 287 NOTE: '\' line wrapping per BCP XX (RFC XXXX) 289 [Note to RFC Editor: Please replace XX and XXXX with the numbers 290 assigned to this document and delete this note. Please make this 291 change in multiple places in this document.] 293 The second line is a blank line. This line provides visual 294 separation for readability. 296 7.1.2. Body 298 The character encoding is the same as described in Section 2 of 299 [RFC7994], except that, per [RFC7991], tab characters are prohibited. 301 Lines that have a backslash ('\') occurring as the last character in 302 a line are considered "folded". 304 Really long lines may be folded multiple times. 306 7.2. Algorithm 308 This section describes the process for folding and unfolding long 309 lines when they are encountered in a single instance of text content. 310 It is assumed that another process inserts/extracts the individual 311 text content instances to/from an Internet-Draft or RFC. For 312 example, the `xiax` utility [xiax] does this. 314 7.2.1. Folding 316 Folding is assumed to be automated although authors may perform the 317 folding steps manually. 319 Determine the desired maximum line length from input to the automated 320 line-wrapping process, such as from a command line parameter. If no 321 value is explicitly specified, the value "69" SHOULD be used. 323 Ensure that the desired maximum line length is not less than the 324 minimum header, which is 46 characters. If the desired maximum line 325 length is less than this minimum, exit (this text-based content 326 cannot be folded). 328 Scan the text content for horizontal tab characters. If any 329 horizontal tab characters appear, either resolve them to space 330 characters or exit, forcing the input provider to convert them to 331 space characters themselves first. 333 Scan the text content to see if any line exceeds the desired maximum. 334 If no line exceeds the desired maximum, exit (this text content does 335 not need to be folded). 337 Scan the text content to ensure no existing lines already end with a 338 backslash ('\') character, as this would lead to an ambiguous result. 339 If such a line is found, exit (this text content cannot be folded). 341 If this text content needs to and can be folded, insert the header 342 described in Section 7.1.1, ensuring that any additional printable 343 characters surrounding the header does not result in a line exceeding 344 the desired maximum.. 346 For each line in the text content, from top-to-bottom, if the line 347 exceeds the desired maximum, then fold the line by: 349 1. Determine where the fold will occur. This location MUST be 350 before or at the desired maximum column, and MUST NOT precede a 351 space (' ') character. 353 2. At the location where the fold is to occur, insert a backslash 354 ('\') character followed by the end of line character sequence. 356 3. On the following line, insert any number of space (' ') 357 characters. 359 The result of the previous operation is that the next line starts 360 with an arbitrary number of space (' ') characters, followed by the 361 character that was previously occupying the position where the fold 362 occurred. 364 Continue in this manner until reaching the end of the text content. 365 Note that this algorithm naturally addresses the case where the 366 remainder of a folded line is still longer than the desired maximum, 367 and hence needs to be folded again, ad infinitum. 369 The process described in this section is illustrated by the 370 "fold_it_1()" function in Appendix A. 372 7.2.2. Unfolding 374 All unfolding is assumed to be automated, although a reader will 375 mentally perform the act of unfolding the text to understand the true 376 nature of the original text content. 378 Scan the beginning of the text content for the header described in 379 Section 7.1.1. If the header is not present, starting on the first 380 line of the text content, exit (this text contents does not need to 381 be unfolded). 383 Remove the 2-line header from the text content. 385 For each line in the text content, from top-to-bottom, if the line 386 has a backslash ('\') character immediately followed by the end of 387 line character sequence, then the line can be unfolded. Remove the 388 backslash ('\') character, the end of line character sequence, and 389 any leading space (' ') characters, which will bring up the next 390 line. Then continue to scan each line in the text content starting 391 with the current line (in case it was multiply folded). 393 Continue in this manner until reaching the end of the text content. 395 The process described in this section is illustrated by the 396 "unfold_it_1()" function in Appendix A. 398 8. The Double Backslash Strategy ('\\') 400 8.1. Folded Structure 402 Text content that has been folded as specified by this strategy MUST 403 adhere to the following structure. 405 8.1.1. Header 407 The header is two lines long. 409 The first line is the following 46-character string that MAY be 410 surrounded by any number of printable characters. This first line 411 cannot itself be folded. 413 NOTE: '\\' line wrapping per BCP XX (RFC XXXX) 415 [Note to RFC Editor: Please replace XX and XXXX with the numbers 416 assigned to this document and delete this note. Please make this 417 change in multiple places in this document.] 419 The second line is a blank line. This line provides visual 420 separation for readability. 422 8.1.2. Body 424 The character encoding is the same as described in Section 2 of 425 [RFC7994], except that, per [RFC7991], tab characters are prohibited. 427 Lines that have a backslash ('\') occurring as the last character in 428 a line immediately followed by the end of line character sequence, 429 when the subsequent line starts with a backslash ('\') as the first 430 non-space (' ') character, are considered "folded". 432 Really long lines may be folded multiple times. 434 8.2. Algorithm 436 This section describes the process for folding and unfolding long 437 lines when they are encountered in a single instance of text content. 438 It is assumed that another process inserts/extracts the individual 439 text content instances to/from an Internet-Draft or RFC. For 440 example, the `xiax` utility [xiax] does this. 442 8.2.1. Folding 444 Folding is assumed to be automated, although authors may perform the 445 folding steps manually. 447 Determine the desired maximum line length from input to the automated 448 line-wrapping process, such as from a command line parameter. If no 449 value is explicitly specified, the value "69" SHOULD be used. 451 Ensure that the desired maximum line length is not less than the 452 minimum header, which is 45 characters. If the desired maximum line 453 length is less than this minimum, exit (this text-based content 454 cannot be folded). 456 Scan the text content for horizontal tab characters. If any 457 horizontal tab characters appear, either resolve them to space 458 characters or exit, forcing the input provider to convert them to 459 space characters themselves first. 461 Scan the text content to see if any line exceeds the desired maximum. 462 If no line exceeds the desired maximum, exit (this text content does 463 not need to be folded). 465 Scan the text content to ensure no existing lines already end with a 466 backslash ('\') character while the subsequent line starts with a 467 backslash ('\') character as the first non-space (' ') character, as 468 this would lead to an ambiguous result. If such a line is found, 469 exit (this text content cannot be folded). 471 If this text content needs to and can be folded, insert the header 472 described in Section 8.1.1, ensuring that any additional printable 473 characters surrounding the header does not result in a line exceeding 474 the desired maximum.. 476 For each line in the text content, from top-to-bottom, if the line 477 exceeds the desired maximum, then fold the line by: 479 1. Determine where the fold will occur. This location MUST be 480 before or at the desired maximum column. 482 2. At the location where the fold is to occur, insert a first 483 backslash ('\') character followed by the end of line character 484 sequence. 486 3. On the following line, insert any number of space (' ') 487 characters followed by a second backslash ('\') character. 489 The result of the previous operation is that the next line starts 490 with an arbitrary number of space (' ') characters, followed by a 491 backslash ('\') character, immediately followed by the character that 492 was previously occupying the position where the fold occurred. 494 Continue in this manner until reaching the end of the text content. 495 Note that this algorithm naturally addresses the case where the 496 remainder of a folded line is still longer than the desired maximum, 497 and hence needs to be folded again, ad infinitum. 499 The process described in this section is illustrated by the 500 "fold_it_2()" function in Appendix A. 502 8.2.2. Unfolding 504 All unfolding is assumed to be automated although a reader will 505 mentally perform the act of unfolding the text to understand the true 506 nature of the original text content. 508 Scan the beginning of the text content for the header described in 509 Section 8.1.1. If the header is not present, starting on the first 510 line of the text content, exit (this text content does not need to be 511 unfolded). 513 Remove the 2-line header from the text content. 515 For each line in the text content, from top-to-bottom, if the line 516 has a backslash ('\') character immediately followed by the end of 517 line character sequence, and if the next line has a backslash ('\') 518 character as the first non-space (' ') character, then the lines can 519 be unfolded. Remove the first backslash ('\') character, the end of 520 line character sequence, any leading space (' ') characters, and the 521 second backslash ('\') character, which will bring up the next line. 522 Then continue to scan each line in the text content starting with the 523 current line (in case it was multiply folded). 525 Continue in this manner until reaching the end of the text content. 527 The process described in this section is illustrated by the 528 "unfold_it_2()" function in Appendix A. 530 9. Examples 532 The following self-documenting examples illustrate folded text-based 533 content. 535 The source text content cannot be presented here, as it would again 536 be folded. Alas, only the results can be provided. 538 9.1. Example Showing Boundary Conditions 540 This example illustrates boundary condition. The input contains 541 seven lines, each line one character longer than the previous line. 542 Numbers for counting purposes. The default desired maximum column 543 value "69" is used. 545 9.1.1. Using '\' 547 =========== NOTE: '\' line wrapping per BCP XX (RFC XXXX) =========== 549 123456789012345678901234567890123456789012345678901234567890123456 550 1234567890123456789012345678901234567890123456789012345678901234567 551 12345678901234567890123456789012345678901234567890123456789012345678 552 123456789012345678901234567890123456789012345678901234567890123456789 553 12345678901234567890123456789012345678901234567890123456789012345678\ 554 90 555 12345678901234567890123456789012345678901234567890123456789012345678\ 556 901 557 12345678901234567890123456789012345678901234567890123456789012345678\ 558 9012 560 9.1.2. Using '\\' 562 ========== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) =========== 564 123456789012345678901234567890123456789012345678901234567890123456 565 1234567890123456789012345678901234567890123456789012345678901234567 566 12345678901234567890123456789012345678901234567890123456789012345678 567 123456789012345678901234567890123456789012345678901234567890123456789 568 12345678901234567890123456789012345678901234567890123456789012345678\ 569 \90 570 12345678901234567890123456789012345678901234567890123456789012345678\ 571 \901 572 12345678901234567890123456789012345678901234567890123456789012345678\ 573 \9012 575 9.2. Example Showing Multiple Wraps of a Single Line 577 This example illustrates what happens when very long line needs to be 578 folded multiple times. The input contains one line containing 280 579 characters. Numbers for counting purposes. The default desired 580 maximum column value "69" is used. 582 9.2.1. Using '\' 584 =========== NOTE: '\' line wrapping per BCP XX (RFC XXXX) =========== 586 12345678901234567890123456789012345678901234567890123456789012345678\ 587 90123456789012345678901234567890123456789012345678901234567890123456\ 588 78901234567890123456789012345678901234567890123456789012345678901234\ 589 56789012345678901234567890123456789012345678901234567890123456789012\ 590 34567890 592 9.2.2. Using '\\' 594 ========== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) =========== 596 12345678901234567890123456789012345678901234567890123456789012345678\ 597 \9012345678901234567890123456789012345678901234567890123456789012345\ 598 \6789012345678901234567890123456789012345678901234567890123456789012\ 599 \3456789012345678901234567890123456789012345678901234567890123456789\ 600 \01234567890 602 9.3. Example Showing Smart Folding 604 This example illustrates how readability can be improved via "smart" 605 folding, whereby folding occurs at format-specific locations and 606 format-specific indentations are used. 608 The text content was manually folded, since the script in the 609 appendix does not implement smart folding. 611 Note that the header is surrounded by different printable characters 612 then shown in the script-generated examples. 614 9.3.1. Using '\' 616 [NOTE: '\' line wrapping per BCP XX (RFC XXXX)] 618 622 623 config-modules 624 625 ietf-interfaces 626 2018-02-20 627 \ 628 urn:ietf:params:xml:ns:yang:ietf-interfaces\ 629 630 631 ... 632 633 ... 634 636 Below is the equivalent to the above, but it was folded using the 637 script in the appendix. 639 =========== NOTE: '\' line wrapping per BCP XX (RFC XXXX) =========== 641 645 646 config-modules 647 648 ietf-interfaces 649 2018-02-20 650 urn:ietf:params:xml:ns:yang:ietf-interfaces 652 653 ... 654 655 ... 656 658 9.3.2. Using '\\' 660 [NOTE: '\\' line wrapping per BCP XX (RFC XXXX)] 662 666 667 config-modules 668 669 ietf-interfaces 670 2018-02-20 671 \ 672 \urn:ietf:params:xml:ns:yang:ietf-interfaces\ 673 \ 674 675 ... 676 677 ... 678 680 Below is the equivalent to the above, but it was folded using the 681 script in the appendix. 683 ========== NOTE: '\\' line wrapping per BCP XX (RFC XXXX) =========== 685 689 690 config-modules 691 692 ietf-interfaces 693 2018-02-20 694 urn:ietf:params:xml:ns:yang:ietf-interfaces 696 697 ... 698 699 ... 700 702 10. Security Considerations 704 This BCP has no Security Considerations. 706 11. IANA Considerations 708 This BCP has no IANA Considerations. 710 12. References 712 12.1. Normative References 714 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 715 Requirement Levels", BCP 14, RFC 2119, 716 DOI 10.17487/RFC2119, March 1997, 717 . 719 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 720 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 721 May 2017, . 723 12.2. Informative References 725 [RFC7749] Reschke, J., "The "xml2rfc" Version 2 Vocabulary", 726 RFC 7749, DOI 10.17487/RFC7749, February 2016, 727 . 729 [RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", 730 RFC 7950, DOI 10.17487/RFC7950, August 2016, 731 . 733 [RFC7991] Hoffman, P., "The "xml2rfc" Version 3 Vocabulary", 734 RFC 7991, DOI 10.17487/RFC7991, December 2016, 735 . 737 [RFC7994] Flanagan, H., "Requirements for Plain-Text RFCs", 738 RFC 7994, DOI 10.17487/RFC7994, December 2016, 739 . 741 [RFC8340] Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams", 742 BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, 743 . 745 [xiax] "The `xiax` Python Package", 746 . 748 [yang-doctors-thread] 749 "[yang-doctors] automating yang doctor reviews", 750 . 753 Appendix A. POSIX Shell Script 755 This non-normative appendix section includes a shell script that can 756 both fold and unfold text content. Note that this script is applied 757 only to single text content instances. 759 #!/bin/bash --posix # must be `bash` (not `sh`) 761 print_usage() { 762 echo 763 echo "Folds the text file, only if needed, at the specified" 764 echo "column, according to BCP XX." 765 echo 766 echo "Usage: $0 [-s ] [-c ] [-r] -i " 767 echo " -o " 768 echo 769 echo " -s: strategy to use, '1' or '2' (default: try 1, else 2)" 770 echo " -c: column to fold on (default: 69)" 771 echo " -r: reverses the operation" 772 echo " -i: the input filename" 773 echo " -o: the output filename" 774 echo " -d: show debug messages" 775 echo " -h: show this message" 776 echo 777 echo "Exit status code: zero on success, non-zero otherwise." 778 echo 779 } 781 # global vars, do not edit 782 strategy=0 # auto 783 debug=0 784 reversed=0 785 infile="" 786 outfile="" 787 maxcol=69 # default, may be overridden by param 788 hdr_txt_1="NOTE: '\\' line wrapping per BCP XX (RFC XXXX)" 789 hdr_txt_2="NOTE: '\\\\' line wrapping per BCP XX (RFC XXXX)" 790 equal_chars="==============================================" 791 space_chars=" " 793 fold_it_1() { 794 # ensure input file doesn't contain the fold-sequence already 795 pcregrep -M "\\\\\n" $infile >> /dev/null 2>&1 796 if [ $? -eq 0 ]; then 797 echo 798 echo "Error1: infile $infile has a line ending with a '\\'" 799 echo "character. This file cannot be folded." 800 echo 801 return 1 802 fi 804 # stash some vars 805 testcol=`expr "$maxcol" + 1` 806 foldcol=`expr "$maxcol" - 1` # for the inserted '\' char 808 # ensure input file doesn't contain whitespace on the fold column 809 grep "^.\{$foldcol\} " $infile >> /dev/null 2>&1 810 if [ $? -eq 0 ]; then 811 echo 812 echo "Error: infile has a space character occuring after the" 813 echo "folding column. This file cannot be folded." 814 echo 815 return 1 816 fi 818 # center header text 819 length=`expr ${#hdr_txt_1} + 2` 820 left_sp=`expr \( "$maxcol" - "$length" \) / 2` 821 right_sp=`expr "$maxcol" - "$length" - "$left_sp"` 822 header=`printf "%.*s %s %.*s" "$left_sp" "$equal_chars"\ 823 "$hdr_txt_1" "$right_sp" "$equal_chars"` 825 # generate outfile 826 echo "$header" > $outfile 827 echo "" >> $outfile 828 gsed "/.\{$testcol\}/s/\(.\{$foldcol\}\)/\1\\\\\n/g"\ 829 < $infile >> $outfile 831 return 0 832 } 834 fold_it_2() { 835 # ensure input file doesn't contain the fold-sequence already 836 pcregrep -M "\\\\\n[\ ]*\\\\" $infile >> /dev/null 2>&1 837 if [ $? -eq 0 ]; then 838 echo 839 echo "Error2: infile has a line ending with a '\\' character" 840 echo "followed by a '\\' character as the first non-space" 841 echo "character on the next line. This file cannot be folded." 842 echo 843 return 1 844 fi 846 # center header text 847 length=`expr ${#hdr_txt_2} + 2` 848 left_sp=`expr \( "$maxcol" - "$length" \) / 2` 849 right_sp=`expr "$maxcol" - "$length" - "$left_sp"` 850 header=`printf "%.*s %s %.*s" "$left_sp" "$equal_chars"\ 851 "$hdr_txt_2" "$right_sp" "$equal_chars"` 853 # fold using recursive passes ('g' used in fold_it_1 didn't work) 854 if [ -z "$1" ]; then 855 # init recursive env 856 cp $infile /tmp/wip 857 fi 858 testcol=`expr "$maxcol" + 1` 859 foldcol=`expr "$maxcol" - 1` # for the inserted '\' char 860 gsed "/.\{$testcol\}/s/\(.\{$foldcol\}\)/\1\\\\\n\\\\/" < /tmp/wip\ 861 >> /tmp/wip2 862 diff /tmp/wip /tmp/wip2 > /dev/null 2>&1 863 if [ $? -eq 1 ]; then 864 mv /tmp/wip2 /tmp/wip 865 fold_it_2 "recursing" 866 else 867 echo "$header" > $outfile 868 echo "" >> $outfile 869 cat /tmp/wip2 >> $outfile 870 rm /tmp/wip* 871 fi 872 return 0 873 } 875 fold_it() { 876 # ensure input file doesn't contain a TAB 877 grep $'\t' $infile >> /dev/null 2>&1 878 if [ $? -eq 0 ]; then 879 echo 880 echo "Error: infile contains a TAB character, which is not" 881 echo "allowed." 882 echo 883 return 1 884 fi 886 # check if file needs folding 887 testcol=`expr "$maxcol" + 1` 888 grep ".\{$testcol\}" $infile >> /dev/null 2>&1 889 if [ $? -ne 0 ]; then 890 if [[ $debug -eq 1 ]]; then 891 echo "nothing to do" 892 fi 893 cp $infile $outfile 894 return -1 895 fi 896 if [[ $strategy -eq 1 ]]; then 897 fold_it_1 898 return $? 899 fi 900 if [[ $strategy -eq 2 ]]; then 901 fold_it_2 902 return $? 903 fi 904 fold_it_1 905 if [ $? -ne 0 ]; then 906 fold_it_2 907 return $? 908 fi 909 return 0 910 } 912 unfold_it_1() { 913 # output all but the first two lines (the header) to wip file 914 awk "NR>2" $infile > /tmp/wip 916 # unfold wip file 917 gsed ":x; /.*\\\\$/N; s/\\\\\n[ ]*//; tx" /tmp/wip > $outfile 919 # clean up and return 920 rm /tmp/wip 921 return 0 922 } 924 unfold_it_2() { 925 # output all but the first two lines (the header) to wip file 926 awk "NR>2" $infile > /tmp/wip 928 # unfold wip file 929 gsed ":x; /.*\\\\$/N; s/\\\\\n[ ]*\\\\//; tx" /tmp/wip > $outfile 931 # clean up and return 932 rm /tmp/wip 933 return 0 934 } 936 unfold_it() { 937 # check if file needs unfolding 938 line=`head -n 1 $infile` 939 result=`echo $line | fgrep "$hdr_txt_1"` 940 if [ $? -eq 0 ]; then 941 unfold_it_1 942 return $? 943 fi 944 result=`echo $line | fgrep "$hdr_txt_2"` 945 if [ $? -eq 0 ]; then 946 unfold_it_2 947 return $? 948 fi 949 if [[ $debug -eq 1 ]]; then 950 echo "nothing to do" 951 fi 952 cp $infile $outfile 953 return -1 954 } 956 process_input() { 957 while [ "$1" != "" ]; do 958 if [ "$1" == "-h" -o "$1" == "--help" ]; then 959 print_usage 960 exit 1 961 fi 962 if [ "$1" == "-d" ]; then 963 debug=1 964 fi 965 if [ "$1" == "-s" ]; then 966 strategy="$2" 967 shift 968 fi 969 if [ "$1" == "-c" ]; then 970 maxcol="$2" 971 shift 972 fi 973 if [ "$1" == "-r" ]; then 974 reversed=1 975 fi 976 if [ "$1" == "-i" ]; then 977 infile="$2" 978 shift 979 fi 980 if [ "$1" == "-o" ]; then 981 outfile="$2" 982 shift 983 fi 984 shift 985 done 987 if [ -z "$infile" ]; then 988 echo 989 echo "Error: infile parameter missing (use -h for help)" 990 echo 991 exit 1 993 fi 995 if [ -z "$outfile" ]; then 996 echo 997 echo "Error: outfile parameter missing (use -h for help)" 998 echo 999 exit 1 1000 fi 1002 if [ ! -f "$infile" ]; then 1003 echo 1004 echo "Error: specified file \"$infile\" is does not exist." 1005 echo 1006 exit 1 1007 fi 1009 if [[ $strategy -eq 2 ]]; then 1010 min_supported=`expr ${#hdr_txt_2} + 8` 1011 else 1012 min_supported=`expr ${#hdr_txt_1} + 8` 1013 fi 1014 if [ $maxcol -lt $min_supported ]; then 1015 echo 1016 echo "Error: the folding column cannot be less than" 1017 echo "$min_supported." 1018 echo 1019 exit 1 1020 fi 1022 # this is only because the code otherwise runs out of equal_chars 1023 max_supported=`expr ${#equal_chars} + 1 + ${#hdr_txt_1} + 1\ 1024 + ${#equal_chars}` 1025 if [ $maxcol -gt $max_supported ]; then 1026 echo 1027 echo "Error: the folding column cannot be more than" 1028 echo "$max_supported." 1029 echo 1030 exit 1 1031 fi 1032 } 1034 main() { 1035 if [ "$#" == "0" ]; then 1036 print_usage 1037 exit 1 1038 fi 1040 process_input $@ 1041 if [[ $reversed -eq 0 ]]; then 1042 fold_it 1043 code=$? 1044 else 1045 unfold_it 1046 code=$? 1047 fi 1048 exit $code 1049 } 1051 main "$@" 1053 Acknowledgements 1055 The authors thank the following folks for their various contributions 1056 (sorted by first name): Benoit Claise, Gianmarco Bruno, Italo Busi, 1057 Joel Jaeggli, Jonathan Hansford, Lou Berger, Martin Bjorklund, and 1058 Rob Wilton. 1060 The authors additionally thank the RFC Editor for confirming that 1061 there is no set convention today for handling long lines in artwork/ 1062 sourcecode inclusions. 1064 Authors' Addresses 1066 Kent Watsen 1067 Watsen Networks 1069 EMail: kent+ietf@watsen.net 1071 Adrian Farrel 1072 Old Dog Consulting 1074 EMail: adrian@olddog.co.uk 1076 Qin Wu 1077 Huawei Technologies 1079 EMail: bill.wu@huawei.com