Jump to content

Write a case rule with exceptions


traba5058

Recommended Posts

I am a new Fusion Pro & Marcomm user and just getting started with Javascript.

 

I have 8 direct mail templates setup for a client. The client provides the list in all uppercase. This works great for the mailing panel but not so great when the name is used elsewhere in the piece.

 

Right now, the list has 1 name field (Full Name) and that is all their system can provide. That field contains First, Middle Initial, Last and Suffix.

 

I need to know how to change the following rule

 

var Var1 = "Full Name";

var CaseSelection = "propercase";

 

 

if(CaseSelection == "propercase")

return ToTitleCase(Field(Var1));

 

so it leaves I, II and III etc. suffixes uppercase.

 

Can anyone help?

 

Thanks!

Link to comment
Share on other sites

Unfortunately, there's no computerized algorithm which can accurately calculate all the somewhat arbitrary capitalization rules for proper names. The ToTitleCase function also doesn't know how to properly capitalize names like McDonald or Werner von Braun, nor acronyms which are parts of names and addresses, such as directional notations like NW. For that matter, not every proper name conforms to the Western ideal of first, middle, last, and suffix.

 

So, using the rather simplistic ToTitleCase string processing function to cleanse or "fix" your data is perilous, as there are many, many exception cases where proper names do not conform to "title case" logic". Here's one of my rants about this from the old email list:

http://www.mail-archive.com/fusionpr.../msg01161.html

 

You could theoretically apply the same kind of exception case logic as in that post, with a list of exceptions like I, II, III, etc., but I still don't recommend doing this, as you will undoubtedly find other kinds of names where forcing a particular mixed case style is simply not appropriate. This is why the USPS standardizes all mailing addresses to upper-case.

 

In short, there's really no reliable way to do programmatically restore the missing capitalization in the data, short of going back to the customer and getting the original data, before it was converted to all upper-case.

Link to comment
Share on other sites

Here is an example of how this code could work. You would have to add all scenarios to meet your customer's needs, as Dan states.

 

var Name = Field("Full Name");
Name = Name.replace("Sr","SR").replace("Jr","JR").replace("iii","III").replace("ii","II");
return Name;

Link to comment
Share on other sites

I actually manipulated it to read

 

var Name = Rule("ProperCase_FullName_Rule");

Name = Name.replace("Ii","II").replace("Iii","III").replace("IIi","III").replace("Iv","IV");

return Name;

 

One thing I noticed is that the PropoerCase rule changed III to Iii, but the rule above changed it to IIi. So, I had to add the "replace("IIi","III")" portion. Logically that didn't make sense to me. Do you have any thoughts on why I had to add that?

Link to comment
Share on other sites

I actually manipulated it to read

 

var Name = Rule("ProperCase_FullName_Rule");

Name = Name.replace("Ii","II").replace("Iii","III").replace("IIi","III").replace("Iv","IV");

return Name;

 

Do you have any thoughts on why I had to add that?

 

Unfortunately I'm no code expert but I see "replace" has a space after the "a." I know one thing with code, if it isn't spelled correctly, it won't work.

Link to comment
Share on other sites

I actually manipulated it to read

 

var Name = Rule("ProperCase_FullName_Rule");

Name = Name.replace("Ii","II").replace("Iii","III").replace("IIi","III").replace("Iv","IV");

return Name;

 

One thing I noticed is that the PropoerCase rule changed III to Iii, but the rule above changed it to IIi. So, I had to add the "replace("IIi","III")" portion. Logically that didn't make sense to me. Do you have any thoughts on why I had to add that?

That is because your first replace() checks for "Ii". The search will replace the first instance that matches that string whether it is "Ii" or "Iii". What you could do instead of adding another replace, would be to reverse the replace methods you already had. So replace("Iii", "III") would come before replace("Ii","II").

 

Keep in mind that if your field value were "John Iilian Ii", your result would be "John IIlian Ii" since the replace method only searches for the first match. There are ways around that, but they fall under JavaScript 301. ;)

Edited by esmith
Link to comment
Share on other sites

Here is an example of how this code could work. You would have to add all scenarios to meet your customer's needs, as Dan states.

 

var Name = Field("Full Name");
Name = Name.replace("Sr","SR").replace("Jr","JR").replace("iii","III").replace("ii","II");
return Name;

Well, yes, although if you're going to do this, despite the caveats I offered, I think it's cleaner to create a simple array of exception-case strings and iterate through them, as in the example I cited, instead of chaining together a bunch of replace calls. Something like this:

var result = ToTitleCase(Field("Full Name"));
var Exceptions = [ "I", "II", "III", "IV" ];
for (var i in Exceptions)
{
   var re = RegExp("\\b" + Exceptions[i] + "\\b", "gi");
   result = result.replace(re, Exceptions[i]);
}
return result;

This makes it a lot easier to add more exceptions to the list. Note also that my version only replaces entire words, while the simpler call to replace without the regular expression could result in output such as "IVerson".

I actually manipulated it to read

 

var Name = Rule("ProperCase_FullName_Rule");

Name = Name.replace("Ii","II").replace("Iii","III").replace("IIi","III").replace("Iv","IV");

return Name;

 

One thing I noticed is that the PropoerCase rule changed III to Iii, but the rule above changed it to IIi. So, I had to add the "replace("IIi","III")" portion. Logically that didn't make sense to me. Do you have any thoughts on why I had to add that?

Yes, well, that rule is very dependent on the order in which the replace calls are made, as it was doing case-sensitive searches. My solution does case-insensitive searches, as denoted by the "i" flag in the RegExp object. It also includes the "g" flag to replace all instances, not just the first, which probably doesn't matter much for a name with a single suffix, but it's technically more complete.

Edited by Dan Korn
fix typo
Link to comment
Share on other sites

Unfortunately I'm no code expert but I see "replace" has a space after the "a." I know one thing with code, if it isn't spelled correctly, it won't work.

This was probably a result of pasting the code in directly without using [noparse]

 and 

[/noparse] tags. If you're posting code to the forum, you can click the "Go Advanced" button, then select the code you pasted in and click the # button to add the appropriate tags, which will put the code in a special "Code" block as in my posts. You can also use the handy "Preview Post" button to make sure things look right before submitting. Okay, I'm taking my moderator hat off now. :)

Link to comment
Share on other sites

Dan,

 

I created a new rule in Fusion Pro and pasted in your code

 

var result = ToTitleCase(Field("Full Name");
var Exceptions = [ "I", "II", "III", "IV" ];
for (var i in Exceptions)
{
   var re = RegExp("\\b" + Exceptions[i] + "\\b", "gi");
   result = result.replace(re, Exceptions[i]);
}
return result;

 

Now I am getting an error when I validate it:

 

line 1:Syntax Error: missing ) after argument list.

 

Can you help me?

Link to comment
Share on other sites

There's an extra semicolon in the first line.

It should read:

var result = ToTitleCase(Field("Full Name"));

Sorry about that. I edited my post to fix it. Here's the corrected version of the full rule:

var result = ToTitleCase(Field("Full Name"));
var Exceptions = [ "I", "II", "III", "IV" ];
for (var i in Exceptions)
{
   var re = RegExp("\\b" + Exceptions[i] + "\\b", "gi");
   result = result.replace(re, Exceptions[i]);
}
return result;

Link to comment
Share on other sites

  • 3 months later...

Sorry to resurrect the thread -

 

I'm having a bit of an issue here, using the typical ProperCase rule:

 

var Var1 = "AgencyName";

return ToTitleCase(Field(Var1));

 

Now, we have two clients that have capital letters in their name - ABC Corporation for instance. What's the syntax so it doesn't come out Abc Corporation? I tried the exceptions listed above but couldn't get that to work.

 

My client only has the two companies that this is affected by, so it's really not a matter of listing out every possible permutation. We'll be notified if any new ones arise, so it'll just be a matter of plugging them in.

 

Long story short, I'd like the ProperCase to continue, just not when the letters ABC are involved....

Link to comment
Share on other sites

Using an array the way Dan suggested is the easiest to manage when there are a lot of variables or when you know you'll be adding more in the future.

 

If you have a few static values you are dealing with or if you don't want to deal with arrays and loops you can use a simple if/else rule:

 

var Var1 = Field("AgencyName").toLowerCase();

if (Var1 == "abc corporation")
return "ABC Corporation";
else if (Var1 == "pti")
return "PTI";
else
return ToTitleCase(Var1);

 

In this case I am pre-converting the Field value to lowercase then checking just to be safe as it has to be an exact match.

Link to comment
Share on other sites

As stated, it has to be an exact match to the entire string, the only exception being that it's all going to be in lowercase to get around any inconsistencies with case.

 

if (Var1 == "mw financial")
return "MW Financial";

 

mw Financial, Mw financial, MW Financial, would all work because they are forced to lowercase before being compared to == "mw financial".

 

The misspelled "mw finacail" would not work. You would have to put in another else if to handle misspellings. This is where Dan's suggestion of using an array and loop would be preferable as you could add in lots of variants easily.

 

Alternatively you could do something like this:

 

if (Var1.substring(0,3) == "abc")
return "ABC Corporation";
else if (Var1.substring(0,2) == "mw")
return "MW Financial";

 

This just checks for a match of the first few characters and doesn't worry about anything after. So the misspelling later in the word would still be a match. The only problem with this would be if you had a few agencies that started with the same letters.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...