ILIAS  Release_3_10_x_branch Revision 61812
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilPCParagraph.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2008 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
24 require_once("./Services/COPage/classes/class.ilPageContent.php");
25 require_once("./Services/COPage/classes/class.ilWysiwygUtil.php");
26 
38 {
39  var $dom;
40  var $par_node; // node of Paragraph element
41 
45  function init()
46  {
47  $this->setType("par");
48  }
49 
55  function setNode(&$a_node)
56  {
57  parent::setNode($a_node); // this is the PageContent node
58  $this->par_node =& $a_node->first_child(); //... and this the Paragraph node
59  }
60 
61 
67  function createAtNode(&$node)
68  {
69  $this->node = $this->createPageContentNode();
70  $this->par_node =& $this->dom->create_element("Paragraph");
71  $this->par_node =& $this->node->append_child($this->par_node);
72  $this->par_node->set_attribute("Language", "");
73  $node->append_child ($this->node);
74  }
75 
82  function createAfter($node)
83  {
84  $this->node = $this->createPageContentNode(false);
85  if($succ_node = $node->next_sibling())
86  {
87  $this->node = $succ_node->insert_before($this->node, $succ_node);
88  }
89  else
90  {
91  $parent_node = $node->parent_node();
92  $this->node = $parent_node->append_child($this->node);
93  }
94  $this->par_node = $this->dom->create_element("Paragraph");
95  $this->par_node = $this->node->append_child($this->par_node);
96  $this->par_node->set_attribute("Language", "");
97  }
98 
106  function create(&$a_pg_obj, $a_hier_id, $a_pc_id = "")
107  {
108 //echo "-$a_pc_id-";
109  $this->node =& $this->dom->create_element("PageContent");
110  $a_pg_obj->insertContent($this, $a_hier_id, IL_INSERT_AFTER, $a_pc_id);
111  $this->par_node =& $this->dom->create_element("Paragraph");
112  $this->par_node =& $this->node->append_child($this->par_node);
113  $this->par_node->set_attribute("Language", "");
114  }
115 
116 
117 
124  function setText($a_text, $a_auto_split = false)
125  {
126  if (!is_array($a_text))
127  {
128  $text = array(array("level" => 0, "text" => $a_text));
129  }
130  else
131  {
132  $text = $a_text;
133  }
134 
135  if ($a_auto_split)
136  {
137  $text = $this->autoSplit($a_text);
138  }
139 
140  // DOMXML_LOAD_PARSING, DOMXML_LOAD_VALIDATING, DOMXML_LOAD_RECOVERING
141 
142  $temp_dom = domxml_open_mem('<?xml version="1.0" encoding="UTF-8"?><Paragraph>'.$text[0]["text"].'</Paragraph>',
143  DOMXML_LOAD_PARSING, $error);
144 
145  //$this->text = $a_text;
146  // remove all childs
147  if(empty($error))
148  {
149  // delete children of paragraph node
150  $children = $this->par_node->child_nodes();
151  for($i=0; $i<count($children); $i++)
152  {
153  $this->par_node->remove_child($children[$i]);
154  }
155 
156  // copy new content children in paragraph node
157  $xpc = xpath_new_context($temp_dom);
158  $path = "//Paragraph";
159  $res =& xpath_eval($xpc, $path);
160  if (count($res->nodeset) == 1)
161  {
162  $new_par_node =& $res->nodeset[0];
163  $new_childs = $new_par_node->child_nodes();
164 
165  for($i=0; $i<count($new_childs); $i++)
166  {
167  $cloned_child =& $new_childs[$i]->clone_node(true);
168  $this->par_node->append_child($cloned_child);
169  }
170  $orig_characteristic = $this->getCharacteristic();
171 
172  // if headlines are entered and current characteristic is a headline
173  // use no characteristic as standard
174  if ((count($text) > 1) && (substr($orig_characteristic, 0, 8) == "Headline"))
175  {
176  $orig_characteristic = "";
177  }
178  if ($text[0]["level"] > 0)
179  {
180  $this->par_node->set_attribute("Characteristic", 'Headline'.$text[0]["level"]);
181  }
182  }
183 
184  $ok = true;
185 
186  $c_node = $this->node;
187  // add other chunks afterwards
188  for ($i=1; $i<count($text); $i++)
189  {
190  if ($ok)
191  {
192  $next_par = new ilPCParagraph($this->dom);
193  $next_par->createAfter($c_node);
194  $next_par->setLanguage($this->getLanguage());
195  if ($text[$i]["level"] > 0)
196  {
197  $next_par->setCharacteristic("Headline".$text[$i]["level"]);
198  }
199  else
200  {
201  $next_par->setCharacteristic($orig_characteristic);
202  }
203  $ok = $next_par->setText($text[$i]["text"], false);
204  $c_node = $next_par->node;
205  }
206  }
207 
208  return true;
209  }
210  else
211  {
212  return $error;
213  }
214  }
215 
221  function getText($a_short_mode = false)
222  {
223  if (is_object($this->par_node))
224  {
225  $content = "";
226  $childs = $this->par_node->child_nodes();
227  for($i=0; $i<count($childs); $i++)
228  {
229  $content .= $this->dom->dump_node($childs[$i]);
230  }
231  return $content;
232  }
233  else
234  {
235  return "";
236  }
237  }
238 
244  function setCharacteristic($a_char)
245  {
246  if (!empty($a_char))
247  {
248  $this->par_node->set_attribute("Characteristic", $a_char);
249  }
250  else
251  {
252  if ($this->par_node->has_attribute("Characteristic"))
253  {
254  $this->par_node->remove_attribute("Characteristic");
255  }
256  }
257  }
258 
264  function getCharacteristic()
265  {
266  if (is_object($this->par_node))
267  {
268  return $this->par_node->get_attribute("Characteristic");
269  }
270  }
271 
272 
276  function setSubCharacteristic($a_char)
277  {
278  if (!empty($a_char))
279  {
280  $this->par_node->set_attribute("SubCharacteristic", $a_char);
281  }
282  else
283  {
284  if ($this->par_node->has_attribute("SubCharacteristic"))
285  {
286  $this->par_node->remove_attribute("SubCharacteristic");
287  }
288  }
289  }
290 
296  function getAutoIndent()
297  {
298  return $this->par_node->get_attribute("AutoIndent");
299  }
300 
301  function setAutoIndent($a_char)
302  {
303  if (!empty($a_char))
304  {
305  $this->par_node->set_attribute("AutoIndent", $a_char);
306  }
307  else
308  {
309  if ($this->par_node->has_attribute("AutoIndent"))
310  {
311  $this->par_node->remove_attribute("AutoIndent");
312  }
313  }
314  }
315 
320  {
321  return $this->par_node->get_attribute("SubCharacteristic");
322  }
323 
328  function setDownloadTitle($a_char)
329  {
330  if (!empty($a_char))
331  {
332  $this->par_node->set_attribute("DownloadTitle", $a_char);
333  }
334  else
335  {
336  if ($this->par_node->has_attribute("DownloadTitle"))
337  {
338  $this->par_node->remove_attribute("DownloadTitle");
339  }
340  }
341  }
342 
346  function getDownloadTitle()
347  {
348  return $this->par_node->get_attribute("DownloadTitle");
349  }
350 
355  function setShowLineNumbers($a_char)
356  {
357  $a_char = empty($a_char)?"n":$a_char;
358 
359  $this->par_node->set_attribute("ShowLineNumbers", $a_char);
360  }
361 
367  {
368  return $this->par_node->get_attribute("ShowLineNumbers");
369  }
370 
374  function setLanguage($a_lang)
375  {
376  $this->par_node->set_attribute("Language", $a_lang);
377  }
378 
382  function getLanguage()
383  {
384  return $this->par_node->get_attribute("Language");
385  }
386 
387  function input2xml($a_text, $a_wysiwyg = 0, $a_handle_lists = true)
388  {
389  return $this->_input2xml($a_text, $this->getLanguage(), $a_wysiwyg, $a_handle_lists);
390  }
391 
395  static function _input2xml($a_text, $a_lang, $a_wysiwyg = 0, $a_handle_lists = true)
396  {
397  $a_text = ilUtil::stripSlashes($a_text, false);
398 
399  // note: the order of the processing steps is crucial
400  // and should be the same as in xml2output() in REVERSE order!
401  $a_text = trim($a_text);
402 
403 //echo "<br>between:".htmlentities($a_text);
404 
405  // mask html
406  $a_text = str_replace("&","&amp;",$a_text);
407  $a_text = str_replace("<","&lt;",$a_text);
408  $a_text = str_replace(">","&gt;",$a_text);
409 
410  // Reconvert PageTurn and BibItemIdentifier
411  $a_text = preg_replace('/&lt;([\s\/]*?PageTurn.*?)&gt;/i',"<$1>",$a_text);
412  $a_text = preg_replace('/&lt;([\s\/]*?BibItemIdentifier.*?)&gt;/i',"<$1>",$a_text);
413 
414 //echo "<br>second:".htmlentities($a_text);
415 
416  // mask curly brackets
417 /*
418 echo htmlentities($a_text);
419  $a_text = str_replace("{", "&#123;", $a_text);
420  $a_text = str_replace("}", "&#125;", $a_text);
421 echo htmlentities($a_text);*/
422  // linefeed to br
423  $a_text = str_replace(chr(13).chr(10),"<br />",$a_text);
424  $a_text = str_replace(chr(13),"<br />", $a_text);
425  $a_text = str_replace(chr(10),"<br />", $a_text);
426 
427  if ($a_handle_lists)
428  {
429  $a_text = ilPCParagraph::input2xmlReplaceLists($a_text);
430  }
431 
432  // bb code to xml
433  $a_text = eregi_replace("\[com\]","<Comment Language=\"".$a_lang."\">",$a_text);
434  $a_text = eregi_replace("\[\/com\]","</Comment>",$a_text);
435  $a_text = eregi_replace("\[emp\]","<Emph>",$a_text);
436  $a_text = eregi_replace("\[\/emp\]","</Emph>",$a_text);
437  $a_text = eregi_replace("\[str\]","<Strong>",$a_text);
438  $a_text = eregi_replace("\[\/str\]","</Strong>",$a_text);
439  $a_text = eregi_replace("\[fn\]","<Footnote>",$a_text);
440  $a_text = eregi_replace("\[\/fn\]","</Footnote>",$a_text);
441  $a_text = eregi_replace("\[quot\]","<Quotation Language=\"".$a_lang."\">",$a_text);
442  $a_text = eregi_replace("\[\/quot\]","</Quotation>",$a_text);
443  $a_text = eregi_replace("\[code\]","<Code>",$a_text);
444  $a_text = eregi_replace("\[\/code\]","</Code>",$a_text);
445 
446  // internal links
447  //$any = "[^\]]*"; // this doesn't work :-(
448  $ws= "[ \t\r\f\v\n]*";
449 
450  while (eregi("\[(iln$ws((inst$ws=$ws([\"0-9])*)?$ws".
451  "((page|chap|term|media|htlm|lm|dbk|glo|frm|exc|tst|svy|webr|chat|cat|crs|grp|file|fold|sahs|mcst|obj)$ws=$ws([\"0-9])*)$ws".
452  "(target$ws=$ws(\"(New|FAQ|Media)\"))?$ws))\]", $a_text, $found))
453  {
454  $attribs = ilUtil::attribsToArray($found[2]);
455  $inst_str = $attribs["inst"];
456  // pages
457  if (isset($attribs["page"]))
458  {
459  if (!empty($found[10]))
460  {
461  $tframestr = " TargetFrame=\"".$found[10]."\" ";
462  }
463  else
464  {
465  $tframestr = "";
466  }
467  $a_text = eregi_replace("\[".$found[1]."\]",
468  "<IntLink Target=\"il_".$inst_str."_pg_".$attribs[page]."\" Type=\"PageObject\"".$tframestr.">", $a_text);
469  }
470  // chapters
471  else if (isset($attribs["chap"]))
472  {
473  if (!empty($found[10]))
474  {
475  $tframestr = " TargetFrame=\"".$found[10]."\" ";
476  }
477  else
478  {
479  $tframestr = "";
480  }
481  $a_text = eregi_replace("\[".$found[1]."\]",
482  "<IntLink Target=\"il_".$inst_str."_st_".$attribs[chap]."\" Type=\"StructureObject\"".$tframestr.">", $a_text);
483  }
484  // glossary terms
485  else if (isset($attribs["term"]))
486  {
487  switch ($found[10])
488  {
489  case "New":
490  $tframestr = " TargetFrame=\"New\" ";
491  break;
492 
493  default:
494  $tframestr = " TargetFrame=\"Glossary\" ";
495  break;
496  }
497  $a_text = eregi_replace("\[".$found[1]."\]",
498  "<IntLink Target=\"il_".$inst_str."_git_".$attribs[term]."\" Type=\"GlossaryItem\" $tframestr>", $a_text);
499  }
500  // media object
501  else if (isset($attribs["media"]))
502  {
503  if (!empty($found[10]))
504  {
505  $tframestr = " TargetFrame=\"".$found[10]."\" ";
506  $a_text = eregi_replace("\[".$found[1]."\]",
507  "<IntLink Target=\"il_".$inst_str."_mob_".$attribs[media]."\" Type=\"MediaObject\"".$tframestr.">", $a_text);
508  }
509  else
510  {
511  $a_text = eregi_replace("\[".$found[1]."\]",
512  "<IntLink Target=\"il_".$inst_str."_mob_".$attribs[media]."\" Type=\"MediaObject\"/>", $a_text);
513  }
514  }
515  // repository items (id is ref_id (will be used internally but will
516  // be replaced by object id for export purposes)
517  else if (isset($attribs["lm"]) || isset($attribs["dbk"]) || isset($attribs["glo"])
518  || isset($attribs["frm"]) || isset($attribs["exc"]) || isset($attribs["tst"])
519  || isset($attribs["svy"]) || isset($attribs["obj"]) || isset($attribs['webr'])
520  || isset($attribs["htlm"]) || isset($attribs["chat"]) || isset($attribs["grp"])
521  || isset($attribs["fold"]) || isset($attribs["sahs"]) || isset($attribs["mcst"])
522  || isset($attribs["cat"]) || isset($attribs["crs"]) || isset($attribs["file"]))
523  {
524  $obj_id = (isset($attribs["lm"])) ? $attribs["lm"] : $obj_id;
525  $obj_id = (isset($attribs["dbk"])) ? $attribs["dbk"] : $obj_id;
526  $obj_id = (isset($attribs["chat"])) ? $attribs["chat"] : $obj_id;
527  $obj_id = (isset($attribs["glo"])) ? $attribs["glo"] : $obj_id;
528  $obj_id = (isset($attribs["frm"])) ? $attribs["frm"] : $obj_id;
529  $obj_id = (isset($attribs["exc"])) ? $attribs["exc"] : $obj_id;
530  $obj_id = (isset($attribs["htlm"])) ? $attribs["htlm"] : $obj_id;
531  $obj_id = (isset($attribs["tst"])) ? $attribs["tst"] : $obj_id;
532  $obj_id = (isset($attribs["svy"])) ? $attribs["svy"] : $obj_id;
533  $obj_id = (isset($attribs["obj"])) ? $attribs["obj"] : $obj_id;
534  $obj_id = (isset($attribs["webr"])) ? $attribs["webr"] : $obj_id;
535  $obj_id = (isset($attribs["fold"])) ? $attribs["fold"] : $obj_id;
536  $obj_id = (isset($attribs["cat"])) ? $attribs["cat"] : $obj_id;
537  $obj_id = (isset($attribs["crs"])) ? $attribs["crs"] : $obj_id;
538  $obj_id = (isset($attribs["grp"])) ? $attribs["grp"] : $obj_id;
539  $obj_id = (isset($attribs["file"])) ? $attribs["file"] : $obj_id;
540  $obj_id = (isset($attribs["sahs"])) ? $attribs["sahs"] : $obj_id;
541  $obj_id = (isset($attribs["mcst"])) ? $attribs["mcst"] : $obj_id;
542  //$obj_id = (isset($attribs["obj"])) ? $attribs["obj"] : $obj_id;
543 
544  if ($inst_str == "")
545  {
546  $a_text = eregi_replace("\[".$found[1]."\]",
547  "<IntLink Target=\"il_".$inst_str."_obj_".$obj_id."\" Type=\"RepositoryItem\">", $a_text);
548  }
549  else
550  {
551  $a_text = eregi_replace("\[".$found[1]."\]",
552  "<IntLink Target=\"il_".$inst_str."_".$found[6]."_".$obj_id."\" Type=\"RepositoryItem\">", $a_text);
553  }
554  }
555  else
556  {
557  $a_text = eregi_replace("\[".$found[1]."\]", "[error: iln".$found[1]."]",$a_text);
558  }
559  }
560  while (eregi("\[(iln$ws((inst$ws=$ws([\"0-9])*)?".$ws."media$ws=$ws([\"0-9])*)$ws)/\]", $a_text, $found))
561  {
562  $attribs = ilUtil::attribsToArray($found[2]);
563  $inst_str = $attribs["inst"];
564  $a_text = eregi_replace("\[".$found[1]."/\]",
565  "<IntLink Target=\"il_".$inst_str."_mob_".$attribs[media]."\" Type=\"MediaObject\"/>", $a_text);
566  }
567  $a_text = eregi_replace("\[\/iln\]","</IntLink>",$a_text);
568 
569  // external link
570  $ws= "[ \t\r\f\v\n]*";
571 
572  //while (eregi("\[(xln$ws(url$ws=$ws([\"0-9])*)$ws)\]", $a_text, $found))
573  while (eregi("\[(xln$ws(url$ws=$ws\"([^\"])*\")$ws)\]", $a_text, $found))
574  {
575 //echo "found2:".addslashes($found[2])."<br>"; flush();;
576  $attribs = ilUtil::attribsToArray($found[2]);
577 //echo "url:".$attribs["url"]."<br>";
578  //$found[1] = str_replace("?", "\?", $found[1]);
579  if (isset($attribs["url"]))
580  {
581 //echo "3";
582  $a_text = str_replace("[".$found[1]."]", "<ExtLink Href=\"".$attribs["url"]."\">", $a_text);
583  }
584  else
585  {
586  $a_text = str_replace("[".$found[1]."]", "[error: xln".$found[1]."]",$a_text);
587  }
588  }
589  $a_text = eregi_replace("\[\/xln\]","</ExtLink>",$a_text);
590  /*$blob = ereg_replace("<NR><NR>","<P>",$blob);
591  $blob = ereg_replace("<NR>"," ",$blob);*/
592 //echo "<br>-".htmlentities($a_text)."-";
593  //$a_text = nl2br($a_text);
594  //$a_text = addslashes($a_text);
595  return $a_text;
596  }
597 
605  function input2xmlReplaceLists($a_text)
606  {
607  $rows = explode("<br />", $a_text."<br />");
608 //var_dump($a_text);
609 
610  $old_level = 0;
611 
612  $text = "";
613 
614  foreach ($rows as $row)
615  {
616  $level = 0;
617  if (str_replace("#", "*", substr($row, 0, 3)) == "***")
618  {
619  $level = 3;
620  }
621  else if (str_replace("#", "*", substr($row, 0, 2)) == "**")
622  {
623  $level = 2;
624  }
625  else if (str_replace("#", "*", substr($row, 0, 1)) == "*")
626  {
627  $level = 1;
628  }
629 
630  // end previous line
631  if ($level < $old_level)
632  {
633  for ($i = $old_level; $i > $level; $i--)
634  {
635  $text.= "</SimpleListItem></".$clist[$i].">";
636  }
637  if ($level > 0)
638  {
639  $text.= "</SimpleListItem>";
640  }
641  }
642  else if ($old_level > 0 && $level > 0 && ($level == $old_level))
643  {
644  $text.= "</SimpleListItem>";
645  }
646  else if (($level == $old_level) && $text != "")
647  {
648  $text.= "<br />";
649  }
650 
651  // start next line
652  if ($level > $old_level)
653  {
654  for($i = $old_level + 1; $i <= $level; $i++)
655  {
656  if (substr($row, $i - 1, 1) == "*")
657  {
658  $clist[$i] = "SimpleBulletList";
659  }
660  else
661  {
662  $clist[$i] = "SimpleNumberedList";
663  }
664  $text.= "<".$clist[$i]."><SimpleListItem>";
665  }
666  }
667  else if ($old_level > 0 && $level > 0)
668  {
669  $text.= "<SimpleListItem>";
670  }
671  $text.= substr($row, $level);
672 
673  $old_level = $level;
674  }
675 
676  // remove "<br />" at the end
677  if (substr($text, strlen($text) - 6) == "<br />")
678  {
679  $text = substr($text, 0, strlen($text) - 6);
680  }
681 
682  return $text;
683  }
684 
692  static function xml2outputReplaceLists($a_text)
693  {
694  $segments = ilPCParagraph::segmentString($a_text, array("<SimpleBulletList>", "</SimpleBulletList>",
695  "</SimpleListItem>", "<SimpleListItem>", "<SimpleListItem/>", "<SimpleNumberedList>", "</SimpleNumberedList>"));
696 
697  $current_list = array();
698  $text = "";
699  for ($i=0; $i<= count($segments); $i++)
700  {
701  if ($segments[$i] == "<SimpleBulletList>")
702  {
703  if (count($current_list) == 0)
704  {
705  $list_start = true;
706  }
707  array_push($current_list, "*");
708  $li = false;
709  }
710  else if ($segments[$i] == "<SimpleNumberedList>")
711  {
712  if (count($current_list) == 0)
713  {
714  $list_start = true;
715  }
716  array_push($current_list, "#");
717  $li = false;
718  }
719  else if ($segments[$i] == "</SimpleBulletList>")
720  {
721  array_pop($current_list);
722  $li = false;
723  }
724  else if ($segments[$i] == "</SimpleNumberedList>")
725  {
726  array_pop($current_list);
727  $li = false;
728  }
729  else if ($segments[$i] == "<SimpleListItem>")
730  {
731  $li = true;
732  }
733  else if ($segments[$i] == "</SimpleListItem>")
734  {
735  $li = false;
736  }
737  else if ($segments[$i] == "<SimpleListItem/>")
738  {
739  if ($list_start)
740  {
741  $text.= "<br />";
742  $list_start = false;
743  }
744  foreach($current_list as $list)
745  {
746  $text.= $list;
747  }
748  $text.= "<br />";
749  $li = false;
750  }
751  else
752  {
753  if ($li)
754  {
755  if ($list_start)
756  {
757  $text.= "<br />";
758  $list_start = false;
759  }
760  foreach($current_list as $list)
761  {
762  $text.= $list;
763  }
764  }
765  $text.= $segments[$i];
766  if ($li)
767  {
768  $text.= "<br />";
769  }
770  $li = false;
771  }
772  }
773 
774  // remove trailing <br />, if text ends with list
775  if ($segments[count($segments) - 1] == "</SimpleBulletList>" ||
776  $segments[count($segments) - 1] == "</SimpleNumberedList>" &&
777  substr($text, strlen($text) - 6) == "<br />")
778  {
779  $text = substr($text, 0, strlen($text) - 6);
780  }
781 
782  return $text;
783  }
784 
788  static function segmentString($a_haystack, $a_needles)
789  {
790  $segments = array();
791 
792  $nothing_found = false;
793  while (!$nothing_found)
794  {
795  $nothing_found = true;
796  $found = -1;
797  foreach($a_needles as $needle)
798  {
799  $pos = stripos($a_haystack, $needle);
800  if (is_int($pos) && ($pos < $found || $found == -1))
801  {
802  $found = $pos;
803  $found_needle = $needle;
804  $nothing_found = false;
805  }
806  }
807  if ($found > 0)
808  {
809  $segments[] = substr($a_haystack, 0, $found);
810  $a_haystack = substr($a_haystack, $found);
811  }
812  if ($found > -1)
813  {
814  $segments[] = substr($a_haystack, 0, strlen($found_needle));
815  $a_haystack = substr($a_haystack, strlen($found_needle));
816  }
817  }
818  if ($a_haystack != "")
819  {
820  $segments[] = $a_haystack;
821  }
822 
823  return $segments;
824  }
825 
833  static function xml2output($a_text)
834  {
835  // note: the order of the processing steps is crucial
836  // and should be the same as in input2xml() in REVERSE order!
837 
838  // xml to bb code
839  $any = "[^>]*";
840  $a_text = eregi_replace("<Comment[^>]*>","[com]",$a_text);
841  $a_text = eregi_replace("</Comment>","[/com]",$a_text);
842  $a_text = eregi_replace("<Comment/>","[com][/com]",$a_text);
843  $a_text = eregi_replace("<Emph>","[emp]",$a_text);
844  $a_text = eregi_replace("</Emph>","[/emp]",$a_text);
845  $a_text = eregi_replace("<Emph/>","[emp][/emp]",$a_text);
846  $a_text = eregi_replace("<Strong>","[str]",$a_text);
847  $a_text = eregi_replace("</Strong>","[/str]",$a_text);
848  $a_text = eregi_replace("<Strong/>","[str][/str]",$a_text);
849  $a_text = eregi_replace("<Footnote[^>]*>","[fn]",$a_text);
850  $a_text = eregi_replace("</Footnote>","[/fn]",$a_text);
851  $a_text = eregi_replace("<Footnote/>","[fn][/fn]",$a_text);
852  $a_text = eregi_replace("<Quotation[^>]*>","[quot]",$a_text);
853  $a_text = eregi_replace("</Quotation>","[/quot]",$a_text);
854  $a_text = eregi_replace("<Quotation/>","[quot][/quot]",$a_text);
855  $a_text = eregi_replace("<Code[^>]*>","[code]",$a_text);
856  $a_text = eregi_replace("</Code>","[/code]",$a_text);
857  $a_text = eregi_replace("<Code/>","[code][/code]",$a_text);
858 
859  // replace lists
860  $a_text = ilPCParagraph::xml2outputReplaceLists($a_text);
861 
862  // internal links
863  while (eregi("<IntLink($any)>", $a_text, $found))
864  {
865  $found[0];
866  $attribs = ilUtil::attribsToArray($found[1]);
867  $target = explode("_", $attribs["Target"]);
868  $target_id = $target[count($target) - 1];
869  $inst_str = (!is_int(strpos($attribs["Target"], "__")))
870  ? $inst_str = "inst=\"".$target[1]."\" "
871  : $inst_str = "";
872  switch($attribs["Type"])
873  {
874  case "PageObject":
875  $tframestr = (!empty($attribs["TargetFrame"]))
876  ? " target=\"".$attribs["TargetFrame"]."\""
877  : "";
878  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."page=\"".$target_id."\"$tframestr]",$a_text);
879  break;
880 
881  case "StructureObject":
882  $tframestr = (!empty($attribs["TargetFrame"]))
883  ? " target=\"".$attribs["TargetFrame"]."\""
884  : "";
885  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."chap=\"".$target_id."\"$tframestr]",$a_text);
886  break;
887 
888  case "GlossaryItem":
889  $tframestr = (empty($attribs["TargetFrame"]) || $attribs["TargetFrame"] == "Glossary")
890  ? ""
891  : " target=\"".$attribs["TargetFrame"]."\"";
892  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."term=\"".$target_id."\"".$tframestr."]",$a_text);
893  break;
894 
895  case "MediaObject":
896  if (empty($attribs["TargetFrame"]))
897  {
898  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."media=\"".$target_id."\"/]",$a_text);
899  }
900  else
901  {
902  $a_text = eregi_replace("<IntLink".$found[1].">","[iln media=\"".$target_id."\"".
903  " target=\"".$attribs["TargetFrame"]."\"]",$a_text);
904  }
905  break;
906 
907  case "RepositoryItem":
908  if ($inst_str == "")
909  {
911  }
912  else
913  {
914  $rtype = $target[count($target) - 2];
915  $target_type = $rtype;
916  }
917  $a_text = eregi_replace("<IntLink".$found[1].">","[iln ".$inst_str."$target_type=\"".$target_id."\"".$tframestr."]",$a_text);
918  break;
919 
920  default:
921  $a_text = eregi_replace("<IntLink".$found[1].">","[iln]",$a_text);
922  break;
923  }
924  }
925  $a_text = eregi_replace("</IntLink>","[/iln]",$a_text);
926 
927  // external links
928  while (eregi("<ExtLink($any)>", $a_text, $found))
929  {
930  $found[0];
931  $attribs = ilUtil::attribsToArray($found[1]);
932  //$found[1] = str_replace("?", "\?", $found[1]);
933  $a_text = str_replace("<ExtLink".$found[1].">","[xln url=\"".$attribs["Href"]."\"]",$a_text);
934  }
935  $a_text = eregi_replace("</ExtLink>","[/xln]",$a_text);
936 
937 
938  // br to linefeed
939  $a_text = str_replace("<br />", "\n", $a_text);
940  $a_text = str_replace("<br/>", "\n", $a_text);
941 
942  // prevent curly brackets from being swallowed up by template engine
943  $a_text = str_replace("{", "&#123;", $a_text);
944  $a_text = str_replace("}", "&#125;", $a_text);
945 
946  // unmask html
947  $a_text = str_replace("&lt;", "<", $a_text);
948  $a_text = str_replace("&gt;", ">",$a_text);
949 
950  // this is needed to allow html like <tag attribute="value">... in paragraphs
951  $a_text = str_replace("&quot;", "\"", $a_text);
952 
953  // make ampersands in (enabled) html attributes work
954  // e.g. <a href="foo.php?n=4&t=5">hhh</a>
955  $a_text = str_replace("&amp;", "&", $a_text);
956 
957  // make &gt; and $lt; work to allow (disabled) html descriptions
958  $a_text = str_replace("&lt;", "&amp;lt;", $a_text);
959  $a_text = str_replace("&gt;", "&amp;gt;", $a_text);
960 
961  return $a_text;
962  //return str_replace("<br />", chr(13).chr(10), $a_text);
963  }
964 
971  function autoSplit($a_text)
972  {
973  $a_text = str_replace ("=<SimpleBulletList>", "=<br /><SimpleBulletList>", $a_text);
974  $a_text = str_replace ("=<SimpleNumberedList>", "=<br /><SimpleNumberedList>", $a_text);
975  $a_text = str_replace ("</SimpleBulletList>=", "</SimpleBulletList><br />=", $a_text);
976  $a_text = str_replace ("</SimpleNumberedList>=", "</SimpleNumberedList><br />=", $a_text);
977  $a_text = "<br />".$a_text."<br />"; // add preceding and trailing br
978 
979  $chunks = array();
980  $c_text = $a_text;
981 //echo "0";
982  while ($c_text != "")
983  {
984 //var_dump($c_text); flush();
985 //echo "1";
986  $s1 = strpos($c_text, "<br />=");
987  if (is_int($s1))
988  {
989 //echo "2";
990  $s2 = strpos($c_text, "<br />==");
991  if (is_int($s2) && $s2 <= $s1)
992  {
993 //echo "3";
994  $s3 = strpos($c_text, "<br />===");
995  if (is_int($s3) && $s3 <= $s2) // possible level three header
996  {
997 //echo "4";
998  $n = strpos($c_text, "<br />", $s3 + 1);
999  if ($n > ($s3+9) && substr($c_text, $n-3, 9) == "===<br />")
1000  {
1001 //echo "5";
1002  // found level three header
1003  if ($s3 > 0 || $head != "")
1004  {
1005 //echo "6";
1006  $chunks[] = array("level" => 0,
1007  "text" => $this->removeTrailingBr($head.substr($c_text, 0, $s3)));
1008  $head = "";
1009  }
1010  $chunks[] = array("level" => 3,
1011  "text" => trim(substr($c_text, $s3+9, $n-$s3-12)));
1012  $c_text = $this->handleNextBr(substr($c_text, $n+6));
1013  }
1014  else
1015  {
1016 //echo "7";
1017  $head.= substr($c_text, 0, $n);
1018  $c_text = substr($c_text, $n);
1019  }
1020  }
1021  else // possible level two header
1022  {
1023 //echo "8";
1024  $n = strpos($c_text, "<br />", $s2 + 1);
1025  if ($n > ($s2+8) && substr($c_text, $n-2, 8) == "==<br />")
1026  {
1027 //echo "9";
1028  // found level two header
1029  if ($s2 > 0 || $head != "")
1030  {
1031 //echo "A";
1032  $chunks[] = array("level" => 0,
1033  "text" => $this->removeTrailingBr($head.substr($c_text, 0, $s2)));
1034  $head = "";
1035  }
1036  $chunks[] = array("level" => 2, "text" => trim(substr($c_text, $s2+8, $n-$s2-10)));
1037  $c_text = $this->handleNextBr(substr($c_text, $n+6));
1038  }
1039  else
1040  {
1041 //echo "B";
1042  $head.= substr($c_text, 0, $n);
1043  $c_text = substr($c_text, $n);
1044  }
1045  }
1046  }
1047  else // possible level one header
1048  {
1049 //echo "C";
1050  $n = strpos($c_text, "<br />", $s1 + 1);
1051  if ($n > ($s1+7) && substr($c_text, $n-1, 7) == "=<br />")
1052  {
1053 //echo "D";
1054  // found level one header
1055  if ($s1 > 0 || $head != "")
1056  {
1057 //echo "E";
1058  $chunks[] = array("level" => 0,
1059  "text" => $this->removeTrailingBr($head.substr($c_text, 0, $s1)));
1060  $head = "";
1061  }
1062  $chunks[] = array("level" => 1, "text" => trim(substr($c_text, $s1+7, $n-$s1-8)));
1063  $c_text = $this->handleNextBr(substr($c_text, $n+6));
1064 //echo "<br>ctext:".htmlentities($c_text)."<br>";
1065  }
1066  else
1067  {
1068  $head.= substr($c_text, 0, $n);
1069  $c_text = substr($c_text, $n);
1070 //echo "<br>head:".$head."c_text:".$c_text."<br>";
1071  }
1072  }
1073  }
1074  else
1075  {
1076 //echo "G";
1077  $chunks[] = array("level" => 0, "text" => $head.$c_text);
1078  $head = "";
1079  $c_text = "";
1080  }
1081  }
1082  if (count($chunks) == 0)
1083  {
1084  $chunks[] = array("level" => 0, "text" => "");
1085  }
1086 
1087 
1088  // remove preceding br
1089  if (substr($chunks[0]["text"], 0, 6) == "<br />")
1090  {
1091  $chunks[0]["text"] = substr($chunks[0]["text"], 6);
1092  }
1093 
1094  // remove trailing br
1095  if (substr($chunks[count($chunks) - 1]["text"],
1096  strlen($chunks[count($chunks) - 1]["text"]) - 6, 6) == "<br />")
1097  {
1098  $chunks[count($chunks) - 1]["text"] =
1099  substr($chunks[count($chunks) - 1]["text"], 0, strlen($chunks[count($chunks) - 1]["text"]) - 6);
1100  if ($chunks[count($chunks) - 1]["text"] == "")
1101  {
1102  unset($chunks[count($chunks) - 1]);
1103  }
1104  }
1105  return $chunks;
1106  }
1107 
1111  function handleNextBr($a_str)
1112  {
1113  // do not remove, if next line starts with a "=", otherwise two
1114  // headlines in a row will not be recognized
1115  if (substr($a_str, 0, 6) == "<br />" && substr($a_str, 6, 1) != "=")
1116  {
1117  $a_str = substr($a_str, 6);
1118  }
1119  else
1120  {
1121  // if next line starts with a "=" we need to reinsert the <br />
1122  // otherwise it will not be recognized
1123  if (substr($a_str, 0, 1) == "=")
1124  {
1125  $a_str = "<br />".$a_str;
1126  }
1127  }
1128  return $a_str;
1129  }
1130 
1134  function removeTrailingBr($a_str)
1135  {
1136  if (substr($a_str, strlen($a_str) - 6) == "<br />")
1137  {
1138  $a_str = substr($a_str, 0, strlen($a_str) - 6);
1139  }
1140  return $a_str;
1141  }
1142 
1146  function getType()
1147  {
1148  return ($this->getCharacteristic() == "Code")?"src":parent::getType();
1149  }
1150 
1151 }
1152 ?>