idnits 2.17.1 draft-kwatsen-netmod-artwork-folding-06.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 == Line 306 has weird spacing: '... # is not a...' -- The document date (June 26, 2018) is 2131 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 388, but not defined ** Downref: Normative reference to an Informational RFC: RFC 7991 ** Downref: Normative reference to an Informational RFC: RFC 7994 Summary: 2 errors (**), 0 flaws (~~), 3 warnings (==), 2 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 NETMOD Working Group K. Watsen 3 Internet-Draft Juniper Networks 4 Intended status: Best Current Practice Q. Wu 5 Expires: December 28, 2018 Huawei Technologies 6 A. Farrel 7 Juniper Networks 8 B. Claise 9 Cisco Systems, Inc. 10 June 26, 2018 12 Handling Long Lines in Artwork in Drafts 13 draft-kwatsen-netmod-artwork-folding-06 15 Abstract 17 This document introduces a simple and yet time-proven strategy for 18 handling long lines in artwork in drafts using a backslash ('\') 19 character where line-folding has occurred. The strategy works on any 20 text based artwork, producing consistent results regardless the 21 artwork content. Using a per-artwork header, the strategy is both 22 self-documenting and enables automated reconstitution of the original 23 artwork. 25 Status of This Memo 27 This Internet-Draft is submitted in full conformance with the 28 provisions of BCP 78 and BCP 79. 30 Internet-Drafts are working documents of the Internet Engineering 31 Task Force (IETF). Note that other groups may also distribute 32 working documents as Internet-Drafts. The list of current Internet- 33 Drafts is at https://datatracker.ietf.org/drafts/current/. 35 Internet-Drafts are draft documents valid for a maximum of six months 36 and may be updated, replaced, or obsoleted by other documents at any 37 time. It is inappropriate to use Internet-Drafts as reference 38 material or to cite them other than as "work in progress." 40 This Internet-Draft will expire on December 28, 2018. 42 Copyright Notice 44 Copyright (c) 2018 IETF Trust and the persons identified as the 45 document authors. All rights reserved. 47 This document is subject to BCP 78 and the IETF Trust's Legal 48 Provisions Relating to IETF Documents 49 (https://trustee.ietf.org/license-info) in effect on the date of 50 publication of this document. Please review these documents 51 carefully, as they describe your rights and restrictions with respect 52 to this document. Code Components extracted from this document must 53 include Simplified BSD License text as described in Section 4.e of 54 the Trust Legal Provisions and are provided without warranty as 55 described in the Simplified BSD License. 57 Table of Contents 59 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 60 2. Requirements Language . . . . . . . . . . . . . . . . . . . . 3 61 3. Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 62 3.1. Automated folding of long lines in artwork . . . . . . . 3 63 3.2. Automated reconstitution of original artwork . . . . . . 3 64 4. Limitations . . . . . . . . . . . . . . . . . . . . . . . . . 4 65 4.1. Doesn't work well on graphical artwork . . . . . . . . . 4 66 4.2. Doesn't work as well as format-specific options . . . . . 4 67 5. Folded Structure . . . . . . . . . . . . . . . . . . . . . . 4 68 5.1. Header . . . . . . . . . . . . . . . . . . . . . . . . . 4 69 5.2. Body . . . . . . . . . . . . . . . . . . . . . . . . . . 5 70 6. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . 5 71 6.1. Folding . . . . . . . . . . . . . . . . . . . . . . . . . 5 72 6.2. Unfolding . . . . . . . . . . . . . . . . . . . . . . . . 6 73 7. Example . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 74 8. Security Considerations . . . . . . . . . . . . . . . . . . . 7 75 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 7 76 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 7 77 10.1. Normative References . . . . . . . . . . . . . . . . . . 7 78 10.2. Informative References . . . . . . . . . . . . . . . . . 8 79 Appendix A. POSIX Shell Script . . . . . . . . . . . . . . . . . 9 80 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 13 81 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 13 83 1. Introduction 85 Internet drafts many times contain artwork that exceed the 72 86 character limit specified by RFC 7994 [RFC7994]. The "xml2rfc" 87 utility, in an effort to maintain clean formatting, issues a warning 88 whenever artwork lines exceed 69 characters. According to RFC 89 Editor, there is currently no convention in place for how to handle 90 long lines, other than clearly indicating that some manipulation has 91 occurred. 93 This document introduces a simple and yet time-proven strategy for 94 handling long lines using a backslash ('\') character where line- 95 folding has occurred. The strategy works on any text based artwork, 96 producing consistent results regardless the artwork content. Using a 97 per-artwork header, the strategy is both self-documenting and enables 98 automated reconstitution of the original artwork. 100 2. Requirements Language 102 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 103 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 104 "OPTIONAL" in this document are to be interpreted as described in BCP 105 14 [RFC2119] [RFC8174] when, and only when, they appear in all 106 capitals, as shown here. 108 3. Goals 110 3.1. Automated folding of long lines in artwork 112 Automated folding of long lines is needed in order to support draft 113 compilations that entail a) validation of source input files (e.g., 114 YANG, XML, JSON, ABNF, ASN.1) and/or b) dynamic generation of output 115 (e.g., tree diagrams) that are stitched into the final draft to be 116 submitted. 118 Generally, in order for tooling to be able to process input files, 119 the files must be in their original/natural state, which may include 120 having some long lines. Thus, these source files need to be modified 121 before inclusion in the draft in order to satisfy the line length 122 limits. This modification SHOULD be automated to reduce effort and 123 errors resulting from manual effort. 125 Similarly, dynamically generated output (e.g., tree diagrams) must 126 also be modified, if necessary, in order for the resulting I-D to 127 satisfy the line length limits. When needed, this effort again 128 SHOULD be automated to reduce effort and errors resulting from manual 129 effort. 131 3.2. Automated reconstitution of original artwork 133 Automated reconstitution of the original artwork is needed to support 134 validation of artwork extracted from drafts. Already YANG modules 135 are extracted from drafts and validated as part of the draft- 136 submission process. Additionally, there has been some discussion 137 regarding needing to do the same for examples contained within drafts 138 ([yang-doctors-thread]). Thus, it SHOULD be possible to mechanically 139 reconstitute artwork in order to satisfy the tooling input parsers. 141 4. Limitations 143 4.1. Doesn't work well on graphical artwork 145 While the solution presented in this document will work on any kind 146 of text-based artwork, it is most useful on artwork that represents 147 sourcecode (YANG, XML, JSON, etc.) or, more generally, on artwork 148 that has not been laid out in two dimensions (e.g., diagrams). 150 Fundamentally, the issue is whether the artwork remains readable once 151 folded. Artwork that is unpredictable is especially susceptible to 152 looking bad when folded; falling into this category are most UML 153 diagrams. Artwork that is somewhat structured (e.g., YANG tree 154 diagrams [RFC8340]) fairs better when folded, as the eyes seem to be 155 able to still see the vertical lines, even when they are interrupted. 157 It is NOT RECOMMENDED to use the solution presented in this document 158 on graphical artwork. 160 4.2. Doesn't work as well as format-specific options 162 The solution presented in this document works generically for all 163 artwork, as it only views artwork as plain text. However, various 164 formats sometimes have built-in mechanisms that can be used to 165 prevent long lines. 167 For instance, some source formats allow any quoted string to be 168 broken up into substrings separated by a concatenation character 169 ('+'), any of which can by on a different line. 171 In another example, some languages allow factoring chunks of code 172 into call outs, such as functions. Using such call outs is 173 especially helpful when in some deeply-nested code, as they typically 174 reset the indentation back to the first column. 176 As such, it is RECOMMENDED that authors do as much as possible within 177 the selected format to avoid long lines. 179 5. Folded Structure 181 Artwork that has been folded as specified by this document MUST 182 contain the following structure. 184 5.1. Header 186 The header is two lines long. 188 The first line is an N-character string: 190 === NOTE: '\' line wrapping per BCP XX (RFC XXXX) === 192 where N is the column on which folding occurred (the minimal value is 193 53, the length of the string above) padded with roughly equivalent 194 number of equal ('=') characters on both sides of the string to reach 195 the artwork's maximum line length. 197 The second line is a blank line. This line provides visual 198 separation for the readability. 200 5.2. Body 202 The character encoding is the same as described in Section 2 of 203 [RFC7994], except that, per [RFC7991], tab ('\t') characters are 204 prohibited. 206 The backslash ('\') character may appear anywhere in the artwork, 207 including at the end of any line. 209 Lines that have a backslash occurring on the artwork's maximum column 210 value (N) followed by the '\n' character are considered "folded". 212 A really long line may be folded multiple times. 214 Folded lines are continued on the next line on column 0. 216 6. Algorithm 218 6.1. Folding 220 Determine the desired maximum line length from input. If no value is 221 explicitly specified, the value "69" SHOULD be used. 223 Ensure that the desired maximum line length is not less than the 224 minimum header, which is 53 characters. If the desired maximum line 225 length is less than this minimum, exit (this artwork can not be 226 folded). 228 Scan the artwork to see if any line exceeds the desired maximum. If 229 no line exceeds the desired maximum, exit (this artwork does not need 230 to be folded). 232 Scan the artwork to ensure no existing lines already end with a '\' 233 character on the desired maximum column, as this would lead to an 234 ambiguous result. If such a line is found, exit (this artwork cannot 235 be folded). 237 Scan the artwork to ensure the horizontal tab character '\t' does not 238 appear. If any horizontal tab character appears, exit (this artwork 239 cannot be folded). 241 For each line in the artwork, from top-to-bottom, if the line exceeds 242 the desired maximum, then fold the line at the desired maximum column 243 by inserting the string "\\n" (backlash followed by line return) at 244 the column before the maximum column. Note that the column before 245 needs to be used in order to enable the '\' character to be placed on 246 the desired maximum column. The result of this operation is that the 247 character that was on the maximum column is now the first character 248 of the next line. 250 Continue in this manner until reaching the end of the artwork. Note 251 that this algorithm naturally addresses the case where the remainder 252 of a folded line is still longer than the desired maximum, and hence 253 needs to be folded again, ad infinitum. 255 6.2. Unfolding 257 Scan the beginning of the artwork for the header described in 258 Section 5.1. If the header is not present, starting on the first 259 line of the artwork, exit (this artwork does not need to be 260 unfolded). 262 Calculate the folding-column used from the length of the provided 263 header. 265 Remove the 2-line header from the artwork. 267 For each line in the artwork, from top-to-bottom, if the line has a 268 '\' on the folding-column followed by a '\n' character, then remove 269 both the '\' and '\n' characters, which will bring up the next line, 270 and then scan the remainder of the line to see if it again has a '\' 271 after folding-column characters followed by a '\n' character, and so 272 on. 274 Continue in this manner until reaching the end of the artwork. 276 7. Example 278 The following self-documenting example illustrates a folded document. 280 The source artwork cannot be presented here, as it would again need 281 to be folded. Alas, only the result can be provided. 283 This artwork was folded on column 69, the default value. 285 =========== NOTE: '\' line wrapping per BCP XX (RFC XXXX) =========== 287 # Boundary condition tests using numbers for counting purposes. 288 # 289 # Any printable character (including ' ' and '\') can be used 290 # as a substitute for any number, except for on the 4th row, 291 # the trailing '9' is not allowed to be a '\' character, as 292 # that leads to an ambiguous result. 293 123456789012345678901234567890123456789012345678901234567890123456 294 1234567890123456789012345678901234567890123456789012345678901234567 295 12345678901234567890123456789012345678901234567890123456789012345678 296 123456789012345678901234567890123456789012345678901234567890123456789 297 12345678901234567890123456789012345678901234567890123456789012345678\ 298 90 299 12345678901234567890123456789012345678901234567890123456789012345678\ 300 901 302 # One very long line (280 characters) 303 # 304 # Any printable character (including ' ' and '\') can be used 305 # as a substitute for any number, except the 69th character 306 # is not allowed to be a '\' character, as that leads to an 307 # ambiguous result. 308 12345678901234567890123456789012345678901234567890123456789012345678\ 309 90123456789012345678901234567890123456789012345678901234567890123456\ 310 78901234567890123456789012345678901234567890123456789012345678901234\ 311 56789012345678901234567890123456789012345678901234567890123456789012\ 312 34567890 314 8. Security Considerations 316 This BCP has no Security Considerations. 318 9. IANA Considerations 320 This BCP has no IANA Considerations. 322 10. References 324 10.1. Normative References 326 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 327 Requirement Levels", BCP 14, RFC 2119, 328 DOI 10.17487/RFC2119, March 1997, 329 . 331 [RFC7991] Hoffman, P., "The "xml2rfc" Version 3 Vocabulary", 332 RFC 7991, DOI 10.17487/RFC7991, December 2016, 333 . 335 [RFC7994] Flanagan, H., "Requirements for Plain-Text RFCs", 336 RFC 7994, DOI 10.17487/RFC7994, December 2016, 337 . 339 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 340 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 341 May 2017, . 343 10.2. Informative References 345 [RFC8340] Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams", 346 BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018, 347 . 349 [yang-doctors-thread] 350 "[yang-doctors] automating yang doctor reviews", 351 . 354 Appendix A. POSIX Shell Script 356 This non-normative appendix section includes a shell script that can 357 both fold and unfold artwork based on the solution presented in this 358 document. 360 As a testament for the simplicity of this solution, note that at the 361 core of the script are the following two one-liners: 363 For folding: 364 gsed "/.\{$testcol\}/s/\(.\{$foldcol\}\)/\1\\\\\n/g" 366 For unfolding: 367 gsed ":x; /[^\t]\\{$foldcol\\}\\\\\$/N; s/\\\\\n/\t/; tx; s/\t//g" 369 Disclaimer: this script has the limitation of disallowing the input 370 file from containing any HTAB ('\t') characters. It does not, for 371 instance, make an attempt to convert an HTAB character to a fixed 372 number of SPACE (' ') characters. 374 =====START SCRIPT===== 376 =========== NOTE: '\' line wrapping per BCP XX (RFC XXXX) =========== 378 #!/bin/bash 379 # 380 # the only reason why /bin/sh isn't being used 381 # is because "echo -n" is broken on the Mac. 383 print_usage() { 384 echo 385 echo "Folds the text file, only if needed, at the specified" 386 echo "column, according to BCP XX." 387 echo 388 echo "Usage: $0 [-c ] [-r] -i -o " 389 echo 390 echo " -c: column to fold on (default: 69)" 391 echo " -r: reverses the operation" 392 echo " -i: the input filename" 393 echo " -o: the output filename" 394 echo " -d: show debug messages" 395 echo " -h: show this message" 396 echo 397 echo "Exit status code: zero on success, non-zero otherwise." 398 echo 399 } 400 # global vars, do not edit 401 debug=0 402 reversed=0 403 infile="" 404 outfile="" 405 maxcol=69 # default, may be overridden by param 406 hdr_txt="=== NOTE: '\' line wrapping per BCP XX (RFC XXXX) ===" 407 equal_chars="===========================================" 409 fold_it() { 410 # since upcomming tests are >= (not >) 411 testcol=`expr "$maxcol" + 1` 413 # check if file needs folding 414 grep ".\{$testcol\}" $infile >> /dev/null 2>&1 415 if [ $? -ne 0 ]; then 416 if [[ $debug -eq 1 ]]; then 417 echo "nothing to do" 418 fi 419 cp $infile $outfile 420 return 0 421 fi 423 foldcol=`expr "$maxcol" - 1` # for the inserted '\' char 425 # ensure file doesn't have any '\' char on $maxcol already 426 # - as this would lead to false positives... 427 grep "^.\{$foldcol\}\\\\$" $infile >> /dev/null 2>&1 428 if [ $? -eq 0 ]; then 429 echo 430 echo "Error: infile has a '\\\' on colomn $maxcol already." 431 echo 432 exit 1 433 fi 435 # calculate '=' character-filled header 436 length=${#hdr_txt} 437 left_sp=`expr \( "$maxcol" - "$length" \) / 2` 438 right_sp=`expr "$maxcol" - "$length" - "$left_sp"` 439 header=`printf "%.*s%s%.*s" "$left_sp" "$equal_chars" "$hdr_txt" "\ 440 $right_sp" "$equal_chars"` 442 # generate outfile and return 443 echo -ne "$header\n\n" > $outfile 444 gsed "/.\{$testcol\}/s/\(.\{$foldcol\}\)/\1\\\\\n/g" < $infile >> \ 445 $outfile 446 return 0 447 } 448 unfold_it() { 449 # check if it looks like a BCP XX header 450 line=`head -n 1 $infile | fgrep "$hdr_txt"` 451 if [ $? -ne 0 ]; then 452 if [[ $debug -eq 1 ]]; then 453 echo "nothing to do" 454 fi 455 cp $infile $outfile 456 return 0 457 fi 459 # determine what maxcol value was used 460 maxcol=${#line} 462 # output all but the first two lines (the header) to wip (work in \ 463 progress) file 464 awk "NR>2" $infile > /tmp/wip 466 # unfold wip file 467 foldcol=`expr "$maxcol" - 1` # for the inserted '\' char 468 gsed ":x; /[^\t]\\{$foldcol\\}\\\\\$/N; s/\\\\\n/\t/; tx; s/\t//g"\ 469 /tmp/wip > $outfile 471 # clean up and return 472 rm /tmp/wip 473 return 0 474 } 476 process_input() { 477 while [ "$1" != "" ]; do 478 if [ "$1" == "-h" -o "$1" == "--help" ]; then 479 print_usage 480 exit 1 481 fi 482 if [ "$1" == "-d" ]; then 483 debug=1 484 fi 485 if [ "$1" == "-c" ]; then 486 maxcol="$2" 487 shift 488 fi 489 if [ "$1" == "-r" ]; then 490 reversed=1 491 fi 492 if [ "$1" == "-i" ]; then 493 infile="$2" 494 shift 496 fi 497 if [ "$1" == "-o" ]; then 498 outfile="$2" 499 shift 500 fi 501 shift 502 done 504 if [ -z "$infile" ]; then 505 echo 506 echo "Error: infile parameter missing (use -h for help)" 507 echo 508 exit 1 509 fi 511 if [ -z "$outfile" ]; then 512 echo 513 echo "Error: outfile parameter missing (use -h for help)" 514 echo 515 exit 1 516 fi 518 if [ ! -f "$infile" ]; then 519 echo 520 echo "Error: specified file \"$infile\" is does not exist." 521 echo 522 exit 1 523 fi 525 min_supported=${#hdr_txt} 526 if [ $maxcol -lt $min_supported ]; then 527 echo 528 echo "Error: the folding column cannot be less than $min_support\ 529 ed" 530 echo 531 exit 1 532 fi 534 max_supported=`expr ${#equal_chars} + ${#hdr_txt} + ${#equal_chars\ 535 }` 536 if [ $maxcol -gt $max_supported ]; then 537 echo 538 echo "Error: the folding column cannot be more than $max_support\ 539 ed" 540 echo 541 exit 1 542 fi 544 } 546 main() { 547 if [ "$#" == "0" ]; then 548 print_usage 549 exit 1 550 fi 552 process_input $@ 554 if [[ $reversed -eq 0 ]]; then 555 fold_it 556 code=$? 557 else 558 unfold_it 559 code=$? 560 fi 561 exit $code 562 } 564 main "$@" 566 =====END SCRIPT===== 568 Acknowledgements 570 The authors thank the following folks for their various contributions 571 (sorted by first name): Martin Bjorklund, Jonathan Hansford, and Rob 572 Wilton. 574 The authors additionally thank the RFC Editor, for confirming that 575 there is no set convention today for handling long lines in artwork. 577 Authors' Addresses 579 Kent Watsen 580 Juniper Networks 582 EMail: kwatsen@juniper.net 584 Qin Wu 585 Huawei Technologies 587 EMail: bill.wu@huawei.com 588 Adrian Farrel 589 Juniper Networks 591 EMail: afarrel@juniper.net 593 Benoit Claise 594 Cisco Systems, Inc. 596 EMail: bclaise@cisco.com