Commit a19db3df authored by Julian Stirling's avatar Julian Stirling 🐧
Browse files

Add string utilities for splitting strings

parent 92e15419
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
/* A collection of string utilities for OpenSCAD.

These functions provide basic string manipulation features that are
not available natively in stable OpenSCAD.
*/

// SPDX-License-Identifier: CERN-OHL-S-2.0
// For copyright and authorship information, see the Git history at:
// https://gitlab.com/openflexure/openflexure-microscope

/* Concatenate a list of strings into a single string.

This function reduces the list recursively, concatenating
pairs of elements until a single string remains.

:param input: A non-empty list of strings
:return: A single string formed by concatenating all elements of `input`
:assert len(input) > 0: Checks the list isn't empty
*/
function str_cat(input) =
    assert(len(input) > 0, "str_cat cannot handle empty lists")
    len(input) == 1 ? input[0] :
       len(input) == 2 ? str(input[0], input[1]) :
           str_cat(
               concat(
                   [str(input[0], input[1])],
                   [for (i = [2:len(input)-1]) input[i]]
               )
           );

/* Return a substring using inclusive start and end indices.

No bounds checking is performed. Supplying indices outside
the valid range may result in undefined behaviour.

:param string: The source string
:param start: Starting index (inclusive, zero-based)
:param end: Ending index (inclusive, zero-based)

:return: The substring from `start` to `end`
*/

function sub_str(string, start, end) =
    str_cat([ for (i = [start:end]) string[i] ]);


/* Split a milti-line string into a list of one-line strings.

:param string: The input string

:return: A list of strings, one per line
*/
function split_string_lines(string) = let(
    // get position of any \n
    pos = search("\n", string, 0)[0],
    s_pos = concat([0], [for (p=pos) p+1]),
    e_pos = concat( [for (p=pos) p-1], len(string)-1)
) [for (i = [0:len(pos)]) sub_str(string, s_pos[i], e_pos[i])];