@Ghazascanner
_2019runbot
Ghazascanner File Manager
server :Linux phosweb007 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64
Current Path :
/
homepage
/
v-mt
/
plugins
/
Textile
/
php
/
Path :
Upload File :
New :
File
Dir
//homepage/v-mt/plugins/Textile/php/Textile.php
<?php # $Id: Textile.php,v 1.9 2004/08/25 17:44:29 ezra Exp $ class Textile { var $filers; var $charset; var $char_encoding; var $do_quotes; var $trim_spaces; var $preserve_spaces; var $head_offset; var $css; var $css_mode; var $macros; var $flavor; var $urlre; var $punct; var $valignre; var $tblalignre; var $halignre; var $alignre; var $imgalignre; var $clstypadre; var $clstyre; var $clstyfiltre; var $codere; var $codere2; var $blocktags; var $qtags; var $qtag; function Textile($opt = array()) { $this->filters = $opt['filters'] or array(); $this->charset = $opt['charset'] or 'iso-8859-1'; $this->char_encoding = array_key_exists('char_encoding',$opt) ? $opt['char_encoding'] : 1; $this->do_quotes = array_key_exists('do_quotes',$opt) ? $opt['do_quotes'] : 1; $this->trim_spaces = array_key_exists('trim_spaces',$opt) ? $opt['trim_spaces'] : 1; //$options{smarty_mode} = 1 unless exists $options{smarty_mode}; $this->preserve_spaces = array_key_exists('preserve_spaces',$opt) ? $options['preserve_spaces'] : 0; $this->head_offset = array_key_exists('head_offset',$opt) ? $options['head_offset'] : 0; if (array_key_exists('css',$opt)) $this->set_css($opt['css']); $this->macros = array_key_exists('macros', $opt) ? $opt['macros'] : $this->default_macros(); if (array_key_exists('flavor',$opt)) { $this->set_flavor($opt['flavor']); } else { $this->set_flavor('xhtml1/css'); } # regular expression initialization # a URL discovery regex. This is from Mastering Regex from O'Reilly. # Some modifications by Brad Choate <brad@bradchoate.com> $this->urlre = '(?: (?=[a-zA-Z0-9.\/#]) (?: (?:ftp|https?|telnet|nntp):\/\/(?:\w+(?::\w+)?@)?[-\w]+(?:\.\w[-\w]*)+ | (?:mailto:)?[-\+\w]+\@[-\w]+(?:\.\w[-\w]*)+ | (?i: [a-z0-9] (?:[-a-z0-9]*[a-z0-9])? \. )+ (?-i: com\b | edu\b | biz\b | gov\b | in(?:t|fo)\b # .int or .info | mil\b | net\b | org\b | museum\b | aero\b | coop\b | name\b | pro\b | [a-z][a-z]\b # two-letter country codes ) )? (?: : \d+ )? (?: \/? [^.\!,?;:"\'<>()\[\]{}\s\x7F-\xFF]* (?: [.\!,?;:]+ [^.\!,?;:"\'<>()\[\]{}\s\x7F-\xFF]+ )* )?)'; $this->punct = '(?:[\!"#\$%&\'()\*\+,\-\./:;<=>\?@\[\\\\\]\^_`{\|}\~])'; $this->valignre = '(?:[\-^~])'; $this->tblalignre = '(?:[<>=])'; $this->halignre = '(?:<>|[<>=])'; $this->alignre = "(?:".$this->valignre.'|<>'.$this->valignre.'?|'.$this->valignre.'?<>|'.$this->valignre.'?'.$this->halignre.'?|'.$this->halignre.'?'.$this->valignre.'?)(?!\w)'; $this->imgalignre = '(?:[<>]|'.$this->valignre.'){1,2}'; $this->clstypadre = '(?: (?: \([A-Za-z0-9_\- \#]+\) ) | (?: { (?: \( [^)]+ \) | [^}] )+ } ) | (?: \(+? (?![A-Za-z0-9_\-\#]) ) | (?: \)+? ) | (?: \[ [a-zA-Z\-]+? \] ) )'; $this->clstyre = '(?: (?: \([A-Za-z0-9_\- \#]+\) ) | (?: { [A-Za-z0-9_\-](?: \( [^)]+ \) | [^}] )+ } ) | (?: \[ [a-zA-Z\-]+? \] ) )'; $this->clstyfiltre = '(?: (?: \([A-Za-z0-9_\- \#]+\) ) | (?: { [A-Za-z0-9_\-](?: \( [^)]+ \) | [^}] )+ } ) | (?: \|[^\|]+\| ) | (?: \(+?(?![A-Za-z0-9_\-\#]) ) | (?: \)+ ) | (?: \[ [a-zA-Z]+? \] ) )'; $this->codere = "(?: (?: [[{] @ # opening (?: \[([A-Za-z0-9]+)\] )? # 1: language id (.+?) # 2: code @ # closing [\]}] ) | (?: (?: ^|(?<=[\s\(]) ) @ # opening (?: \[([A-Za-z0-9]+)\] )? # $3: language id ([^\s].+?[^\s]) # $4: code itself @ # closing (?: $|(?=[[:punct:]]{1,2}|\s) ) ) )"; # non-capturing version for tokenize $this->codere2 = "(?: (?: [[{] @ # opening (?: \[(?:[A-Za-z0-9]+)\] )? # 1: language id (?:.+?) # 2: code @ # closing [\]}] ) | (?: (?: ^|(?<=[\s\(]) ) @ # opening (?: \[(?:[A-Za-z0-9]+)\] )? # $3: language id (?:[^\s].+?[^\s]) # $4: code itself @ # closing (?: $|(?=[[:punct:]]{1,2}|\s) ) ) )"; $this->blocktags = "(?: < (?: (?: \/? (?: h[1-6] | p | pre | div | table | t[rdh] | [ou]l | li | block(?: quote | code ) | form | input | select | option | textarea ) [ >] ) | !-- ) )"; $this->qtag = array( '**' => 'b', '__' => 'i', '??' => 'cite', '*' => 'strong', '_' => 'em', '-' => 'del', '+' => 'ins', '++' => 'big', '--' => 'small', '~' => 'sub' ); $this->qtags = array( array('**', 'b', '(?<!\*)\*\*(?!\*)', '\*'), array('__', 'i', '(?<!_)__(?!_)', '_'), array('??', 'cite', '\?\?(?!\?)', '\?'), array('*', 'strong', '(?<!\*)\*(?!\*)', '\*'), array('_', 'em', '(?<!_)_(?!_)', '_'), array('-', 'del', '(?<!\-)\-(?!\-)', '-'), array('+', 'ins', '(?<!\+)\+(?!\+)', '\+'), array('++', 'big', '(?<!\+)\+\+(?!\+)', '\+\+'), array('--', 'small', '(?<!\-)\-\-(?!\-)', '\-\-'), array('~', 'sub', '(?<!\~)\~(?![\\\\\/~])', '\~') ); } # getter/setter methods... function set($opt, $value) { if (is_array($opt)) { foreach ($opt as $key => $val) { $this->set($key, $val); } } else { # the following options have special set methods # that activate upon setting: if ($opt == 'charset') { $this->set_charset($value); } elseif ($opt == 'css') { $this->set_css($value); } elseif ($opt == 'flavor') { $this->set_flavor($value); } else { $this->$opt = $value; } } } function get($opt) { return $this->$opt; } function set_flavor($flavor) { $this->flavor = $flavor; if (preg_match('/^xhtml(\d)?(\D|$)/',$flavor,$matches)) { if ($matches[1] == '2') { $this->_line_open = '<l>'; $this->_line_close = '</l>'; $this->_blockcode_open = '<blockcode>'; $this->_blockcode_close = '</blockcode>'; $this->css_mode = 1; } else { # xhtml 1.x $this->_line_open = ''; $this->_line_close = '<br />'; $this->_blockcode_open = '<pre><code>'; $this->_blockcode_close = '</code></pre>'; $this->css_mode = 1; } } elseif (preg_match('/^html/', $flavor)) { $this->_line_open = ''; $this->_line_close = '<br>'; $this->_blockcode_open = '<pre><code>'; $this->_blockcode_close = '</code></pre>'; $this->css_mode = preg_match('/\/css/',$flavor); } if ($this->css_mode && !$this->css) $this->_css_defaults(); } function set_css($css) { if (is_array($css)) { $this->css = $css; $this->css_mode = 1; } else { $this->css_mode = $css; if ($css && !$this->css) $this->_css_defaults(); } } function set_charset($charset) { $this->charset = $charset; if (preg_match('/^utf-?8$/i',$charset)) { $this->char_encoding = 0; } else { $this->char_encoding = 1; } } # end of getter/setter methods function _replace_block($matches) { return $matches[1] . "\n\n" . $this->_repl($this->format_block(array('text' => $matches[2]))) . "\n\n".$matches[3]; } function _replace_inline_block($matches) { return $this->_repl($this->format_block(array('text' => $matches[2], 'inline' => 1, 'pre' => $matches[1], 'post' => $matches[3]))); } function _replace_simple($matches) { return $this->_repl($matches[1]); } function _replace_pre($matches) { return "\n\n" .$this->_repl($matches[1].$this->encode_html($matches[2], 1).$matches[3]) ."\n\n"; } function _replace_code($matches) { return $this->_repl($this->format_code(array('text' => $matches[2].$matches[4], 'lang' => $matches[1].$matches[3]))); } function _save_link($matches) { $this->links[$matches[1]] = array('url' => $matches[3], 'title' => $matches[2]); return $matches[4]; } function _replace_image($matches) { return $this->_repl($this->format_image(array('pre' => $matches[1], 'src' => $matches[5], 'align' => $matches[2].$matches[4], 'extra' => $matches[6], 'url' => $matches[7], 'clsty' => $matches[3], 'post' => $matches[8]))); } function _replace_span($matches) { return $this->_repl($this->format_span(array('pre' => $matches[1], 'text' => $matches[5], 'align' => $matches[2].$matches[4], 'cite' => $matches[6], 'clsty' => $matches[3], 'post' => $matches[7]))); } function _replace_link($matches) { return $this->_repl($this->format_link(array('text' => $matches[1], 'linktext' => $matches[3].$matches[6], 'title' => $this->encode_html_basic($matches[4].$matches[7]), 'url' => $matches[8], 'clsty' => $matches[2].$matches[5]))); } function _replace_citation($matches) { return $this->_repl($this->format_cite(array('pre' => $matches[1], 'text' => $matches[2], 'cite' => $matches[3], 'post' => $matches[4]))); } function _replace_macro($matches) { return $this->format_macro(array('pre' => $matches[1], 'post' => $matches[3], 'macro' => $matches[2])); } function _replace_format($matches) { $marker = $matches[2]; $tag = $this->qtag[$marker]; return $this->format_tag(array('tag' => $tag, 'marker' => $marker, 'pre' => $matches[1], 'text' => $matches[4], 'clsty' => $matches[3], 'post' => $matches[5])); } function _replace_acronym($matches) { return $this->_repl('<acronym title="'.$this->encode_html_basic($matches[2]).'">'.$matches[1].'</acronym>'); } function _replace_capped($matches) { return $matches[1].$this->_repl('<span class="'.$this->css['class_caps'].'">'.$matches[2].'</span>'); } function _replace_enc_link($matches) { return $matches[1].$this->encode_url($matches[2]); } function _replace_enc_char($matches) { return ord($matches[1]) > 255 ? '%u' . (sprintf('%04X', ord($matches[1]))) : '%' . (sprintf('%02X', ord($matches[1]))); } function _repl($item) { $this->repl[] = $item; return '<textile#'.(count($this->repl)).'>'; } function process(&$str) { return $this->TextileThis($str); } function TextileThis($str) { # save a copy of whatever replacements might exist. this is # in case we call ourselves at some point: $save_repl = $this->repl; $save_links = $this->links; # quick translator for abbreviated block names # to their tag $macros = array('bq' => 'blockquote'); # an array to hold any portions of the text to be preserved # without further processing by Textile $this->repl = array(); # strip out extra newline characters. we're only matching for \n herein #$str = preg_replace('!(?:\015?\012|\015)!',"\n", $str); # optionally remove trailing spaces if ($this->trim_spaces) $str = preg_replace("/ +$/m", '', $str); # preserve contents of the '==', 'pre', 'blockcode' sections $str = preg_replace_callback("/(^|\n\n)==(.+?)==($|\n\n)/s", array(&$this, '_replace_block'), $str); if (!$this->disable_html) { # preserve style, script tag contents $str = preg_replace_callback('/(<(style|script)(?:>| .+?'.'>).*?<\/\2>)/s',array(&$this, '_replace_simple'), $str); # preserve HTML comments $str = preg_replace_callback('/(<!--.+?-->)/s',array(&$this, '_replace_simple'),$str); # preserve pre block contents, encode contents by default $pre_start = count($this->repl); $str = preg_replace_callback('/(<pre(?: [^>]*)?'.'>)(.+?)(<\/pre>)/s', array(&$this, '_replace_pre'), $str); # fix code tags within pre blocks we just saved. for ($i = $pre_start; $i < count($this->repl); $i++) { $this->repl[$i] = preg_replace('/<(\/?)code(.*?)>/s','<\\1code\\2>', $this->repl[$i]); } # preserve code blocks by default, encode contents $str = preg_replace_callback('/(<code(?: [^>]+)?'.'>)(.+?)(<\/code>)/s', array(&$this, '_replace_pre'), $str); # encode blockcode tag (an XHTML 2 tag) and encode it's # content by default $str = preg_replace_callback('/(<blockcode(?: [^>]+)?'.'>)(.+?)(<\/blockcode>)/s', array(&$this, '_replace_pre'), $str); # preserve PHPish, ASPish code $str = preg_replace_callback('/(<([\?\%]).*?(\2)>)/s',array(&$this, '_replace_simple'), $str); } # pass through and remove links that follow this format # [id_without_spaces (optional title text)]url # lines like this are stripped from the content, and can be # referred to using the "link text":id_without_spaces syntax $this->links = array(); $str = preg_replace_callback('/(?:\n|^) [ ]* \[ ([^ ]+?) [ ]*? (?:\( (.+?) \) )? \] ((?:(?:ftp|https?|telnet|nntp):\/\/|\/)[^ ]+?) [ ]* (\n|$)/mx', array(&$this, '_save_link'), $str); # eliminate starting/ending blank lines $str = preg_replace('/^\n+/s', '', $str); $str = preg_replace('/\n+$/s', '', $str); # split up text into paragraph blocks, capturing newlines too $paras = preg_split('/(\n{2,})/', $str, -1, PREG_SPLIT_DELIM_CAPTURE); //my ($block, $bqlang, $filter, $class, $sticky, @lines, // $style, $stickybuff, $lang, $clear); $out = ''; foreach ($paras as $para) { if (preg_match('/^\n+$/s', $para)) { if ($sticky && isset($stickybuff)) { $stickybuff .= $para; } else { $out .= $para; } continue; } if ($sticky) { $sticky++; } else { unset ($block, $class, $lang); $style = ''; } unset ($id, $cite, $align, $padleft, $padright, $lines, $buffer); $sigre = '/^(h[1-6]|p|bq|bc|fn\d+) ((?:'.$this->clstyfiltre.'*|'.$this->halignre.')*) (\.\.?) (?: : (\d+|'.$this->urlre.'))?\ /x'; $xxre = '/^ (?:'.$this->halignre.'|'.$this->clstypadre.'*)* [\*\#] (?:'.$this->halignre.'|'.$this->clstypadre.'*)* \ /x'; if (preg_match($sigre, $para, $matches)) { $para = substr($para, strlen($matches[0])); if ($sticky) { if ($block == 'bc') { # close our blockcode section $out = preg_replace('/\n\n$/s','',$out); $out .= $this->_blockcode_close."\n\n"; } elseif ($block == 'bq') { $out = preg_replace('/\n\n$/', '', $out); $out .= '</blockquote>'."\n\n"; } elseif ($block == 'table') { $table_out = $this->format_table(array('text' => $stickybuff)); if (!isset($table_out)) $table_out = ''; $out .= $table_out; unset($stickybuff); } elseif ($block == 'dl') { $dl_out = $this->format_deflist(array('text' => $stickybuff)); if (!isset($dl_out)) $dl_out = ''; $out .= $dl_out; unset($stickybuff); } $sticky = 0; } # block macros: h[1-6](class)., bq(class)., bc(class)., p(class). # echo "paragraph: [[$para]]\n\tblock: $1\n\tparams: $2\n\tcite: $4"; $block = $matches[1]; $params = $matches[2]; $cite = $matches[4]; if ($matches[3] == '..') { $sticky = 1; } else { $sticky = 0; unset ($class, $bqlang, $lang, $filter); $style = ''; } if (preg_match('/^h([1-6])$/', $block, $matches)) { if ($this->head_offset > 0) { $block = 'h' . ($matches[1] + $this->head_offset); } } if (preg_match('/('.$this->halignre.'+)/', $params, $matches)) { $align = $matches[1]; $params = preg_replace('/'.$this->halignre.'+/x','',$params, 1); } if (isset($params)) { if (preg_match('/\|(.+)\|/', $params, $matches)) { $filter = $matches[1]; $params = preg_replace('/\|.+?\|/','',$params, 1); } if (preg_match('/{([^}]+)}/', $params, $matches)) { $style = $matches[1]; $style = preg_replace('/\n/', ' ', $style); $params = preg_replace('/{[^}]+}/', '', $params); } if (preg_match('/\(([A-Za-z0-9_\-\ ]+?)(?:\#(.+?))?\)/', $params, $matches) or preg_match('/\(([A-Za-z0-9_\-\ ]+?)?(?:\#(.+?))\)/',$params, $matches)) { if ($matches[1] or $matches[2]) { $class = $matches[1]; $id = $matches[2]; if ($class) { $params = preg_replace('/\([A-Za-z0-9_\-\ ]+?(#.*?)?\)/', '', $params); } elseif ($id) { $params = preg_replace('/\(#.+?\)/', '', $params); } } } if (preg_match('/(\(+)/', $params, $matches)) { $padleft = strlen($matches[1]); $params = preg_replace('/\(+/', '', $params, 1); } if (preg_match('/(\)+)/', $params, $matches)) { $padright = strlen($matches[1]); $params = preg_replace('/\)+/', '', $params, 1); } if (preg_match('/\[(.+?)\]/', $params, $matches)) { $lang = $matches[1]; if ($block == 'bc') { $bqlang = $lang; unset($lang); } $params = preg_replace('/\[.+?\]/', '', $params, 1); } } #warn "settings:\n\tblock: $block\n\tpadleft: $padleft\n\tpadright: $padright\n\tclass: $class\n\tstyle: $style\n\tid: $id\n\tfilter: $filter\n\talign: $align\n\tlang: $lang\n\tsticky: $sticky"; } elseif (preg_match('/^<textile#(\d+)>$/', $para, $matches)) { $buffer = $this->repl[$matches[1]-1]; } elseif (preg_match('/^clear([<>]+)?\.$/', $para, $matches)) { if ($matches[1] == '<') { $clear = 'left'; } elseif ($matches[1] == '>') { $clear = 'right'; } else { $clear = 'both'; } continue; } elseif ($sticky && (isset($stickybuff)) && (($block == 'table') or ($block == 'dl'))) { $stickybuff .= $para; continue; } elseif (preg_match($xxre, $para)) { # '*', '#' prefix means a list $buffer = $this->format_list(array('text' => $para)); } elseif (preg_match('/^(?:table(?:'.$this->tblalignre.'|'.$this->clstypadre.'*)* (\.\.?)\s+)? (?:_|'.$this->alignre.'|'.$this->clstypadre.'*)*\|/sx', $para, $matches)) { # handle wiki-style tables if (isset($matches[1]) && ($matches[1] == '..')) { $block = 'table'; $stickybuff = $para; $sticky = 1; continue; } else { $buffer = $this->format_table(array('text' => $para)); } } elseif (preg_match('/^(?:dl(?:'.$this->clstyre.')*(\.\.?)\s+)/x', $para, $matches)) { # handle definition lists if (isset($matches[1]) && ($matches[1] == '..')) { $block = 'dl'; $stickybuff = $para; $sticky = 1; continue; } else { $buffer = $this->format_deflist(array('text' => $para)); } } if (isset($buffer)) { $out .= $buffer; continue; } $lines = preg_split('/\n/', $para); if (!count($lines)) continue; $block or $block = 'p'; $buffer = ''; $pre = ''; $post = ''; if ($block == 'bc') { if ($sticky <= 1) { $pre .= $this->_blockcode_open; $pre = preg_replace('/>$/', '', $pre, 1); if ($bqlang) $pre .= " language=\"$bqlang\""; if ($align) { $alignment = _halign($align); if ($this->css_mode) { if (($padleft or $padright) && (($alignment == 'left') || ($alignment == 'right'))) { $style .= ';float:'.$alignment; } else { $style .= ';text-align:'.$alignment; } $class .= ' '.$this->css["class_align_$alignment"] or $alignment; } else { if ($alignment) $pre .= " align=\"$alignment\""; } } if ($padleft) $style .= ";padding-left:$padleft".'em'; if ($padright) $style .= ";padding-right:$padright".'em'; if ($clear) $style .= ";clear:$clear"; if ($class) { $class = preg_replace('/^ /', '', $class, 1); $pre .= " class=\"$class\""; } if ($id) $pre .= " id=\"$id\""; if ($style) { $style = preg_replace('/^;/', '', $style, 1); $pre .= " style=\"$style\""; } if ($lang) $pre .= " lang=\"$lang\""; $pre .= '>'; unset ($lang, $bqlang, $clear); } $para = preg_replace_callback("/(?:^|(?<=[\s>])|([{[])) ==(.+?)== (?:$|([\]}])|(?=[[:punct:]]{1,2}|\s))/sx", array(&$this, '_replace_inline_block'), $para); $buffer .= $this->encode_html_basic($para, 1); $buffer = preg_replace('/<textile#(\d+)>/', '<textile#\\1>/', $buffer); if ($sticky == 0) $post .= $this->_blockcode_close; $out .= $pre . $buffer . $post; continue; } elseif ($block == 'bq') { if ($sticky <= 1) { $pre .= '<blockquote'; if ($align) { $alignment = _halign($align); if ($this->css_mode) { if (($padleft or $padright) && (($alignment == 'left') || ($alignment == 'right'))) { $style .= ';float:'.$alignment; } else { $style .= ';text-align:'.$alignment; } $class .= ' '.$this->css["class_align_$alignment"] or $alignment; } else { if ($alignment) $pre .= " align=\"$alignment\""; } } if ($padleft) $style .= ";padding-left:$padleft".'em'; if ($padright) $style .= ";padding-right:$padright".'em'; if ($clear) $style .= ";clear:$clear"; if ($class) { $class = preg_replace('/^ /', '', $class); $pre .= " class=\"$class\""; } if ($id) $pre .= " id=\"$id\""; if ($style) { $style = preg_replace('/^;/','',$style); $pre .= " style=\"$style\""; } if ($lang) $pre .= " lang=\"$lang\""; if (isset($cite)) $pre .= ' cite="' . $this->format_url(array('url' => $cite)) . '"'; $pre .= '>'; unset($clear); } $pre .= '<p>'; } elseif (preg_match('/fn(\d+)/', $block, $matches)) { $fnum = $matches[1]; $pre .= '<p'; if (array_key_exists('class_footnote', $this->css)) $class .= ' '.$this->css['class_footnote']; if ($align) { $alignment = _halign($align); if ($this->css_mode) { if (($padleft or $padright) && (($alignment == 'left') || ($alignment == 'right'))) { $style .= ';float:'.$alignment; } else { $style .= ';text-align:'.$alignment; } $class .= ($this->css["class_align_$alignment"] or $alignment); } else { $pre .= " align=\"$alignment\""; } } if ($padleft) $style .= ";padding-left:$padleft".'em'; if ($padright) $style .= ";padding-right:$padright".'em'; if ($clear) $style .= ";clear:$clear"; if ($class) { $class = preg_replace('/^ /', '', $class); $pre .= " class=\"$class\""; } $pre .= ' id="'.($this->css['id_footnote_prefix'] ? $this->css['id_footnote_prefix'] : 'fn').$fnum.'"'; if ($style) { $style = preg_replace('/^;/', '', $style); $pre .= " style=\"$style\""; } if ($lang) $pre .= " lang=\"$lang\""; $pre .= '>'; $pre .= '<sup>'.$fnum.'</sup> '; # we can close like a regular paragraph tag now $block = 'p'; unset($clear); } else { $pre .= '<' . ($macros[$block] ? $macros[$block] : $block); if ($align) { $alignment = _halign($align); if ($this->css_mode) { if (($padleft or $padright) && (($alignment == 'left') or ($alignment == 'right'))) { $style .= ';float:'.$alignment; } else { $style .= ';text-align:'.$alignment; } $class .= ' '.$this->css["class_align_$alignment"] or $alignment; } else { $pre .= " align=\"$alignment\""; } } if ($padleft) $style .= ";padding-left:$padleft".'em'; if ($padright) $style .= ";padding-right:$padright".'em'; if ($clear) $style .= ";clear:$clear"; if ($class) { $class = preg_replace('/^ /', '', $class); $pre .= " class=\"$class\""; } if ($id) $pre .= " id=\"$id\""; if ($style) { $style = preg_replace('/^;/', '', $style); $pre .= " style=\"$style\""; } if ($lang) $pre .= " lang=\"$lang\""; if (isset($cite) && ($block == 'bq')) $pre .= ' cite="' . $this->format_url(array('url' => $cite)) . '"'; $pre .= '>'; unset($clear); } $buffer = $this->format_paragraph(array('text' => $para)); if ($block == 'bq') { if (!preg_match('/<p[ >]/', $buffer)) $post .= '</p>'; if ($sticky == 0) $post .= '</blockquote>'; } else { $post .= '</' . $block . '>'; } if (preg_match('/'.$this->blocktags.'/x', $buffer)) { $buffer = preg_replace('/^\n\n/s', '', $buffer); $out .= $buffer; } else { if (isset($filter)) $buffer = $this->format_block(array('text' => "|$filter|".$buffer, 'inline' => 1)); $out .= $pre . $buffer . $post; } } if ($sticky) { if ($block == 'bc') { # close our blockcode section $out .= $this->_blockcode_close; } elseif ($block == 'bq') { $out .= '</blockquote>'; } elseif (($block == 'table') && ($stickybuff)) { $table_out = $this->format_table(array('text' => $stickybuff)); if (isset($table_out)) $out .= $table_out; } elseif (($block == 'dl') && ($stickybuff)) { $dl_out = $this->format_deflist(array('text' => $stickybuff)); if (isset($dl_out)) $out .= $dl_out; } } # cleanup-- restore preserved blocks while ($i = count($this->repl)) { $rep = array_pop($this->repl); $out = preg_replace("/(?:<|<)textile#$i(?:>|>)/", $rep, $out, 1); } # scan for br, hr tags that are not closed and close them # only for xhtml! just the common ones -- don't fret over input # and the like. if (preg_match('/^xhtml/i', $this->flavor)) $out = preg_replace('/(<(?:img|br|hr)[^>]*?(?<!\/))>/','\\1 />', $out); $this->repl = $save_repl; $this->links = $save_links; return $out; } function format_paragraph($args) { $save_repl = $this->repl; $this->repl = array(); $buffer = array_key_exists('text', $args) ? $args['text'] : ''; $buffer = preg_replace_callback('/(?:^|(?<=[\s>])|([{[])) ==(.+?)== (?:$|([\]}])|(?=[[:punct:]]{1,2}|\s))/sx', array(&$this, '_replace_inline_block'), $buffer); if (preg_match('/</', $buffer) && (!$this->disable_html)) { # optimization -- no point in tokenizing if we # have no tags to tokenize $tokens = $this->tokenize($buffer); } else { $tokens = array(array('text', $buffer)); } $result = ''; foreach ($tokens as $token) { $text = $token[1]; if ($token[0] == 'tag') { $text = preg_replace('/&(?!amp;)/', '&', $text); $result .= $text; } else { $text = $this->format_inline(array('text' => $text)); $result .= $text; } } # now, add line breaks for lines that contain plaintext $lines = preg_split('/\n/', $result); $result = ''; $needs_closing = 0; foreach ($lines as $line) { if (!preg_match('/'.$this->blocktags.'/x', $line) && ((preg_match('/^[^<]/', $line) || preg_match('/>[^<]/', $line)) || (!preg_match('/<img /', $line)))) { if ($this->_line_open) { if ($result != '') $result .= "\n"; $result .= $this->_line_open . $line . $this->_line_close; } else { if ($needs_closing) { $result .= $this->_line_close ."\n"; } else { $needs_closing = 1; if ($result != '') $result .= "\n"; } $result .= $line; } } else { if ($needs_closing) { $result .= $this->_line_close ."\n"; } else { if ($result != '') $result .= "\n"; } $result .= $line; $needs_closing = 0; } } # at this point, we will restore the \001's to \n's (reversing # the step taken in _tokenize). #$result =~ s/\r/\n/g; $result = preg_replace('/\001/', "\n", $result); while ($i = count($this->repl)) { $rep = array_pop($this->repl); $result = preg_replace("/<textile#$i>/", $rep, $result, 1); } # quotalize if ($this->do_quotes) { $result = $this->process_quotes($result); } $this->repl = $save_repl; return $result; } function format_inline($args) { $text = array_key_exists('text', $args) ? $args['text'] : ''; $save_repl = $this->repl; $this->repl = array(); $text = preg_replace_callback("/".$this->codere."/x", array(&$this, '_replace_code'), $text); # images must be processed before encoding the text since they might # have the <, > alignment specifiers... # !blah (alt)! -> image $imgre = '/ (?: ^ | (?<=[\s>]) | ([{[]) ) ! ('.$this->imgalignre.'?)? ('.$this->clstypadre.'*)? ('.$this->imgalignre.'?)? (?:\s*) ([^\s\(!]+) (?:\s*) ([^\(!]*(?:\([^\)]+\))?[^!]*) ! (?: : (\d+ | '.$this->urlre.') )? (?: $ | ([\]}]) | (?= [[:punct:]]{1,2} | \s ) ) /x'; $text = preg_replace_callback($imgre, array(&$this, '_replace_image'), $text); $text = preg_replace_callback('/ (?: ^ | (?<=[\s>]) | ([{[]) ) # $1: open brace, bracket % # opening ('.$this->halignre.'?) # $2: optional alignment ('.$this->clstyre.'*) # $3: optional CSS class, id ('.$this->halignre.'?) # $4: optional alignment (?:\s*) # spacing ([^\%]+?) # $5: text % # closing (?: : (\d+|'.$this->urlre.'))? # $6: optional URL (?:$|([\]}])|(?=[[:punct:]]{1,2}|\s))# $7: closing brace, bracket /x', array(&$this, '_replace_span'), $text); $text = $this->encode_html($text); $text = preg_replace('/<textile#(\d+)>/', '<textile#\\1>', $text); $text = preg_replace('/&quot;/', '"', $text); $text = preg_replace('/&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8});)/', '&\\1', $text); $text = preg_replace('/&(([a-z]+|#\d+);)/', '&\\1', $text); $text = preg_replace('/"/', '"', $text); # These create markup with entities. Do first and 'save' result for later: # "text":url -> hyperlink # links with brackets surrounding $parenre = '\((?:[^()])*\)'; $text = preg_replace_callback('/( [{[] (?: (?:" # quote character ('.$this->clstyre.'*)? # $2: optional CSS class, id ([^"]+?) # $3: link text (?:\( ( (?:[^()]|'.$parenre.')*) \))? # $4: optional link title " # closing quote ) | (?:\' # open single quote ('.$this->clstyre.'*)? # $5: optional CSS class, id ([^\']+?) # $6: link text (?:\( ( (?:[^()]|'.$parenre.')*) \))? # $7: optional link title \' # closing quote ) ) :(.+?) # $8: URL suffix [\]}] ) /x', array(&$this, '_replace_link'), $text); $text = preg_replace_callback('/ ((?:^|(?<=[\s>\(])) # $1: open brace, bracket (?: (?:" # quote character ('.$this->clstyre.'*)? # $2: optional CSS class, id ([^"]+?) # $3: link text (?:\( ( (?:[^()]|'.$parenre.')*) \))? # $4: optional link title " # closing quote ) | (?:\' # open single quote ('.$this->clstyre.'*)? # $5: optional CSS class, id ([^\']+?) # $6: link text (?:\( ( (?:[^()]|'.$parenre.')*) \))? # $7: optional link title \' # closing quote ) ) :(\d+|'.$this->urlre.') # $8: URL suffix (?:$|(?=[[:punct:]]{1,2}|\s))) # $9: closing brace, bracket /x', array(&$this, '_replace_link'), $text); if (preg_match('/^xhtml2/', $this->flavor)) { # citation with cite link $text = preg_replace_callback('/ (?:^|(?<=[\s>\'"\(])|([{[]))# $1: open brace, bracket \?\? # opening ([^\?]+?) # $2: characters \?\? # closing :(\d+|'.$this->urlre.') # $3: optional citation URL (?:$|([\]}])|(?=[[:punct:]]{1,2}|\s))# $4: closing brace, bracket /x', array(&$this, '_replace_citation'), $text); } # footnotes if (preg_match('/[^ ]\[\d+\]/', $text)) { $fntag = '<sup'; if (array_key_exists('class_footnote', $this->css)) $fntag .= ' class="'.$this->css['class_footnote'].'"'; $fntag .= '><a href="#'.($this->css['id_footnote_prefix'] ? $this->css['id_footnote_prefix'] : 'fn'); $text = preg_replace('/([^ ])\[(\d+)\]/', '\\1'.$fntag.'\\2">\\2</a></sup>', $text); } # translate macros: $text = preg_replace_callback('{(\{)(.+?)(\})}x', array(&$this, '_replace_macro'), $text); # these were present with textile 1 and are common enough # to not require macro braces... # (tm) -> ™ $text = preg_replace('/[\(\[]TM[\)\]]/i', '™', $text); # (c) -> © $text = preg_replace('/[\(\[]C[\)\]]/i', '©', $text); # (r) -> ® $text = preg_replace('/[\(\[]R[\)\]]/i', '®', $text); if ($this->preserve_spaces) { # replace two spaces with an em space $text = preg_replace('/(?<!\s)\ \ (?!=\s)/', ' ', $text); } $redo = preg_match('/[\*_\?\-\+\^\~]/', $text); $last = $text; while ($redo) { # simple replacements... $redo = 0; foreach ($this->qtags as $tag) { list($f, $r, $qf, $cls) = $tag; if ($text = preg_replace_callback('/ (?:^|(?<=[\s>\'"])|([{[]))# 1 - pre ('.$qf.') ('.$this->clstyre.'*)? # 3 - attributes ([^'.$cls.'\s].*?) # 4 - content (?<=\S)'.$qf.' (?:$|([\]}])|(?=[[:punct:]]{1,2}|\s)) # 5 - post /x', array(&$this, '_replace_format'), $text)) { $redo or $redo = $last != $text; $last = $text; } } } # superscript is an even simpler replacement... $text = preg_replace('/(?<!\^)\^(?!\^)(.+?)(?<!\^)\^(?!\^)/', '<sup>\\1</sup>', $text); # ABC(Aye Bee Cee) -> acronym $text = preg_replace_callback('/\b([A-Z][A-Za-z0-9]*?[A-Z0-9]+?)\b(?:[(]([^)]*)[)])/', array(&$this, '_replace_acronym'), $text); # ABC -> 'capped' span if ($this->css['class_caps']) { $text = preg_replace_callback('/ (^|[^"][>\s]) ((?:[A-Z](?:[A-Z0-9\.,\']|\&){2,}\ *)+?) (?=[^A-Z\.0-9]|$) /x', array(&$this, '_replace_capped'), $text); } # nxn -> n×n $text = preg_replace('/((?:[0-9\.]0|[1-9]|\d[\'"])\ ?)x(\ ?\d)/', '\\1×\\2', $text); # translate these entities to the Unicode equivalents: $text = preg_replace('/…/', '…', $text); $text = preg_replace('/‘/', '‘', $text); $text = preg_replace('/’/', '’', $text); $text = preg_replace('/“/', '“', $text); $text = preg_replace('/”/', '”', $text); $text = preg_replace('/–/', '–', $text); $text = preg_replace('/—/', '—', $text); # Restore replacements done earlier: while ($i = count($this->repl)) { $rep = array_pop($this->repl); $text = preg_replace('/<textile#'.$i.'>/', $rep, $text, 1); } # translate entities to characters for highbit stuff since # we're using utf8 # removed for backward compatability with older versions of Perl #if ($this->{charset} =~ m/^utf-?8$/i) { # # translate any unicode entities to native UTF-8 # $text =~ s/\&\#(\d+);/($1 > 127) ? pack('U',$1) : chr($1)/ge; #} $this->repl = $save_repl; return $text; } function format_macro($args) { $macro = $args['macro']; if (array_key_exists($macro, $this->macros)) { return $this->macros[$macro]; } # handle full unicode name translation #if ($Have_Charnames) { # # charnames::vianame is only available in Perl 5.8.0 and later... # if (defined (my $unicode = charnames::vianame(uc($macro)))) { # return '&#'.$unicode.';'; # } #} return $args['pre'].$macro.$args['post']; } function format_cite($args) { $pre = array_key_exists('pre', $args) ? $args['pre'] : ''; $text = array_key_exists('text', $args) ? $args['text'] : ''; $cite = $args['cite']; $post = array_key_exists('post', $args) ? $args['post'] : ''; _strip_borders($pre, $post); $tag = $pre.'<cite'; if ((preg_match('/^xhtml2/', $this->flavor)) && isset($cite)) { $cite = $this->format_url(array('url' => $cite)); $tag .= " cite=\"$cite\""; } else { $post .= ':'; } $tag .= '>'; return $tag . $this->format_inline(array('text' => $text)) . '</cite>'.$post; } function format_code($args) { $code = array_key_exists('text', $args) ? $args['text'] : ''; $lang = $args['lang']; $code = $this->encode_html($code, 1); $code = preg_replace('/<textile#(\d+)>/', '<textile#\\1>', $code); $tag = '<code'; if ($lang) $tag .= " language=\"$lang\""; return $tag . '>' . $code . '</code>'; } function format_classstyle($clsty, $class = '', $style = '') { $class = preg_replace('/^ /', '', $class); if ($clsty && (preg_match('/{([^}]+)}/', $clsty, $matches))) { $_style = $matches[1]; $_style = preg_replace('/\n/', ' ', $_style); $style .= ';'.$_style; $clsty = preg_replace('/{[^}]+}/', '', $clsty); } if ($clsty && (preg_match('/\(([A-Za-z0-9_\- ]+?)(?:#(.+?))?\)/',$clsty,$matches) || preg_match('/\(([A-Za-z0-9_\- ]+?)?(?:#(.+?))\)/', $clsty, $matches))) { if ($matches[1] || $matches[2]) { if ($class) { $class = $matches[1] . ' ' . $class; } else { $class = $matches[1]; } $id = $matches[2]; if ($class) $clsty = preg_replace('/\([A-Za-z0-9_\- ]+?(#.*?)?\)/', '', $clsty); if ($id) $clsty = preg_replace('/\(#.+?\)/', '', $clsty); } } if ($clsty && (preg_match('/(\(+)/', $clsty, $matches))) { $padleft = strlen($matches[1]); $clsty = preg_replace('/\(+/', '', $clsty, 1); } if ($clsty && (preg_match('/(\)+)/', $clsty, $matches))) { $padright = strlen($matches[1]); $clsty = preg_replace('/\)+/', '', $clsty, 1); } if ($clsty && (preg_match('/\[(.+?)\]/', $clsty, $matches))) { $lang = $matches[1]; $clsty = preg_replace('/\[.+?\]/', '', $clsty); } $attrs = ''; if ($padleft) $style .= ";padding-left:$padleft".'em'; if ($padright) $style .= ";padding-right:$padright".'em'; $style = preg_replace('/^;/', '', $style); $class = preg_replace('/^ /', '', $class); $class = preg_replace('/ $/', '', $class); if ($class) $attrs .= " class=\"$class\""; if ($id) $attrs .= " id=\"$id\""; if ($style) $attrs .= " style=\"$style\""; if ($lang) $attrs .= " lang=\"$lang\""; $attrs = preg_replace('/^ /', '', $attrs); return $attrs; } function format_tag($args) { $tagname = $args['tag']; $text = array_key_exists('text', $args) ? $args['text'] : ''; $pre = array_key_exists('pre', $args) ? $args['pre'] : ''; $post = array_key_exists('post', $args) ? $args['post'] : ''; $clsty = array_key_exists('clsty', $args) ? $args['clsty'] : ''; _strip_borders($pre, $post); $tag = "<$tagname"; $attr = $this->format_classstyle($clsty); if ($attr) $tag .= " $attr"; $tag .= ">$text</$tagname>"; return $pre.$tag.$post; } function _add_term($dt, $dd) { if (preg_match('/^('.$this->clstyre.'*)/x', $dt, $matches)) { $param = $matches[1]; $dtattr = $this->format_classstyle($param); if (preg_match('/\[([A-Za-z]+?)\]/', $param, $matches)) { $dtlang = $matches[1]; } $dt = substr($dt, strlen($param)); } if (preg_match('/^('.$this->clstyre.'*)/x', $dd, $matches)) { $param = $matches[1]; # if the language was specified for the term, # then apply it to the definition as well (unless # already specified of course) if ($dtlang && (preg_match('/\[([A-Za-z]+?)\]/', $param))) { unset($dtlang); } $ddattr = $this->format_classstyle(($dtlang ? "[$dtlang]" : '') . $param); $dd = substr($dd, strlen($param)); } $out = '<dt'; if ($dtattr) $out .= " $dtattr"; $out .= '>' . $this->format_paragraph(array('text' => $dt)) . '</dt>' . "\n"; if (preg_match('/\n\n/', $dd)) { $dd = $this->textile($dd); } else { $dd = $this->format_paragraph(array('text' => $dd)); } $out .= '<dd'; if ($ddattr) $out .= " $ddattr"; return $out .= '>' . $dd . '</dd>' . "\n"; } function format_deflist($args) { $str = array_key_exists('text', $args) ? $args['text'] : ''; $lines = preg_split('/\n/', $str); if (preg_match('/^(dl('.$this->clstyre.'*?)\.\.?(?:\ +|$))/x', $lines[0], $matches)) { $clsty = $matches[2]; $lines[0] = substr($lines[0], strlen($matches[1])); } $out = ''; foreach ($lines as $line) { if (preg_match('/^((?:'.$this->clstyre.'*)(?:[^\ ].*?)(?<!["\'\ ])):([^\ \/].*)$/x', $line, $matches)) { if ($dt && $dd) $out .= $this->_add_term($dt, $dd); $dt = $matches[1]; $dd = $matches[2]; } else { $dd .= "\n" . $line; } } if ($dt && $dd) $out .= $this->_add_term($dt, $dd); $tag = '<dl'; if ($clsty) $attr = $this->format_classstyle($clsty); if ($attr) $tag .= " $attr"; $tag .= '>'."\n"; return $tag.$out."</dl>\n"; } function format_list($args) { $str = array_key_exists('text', $args) ? $args['text'] : ''; $list_tags = array('*' => 'ul', '#' => 'ol'); $lines = preg_split('/\n/', $str); $stack = array(); $last_depth = 0; $item = ''; $out = ''; foreach ($lines as $line) { if (preg_match('/^((?:'.$this->clstypadre.'*|'.$this->halignre.')*)? ([\#\*]+) ((?:'.$this->halignre.'|'.$this->clstypadre.'*)*)? \ (.+)$/x', $line, $matches)) { if ($item != '') { if (preg_match('/\n/', $item)) { if ($this->_line_open) { $item = preg_replace('/(<li[^>]*>|^)/m', '\\1'.$this->_line_open.'/', $item); $item = preg_replace('/(\n|$)/s', $this->_line_close.'\\1', $item); } else { $item = preg_replace('/(\n)/s',$this->_line_close.'\\1', $item); } } $out .= $item; $item = ''; } $type = substr($matches[2], 0, 1); $depth = strlen($matches[2]); $blockparam = $matches[1]; $itemparam = $matches[3]; $line = $matches[4]; unset ($blockclsty, $blockalign, $blockattr, $itemattr, $itemclsty, $itemalign); if (preg_match('/('.$this->clstypadre.'+)/x', $blockparam, $matches)) $blockclsty = $matches[1]; if (preg_match('/('.$this->halignre.'+)/x', $blockparam, $matches)) $blockalign = $matches[1]; if (preg_match('/('.$this->clstypadre.'+)/x', $itemparam, $matches)) $itemclsty = $matches[1]; if (preg_match('/('.$this->halignre.'+)/x', $itemparam, $matches)) $itemalign = $matches[1]; if ($itemclsty) $itemattr = $this->format_classstyle($itemclsty); if ($depth > $last_depth) { for ($j = $last_depth; $j < $depth; $j++) { $out .= "\n<" . $list_tags[$type]; $stack[] = $type; if ($blockclsty) { $blockattr = $this->format_classstyle($blockclsty); if ($blockattr) $out .= ' '.$blockattr; } $out .= ">\n<li"; if ($itemattr) $out .= " $itemattr"; $out .= ">"; } } elseif ($depth < $last_depth) { for ($j = $depth; $j < $last_depth; $j++) { if ($j == $depth) $out .= "</li>\n"; $type = array_pop($stack); $out .= "</$list_tags[$type]>\n</li>\n"; } if ($depth) { $out .= '<li'; if ($itemattr) $out .= " $itemattr"; $out .= '>'; } } else { $out .= "</li>\n<li"; if ($itemattr) $out .= " $itemattr"; $out .= '>'; } $last_depth = $depth; } if ($item != '') $item .= "\n"; $item .= $this->format_paragraph(array('text' => $line)); } if (preg_match('/\n/', $item)) { if ($this->_line_open) { $item = preg_replace('/(<li[^>]*>|^)/m', '\\1'.$this->_line_open, $item); $item = preg_replace('/(\n|$)/s', $this->_line_close.'\\1', $item); } else { $item = preg_replace('/(\n)/s', $this->_line_close.'\\1', $item); } } $out .= $item; for ($j = 1; $j <= $last_depth; $j++) { if ($j == 1) $out .= '</li>'; $type = array_pop($stack); $out .= "\n".'</'.$list_tags[$type].'>'."\n"; if ($j != $last_depth) $out .= '</li>'; } return $out."\n"; } function format_block($args) { $str = array_key_exists('text', $args) ? $args['text'] : ''; $inline = $args['inline']; $pre = array_key_exists('pre', $args) ? $args['pre'] : ''; $post = array_key_exists('post', $args) ? $args['post'] : ''; _strip_borders($pre, $post); if (preg_match('/^(\|(?:(?:[a-z0-9_\-]+)\|)+)/', $str, $matches)) { $filters = $matches[1]; $filtreg = preg_quote($filters); $str = preg_replace("/^$filtreg/", '', $str); $filters = preg_replace('/^\|/', '', $filters); $filters = preg_replace('/\|$/', '', $filters); $filter_list = preg_split('/\|/', $filters); $str = $this->apply_filters(array('text' => $str, 'filters' => $filter_list)); $count = count($filter_list); if ($str = preg_replace("/(<p>){$count}/s", '\\1', $str)) { $str = preg_replace("/(<\/p>){$count}/s", '\\1', $str); $str = preg_replace("/(<br( \/)?".">){$count}/s", '\\1', $str); } } if ($inline) { # strip off opening para, closing para, since we're # operating within an inline block $str = preg_replace('/^\s*<p[^>]*>/', '', $str); $str = preg_replace('/<\/p>\s*$/', '', $str); } return $pre.$str.$post; } function format_link($args) { $text = array_key_exists('text', $args) ? $args['text'] : ''; $linktext = array_key_exists('linktext', $args) ? $args['linktext'] : ''; $title = $args['title']; $url = $args['url']; $clsty = $args['clsty']; if (!isset($url) || ($url == '')) return $text; if (array_key_exists($url, $this->links)) { $title or $title = $this->links[$url]['title']; $url = $this->links[$url]['url']; } $linktext = preg_replace('/ +$/', '', $linktext); $linktext = $this->format_paragraph(array('text' => $linktext)); $url = $this->format_url(array('linktext' => $linktext, 'url' => $url)); $tag = "<a href=\"$url\""; $attr = $this->format_classstyle($clsty); if ($attr) $tag .= " $attr"; if ($title != '') { $title = preg_replace('/^\s+/', '', $title); if (title != '') $tag .= " title=\"$title\""; } $tag .= ">$linktext</a>"; return $tag; } function format_url($args) { $url = array_key_exists('url', $args) ? $args['url'] : ''; if (preg_match('/^(mailto:)?([-\+\w]+\@[-\w]+(\.\w[-\w]*)+)$/', $url, $matches)) $url = 'mailto:'.$this->mail_encode($matches[2]); if (!preg_match('/^(\/|\.\/|\.\.\/|#)/', $url)) if (!preg_match('/^(https?|ftp|mailto|nntp|telnet)/', $url)) $url = "http://$url"; $url = preg_replace('/&(?!amp;)/', '&', $url); $url = preg_replace('/\ /', '+', $url); $url = preg_replace_callback('/^((?:.+?)\?)(.+)$/', array(&$this, '_replace_enc_link'), $url); return $url; } function format_span($args) { $text = array_key_exists('text', $args) ? $args['text'] : ''; $pre = array_key_exists('pre', $args) ? $args['pre'] : ''; $post = array_key_exists('post', $args) ? $args['post'] : ''; $align = $args['align']; $cite = array_key_exists('cite', $args) ? $args['cite'] : ''; $clsty = $args['clsty']; _strip_borders($pre, $post); $tag = '<span'; $style = ''; if (isset($align)) { if ($this->css_mode) { $alignment = _halign($align); if ($alignment) { $style .= ";float:$alignment"; $class .= ' '.$this->css["class_align_$alignment"]; } } else { $alignment = _halign($align) or _valign($align); if ($alignment) $tag .= " align=\"$alignment\""; } } $attr = $this->format_classstyle($clsty, $class, $style); if ($attr) $tag .= " $attr"; if ($cite != '') { $cite = preg_replace('/^:/', '', $cite); $cite = $this->format_url(array('url' => $cite)); $tag .= " cite=\"$cite\""; } return $pre.$tag.'>'.$this->format_paragraph(array('text' => $text)).'</span>'.$post; } function format_image($args) { $src = array_key_exists('src', $args) ? $args['src'] : ''; $extra = $args['extra']; $align = $args['align']; $pre = array_key_exists('pre', $args) ? $args['pre'] : ''; $post = array_key_exists('post', $args) ? $args['post'] : ''; $link = $args['url']; $clsty = $args['clsty']; _strip_borders($pre, $post); if ($src == '') return $pre.'!!'.$post; if (preg_match('/^xhtml2/', $this->flavor)) { $type; # poor man's mime typing. need to extend this externally if (preg_match('/(?:\.jpeg|\.jpg)$/i', $src)) { $type = 'image/jpeg'; } elseif (preg_match('/\.gif$/i', $src)) { $type = 'image/gif'; } elseif (preg_match('/\.png$/i', $src)) { $type = 'image/png'; } elseif (preg_match('/\.tiff$/i', $src)) { $type = 'image/tiff'; } $tag = '<object'; if ($type) $tag .= " type=\"$type\""; $tag .= " data=\"$src\""; } else { $tag = "<img src=\"$src\""; } if (isset($align)) { if ($this->css_mode) { $alignment = _halign($align); if ($alignment) { $style .= ";float:$alignment"; $class .= ' '.$alignment; } $alignment = _valign($align); if ($alignment) { $imgvalign = (preg_match('/(top|bottom)/', $alignment) ? 'text-' . $alignment : $alignment); if ($imgvalign) $style .= ";vertical-align:$imgvalign"; if ($aligment) $class .= ' '.$this->css["class_align_$alignment"]; } } else { $alignment = _halign($align) or _valign($align); if ($alignment) $tag .= " align=\"$alignment\""; } } if (isset($extra)) { if (preg_match('/\(([^\)]+)\)/', $extra, $matches)) $alt = $matches[1]; $extra = preg_replace('/\([^\)]+\)/', '', $extra, 1); if (preg_match('/(?:^|\s)(\d+)%(?:\s|$)/', $extra, $matches)) $pct = $matches[1]; if (!$pct) { if (preg_match('/(?:^|\s)(\d+)%x(\d+)%(?:\s|$)/', $extra, $matches)) { $pctw = $matches[1]; $pcth = $matches[2]; } } else { $pctw = $pct; $pcth = $pct; } if (!$pctw && !$pcth) { if (preg_match('/(?:^|\s)(\d+|\*)x(\d+|\*)(?:\s|$)/', $extra, $matches)) { $w = $matches[1]; $h = $matches[2]; } if ($w == '*') $w = ''; if ($h == '*') $h = ''; if (!$w) if (preg_match('/(^|[,\s])(\d+)w([\s,]|$)/', $extra, $matches)) $w = $matches[1]; if (!$h) if (preg_match('/(^|[,\s])(\d+)h([\s,]|$)/', $extra, $matches)) $h = $matches[1]; } } if (!isset($alt)) $alt = ''; if (!preg_match('/^xhtml2/', $this->flavor)) { $tag .= ' alt="' . $this->encode_html_basic($alt) . '"'; } if ($w && $h) { if (!preg_match('/^xhtml2/', $this->flavor)) { $tag .= " height=\"$h\" width=\"$w\""; } else { $style .= ";height:$h\px;width:$w\px"; } } else { list($image_w, $image_h) = $this->image_size($src); if (($image_w && $image_h) && ($w || $h)) { # image size determined, but only width or height specified if ($w && !$h) { # width defined, scale down height proportionately $h = int($image_h * ($w / $image_w)); } elseif ($h && !$w) { $w = int($image_w * ($h / $image_h)); } } else { $w = $image_w; $h = $image_h; } if ($w && $h) { if ($pctw || $pcth) { $w = int($w * $pctw / 100); $h = int($h * $pcth / 100); } if (preg_match('/^xhtml2', $this->flavor)) { $tag .= " height=\"$h\" width=\"$w\""; } else { $style .= ";height:$h\px;width:$w\px"; } } } $attr = $this->format_classstyle($clsty, $class, $style); if ($attr) $tag .= " $attr"; if (preg_match('/^xhtml2/', $this->flavor)) { $tag .= '><p>' . $this->encode_html_basic($alt) . '</p></object>'; } elseif (preg_match('/^xhtml/', $this->flavor)) { $tag .= ' />'; } else { $tag .= '>'; } if ($link != '') { $link = preg_replace('/^:/', '', $link); $link = $this->format_url(array('url' => $link)); $tag = '<a href="'.$link.'">'.$tag.'</a>'; } return $pre.$tag.$post; } function format_table($args) { $str = array_key_exists('text',$args) ? $args['text'] : ''; $lines = preg_split('/\n/', $str); $rows = array(); $line_count = count($lines); for ($i = 0; $i < $line_count; $i++) { if (!preg_match('/\|\s*$/', $lines[$i])) { if ($i + 1 < $line_count) { if ($i+1 <= (count($lines) - 1)) $lines[$i+1] = $lines[$i] . "\n" . $lines[$i+1]; } else { $rows[] = $lines[$i]; } } else { $rows[] = $lines[$i]; } } unset ($tid, $tpadl, $tpadr, $tlang); $tclass = ''; $tstyle = ''; $talign = ''; if (preg_match('/^table[^\.]/', $rows[0])) { $row = $rows[0]; $row = preg_replace('/^table/', '', $row); $params = 1; # process row parameters until none are left while ($params) { if (preg_match('/^('.$this->tblalignre.')/x', $row, $matches)) { # found row alignment $talign .= $matches[1]; if ($matches[1]) { $row = substr($row, strlen($matches[1])); continue; } } if (preg_match('/^('.$this->clstypadre.')/x', $row, $matches)) { # found a class/id/style/padding indicator $clsty = $matches[1]; if ($clsty) $row = substr($row, strlen($clsty)); if (preg_match('/{([^}]+)}/', $clsty, $matches)) { $tstyle = $matches[1]; $clsty = preg_replace('/{([^}]+)}/', '', $clsty); if ($tstyle) continue; } if (preg_match('/\(([A-Za-z0-9_\- ]+?)(?:#(.+?))?\)/', $clsty, $matches) || preg_match('/\(([A-Za-z0-9_\- ]+?)?(?:#(.+?))\)/', $clsty, $matches)) { if ($matches[1] or $matches[2]) { $tclass = $matches[1]; $tid = $matches[2]; continue; } } if (preg_match('/(\(+)/', $clsty, $matches)) $tpadl = strlen($matches[1]); if (preg_match('/(\)+)/', $clsty, $matches)) $tpadr = strlen($matches[1]); if (preg_match('/\[(.+?)\]/', $clsty, $matches)) $tlang = $matches[1]; if ($clsty) continue; } $params = 0; } $row = preg_replace('/\.\s+/s', '', $row, 1); $rows[0] = $row; } $out = ''; $cols = preg_split('/\|/', $rows[0].' '); $colaligns = array(); $rowspans = array(); foreach ($rows as $row) { $cols = preg_split('/\|/', $row.' '); $colcount = count($cols) - 1; array_pop($cols); $colspan = 0; $row_out = ''; unset ($rowclass, $rowid, $rowalign, $rowstyle, $rowheader); if (!isset($cols[0])) $cols[0] = ''; if (preg_match('/_/', $cols[0])) { $cols[0] = preg_replace('/_/', '', $cols[0]); $rowheader = 1; } if (preg_match('/{([^}]+)}/', $cols[0], $matches)) { $rowstyle = $matches[1]; $cols[0] = preg_replace('/{[^}]+}/', '', $cols[0]); } if (preg_match('/\(([^\#]+?)?(#(.+))?\)/', $cols[0], $matches)) { $rowclass = $matches[1]; $rowid = $matches[3]; $cols[0] = preg_replace('/\([^\)]+\)/', '', $cols[0]); } if (preg_match('/('.$this->alignre.')/x', $cols[0], $matches)) $rowalign = $matches[1]; for ($c = $colcount - 1; $c > 0; $c--) { if ($rowspans[$c]) { $rowspans[$c]--; if ($rowspans[$c] > 1) continue; } unset ($colclass, $colid, $header, $colparams, $colpadl, $colpadr, $collang); $colstyle = ''; $colalign = $colaligns[$c]; $col = array_pop($cols); $col or $col = ''; $attrs = ''; if (preg_match('/^(((_|[\/\\\\]\d+|'.$this->alignre.'|'.$this->clstypadre.')+)\. )/x', $col, $matches)) { $colparams = $matches[2]; $col = substr($col, strlen($matches[1])); $params = 1; # keep processing column parameters until there # are none left... while ($params) { if (preg_match('/^(_|'.$this->alignre.')/x', $colparams, $matches)) { # found alignment or heading indicator $attrs .= $matches[1]; if ($matches[1]) { $colparams = substr($colparams, strlen($matches[1])); continue; } } if (preg_match('/^('.$this->clstypadre.')/x', $colparams, $matches)) { # found a class/id/style/padding marker $clsty = $matches[1]; if ($matches[1]) $colparams = substr($colparams, strlen($matches[1])); if (preg_match('/{([^}]+)}/', $clsty, $matches)) { $colstyle = $matches[1]; $clsty = preg_replace('/{([^}]+)}/', '', $clsty, 1); } if (preg_match('/\(([A-Za-z0-9_\- ]+?)(?:#(.+?))?\)/', $clsty, $matches) || preg_match('/\(([A-Za-z0-9_\- ]+?)?(?:#(.+?))\)/', $clsty, $matches)) { if ($matches[1] or $matches[2]) { $colclass = $matches[1]; $colid = $matches[2]; if ($colclass) { $clsty = preg_replace('/\([A-Za-z0-9_\- ]+?(#.*?)?\)/', '', $clsty); } elseif ($colid) { $clsty = preg_replace('/\(#.+?\)/', '', $clsty); } } } if (preg_match('/(\(+)/', $clsty, $matches)) { $colpadl = strlen($matches[1]); $clsty = preg_replace('/\(+/', '', $clsty, 1); } if (preg_match('/(\)+)/', $clsty, $matches)) { $colpadr = strlen($matches[1]); $clsty = preg_replace('/\)+/', '', $clsty, 1); } if (preg_match('/\[(.+?)\]/', $clsty, $matches)) { $collang = $matches[1]; $clsty = preg_replace('/\[.+?\]/', '', $clsty, 1); } if ($clsty) continue; } if (preg_match('/^\\\\(\d+)/', $colparams, $matches)) { $colspan = $matches[1]; $colparams = substr($colparams, strlen($matches[1])+1); continue; } if (preg_match('/\/(\d+)/', $colparams, $matches)) { if ($matches[1]) $rowspans[$c] = $matches[1]; $colparams = substr($colparams, strlen($matches[1])+1); continue; } $params = 0; } } if (strlen($attrs)) { if (preg_match('/_/', $attrs)) $header = 1; if (preg_match('/('.$this->alignre.')/x', $attrs, $matches) && strlen($matches[1])) $colalign = ''; # determine column alignment if (preg_match('/<>/', $attrs)) { $colalign .= '<>'; } elseif (preg_match('/</', $attrs)) { $colalign .= '<'; } elseif (preg_match('/=/', $attrs)) { $colalign = '='; } elseif (preg_match('/>/', $attrs)) { $colalign = '>'; } if (preg_match('/\^/', $attrs)) { $colalign .= '^'; } elseif (preg_match('/~/', $attrs)) { $colalign .= '~'; } elseif (preg_match('/-/', $attrs)) { $colalign .= '-'; } } if ($rowheader) $header = 1; if ($header) $colaligns[$c] = $colalign; $col = preg_replace('/^ +/', '', $col); $col = preg_replace('/ +$/', '', $col); if (strlen($col)) { # create one cell tag $rowspan = $rowspans[$c]; $col_out = '<' . ($header ? 'th' : 'td'); if (!empty($colalign)) { # horizontal, vertical alignment $halign = _halign($colalign); if ($halign) $col_out .= " align=\"$halign\""; $valign = _valign($colalign); if ($valign) $col_out .= " valign=\"$valign\""; } # apply css attributes, row, column spans if ($colpadl) $colstyle .= ";padding-left:$colpadl".'em'; if ($colpadr) $colstyle .= ";padding-right:$colpadr".'em'; if ($colclass) $col_out .= " class=\"$colclass\""; if ($colid) $col_out .= " id=\"$colid\""; if ($colstyle) $colstyle = preg_replace('/^;/', '', $colstyle); if ($colstyle) $col_out .= " style=\"$colstyle\""; if ($collang) $col_out .= " lang=\"$collang\""; if ($colspan > 1) $col_out .= " colspan=\"$colspan\""; if ($rowspan > 1) $col_out .= " rowspan=\"$rowspan\""; $col_out .= '>'; # if the content of this cell has newlines OR matches # our paragraph block signature, process it as a full-blown # textile document if (preg_match('/\n\n/', $col) || preg_match('/^(?:'.$this->halignre.'|'.$this->clstypadre.'*)* [\*\#] (?:'.$this->clstypadre.'*|'.$this->halignre.')*\ /x', $col, $matches)) { $col_out .= $this->TextileThis($col); } else { $col_out .= $this->format_paragraph(array('text' => $col)); } $col_out .= '</' . ($header ? 'th' : 'td') . '>'; $row_out = $col_out . $row_out; if ($colspan) $colspan = 0; } else { if ($colspan == 0) $colspan = 1; $colspan++; } } if ($colspan > 1) { # handle the spanned column if we came up short $colspan--; $row_out = '<td' . ($colspan>1 ? " colspan=\"$colspan\"" : '') . "></td>$row_out"; } # build one table row $out .= '<tr'; if ($rowalign) { $valign = _valign($rowalign); if ($valign) $out .= " valign=\"$valign\""; } if ($rowclass) $out .= " class=\"$rowclass\""; if ($rowid) $out .= " id=\"$rowid\""; if ($rowstyle) $out .= " style=\"$rowstyle\""; $out .= ">$row_out</tr>"; } # now, form the table tag itself $table = ''; $table .= '<table'; if ($talign) { if ($this->css_mode) { # horizontal alignment $alignment = _halign($talign); if ($talign == '=') { $tstyle .= ';margin-left:auto;margin-right:auto'; } else { if ($alignment) $tstyle .= ';float:'.$alignment; } if ($alignment) $tclass .= ' '.$alignment; } else { $alignment = _halign($talign); if ($alignment) $table .= " align=\"$alignment\""; } } if ($tpadl) $tstyle .= ";padding-left:$tpadl".'em'; if ($tpadr) $tstyle .= ";padding-right:$tpadr".'em'; if ($tclass) $tclass = preg_replace('/^ /', '', $tclass); if ($tclass) $table .= " class=\"$tclass\""; if ($tid) $table .= " id=\"$tid\""; if ($tstyle) $tstyle = preg_replace('/^;/', '', $tstyle); if ($tstyle) $table .= " style=\"$tstyle\""; if ($tlang) $table .= " lang=\"$tlang\""; if ($tclass || $tid || $tstyle) $table .= ' cellspacing="0"'; $table .= ">$out</table>"; if (preg_match('|<tr></tr>|', $table)) { # exception -- something isn't right so return fail case return null; } return $table; } function apply_filters($args) { $text = $args['text']; if (!isset($text)) return ''; $list = $args['filters']; $filters = $this->filters; if (!is_array($filters)) return $text; $param = $this->filter_param; foreach ($list as $filter) { if (!array_key_exists($filter, $filters)) continue; if (is_callable($filters[$filter])) { $text = $filters[$filter]($text, $param); } } $text; } # minor utility / formatting routines function encode_html($html, $can_double_encode = 0) { if (!isset($html)) return ''; if ($this->char_encoding) { $html = htmlentities($html); } else { $html = $this->encode_html_basic($html, $can_double_encode); } return $html; } function decode_html($html) { $html = preg_replace('/"/', '"', $html); $html = preg_replace('/&/', '&', $html); $html = preg_replace('/</', '<', $html); $html = preg_replace('/>/', '>', $html); return $html; } function encode_html_basic($html, $can_double_encode = 0) { //$html = stripslashes($html); if (!isset($html)) return ''; if (!preg_match('/[^\w\s]/', $html)) return $html; if ($can_double_encode) $html = preg_replace('/&/', '&', $html); else { ## Encode any & not followed by something that looks like ## an entity, numeric or otherwise. $html = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w{1,8});)/', '&', $html); } $html = preg_replace('/"/', '"', $html); $html = preg_replace('/</', '<', $html); $html = preg_replace('/>/', '>', $html); return $html; } function image_size($file) { if ($Have_ImageSize) { if (file_exists($file)) { #return Image::Size::imgsize($file); } else { if ($docroot = $this->docroot) { #require File::Spec; #$fullpath = File::Spec->catfile($docroot, $file); #if (-f $fullpath) { # return Image::Size::imgsize($fullpath); #} } } } return; } function encode_url($str) { $str = preg_replace_callback('/([^A-Za-z0-9_\.\-\+\&=\%;])/x', array(&$this, '_replace_enc_char'), $str); return $str; #return urlencode($str); } function mail_encode($addr) { $addr = preg_replace_callback('/([^\$])/x', array(&$this, '_replace_enc_char'), $addr); return $addr; } function process_quotes($str) { return $str; } # a default set of macros for the {...} macro syntax # just a handy way to write a lot of the international characters # and some commonly used symbols function default_macros() { # <, >, " must be html entities in the macro text since # those values are escaped by the time they are processed # for macros. return array( 'c|' => '¢', # CENT SIGN '|c' => '¢', # CENT SIGN 'L-' => '£', # POUND SIGN '-L' => '£', # POUND SIGN 'Y=' => '¥', # YEN SIGN '=Y' => '¥', # YEN SIGN '(c)' => '©', # COPYRIGHT SIGN '<<' => '«', # LEFT-POINTING DOUBLE ANGLE QUOTATION '(r)' => '®', # REGISTERED SIGN '+_' => '±', # PLUS-MINUS SIGN '_+' => '±', # PLUS-MINUS SIGN '>>' => '»', # RIGHT-POINTING DOUBLE ANGLE QUOTATION '1/4' => '¼', # VULGAR FRACTION ONE QUARTER '1/2' => '½', # VULGAR FRACTION ONE HALF '3/4' => '¾', # VULGAR FRACTION THREE QUARTERS 'A`' => 'À', # LATIN CAPITAL LETTER A WITH GRAVE '`A' => 'À', # LATIN CAPITAL LETTER A WITH GRAVE 'A\'' => 'Á', # LATIN CAPITAL LETTER A WITH ACUTE '\'A' => 'Á', # LATIN CAPITAL LETTER A WITH ACUTE 'A^' => 'Â', # LATIN CAPITAL LETTER A WITH CIRCUMFLEX '^A' => 'Â', # LATIN CAPITAL LETTER A WITH CIRCUMFLEX 'A~' => 'Ã', # LATIN CAPITAL LETTER A WITH TILDE '~A' => 'Ã', # LATIN CAPITAL LETTER A WITH TILDE 'A"' => 'Ä', # LATIN CAPITAL LETTER A WITH DIAERESIS '"A' => 'Ä', # LATIN CAPITAL LETTER A WITH DIAERESIS 'Ao' => 'Å', # LATIN CAPITAL LETTER A WITH RING ABOVE 'oA' => 'Å', # LATIN CAPITAL LETTER A WITH RING ABOVE 'AE' => 'Æ', # LATIN CAPITAL LETTER AE 'C,' => 'Ç', # LATIN CAPITAL LETTER C WITH CEDILLA ',C' => 'Ç', # LATIN CAPITAL LETTER C WITH CEDILLA 'E`' => 'È', # LATIN CAPITAL LETTER E WITH GRAVE '`E' => 'È', # LATIN CAPITAL LETTER E WITH GRAVE 'E\'' => 'É', # LATIN CAPITAL LETTER E WITH ACUTE '\'E' => 'É', # LATIN CAPITAL LETTER E WITH ACUTE 'E^' => 'Ê', # LATIN CAPITAL LETTER E WITH CIRCUMFLEX '^E' => 'Ê', # LATIN CAPITAL LETTER E WITH CIRCUMFLEX 'E"' => 'Ë', # LATIN CAPITAL LETTER E WITH DIAERESIS '"E' => 'Ë', # LATIN CAPITAL LETTER E WITH DIAERESIS 'I`' => 'Ì', # LATIN CAPITAL LETTER I WITH GRAVE '`I' => 'Ì', # LATIN CAPITAL LETTER I WITH GRAVE 'I\'' => 'Í', # LATIN CAPITAL LETTER I WITH ACUTE '\'I' => 'Í', # LATIN CAPITAL LETTER I WITH ACUTE 'I^' => 'Î', # LATIN CAPITAL LETTER I WITH CIRCUMFLEX '^I' => 'Î', # LATIN CAPITAL LETTER I WITH CIRCUMFLEX 'I"' => 'Ï', # LATIN CAPITAL LETTER I WITH DIAERESIS '"I' => 'Ï', # LATIN CAPITAL LETTER I WITH DIAERESIS 'D-' => 'Ð', # LATIN CAPITAL LETTER ETH '-D' => 'Ð', # LATIN CAPITAL LETTER ETH 'N~' => 'Ñ', # LATIN CAPITAL LETTER N WITH TILDE '~N' => 'Ñ', # LATIN CAPITAL LETTER N WITH TILDE 'O`' => 'Ò', # LATIN CAPITAL LETTER O WITH GRAVE '`O' => 'Ò', # LATIN CAPITAL LETTER O WITH GRAVE 'O\'' => 'Ó', # LATIN CAPITAL LETTER O WITH ACUTE '\'O' => 'Ó', # LATIN CAPITAL LETTER O WITH ACUTE 'O^' => 'Ô', # LATIN CAPITAL LETTER O WITH CIRCUMFLEX '^O' => 'Ô', # LATIN CAPITAL LETTER O WITH CIRCUMFLEX 'O~' => 'Õ', # LATIN CAPITAL LETTER O WITH TILDE '~O' => 'Õ', # LATIN CAPITAL LETTER O WITH TILDE 'O"' => 'Ö', # LATIN CAPITAL LETTER O WITH DIAERESIS '"O' => 'Ö', # LATIN CAPITAL LETTER O WITH DIAERESIS 'O/' => 'Ø', # LATIN CAPITAL LETTER O WITH STROKE '/O' => 'Ø', # LATIN CAPITAL LETTER O WITH STROKE 'U`' => 'Ù', # LATIN CAPITAL LETTER U WITH GRAVE '`U' => 'Ù', # LATIN CAPITAL LETTER U WITH GRAVE 'U\'' => 'Ú', # LATIN CAPITAL LETTER U WITH ACUTE '\'U' => 'Ú', # LATIN CAPITAL LETTER U WITH ACUTE 'U^' => 'Û', # LATIN CAPITAL LETTER U WITH CIRCUMFLEX '^U' => 'Û', # LATIN CAPITAL LETTER U WITH CIRCUMFLEX 'U"' => 'Ü', # LATIN CAPITAL LETTER U WITH DIAERESIS '"U' => 'Ü', # LATIN CAPITAL LETTER U WITH DIAERESIS 'Y\'' => 'Ý', # LATIN CAPITAL LETTER Y WITH ACUTE '\'Y' => 'Ý', # LATIN CAPITAL LETTER Y WITH ACUTE 'a`' => 'à', # LATIN SMALL LETTER A WITH GRAVE '`a' => 'à', # LATIN SMALL LETTER A WITH GRAVE 'a\'' => 'á', # LATIN SMALL LETTER A WITH ACUTE '\'a' => 'á', # LATIN SMALL LETTER A WITH ACUTE 'a^' => 'â', # LATIN SMALL LETTER A WITH CIRCUMFLEX '^a' => 'â', # LATIN SMALL LETTER A WITH CIRCUMFLEX 'a~' => 'ã', # LATIN SMALL LETTER A WITH TILDE '~a' => 'ã', # LATIN SMALL LETTER A WITH TILDE 'a"' => 'ä', # LATIN SMALL LETTER A WITH DIAERESIS '"a' => 'ä', # LATIN SMALL LETTER A WITH DIAERESIS 'ao' => 'å', # LATIN SMALL LETTER A WITH RING ABOVE 'oa' => 'å', # LATIN SMALL LETTER A WITH RING ABOVE 'ae' => 'æ', # LATIN SMALL LETTER AE 'c,' => 'ç', # LATIN SMALL LETTER C WITH CEDILLA ',c' => 'ç', # LATIN SMALL LETTER C WITH CEDILLA 'e`' => 'è', # LATIN SMALL LETTER E WITH GRAVE '`e' => 'è', # LATIN SMALL LETTER E WITH GRAVE 'e\'' => 'é', # LATIN SMALL LETTER E WITH ACUTE '\'e' => 'é', # LATIN SMALL LETTER E WITH ACUTE 'e^' => 'ê', # LATIN SMALL LETTER E WITH CIRCUMFLEX '^e' => 'ê', # LATIN SMALL LETTER E WITH CIRCUMFLEX 'e"' => 'ë', # LATIN SMALL LETTER E WITH DIAERESIS '"e' => 'ë', # LATIN SMALL LETTER E WITH DIAERESIS 'i`' => 'ì', # LATIN SMALL LETTER I WITH GRAVE '`i' => 'ì', # LATIN SMALL LETTER I WITH GRAVE 'i\'' => 'í', # LATIN SMALL LETTER I WITH ACUTE '\'i' => 'í', # LATIN SMALL LETTER I WITH ACUTE 'i^' => 'î', # LATIN SMALL LETTER I WITH CIRCUMFLEX '^i' => 'î', # LATIN SMALL LETTER I WITH CIRCUMFLEX 'i"' => 'ï', # LATIN SMALL LETTER I WITH DIAERESIS '"i' => 'ï', # LATIN SMALL LETTER I WITH DIAERESIS 'n~' => 'ñ', # LATIN SMALL LETTER N WITH TILDE '~n' => 'ñ', # LATIN SMALL LETTER N WITH TILDE 'o`' => 'ò', # LATIN SMALL LETTER O WITH GRAVE '`o' => 'ò', # LATIN SMALL LETTER O WITH GRAVE 'o\'' => 'ó', # LATIN SMALL LETTER O WITH ACUTE '\'o' => 'ó', # LATIN SMALL LETTER O WITH ACUTE 'o^' => 'ô', # LATIN SMALL LETTER O WITH CIRCUMFLEX '^o' => 'ô', # LATIN SMALL LETTER O WITH CIRCUMFLEX 'o~' => 'õ', # LATIN SMALL LETTER O WITH TILDE '~o' => 'õ', # LATIN SMALL LETTER O WITH TILDE 'o"' => 'ö', # LATIN SMALL LETTER O WITH DIAERESIS '"o' => 'ö', # LATIN SMALL LETTER O WITH DIAERESIS ':-' => '÷', # DIVISION SIGN '-:' => '÷', # DIVISION SIGN 'o/' => 'ø', # LATIN SMALL LETTER O WITH STROKE '/o' => 'ø', # LATIN SMALL LETTER O WITH STROKE 'u`' => 'ù', # LATIN SMALL LETTER U WITH GRAVE '`u' => 'ù', # LATIN SMALL LETTER U WITH GRAVE 'u\'' => 'ú', # LATIN SMALL LETTER U WITH ACUTE '\'u' => 'ú', # LATIN SMALL LETTER U WITH ACUTE 'u^' => 'û', # LATIN SMALL LETTER U WITH CIRCUMFLEX '^u' => 'û', # LATIN SMALL LETTER U WITH CIRCUMFLEX 'u"' => 'ü', # LATIN SMALL LETTER U WITH DIAERESIS '"u' => 'ü', # LATIN SMALL LETTER U WITH DIAERESIS 'y\'' => 'ý', # LATIN SMALL LETTER Y WITH ACUTE '\'y' => 'ý', # LATIN SMALL LETTER Y WITH ACUTE 'y"' => 'ÿ', # LATIN SMALL LETTER Y WITH DIAERESIS '"y' => 'ÿ', # LATIN SMALL LETTER Y WITH DIAERESIS 'OE' => 'Œ', # LATIN CAPITAL LIGATURE OE 'oe' => 'œ', # LATIN SMALL LIGATURE OE '*' => 'ߦ', # BULLET 'Fr' => '₣', # FRENCH FRANC SIGN 'L=' => '₤', # LIRA SIGN '=L' => '₤', # LIRA SIGN 'Rs' => '₨', # RUPEE SIGN 'C=' => '€', # EURO SIGN '=C' => '€', # EURO SIGN 'tm' => '™', # TRADE MARK SIGN '<-' => '←', # LEFTWARDS ARROW '->' => '→', # RIGHTWARDS ARROW '<=' => '⇐', # LEFTWARDS DOUBLE ARROW '=>' => '⇒', # RIGHTWARDS DOUBLE ARROW '=/' => '≠', # NOT EQUAL TO '/=' => '≠', # NOT EQUAL TO '<_' => '≤', # LESS-THAN OR EQUAL TO '_<' => '≤', # LESS-THAN OR EQUAL TO '>_' => '≥', # GREATER-THAN OR EQUAL TO '_>' => '≥', # GREATER-THAN OR EQUAL TO ':(' => '☹', # WHITE FROWNING FACE ':)' => '☺', # WHITE SMILING FACE 'spade' => '♠', # BLACK SPADE SUIT 'club' => '♣', # BLACK CLUB SUIT 'heart' => '♥', # BLACK HEART SUIT 'diamond' => '♦', # BLACK DIAMOND SUIT ); } # "private", internal routines function _css_defaults() { $css_defaults = array( 'class_align_right' => 'right', 'class_align_left' => 'left', 'class_align_center' => 'center', 'class_align_top' => 'top', 'class_align_bottom' => 'bottom', 'class_align_middle' => 'middle', 'class_align_justify' => 'justify', 'class_caps' => 'caps', 'class_footnote' => 'footnote', 'id_footnote_prefix' => 'fn', ); $this->set_css($css_defaults); } function tokenize($str) { $tokens = array(); $depth = 6; $tag = array(); for ($i = 0; $i < $depth; $i++) { $tag[] = '(?:<\/?[A-Za-z0-9:]+ \s? (?:[^<>]'; } $nested_tags = implode('|', $tag) . str_repeat(')*>)',$depth); $match = '/((?s: <! ( -- .*? -- \s* )+ > )| (?s: <\? .*? \?> )| (?s: <% .*? %> )| '.$nested_tags.'| '.$this->codere2.')/x'; $items = preg_split($match, $str, -1, PREG_SPLIT_DELIM_CAPTURE); foreach ($items as $item) { if (preg_match('/^[[{]?\@/', $item)) { $tokens[] = array('text', $item); } elseif (preg_match($match, $item)) { $item = preg_replace('/\n/', "\001", $item); $tokens[] = array('tag', $item); } else { $tokens[] = array('text', $item); } } return $tokens; } } function _halign($align) { if (preg_match('/<>/', $align)) { return 'justify'; } elseif (preg_match('/</', $align)) { return 'left'; } elseif (preg_match('/>/', $align)) { return 'right'; } elseif (preg_match('/=/', $align)) { return 'center'; } return ''; } function _valign($align) { if (preg_match('/\^/', $align)) { return 'top'; } elseif (preg_match('/~/', $align)) { return 'bottom'; } elseif (preg_match('/-/', $align)) { return 'middle'; } return ''; } function _imgalign($align) { $align = preg_replace('/(<>|=)/', '', $align); return _valign($align) or _halign($align); } function _strip_borders(&$pre, &$post) { $open = substr($pre, 0, 1); if ($post && $pre && preg_match('/[{[]/', $open)) { $close = substr($post, 0, 1); if ((($open == '{') && ($close == '}')) || (($open == '[') && ($close == ']'))) { $pre = substr($pre, 1); $post = substr($post, 1); } else { if (!preg_match('/[}\]]/', $close)) $close = substr($post, -1, 1); if ((($open == '{') & ($close == '}')) || (($open == '[') & ($close == ']'))) { $pre = substr($pre, 1); $post = substr($post, 0, strlen($post) - 1); } } } return array($pre, $post); } ?>