]*)>(.*?)<\/h\1>/', create_function ('$m',
'return "".titleCase($m[3])."";'
), $s_content
);
//preserve the `` blocks from indenting and wrapping
$chunks = preg_split ('/<\/?pre>/', $s_content);
//is this odd/even? ()
foreach ($chunks as $key => &$chunk) $chunk = ($key & 1)
//`` blocks
? markupSyntax ($chunk)
//wrap and indent the HTML
: wrapAndIndent ($b_absoluteurls
? preg_replace('/href="\//', 'href="http://camendesign.com/', $chunk) : $chunk
)
;
return implode ('', $chunks);
}
//word wraps, and then indents to match. why? I’m anal-retentive about HTML output and believe that the source should
//always be indented correctly and wrapped accordingly, to allow better debugging and easy readability for those who are
//interested in the source code
function wrapAndIndent ($s_text, $i_dent_count = 1) {
//indent already existing line breaks
$indent = str_repeat ("\t", $i_dent_count);
$s_text = str_replace ("\n", "\n$indent", $s_text);
//convert tabs to 8 spaces, for the wrap limit
$s_text = str_replace ("\t", ' ', $s_text);
//the reason 125 is used as the wrap margin is because firefox’s view->source window maxmized at
//1024x768 is 125 chars wide and seems like a modern enough standard for code, compared to the
//behaviour of writing notepad readme files at 77 chars wide because that’s the viewport of a
//maximised Notepad window on a 640x480 screen. tabs of 8 are used because this is what firefox &
//Notepad use, and it encourages reworking code to use less indentation
$offset = 0;
while (preg_match (
//I wrote this, and I still have no solid understanding why it works. essentially it finds
//the first space character before the wrap margin that is not within an html tag, but also
//remembers the number of tabs at the beginning of each line
'/(?:^|\n)(?=.{125})((?:\040{8})+)?(?:.{'.(109-8*$i_dent_count).',}?)(\040)(?![^<]*>)/',
$s_text, $a_result, PREG_OFFSET_CAPTURE, $offset
) == 1) $s_text = substr_replace ($s_text, "\n".$a_result[1][0], $offset = $a_result[2][1], 1);
//return sets of 8 spaces back to tabs
return str_replace (' ', "\t", $s_text);
}
//splits pre blocks into lines of `` elements
//this needs to be expanded in the future to syntax colour automatically
function markupSyntax ($s_text) {
return ''.array_reduce (
//split into lines
explode ("\n", preg_replace (
//retain syntax markup tags
'/<(\/?)(samp|var|dfn|i)>/', '<$1$2>',
//also auto-encodes the pre block to save having to type “>” & “<” manually
htmlspecialchars (trim ($s_text), ENT_NOQUOTES)
)),
create_function ('$a,$v','$a.="$v\n";return $a;')
).'';
}
//correctly Title Case text, accounting for fringe cases
function titleCase ($s_title) {
//original Title Case script © John Gruber
//javascript port © David Gouch
//remove HTML, storing it for later
// HTML elements to ignore | tags | entities
$regex = '/<(code|var)[^>]*>.*?<\/\1>|<[^>]+>|&[^\w]+;/';
preg_match_all ($regex, $s_title, $html, PREG_OFFSET_CAPTURE);
$result = preg_replace ($regex, '', $s_title);
//break by punctuation, find the start of words
preg_match_all ('/[\w&`\'‘’"“\.@:\/\{\(\[<>_]+-? */', $result, $matches, PREG_OFFSET_CAPTURE);
foreach ($matches[0] as &$m) {
//find words that should be lowercase
if ($m[1]>0 && mb_substr ($result, $m[1]-2, 1) !== ':' && preg_match (
'/^(a(nd?|s|t)?|b(ut|y)|en|for|i[fn]|o[fnr]|t(he|o)|vs?\.?|via)[ \-]/i', $m[0]
)) {
$m[0] = mb_strtolower ($m[0]);
//brackets and other wrappers
} elseif (preg_match ('/[\'"_{(\[]/', mb_substr ($result, $m[1], 3))) {
$m[0] = mb_substr ($m[0], 0, 1).mb_strtoupper (mb_substr ($m[0], 1, 1)).mb_substr ($m[0], 2);
//both of these cases are no change, thus if not matched fall back to capitalisation
} elseif (!(
preg_match ('/[A-Z]+|&|[\w]+[._][\w]+/', mb_substr ($m[0], 1)) ||
preg_match ('/[\])}]/', mb_substr ($result, $m[1]-1, 3))
)) {
$m[0] = mb_strtoupper (mb_substr ($m[0], 0, 1)).mb_substr ($m[0], 1);
}
//substitute the change into the title
$result = substr_replace ($result, $m[0], $m[1], strlen ($m[0]));
}
//restore the HTML
foreach ($html[0] as $tag) $result = substr_replace ($result, $tag[0], $tag[1], 0);
return $result;
}
/* ==================================================================================================== code is art === */ ?>