]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WysiwygEdit/Wikiwyg.php
Merge OldTextFormattingRules into TextFormattingRules; rename underscore plugins
[SourceForge/phpwiki.git] / lib / WysiwygEdit / Wikiwyg.php
1 <?php
2
3 /**
4  * Wikiwyg is compatible with most internet browsers which
5  * include: IE 5.5+ (Windows), Firefox 1.0+, Mozilla 1.3+
6  * and Netscape 7+.
7  *
8  * Download: http://openjsan.org/doc/i/in/ingy/Wikiwyg/
9  * Suggested installation into themes/default/Wikiwyg/
10  *
11  * @package WysiwygEdit
12  * @author  Reini Urban, based on a patch by Jean-Nicolas GEREONE, STMicroelectronics, 2006
13  * Current maintainer: Sabri LABBENE, STMicroelectronics, 2006
14  */
15
16 require_once 'lib/WysiwygEdit.php';
17
18 class WysiwygEdit_Wikiwyg extends WysiwygEdit
19 {
20
21     function WysiwygEdit_Wikiwyg()
22     {
23         global $request, $LANG;
24         $this->_transformer_tags = false;
25         $this->BasePath = DATA_PATH . '/themes/default/Wikiwyg';
26         $this->_htmltextid = "edit-content";
27         $this->_wikitextid = "editareawiki";
28         $script_url = deduce_script_name();
29         if ((DEBUG & _DEBUG_REMOTE) and isset($_GET['start_debug']))
30             $script_url .= ("?start_debug=" . $_GET['start_debug']);
31         $this->_jsdefault = "";
32     }
33
34     function Head($name = 'edit[content]')
35     {
36         global $WikiTheme;
37         foreach (array("Wikiwyg.js", "Wikiwyg/Toolbar.js", "Wikiwyg/Preview.js", "Wikiwyg/Wikitext.js",
38                      "Wikiwyg/Wysiwyg.js", "Wikiwyg/Phpwiki.js", "Wikiwyg/HTML.js",
39                      "Wikiwyg/Toolbar.js") as $js) {
40             $WikiTheme->addMoreHeaders
41             (Javascript('', array('src' => $this->BasePath . '/' . $js,
42                 'language' => 'JavaScript')));
43         }
44         $doubleClickToEdit = ($GLOBALS['request']->getPref('doubleClickEdit') or ENABLE_DOUBLECLICKEDIT)
45             ? 'true' : 'false';
46         if ($GLOBALS['request']->getArg('mode') && $GLOBALS['request']->getArg('mode') == 'wysiwyg') {
47             return JavaScript($this->_jsdefault . "
48             window.onload = function() {
49             var wikiwyg = new Wikiwyg.Phpwiki();
50             var config = {
51             doubleClickToEdit:  $doubleClickToEdit,
52             javascriptLocation: data_path+'/themes/default/Wikiwyg/',
53             toolbar: {
54             imagesLocation: data_path+'/themes/default/Wikiwyg/images/',
55         controlLayout: [
56                'save','preview','save_button','|',
57                'p','|',
58                'h2', 'h3', 'h4','|',
59                'bold', 'italic', '|',
60                        'sup', 'sub', '|',
61                        'toc',
62                        'wikitext','|',
63                'pre','|',
64                'ordered', 'unordered','hr','|',
65                'link','|',
66                        'table'
67                ],
68         styleSelector: [
69                'label', 'p', 'h2', 'h3', 'h4', 'pre'
70                 ],
71         controlLabels: {
72                    save:     '" . _("Apply changes") . "',
73                cancel:   '" . _("Exit toolbar") . "',
74                h2:       '" . _("Title 1") . "',
75                h3:       '" . _("Title 2") . "',
76                h4:       '" . _("Title 3") . "',
77                verbatim: '" . _("Verbatim") . "',
78                        toc:   '" . _("Table of Contents") . "',
79                        wikitext:   '" . _("Insert Wikitext section") . "',
80                        sup:      '" . _("Sup") . "',
81                        sub:      '" . _("Sub") . "',
82                        preview:  '" . _("Preview") . "',
83                        save_button:'" . _("Save") . "'
84                   }
85             },
86             wysiwyg: {
87                 iframeId: 'iframe0'
88             },
89         wikitext: {
90           supportCamelCaseLinks: true
91         }
92             };
93             var div = document.getElementById(\"" . $this->_htmltextid . "\");
94             wikiwyg.createWikiwygArea(div, config);
95             wikiwyg_divs.push(wikiwyg);
96             wikiwyg.editMode();}"
97             );
98         }
99     }
100
101     function Textarea($textarea, $wikitext, $name = 'edit[content]')
102     {
103         global $request;
104
105         $htmltextid = $this->_htmltextid;
106         $textarea->SetAttr('id', $htmltextid);
107         $iframe0 = new RawXml('<iframe id="iframe0" src="blank.htm" height="0" width="0" frameborder="0"></iframe>');
108         if ($request->getArg('mode') and $request->getArg('mode') == 'wysiwyg') {
109             $out = HTML(HTML::div(array('class' => 'hint'),
110                     _("Warning: This Wikiwyg editor has only Beta quality!")),
111                 $textarea,
112                 $iframe0,
113                 "\n");
114         } else {
115             $out = HTML($textarea, $iframe0, "\n");
116         }
117         return $out;
118     }
119
120     /**
121      * Handler to convert the Wiki Markup to HTML before editing.
122      * This will be converted back by WysiwygEdit_ConvertAfter if required.
123      *  *text* => '<b>text<b>'
124      */
125     function ConvertBefore($text)
126     {
127         return $text;
128     }
129
130     /*
131      * No special PHP HTML->Wikitext conversion needed. This is done in js thanksfully.
132      * Avoided in editpage.php: PageEditor->getContent
133      */
134     function ConvertAfter($text)
135     {
136         return TransformInline($text);
137     }
138 }
139
140 class WikiToHtml
141 {
142     function WikiToHtml($wikitext, &$request)
143     {
144         $this->_wikitext = $wikitext;
145         $this->_request =& $request;
146         $this->_html = "";
147         $this->html_content = "";
148     }
149
150     function send()
151     {
152         $this->convert();
153         echo $this->html_content;
154     }
155
156     function convert()
157     {
158         require_once 'lib/BlockParser.php';
159         $xmlcontent = TransformText($this->_wikitext, $this->_request->getArg('pagename'));
160         $this->_html = $xmlcontent->AsXML();
161
162         $this->replace_inside_html();
163     }
164
165     function replace_inside_html()
166     {
167         $this->clean_links();
168         $this->clean_plugin_name();
169         $this->replace_known_plugins();
170         $this->replace_unknown_plugins();
171         // $this->replace_tags();
172         $this->clean_plugin();
173         $this->html_content = $this->_html;
174     }
175
176     // Draft function to replace RichTable
177     // by a html table
178     // Works only on one plugin for the moment
179     function replace_known_plugins()
180     {
181         // If match a plugin
182         $pattern = '/\&lt\;\?plugin\s+RichTable(.*)\?\&gt\;/Umsi';
183         $replace_string = "replace_rich_table";
184         $this->_html = preg_replace_callback($pattern,
185             $replace_string,
186             $this->_html);
187     }
188
189     // Replace unknown plugins by keyword Wikitext { tag }
190     function replace_unknown_plugins()
191     {
192         $pattern = '/(\&lt\;\?plugin[^?]*\?\&gt\;)/Usi';
193         $replace_string =
194             '<p><div style="background-color:#D3D3D3;font-size:smaller;">Wikitext {
195  <br> \1 <br>}</div><br></p>';
196
197         $this->_html = preg_replace($pattern,
198             $replace_string,
199             $this->_html);
200     }
201
202     // Clean links to keep only <a href="link">name</a>
203     function clean_links()
204     {
205         // Existing links
206         // FIXME: use VIRTUAL_PATH
207         $pattern = '/\<a href\=\"index.php\?pagename\=(\w+)\"([^>])*\>/Umsi';
208         $replace_string = '<a href="\1">';
209         $this->_html = preg_replace($pattern,
210             $replace_string,
211             $this->_html);
212         // Non existing links
213         $pattern = '/\<a href\=\"index.php\?pagename\=([^"]*)(&amp;action){1}([^>])*\>/Umsi';
214         $replace_string = '<a href="\1">';
215
216         $this->_html = preg_replace($pattern,
217             $replace_string,
218             $this->_html);
219
220         // Clean underline
221         $pattern = '/\<u\>(.*)\<\/u\>(\<a href="(.*))[?"]{1}.*\>.*\<\/a\>/Umsi';
222         $replace_string =
223             '<span>\2" style="color:blue;">\1</a></span>';
224
225         $this->_html = preg_replace($pattern,
226             $replace_string,
227             $this->_html);
228     }
229
230     // Put unknown tags in Wikitext {}
231     function replace_tags()
232     {
233         // Replace old table format ( non plugin )
234         $pattern = '/(\ {0,4}(?:\S.*)?\|\S+\s*$.*?\<\/p\>)/ms';
235         $replace_string =
236             '<p><div style="background-color:#D3D3D3;font-size:smaller;">Wikitext {
237  <br> \1 <br>}</div><br></p>';
238
239         $this->_html = preg_replace($pattern,
240             $replace_string,
241             $this->_html);
242     }
243
244     // Replace \n by <br> only in
245     // <?plugin ? > tag to keep formatting
246     function clean_plugin()
247     {
248         $pattern = '/(\&lt\;\?plugin.*\?\&gt\;)/Umsei';
249         $replace_string = 'preg_replace("/\n/Ums","<br>","\1")';
250
251         $this->_html = preg_replace($pattern,
252             $replace_string,
253             $this->_html);
254
255     }
256
257     function clean_plugin_name()
258     {
259         // Remove plugin name converted in a link
260         $pattern = '/(\&lt\;\?plugin\s)\<span.*\>\<span\>\<a href=.*\>(\w+)\<\/a\><\/span\><\/span>([^?]*\?\&gt\;)/Umsi';
261         $replace_string = '\1 \2 \3';
262         $this->_html = preg_replace($pattern,
263             $replace_string,
264             $this->_html);
265     }
266 }
267
268 // This is called to replace the RichTable plugin by an html table
269 // $matched contains html <p> tags so
270 // they are deleted before the conversion.
271 function replace_rich_table($matched)
272 {
273     $plugin = $matched[1];
274
275     $unknown_options = "/colspan|rowspan|width|height/";
276
277     // if the plugin contains one of the options bellow
278     // it won't be converted
279     if (preg_match($unknown_options, $plugin))
280         return $matched[0] . "\n";
281     else {
282         //Replace unused <p...>
283         $pattern = '/\<p.*\>/Umsi';
284         $replace_string = "";
285
286         $plugin = preg_replace($pattern,
287             $replace_string,
288             $plugin);
289
290         //replace unused </p> by \n
291         $pattern = '/\<\/p\>/Umsi';
292         $replace_string = "\n";
293
294         $plugin = preg_replace($pattern,
295             $replace_string,
296             $plugin);
297
298         $plugin = "<?plugin RichTable " . $plugin . " ?>";
299
300         require_once 'lib/BlockParser.php';
301         $xmlcontent = TransformText($plugin, $GLOBALS['request']->getArg('pagename'));
302         return $xmlcontent->AsXML();
303     }
304 }
305
306 // Local Variables:
307 // mode: php
308 // tab-width: 8
309 // c-basic-offset: 4
310 // c-hanging-comment-ender-p: nil
311 // indent-tabs-mode: nil
312 // End: