# Copyright (C) 2005 Alex Schroeder # Copyright (C) 2008 Eric Hsu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the # Free Software Foundation, Inc. # 59 Temple Place, Suite 330 # Boston, MA 02111-1307 USA, $ModulesDescription .= '

$Id: fckeditor-bfc.pl,v 2.4 2008/07/27 14:12:22 as Exp $

'; use vars qw($FCKeditorHeight); $FCKeditorHeight = 500; # Pixels $MarkupQuotes=0; $Translate{'Add your comment here.'}="Add your comment here. Use the Save or Preview below to finish."; push (@MyRules, \&WysiwygRule); $RuleOrder{\&WysiwygRule}=5; # run this last sub WysiwygRule { if (m/\G(<.*?>)/gc) { return $1 if substr($1,5,6) eq 'script' or substr($1,4,6) eq 'script'; return UnquoteHtml($1); } return undef; } *OldFckImproveDiff = *ImproveDiff; *ImproveDiff = *NewFckImproveDiff; sub NewFckImproveDiff { my $old = OldFckImproveDiff(@_); my $new = ''; my $protected = 0; # fix diff inserting change boundaries inside tags $old =~ s!&([a-z]+);!&$1;!g; $old =~ s!&([a-z]+);!&$1;!g; # unquote named html entities $old =~ s/\&([a-z]+);/&$1;/g; foreach my $str (split(/(|<\/strong>)/, $old)) { # Don't remove HTML tags affected by changes. $protected = 1 if $str eq ''; # strip html tags and don't get confused with the < and > created # by diff! $str =~ s/\<.*?\>//g unless $protected; $protected = 0 if $str eq ''; $new .= $str; } return $new; } # Includes the suggested rules to translate fckeditor input/output to wiki markup. # Adds a flag to allow modules to opt out of formatting if we want fckeditor to see the raw markup (e.g. BibTeX files). # Also override some converter rules. use HTML::WikiConverter; push (@MyInitVariables, \&AddFCKEditorJS, \&htmltext2wiki); sub AddFCKEditorJS { my $is_comment; my $is_preview; return if ($q->param('upload') || $q->param("pure") == 1); $is_comment=1 if (($q->param('id') =~ /^$CommentsPrefix/o ) && ($q->param('action') eq 'browse')); $is_comment=1 if ($ENV{'QUERY_STRING'} =~ /^$CommentsPrefix/o); $is_comment=1 if ($q->param('Preview') && ($q->param('title') =~ /^$CommentsPrefix/o) ); $is_preview=1 if ($q->param('Preview') || $q->param('action') eq "draft"); if (($q->param('action') eq 'edit') || $is_comment || $is_preview ) { my $textareaname = "text"; $textareaname = "aftertext" if (($is_comment && !$is_preview) || $q->param('aftertext')); $HtmlHeaders .= qq{ }; } } sub htmltext2wiki { return if ($q->param('upload') || $q->param("pure") == 1); my $wc = new HTML::WikiConverter( dialect => 'Oddmuse' ); # override HTML::WikiConverter::Oddmuse::rules *OldRules = *HTML::WikiConverter::Oddmuse::rules; *HTML::WikiConverter::Oddmuse::rules = *NewConverterRules; my $text = $q->param('text'); my $aftertext = $q->param('aftertext'); if ($text) { $text = MyHackBr($text); my $translation = $wc->html2wiki($text); $translation=MyTranslation($translation); $q->param('text', $translation); } if ($aftertext) { $aftertext = MyHackBr($aftertext); my $translation = $wc->html2wiki($aftertext); $translation=MyTranslation($translation); $q->param('aftertext', $translation); } } # absurd hack to deal with FCKeditor messing with
s as well as html2wiki messing. sub MyHackBr { my $text = shift; $text =~ s/\ \;/ /g; $text =~ s/<(\/?)div/<$1p/g; $text =~ s/

//g; $text =~ s/<\/p>//g; $text =~ s/(\s*){2,}/

 <\/p>/g; return ($text); } sub MyTranslation { # stripping out some excess HTML from FCKEditor that otherwise isn't translated to wiki code. my $text = shift; $text = UnquoteHtml($text); $text =~ s/\&l[ds]quo\;/\"/g; $text =~ s/\&r[ds]quo\;/\"/g; $text =~ s/“/\"/g; $text =~ s/”/\"/g; $text =~ s/‘/\'/g; $text =~ s/’/\'/g; $text =~ s/[\ \t]*\n/\n/g; $text =~ s/\n\n+/\n\n/g; return ($text); } sub NewConverterRules { my $rules = OldRules(); my %newrules = ( hr => { replace => "\n----\n" }, br => { replace => "\n" }, p => { start => "\n\n", end => "", block => 1, line_format => 'multi' }, h1 => { start => '==', end => "\n", block => 1, line_format => 'single' }, h2 => { start => '==', end => "\n", block => 1, line_format => 'single' }, h3 => { start => '===', end => "\n", block => 1, line_format => 'single' }, h4 => { start => '====', end => "\n", block => 1, line_format => 'single' }, pre => { start => "\n{{{\n", end => "\n}}}\n", block => 1, line_format => 'single' }, code => { start => "{{{", end => "}}}", block => 1, line_format => 'single' }, # code => { start => "##", end => "##", block => 1, line_format => 'single' }, sub => { start => ",,", end => ",,", block => 1, line_format => 'single' }, sup => { start => "^^", end => "^^", block => 1, line_format => 'single' }, strike => { start => "\-\=\-", end => "\-\=\-", block => 1, line_format => 'single' }, em => { start => '/', end => '/' }, ); %$rules = (%$rules, %newrules); return ($rules); } # "---" taken by emdash in markup.pl. Too annoying to scrap it, and I don't expect humans to write this code. # -=-strike-=- push(@MyRules, \&StrikethroughRule); sub StrikethroughRule { if ( m/\G\-\=\-/cg ) { return (defined $HtmlStack[0] && $HtmlStack[0] eq 'strike') ? CloseHtmlEnvironment() : AddHtmlEnvironment('strike'); } return undef; } *OldGetTextArea = *GetTextArea; *GetTextArea = *NewGetTextArea; sub NewGetTextArea { my ($name, $text, $rows) = @_; if ($q->param("pure") == 1) { return OldGetTextArea($name, $text, $rows); } local $WikiLinks = 0; local $FreeLinks = 0; # these are meant to prevent special link rules from turning into plain urls. # without LinkRules, a pesky table rule from Creole grabs links like [[Page | text]] # LinkRules is too hard to override, so we'll fuss with Creole. $UseCache = -1; # Otherwise we get the cached post-processed HTML. $PassToHtmlEditor=1; # Set flag so rules can skip processing if they don't have a direct HTML translation. if ( $q->param('Preview') || ($name eq 'text') ) { # we need to process the preview, but PrintWikiToHTML only prints # so we have to capture the default filehandle and restore after we got the goods. # In fact, this routine works for every editing situation. my $html; open my $newout, '>', \$html; my $oldout = select; select $newout; PrintWikiToHTML($text); select $oldout; $text = $html; } $PassToHtmlEditor=0; $text= UnquoteHtml($text); # FCKEditor will quote entities itself. $text =~ s/\n/\/g; # so raw markup stays on its lines. my $html = $q->textarea(-id=>$name, -name=>$name, -default=>$text, -rows=>$rows||25, -columns=>78, -override=>1); # $html .= $q->hidden(-name=>'pure', -default=>$q->param("pure")); return $html; } __END__ = (2.4) Darned problem of dropping
's. Basically, was compressing all
s into a single one, which messes up Latex. Also transformed divs into ps. (2.3) Allow editor to work on recovered drafts. Fixed name of .js directory so it works on case sensitive settings. (2.2) Bug fixes to deal with smart quotes, ampersand bugs, made sure we did markup processing before we added br to preserve line-by-line formatting in the wysiwyg editor. We have some trouble editing forms in the wysiwyg editor because we usually put br's after all lines so the line format is preserved. That fouls up pure HTML. (2.1) Support for

 (requires markup.pl), , ,  (requires creoleadditions.pl),  (notice the added StrikethroughRule -=-strikethrough-=-). Cleaned up the toolbar.

(2.0) Based on fckeditor v.1.8. Added support for fckeditor in comments and previews. Added a Hook for us to add conversions to HTML::WikiConverter::Oddmuse. Added new conversions to accomodate linebreaks.pl, disallow h1 and to allow insertion of hr's.    

# ==============
# = More Notes =
# ==============

I. If you want to have a MyRule that shouldn't process before the text gets to the editor space, you should add the line 

return undef if ($PassToHtmlEditor);  # Leave as markup for HTML WYSIWYG editor

to the start of your routine.  This module sets that global as 1. For instance, if you are using toc.pl, you'll have to customize it by adding that line, or else the whole TOC will make it to the editor. I've done that in the tweak toc-bfc.pl.

II. You need two support files for fckeditor in your root web directory.
  
1. myconfig.js.  I suggest you fill it with:

FCKConfig.ToolbarSets["BFCMarkup"] =
    [['Bold','Italic','Underline','Subscript','Superscript','StrikeThrough','RemoveFormat'],
	 ['UnorderedList','OrderedList','Outdent','Indent'], 
	 ['Style'],
	 ['Table','Rule','SpecialChar'],
     ['Link','Unlink', 'Image'],
     ['Undo','Redo','-','Find','Replace'],
	 ['SelectAll'],
     ['FitWindow', 'Source']];

FCKConfig.GeckoUseSPAN = 0;
FCKConfig.EditorAreaCSS = '/bfc.css';
FCKConfig.CustomStyles = { };  // Clear demo styles from fckstyles.xml

FCKConfig.StylesXmlPath = '/mystyles.xml' ;
FCKConfig.EnterMode = 'br';


2. mystyles.xml.  I like: