@@ -21,13 +21,15 @@ public struct CodePrinter {
2121 /// in smaller files.
2222 private static let initialBufferSize = 65536
2323
24+ private static let kNewline : String . UnicodeScalarView . Element = " \n "
25+
2426 /// The string content that was printed.
2527 public var content : String {
2628 return String ( contentScalars)
2729 }
2830
2931 /// See if anything was printed.
30- public var isEmpty : Bool { return content . isEmpty }
32+ public var isEmpty : Bool { return contentScalars . isEmpty }
3133
3234 /// The Unicode scalar buffer used to build up the printed contents.
3335 private var contentScalars = String . UnicodeScalarView ( )
@@ -42,19 +44,29 @@ public struct CodePrinter {
4244 /// of a line.
4345 private var atLineStart = true
4446
47+ /// Initialize the printer to use the give indent.
4548 public init ( indent: String . UnicodeScalarView = " " . unicodeScalars) {
4649 contentScalars. reserveCapacity ( CodePrinter . initialBufferSize)
4750 singleIndent = indent
4851 }
4952
53+ /// Initialize a printer using the existing indention information from
54+ /// another CodePrinter.
55+ ///
56+ /// This is most useful to then use `append` to add the new content.
57+ public init ( _ parent: Self ) {
58+ self . init ( indent: parent. singleIndent)
59+ indentation = parent. indentation
60+ }
61+
5062 /// Writes the given strings to the printer.
5163 ///
5264 /// Newlines within the strings are honored and indentention is applied.
5365 ///
5466 /// - Parameter text: A variable-length list of strings to be printed.
5567 public mutating func print( _ text: String ... ) {
5668 for t in text {
57- printInternal ( t, false )
69+ printInternal ( t. unicodeScalars )
5870 }
5971 }
6072
@@ -71,7 +83,9 @@ public struct CodePrinter {
7183 atLineStart = true
7284 } else {
7385 for t in text {
74- printInternal ( t, true )
86+ printInternal ( t. unicodeScalars)
87+ contentScalars. append ( CodePrinter . kNewline)
88+ atLineStart = true
7589 }
7690 }
7791 }
@@ -85,27 +99,40 @@ public struct CodePrinter {
8599 public mutating func printlnIndented( _ text: String ... ) {
86100 indent ( )
87101 for t in text {
88- printInternal ( t, true )
102+ printInternal ( t. unicodeScalars)
103+ contentScalars. append ( CodePrinter . kNewline)
104+ atLineStart = true
89105 }
90106 outdent ( )
91107 }
92108
93- private static let kNewline : String . UnicodeScalarView . Element = " \n "
94-
95- private mutating func printInternal( _ text: String , _ newline: Bool ) {
96- for scalar in text. unicodeScalars {
109+ private mutating func printInternal( _ scalars: String . UnicodeScalarView ) {
110+ for scalar in scalars {
97111 // Indent at the start of a new line, unless it's a blank line.
98112 if atLineStart && scalar != CodePrinter . kNewline {
99113 contentScalars. append ( contentsOf: indentation)
100114 }
101115 contentScalars. append ( scalar)
102116 atLineStart = ( scalar == CodePrinter . kNewline)
103117 }
104- if newline {
105- contentScalars. append ( CodePrinter . kNewline)
106- atLineStart = true
118+ }
119+
120+ /// Appended the content of another `CodePrinter`to this one.
121+ ///
122+ /// - Parameters:
123+ /// - printer: The other `CodePrinter` to copy from.
124+ /// - indenting: Boolean, if the text being appended should be reindented
125+ /// to the current state of this printer. If the `printer` was
126+ /// initialized off of this printer, there isn't a need to reindent.
127+ public mutating func append( _ printer: Self , indenting: Bool = false ) {
128+ if indenting {
129+ printInternal ( printer. contentScalars)
130+ } else {
131+ contentScalars. append ( contentsOf: printer. contentScalars)
132+ atLineStart = printer. atLineStart
107133 }
108134 }
135+
109136 /// Increases the printer's indentation level.
110137 public mutating func indent( ) {
111138 indentation. append ( contentsOf: singleIndent)
0 commit comments