/* * Fun filters by Dougal * * This started when I added a pirate filter to my blog for Talk Like * a Pirate Day (talklikeapirate.com). My first version was easier * than I expected it to be (though it had flaws), which inspired me * to locate and convert some of Kalsey's MovableJive filters. * * The earliest version had a flaw, in that it would filter text inside of * HTML tags, causing it to mangle links and such. I fixed this by borrowing * an idea from Simon Willison. Simon's use of a callback function to only * match text that was not part of a tag was good, but it included the '>' * and '<' brackets from surrounding tags, requiring you to hack them back * in at the end of your content filter. * * After an afternoon studying the pcre pattern syntax and wrestling regexps * with the help of the Regex Coach (http://weitz.de/regex-coach/) I came up * with an improved pattern, which doesn't require us to tack the '>' and * '<' back on manually. Cool, huh? */ // An idea from Simon Willison (http://simon.incutio.com/) // This tries to make sure that we only filter text *between* // any HTML tags, and not *within* them. function filter_cdata_content($content, $filter='none') { if (function_exists($filter)) { $content = preg_replace_callback('/(?(?<=>)|\A)([^<>]+)(?(?=<)|\Z)/s', $filter, $content); } return $content; } // This function takes an array of ('/pattern/' => 'replacement') pairs // and applies them all to $content. function array_apply_regexp($patterns,$content) { // Extract the values: $keys = array_keys($patterns); $values = array_values($patterns); // Replace the words: $content = preg_replace($keys,$values,$content); return $content; } // For Talk Like a Pirate Day function pirate($content) { return filter_cdata_content($content,'pirate_filter'); } function pirate_filter($content) { $content = $content[1]; $patterns = array( '%\bmy\b%' => 'me', '%\bboss\b%' => 'admiral', '%\bmanager\b%' => 'admiral', '%\b[Cc]aptain\b%' => "Cap'n", '%\bmyself\b%' => 'meself', '%\byour\b%' => 'yer', '%\byou\b%' => 'ye', '%\bfriend\b%' => 'matey', '%\bfriends\b%' => 'maties', '%\bco[-]?worker\b%' => 'shipmate', '%\bco[-]?workers\b%' => 'shipmates', '%\bearlier\b%' => 'afore', '%\bold\b%' => 'auld', '%\bthe\b%' => "th'", '%\bof\b%' => "o'", "%\bdon't\b%" => "dern't", '%\bdo not\b%' => "dern't", '%\bnever\b%' => "ne'er", '%\bever\b%' => "e'er", '%\bover\b%' => "o'er", '%\bYes\b%' => 'Aye', '%\bNo\b%' => 'Nay', "%\bdon't know\b%" => "dinna", "%\bhadn't\b%" => "ha'nae", "%\bdidn't\b%"=> "di'nae", "%\bwasn't\b%" => "weren't", "%\bhaven't\b%" => "ha'nae", '%\bfor\b%' => 'fer', '%\bbetween\b%' => 'betwixt', '%\baround\b%' => "aroun'", '%\bto\b%' => "t'", "%\bit's\b%" => "'tis", '%\bwoman\b%' => 'wench', '%\blady\b%' => 'wench', '%\bwife\b%' => 'lady', '%\bgirl\b%' => 'lass', '%\bgirls\b%' => 'lassies', '%\bguy\b%' => 'lubber', '%\bman\b%' => 'lubber', '%\bfellow\b%' => 'lubber', '%\bdude\b%' => 'lubber', '%\bboy\b%' => 'lad', '%\bboys\b%' => 'laddies', '%\bchildren\b%' => 'little sandcrabs', '%\bkids\b%' => 'minnows', '%\bhim\b%' => 'that scurvey dog', '%\bher\b%' => 'that comely wench', '%\bhim\.\b%' => 'that drunken sailor', '%\bHe\b%' => 'The ornery cuss', '%\bShe\b%' => 'The winsome lass', "%\bhe's\b%" => 'he be', "%\bshe's\b%" => 'she be', '%\bwas\b%' => "were bein'", '%\bHey\b%' => 'Avast', '%\bher\.\b%' => 'that lovely lass', '%\bfood\b%' => 'chow', '%\broad\b%' => 'sea', '%\broads\b%' => 'seas', '%\bstreet\b%' => 'river', '%\bstreets\b%' => 'rivers', '%\bhighway\b%' => 'ocean', '%\bhighways\b%' => 'oceans', '%\bcar\b%' => 'boat', '%\bcars\b%' => 'boats', '%\btruck\b%' => 'schooner', '%\btrucks\b%' => 'schooners', '%\bSUV\b%' => 'ship', '%\bairplane\b%' => 'flying machine', '%\bjet\b%' => 'flying machine', '%\bmachine\b%' => 'contraption', '%\bdriving\b%' => 'sailing', '%\bdrive\b%' => 'sail', '/ing\b/' => "in'", '/ings\b/' => "in's", // These next two do cool random substitutions '/(\.\s)/e' => 'avast("$0",3)', '/([!\?]\s)/e' => 'avast("$0",2)', // Greater chance after exclamation ); // Replace the words: $content = array_apply_regexp($patterns,$content); return $content; } // support function for pirate() // this could probably be refactored to make it more generic, allowing // different filters to pass their own patterns in. function avast($stub = '',$chance = 5) { $shouts = array( ", avast$stub", "$stub Ahoy!", ", and a bottle of rum!", ", by Blackbeard's sword$stub", ", by Davy Jones' locker$stub", "$stub Walk the plank!", "$stub Aarrr!", "$stub Yaaarrrrr!", ", pass the grog!", ", and dinna spare the whip!", ", with a chest full of booty$stub", ", and a bucket o' chum$stub", ", we'll keel-haul ye!", "$stub Shiver me timbers!", "$stub And hoist the mainsail!", "$stub And swab the deck!", ", ye scurvey dog$stub", "$stub Fire the cannons!", ", to be sure$stub", ", I'll warrant ye$stub", ); shuffle($shouts); return (((1 == rand(1,$chance))?array_shift($shouts):$stub) . ' '); } // Borrowed fudd, jive, kraut, and chef from Kalsey's MovableJive filter // http://kalsey.com/blog/2003/02/movablejive/ // These filters (particularly 'kraut' and 'jive' might contain something // that could offend you or your readers. Edit and/or use at your own risk. function fudd($content) { return filter_cdata_content($content,'fudd_filter'); } function fudd_filter($content) { $content = $content[1]; $patterns = array( '%(r|l)%' => 'w', '%qu%' => 'qw', '%th(\s)%' => 'f$1', '%th%' => 'd', '%n\.%' => 'n, uh-hah-ha-ha.', '%(R|L)%' => 'W', '%(Qu|QW)%' => 'QW', '%TH(\s)%' => 'F$1', '%Th%' => 'D', '%N\.%' => 'N, uh-hah-hah-hah.' ); $content = array_apply_regexp($patterns,$content); return $content; } function kraut($content) { return filter_cdata_content($content,'kraut_filter'); } function kraut_filter($content) { $content = $content[1]; $patterns = array( '%ing%' => 'ingkt', '% the %' => ' ze ', '%The %' => 'Ze ', '% with %' => ' mitt ', '%With %' => 'Mitt ', '% is%' => ' iss', '% Is%' => ' Iss', '%wr%' => 'w-r-r', '%Wr%' => 'W-r-r', '%R%' => 'R-r-r', '% r%' => ' r-r-r', '%Yes( |\.|!)%' => 'Jawohl$1', '%YES!%' => 'JAWOHL!', '% yes( |.|!)%' => ' ja$1', '%No( |!|\?) %' => 'Nein$1', '% no( |\.|!|\?)%' => ' nein$1', '% not%' => ' nicht', '%Not%' => 'Nicht', '%[Mm]r.%' => 'Herr', '%[Mm]rs.%' => 'Frau', '%Miss%' => 'Fraulein', '% of %' => ' uff ', '%Of %' => 'Uff ', '%my%' => 'mein', '%My%' => 'Mein', '% and %' => ' undt ', '%And %' => 'Undt ', '%and%' => 'ent', '%One %' => 'Ein ', '% one%' => ' ein', '%Is %' => 'Ist ', '% is %' => ' ist ', '%ow %' => 'ow ', '%w %' => 'w ', '% sc%' => ' shc', '%Sc%' => 'Shc', '% st%' => ' sht', '%St%' => 'Sht', '%sh%' => 'sch', '%Sh%' => 'Sch', '%ch%' => 'ch', '%Ch%' => 'Ch', '% c%' => ' k', '% C%' => ' K', '% for %' => ' fur ', '%Have%' => 'Haf', '%have%' => 'haf', '%j%' => 'ch', '%J%' => 'Ch', '%Qu%' => 'Qv', '%qu%' => 'qv', '%rd%' => 'rt', '%v%' => 'f', '%V%' => 'F', '% w%' => ' v', '%W%' => 'V', '%ward%' => 'verrt', '%wh%' => 'v', '%Wh%' => 'V', '% th%' => ' z', '%Th%' => 'Z', '%th%' => 'zz', '%[Cc]offee%' => 'Kafe', '%[Tt]hank[s]*%' => 'Danke', '%[Jj]ohn%' => 'Johann', '%[Ww]illiam%' => 'Wilhelm', '%[Bb]rad%' => 'Wilhelm', '%[Gg]ary%' => 'Gerhardt', '%[Jj]on%' => 'Hansel', '%[a-f]!%' => '$1 Naturlich!', '%[p-z]!%' => '$1 Seig Heil!' ); $content = array_apply_regexp($patterns,$content); return $content; } function jive($content) { return filter_cdata_content($content,'jive_filter'); } function jive_filter($content) { $content = $content[1]; $patterns = array( '%file%' => 'stash', '%send%' => "t'row", '%program%' => 'honky code', '%atlas%' => 'Isaac', '%unix%' => 'slow mo-fo', '%UNIX%' => 'that slow mo-fo', '%takes%' => "snatch'd", '%Mexican%' => 'wet-back', '%Italian%' => 'greaser', '%take%' => 'snatch', "%don't%" => "duzn't", '%jive%' => 'JIBE', '%fool%' => 'honkyfool', '%modem%' => 'doodad', '%e the %' => 'e da damn ', '%a the %' => 'a da damn ', '%t the %' => 't da damn ', '%d the %' => 'd da damn ', '% man %' => ' dude ', '%woman%' => 'mama', '%girl%' => 'goat', '%somethin%' => "sump'n", '% lie %' => ' honky jibe ', '%([a-b]\.)%' => '$1 Sheeeiit.', '%([e-f]\.)%' => '$1 What it is, Mama!', '%([i-j]\.)%' => "$1 Ya' know?", '%([m-n]\.)%' => "$1 'S coo', bro.", '%([q-r]\.)%' => '$1 Ah be baaad...', '%([u-v]\.)%' => '$1 Man!', '%([y-z]\.)%' => '$1 Slap mah fro!', '%Sure%' => "Sho' nuff", '%sure%' => "sho' nuff", '% get %' => ' git', '%will have%' => "gots'ta", '%will%' => "gots'ta ", '%got to%' => "gots'ta", '%I am%' => "I's gots'ta be", '%am not %' => 'aint ', '%is not %' => 'aint ', '%are not %' => 'aint', '% are your %' => " is yo' ", '% are you %' => ' you is ', '% hat %' => ' fedora ', '% shoe %' => ' kicker ', "%haven't%" => 'aint', '%have to%' => "gots'ta", '%have%' => "gots'", '% has%' => " gots'ta", '%come over%' => 'mosey on down', '% come %' => ' mosey on down ', '%!%' => '. Right On!', '%buy %' => 'steal', '% car %' => ' wheels ', '%drive%' => 'roll', '% eat %' => ' feed da bud ', '% black %' => ' brother ', '% negro %' => ' brother', '%white%' => 'honky', '%nigger%' => ' gentleman ', '%nice%' => "supa' fine", '%person%' => "sucka'", '% thing%' => ' wahtahmellun', '%home%' => 'plantation', '%name%' => 'dojigger', '% path%' => ' alley', '%computer%' => 'clunker', '%or%' => "o'", '%killed%' => 'wasted', '%president%' => 'super-dude', '%prime minister%' => 'super honcho', '%injured%' => 'hosed', '%government%' => "guv'ment", '%knew%' => 'knowed', '%because%' => "a'cuz", '%Because%' => "A'cuz", '%your%' => "yo'", '%Your%' => "Yo'", '%four%' => 'foe', '%got%' => 'gots', "%aren't%" => "ain't", '%young%' => 'yung', '%you%' => "ya'", '%You%' => "You's", '%first%' => 'fust', '%police%' => 'honky pigs', '% string%' => " chittlin'", '% read%' => ' eyeball', '%write%' => 'scribble', '%th%' => 'd', '%Th%' => 'D', '%ing%' => "in'", '% a %' => ' some ', '% to\s+%' => " t'", '%tion%' => 'shun', '% almost %' => " mos' ", '% from%' => ' fum', '% because %' => " cuz' ", "%you're%" => 'youse', "%You're%" => 'Youse', '%alright%' => "coo'", '%okay%' => "coo'", '%er %' => "a' ", '%known%' => 'knode', '%want%' => "wants'", '%beat%' => "whup'", '%exp%' => "'sp", '%exs%' => "'s", '% exc%' => " 's", '% ex%' => " 'es", '%like%' => 'likes', '%did %' => 'dun did', '%kind of%' => "kind'a", '%women%' => 'honky chicks', '% men %' => ' dudes ', '% mens %' => ' dudes ', '% man %' => ' dude ', '%woman%' => 'honky chick', '%dead%' => 'wasted', '%good%' => 'baaaad', '%open %' => 'jimmey ', '%opened %' => "jimmey'd ", '% very%' => ' real', '%per%' => "puh'", '%pera%' => "puh'", '%oar%' => "o'", '% can%' => ' kin', '%just %' => 'plum ', '%detroit%' => 'Mo-town', '%western electric%' => "da' cave", '% believe%' => " recon'", '%[Ii]ndianapolis%' => 'Nap-town', '% [Jj]ack%' => ' Buckwheat', '% [Bb]ob %' => " Liva' Lips ", '% [Pp]hil %' => ' dat fine soul ', '% [Mm]ark %' => ' Amos ', '%[Rr]ober%' => 'Leroy', '%[Ss]andy%' => 'dat fine femahnaine ladee', '%[Jj]ohn %' => "Raz'tus ", '% [Pp]aul%' => " Fuh'rina", '%[Rr]eagan%' => 'Kingfish', '%[Dd]avid%' => 'Issac', '%[Rr]onald%' => 'Rolo', '% [Jj]im %' => ' Bo-Jangles ', '% [Mm]ary%' => ' Snow Flake', '%[Ll]arry%' => 'Remus', '%[Jj]oe%' => "Massa' ", '%[Jj]oseph%' => "Massa' ", '%mohammed%' => "liva' lips", '%pontiff%' => "wiz'", '%pope%' => "wiz'", '%pravda%' => 'dat commie rag', '%broken%' => "bugger'd", '%strange %' => 'funky ', '%dance %' => 'boogy ', '% house%' => ' crib', '%ask %' => "ax'", '% so %' => " so's ", '%head%' => "'haid", '%boss%' => 'main man', '%wife%' => 'mama', '%people%' => "sucka's", '%money%' => "bre'd", '%([a-z]):%' => '$1, dig dis:', '%amateur%' => "begina'", '%radio %' => "transista'", '% of %' => ' uh ', '%what%' => 'whut', '%does%' => 'duz', '%was%' => 'wuz', '% were%' => ' wuz', '%understand it%' => 'dig it', '%understand%' => 'dig it', '% my%' => " mah'", '% [Ii] %' => " ah' ", '%meta%' => "meta-fuckin'", '%hair%' => 'fro', '%talk%' => 'rap', '%music%' => 'beat', '%basket%' => 'hoop', '%football%' => 'ball', '%friend%' => 'homey', '%school%' => 'farm', '%boss%' => 'Man', '%want to%' => 'wanna', '%wants to%' => "be hankerin' aftah", '%well%' => 'sheeit', '%Well%' => 'Sheeit', '%big%' => 'big-ass', '%bad%' => 'bad-ass', '%small%' => 'little-ass', '%sort of%' => 'radical', '% is %' => ' be ', '%water%' => 'booze', '%book%' => "scribblin'", '%magazine%' => 'issue of GQ', '%paper%' => 'sheet', '%\bup\b%' => 'down', '%\bdown\b%' => 'waaay down', '%break%' => 'boogie', '%Hi%' => "'Sup, dude", '%VAX%' => 'pink Cadillac', ); $content = array_apply_regexp($patterns,$content); return $content; } function chef($content) { return filter_cdata_content($content,'chef_filter'); } function chef_filter($content) { $content = $content[1]; $patterns = array( '%an%' => 'un', '%An%' => 'Un', '%au%' => 'oo', '%Au%' => 'Oo', '%(\w)ew%' => '$1oo', '%(\w)ow%' => '$1oo', '%(\W)o%' => '$1oo', '%(\W)O%' => '$1Oo', '%(\w)u%' => '$1oo', '%(\w)U%' => '$1Oo', '%a(\w)%' => 'e$1', '%A(\w)%' => 'E$1', '%en(\W)%' => 'ee$1', '%(\w)e(\W)%' => '$1e-a$2', '%(\W)e%' => '$1i', '%(\W)E%' => '$1I', '%(\w)f%' => '$1ff', '%(\w)ir%' => '$1ur', '%([a-m])i%' => '$1ee', '%([A-M])i%' => '$1EE', '%(\w)o%' => '$1u', '%the%' => 'zee', '%The%' => 'Zee', '%th(\W)%' => 't$1', '%(\w)tion%' => '$1shun', '%v%' => 'f', '%V%' => 'F', '%w%' => 'v', '%W%' => 'V', '%f{2,}%' => 'ff', '%o{2,}%' => 'oo', '%e{2,}%' => 'ee', '%([\.!\?])\s*(]+>)?\s*$%' => '$1 Bork Bork Bork!$2', ); $content = array_apply_regexp($patterns,$content); return $content; }