go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/stringutil/split_lines.go (about)

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