7 * LICENSE: This source file is licensed under the terms of the GNU General Public License.
9 * @package Magic3 Framework
10 * @author 平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
11 * @copyright Copyright 2006-2010 Magic3 Project.
12 * @license http://www.gnu.org/copyleft/gpl.html GPL License
13 * @version SVN: $Id: html.php 3474 2010-08-13 10:36:48Z fishbone $
14 * @link http://www.magic3.org
17 // 2002-2006 PukiWiki Developers Team
18 // 2001-2002 Originally written by yu-ji
19 // License: GPL v2 or (at your option) any later version
21 // HTML-publishing related functions
24 // modified for Magic3 by naoki on 2008/9/29
25 //function catbody($title, $page, $body)
26 function catbody($body)
28 // modified for Magic3 by naoki on 2008/9/26
29 //global $script, $vars, $arg, $defaultpage, $whatsnew, $help_page, $hr;
30 global $script, $defaultpage, $whatsnew, $help_page, $hr;
31 global $attach_link, $related_link, $cantedit, $function_freeze;
32 global $search_word_color, $_msg_word, $foot_explain, $note_hr, $head_tags;
33 global $trackback, $trackback_javascript, $referer, $javascript;
35 //global $_LANG, $_LINK, $_IMAGE;
37 global $pkwk_dtd; // XHTML 1.1, XHTML1.0, HTML 4.01 Transitional...
38 global $page_title; // Title of this site
39 global $do_backup; // Do backup or not
40 global $modifier; // Site administrator's web page
41 global $modifierlink; // Site administrator's name
43 // modified for Magic3 by naoki on 2008/9/22
44 // if (! file_exists(SKIN_FILE) || ! is_readable(SKIN_FILE))
45 // die_message('SKIN_FILE is not found');
47 // $_LINK = $_IMAGE = array();
49 // Add JavaScript header when ...
50 if ($trackback && $trackback_javascript) $javascript = 1; // Set something If you want
51 if (! PKWK_ALLOW_JAVASCRIPT) unset($javascript);
55 //function edit_form($page, $postdata, $digest = FALSE, $b_template = TRUE)
56 function edit_form($page, $postdata, $digest = FALSE, $b_template = TRUE, $cmd='')
58 //global $script, $vars, $rows, $cols, $hr, $function_freeze;
59 global $script, $rows, $cols, $hr, $function_freeze;
60 global $_btn_preview, $_btn_repreview, $_btn_update, $_btn_cancel, $_msg_help;
61 global $whatsnew, $_btn_template, $_btn_load, $load_template_func;
64 // Newly generate $digest or not
65 //if ($digest === FALSE) $digest = md5(join('', get_source($page)));
66 if ($digest === FALSE) $digest = md5(get_source($page, true));
68 $refer = $template = '';
71 $addtag = $add_top = '';
72 //if(isset($vars['add'])) {
75 $addtag = '<input type="hidden" name="add" value="true" />';
76 //$add_top = isset($vars['add_top']) ? ' checked="checked"' : '';
77 $add_top = (WikiParam::getVar('add_top') != '') ? ' checked="checked"' : '';
78 $add_top = '<input type="checkbox" name="add_top" ' .
79 'id="_edit_form_add_top" value="true"' . $add_top . ' />' . "\n" .
80 ' <label for="_edit_form_add_top">' .
81 '<span class="small">' . $_btn_addtop . '</span>' .
85 if($load_template_func && $b_template) {
87 foreach(get_existpages() as $_page) {
88 if ($_page == $whatsnew || check_non_list($_page))
90 $s_page = htmlspecialchars($_page);
91 $pages[$_page] = ' <option value="' . $s_page . '">' .
92 $s_page . '</option>';
95 $s_pages = join("\n", $pages);
97 <select name="template_page">
98 <option value="">-- $_btn_template --</option>
101 <input type="submit" name="template" class="button" value="$_btn_load" accesskey="r" />
105 /*if (isset($vars['refer']) && $vars['refer'] != '')
106 $refer = '[[' . strip_bracket($vars['refer']) . ']]' . "\n\n";*/
107 $referValue = WikiParam::getVar('refer');
108 if ($referValue != '') $refer = '[[' . strip_bracket($referValue) . ']]' . "\n\n";
111 $r_page = rawurlencode($page);
112 $s_page = htmlspecialchars($page);
113 $s_digest = htmlspecialchars($digest);
114 $s_postdata = htmlspecialchars($refer . $postdata);
115 /*$s_original = isset($vars['original']) ? htmlspecialchars($vars['original']) : $s_postdata;
116 $b_preview = isset($vars['preview']); // TRUE when preview*/
117 $s_original = (WikiParam::getVar('original') != '') ? htmlspecialchars(WikiParam::getVar('original')) : $s_postdata;
118 $b_preview = (WikiParam::getVar('preview') != ''); // TRUE when preview
119 $btn_preview = $b_preview ? $_btn_repreview : $_btn_preview;
121 // Checkbox 'do not change timestamp'
122 $add_notimestamp = '';
123 if ($notimeupdate != 0) {
124 global $_btn_notchangetimestamp;
125 //$checked_time = isset($vars['notimestamp']) ? ' checked="checked"' : '';
126 $checked_time = (WikiParam::getVar('notimestamp') != '') ? ' checked="checked"' : '';
127 // Only for administrator
128 if ($notimeupdate == 2) {
129 $add_notimestamp = ' ' .
130 '<input type="password" name="pass" size="12" />' . "\n";
132 $add_notimestamp = '<input type="checkbox" name="notimestamp" ' .
133 'id="_edit_form_notimestamp" value="true"' . $checked_time . ' />' . "\n" .
134 ' ' . '<label for="_edit_form_notimestamp"><span class="small">' .
135 $_btn_notchangetimestamp . '</span></label>' . "\n" .
140 // 'margin-bottom', 'float:left', and 'margin-top'
141 // are for layout of 'cancel button'
142 // modified for Magic3 by naoki on 2008/10/6
143 $postScript = $script . WikiParam::convQuery("?");
145 <div class="edit_form">
146 <form action="$postScript" method="post" style="margin-bottom:0px;" class="form">
149 <input type="hidden" name="wcmd" value="edit" />
150 <input type="hidden" name="page" value="$s_page" />
151 <input type="hidden" name="digest" value="$s_digest" />
152 <textarea name="msg" class="wiki_edit" rows="$rows" cols="$cols">$s_postdata</textarea>
154 <div style="float:left;">
155 <input type="submit" name="preview" class="button" value="$btn_preview" accesskey="p" />
156 <input type="submit" name="write" class="button" value="$_btn_update" accesskey="s" />
160 <textarea name="original" rows="1" cols="1" style="display:none">$s_original</textarea>
162 <form action="$postScript" method="post" style="margin-top:0px;" class="form">
163 <input type="hidden" name="wcmd" value="edit" />
164 <input type="hidden" name="page" value="$s_page" />
165 <input type="submit" name="cancel" class="button" value="$_btn_cancel" accesskey="c" />
170 //if (isset($vars['help'])) {
171 if (WikiParam::getVar('help') != ''){
172 $body .= $hr . catrule();
174 // modified for Magic3 by naoki on 2008/10/6
175 /*$body .= '<ul><li><a href="' .
176 $script . '?cmd=edit&help=true&page=' . $r_page .
177 '">' . $_msg_help . '</a></li></ul>';*/
178 $body .= '<ul><li><a href="' .
179 $script . WikiParam::convQuery("?cmd=edit&help=true&page=$r_page") .
180 '">' . $_msg_help . '</a></li></ul>';
187 function make_related($page, $tag = '')
189 //global $script, $vars, $rule_related_str, $related_str;
190 global $script, $rule_related_str, $related_str;
191 global $_ul_left_margin, $_ul_margin, $_list_pad_str;
193 $links = links_get_related($page);
202 foreach ($links as $page=>$lastmod) {
203 if (check_non_list($page)) continue;
205 $r_page = rawurlencode($page);
206 $s_page = htmlspecialchars($page);
207 $passage = get_passage($lastmod);
208 // modified for Magic3 by naoki on 2008/10/6
210 '<a href="' . $script . '?' . $r_page . '" title="' .
211 $s_page . ' ' . $passage . '">' . $s_page . '</a>' :
212 '<a href="' . $script . '?' . $r_page . '">' .
213 $s_page . '</a>' . $passage;*/
215 '<a href="' . $script . WikiParam::convQuery("?$r_page") . '" title="' .
216 $s_page . ' ' . $passage . '">' . $s_page . '</a>' :
217 '<a href="' . $script . WikiParam::convQuery("?$r_page") . '">' .
218 $s_page . '</a>' . $passage;
220 if (empty($_links)) return ''; // Nothing
222 if ($tag == 'p') { // From the line-head
223 $margin = $_ul_left_margin + $_ul_margin;
224 $style = sprintf($_list_pad_str, 1, $margin, $margin);
225 $retval = "\n" . '<ul' . $style . '>' . "\n" .
226 '<li>' . join($rule_related_str, $_links) . '</li>' . "\n" .
229 $retval = join($rule_related_str, $_links);
231 $retval = join($related_str, $_links);
237 // User-defined rules (convert without replacing source)
238 function make_line_rules($str)
241 static $pattern, $replace;
243 if (! isset($pattern)) {
244 $pattern = array_map(create_function('$a',
245 'return \'/\' . $a . \'/\';'), array_keys($line_rules));
246 $replace = array_values($line_rules);
250 return preg_replace($pattern, $replace, $str);
253 // Remove all HTML tags(or just anchor tags), and WikiName-speific decorations
254 function strip_htmltag($str, $all = TRUE)
256 global $_symbol_noexists;
257 static $noexists_pattern;
259 if (! isset($noexists_pattern))
260 $noexists_pattern = '#<span class="noexists">([^<]*)<a[^>]+>' .
261 preg_quote($_symbol_noexists, '#') . '</a></span>#';
263 // Strip Dagnling-Link decoration (Tags and "$_symbol_noexists")
264 $str = preg_replace($noexists_pattern, '$1', $str);
267 // All other HTML tags
268 return preg_replace('#<[^>]+>#', '', $str);
270 // All other anchor-tags only
271 return preg_replace('#<a[^>]+>|</a>#i', '', $str);
275 // Remove AutoLink marker with AutLink itself
276 function strip_autolink($str)
278 return preg_replace('#<!--autolink--><a [^>]+>|</a><!--/autolink-->#', '', $str);
281 // Make a backlink. searching-link of the page name, by the page name, for the page name
282 function make_search($page)
286 $s_page = htmlspecialchars($page);
287 $r_page = rawurlencode($page);
289 // modified for Magic3 by naoki on 2008/10/6
290 /* return '<a href="' . $script . '?plugin=related&page=' . $r_page .
291 '">' . $s_page . '</a> ';*/
292 return '<a href="' . $script . WikiParam::convQuery("?plugin=related&page=$r_page") . '">' . $s_page . '</a> ';
295 // Make heading string (remove heading-related decorations from Wiki text)
296 function make_heading(& $str, $strip = TRUE)
300 // Cut fixed-heading anchors
303 if (preg_match('/^(\*{0,3})(.*?)\[#([A-Za-z][\w-]+)\](.*?)$/m', $str, $matches)) {
304 $str = $matches[2] . $matches[4];
307 $str = preg_replace('/^\*{0,3}/', '', $str);
310 // Cut footnotes and tags
312 $str = strip_htmltag(make_link(preg_replace($NotePattern, '', $str)));
317 // Separate a page-name(or URL or null string) and an anchor
318 // (last one standing) without sharp
319 function anchor_explode($page, $strict_editable = FALSE)
321 $pos = strrpos($page, '#');
322 if ($pos === FALSE) return array($page, '', FALSE);
324 // Ignore the last sharp letter
325 if ($pos + 1 == strlen($page)) {
326 $pos = strpos(substr($page, $pos + 1), '#');
327 if ($pos === FALSE) return array($page, '', FALSE);
330 $s_page = substr($page, 0, $pos);
331 $anchor = substr($page, $pos + 1);
333 if($strict_editable === TRUE && preg_match('/^[a-z][a-f0-9]{7}$/', $anchor)) {
334 return array ($s_page, $anchor, TRUE); // Seems fixed-anchor
336 return array ($s_page, $anchor, FALSE);
340 // Check HTTP header()s were sent already, or
341 // there're blank lines or something out of php blocks
342 function pkwk_headers_sent()
344 if (PKWK_OPTIMISE) return;
347 if (version_compare(PHP_VERSION, '4.3.0', '>=')) {
348 if (headers_sent($file, $line))
349 die('Headers already sent at ' .
350 htmlspecialchars($file) .
351 ' line ' . $line . '.');
354 die('Headers already sent.');
358 // Output common HTTP headers
359 function pkwk_common_headers()
361 if (! PKWK_OPTIMISE) pkwk_headers_sent();
363 if(defined('PKWK_ZLIB_LOADABLE_MODULE')) {
365 if(ini_get('zlib.output_compression') &&
366 preg_match('/\b(gzip|deflate)\b/i', $_SERVER['HTTP_ACCEPT_ENCODING'], $matches)) {
367 // Bug #29350 output_compression compresses everything _without header_ as loadable module
368 // http://bugs.php.net/bug.php?id=29350
369 header('Content-Encoding: ' . $matches[1]);
370 header('Vary: Accept-Encoding');
376 define('PKWK_DTD_XHTML_1_1', 17); // Strict only
377 define('PKWK_DTD_XHTML_1_0', 16); // Strict
378 define('PKWK_DTD_XHTML_1_0_STRICT', 16);
379 define('PKWK_DTD_XHTML_1_0_TRANSITIONAL', 15);
380 define('PKWK_DTD_XHTML_1_0_FRAMESET', 14);
381 define('PKWK_DTD_HTML_4_01', 3); // Strict
382 define('PKWK_DTD_HTML_4_01_STRICT', 3);
383 define('PKWK_DTD_HTML_4_01_TRANSITIONAL', 2);
384 define('PKWK_DTD_HTML_4_01_FRAMESET', 1);
386 define('PKWK_DTD_TYPE_XHTML', 1);
387 define('PKWK_DTD_TYPE_HTML', 0);
389 // Output HTML DTD, <html> start tag. Return content-type.
390 function pkwk_output_dtd($pkwk_dtd = PKWK_DTD_XHTML_1_1, $charset = CONTENT_CHARSET)
393 if (isset($called)) die('pkwk_output_dtd() already called. Why?');
396 $type = PKWK_DTD_TYPE_XHTML;
399 case PKWK_DTD_XHTML_1_1 :
401 $dtd = 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd';
403 case PKWK_DTD_XHTML_1_0_STRICT :
406 $dtd = 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd';
408 case PKWK_DTD_XHTML_1_0_TRANSITIONAL:
410 $option = 'Transitional';
411 $dtd = 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd';
414 case PKWK_DTD_HTML_4_01_STRICT :
415 $type = PKWK_DTD_TYPE_HTML;
417 $dtd = 'http://www.w3.org/TR/html4/strict.dtd';
419 case PKWK_DTD_HTML_4_01_TRANSITIONAL:
420 $type = PKWK_DTD_TYPE_HTML;
422 $option = 'Transitional';
423 $dtd = 'http://www.w3.org/TR/html4/loose.dtd';
426 default: die('DTD not specified or invalid DTD');
430 $charset = htmlspecialchars($charset);
433 if ($type == PKWK_DTD_TYPE_XHTML) echo '<?xml version="1.0" encoding="' . $charset . '" ?>' . "\n";
436 echo '<!DOCTYPE html PUBLIC "-//W3C//DTD ' .
437 ($type == PKWK_DTD_TYPE_XHTML ? 'XHTML' : 'HTML') . ' ' .
439 ($option != '' ? ' ' . $option : '') .
444 // Output <html> start tag
446 if ($type == PKWK_DTD_TYPE_XHTML) {
447 echo ' xmlns="http://www.w3.org/1999/xhtml"'; // dir="ltr" /* LeftToRight */
448 echo ' xml:lang="' . LANG . '"';
449 if ($version == '1.0') echo ' lang="' . LANG . '"'; // Only XHTML 1.0
451 echo ' lang="' . LANG . '"'; // HTML
453 echo '>' . "\n"; // <html>
455 // Return content-type (with MIME type)
456 if ($type == PKWK_DTD_TYPE_XHTML) {
457 // NOTE: XHTML 1.1 browser will ignore http-equiv
458 return '<meta http-equiv="content-type" content="application/xhtml+xml; charset=' . $charset . '" />' . "\n";
460 return '<meta http-equiv="content-type" content="text/html; charset=' . $charset . '" />' . "\n";