Sunday 25 January, 2009

Drupal + FCKEditor + GeSHi Filter

In my site www.ustudy.in, I have drupal 6.9 with FCKEditor working fine. I was trying to configure GeSHi Filter. GeSHi Filter offers source code formatting. If you type the source code in almost any language, GeSHi filter formats the code, color highlighting the syntax, adding line numbers etc.

Problem is FCKEditor converts html entities like >< to & lt; etc., even before GeSHi filter gets its hands on the code. FCKEditor seems not to mess up with just this tags: SCRIPT, <!-- -->, . If I configured GeSHi filter to process SCRIPT tag for coloring code, It works fine. Until some one wants SCRIPT tag itself to appear in the quoted, formatted code!

So I decided to configured the GeSHi Filter to process a fictions tag: <codeformat> and configured FCKEditor to process it as a ProtectedSource. Here is what I added to the fckeditor\fckeditor\fckconfig.js:

FCKConfig.ProtectedSource.Add( /<\codeformat[\s\S]*?<\/codeformat>/gi ) ;

It works fine - the users switch to source view in FCKEditor and add a <codeformat language="c"> c_code++; etc(); </codeformat>. This is properly formatted by GeSHi filter and I can see the colored output.

BUT if I click the edit button to the page again, the instant FCKEditor loads up, it converts the <> to & lt; entities. Why FCKEditor is converting the html entities while a page is reloaded for editing remained a mystery to me. This does not happen when I switch between source and WYSIWYG views or while saving the page.

So I dug deeeeeppp in to the jungle of FCKEditor's Javascript source. My God, what an animal it is! Yuucckkk...

I made the following changes to fckeditor/fckeditor/editor/_source/internals/fcklistslib.js:

// We are not handling ins and del as block elements, for now.
BlockElements : { address:1,blockquote:1,center:1,codeformat:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,marquee:1,noscript:1,ol:1,p:1,pre:1,script:1,table:1,ul:1 },

// Elements that accept text nodes, but are not possible to edit in the browser.
NonEditableElements : { button:1,codeformat:1, option:1,script:1,iframe:1,textarea:1,object:1,embed:1,map:1,applet:1 },



Now it works fine! Only problem is, the code block is not visible in Wyswig mode at all. The users have to switch to source view to see it. Ok, atleast, it works.