github.com/blend/go-sdk@v1.20220411.3/stringutil/split_lines.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package stringutil
     9  
    10  // SplitLinesOptions are options for the SplitLines function.
    11  type SplitLinesOptions struct {
    12  	IncludeNewline    bool
    13  	IncludeEmptyLines bool
    14  }
    15  
    16  // SplitLinesOption is a mutator for SplitLinesOptions.
    17  type SplitLinesOption func(*SplitLinesOptions)
    18  
    19  // OptSplitLinesIncludeNewLine sets if we should omit newlines in the returned lines.
    20  func OptSplitLinesIncludeNewLine(include bool) SplitLinesOption {
    21  	return func(opts *SplitLinesOptions) {
    22  		opts.IncludeNewline = include
    23  	}
    24  }
    25  
    26  // OptSplitLinesIncludeEmptyLines sets if we should omit newlines in the returned lines.
    27  func OptSplitLinesIncludeEmptyLines(include bool) SplitLinesOption {
    28  	return func(opts *SplitLinesOptions) {
    29  		opts.IncludeEmptyLines = include
    30  	}
    31  }
    32  
    33  // SplitLines splits a corpus into individual lines by the ascii control character `\n`.
    34  // You can control some behaviors of the splitting process with variadic options.
    35  func SplitLines(contents string, opts ...SplitLinesOption) []string {
    36  	contentRunes := []rune(contents)
    37  
    38  	var options SplitLinesOptions
    39  	for _, opt := range opts {
    40  		opt(&options)
    41  	}
    42  
    43  	var output []string
    44  
    45  	const newline = '\n'
    46  
    47  	var line []rune
    48  	var c rune
    49  	for index := 0; index < len(contentRunes); index++ {
    50  		c = contentRunes[index]
    51  
    52  		// if we hit a newline
    53  		if c == newline {
    54  
    55  			// if we should omit newlines
    56  			if options.IncludeNewline {
    57  				line = append(line, c)
    58  			}
    59  
    60  			// if we should omit empty lines
    61  			if options.IncludeNewline {
    62  				if len(line) == 1 && !options.IncludeEmptyLines {
    63  					line = nil
    64  					continue
    65  				}
    66  			} else {
    67  				if len(line) == 0 && !options.IncludeEmptyLines {
    68  					line = nil
    69  					continue
    70  				}
    71  			}
    72  
    73  			// add to the output
    74  			output = append(output, string(line))
    75  			line = nil
    76  			continue
    77  		}
    78  
    79  		// add non-newline characters to the line
    80  		line = append(line, c)
    81  		continue
    82  	}
    83  
    84  	// add anything left
    85  	if len(line) > 0 {
    86  		output = append(output, string(line))
    87  	}
    88  	return output
    89  }