[pmwiki-users] Re: sectionedit 1.4.1 released

Russell Bailey russell-pmwiki at saberpunk.net
Tue Sep 20 21:03:45 CDT 2005


Karl Loncarek wrote:

>"Patrick R. Michaud" <pmichaud at pobox.com> wrote in 
>news:20050920171243.GC16656 at host.pmichaud.com:
>
>  
>
>>On Tue, Sep 20, 2005 at 12:41:27PM -0400, Russell Bailey wrote:
>>    
>>
>>>>I don't want to kill any momentum you may have, but I do want to note
>>>>that I'm planning on incorporating a section edit capability into the
>>>>core relatively soon now, so we might want to coordinate a 
>>>>bit before you expend too much effort on this.  We may need to
>>>>make sure we have some agreement or consensus on the markup
>>>>involved and the overall design features if we don't want to conflict
>>>>in the long run...
>>>>        
>>>>
>>>I did a teeny bit of a rewrite of SectionEdit for use in RichEdit.  It 
>>>wasn't much,  but I integrated it into to the EditFunctions flow,  so 
>>>that it behaves well with extensions that process the text.  Is this 
>>>      
>>>
>of 
>  
>
>>>interest to either of you?
>>>      
>>>
>>Yes; one of the things that I will definitely be doing different
>>from sectionedit.php is integrating it into the $EditFunctions 
>>array instead of writing a special HandleEdit for it.
>>
>>Pm
>>
>>    
>>
>You're rigth this is definitly a better solution. I just don't know 
>enough about the internals of pmwiki to do it myself.
>  
>
Here's the version I built.  The code is messy,  but the integration is 
roughly the way it should be:

<?php
/*
 * Created on Sep 13, 2005
 *
 * Integrates section editing into the rich text editor
 * by placing the splitting and combining steps in
 * $EditFunctions,  rather than replacing HandleEdit().
 *
 * @author Patrick R. Michaud <pmichaud at pobox.com>
 * @author John Rankin <john.rankin at affinity.co.nz>
 * @author Sebastian Siedentopf <Schlaefer at macnews.de>
 * @author Karl Loncarek <dh2mll at web.de>
 * @author Russell Bailey <russell-lists at saberpunk.net>
 */
 
 // Load array utility functions, so that we can insert into
 // the $EditFunctions array.
 include_once('cookbook/richedit/arrayutils.php');
 
 // Define the layout of the section edit links.
 SDV($HTMLStylesFmt['sectionedit'], "div.sectionedit { 
float:right;text-align:right;font-size:smaller;clear:both;}");

 // Set default values
 SDV($SectionEditWithoutHeaders, FALSE);
 SDV($SectionEditAutoDepth, '6');
 SDV($SectionEditMediaWikiStyle, TRUE);
 
 // Only show links for section editing when browsing
 if ( $action == $RichEdit_BrowseAction )
 {
    Markup('editseclinkgen', '<include', 
'/^.*(([\n]!{1,6})|(====+)).*$/se', 
"RichEdit_SectionEditMarkup(\$pagename,PSS('$0'))");
 }
 else if ( ( $action == $RichEdit_EditAction ) &&
            ( @ $_REQUEST['s'] > 0 ) )
 {
    // Add these functions to $EditFunctions only if
    // a section parameter was specified.   
   
    if( $RichEdit_Enabled )
    {   
        $EditFunctions = RichEdit_Util_ArrayInsertBefore( 
'RichEdit_OnEdit', $EditFunctions, array('RichEdit_SplitSections') );
        $EditFunctions = RichEdit_Util_ArrayInsertAfter ( 
'RichEdit_OnSave', $EditFunctions, array('RichEdit_CombineSections') 
);       
    }
    else
    {
        $EditFunctions = RichEdit_Util_ArrayInsertAfter ( 'RestorePage', 
$EditFunctions, array('RichEdit_SplitSections', 
'RichEdit_CombineSections') );       
    }
   
 }
 
 // Custom markup for section editing
 Markup('removesectionedit', 'directives', '/====+/', '');
 Markup('nosections', 'directives', '/\\(:nosections:\\)/i', "");
 Markup('autosections', 'directives', '/\\(:autosections\s*(\d)*:\\)/i', 
"");
 
 // Don't edit the ==== markup.
 RichEdit_DoNotEditMarkup( 'removesectionedit', '/====+/');
 
 function RichEdit_SectionEditMarkup($pagename, $text)
 {
    global $SectionEditWithoutHeaders,$SectionEditAutoDepth,$InclCount;
    global $RichEdit_EditAction;

      /*combine Page, GroupHeader and GroupFooter to one string for 
directive markup checking
       *Regex is taken from include-Markup*/
    
preg_match('/\\(:include\\s+(\\S.*?):\\)/i',$GLOBALS['GroupHeaderFmt'],$temp);
    eval("\$temp[1] = \"$temp[1]\";");
      $checktext = IncludeText($pagename,$temp[1]);
    $checktext.=$text;
    
preg_match('/\\(:include\\s+(\\S.*?):\\)/i',$GLOBALS['GroupFooterFmt'],$temp);
    eval("\$temp[1] = \"$temp[1]\";");
    $checktext .= IncludeText($pagename,$temp[1]);
    //Reset inclusion counter
    $InclCount -= 2;

    /*check for directive markup (:autosections:) within the page*/
    if (preg_match("/\(:(autosections)(\s*\d)?:\)/i",$checktext,$temp)) {
        $SectionEditWithoutHeaders = false;
        //check for supplied parameter
        if (isset($temp[2])) {
            $temp[2] = ltrim($temp[2]);
            //disable Autosectioning when parameter is 0 or less
            if ($temp[2] <= 0)
                $SectionEditWithoutHeaders = true;
            //set depth according to supplied parameter
            else
                $SectionEditAutoDepth = $temp[2];
        }
    }

    /*check for directive markup (:nosections:) within page*/
    if (preg_match("/\(:(nosections)/i",$checktext) || $InclCount > 0)
        return $text;

    //split text into sections separated with ====
    if ($SectionEditWithoutHeaders)
        $p = preg_split('/((?<=header:\))|(?m:^))(?=====)/', $text);
    else {
        //now check whether exisiting sections contain headers and split 
them again
        $p = 
preg_split('/((?<=header:\))|(?m:^))((?=!{1,'.$SectionEditAutoDepth.'}[^!])|(?=====))/', 
$text);
        //add a style for the headings
        $p = 
preg_replace('/(?m:^)(!{1,'.$SectionEditAutoDepth.'})([^!])/',"$1%block 
margin-top=0px%$2",$p);
    }

    //creates the editlinks
    for ($i = 1; $i <= count($p); $i ++) {
        $editlink[$i] = FmtPageName("[<a name='section$i'><a 
href='\$PageUrl?action=$RichEdit_EditAction&s=$i'>edit</a></a>]", 
$pagename);
    }
    //output of editlinks and sections
    $out2[] = $p[0];
    for ($i = 1; $i < count($p); $i ++) {
        $out2[] = Keep("<div class='sectionedit'>$editlink[$i]</div>");
        $out2[] = "(:nl:)".$p[$i];
    }
    return (implode('', $out2));
}
 
 $p = array();
 
 // This function splits the sections of the text
 // up before RichEdit_OnEdit() gets called and
 // converts the text we actually want to change.
 function RichEdit_SplitSections( $pagename, &$page, &$new )
 {
     global $IsPagePosted, $EditFields, $ChangeSummary, $EditFunctions, 
$FmtV, $Now, $HandleEditFmt;
    global $PageStartFmt, $PageEditFmt, $PagePreviewFmt, $PageEndFmt, 
$GroupHeaderFmt, $GroupFooterFmt;
    global $PageEditForm, $EnablePost, $InputTags, 
$SectionEditWithoutHeaders;
    global $SectionEditMediaWikiStyle, $SectionEditAutoDepth;
    global $RichEdit_EditAction;
   
    global $p, $n;
    
     // 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" => "<a name='editor'/><form 
method='post' action='\$PageUrl?action=$RichEdit_EditAction&s=\$PNum'>
                                        <input type='hidden' 
name='action' value='$RichEdit_EditAction' />
                                        <input type='hidden' name='n' 
value='\$FullName' />
                                        <input type='hidden' 
name='basetime' value='\$EditBaseTime' />
                                        <input type='hidden' 
name='prechunk' value=\"\$PreChunk\" />
                                        <input type='hidden' name='s' 
value='\$PNum' />
                                        <input type='hidden' 
name='postchunk' value=\"\$PostChunk\" />");
                                       
    $InputTags['e_pretext'] = array(":html" => "\$PreChunkHtml");
    $InputTags['e_posttext']  = array(":html" => "\$PostChunkHtml");
                                       
    // Combine Page, GroupHeader and GroupFooter to one string for 
directive markup checking
    // Regex is taken from (:include:) Markup.
    
preg_match('/\\(:include\\s+(\\S.*?):\\)/i',$GLOBALS['GroupHeaderFmt'],$temp);
    eval("\$temp[1] = \"$temp[1]\";");
      $checktext = IncludeText($pagename,$temp[1]).$new['text'];
    
preg_match('/\\(:include\\s+(\\S.*?):\\)/i',$GLOBALS['GroupFooterFmt'],$temp);
    eval("\$temp[1] = \"$temp[1]\";");
    $checktext .= IncludeText($pagename,$temp[1]);

    // Reset inclusion counter
    $InclCount -= 2;
                                       
    // Check for directive markup (:autosections:) within the page*/
    if (preg_match("/\(:(autosections)(\s*\d)?:\)/i",$checktext,$temp)) {
        $SectionEditWithoutHeaders = false;
        //check for supplied parameter
        if (isset($temp[2]))
        {
            $temp[2] = ltrim($temp[2]);
           
            // Disable Autosectioning when parameter is 0 or less
            if ($temp[2] <= 0)
                $SectionEditWithoutHeaders = true;
               
            // Set depth according to supplied parameter
            else
                $SectionEditAutoDepth = $temp[2];
        }
    }
   
    // Splits the page text and sets the currently edited section.
   
    if ($SectionEditWithoutHeaders)
        $p = preg_split('/((?<=header:\))|(?m:^))(?=====)/', $new['text']);
    else {
        // Now check whether existing sections contain headers and split 
them again
        $p = 
preg_split('/((?<=header:\))|(?m:^))((?=!{1,'.$SectionEditAutoDepth.'}[^!])|(?=====))/', 
$new['text']);
    }

    //$n holds the number of the section to be edited
    $n = @ $_REQUEST['s'];
    if ($n < 1)
        $n = 1;
    if ($n > count($p))
        $n = count($p);

    // Here the merging of all sub-headings is done to achieve 
autosectioning a la MediaWiki */
    if ($SectionEditMediaWikiStyle && !$SectionEditWithoutHeaders)
    {
        // Check what heading level started this section
            if 
(preg_match('/(!{1,'.$SectionEditAutoDepth.'})[^!]/',$p[$n],$parts))
            {
                // Search in following sections:
                for ($i = $n+1; $i < count($p); $i ++)
                {
                    // If higher or same level exists then exit

                    if 
(preg_match('/((?<=header:\))|(?m:^))!{1,'.strlen($parts[1]).'}[^!]/',$p[$i]))
                        break;
                    else
                    {
                        // Add currently checked section to active section
                        $p[$n] .= $p[$i];
                    }
                }
               
                // Combine parts of old array into a new array
                $p = 
array_merge_recursive(array_slice($p,0,$n+1),array_slice($p,$i));
            }
    }

    // Here the section for editing is selected.
    if( !(@ $_POST['post'] ) )
    {
        $new['text'] = $p[$n];
    }
   
    $FmtV['$PNum'] = $n;
 }
 
 function RichEdit_CombineSections( $pagename, &$page, &$new )
 {
     //print($new['text']);

     global $IsPagePosted, $EditFields, $ChangeSummary, $EditFunctions, 
$FmtV, $Now, $HandleEditFmt;
    global $PageStartFmt, $PageEditFmt, $PagePreviewFmt, $PageEndFmt, 
$GroupHeaderFmt, $GroupFooterFmt;
    global $PageEditForm, $EnablePost, $InputTags, 
$SectionEditWithoutHeaders;
    global $SectionEditMediaWikiStyle, $SectionEditAutoDepth;
   
    global $p, $n;
   
    // 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 we're posting, the currently not edited sections are added
    if (@ $_POST['post'])
    {
        // Remove one \n if necessary to avoid hidden growing of the section
        if (substr($new['text'],-1)=="\n")
            $new['text'] = substr($new['text'],0,strlen($new['text'])-1);
        $new['text'] = $prechunk."\n\n".$new['text']."\n\n".$postchunk;
    }
    elseif (@ $_POST['preview'])
    {
        // Page header contains info which section is edited
        if ($n > 1)
            $GroupHeaderFmt = '';
        $GroupHeaderFmt .= '=&gt; ($[Section] '.@ $_REQUEST['s'].' $[of] 
'.count($p).')(:nl:)';
        if ($n < count($p))
            $GroupFooterFmt = '';
    }
    else
    {
        // 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       

        unset($prechunk);
        unset($postchunk);
        for ($i = 0; $i < count($p); $i ++) {
            if ($i < $n) {
                $prechunk .= $p[$i];
            }
            elseif ($i > $n) {
                $postchunk .= $p[$i];
            }
        }
    }
   
    // Additional FmtV for this script
    $FmtV['$PreChunk'] = str_replace('"', '&quot;', str_replace('$', 
'&#036;', htmlspecialchars($prechunk, ENT_NOQUOTES)));
    $FmtV['$PostChunk'] = str_replace('"', '&quot;', str_replace('$', 
'&#036;', htmlspecialchars($postchunk, ENT_NOQUOTES)));
   
    $FmtV['$PreChunkHtml'] = MarkupToHtml($pagename, $FmtV['$PreChunk']);
    $FmtV['$PostChunkHtml'] = MarkupToHtml($pagename, $FmtV['$PostChunk']);
   
    $FmtV['$PNum'] = $n;
       
 }
?>





More information about the pmwiki-users mailing list