From: garvinhicking Date: Thu, 6 Dec 2007 11:12:30 +0000 (+0000) Subject: Update textile X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=7dfba96a69bd31eb7cc7e1a1c25bafdbb0ed93c9;p=s9y.git Update textile --- diff --git a/plugins/serendipity_event_textile/UTF-8/lang_bg.inc.php b/plugins/serendipity_event_textile/UTF-8/lang_bg.inc.php index a4393cb..2328c9f 100644 --- a/plugins/serendipity_event_textile/UTF-8/lang_bg.inc.php +++ b/plugins/serendipity_event_textile/UTF-8/lang_bg.inc.php @@ -3,8 +3,11 @@ /** * @version $Revision$ * @author Ivan Cenov jwalker@hotmail.bg - */ + * EN-Revision: 2034 +*/ @define('PLUGIN_EVENT_TEXTILE_NAME', 'Форматиране на текст: Textile'); @define('PLUGIN_EVENT_TEXTILE_DESC', 'Форматиране на текст чрез Textile конвертор.'); @define('PLUGIN_EVENT_TEXTILE_TRANSFORM', 'Форматиране Textile е разрешено'); + @define('PLUGIN_EVENT_TEXTILE_VERSION', 'Версия на Textile'); + @define('PLUGIN_EVENT_TEXTILE_VERSION_DESCRIPTION', 'Коя версия на Textile искате да използвате?'); diff --git a/plugins/serendipity_event_textile/classTextile.php b/plugins/serendipity_event_textile/classTextile.php new file mode 100644 index 0000000..f8e8338 --- /dev/null +++ b/plugins/serendipity_event_textile/classTextile.php @@ -0,0 +1,1135 @@ +TextileThis($string); + * + */ + +/* +$Id: classTextile.php 216 2006-10-17 22:31:53Z zem $ +$LastChangedRevision: 216 $ +*/ + +/* + +_____________ +T E X T I L E + +A Humane Web Text Generator + +Version 2.0 + +Copyright (c) 2003-2004, Dean Allen +All rights reserved. + +Thanks to Carlo Zottmann for refactoring +Textile's procedural code into a class framework + +Additions and fixes Copyright (c) 2006 Alex Shiels http://thresholdstate.com/ + +_____________ +L I C E N S E + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name Textile nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +_________ +U S A G E + +Block modifier syntax: + + Header: h(1-6). + Paragraphs beginning with 'hn. ' (where n is 1-6) are wrapped in header tags. + Example: h1. Header... ->

Header...

+ + Paragraph: p. (also applied by default) + Example: p. Text ->

Text

+ + Blockquote: bq. + Example: bq. Block quotation... ->
Block quotation...
+ + Blockquote with citation: bq.:http://citation.url + Example: bq.:http://textism.com/ Text... + ->
Text...
+ + Footnote: fn(1-100). + Example: fn1. Footnote... ->

Footnote...

+ + 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:
  • unordered list
+ +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 + %(bob)span% -> span + + ==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 + + +Table syntax: + + Simple tables: + + |a|simple|table|row| + |And|Another|table|row| + + |_. A|_. table|_. header|_.row| + |A|simple|table|row| + + Tables with attributes: + + table{border:1px solid black}. + {background:#ddd;color:red}. |{}| | | | + + +Applying Attributes: + + Most anywhere Textile code is used, attributes such as arbitrary css style, + css classes, and ids can be applied. The syntax is fairly consistent. + + The following characters quickly alter the alignment of block elements: + + < -> left align ex. p<. left-aligned para + > -> right align h3>. right-aligned header 3 + = -> centred h4=. centred header 4 + <> -> justified p<>. justified paragraph + + These will change vertical alignment in table cells: + + ^ -> top ex. |^. top-aligned table cell| + - -> middle |-. middle aligned| + ~ -> bottom |~. bottom aligned cell| + + Plain (parentheses) inserted between block syntax and the closing dot-space + indicate classes and ids: + + p(hector). paragraph ->

paragraph

+ + p(#fluid). paragraph ->

paragraph

+ + (classes and ids can be combined) + p(hector#fluid). paragraph ->

paragraph

+ + Curly {brackets} insert arbitrary css style + + p{line-height:18px}. paragraph ->

paragraph

+ + h3{color:red}. header 3 ->

header 3

+ + Square [brackets] insert language attributes + + p[no]. paragraph ->

paragraph

+ + %[fr]phrase% -> phrase + + Usually Textile block element syntax requires a dot and space before the block + begins, but since lists don't, they can be styled just using braces + + #{color:blue} one ->
    + # big
  1. one
  2. + # list
  3. big
  4. +
  5. list
  6. +
+ + Using the span tag to style a phrase + + It goes like this, %{color:red}the fourth the fifth% + -> It goes like this, the fourth the fifth + +*/ + +// define these before including this file to override the standard glyphs +@define('txt_quote_single_open', '‘'); +@define('txt_quote_single_close', '’'); +@define('txt_quote_double_open', '“'); +@define('txt_quote_double_close', '”'); +@define('txt_apostrophe', '’'); +@define('txt_prime', '′'); +@define('txt_prime_double', '″'); +@define('txt_ellipsis', '…'); +@define('txt_emdash', '—'); +@define('txt_endash', '–'); +@define('txt_dimension', '×'); +@define('txt_trademark', '™'); +@define('txt_registered', '®'); +@define('txt_copyright', '©'); + +class Textile +{ + var $hlgn; + var $vlgn; + var $clas; + var $lnge; + var $styl; + var $cspn; + var $rspn; + var $a; + var $s; + var $c; + var $pnct; + var $rel; + var $fn; + + var $shelf = array(); + var $restricted = false; + var $noimage = false; + var $lite = false; + var $url_schemes = array(); + var $glyph = array(); + var $hu = ''; + + var $ver = '2.0.0'; + var $rev = '$Rev: 216 $'; + +// ------------------------------------------------------------- + function Textile() + { + $this->hlgn = "(?:\<(?!>)|(?|\<\>|\=|[()]+(?! ))"; + $this->vlgn = "[\-^~]"; + $this->clas = "(?:\([^)]+\))"; + $this->lnge = "(?:\[[^]]+\])"; + $this->styl = "(?:\{[^}]+\})"; + $this->cspn = "(?:\\\\\d+)"; + $this->rspn = "(?:\/\d+)"; + $this->a = "(?:{$this->hlgn}|{$this->vlgn})*"; + $this->s = "(?:{$this->cspn}|{$this->rspn})*"; + $this->c = "(?:{$this->clas}|{$this->styl}|{$this->lnge}|{$this->hlgn})*"; + + $this->pnct = '[\!"#\$%&\'()\*\+,\-\./:;<=>\?@\[\\\]\^_`{\|}\~]'; + $this->urlch = '[\w"$\-_.+!*\'(),";\/?:@=&%#{}|\\^~\[\]`]'; + + $this->url_schemes = array('http','https','ftp','mailto'); + + $this->btag = array('bq', 'bc', 'notextile', 'pre', 'h[1-6]', 'fn\d+', 'p'); + + $this->glyph = array( + 'quote_single_open' => txt_quote_single_open, + 'quote_single_close' => txt_quote_single_close, + 'quote_double_open' => txt_quote_double_open, + 'quote_double_close' => txt_quote_double_close, + 'apostrophe' => txt_apostrophe, + 'prime' => txt_prime, + 'prime_double' => txt_prime_double, + 'ellipsis' => txt_ellipsis, + 'emdash' => txt_emdash, + 'endash' => txt_endash, + 'dimension' => txt_dimension, + 'trademark' => txt_trademark, + 'registered' => txt_registered, + 'copyright' => txt_copyright, + ); + + if (defined('hu')) + $this->hu = hu; + + } + +// ------------------------------------------------------------- + function TextileThis($text, $lite='', $encode='', $noimage='', $strict='', $rel='') + { + if ($rel) + $this->rel = ' rel="'.$rel.'" '; + $this->lite = $lite; + $this->noimage = $noimage; + + if ($encode) { + $text = $this->incomingEntities($text); + $text = str_replace("x%x%", "&", $text); + return $text; + } else { + + if(!$strict) { + $text = $this->cleanWhiteSpace($text); + } + + $text = $this->getRefs($text); + + if (!$lite) { + $text = $this->block($text); + } + + $text = $this->retrieve($text); + + // just to be tidy + $text = str_replace("
", "
\n", $text); + + return $text; + } + } + +// ------------------------------------------------------------- + function TextileRestricted($text, $lite=1, $noimage=1, $rel='nofollow') + { + $this->restricted = true; + $this->lite = $lite; + $this->noimage = $noimage; + if ($rel) + $this->rel = ' rel="'.$rel.'" '; + + // escape any raw html + $text = $this->encode_html($text, 0); + + $text = $this->cleanWhiteSpace($text); + $text = $this->getRefs($text); + + if ($lite) { + $text = $this->blockLite($text); + } + else { + $text = $this->block($text); + } + + $text = $this->retrieve($text); + + // just to be tidy + $text = str_replace("
", "
\n", $text); + + return $text; + } + +// ------------------------------------------------------------- + function pba($in, $element = "") // "parse block attributes" + { + $style = ''; + $class = ''; + $lang = ''; + $colspan = ''; + $rowspan = ''; + $id = ''; + $atts = ''; + + if (!empty($in)) { + $matched = $in; + if ($element == 'td') { + if (preg_match("/\\\\(\d+)/", $matched, $csp)) $colspan = $csp[1]; + if (preg_match("/\/(\d+)/", $matched, $rsp)) $rowspan = $rsp[1]; + } + + if ($element == 'td' or $element == 'tr') { + if (preg_match("/($this->vlgn)/", $matched, $vert)) + $style[] = "vertical-align:" . $this->vAlign($vert[1]) . ";"; + } + + if (preg_match("/\{([^}]*)\}/", $matched, $sty)) { + $style[] = rtrim($sty[1], ';') . ';'; + $matched = str_replace($sty[0], '', $matched); + } + + if (preg_match("/\[([^]]+)\]/U", $matched, $lng)) { + $lang = $lng[1]; + $matched = str_replace($lng[0], '', $matched); + } + + if (preg_match("/\(([^()]+)\)/U", $matched, $cls)) { + $class = $cls[1]; + $matched = str_replace($cls[0], '', $matched); + } + + if (preg_match("/([(]+)/", $matched, $pl)) { + $style[] = "padding-left:" . strlen($pl[1]) . "em;"; + $matched = str_replace($pl[0], '', $matched); + } + + if (preg_match("/([)]+)/", $matched, $pr)) { + // $this->dump($pr); + $style[] = "padding-right:" . strlen($pr[1]) . "em;"; + $matched = str_replace($pr[0], '', $matched); + } + + if (preg_match("/($this->hlgn)/", $matched, $horiz)) + $style[] = "text-align:" . $this->hAlign($horiz[1]) . ";"; + + if (preg_match("/^(.*)#(.*)$/", $class, $ids)) { + $id = $ids[2]; + $class = $ids[1]; + } + + if ($this->restricted) + return ($lang) ? ' lang="' . $lang .'"':''; + + return join('',array( + ($style) ? ' style="' . join("", $style) .'"':'', + ($class) ? ' class="' . $class .'"':'', + ($lang) ? ' lang="' . $lang .'"':'', + ($id) ? ' id="' . $id .'"':'', + ($colspan) ? ' colspan="' . $colspan .'"':'', + ($rowspan) ? ' rowspan="' . $rowspan .'"':'' + )); + } + return ''; + } + +// ------------------------------------------------------------- + function hasRawText($text) + { + // checks whether the text has text not already enclosed by a block tag + $r = trim(preg_replace('@<(p|blockquote|div|form|table|ul|ol|pre|h\d)[^>]*?>.*@s', '', trim($text))); + $r = trim(preg_replace('@<(hr|br)[^>]*?/>@', '', $r)); + return '' != $r; + } + +// ------------------------------------------------------------- + function table($text) + { + $text = $text . "\n\n"; + return preg_replace_callback("/^(?:table(_?{$this->s}{$this->a}{$this->c})\. ?\n)?^({$this->a}{$this->c}\.? ?\|.*\|)\n\n/smU", + array(&$this, "fTable"), $text); + } + +// ------------------------------------------------------------- + function fTable($matches) + { + $tatts = $this->pba($matches[1], 'table'); + + foreach(preg_split("/\|$/m", $matches[2], -1, PREG_SPLIT_NO_EMPTY) as $row) { + if (preg_match("/^($this->a$this->c\. )(.*)/m", ltrim($row), $rmtch)) { + $ratts = $this->pba($rmtch[1], 'tr'); + $row = $rmtch[2]; + } else $ratts = ''; + + $cells = array(); + foreach(explode("|", $row) as $cell) { + $ctyp = "d"; + if (preg_match("/^_/", $cell)) $ctyp = "h"; + if (preg_match("/^(_?$this->s$this->a$this->c\. )(.*)/", $cell, $cmtch)) { + $catts = $this->pba($cmtch[1], 'td'); + $cell = $cmtch[2]; + } else $catts = ''; + + $cell = $this->graf($this->span($cell)); + + if (trim($cell) != '') + $cells[] = "\t\t\t$cell"; + } + $rows[] = "\t\t\n" . join("\n", $cells) . ($cells ? "\n" : "") . "\t\t"; + unset($cells, $catts); + } + return "\t\n" . join("\n", $rows) . "\n\t\n\n"; + } + +// ------------------------------------------------------------- + function lists($text) + { + return preg_replace_callback("/^([#*]+$this->c .*)$(?![^#*])/smU", array(&$this, "fList"), $text); + } + +// ------------------------------------------------------------- + function fList($m) + { + $text = explode("\n", $m[0]); + foreach($text as $nr => $line) { + $nextline = isset($text[$nr+1]) ? $text[$nr+1] : false; + if (preg_match("/^([#*]+)($this->a$this->c) (.*)$/s", $line, $m)) { + list(, $tl, $atts, $content) = $m; + $nl = ''; + if (preg_match("/^([#*]+)\s.*/", $nextline, $nm)) + $nl = $nm[1]; + if (!isset($lists[$tl])) { + $lists[$tl] = true; + $atts = $this->pba($atts); + $line = "\t<" . $this->lT($tl) . "l$atts>\n\t\t
  • " . $this->graf($content); + } else { + $line = "\t\t
  • " . $this->graf($content); + } + + if(strlen($nl) <= strlen($tl)) $line .= "
  • "; + foreach(array_reverse($lists) as $k => $v) { + if(strlen($k) > strlen($nl)) { + $line .= "\n\tlT($k) . "l>"; + if(strlen($k) > 1) + $line .= ""; + unset($lists[$k]); + } + } + } + $out[] = $line; + } + return join("\n", $out); + } + +// ------------------------------------------------------------- + function lT($in) + { + return preg_match("/^#+/", $in) ? 'o' : 'u'; + } + +// ------------------------------------------------------------- + function doPBr($in) + { + return preg_replace_callback('@<(p)([^>]*?)>(.*)()@s', array(&$this, 'doBr'), $in); + } + +// ------------------------------------------------------------- + function doBr($m) + { + $content = preg_replace("@(.+)(?|
    )\n(?![#*\s|])@", '$1
    ', $m[3]); + return '<'.$m[1].$m[2].'>'.$content.$m[4]; + } + +// ------------------------------------------------------------- + function block($text) + { + $find = $this->btag; + $tre = join('|', $find); + + $text = explode("\n\n", $text); + + $tag = 'p'; + $atts = $cite = $graf = $ext = ''; + + foreach($text as $line) { + $anon = 0; + if (preg_match("/^($tre)($this->a$this->c)\.(\.?)(?::(\S+))? (.*)$/s", $line, $m)) { + // last block was extended, so close it + if ($ext) + $out[count($out)-1] .= $c1; + // new block + list(,$tag,$atts,$ext,$cite,$graf) = $m; + list($o1, $o2, $content, $c2, $c1) = $this->fBlock(array(0,$tag,$atts,$ext,$cite,$graf)); + + // leave off c1 if this block is extended, we'll close it at the start of the next block + if ($ext) + $line = $o1.$o2.$content.$c2; + else + $line = $o1.$o2.$content.$c2.$c1; + } + else { + // anonymous block + $anon = 1; + if ($ext or !preg_match('/^ /', $line)) { + list($o1, $o2, $content, $c2, $c1) = $this->fBlock(array(0,$tag,$atts,$ext,$cite,$line)); + // skip $o1/$c1 because this is part of a continuing extended block + if ($tag == 'p' and !$this->hasRawText($content)) { + $line = $content; + } + else { + $line = $o2.$content.$c2; + } + } + else { + $line = $this->graf($line); + } + } + + $line = $this->doPBr($line); + $line = preg_replace('/
    /', '
    ', $line); + + if ($ext and $anon) + $out[count($out)-1] .= "\n".$line; + else + $out[] = $line; + + if (!$ext) { + $tag = 'p'; + $atts = ''; + $cite = ''; + $graf = ''; + } + } + if ($ext) $out[count($out)-1] .= $c1; + return join("\n\n", $out); + } + + + +// ------------------------------------------------------------- + function fBlock($m) + { + // $this->dump($m); + list(, $tag, $atts, $ext, $cite, $content) = $m; + $atts = $this->pba($atts); + + $o1 = $o2 = $c2 = $c1 = ''; + + if (preg_match("/fn(\d+)/", $tag, $fns)) { + $tag = 'p'; + $fnid = empty($this->fn[$fns[1]]) ? $fns[1] : $this->fn[$fns[1]]; + $atts .= ' id="fn' . $fnid . '"'; + if (strpos($atts, 'class=') === false) + $atts .= ' class="footnote"'; + $content = '' . $fns[1] . ' ' . $content; + } + + if ($tag == "bq") { + $cite = $this->checkRefs($cite); + $cite = ($cite != '') ? ' cite="' . $cite . '"' : ''; + $o1 = "\t\n"; + $o2 = "\t\t"; + $c2 = "

    "; + $c1 = "\n\t"; + } + elseif ($tag == 'bc') { + $o1 = ""; + $o2 = ""; + $c2 = ""; + $c1 = ""; + $content = $this->shelve($this->encode_html(rtrim($content, "\n")."\n")); + } + elseif ($tag == 'notextile') { + $content = $this->shelve($content); + $o1 = $o2 = ''; + $c1 = $c2 = ''; + } + elseif ($tag == 'pre') { + $content = $this->shelve($this->encode_html(rtrim($content, "\n")."\n")); + $o1 = ""; + $o2 = $c2 = ''; + $c1 = ""; + } + else { + $o2 = "\t<$tag$atts>"; + $c2 = ""; + } + + $content = $this->graf($content); + + return array($o1, $o2, $content, $c2, $c1); + } + +// ------------------------------------------------------------- + function graf($text) + { + // handle normal paragraph text + if (!$this->lite) { + $text = $this->noTextile($text); + $text = $this->code($text); + } + + $text = $this->links($text); + if (!$this->noimage) + $text = $this->image($text); + + if (!$this->lite) { + $text = $this->lists($text); + $text = $this->table($text); + } + + $text = $this->span($text); + $text = $this->footnoteRef($text); + $text = $this->glyphs($text); + return rtrim($text, "\n"); + } + +// ------------------------------------------------------------- + function span($text) + { + $qtags = array('\*\*','\*','\?\?','-','__','_','%','\+','~','\^'); + $pnct = ".,\"'?!;:"; + + foreach($qtags as $f) { + $text = preg_replace_callback("/ + (?:^|(?<=[\s>$pnct])|([{[])) + ($f)(?!$f) + ({$this->c}) + (?::(\S+))? + ([^\s$f]+|\S[^$f\n]*[^\s$f\n]) + ([$pnct]*) + $f + (?:$|([\]}])|(?=[[:punct:]]{1,2}|\s)) + /x", array(&$this, "fSpan"), $text); + } + return $text; + } + +// ------------------------------------------------------------- + function fSpan($m) + { + $qtags = array( + '*' => 'strong', + '**' => 'b', + '??' => 'cite', + '_' => 'em', + '__' => 'i', + '-' => 'del', + '%' => 'span', + '+' => 'ins', + '~' => 'sub', + '^' => 'sup', + ); + + list(,, $tag, $atts, $cite, $content, $end) = $m; + $tag = $qtags[$tag]; + $atts = $this->pba($atts); + $atts .= ($cite != '') ? 'cite="' . $cite . '"' : ''; + + $out = "<$tag$atts>$content$end"; + +// $this->dump($out); + + return $out; + + } + +// ------------------------------------------------------------- + function links($text) + { + return preg_replace_callback('/ + (?:^|(?<=[\s>.$pnct\(])|([{[])) # $pre + " # start + (' . $this->c . ') # $atts + ([^"]+) # $text + \s? + (?:\(([^)]+)\)(?="))? # $title + ": + ('.$this->urlch.'+) # $url + (\/)? # $slash + ([^\w\/;]*) # $post + (?:([\]}])|(?=\s|$|\))) + /Ux', array(&$this, "fLink"), $text); + } + +// ------------------------------------------------------------- + function fLink($m) + { + list(, $pre, $atts, $text, $title, $url, $slash, $post) = $m; + + $url = $this->checkRefs($url); + + $atts = $this->pba($atts); + $atts .= ($title != '') ? ' title="' . $this->encode_html($title) . '"' : ''; + + if (!$this->noimage) + $text = $this->image($text); + + $text = $this->span($text); + $text = $this->glyphs($text); + + $url = $this->relURL($url); + + $out = 'rel . '>' . $text . '' . $post; + + // $this->dump($out); + return $this->shelve($out); + + } + +// ------------------------------------------------------------- + function getRefs($text) + { + return preg_replace_callback("/(?<=^|\s)\[(.+)\]((?:http:\/\/|\/)\S+)(?=\s|$)/U", + array(&$this, "refs"), $text); + } + +// ------------------------------------------------------------- + function refs($m) + { + list(, $flag, $url) = $m; + $this->urlrefs[$flag] = $url; + return ''; + } + +// ------------------------------------------------------------- + function checkRefs($text) + { + return (isset($this->urlrefs[$text])) ? $this->urlrefs[$text] : $text; + } + +// ------------------------------------------------------------- + function relURL($url) + { + $parts = parse_url($url); + if ((empty($parts['scheme']) or @$parts['scheme'] == 'http') and + empty($parts['host']) and + preg_match('/^\w/', @$parts['path'])) + $url = $this->hu.$url; + if ($this->restricted and !empty($parts['scheme']) and + !in_array($parts['scheme'], $this->url_schemes)) + return '#'; + return $url; + } + +// ------------------------------------------------------------- + function image($text) + { + return preg_replace_callback("/ + (?:[[{])? # pre + \! # opening ! + (\<|\=|\>)?? # optional alignment atts + ($this->c) # optional style,class atts + (?:\. )? # optional dot-space + ([^\s(!]+) # presume this is the src + \s? # optional space + (?:\(([^\)]+)\))? # optional title + \! # closing + (?::(\S+))? # optional href + (?:[\]}]|(?=\s|$)) # lookahead: space or end of string + /Ux", array(&$this, "fImage"), $text); + } + +// ------------------------------------------------------------- + function fImage($m) + { + list(, $algn, $atts, $url) = $m; + $atts = $this->pba($atts); + $atts .= ($algn != '') ? ' align="' . $this->iAlign($algn) . '"' : ''; + $atts .= (isset($m[4])) ? ' title="' . $m[4] . '"' : ''; + $atts .= (isset($m[4])) ? ' alt="' . $m[4] . '"' : ' alt=""'; + $size = @getimagesize($url); + if ($size) $atts .= " $size[3]"; + + $href = (isset($m[5])) ? $this->checkRefs($m[5]) : ''; + $url = $this->checkRefs($url); + + $url = $this->relURL($url); + + $out = array( + ($href) ? '' : '', + '', + ($href) ? '' : '' + ); + + return join('',$out); + } + +// ------------------------------------------------------------- + function code($text) + { + $text = $this->doSpecial($text, '', '', 'fCode'); + $text = $this->doSpecial($text, '@', '@', 'fCode'); + $text = $this->doSpecial($text, '
    ', '
    ', 'fPre'); + return $text; + } + +// ------------------------------------------------------------- + function fCode($m) + { + @list(, $before, $text, $after) = $m; + if ($this->restricted) + // $text is already escaped + return $before.$this->shelve(''.$text.'').$after; + else + return $before.$this->shelve(''.$this->encode_html($text).'').$after; + } + +// ------------------------------------------------------------- + function fPre($m) + { + @list(, $before, $text, $after) = $m; + if ($this->restricted) + // $text is already escaped + return $before.'
    '.$this->shelve($text).'
    '.$after; + else + return $before.'
    '.$this->shelve($this->encode_html($text)).'
    '.$after; + } +// ------------------------------------------------------------- + function shelve($val) + { + $i = uniqid(rand()); + $this->shelf[$i] = $val; + return $i; + } + +// ------------------------------------------------------------- + function retrieve($text) + { + if (is_array($this->shelf)) + do { + $old = $text; + $text = strtr($text, $this->shelf); + } while ($text != $old); + + return $text; + } + +// ------------------------------------------------------------- +// NOTE: deprecated + function incomingEntities($text) + { + return preg_replace("/&(?![#a-z0-9]+;)/i", "x%x%", $text); + } + +// ------------------------------------------------------------- +// NOTE: deprecated + function encodeEntities($text) + { + return (function_exists('mb_encode_numericentity')) + ? $this->encode_high($text) + : htmlentities($text, ENT_NOQUOTES, "utf-8"); + } + +// ------------------------------------------------------------- +// NOTE: deprecated + function fixEntities($text) + { + /* de-entify any remaining angle brackets or ampersands */ + return str_replace(array(">", "<", "&"), + array(">", "<", "&"), $text); + } + +// ------------------------------------------------------------- + function cleanWhiteSpace($text) + { + $out = str_replace("\r\n", "\n", $text); + $out = preg_replace("/\n{3,}/", "\n\n", $out); + $out = preg_replace("/\n *\n/", "\n\n", $out); + $out = preg_replace('/"$/', "\" ", $out); + return $out; + } + +// ------------------------------------------------------------- + function doSpecial($text, $start, $end, $method='fSpecial') + { + return preg_replace_callback('/(^|\s|[[({>])'.preg_quote($start, '/').'(.*?)'.preg_quote($end, '/').'(\s|$|[\])}])?/ms', + array(&$this, $method), $text); + } + +// ------------------------------------------------------------- + function fSpecial($m) + { + // A special block like notextile or code + @list(, $before, $text, $after) = $m; + return $before.$this->shelve($this->encode_html($text)).$after; + } + +// ------------------------------------------------------------- + function noTextile($text) + { + $text = $this->doSpecial($text, '', '', 'fTextile'); + return $this->doSpecial($text, '==', '==', 'fTextile'); + + } + +// ------------------------------------------------------------- + function fTextile($m) + { + @list(, $before, $notextile, $after) = $m; + #$notextile = str_replace(array_keys($modifiers), array_values($modifiers), $notextile); + return $before.$this->shelve($notextile).$after; + } + +// ------------------------------------------------------------- + function footnoteRef($text) + { + return preg_replace('/\b\[([0-9]+)\](\s)?/Ue', + '$this->footnoteID(\'\1\',\'\2\')', $text); + } + +// ------------------------------------------------------------- + function footnoteID($id, $t) + { + if (empty($this->fn[$id])) + $this->fn[$id] = uniqid(rand()); + $fnid = $this->fn[$id]; + return ''.$id.''.$t; + } + +// ------------------------------------------------------------- + function glyphs($text) + { + // fix: hackish + $text = preg_replace('/"\z/', "\" ", $text); + $pnc = '[[:punct:]]'; + + $glyph_search = array( + '/(\w)\'(\w)/', // apostrophe's + '/(\s)\'(\d+\w?)\b(?!\')/', // back in '88 + '/(\S)\'(?=\s|'.$pnc.'|<|$)/', // single closing + '/\'/', // single opening + '/(\S)\"(?=\s|'.$pnc.'|<|$)/', // double closing + '/"/', // double opening + '/\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/', // 3+ uppercase acronym + '/\b([A-Z][A-Z\'\-]+[A-Z])(?=[\s.,\)>])/', // 3+ uppercase + '/\b( )?\.{3}/', // ellipsis + '/(\s?)--(\s?)/', // em dash + '/\s-(?:\s|$)/', // en dash + '/(\d+)( ?)x( ?)(?=\d+)/', // dimension sign + '/\b ?[([]TM[])]/i', // trademark + '/\b ?[([]R[])]/i', // registered + '/\b ?[([]C[])]/i', // copyright + ); + + extract($this->glyph, EXTR_PREFIX_ALL, 'txt'); + + $glyph_replace = array( + '$1'.$txt_apostrophe.'$2', // apostrophe's + '$1'.$txt_apostrophe.'$2', // back in '88 + '$1'.$txt_quote_single_close, // single closing + $txt_quote_single_open, // single opening + '$1'.$txt_quote_double_close, // double closing + $txt_quote_double_open, // double opening + '$1', // 3+ uppercase acronym + '$1', // 3+ uppercase + '$1'.$txt_ellipsis, // ellipsis + '$1'.$txt_emdash.'$2', // em dash + ' '.$txt_endash.' ', // en dash + '$1$2'.$txt_dimension.'$3', // dimension sign + $txt_trademark, // trademark + $txt_registered, // registered + $txt_copyright, // copyright + ); + + $text = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE); + foreach($text as $line) { + if (!preg_match("/<.*>/", $line)) { + $line = preg_replace($glyph_search, $glyph_replace, $line); + } + $glyph_out[] = $line; + } + return join('', $glyph_out); + } + +// ------------------------------------------------------------- + function iAlign($in) + { + $vals = array( + '<' => 'left', + '=' => 'center', + '>' => 'right'); + return (isset($vals[$in])) ? $vals[$in] : ''; + } + +// ------------------------------------------------------------- + function hAlign($in) + { + $vals = array( + '<' => 'left', + '=' => 'center', + '>' => 'right', + '<>' => 'justify'); + return (isset($vals[$in])) ? $vals[$in] : ''; + } + +// ------------------------------------------------------------- + function vAlign($in) + { + $vals = array( + '^' => 'top', + '-' => 'middle', + '~' => 'bottom'); + return (isset($vals[$in])) ? $vals[$in] : ''; + } + +// ------------------------------------------------------------- +// NOTE: deprecated + function encode_high($text, $charset = "UTF-8") + { + return mb_encode_numericentity($text, $this->cmap(), $charset); + } + +// ------------------------------------------------------------- +// NOTE: deprecated + function decode_high($text, $charset = "UTF-8") + { + return mb_decode_numericentity($text, $this->cmap(), $charset); + } + +// ------------------------------------------------------------- +// NOTE: deprecated + function cmap() + { + $f = 0xffff; + $cmap = array( + 0x0080, 0xffff, 0, $f); + return $cmap; + } + +// ------------------------------------------------------------- + function encode_html($str, $quotes=1) + { + $a = array( + '&' => '&', + '<' => '<', + '>' => '>', + ); + if ($quotes) $a = $a + array( + "'" => ''', + '"' => '"', + ); + + return strtr($str, $a); + } + +// ------------------------------------------------------------- + function textile_popup_help($name, $helpvar, $windowW, $windowH) + { + return ' ' . $name . '
    '; + + return $out; + } + +// ------------------------------------------------------------- +// NOTE: deprecated + function txtgps($thing) + { + if (isset($_POST[$thing])) { + if (get_magic_quotes_gpc()) { + return stripslashes($_POST[$thing]); + } + else { + return $_POST[$thing]; + } + } + else { + return ''; + } + } + +// ------------------------------------------------------------- +// NOTE: deprecated + function dump() + { + foreach (func_get_args() as $a) + echo "\n
    ",(is_array($a)) ? print_r($a) : $a, "
    \n"; + } + +// ------------------------------------------------------------- + + function blockLite($text) + { + $this->btag = array('bq', 'p'); + return $this->block($text."\n\n"); + } + + +} // end class + +?> diff --git a/plugins/serendipity_event_textile/lang_bg.inc.php b/plugins/serendipity_event_textile/lang_bg.inc.php index b73ab6b..408bb5a 100644 --- a/plugins/serendipity_event_textile/lang_bg.inc.php +++ b/plugins/serendipity_event_textile/lang_bg.inc.php @@ -3,8 +3,11 @@ /** * @version $Revision$ * @author Ivan Cenov jwalker@hotmail.bg - */ + * EN-Revision: 2034 +*/ @define('PLUGIN_EVENT_TEXTILE_NAME', 'Ôîðìàòèðàíå íà òåêñò: Textile'); @define('PLUGIN_EVENT_TEXTILE_DESC', 'Ôîðìàòèðàíå íà òåêñò ÷ðåç Textile êîíâåðòîð.'); @define('PLUGIN_EVENT_TEXTILE_TRANSFORM', 'Ôîðìàòèðàíå Textile å ðàçðåøåíî'); + @define('PLUGIN_EVENT_TEXTILE_VERSION', 'Âåðñèÿ íà Textile'); + @define('PLUGIN_EVENT_TEXTILE_VERSION_DESCRIPTION', 'Êîÿ âåðñèÿ íà Textile èñêàòå äà èçïîëçâàòå?'); diff --git a/plugins/serendipity_event_textile/serendipity_event_textile.php b/plugins/serendipity_event_textile/serendipity_event_textile.php index cc032ff..b87fb1b 100644 --- a/plugins/serendipity_event_textile/serendipity_event_textile.php +++ b/plugins/serendipity_event_textile/serendipity_event_textile.php @@ -1,6 +1,5 @@ add('name', PLUGIN_EVENT_TEXTILE_NAME); $propbag->add('description', PLUGIN_EVENT_TEXTILE_DESC); $propbag->add('stackable', false); - $propbag->add('author', 'Serendipity Team'); - $propbag->add('version', '1.4'); + $propbag->add('author', 'Serendipity Team', 'Lars Strojny'); + $propbag->add('version', '1.5'); $propbag->add('requirements', array( 'serendipity' => '0.8', 'smarty' => '2.6.7', @@ -68,6 +67,7 @@ class serendipity_event_textile extends serendipity_event foreach($this->markup_elements as $element) { $conf_array[] = $element['name']; } + $conf_array[] = 'textile_version'; $propbag->add('configuration', $conf_array); } @@ -87,6 +87,17 @@ class serendipity_event_textile extends serendipity_event function introspect_config_item($name, &$propbag) { + if ($name === 'textile_version') { + $propbag->add('type', 'radio'); + $propbag->add('name', PLUGIN_EVENT_TEXTILE_VERSION); + $propbag->add('description', PLUGIN_EVENT_TEXTILE_VERSION_DESCRIPTION); + $propbag->add('radio', array( + 'value' => array(1, 2), + 'desc' => array('1.0', '2.0'), + )); + $propbag->add('default', 2); + return true; + } $propbag->add('type', 'boolean'); $propbag->add('name', constant($name)); $propbag->add('description', sprintf(APPLY_MARKUP_TO, constant($name))); @@ -133,7 +144,7 @@ class serendipity_event_textile extends serendipity_event /* textile it */ - $eventData[$element] = textile($eventData[$element]); + $eventData[$element] = $this->textile($eventData[$element]); /* each block will now be "BLOCK::2" * so look for those place holders and replace @@ -230,6 +241,16 @@ class serendipity_event_textile extends serendipity_event return ''; } + function textile($string) { + if ($this->get_config('textile_version') == 2) { + require_once S9Y_INCLUDE_PATH . 'plugins/serendipity_event_textile/classTextile.php'; + $textile = new Textile(); + return $textile->textileThis($string); + } else { + require_once S9Y_INCLUDE_PATH . 'plugins/serendipity_event_textile/textile.php'; + return textile($string); + } + } } /* vim: set sts=4 ts=4 expandtab : */ diff --git a/plugins/serendipity_event_textile/textile.php b/plugins/serendipity_event_textile/textile.php index 7d076ba..c18c58e 100644 --- a/plugins/serendipity_event_textile/textile.php +++ b/plugins/serendipity_event_textile/textile.php @@ -488,12 +488,12 @@ Applying Attributes: global $textile_c; return preg_replace_callback('/ ([\s[{(]|[[:punct:]])? # $pre - " # start + ("|") # start ('.$textile_c.') # $textile_atts ([^"]+) # $text \s? (?:\(([^)]+)\)(?="))? # $title - ": + ("|"): (\S+\b) # $url (\/)? # $textile_slash ([^\w\/;]*) # $post