The Task
My task was to take a php i18n language file and convert it to a ColdFusion struct. Here is a portion of the input
...
"ASK_DELETE" => "<em>D</em>elete", // 'd' is the accesskey identifier
"BACKUP_OF" => 'Backup of',
"PAGE_TITLE" => "Page Title",
...
Current Attempt at converting
The code below does work for the php language file that I have been handed. The issue is, the code looks like the beginning of spaghetti code. Some of the things I don’t like are
- If one more string pattern comes along, things will crash
- I have a variable called “value”
- Lots of mid string based chopping.
The code looks like the beginning of spaghetti code. What kinds of things should be done about this?
<cffunction name="readPropertiesFile" returnType="Struct" hint="Read a properties file and return a structure">
<cfargument name="propertiesFile" type="string" required="true" hint="path to properties file">
<cfscript>
VAR stProperties = {};
VAR phpText = "";
VAR key = "";
VAR value = "";
VAR line = "";
var propertiesFilePath = "#GetDirectoryFromPath(GetBaseTemplatePath())##arguments.propertiesfile#";
if (NOT FileExists(propertiesFilePath))
return stProperties;
</cfscript>
<!--- read props file --->
<cffile action="read" file="#propertiesFilePath#" variable="phpText">
<!--- remove any whitespace at top and tail --->
<cfset phpText = trim(phpText)>
<!--- remove comments and blank lines --->
<cfset phpText = ReReplace(phpText,"(?m)\##.*?$", "","all")>
<cfset phpText = ReReplace(phpText,"[#Chr(10)#]{2,}", "#Chr(10)#","all")>
<cfset phpText = ReplaceList(phpText, '",', '"')>
<!--- loop over each line, ignore comments (#...) and insert keys/values into return struct --->
<cfloop list="#phpText#" index="line" delimiters="#CHR(10)#">
<cfscript>
line = trim(line);
splitAt = Find("=>", line);
CommentAt = Find("//", line);
if (splitAt != 0) {
key = replacelist(trim(Left(line, splitAt - 1)), '"', "");
if (CommentAt == 0)
value = replacelist(trim(Mid(line, splitAt + 2, 1000)), '"', '');
else
value = replacelist(trim(Mid(line, splitAt + 2, CommentAt - (splitAt + 2))), '"', '');
// Remove trailing ,
if (right(value, 1) == ",")
value = mid(value, 1, len(value) - 1);
if (right(value, 1) == "'")
value = mid(value, 1, len(value) - 1);
if (left(value, 1) == "'")
value = mid(value, 2, 1000);
stProperties[key] = value;
} // end if
</cfscript>
</cfloop>
<cfreturn stProperties>
This would be my approach. You can of course make this more resilient or add error trapping to catch inconsistent file parsing. I’m assuming there won’t be quotes in the key values.