Created
March 18, 2015 22:07
-
-
Save dansmith65/678e137357ba8499c249 to your computer and use it in GitHub Desktop.
in-progress version of # custom function for FileMaker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ===================================== | |
* # ( name ; value ) | |
* | |
* RETURNS: | |
* An name-value pair in Let notation. | |
* | |
* PARAMETERS: | |
* name: The name for the returned name-value pair. name can be any value | |
* that would be a valid Let() variable name. | |
* value: The value for the returned name-value pair. | |
* | |
* EXAMPLE: | |
* # ( "name"; $value ) & # ( "foo" ; "bar" ) | |
* | |
* DEPENDENCIES: none | |
* | |
* HISTORY: | |
* MODIFIED on 2015-MAR-09 by Daniel Smith [email protected] | |
* - fix a type detection bug introduced in last change where text longer than | |
* 1000 characters was detected as a number | |
* MODIFIED on 2015-02-24 by Daniel Smith [email protected] to improve performance | |
* - use empty value for isValidExpression | |
* - don't save ~plusOneText if it's not needed | |
* - don't save GetAsNumber to variable | |
* - assume value is not date/time/timestamp if over pre-defined length | |
* MODIFIED on 2014-10-07 by Daniel Smith [email protected] to prevent | |
* from returning an EvaluationError. | |
* MODIFIED on 2014-06-06 by Jeremy Bante <http://scr.im/jbante> to fix an | |
* issue where long sequences of digits could be interpreted as timestamps. | |
* MODIFIED on 2014-05-25 by Jeremy Bante <http://scr.im/jbante> to detect | |
* type using a different method suggested by Arnold Kegebein. | |
* MODIFIED on 2013-12-24 by Jeremy Bante <http://scr.im/jbante> to return | |
* an error if name contains a carriage return (Char ( 13 )), and removing | |
* explicit encoding for line feeds. | |
* MODIFIED on 2013-12-12 by John Jones <[email protected]> | |
* to explicitly encode line feed characters in text values. | |
* MODIFIED on 2013-09-02 by Daniel Smith [email protected] to fix a | |
* type misidentification bug. | |
* MODIFIED on 2013-07-27 by Jeremy Bante <http://scr.im/jbante> to fix a | |
* type misidentification bug. | |
* MODIFIED on 2013-04-15 by Jeremy Bante <http://scr.im/jbante> to not | |
* wrap numbers in GetAsNumber. | |
* MODIFIED on 2013-01-14 by Daniel Smith [email protected] to include | |
* trailing return on error result and accept a value of "?" | |
* MODIFIED on 2012-12-12 by Daniel Smith [email protected] to preserve | |
* data type of value | |
* MODIFIED on 2012-12-07 by Jeremy Bante <http://scr.im/jbante> where an | |
* error result could create invalid sytax for values containing a comment | |
* close sequence. | |
* MODIFIED on 2012-11-28 by Jeremy Bante <http://scr.im/jbante> to return | |
* error feedback, and to prefix names with "$". | |
* CREATED on 2012-11-10 by Jeremy Bante <http://scr.im/jbante>. | |
* | |
* REFERENCES: | |
* https://github.com/filemakerstandards/fmpstandards/blob/master/Functions/%23Name-Value/%23.fmfn | |
* ===================================== | |
*/ | |
Let ( [ | |
~name = // strip leading "$$" and "$" | |
Substitute ( | |
"/*start*/" & name ; | |
[ "/*start*/$$" ; "" ] ; | |
[ "/*start*/$" ; "" ] ; | |
[ "/*start*/" ; "" ] | |
) ; | |
~length = Length ( value ) ; | |
~isValidDate = If ( ~length < 100 ; | |
not EvaluationError ( GetAsDate ( value ) ) | |
) ; | |
~isValidTime = If ( ~length < 100 ; | |
not EvaluationError ( GetAsTime ( value ) ) | |
) ; | |
~plusOneText = If ( ~isValidDate or ~isValidTime ; | |
GetAsText ( value + 1 ) | |
) ; | |
~value = | |
Case ( | |
value = "" or value = "?" ; | |
Quote ( value ) ; | |
~isValidDate | |
and ~isValidTime | |
and GetAsText ( GetAsTimestamp ( value ) + 1 ) = ~plusOneText ; | |
"GetAsTimestamp ( " & Quote ( value ) & " )" ; | |
~isValidTime | |
and GetAsText ( GetAsTime ( value ) + 1 ) = ~plusOneText ; | |
"GetAsTime ( " & Quote ( value ) & " )" ; | |
~isValidDate | |
and GetAsText ( GetAsDate ( value ) + 1 ) = ~plusOneText ; | |
"GetAsDate ( " & Quote ( value ) & " )" ; | |
/* prevent running GetAsNumber on large text, for performance reasons */ | |
~length > 1000 ; | |
Quote ( value ) ; | |
value ≠ GetAsNumber ( value ) ; | |
Quote ( value ) ; | |
/* Else: number */ | |
value | |
) ; | |
~result = | |
"$" | |
& ~name | |
& " = " | |
& ~value | |
& " ;¶" ; | |
~testExpression = | |
"Let ( [ " | |
& "$" | |
& ~name | |
& " = " | |
& "\"\"" | |
& " ]; \"\" )" ; | |
~error = | |
Case ( | |
IsEmpty ( ~name ) or Position ( ~name ; ¶ ; 1 ; 1 ) ≠ 0 ; | |
11 ; // Name is not valid | |
not IsValidExpression ( ~testExpression ) ; | |
1200 // Generic calculation error | |
) | |
]; | |
If ( ~error ; // prevent bad pairs from affecting evaluation by commenting | |
"/* Error " | |
& ~error | |
& " name: " | |
& Quote ( | |
Substitute ( // escape comment character sequences | |
name ; | |
[ "*/" ; "\*\/" ] ; | |
[ "/*" ; "\/\*" ] | |
) | |
) | |
& " value: " | |
& Quote ( | |
Substitute ( // escape comment character sequences | |
value ; | |
[ "*/" ; "\*\/" ] ; | |
[ "/*" ; "\/\*" ] | |
) | |
) | |
& " */" | |
& ¶ ; | |
/* Else */ | |
~result | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment