How do you convert a string to lowercase in gnuplot?
This is a gnuplot string handling question.
Example:- I wish to check a user typed parameter in a gnuplot script....
if (tolower(ARG2) == "ohms") {.....
so by accepting "ohms", "Ohms", or "OHMS".
The preference is to not need to use an external "system" command so that the script is more portable. My current best solution is
arg2 = system("awk 'BEGIN { print toupper(\"".ARG2."\") }'")
and then test the new string variable "arg2", but awk (or other program) may not be generally available on a non unix system, making the gnuplot script less portable.
I cannot see any enhanced gprintf % format specifiers that modifies string presentation - it seems gprintf is only for converting values.
The full function Macro solution (Thanks theozh) has me thinking again of how to implement this as a function. The idea of using a lookup table to convert characters by equating an ordinal number was a great idea. Encapsulating single character case conversion into a function was the start, and then along with recursion, it has made it possible to handle full strings as I had first looked for. I hope this is now a tidy solution for all. Share and enjoy.
# GNUPLOT string case conversion
# string_case.gnu M J Pot, 14/1/2019
# Index lookup table strings
UCases="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
LCases="abcdefghijklmnopqrstuvwxyz"
# Convert a single character
# Char to convert is added to string so it is always found to default other chars
toupperchr(c)=substr( UCases.c, strstrt(LCases.c, c), strstrt(LCases.c, c) )
tolowerchr(c)=substr( LCases.c, strstrt(UCases.c, c), strstrt(UCases.c, c) )
# Convert whole strings
# Conversion first char (or return null), and recurse for the remaining
toupper(s) = s eq "" ? "" : toupperchr(s[1:1]).toupper(s[2:*])
tolower(s) = s eq "" ? "" : tolowerchr(s[1:1]).tolower(s[2:*])
This is a re-work of the recursive case conversion as self contained functions. A little more effort has resolved the excessive stack usage of the first solution. I had only been considering strings of single words when I had the problem. Note:- the single character conversion has been made more robust.
# GNUPLOT string case conversion
# string_case.gnu M J Pot, 29/1/2019
# toupper(), tolower() functions
# Index lookup table strings
UCases="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
LCases="abcdefghijklmnopqrstuvwxyz"
# Convert a single character
# Char to convert is added to string so it is always found to default other chars
# Null strings are returned null
toupperchr(c)= c eq "" ? "" : substr( UCases.c, strstrt(LCases.c, c), strstrt(LCases.c, c) )
tolowerchr(c)= c eq "" ? "" : substr( LCases.c, strstrt(UCases.c, c), strstrt(UCases.c, c) )
# Divide & conquer
# A simple linear recursive call uses too much stack for longer strings.
# This undertakes a binary tree division to make the stack growth order log_2(length)
toupper(s) = strlen(s) <= 1 ? toupperchr(s) : toupper( substr(s,1,strlen(s)/2) ) . toupper( substr(s,(strlen(s)/2)+1,strlen(s)) )
tolower(s) = strlen(s) <= 1 ? tolowerchr(s) : tolower( substr(s,1,strlen(s)/2) ) . tolower( substr(s,(strlen(s)/2)+1,strlen(s)) )