Having trouble getting some code to auto-capitalize words properly

I set $max_length at a high number (8) just to test and it still doesn’t seem to work.

Thank you for your help!

Rehan,

Sorry about the delay in getting back to you. I have a meeting in about 20 minutes, but I will look at it right now and hopefully be back to you very shortly. If not, I promise I will be back to you soon!

Thank you so much!

OK,

Sorry to not have a solution yet, this meeting should be pretty short and I see the problem.

Could you do me a favor though…

I think at some point I got confused about some of the rules. Would you mind putting together a current list describing each of the rules it should follow. This way we won’t break a different rule fixing this one. I think that is what may have happened at some point. If you could also put together a test string with each scenario we are looking for (hypens, quotes, punctuation, words in each group, etc.) with an example of how it should look when done, that would be awesome. I hate to ask you to do this, but I think it will ensure that we have this completely functional.

Thanks!

That’s a great idea Malasho :slight_smile:

Rules lower on the list override rules higher on the list.

Rules:

[ol][li]First letter of every word in a sentence needs to be capitalized, all others lowercase.[/li]
[li]If word is on $exclude_words list, make sure it stays all lowercase.[/li]
[li]If word is on $exclude_words list but is the first word in a sentence, capitalize first letter and lowercase the remaining letters in that word.[/li]
[li]If word is entered in all caps and is NOT on $capital_words AND is less than $max_length, leave it in all caps.[/li]
[li]If word is entered in all caps and is NOT on $capital_words AND is greater than $max_length, capitalize first letter only.[/li]
[li]If word is on $capital_words list, capitalize all letters in that word, regardless of position in sentence.[/li]
[li]If word contains punctuation (comma, exclamation mark, question mark, period, hyphen, forward or back slash, quotes,etc), separate words from punctuation and capitalize based on previous rules.[/li][/ol]

Sample $capital_words: usa, lol, brb, rofl, california
Sample $exclude_words: the, of, and, a
Sample $max_length: 5

Test Strings with input and desired output:

[php]Testing Rule #1
Input: foOd was great
Output: Food Was Great

Testing Rule #2
Input: cats are a lot of fun
Output: Cats Are a Lot of Fun

Testing Rule #3
Input: tHe cat in the hat
Output: The Cat In the Hat

Testing Rule #4
Input: IMHO means in my humble opinion
Output: IMHO Means In My Humble Opinion

Testing Rule #5
Input: TESTING the max length
Output: Testing the Max Length

Testing Rule #6
Input: lol i love california, usa
Output: LOL I Love CALIFORNIA, USA

Testing Rule #7
Input: lol! i reALly–loVe CALIfornia, usa And “other” states…also! SOMETIMES some places are better/nicer than OThErS though!
Output: LOL! I Really–Love CALIFORNIA, USA and “Other” States…Also! Sometimes Some Places Are Better/Nicer Than Others Though![/php]

Hope this helps!! :slight_smile:

OK, I am nearly there.

I started over from scratch with the rules list. This turned out to be a great decision, I think you will find the new code much cleaner than where we were at. I am currently testing and I have one change to make.

Be back with you soon!

Thank you!

One rule I forgot to explicitly mention, was how it handles a letter that comes after an apostrophe. Not really sure how to write that rule, but basically don’t want it to capitalize the letter that immediately follows an apostrophe so that:

what’s --> What’s

insted of

what’s --> What’S

I did remember the apostrophe, thank you though!

Here it is, for your testing pleasure…

Note that I removed the global variable declaration, as I don’t see any reason it is needed in this context. I can’t imagine that wrapping the code will affect this, but it’s something to watch for.

Let me know…

jay[php]<?php
$data = “insert the text you wish to test here”;

$exclude_words = array(“a”,“an”,“and”,“at”,“but”,“by”,“for”,“in”,“nor”,“of”,“on”,“or”,“so”,“the”,“to”,“up”,“yet”); // Exclude analyzing these words
$capital_words = array(“usa”, “lol”, “brb”, “rofl”, “california”); // Capital exclusives (leave in lowercase in array)
$max_length = 5; // Maximum word length, anything over is case-lowered
$ending_punc = array(".","!","?");
$output = array();
$start = 1;

$words = preg_split("/([^a-zA-Z’])/", $data, -1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
foreach($words as $i=>$word)
{
$lcWord = strtolower($word);
$ucWord = strtoupper($word);
if(in_array($lcWord,$capital_words)) $output[$i] = strtoupper($word); // Word was in capital words array
elseif($ucWord==$word) // Word was entered all caps and not in capital words array
{
if(strlen($word)>$max_length) $output[$i] = ucWords($lcWord);
else $output[$i] = $ucWord;
}
elseif($start == 1) $output[$i] = ucWords($lcWord);
elseif(in_array($lcWord,$exclude_words)) $output[$i] = $lcWord;
else $output[$i] = ucWords($lcWord);
if(in_array($word,$ending_punc)) $start = 1;
else $start = 0;
}

$result = implode($output);
echo $result;[/php]

Wow that works perfectly!!

Will try to wrap the vBulletin stuff around it and report back!!! :slight_smile:

Thank you so much Malasho!

I’m getting the error:

Parse error: syntax error, unexpected ‘]’

And this is the code I use:

[php]if (is_subclass_of($this, ‘vB_DataManager_ThreadPost’) && is_array($this->validfields[‘title’])) {

$exclude_words = array(“a”,“an”,“and”,“at”,“but”,“by”,“for”,“in”,“nor”,“of”,“on”,“or”,“so”,“the”,“to”,“up”,“yet”); // Exclude analyzing these words
$capital_words = array(“usa”, “lol”, “brb”, “rofl”, “california”); // Capital exclusives (leave in lowercase in array)
$max_length = 5; // Maximum word length, anything over is case-lowered
$ending_punc = array(".","!","?");

$this->validfields[‘title’][VF_CODE] = ’
$retval = $dm->verify_title($data);
$output = array();
$start = 1;

$words = preg_split("/([^a-zA-Z’])/", $data, -1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
foreach($words as $i=>$word)
{
$lcWord = strtolower($word);
$ucWord = strtoupper($word);
if(in_array($lcWord,$capital_words)) $output[$i] = strtoupper($word); // Word was in capital words array
elseif($ucWord==$word) // Word was entered all caps and not in capital words array
{
if(strlen($word)>$max_length) $output[$i] = ucWords($lcWord);
else $output[$i] = $ucWord;
}
elseif($start == 1) $output[$i] = ucWords($lcWord);
elseif(in_array($lcWord,$exclude_words)) $output[$i] = $lcWord;
else $output[$i] = ucWords($lcWord);
if(in_array($word,$ending_punc)) $start = 1;
else $start = 0;
}

$data = implode($output);

return $retval;
';
}[/php]

I’ve changed the code around a bit (the way I was wrapping it)

but this is what I’m using now and still getting the same error:

[php]if (is_subclass_of($this, ‘vB_DataManager_ThreadPost’) && is_array($this->validfields[‘title’]))
{
$this->validfields[‘title’][VF_CODE] = ’
//$data = “insert the text you wish to test here”;
$exclude_words = array(“a”,“an”,“and”,“at”,“but”,“by”,“for”,“in”,“nor”,“of”,“on”,“or”,“so”,“the”,“to”,“up”,“yet”); // Exclude analyzing these words
$capital_words = array(“usa”, “lol”, “brb”, “rofl”, “california”); // Capital exclusives (leave in lowercase in array)
$max_length = 5; // Maximum word length, anything over is case-lowered
$ending_punc = array(".","!","?");
$output = array();
$retval = $dm->verify_title($data);
$start = 1;

$words = preg_split("/([^a-zA-Z’])/", $data, -1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
foreach($words as $i=>$word)
{
$lcWord = strtolower($word);
$ucWord = strtoupper($word);
if(in_array($lcWord,$capital_words)) $output[$i] = strtoupper($word); // Word was in capital words array
elseif($ucWord==$word) // Word was entered all caps and not in capital words array
{
if(strlen($word)>$max_length) $output[$i] = ucWords($lcWord);
else $output[$i] = $ucWord;
}
elseif($start == 1) $output[$i] = ucWords($lcWord);
elseif(in_array($lcWord,$exclude_words)) $output[$i] = $lcWord;
else $output[$i] = ucWords($lcWord);
if(in_array($word,$ending_punc)) $start = 1;
else $start = 0;
}

$result = implode($output);
$data = implode(" ",$result);
return $retval;
';
}[/php]

See if this works (make sure to test the correct handling of the apostrophe in words after making the change:[php]if (is_subclass_of($this, ‘vB_DataManager_ThreadPost’) && is_array($this->validfields[‘title’])) {

$exclude_words = array(“a”,“an”,“and”,“at”,“but”,“by”,“for”,“in”,“nor”,“of”,“on”,“or”,“so”,“the”,“to”,“up”,“yet”); // Exclude analyzing these words
$capital_words = array(“usa”, “lol”, “brb”, “rofl”, “california”); // Capital exclusives (leave in lowercase in array)
$max_length = 5; // Maximum word length, anything over is case-lowered
$ending_punc = array(".","!","?");

$this->validfields[‘title’][VF_CODE] = ’
$retval = $dm->verify_title($data);
$output = array();
$start = 1;

$words = preg_split("/([^a-zA-Z\x27])/", $data, -1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
foreach($words as $i=>$word)
{
$lcWord = strtolower($word);
$ucWord = strtoupper($word);
if(in_array($lcWord,$capital_words)) $output[$i] = strtoupper($word); // Word was in capital words array
elseif($ucWord==$word) // Word was entered all caps and not in capital words array
{
if(strlen($word)>$max_length) $output[$i] = ucWords($lcWord);
else $output[$i] = $ucWord;
}
elseif($start == 1) $output[$i] = ucWords($lcWord);
elseif(in_array($lcWord,$exclude_words)) $output[$i] = $lcWord;
else $output[$i] = ucWords($lcWord);
if(in_array($word,$ending_punc)) $start = 1;
else $start = 0;
}

$data = implode($output);

return $retval;
';
}[/php]

Thanks malasho,

That is giving the error code:

Warning: in_array() [function.in-array]: Wrong datatype for second argument in [path]/includes/class_dm.php(504) : runtime-created function on line 11

This code is working now:

I guess the globals are important for vBulletin :stuck_out_tongue:

The only situation that I still can’t get to work is the double quotes, but I suppose that is something that our code is doing. When I remove this code completely, double quotes work, but once I turn this on, anything with double quotes goes back to being wrapped with " around it.

I wish I had an in depth understanding of what it is in our code that messes it up! :’(

[php]if (is_subclass_of($this, ‘vB_DataManager_ThreadPost’) && is_array($this->validfields[‘title’])) {

$this->validfields[‘title’][VF_CODE] = ’
global $exclude_words, $capital_words, $max_length;
$exclude_words = array(“a”,“an”,“and”,“at”,“but”,“by”,“for”,“in”,“nor”,“of”,“on”,“or”,“so”,“the”,“to”,“up”,“yet”); // Exclude analyzing these words
$capital_words = array(“usa”, “lol”, “brb”, “rofl”, “california”); // Capital exclusives (leave in lowercase in array)
$max_length = 5; // Maximum word length, anything over is case-lowered
$ending_punc = array(".","!","?");
$retval = $dm->verify_title($data);
$output = array();
$start = 1;
$words = preg_split("/([^a-zA-Z\x27])/", $data, -1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

foreach($words as $i=>$word)
{
$lcWord = strtolower($word);
$ucWord = strtoupper($word);
if(in_array($lcWord,$capital_words)) $output[$i] = strtoupper($word); // Word was in capital words array
elseif($ucWord==$word) // Word was entered all caps and not in capital words array
{
if(strlen($word)>$max_length) $output[$i] = ucWords($lcWord);
else $output[$i] = $ucWord;
}
elseif($start == 1) $output[$i] = ucWords($lcWord);
elseif(in_array($lcWord,$exclude_words)) $output[$i] = $lcWord;
else $output[$i] = ucWords($lcWord);
if(in_array($word,$ending_punc)) $start = 1;
else $start = 0;
}

$data = implode($output);

return $retval;
';
}[/php]

I wish I knew too! It doesn’t happen when the code is unwrapped and when we overrode the vBulletin specific function, it didn’t happen. It has to be something to do with the wrapper, but I don’t know what.

Malasho,

I wanted to say thank you again for all your hard work and time spent helping me with this problem!!! I would have been completely stuck without you.

I have been using the code on my site for the past couple of days and it has been working really well. One issue (albeit minor) is that a word on the $exclude_words list is not capitalized when it starts a sentence other than the first one.

Example:

Input:
what is the best way to code this? and for people who are just learning?

Desired Output:
What Is the Best Way to Code This? And for People Who Are Just Learning?

Actual Output:
What Is the Best Way to Code This? and for People Who Are Just Learning?

I see that you’re separately defining “ending punctuation” with a comma, question mark, or exclamation mark. Is there a way to make it so that if there’s ending punctuation, the $exclude_words list are capitalized again if they are the first word of the next sentence?

Thank you for taking the time to look at this again! :slight_smile:

Sorry about that. Let change the last line from this:[php]else $start = 0;
[/php]

to this:[php]else if($word != ’ ') $start = 0;[/php]

That worked!! :slight_smile:

I really can’t thank you enough for getting this to work so well. I am very grateful to your help Jay – thank you again for all that you do! :smiley:

My pleasure. I’m happy to help!

Best,

jay

Hi Malasho,

I hate to come back and bug you again but I was wondering if you had an idea on how to work out one bug that is popping up with the code you wrote for me last time.

I’m having an issue with words like 1st, 2nd, 3rd, etc.

I’d like them to look just like this: 1st, 2nd, 3rd, etc

but instead they are being output like:

1St, 2Nd, 3Rd, etc.

I tried adding these words to the exclude_words array but unfortunately that doesn’t work.

Is this an easy fix or would it require a substantial rewrite? If its the latter I will just live with it.

Thank you! :slight_smile:

Sponsor our Newsletter | Privacy Policy | Terms of Service