diff --git a/b2-include/b2vars.php b/b2-include/b2vars.php index 01399c0f3e..d1fa02b8a2 100644 --- a/b2-include/b2vars.php +++ b/b2-include/b2vars.php @@ -3,7 +3,7 @@ /* This file sets various arrays and variables for use in b2 */ #b2 version -$b2_version = '0.6.1'; +$b2_version = '0.7'; #BBcode search and replace arrays $b2_bbcode['in'] = array( @@ -267,9 +267,12 @@ foreach($b2smiliestrans as $smiley => $img) { } $b2_smiliesreplace[] = "$smiley_masked"; } +include_once('textile.php'); add_filter('all', 'wptexturize'); add_filter('the_content', 'wpautop'); add_filter('comment_text', 'wpautop'); - + // Uncomment the next line for Textile support + // add_filter('the_content', 'textile'); + // There is some duplication of effore so textile.php really should be tweaked to eliminate that. ?> \ No newline at end of file diff --git a/b2-include/textile.php b/b2-include/textile.php new file mode 100644 index 0000000000..53dd9be528 --- /dev/null +++ b/b2-include/textile.php @@ -0,0 +1,500 @@ +Text + +Header with CSS class: hn(class). +Paragraphs beginning with 'hn(class). ' receive a CSS class attribute. +Example:

Text

+ +Paragraph: p. (applied by default) +Paragraphs beginning with 'p. ' are wrapped in paragraph tags. +Example:

Text

+ +Paragraph with CSS class: p(class). +Paragraphs beginning with 'p(class). ' receive a CSS class attribute. +Example:

Text

+ +Blockquote: bq. +Paragraphs beginning with 'bq. ' are wrapped in block quote tags. +Example:
Text
+ +Blockquote with citation: bq(citeurl). +Paragraphs beginning with 'bq(citeurl). ' receive a citation attribute. +Example:
Text
+ +Numeric list: # +Consecutive paragraphs beginning with # are wrapped in ordered list tags. +Example:
  1. ordered list
+ +Bulleted list: * +Consecutive paragraphs beginning with * are wrapped in unordered list tags. +Example: + + +Phrase modifier syntax: + +_emphasis_ emphasis +__italic__ italic +*strong* strong +**bold** bold +??citation?? citation +-deleted text- deleted ++inserted text+ inserted +^superscript^ superscript +~subscript~ subscript +@code@ computer code + +==notextile== leave text alone (do not format) + +"linktext":url linktext +"linktext(title)":url linktext + +!imageurl! +!imageurl(alt text)! alt text +!imageurl!:linkurl + +ABC(Always Be Closing) ABC + +*/ + + + function textile($text) { + +### Basic global changes + + $text = stripslashes($text); + + # turn any incoming ampersands into a dummy character for now. + # This uses a negative lookahead for alphanumerics followed by a semicolon, + # implying an incoming html entity, to be skipped + $text = preg_replace("/&(?![#a-zA-Z0-9]+;)/","x%x%",$text); + + # entify everything + if (function_exists('mb_encode_numericentity')) { + $text = encode_high($text); + } else { + $text = htmlentities($text,ENT_NOQUOTES,"utf-8"); + } + + # unentify angle brackets and ampersands + $text = str_replace(array(">", "<", "&"), array(">", "<", "&"), $text); + + # zap carriage returns + $text = str_replace("\r\n", "\n", $text); + + # zap tabs + $text = str_replace("\t", "", $text); + + $text = preg_split("/\n/",$text); + foreach($text as $line){ + $line = trim($line); + $lineout[] = $line; + } + + $text = implode("\n",$lineout); + +### Find and replace quick tags + + # double equal signs means + $text = preg_replace('/(^|\s)==(.*)==(\s|$)?/msU','$1$2$3',$text); + + + # image qtag + $text = preg_replace('/!([^\s\(=]+)\s?(?:\(([^\)]+)\))?!(\s)?/mU','$2$3',$text); + + + # image with hyperlink + $text = preg_replace('/():(\S+)(\s)/U','$1$3',$text); + + # hyperlink qtag + $text = preg_replace( + '/ + ([\s[{(]|[[:punct:]])? # 1 optional space or brackets before + " # starting " + ([^"\(]+) # 2 text of link + \s? # opt space + (?:\(([^\(]*)\))? # 3 opt title attribute in parenths + ": # dividing ": + (\S+\b) # 4 suppose this is the url + (\/)? # 5 opt trailing slash + ([^[:alnum:]\/;]*) # 6 opt punctuation after the url + (\s|$) # 7 either white space or end of string + /x', + '$1$2$6$7',$text); + + + # arrange qtag delineators and replacements in an array + $qtags = array( + '\*\*'=>'b', + '\*'=>'strong', + '\?\?'=>'cite', + '-'=>'del', + '\+'=>'ins', + '~'=>'sub', + '@'=>'code'); + + # loop through the array, replacing qtags with html + foreach($qtags as $f=>$r){ + $text = preg_replace( + '/(^|\s|>)'.$f.'\b(.+)\b([[:punct:]]*)'.$f.'([[:punct:]]{0,2})(\s|$)?/mU', + '$1<'.$r.'>$2$3$4$5', + $text); + } + + + # some weird bs with underscores and \b word boundaries, + # so we'll do those on their own + $text = preg_replace('/(^|\s)__(.*)__([[:punct:]]{0,2})(\s|$)?/mU','$1$2$3$4',$text); + $text = preg_replace('/(^|\s)_(.*)_([[:punct:]]{0,2})(\s|$)?/mU','$1$2$3$4',$text); + + $text = preg_replace('/\^(.*)\^/mU','$1',$text); + + + +### Find and replace typographic chars and special tags + + # small problem with double quotes at the end of a string + $text = preg_replace('/"$/',"\" ", $text); + + # NB: all these will wreak havoc inside tags + + $glyph_search = array( + '/([^\s[{(>])?\'(?(1)|(?=\s|s\b))/', # single closing + '/\'/', # single opening + '/([^\s[{(])?"(?(1)|(?=\s))/', # double closing + '/"/', # double opening + '/\b( )?\.{3}/', # ellipsis + '/\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/', # 3+ uppercase acronym + '/(^|[^"][>\s])([A-Z][A-Z0-9 ]{2,})([^$1', # 3+ uppercase acronym + '$1$2$3', # 3+ uppercase caps + '—', # em dash + ' – ', # en dash + '$1×$2', # dimension sign + '™', # trademark + '®', # registered + '©'); # copyright + + # set toggle for turning off replacements between or
+	$codepre = false;
+
+		# if there is no html, do a simple search and replace
+	if(!preg_match("/<.*>/",$text)){
+		$text = preg_replace($glyph_search,$glyph_replace,$text);
+	} else {
+	
+			# else split the text into an array at <.*>
+		$text = preg_split("/(<.*>)/U",$text,-1,PREG_SPLIT_DELIM_CAPTURE);
+			foreach($text as $line){
+			
+					# matches are off if we're between , 
 etc. 
+				if(preg_match('/<(code|pre|kbd|notextile)>/i',$line)){$codepre = true; }
+				if(preg_match('/<\/(code|pre|kbd|notextile)>/i',$line)){$codepre = false; }
+			
+				if(!preg_match("/<.*>/",$line) && $codepre == false){
+					$line = preg_replace($glyph_search,$glyph_replace,$line);
+				}
+
+				# convert htmlspecial if between 
+				if ($codepre == true){
+					$line = htmlspecialchars($line,ENT_NOQUOTES,"UTF-8");
+					$line = str_replace("<pre>","
",$line);
+					$line = str_replace("<code>","",$line);
+					$line = str_replace("<notextile>","",$line);
+					$line = str_replace("<kbd>","",$line);
+				}
+
+				# each line gets pushed to a new array
+			$glyph_out[] = $line;
+		}
+			# $text is now the new array, cast to a string 
+		$text = implode('',$glyph_out);
+	}
+
+	
+### Block level formatting
+
+	# deal with forced breaks; this is going to be a problem between
+	#  
 tags, but we'll clean them later
+	$text = preg_replace("/(\S)(_*)([[:punct:]]*) *\n([^#*\s])/", "$1$2$3
$4", $text); + + # might be a problem with lists + $text = str_replace("l>
", "l>\n", $text); + + # clear out multiple newlines for now +# $text = preg_replace("/\n+/","\n",$text); + + # split the text into an array by newlines + $text = preg_split("/\n/",$text); + + array_push($text," "); + + $list = ''; + $pre = false; + + $block_find = array( + '/^\s?\*\s(.*)/', # bulleted list * + '/^\s?#\s(.*)/', # numeric list # + '/^bq\. (.*)/', # blockquote bq. + '/^h(\d)\(([[:alnum:]]+)\)\.\s(.*)/', # header hn(class). w/ css class + '/^h(\d)\. (.*)/', # plain header hn. + '/^p\(([[:alnum:]]+)\)\.\s(.*)/', # para p(class). w/ css class + '/^p\. (.*)/i', # plain paragraph + '/^([^\t ]+.*)/i' # remaining plain paragraph + ); + + $block_replace = array( + "\t\t
  • $1
  • ", + "\t\t\t
  • $1
  • ", + "\t
    $1
    ", + "\t$3$4", + "\t$2$3", + "\t

    $2

    $3", + "\t

    $1

    ", + "\t

    $1

    $2" + ); + + + # loop through lines + foreach($text as $line){ + + # matches are off if we're between
     or  tags 
    +			if(preg_match('/
    /i',$line)){$pre = true; }
    +
    +			# deal with block replacements first, then see if we're in a list
    +			if ($pre == false){
    +				$line = preg_replace($block_find,$block_replace,$line);
    +			}
    +
    +			# kill any br tags that slipped in earlier
    +			if ($pre == true){
    +				$line = str_replace("
    ","\n",$line); + } + + # matches back on after
    + if(preg_match('/<\/pre>/i',$line)){$pre = false; } + + # on entry to a list, $list switches to a value + # two tabs means unordered list + if ($list == '' && preg_match('/^\t\t
  • /',$line)){ + $list = "ul"; + $line = preg_replace('/^(\t\t
  • .*)/',"\t
      \n$1",$line); + + } else if ($list == '' && preg_match('/^\t\t\t
    • /',$line)){ + $list = "ol"; + $line = preg_replace('/^\t(\t\t
    • .*)/',"\t
        \n$1",$line); + + # at the end of a ul + } else if ($list == 'ul' && !preg_match('/^\t\t
      1. /',$line)){ + $list = ''; + $line = preg_replace('/^(.*)$/',"\t
    \n$1",$line); + + # at the end of a ol + } else if ($list == 'ol' && !preg_match('/^\t\t\t
  • /',$line)){ + $list = ''; + $line = preg_replace('/^(.*)$/',"\t\n$1",$line); + } + + + # push each line to a new array once processed + $block_out[] = $line; + } + $text = implode("\n",$block_out); + + #clean up + $text = preg_replace('/<\/?notextile>/', "",$text); + + # turn the temp char back to an ampersand entity + $text = str_replace("x%x%","&",$text); + + # Newline linebreaks, just for markup tidiness + $text = str_replace("
    ","
    \n",$text); + + return $text; + + } + + + function callback_url($text,$title='',$url) { + + $out = 'a href="'.$url.'"'; + $out.=($title!='')?' title="'.$title.'"':''; + $out.='>$text'; + return $out; + } + + + + function textile_popup_help($name,$helpvar,$windowW,$windowH) { + + $out = $name; + $out .= ' ?
    '; + + print $out; + } + + + function encode_high($text) { + $cmap = cmap(); + return mb_encode_numericentity($text, $cmap, "UTF-8"); + } + + + function decode_high($text) { + $cmap = cmap(); + return mb_decode_numericentity($text, $cmap, "UTF-8"); + } + + + function cmap() { + + $f = 0xffff; + + $cmap = array( + 160, 255, 0, $f, + 402, 402, 0, $f, + 913, 929, 0, $f, + 931, 937, 0, $f, + 945, 969, 0, $f, + 977, 978, 0, $f, + 982, 982, 0, $f, + 8226, 8226, 0, $f, + 8230, 8230, 0, $f, + 8242, 8243, 0, $f, + 8254, 8254, 0, $f, + 8260, 8260, 0, $f, + 8465, 8465, 0, $f, + 8472, 8472, 0, $f, + 8476, 8476, 0, $f, + 8482, 8482, 0, $f, + 8501, 8501, 0, $f, + 8592, 8596, 0, $f, + 8629, 8629, 0, $f, + 8656, 8660, 0, $f, + 8704, 8704, 0, $f, + 8706, 8707, 0, $f, + 8709, 8709, 0, $f, + 8711, 8713, 0, $f, + 8715, 8715, 0, $f, + 8719, 8719, 0, $f, + 8721, 8722, 0, $f, + 8727, 8727, 0, $f, + 8730, 8730, 0, $f, + 8733, 8734, 0, $f, + 8736, 8736, 0, $f, + 8743, 8747, 0, $f, + 8756, 8756, 0, $f, + 8764, 8764, 0, $f, + 8773, 8773, 0, $f, + 8776, 8776, 0, $f, + 8800, 8801, 0, $f, + 8804, 8805, 0, $f, + 8834, 8836, 0, $f, + 8838, 8839, 0, $f, + 8853, 8853, 0, $f, + 8855, 8855, 0, $f, + 8869, 8869, 0, $f, + 8901, 8901, 0, $f, + 8968, 8971, 0, $f, + 9001, 9002, 0, $f, + 9674, 9674, 0, $f, + 9824, 9824, 0, $f, + 9827, 9827, 0, $f, + 9829, 9830, 0, $f, + 338, 339, 0, $f, + 352, 353, 0, $f, + 376, 376, 0, $f, + 710, 710, 0, $f, + 732, 732, 0, $f, + 8194, 8195, 0, $f, + 8201, 8201, 0, $f, + 8204, 8207, 0, $f, + 8211, 8212, 0, $f, + 8216, 8218, 0, $f, + 8218, 8218, 0, $f, + 8220, 8222, 0, $f, + 8224, 8225, 0, $f, + 8240, 8240, 0, $f, + 8249, 8250, 0, $f, + 8364, 8364, 0, $f + ); + + return $cmap; + } + + +function linkit($text,$title,$url){ + $url = preg_replace("/&(?!amp;)/","&",$url); + $out = ''; + + return $out; +} + + +?>