parse($lines); return $body->toString(); } // インライン要素の変換 function guiedit_make_link($line) { $obj = new InlineConverterEx(); return $obj->convert($line); } // 添付ファイルプラグインの変換 function guiedit_convert_ref($args, $div = TRUE) { $options = htmlspecialchars(join(',', $args)); $filename = array_shift($args); $_title = array(); $params = array( 'left' => 0, // 左寄せ 'center' => 0, // 中央寄せ 'right' => 0, // 右寄せ 'wrap' => 0, // TABLEで囲む 'nowrap' => 0, // TABLEで囲まない 'around' => 0, // 回り込み 'noicon' => 0, // アイコンを表示しない 'nolink' => 0, // 元ファイルへのリンクを張らない 'noimg' => 0, // 画像を展開しない 'zoom' => 0, // 縦横比を保持する '_w' => 0, // 幅 '_h' => 0, // 高さ '_size' => '%' ); // パラメータ解析 foreach ($args as $arg) { $s_arg = strtolower($arg); if (array_key_exists($s_arg, $params)) { $params[$s_arg] = 1; } else if (preg_match('/^([0-9]+)x([0-9]+)$/', $arg, $matches)) { $params['_w'] = $matches[1]; $params['_h'] = $matches[2]; $params['_size'] = 'px'; } else if (preg_match('/^([0-9.]+)%$/', $arg, $matches) && $matches[1] > 0) { $params['_w'] = $matches[1]; } else { $_title[] = $arg; } } $align = ''; if ($params['left']) { $align = 'left'; } else if ($params['center']) { $align = 'center'; } else if ($params['right']) { $align = 'right'; } $alt = !empty($_title) ? htmlspecialchars(join(',', $_title)) : ''; $alt = preg_replace("/^,/", '', $alt); $attribute = 'class="ref" contenteditable="false"' . ((UA_NAME == MSIE) ? '' : ' style="cursor:default"'); $attribute .= ' _filename="' . $filename . '"'; $attribute .= ' _alt="' . $alt . '"'; $attribute .= ' _width="' . ($params['_w'] ? $params['_w'] : '') . '"'; $attribute .= ' _height="' . ($params['_h'] ? $params['_h'] : '') . '"'; $attribute .= ' _size="' . $params['_size'] . '"'; $attribute .= ' _align="' . $align . '"'; $attribute .= ' _wrap="' . $params['wrap'] . '"'; $attribute .= ' _around="' . $params['around'] . '"'; $attribute .= ' _nolink="' . $params['nolink'] . '"'; $attribute .= ' _noicon="' . $params['noicon'] . '"'; $attribute .= ' _noimg="' . $params['noimg'] . '"'; $attribute .= ' _zoom="' . $params['zoom'] . '"'; if ($div) { $tags = "
#ref($options)
"; } else { $tags = "&ref($options);"; } return $tags; } function guiedit_make_line_rules($line) { global $guiedit_line_rules, $guiedit_facemark_rules; global $usefacemark; static $pattern, $replace; if (!isset($pattern)) { if ($usefacemark) { $guiedit_line_rules += $guiedit_facemark_rules; } $pattern = array_map(create_function('$a', 'return \'/\' . $a . \'/\';'), array_keys($guiedit_line_rules)); $replace = array_values($guiedit_line_rules); unset($guiedit_facemark_rules); unset($guiedit_line_rules); } return preg_replace($pattern, $replace, $line); } // インライン変換クラス class InlineConverterEx { function convert($line, $link = TRUE, $enc = TRUE) { if ($enc) { $line = preg_replace("/&/", "&", $line); $line = htmlspecialchars($line); } // インライン・プラグイン $pattern = '/&(\w+)(?:\(((?:(?!\)[;{]).)*)\))?(?:\{((?:(?R)|(?!};).)*)\})?;/'; $line = preg_replace_callback($pattern, array(&$this, 'convert_plugin'), $line); // ルールの変換 $line = guiedit_make_line_rules($line); // 文字サイズの変換 $pattern = "//"; $line = preg_replace_callback($pattern, array(&$this, 'convert_size'), $line); // 色の変換 $pattern = "//"; $line = preg_replace_callback($pattern, array(&$this, 'convert_color'), $line); // 注釈 $line = preg_replace("/\(\(((?:(?R)|(?!\)\)).)*)\)\)/", "\"Note\"", $line); // 参照文字 $line = preg_replace('/&(#?[a-z0-9]+);/', "&$1;", $line); // 上付き文字 $line = preg_replace('/SUP{(.*?)}/', "$1", $line); // 下付き文字・添え字 $line = preg_replace('/SUB{(.*?)}/', "$1", $line); // リンク if ($link) { $pattern = "/\(\(((?:(?R)|(?!\)\)).)*)\)\)/"; $replace = "\"Note\""; $line = $this->make_link($line); } if (preg_match("/^$/", $line)) { $line .= "\n "; } return $line; } // 文からリンクを検出し、link_replace を呼び出す function make_link($line) { $link_rules = "/( (?:\[\[((?:(?!\]\]).)+):)? ((?:https?|ftp|news)(?::\/\/[!~*'();\/?:\@&=+\$,%#\w.-]+)) (?(2)\]\]) | (\[\[ (?: (?:((?:(?!\]\]).)+)) (?:>) )? (?: (\#(?:[a-zA-Z][\w-]*)?) | ((?:(?!\]\]).)*) )? \]\]) )/x"; return preg_replace_callback($link_rules, array(&$this,'link_replace'), $line); } // make_link で検出したリンクにリンクタグを付加する function link_replace($matches) { if ($matches[3] != '') { if (!$matches[2]) { return $matches[3]; } $url = $matches[3]; $alias = empty($matches[2]) ? $url : $matches[2]; return ''.$alias.''; } if ($matches[6] != '') { $str = empty($matches[5]) ? $matches[6] : $matches[5]; return '' . $str.''; } if ($matches[7] != '') { $str = empty($matches[5]) ? $matches[7] : $matches[5]; return '' . $str . ''; } return $matches[0]; } // インラインプラグイン処理メソッド function convert_plugin($matches) { $aryargs = (!empty($matches[2])) ? explode(',', $matches[2]) : array(); $name = strtolower($matches[1]); $body = empty($matches[3]) ? '' : $matches[3]; // プラグインが存在しない場合はそのまま返す。 // if (!file_exists(PLUGIN_DIR . $name . '.inc.php')) { if (!exist_plugin($name)) { return $matches[0]; } switch ($name) { case 'aname': return ''.$body.''; case 'br': return '
'; case 'color': $color = $aryargs[0]; $bgcolor = $aryargs[1]; if ($body == '') return ''; if ($color != '' && !preg_match('/^(#[0-9a-f]+|[\w-]+)$/i', $color)) return $body; if ($bgcolor != '' && !preg_match('/^(#[0-9a-f]+|[\w-]+)$/i', $bgcolor)) return $body; if ($color != '') $color = 'color:'.$color; if ($bgcolor != '') $bgcolor = ($color ? '; ' : '') . 'background-color:'.$bgcolor; return '' . $this->convert($body, TRUE, FALSE) . ''; case 'sup': case 'sub': return '<'.$name.'>'.$body.''; case 'size': $size = $aryargs[0]; if ($size == '' || $body == '') return ''; if (!preg_match('/^\d+$/', $size)) return $body; return '' . $this->convert($body, TRUE, FALSE) . ""; case 'ref': return guiedit_convert_ref($aryargs, FALSE); } if ($body) { $pattern = array("%%", "''", "[[", "]]", "{", "|", "}"); $replace = array("%%", "''", "[[", "]]", "{", "|", "}"); $body = str_replace($pattern, $replace, $body); } $inner = '&' . $matches[1] . ($matches[2] ? '('.$matches[2].')' : '') . ($body ? '{'.$body.'}' : '') . ';'; $style = (UA_NAME == MSIE) ? '' : ' style="cursor:default"'; return ''.$inner.''; } // 色の変換 function convert_color($matches) { $color = $matches[1]; $bgcolor = $matches[3]; if ($bgcolor && preg_match("/^#[0-9a-z]{3}$/i", $bgcolor)) { $bgcolor = "; background-color:" . preg_replace('/[0-9a-f]/i', "$0$0", $bgcolor); } if (preg_match("/^#[0-9a-z]{3}$/i", $color)) { $color = preg_replace('/[0-9a-f]/i', "$0$0", $color); } // return ""; // UPK return ''; } // 文字サイズの変換 function convert_size($matches) { if ($matches[2]) { $size = $matches[2]; if ($size <= 8) $size = 8; else if ($size <= 9) $size = 9; else if ($size <= 10) $size = 10; else if ($size <= 11) $size = 11; else if ($size <= 12) $size = 12; else if ($size <= 14) $size = 14; else if ($size <= 16) $size = 16; else if ($size <= 18) $size = 18; else if ($size <= 22) $size = 20; else if ($size <= 26) $size = 24; else if ($size <= 30) $size = 28; else if ($size <= 36) $size = 32; else if ($size <= 44) $size = 40; else if ($size <= 52) $size = 48; else $size = 60; return ''; } switch ($matches[3]) { case 1: $size = 'xx-small'; case 2: $size = 'x-small'; case 3: $size = 'small'; case 4: $size = 'medium'; case 5: $size = 'large'; case 6: $size = 'x-large'; case 7: $size = 'xx-large'; } return ''; } } // Block elements class ElementEx { var $parent; var $elements; // References of childs var $last; // Insert new one at the back of the $last function ElementEx() { $this->elements = array(); $this->last = & $this; } function setParent(& $parent) { $this->parent = & $parent; } function & add(& $obj) { if ($this->canContain($obj)) { return $this->insert($obj); } else { return $this->parent->add($obj); } } function & insert(& $obj) { $obj->setParent($this); $this->elements[] = & $obj; return $this->last = & $obj->last; } function canContain($obj) { return TRUE; } function wrap($string, $tag, $param = '', $canomit = TRUE) { return ($canomit && $string == '') ? '' : '<' . $tag . $param . '>' . $string . ''; } function toString() { $ret = array(); foreach (array_keys($this->elements) as $key) $ret[] = $this->elements[$key]->toString(); return join("\n", $ret); } function dump($indent = 0) { $ret = str_repeat(' ', $indent) . get_class($this) . "\n"; $indent += 2; foreach (array_keys($this->elements) as $key) { $ret .= is_object($this->elements[$key]) ? $this->elements[$key]->dump($indent) : ''; //str_repeat(' ', $indent) . $this->elements[$key]; } return $ret; } } // Returns inline-related object function & Factory_InlineEx($text) { // Check the first letter of the line if (substr($text, 0, 1) == '~') { // return new ParagraphEx(' ' . substr($text, 1)); $obj = new ParagraphEx(' ' . substr($text, 1)); } else { // return new InlineEx($text); $obj = new InlineEx($text); } return $obj; } function & Factory_DListEx(& $root, $text) { $out = explode('|', ltrim($text), 2); if (count($out) < 2) { return Factory_InlineEx($text); } else { return new DListEx($out); } } // '|'-separated table function & Factory_TableEx(& $root, $text) { if (! preg_match('/^\|(.+)\|([hHfFcC]?)$/', $text, $out)) { return Factory_InlineEx($text); } else { // return new TableEx($out); $obj = new TableEx($out); return $obj; } } // Comma-separated table function & Factory_YTableEx(& $root, $text) { if ($text == ',') { return Factory_InlineEx($text); } else { // return new YTableEx(csv_explode(',', substr($text, 1))); $obj = new YTableEx(csv_explode(',', substr($text, 1))); return $obj; } } function & Factory_DivEx(& $root, $text) { $matches = array(); // Seems block plugin? if (PKWKEXP_DISABLE_MULTILINE_PLUGIN_HACK) { // Usual code if (preg_match('/^\#([^\(]+)(?:\((.*)\))?/', $text, $matches)) { // return new DivEx($matches); $obj = new DivEx($matches); return $obj; } } else { // Hack code if (preg_match('/^#([^\(\{]+)(?:\(([^\r]*)\))?(\{*)/', $text, $matches)) { $len = strlen($matches[3]); $body = array(); if ($len == 0) { // return new DivEx($matches); // Seems legacy block plugin $obj = new DivEx($matches); return $obj; } else if (preg_match('/\{{' . $len . '}\s*\r(.*)\r\}{' . $len . '}/', $text, $body)) { $matches[3] .= "\r" . $body[1] . "\r" . str_repeat('}', $len); // return new DivEx($matches); // Seems multiline-enabled block plugin $obj = new DivEx($matches); return $obj; } } } // return new ParagraphEx($text); $obj = new ParagraphEx($text); return $obj; } // InlineEx elements class InlineEx extends ElementEx { function InlineEx($text) { parent::ElementEx(); $this->elements[] = trim((substr($text, 0, 1) == "\n") ? $text : guiedit_make_link($text)); } function & insert(& $obj) { $this->elements[] = $obj->elements[0]; return $this; } function canContain($obj) { return is_a($obj, 'InlineEx'); } function toString() { global $line_break; return join(($line_break ? '
' . "\n" : "\n"), $this->elements); } function & toPara($class = '') { $obj = new ParagraphEx('', $class); $obj->insert($this); return $obj; } } // ParagraphEx: blank-line-separated sentences class ParagraphEx extends ElementEx { var $param; function ParagraphEx($text, $param = '') { parent::ElementEx(); $this->param = $param; if ($text == '') return; if (substr($text, 0, 1) == '~') $text = ' ' . substr($text, 1); $this->insert(Factory_InlineEx($text)); } function canContain($obj) { return is_a($obj, 'InlineEx'); } function toString() { return $this->wrap(parent::toString(), 'p', $this->param); } } // * HeadingEx1 // ** HeadingEx2 // *** HeadingEx3 class HeadingEx extends ElementEx { var $level; var $id; var $msg_top; function HeadingEx(& $root, $text) { parent::ElementEx(); $this->level = min(3, strspn($text, '*')); $text = substr($text, $this->level); if (preg_match('/\s*\[#(\w+)\]/', $text, $matches)) { $this->id = $matches[1]; } $text = preg_replace('/\s*\[#\w+\]/', '', $text); $this->insert(Factory_InlineEx($text)); $this->level++; // h2,h3,h4 } function & insert(& $obj) { parent::insert($obj); return $this->last = & $this; } function canContain(& $obj) { return FALSE; } function toString() { return $this->wrap(parent::toString(), 'h' . $this->level, ' id="' . $this->id . '"'); } } // ---- // Horizontal Rule class HRuleEx extends ElementEx { function HRuleEx(& $root, $text) { parent::ElementEx(); } function canContain(& $obj) { return FALSE; } function toString() { global $hr; return $hr; } } // Lists (UL, OL, DL) class ListContainerEx extends ElementEx { var $tag; var $tag2; var $level; var $style; var $margin; var $left_margin; function ListContainerEx($tag, $tag2, $head, $text) { parent::ElementEx(); $var_margin = '_' . $tag . '_margin'; $var_left_margin = '_' . $tag . '_left_margin'; global $$var_margin, $$var_left_margin; $this->margin = $$var_margin; $this->left_margin = $$var_left_margin; $this->tag = $tag; $this->tag2 = $tag2; $this->level = min(3, strspn($text, $head)); $text = ltrim(substr($text, $this->level)); parent::insert(new ListElementEx($this->level, $tag2)); if ($text != '') $this->last = & $this->last->insert(Factory_InlineEx($text)); } function canContain(& $obj) { return (! is_a($obj, 'ListContainerEx') || ($this->tag == $obj->tag && $this->level == $obj->level)); } function setParent(& $parent) { global $_list_pad_str; parent::setParent($parent); $step = $this->level; if (isset($parent->parent) && is_a($parent->parent, 'ListContainerEx')) $step -= $parent->parent->level; $margin = $this->margin * $step; if ($step == $this->level) $margin += $this->left_margin; $this->style = sprintf($_list_pad_str, $this->level, $margin, $margin); } function & insert(& $obj) { if (! is_a($obj, get_class($this))) return $this->last = & $this->last->insert($obj); // Break if no elements found (BugTrack/524) if (count($obj->elements) == 1 && empty($obj->elements[0]->elements)) return $this->last->parent; // up to ListElementEx // Move elements foreach(array_keys($obj->elements) as $key) parent::insert($obj->elements[$key]); return $this->last; } function toString() { return $this->wrap(parent::toString(), $this->tag, $this->style); } } class ListElementEx extends ElementEx { function ListElementEx($level, $head) { parent::ElementEx(); $this->level = $level; $this->head = $head; } function canContain(& $obj) { return (! is_a($obj, 'ListContainerEx') || ($obj->level > $this->level)); } function toString() { return $this->wrap(parent::toString(), $this->head); } } // - One // - Two // - Three class UListEx extends ListContainerEx { function UListEx(& $root, $text) { parent::ListContainerEx('ul', 'li', '-', $text); } } // + One // + Two // + Three class OListEx extends ListContainerEx { function OListEx(& $root, $text) { parent::ListContainerEx('ol', 'li', '+', $text); } } // : definition1 | description1 // : definition2 | description2 // : definition3 | description3 class DListEx extends ListContainerEx { function DListEx($out) { parent::ListContainerEx('dl', 'dt', ':', $out[0]); $this->last = & ElementEx::insert(new ListElementEx($this->level, 'dd')); if ($out[1] != '') $this->last = & $this->last->insert(Factory_InlineEx($out[1])); } } // > Someting cited // > like E-mail text class BQuoteEx extends ElementEx { var $level; function BQuoteEx(& $root, $text) { parent::ElementEx(); $head = substr($text, 0, 1); $this->level = min(3, strspn($text, $head)); $text = ltrim(substr($text, $this->level)); if ($head == '<') { // Blockquote close $level = $this->level; $this->level = 0; $this->last = & $this->end($root, $level); if ($text != '') $this->last = & $this->last->insert(Factory_InlineEx($text)); } else { $this->insert(Factory_InlineEx($text)); } } function canContain(& $obj) { return (! is_a($obj, get_class($this)) || $obj->level >= $this->level); } function & insert(& $obj) { // BugTrack/521, BugTrack/545 if (is_a($obj, 'InlineEx')) return parent::insert($obj->toPara(' class="quotation"')); if (is_a($obj, 'BQuoteEx') && $obj->level == $this->level && count($obj->elements)) { $obj = & $obj->elements[0]; if (is_a($this->last, 'ParagraphEx') && count($obj->elements)) $obj = & $obj->elements[0]; } return parent::insert($obj); } function toString() { return $this->wrap(parent::toString(), 'blockquote'); } function & end(& $root, $level) { $parent = & $root->last; while (is_object($parent)) { if (is_a($parent, 'BQuoteEx') && $parent->level == $level) return $parent->parent; $parent = & $parent->parent; } return $this; } } class TableCellEx extends ElementEx { var $tag = 'td'; // {td|th} var $colspan = 1; var $rowspan = 1; var $style; // is array('width'=>, 'align'=>...); var $is_template; var $hspace = 0; var $fspace = 0; function TableCellEx($text, $is_template = FALSE) { parent::ElementEx(); $this->style = $matches = array(); $this->is_template = $is_template; while (preg_match('/^(?:(LEFT|CENTER|RIGHT)|(BG)?COLOR\(([#\w]+)\)|SIZE\((\d+)\)):(.*)$/', $text, $matches)) { if ($matches[1]) { $this->style['align'] = ' align="' . strtolower($matches[1]) . '"'; $text = $matches[5]; } else if ($matches[3]) { $name = $matches[2] ? 'background-color' : 'color'; $color = $matches[3]; if (preg_match("/^#[0-9a-f]{3}$/i", $color)) { $color = preg_replace("/[0-9a-f]/i", "$0$0", $color); } $this->style[$name] = $name . ':' . htmlspecialchars($color) . ';'; $text = $matches[5]; } else if ($matches[4]) { $this->style['size'] = 'font-size:' . htmlspecialchars($matches[4]) . 'px;'; $text = $matches[5]; } } if ($is_template && is_numeric($text)) $this->style['width'] = ' width="' . $text . '"'; if ($text == '>') { $this->colspan = 0; } if ($is_template) { $this->tag = 'col'; } else if ($text == '~') { $this->rowspan = 0; } else if (substr($text, 0, 1) == '~') { $this->tag = 'th'; $text = substr($text, 1); } if ($text != '' && $text{0} == '#') { // Try using DivEx class for this $text $obj = & Factory_DivEx($this, $text); if (is_a($obj, 'ParagraphEx')) $obj = & $obj->elements[0]; } else { if (preg_match("/^(\s+)?.+?(\s+)?$/", $text, $matches)) { $this->hspace = isset($matches[1]) ? strlen($matches[1]) : 0; $this->fspace = isset($matches[2]) ? strlen($matches[2]) : 0; } $obj = & Factory_InlineEx($text); } $this->insert($obj); } function setStyle(& $style) { foreach ($style as $key=>$value) if (! isset($this->style[$key])) $this->style[$key] = $value; } function toString() { if ($this->is_template) { $param = ''; } else { if ($this->rowspan == 0 || $this->colspan == 0) return ''; $param = ' class="style_' . $this->tag . '"' . ' _hspace="' . $this->hspace . '"' . ' _fspace="' . $this->fspace . '"'; if ($this->rowspan > 1) $param .= ' rowspan="' . $this->rowspan . '"'; if ($this->colspan > 1) { $param .= ' colspan="' . $this->colspan . '"'; unset($this->style['width']); } } if (! empty($this->style)) { foreach($this->style as $key=>$value) { if ($key == 'align' || $key == 'width') { $param .= $value; unset($this->style[$key]); } } $param .= ' style="' . join(' ', $this->style) . '"'; } return $this->wrap($this->is_template ? '' : parent::toString(), $this->tag, $param, FALSE); } } // | title1 | title2 | title3 | // | cell1 | cell2 | cell3 | // | cell4 | cell5 | cell6 | class TableEx extends ElementEx { var $type; var $types; var $col; // number of column function TableEx($out) { parent::ElementEx(); $cells = explode('|', $out[1]); $this->col = count($cells); $this->type = strtolower($out[2]); $this->types = array($this->type); $is_template = ($this->type == 'c'); $row = array(); foreach ($cells as $cell) $row[] = new TableCellEx($cell, $is_template); $this->elements[] = $row; } function canContain(& $obj) { return is_a($obj, 'TableEx') && ($obj->col == $this->col); } function & insert(& $obj) { $this->elements[] = $obj->elements[0]; $this->types[] = $obj->type; return $this; } function toString() { static $parts = array('h'=>'thead', 'f'=>'tfoot', ''=>'tbody'); // Set rowspan (from bottom, to top) for ($ncol = 0; $ncol < $this->col; $ncol++) { $rowspan = 1; foreach (array_reverse(array_keys($this->elements)) as $nrow) { $row = & $this->elements[$nrow]; if ($row[$ncol]->rowspan == 0) { ++$rowspan; continue; } $row[$ncol]->rowspan = $rowspan; // Inherits row type while (--$rowspan) $this->types[$nrow + $rowspan] = $this->types[$nrow]; $rowspan = 1; } } // Set colspan and style $stylerow = NULL; foreach (array_keys($this->elements) as $nrow) { $row = & $this->elements[$nrow]; $colspan = 1; if ($this->types[$nrow] == 'c') { for ($i = count($row) - 2; $i >= 0; $i--) { if ($row[$i]->colspan == 0) { $row[$i]->setStyle($row[$i + 1]->style); } } } foreach (array_keys($row) as $ncol) { if ($row[$ncol]->colspan == 0) { ++$colspan; continue; } $row[$ncol]->colspan = $colspan; if ($stylerow !== NULL) { $row[$ncol]->setStyle($stylerow[$ncol]->style); // Inherits column style while (--$colspan) $row[$ncol - $colspan]->setStyle($stylerow[$ncol]->style); } $colspan = 1; } } // toString $string = ''; $part_string = ''; $old_type = ''; foreach (array_keys($this->elements) as $nrow) { if (($old_type != $this->types[$nrow]) && ($part_string != '')) { $string .= ($old_type == 'c') ? $part_string : $this->wrap($part_string, $parts[$old_type]); $part_string = ''; } $row = & $this->elements[$nrow]; $row_string = ''; foreach (array_keys($row) as $ncol) { $row_string .= $row[$ncol]->toString(); } $part_string .= $this->wrap($row_string, (($this->types[$nrow] == 'c') ? 'colgroup' : 'tr')); $old_type = $this->types[$nrow]; } $string .= ($old_type == 'c') ? $part_string : $this->wrap($part_string, $parts[$old_type]); return $this->wrap($string, 'table', ' class="style_table" cellspacing="1" border="0" align="center"'); } } // , title1 , title2 , title3 // , cell1 , cell2 , cell3 // , cell4 , cell5 , cell6 class YTableEx extends ElementEx { var $col; function YTableEx($_value) { parent::ElementEx(); $align = $value = $matches = array(); foreach($_value as $val) { if (preg_match('/^(\s+)?(.+?)(\s+)?$/', $val, $matches)) { $align[] =($matches[1] != '') ? ((isset($matches[3]) && $matches[3] != '') ? ' align="center"' : ' align="right"' ) : ''; $value[] = $matches[2]; } else { $align[] = ''; $value[] = $val; } } $this->col = count($value); $colspan = array(); foreach ($value as $val) $colspan[] = ($val == '==') ? 0 : 1; $str = ''; $count = count($value); for ($i = 0; $i < $count; $i++) { if ($colspan[$i]) { while ($i + $colspan[$i] < $count && $value[$i + $colspan[$i]] == '==') $colspan[$i]++; $colspan[$i] = ($colspan[$i] > 1) ? ' colspan="' . $colspan[$i] . '"' : ''; $str .= '' . guiedit_make_link($value[$i]) . ''; } } $this->elements[] = $str; } function canContain(& $obj) { return is_a($obj, 'YTableEx') && ($obj->col == $this->col); } function & insert(& $obj) { $this->elements[] = $obj->elements[0]; return $this; } function toString() { $rows = ''; foreach ($this->elements as $str) $rows .= "\n" . '' . $str . '' . "\n"; $rows = $this->wrap($rows, 'table', ' class="style_table" cellspacing="1" border="0"'); return $this->wrap($rows, 'div', ' class="ie5"'); } } // ' 'Space-beginning sentence // ' 'Space-beginning sentence // ' 'Space-beginning sentence class PreEx extends ElementEx { function PreEx(& $root, $text) { global $preformat_ltrim; parent::ElementEx(); $this->elements[] = htmlspecialchars( (! $preformat_ltrim || $text == '' || $text{0} != ' ') ? $text : substr($text, 1)); } function canContain(& $obj) { return is_a($obj, 'PreEx'); } function & insert(& $obj) { $this->elements[] = $obj->elements[0]; return $this; } function toString() { return $this->wrap(join("
", $this->elements), 'pre'); } } // Block plugin: #something (started with '#') class DivEx extends ElementEx { var $text; var $name; var $param; function DivEx($out) { parent::ElementEx(); list(, $this->name, $this->param, $this->text) = array_pad($out, 4, ''); } function canContain(& $obj) { return FALSE; } function toString() { switch ($this->name) { case 'br': return "
\n "; case 'hr': return '
'; case 'pagebreak': return '
 
'; case 'ref': $param = ($this->param != '') ? explode(',', $this->param) : array(); return guiedit_convert_ref($param); } if ($this->text) { $this->text = preg_replace("/\r/", "
", $this->text); } $inner = "#$this->name" . ($this->param ? "($this->param)" : '') . $this->text; $style = (UA_NAME == MSIE) ? '' : ' style="cursor:default"'; return $this->wrap($inner, 'div', ' class="plugin" contenteditable="false"' . $style); } } // LEFT:/CENTER:/RIGHT: class AlignEx extends ElementEx { var $align; function AlignEx($align) { parent::ElementEx(); $this->align = $align; } function canContain(& $obj) { return is_a($obj, 'InlineEx'); } function toString() { return $this->wrap(parent::toString(), 'div', ' style="text-align: ' . $this->align . '"'); } } // BodyEx class BodyEx extends ElementEx { var $classes = array( '-' => 'UListEx', '+' => 'OListEx', '>' => 'BQuoteEx', '<' => 'BQuoteEx'); var $factories = array( ':' => 'DListEx', '|' => 'TableEx', ',' => 'YTableEx', '#' => 'DivEx'); var $comments = array(); function BodyEx() { parent::ElementEx(); } function parse(& $lines) { $this->last = & $this; $matches = array(); while (! empty($lines)) { $line = array_shift($lines); // Escape comments if (substr($line, 0, 2) == '//') { $this->comments[] = substr($line, 2); $line = '___COMMENT___'; } if (preg_match('/^(LEFT|CENTER|RIGHT):(.*)$/', $line, $matches)) { //
$this->last = & $this->last->add(new AlignEx(strtolower($matches[1]))); if ($matches[2] == '') continue; $line = $matches[2]; } $line = rtrim($line, "\r\n"); // Empty if ($line == '') { $this->last = & $this; continue; } // Horizontal Rule if (substr($line, 0, 4) == '----') { $this->insert(new HRuleEx($this, $line)); continue; } // Multiline-enabled block plugin if (! PKWKEXP_DISABLE_MULTILINE_PLUGIN_HACK && preg_match('/^#[^{]+(\{\{+)\s*$/', $line, $matches)) { $len = strlen($matches[1]); $line .= "\r"; // Delimiter while (! empty($lines)) { $next_line = preg_replace("/[\r\n]*$/", '', array_shift($lines)); // UPK $next_line = htmlspecialchars($next_line); if (preg_match('/\}{' . $len . '}/', $next_line)) { $line .= $next_line; break; } else { $line .= $next_line .= "\r"; // Delimiter } } } // The first character $head = $line{0}; // HeadingEx if ($head == '*') { $this->insert(new HeadingEx($this, $line)); continue; } // PreEx if ($head == ' ' || $head == "\t") { $this->last = & $this->last->add(new PreEx($this, $line)); continue; } // Line Break if (substr($line, -1) == '~') $line = substr($line, 0, -1) . "\r"; // Other Character if (isset($this->classes[$head])) { $classname = $this->classes[$head]; $this->last = & $this->last->add(new $classname($this, $line)); continue; } // Other Character if (isset($this->factories[$head])) { $factoryname = 'Factory_' . $this->factories[$head]; $this->last = & $this->last->add($factoryname($this, $line)); continue; } // Default $this->last = & $this->last->add(Factory_InlineEx($line)); } } function & insert(& $obj) { if (is_a($obj, 'InlineEx')) $obj = & $obj->toPara(); return parent::insert($obj); } function toString() { global $vars; $text = parent::toString(); $text = preg_replace_callback("/___COMMENT___(\n___COMMENT___)*/", array(&$this, 'comment'), $text); return $text . "\n"; } function comment($matches) { $comments = explode("\n", $matches[0]); foreach ($comments as $key=>$comment) { $comments[$key] = array_shift($this->comments); } $comment = join("\n", $comments); return 'Comment'; } } ?>