Changeset 3992


Ignore:
Timestamp:
05/30/09 15:46:14 (3 years ago)
Author:
MichaelTempest
Message:

Item1674: Add support for protecting custom XML-like markup.

(Thanks to Crawford for suggesting the API)

Location:
trunk/WysiwygPlugin/lib/Foswiki/Plugins
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WysiwygPlugin/lib/Foswiki/Plugins/WysiwygPlugin.pm

    r3947 r3992  
    3535 
    3636use vars qw( $html2tml $tml2html $recursionBlock $imgMap ); 
    37 use vars qw( %TWikiCompatibility @refs ); 
     37use vars qw( %TWikiCompatibility @refs %xmltag %xmltagPlugin); 
    3838 
    3939our $SHORTDESCRIPTION  = 'Translator framework for Wysiwyg editors'; 
     
    434434 
    435435        if ( $web && $web ne $opts->{web} ) { 
    436             print STDERR "$orig -> $web+$topic$anchor\n";    #debug 
     436 
     437            #print STDERR "$orig -> $web+$topic$anchor\n";    #debug 
    437438            return $web . '.' . $topic . $anchor; 
    438439        } 
     
    548549} 
    549550 
     551=pod 
     552 
     553---++ ObjectMethod addXMLTag($tag, \&fn) 
     554 
     555Instruct WysiwygPlugin to "lift out" the named tag  
     556and pass it to &fn for processing. 
     557&fn may modify the text of the tag. 
     558&fn should return 0 is the tag is to be re-embedded immediately, 
     559or 1 if it is to be re-embedded after all processing is complete. 
     560The text passed (by reference) to &fn includes the  
     561=<tag> ... </tag>= brackets. 
     562 
     563A plugin may call this function more than once  
     564e.g. to change the processing function for a tag. 
     565However, only the *original plugin* may change the processing 
     566for a tag. 
     567 
     568=cut 
     569 
     570sub addXMLTag { 
     571    my ( $tag, $fn ) = @_; 
     572 
     573    my $plugin = caller; 
     574    $plugin =~ s/^Foswiki::Plugins:://; 
     575 
     576    return if not defined $tag; 
     577 
     578    if (   ( not exists $xmltag{$tag} and not exists $xmltagPlugin{$tag} ) 
     579        or ( $xmltagPlugin{$tag} eq $plugin ) ) 
     580    { 
     581 
     582        # This is either a plugin adding a new tag 
     583        # or a plugin adding a tag it had previously added before. 
     584        # A plugin is allowed to add a tag that it had added before 
     585        # and the new function replaces the old. 
     586        # 
     587        $fn = sub { 1 } 
     588          unless $fn;    # Default function 
     589 
     590        $xmltag{$tag}       = $fn; 
     591        $xmltagPlugin{$tag} = $plugin; 
     592    } 
     593    else { 
     594 
     595        # DON'T replace the existing processing for this tag 
     596        printf STDERR "WysiwygPlugin::addXMLTag: " 
     597          . "$plugin cannot add XML tag $tag, " 
     598          . "that tag was already registered by $xmltagPlugin{$tag}\n"; 
     599    } 
     600} 
     601 
    550602sub TranslateTML2HTML { 
    551603    my ( $text, $web, $topic ) = @_; 
     
    563615            getViewUrl      => \&getViewUrl, 
    564616            expandVarsInURL => \&expandVarsInURL, 
     617            xmltag          => \%xmltag, 
    565618        } 
    566619    ); 
  • trunk/WysiwygPlugin/lib/Foswiki/Plugins/WysiwygPlugin/TML2HTML.pm

    r3947 r3992  
    246246    $text = $this->_takeOutSets($text); 
    247247 
     248    $text = $this->_takeOutCustomTags($text); 
     249 
    248250    $text =~ s/\\\n/ /g; 
    249251    $text =~ s/\t/   /g; 
     
    595597} 
    596598 
     599sub _takeOutCustomTags { 
     600    my ( $this, $text ) = @_; 
     601 
     602    # Take out custom XML tags 
     603    sub _takeOutCustomXmlProcess { 
     604        my ( $this, $state, $scoop ) = @_; 
     605        return $this->_liftOut( $scoop, 'PROTECTED' ); 
     606    } 
     607    my $xmltags = $this->{opts}->{xmltag}; 
     608    for my $tag ( sort keys %$xmltags ) { 
     609        $text = _takeOutXml( $this, $text, $tag, \&_takeOutCustomXmlProcess ); 
     610    } 
     611 
     612    # Take out other custom tags here 
     613 
     614    return $text; 
     615} 
     616 
    597617sub _takeOutBlocks { 
    598     my ( $this, $intext, $tag ) = @_; 
    599     die unless $tag; 
     618    # my ( $this, $intext, $tag ) = @_; 
     619 
     620    sub _takeOutBlocksProcess { 
     621        my ( $this, $state, $scoop ) = @_; 
     622        my $placeholder = $state->{tag} . $state->{n}; 
     623        $this->{removed}->{$placeholder} = { 
     624            params => _parseParams( $state->{tagParams} ), 
     625            text   => $scoop, 
     626        }; 
     627        return $TT0 . $placeholder . $TT0; 
     628    } 
     629 
     630    return _takeOutXml( @_, \&_takeOutBlocksProcess ); 
     631} 
     632 
     633sub _takeOutXml { 
     634    my ( $this, $intext, $tag, $fn ) = @_; 
     635    die       unless $tag; 
     636    die       unless $fn; 
    600637    return '' unless $intext; 
    601638    return $intext unless ( $intext =~ m/<$tag\b/ ); 
    602639 
    603     my $open  = qr/<$tag\b[^>]*>/i; 
    604     my $close = qr/<\/$tag>/i; 
    605     my $out   = ''; 
    606     my $depth = 0; 
     640    my $openNoCapture    = qr/<$tag\b[^>]*>/i; 
     641    my $openCaptureAttrs = qr/<$tag\b([^>]*)>/i; 
     642    my $close            = qr/<\/$tag>/i; 
     643    my $out              = ''; 
     644    my $depth            = 0; 
    607645    my $scoop; 
    608     my $tagParams; 
    609     my $n = 0; 
    610  
    611     foreach my $chunk ( split /($open|$close)/, $intext ) { 
     646 
     647    # &$fn may rely on the existence of these fields,  
     648        # and may add more fields, if needed 
     649    my %state = ( tag => $tag, n => 0, tagParams => undef ); 
     650 
     651    foreach my $chunk ( split /($openNoCapture|$close)/, $intext ) { 
    612652        next unless defined($chunk); 
    613         if ( $chunk =~ m/<$tag\b([^>]*)>/ ) { 
     653        if ( $chunk =~ m/$openCaptureAttrs/ ) { 
    614654            unless ( $depth++ ) { 
    615                 $tagParams = $1; 
    616                 $scoop     = ''; 
     655                $state{tagParams} = $1; 
     656                $scoop = ''; 
    617657                next; 
    618658            } 
     
    620660        elsif ( $depth && $chunk =~ m/$close/ ) { 
    621661            unless ( --$depth ) { 
    622                 my $placeholder = $tag . $n; 
    623                 $this->{removed}->{$placeholder} = { 
    624                     params => _parseParams($tagParams), 
    625                     text   => $scoop, 
    626                 }; 
    627                 $chunk = $TT0 . $placeholder . $TT0; 
    628                 $n++; 
     662                $chunk = $fn->( $this, \%state, $scoop ); 
     663                $state{n}++; 
    629664            } 
    630665        } 
     
    643678        #     $scoop .= "</$tag>\n"; 
    644679        # } 
    645         my $placeholder = $tag . $n; 
    646         $this->{removed}->{$placeholder} = { 
    647             params => _parseParams($tagParams), 
    648             text   => $scoop, 
    649         }; 
    650         $out .= $TT0 . $placeholder . $TT0; 
     680        $out .= $fn->( $this, \%state, $scoop ); 
    651681    } 
    652682 
    653683    # Filter spurious tags without matching open/close 
    654     $out =~ s/$open/&lt;$tag$1&gt;/g; 
     684    $out =~ s/$openCaptureAttrs/&lt;$tag$1&gt;/g; 
    655685    $out =~ s/$close/&lt;\/$tag&gt;/g; 
    656686    $out =~ s/<($tag\s+\/)>/&lt;$1&gt;/g; 
Note: See TracChangeset for help on using the changeset viewer.