An instant rhyming dictionary for any web site
I managed to get it down to that using a technique called JSONP. This technique avoids any problems with cross domain requests, and allows non-coders to use the API using a short, customizable HTML snippet.
Demonstration
Paste this in your web site:
... and you get this:
How it works
1. The API user pastes a form and reference to a script into their web page.
2. The script inserts some more DIV elements to contain the search results. The DIVs could have been included in the pasted code, but this way is more flexible in case I want to change it later on.
var resultDiv; document.write("<div id='RhymeBrainResultDiv'></div><div style='clear:both'></div>"); resultDiv = document.getElementById("RhymeBrainResultDiv");
When the user clicks the Rhyme button, this function is called. It creates a special URL that points back to a program on my server. For example, this one: http://rhymebrain.com/talk?function=getRhymes&maxResults=10&word=javascript&jsonp=RhymeBrainResponse. It adds a brand new script element to the end of the document, and sets it source to point back to a program on the rhymebrain server.
function RhymeBrainSubmit() { var input = document.getElementById("RhymeBrainInput"); var word = input.value; $(resultDiv).empty(); resultDiv.appendChild( img ); var script = document.createElement("script"); script.type = "text/javascript"; script.src = "http://rhymebrain.com/talk?function=getRhymes" + "&word=" + encodeURIComponent(word) + "&maxResults=" + MaxResults + "&jsonp=RhymeBrainResponse"; document.body.appendChild(script); }3. The server does some super intensive processing involving C, mmap() and 100 MB files, and sends back a response. The response happens to be executable javascript.
RhymeBrainResponse([ {"word":"equipped", "freq":22,"score":"300","flags":"c","syllables":"2"}, {"word":"manuscript", "freq":22,"score":"300","flags":"bc","syllables":"3"}, {"word":"script", "freq":21,"score":"300","flags":"bc","syllables":"1"}, {"word":"shipped", "freq":21,"score":"300","flags":"c","syllables":"1"}, {"word":"slipped", "freq":21,"score":"300","flags":"c","syllables":"1"}, {"word":"stripped", "freq":21,"score":"300","flags":"c","syllables":"1"}, {"word":"dipped", "freq":20,"score":"300","flags":"c","syllables":"1"}, {"word":"tipped", "freq":20,"score":"300","flags":"c","syllables":"1"}, {"word":"whipped", "freq":20,"score":"300","flags":"c","syllables":"1"}, {"word":"gripped", "freq":19,"score":"300","flags":"c","syllables":"1"}]);
4. The browser executes the javascript, which calls the function name that was passed as the jsonp parameter to the script URL. It calls a function which displays the results on the web page.
That's all there is to it. JSONP neatly sidesteps the problem cross domain requests, since script tags can be included from any domain, and it provides a way for non-coders to create mashups.
lacked and hacked produce output fact and impact
pact produces fact and impact
But lacked hacked pact tact etc. are never seen in the output, not even in the near rhymes or slant rhymes.
The rhyming functionary is symmetrical, if a rhymes with b then b rhymes with a. But this code + data does not meet that requirement.
P.S. I am only posting because your blog is otherwise excellent & I thought you might want the feedback on your hobby project.
I input "fact" and the output (for exact rhymes) was just impact
I input "tact" and the output was: fact and impact
I input "impact" and the output was just: fact
mikeDOTreddyATnewportDOTacDOTuk
I think it unlikely that we will exceed 350 requests per hour, as the script will be called in game editor, rather than in game (unless players put in words that the software doesn't recognise) but if this does get more popular I'll be in touch.
Search for Steve Souder's post on the Digg widget for an explanation (hint: scripts with 'document.write' can block downloading of other scripts).
Otherwise, very, very cool :)
_jason