* @author John Rankin * @author Sebastian Siedentopf * @version 1.5 * @link http://www.pmwiki.org/wiki/Cookbook/BreakPage http://www.pmwiki.org/wiki/Cookbook/SectionEdit * @copyright by the authors 2004-2005 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License * @package break-page */ /* For the Admins ============== Requirements ------------ * Requires PmWiki 2beta44 and higher * Last tested on PmWiki 2beta55 Install ------- 1. put this script into your cookbook folder 2. include it into your config.php: "include_once("$FarmD/cookbook/break-page.php");" 3. in scripts/forms.php change line: if ($action != 'edit') return; into if ($action != 'edit' && $action != 'editpage') return; Customization ------------- ### Layout The position and layout of the section links are controlled by the div.breakpage class in the script. You should also look if a "float:right;" looks better for you. ### XLPage Strings * $[(Edit Section ↓)] * $[Section] x $[of] y Usage ===== To break a page use "====" on your wikipage *before* the wanted section. If you set $BreakPageAuto a page will addionaly split by the headers. The ==== have only effect in the header they are used in. For Developers ============== Version History --------------- * 1.5 - 2005-08-28 - Schlaefer ** [feature] BreakPageAuto and ==== can be used together in sophisticated way * 1.4.4 - 2005-08-25 - Schlaefer ** [bugfix] set $HandleAuth to respect password protection ** [change] XLPage string $[(Edit Section ↓)] contains the paratheses now ** [feature] after edit the page jumps to the last edited section * 1.4.3 - 2005-08-22 - Schlaefer ** BreakPageAuto Bugfix: included sides don't get wikilinks ** some code cleanup * 1.4.2 - 2005-08-22 - Schlaefer ** BreakPageAuto: new regex string. starting no header text no longer supported because of wikistyles and other posible (::) Markup in the page that would cause an editlink for no obvious reason * 1.4.1 - 2005-08-21 - Schlaefer ** Bugfix: BreakPageAuto: starting no header text sections are recognized ** Bugfix: BreakPageAuto: starting header are recognized ** Bugfix: BreakPageAuto (:nosections:) working ** code commenting and cleaning * 1.4 - 2005-08-21 ** much improved BreakPageAuto implementation - Schlaefer * * 1.3 - 2005-08-21 ** first BreakPageAuto Implementation - Schlaefer * 1.2 - 2005-08-21 ** code cleanup, comments, localization - Schlaefer * 1.1 - 2005-08-04 ** PmWiki 2b54 compatibility - Schlaefer * 1.0 - inital realease */ if (!defined('PmWiki')) exit (); /** * cookbook break-page is included * and running on this pmwiki installation */ define('break-page', 1); SDV($HandleAuth['editpage'] ,'edit'); //layout of the section edit links SDV($HTMLStylesFmt['editpage'], " div.breakpage { text-align: right;font-size:smaller;} "); /** * This function searches for the "====" oder header markup on the page and replaces it * with the appropriate edit links. This is performed on the whole wiki page at once. * * @param string $pagename the name of the page on which section edit links should be inserted * @param string $text the text of $pagename * @return string returns the text with all section edit links on it * @see HandleEditPage */ function PageBreak($pagename, $text) { global $BreakPageAuto, $InclCount; //we do not generate (false) links for included sites if (preg_match("/\(:(nosections)/", $text) || $InclCount > 0) return $text; if ($BreakPageAuto) { $p = preg_split('/((?<=header:\))|(?m:^))((?=!{1,6})|(?=====))/', $text."\n\n"); $p = insertblanksectionfct($p); } else { $p = explode('====', $text."\n\n"); } $n = count($p); //creates the editlinks for ($i = 1; $i <= count($p); $i ++) { $editlink[] = FmtPageName("$[(Edit Section ↓)]", $pagename); } //output of editlinks and sections $out2[] = $p[0]; for ($i = 1; $i < count($p); $i ++) { $out2[] = Keep("
$editlink[$i]
"); $out2[] = "(:nl:)".$p[$i]; } return (implode('', $out2)); } /** * Handles the edit, preview and saving of page sections. * * It is derived from the standard HandleEdit() function defined in pmwiki.php. * * @param string $pagename the currently edited site * @param string $auth * @see HandleEdit * @see PageBreak */ function HandleEditPage($pagename, $auth = 'edit') { global $IsPagePosted, $EditFields, $ChangeSummary, $EditFunctions, $FmtV, $Now, $HandleEditFmt; global $PageStartFmt, $PageEditFmt, $PagePreviewFmt, $PageEndFmt, $GroupHeaderFmt, $GroupFooterFmt; global $PageEditForm, $EnablePost, $InputTags, $BreakPageAuto; // we need some additional values in the edit form for section editing. // To respect Site.EditForm we replace the standard PmWiki edit form // e_form defined in /scripts/form.php with this $InputTags['e_form'] = array (":html" => "
"); /* standard code from HandleEdit()*/ if ($_REQUEST['cancel']) { Redirect($pagename); return; } Lock(2); $IsPagePosted = false; $page = RetrieveAuthPage($pagename, $auth, true); if (!$page) Abort("?cannot edit $pagename"); PCache($pagename, $page); $new = $page; /*splits the page text and sets the currently edited section*/ if ($BreakPageAuto) { $p = preg_split('/((?<=header:\))|(?m:^))((?=!{1,6})|(?=====))/', $new['text']); $p = insertblanksectionfct($p); } else { $p = explode('====', $new['text']."\n\n"); } $n = @ $_REQUEST['p']; if ($n < 1) $n = 1; if ($n > count($p)) $n = count($p); //we use this anchor to jump to the last edited section in browser after page storage //and save it here, because it could be overwritten by $nnew $htmlanchor = $n; /* here all the include subheaders when editing a top header takes place*/ if ($BreakPageAuto) { //if a section after the current section "A" exist and "A" is a header if (isset ($p[$n]) && preg_match('/^(!{1,6})[^!]/', $p[$n -1], $sn)) { //look if there are sections "B" after "A" which are headers for ($k = $n;($k < count($p) && !preg_match('/^(!{1,6})[^!]/', $p[$k], $u)); $k ++); //if following sections are no header, all following sections are included; //this will happen only for the last header on a side followed only by ====s if (!isset ($u[1])) $u[1] = $sn[1]."it will be longer than sn[1]"; $sn1 = strlen($sn[1]); //if the next found headers "B" is a level under current header "A" if ($sn1 < strlen($u[1])) { //we only want to split the page down to header level "A" now, but we need to know //which section "A" would be, if we split the page only down to this level //$nnewin will contain this new section number $nnew = 1; for ($i = 2; $i <= $n; $i ++) { if (preg_match("/^!{1,".$sn1."}[^!]/", $p[$i -1])) $nnew += 1; } // now we really split the whole text again until the header level of "A" // and we set the section number to match this new split style $p = preg_split("/((?<=header:\))|(?m:^))(?=!{1,".$sn1."}[^!])/", $new['text']); $n = $nnew; } } } $new['text'] = $p[$n -1]; /* standard code from HandleEdit()*/ foreach ((array) $EditFields as $k) if (isset ($_POST[$k])) $new[$k] = str_replace("\r", '', stripmagic($_POST[$k])); if ($ChangeSummary) $new["csum:$Now"] = $ChangeSummary; /*if a preview previously took place the currently not edited text sections are obtained*/ $PageChunks = array ('prechunk', 'postchunk'); foreach ((array) $PageChunks as $c) { $$c = ''; if (@ $_POST[$c]) $$c = str_replace("\r", '', stripmagic($_REQUEST[$c])); } if (@ $_POST['post']) //the currently not edited sections are added $new['text'] = $prechunk."\n".$new['text']."\n".$postchunk; elseif (@ $_POST['preview']) { //page header contains info which section is edited if ($n > 1) $GroupHeaderFmt = ''; $GroupHeaderFmt .= '=>($[Section] '.@ $_REQUEST['p'].' $[of] '.count($p).')(:nl:)'; if ($n < count($p)) $GroupFooterFmt = ''; } elseif ($BreakPageAuto) { /* if the section is edited, the not edited sections go into $prechunk and * $postchunk and retained here while editing/previewing until saving the whole page */ for ($i = 1; $i <= count($p); $i ++) { if ($i < $n) $prechunk .= $p[$i -1]; elseif ($i > $n) $postchunk .= $p[$i -1]; } } else { for ($i = 1; $i <= count($p); $i ++) { if ($i < $n) $prechunk .= $p[$i -1].'===='; elseif ($i > $n) $postchunk .= '===='.$p[$i -1]; } } /* standard code from HandleEdit()*/ $EnablePost &= (@ $_POST['post'] || @ $_POST['postedit']); foreach ((array) $EditFunctions as $fn) $fn ($pagename, $page, $new); Lock(0); if ($IsPagePosted && !@ $_POST['postedit']) { Redirect($pagename, "\$PageUrl#section".$htmlanchor); return; } $FmtV['$DiffClassMinor'] = (@ $_POST['diffclass'] == 'minor') ? "checked='checked'" : ''; $FmtV['$EditText'] = str_replace('$', '$', htmlspecialchars(@ $new['text'], ENT_NOQUOTES)); $FmtV['$EditBaseTime'] = $Now; /*additional FmtV for this script*/ $FmtV['$PreChunk'] = str_replace('"', '"', str_replace('$', '$', htmlspecialchars($prechunk, ENT_NOQUOTES))); $FmtV['$PostChunk'] = str_replace('"', '"', str_replace('$', '$', htmlspecialchars($postchunk, ENT_NOQUOTES))); $FmtV['$PNum'] = $n; /* standard code from HandleEdit() */ if ($PageEditForm) { $form = ReadPage(FmtPageName($PageEditForm, $pagename), READPAGE_CURRENT); $FmtV['$EditForm'] = MarkupToHTML($pagename, $form['text']); } SDV($HandleEditFmt, array (& $PageStartFmt, & $PageEditFmt, & $PageEndFmt)); PrintFmt($pagename, $HandleEditFmt); } /** * Inserts a pseudo ====. * * If a header "A" is followed by Text1, ==== and Text2 an additional * ==== ist set between "A" and Text1. * * @param array $p splited orignal text * @return array the splited text with additional ==== split * @since 1.5 - 2005-08-28 */ function insertblanksectionfct($p) { $q = array (); for ($i = 0; $i < count($p); $i ++) { if (preg_match("/^====/", $p[$i +1]) && preg_match("/^!/", $p[$i])) { $t = preg_split('/(^!{1,6}.*?\n)/', $p[$i], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); $q = array_merge($q, $t); } else $q = array_merge($q, $p[$i]); } return $q; } if ($action == 'browse') { if ($BreakPageAuto){ Markup('editsectlinkgen', 'include', '/^.*====.*$/se', "PageBreak(\$pagename,PSS('$0'))"); } } elseif ($action == 'edit' || $action == 'editpage') { Markup('editsect', '>include', '/====/', "\n
— === —
\n"); if ($action == 'editpage') $HandleActions['editpage'] = 'HandleEditPage'; } else Markup('removebreakpage', 'directives', '/====/', ''); Markup('nosections', 'directives', '/\\(:nosections:\\)/', ""); ?>