In my Objective-C code for my GPUImage framework, I have the following macro:
#define STRINGIZE(x) #x #define STRINGIZE2(x) STRINGIZE(x) #define SHADER_STRING(text) @ STRINGIZE2(text)
which allows me to inline multiline vertex and fragment shaders as NSString literals within my custom filter subclasses, like this:
NSString *const kGPUImagePassthroughFragmentShaderString = SHADER_STRING ( varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; void main() { gl_FragColor = texture2D(inputImageTexture, textureCoordinate); } );
GPUImage needs this in order to provide formatted vertex and fragment shaders that are included in the body text of filter subclasses. Shipping them as separate files would make the framework unable to be compiled into a static library. Using the above macro, I can make these shaders able to be copied and pasted between the framework code and external shader files without a ridiculous amount of reformatting work.
Swift does away with compiler macros, and the documentation has this to say:
Complex macros are used in C and Objective-C but have no counterpart in Swift. Complex macros are macros that do not define constants, including parenthesized, function-like macros. You use complex macros in C and Objective-C to avoid type-checking constraints or to avoid retyping large amounts of boilerplate code. However, macros can make debugging and refactoring difficult. In Swift, you can use functions and generics to achieve the same results without any compromises. Therefore, the complex macros that are in C and Objective-C source files are not made available to your Swift code.
Per the line "In Swift, you can use functions and generics to achieve the same results without any compromises", is there a way in Swift to provide multiline string literals without resorting to a string of concatenation operations?
String Literals A string literal is a sequence of characters surrounded by double quotes, with the following form − "characters" String literals cannot contain an unescaped double quote ("), an unescaped backslash (\), a carriage return, or a line feed.
Raw strings New in Swift 5, raw strings enable us to turn off all dynamic string literal features (such as interpolation, and interpreting special characters, like \n ), in favor of simply treating a literal as a raw sequence of characters.
You can have a string split across multiple lines by enclosing it in triple quotes. Alternatively, brackets can also be used to spread a string into different lines. Moreover, backslash works as a line continuation character in Python. You can use it to join text on separate lines and create a multiline string.
Alas Swift multiline strings are still not available, as far as I know. However when doing some research regarding this, I found a workaround which could be useful. It is a combination of these items:
"\n".join(...)
to emulate the multiline stringsUsing Automator you could set up an extra service with the following properties:
/usr/bin/perl
print "\"\\n\".join([\n"; # Start a join operation # For each line, reformat and print while(<>) { print " "; # A little indentation chomp; # Loose the newline s/([\\\"])/\\$1/g; # Replace \ and " with escaped variants print "\"$_\""; # Add quotes around the line print "," unless eof # Add a comma, unless it is the last line print "\n"; # End the line, preserving original line count } print " ])"; # Close the join operation
You are of course free to use whatever shell and code you want, I chose perl as that is familiar to me, and here are some comments:
"\n".join(...)
version to create the multiline string, you could use the extension answer from Swift - Split string over multiple lines, or even the +
variant, I'll leave that as an exercise for the user\
and "
to make it a little sturdierOpen up your playground or code editor, and insert/write some multline text:
You now have a multiline string in proper swift coding. Here are an example of before and after text:
Here is my multiline text example with both a " and a \ within the text "\n".join([ "Here is my multiline text ", "example with both a \" and", "a \\ within the text" ])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With