Technical Tip
1391
A bit of Php, a taste of regular expressions... That's it!
Have an idea to share on CoolSolutions? Don't want to use to much time writing it with HTML tags? Use the Wiki format! I adapted a Wiki parser written in Php from http://code.blitzaffe.com. I added some styles that were not included such as blockquotes, callouts, tables with headers and table of contents.
This document shows the different Wiki constructions you can use to write your CoolSolutions. I wrote this article using all the Wiki components available.
Table of Contents
Wiki to CoolSolutions Converter
A bit of Php, a taste of regular expressions... Thats it!
Content of the attached archive
Sections
Displaying Texts
Displaying Definition Lists
Indenting text
Displaying Code
Displaying Images
Displaying Lists
Unordered list
Unordered list, spread class
Ordered list
Mixed list
Displaying blockquotes and callouts
Displaying Links
Displaying Tables
Without header
With horizontal header
With vertical header
Technical Details
Lines handling
Characters handling
Conclusion
Content of the attached archive
Here is the content of the file wiki2cool.zip:
./wiki2cool + WikiParser.php + convert.php + index.php + main.css + tier4.css + Wiki2Cool_OnlineConverter_1.png + Wiki2Cool_OnlineConverter_2.png + Wiki2Cool_OnlineConverter_3.png + Wiki2Cool_Sections.png + article.txt + article.html
Details:
WikiParser.php: The class used to parse Wiki text. This class has been updated to handle Novell classes, such as "callout" on div tags, "spread" class for lists, "code" class for preformatted text and inline code, and new tables components.convert.php: script to convert Wiki text file on the command line. To use it, execute "convert.php article.txt > article.html".index.php: If you copy all the files to a Apache/Php folder, this page will offer you an online page to convert and preview Wiki content to HTML. You can also try http://wiki2cool.kalfane.org if it is available. It is an install of my files on an accessible public web server. Use it to test your Wiki content!*.css: The files that enable a Novell style for index.php. It is not fully like the CoolSolutions web site, but it is close to it.*.png: Images included in this article to illustrate sections, table of contents and the online converterarticle.txt: The source code of this article in Wiki format!article.html: The final HTML code of this article
Sections
To create a section, just surround your line with one or more equals signs, according to the level. You can generate a Table of Contents automatically if you put {{__TOC__}} at the end of the document. Then, when you generate the HTML, you can move it to the beginning of the document.
If you use the following:
= This is the Title =
== This is the Sub-Title ==
=== Introduction ===
Lorem ipsum lorem ipsum ipsum lorem ipsum
=== Part 1 ===
==== Sub-Part 1 ====
Lorem ipsum lorem ipsum ipsum lorem ipsum
==== Sub-Part 2 ====
Lorem ipsum lorem ipsum ipsum lorem ipsum
=== Part 2 ===
Lorem ipsum lorem ipsum ipsum lorem ipsum
=== Summary ===
Lorem ipsum lorem ipsum ipsum lorem ipsum
{{__TOC__}}
The result will magically be:

Displaying Texts
If you type text on several lines, they will be joined by default. The exceptions are if there are two line returns, which means a new paragraph, or if you force the line return using the code "///". For instance, if you type the following:
This is regular text. The second line is in the same paragraph. It is also possible to force///line breaks
The result will be the following:
This is regular text. The second line is in the same paragraph.
It is also possible to force
line breaks
You can also format code inline by surrounding it with dollars "$":
$convert.php$: script to convert Wiki text to HTML
The result will be the following:
convert.php: script to convert Wiki text to HTML
To display a separator, use 4 dashes "----":
Text above separator ---- Text under separator
Here is the result of the conversion from Wiki to HTML:
Text above separator Text under separator
There are several levels of emphasis you can use by surrounding the text with multiple quotes:
* ''level 2 emphasis'' * '''level 3 emphasis''' * ''''level 4 emphasis''''
Here is the result of the conversion from Wiki to HTML:
- level 2 emphasis
- level 3 emphasis
- level 4 emphasis
Displaying Definition Lists
Use ";" and ":" separator to display terms and definitions:
; '''yes''' : opposite of no ; '''no''' : opposite of yes ; '''maybe''' : somewhere in between yes and no
Here is the result of the conversion from Wiki to HTML:
- yes
- opposite of no
- no
- opposite of yes
- maybe
- somewhere in between yes and no
Indenting text
Use ":" to indent text:
Normal : indented : more indentation
Here is the result of the conversion from Wiki to HTML:
Normal
- indented
- more indentation
Displaying Code
To display preformatted code add a space at the beginning of the lines:
<?xml version="1.0"?> <nodes> <node id="node1"/> <node id="node2"/> <node id="node3"/> <node id="node4"/> </nodes>
Here's another one:
34 '''print''' "Listing filtered files v2 (list comprehension)"
35 dir = "."
36 ext = "py"
37 files = [f <b>for</b> f <b>in</b> os.listdir( dir ) '''if''' re.search('^.*.' + ext + '$',f) ]
38 '''print''' "n".join( files )
39 '''print''' "Found %d .%s file(s) in current directory" % ( len( files ), ext )
40 '''print''' ""
Displaying Images
You can display images using the following format:
The image can be aligned on the left with text on the right, aligned on the right with text on the left or centered with text under it. For instance:
[[Image:http://www.novell.com/communities/sites/all/themes/novell/images/icons/feature.gif|right|CoolSolution Icon]] Conectitur contumeliae, interesse meminerimus poenis sapiens. Aenean aeque dominationis eodem invenire malesuada paulo. Aegritudinem careret didicisse disciplinae discordant, emancipaverat ferant infimum laboramus nos oblivione officiis rudem sadipscing solum. Arte atque dicitur efficere fingitur gratissimo partem quamvis unum. Angatur asperiores compositis discordant, excelsus ipse magnis nemore, no reperiuntur suum vicinum videri. [[Image:http://www.novell.com/communities/sites/all/themes/novell/images/icons/feature.gif|left|CoolSolution Icon]] Conectitur contumeliae, interesse meminerimus poenis sapiens. Aenean aeque dominationis eodem invenire malesuada paulo. Aegritudinem careret didicisse disciplinae discordant, emancipaverat ferant infimum laboramus nos oblivione officiis rudem sadipscing solum. Arte atque dicitur efficere fingitur gratissimo partem quamvis unum. Angatur asperiores compositis discordant, excelsus ipse magnis nemore, no reperiuntur suum vicinum videri.
Here is the result of the conversion from Wiki to HTML:
![]()
Conectitur contumeliae, interesse meminerimus poenis sapiens. Aenean aeque dominationis eodem invenire malesuada paulo. Aegritudinem careret didicisse disciplinae discordant, emancipaverat ferant infimum laboramus nos oblivione officiis rudem sadipscing solum. Arte atque dicitur efficere fingitur gratissimo partem quamvis unum. Angatur asperiores compositis discordant, excelsus ipse magnis nemore, no reperiuntur suum vicinum videri.
![]()
Conectitur contumeliae, interesse meminerimus poenis sapiens. Aenean aeque dominationis eodem invenire malesuada paulo. Aegritudinem careret didicisse disciplinae discordant, emancipaverat ferant infimum laboramus nos oblivione officiis rudem sadipscing solum. Arte atque dicitur efficere fingitur gratissimo partem quamvis unum. Angatur asperiores compositis discordant, excelsus ipse magnis nemore, no reperiuntur suum vicinum videri.
If you have a look at the WikiParser.php file, you can extend the features by adding your own Wiki components. For instance, I added a special one:
{*cool_solutions}Here is the result of the conversion from Wiki to HTML:

Displaying Lists
Use asterisks "*" followed by space to build your normal or multi-level unordered lists:
* list * list ** list ** list * list * list
Here is the result of the conversion from Wiki to HTML:
- list
- list
- list
- list
- list
- list
Use "o" followed by space to build your normal or multi-level unordered lists with the spread class:
o list o list oo list oo list o list o list
Here is the result of the conversion from Wiki to HTML:
- list
- list
- list
- list
- list
- list
Use pound-signs "#" followed by space to build your normal or multi-level ordered lists:
# list # list ## list ## list ## list # list ## list ## list
Here is the result of the conversion from Wiki to HTML:
- list
- list
- list
- list
- list
- list
- list
- list
You can mix ordered and unordered lists:
* One bullet * Another '''bullet''' *# a list item *# another list item *#* unordered, ordered, unordered *#* again *# back down one
Here is the result of the conversion from Wiki to HTML:
- One bullet
- Another bullet
- a list item
- another list item
- unordered, ordered, unordered
- again
- back down one
Displaying blockquotes and callouts
To display callouts, use the "@" character at the beginning of the lines:
@'''Note:''' @This is a callout. @Use "@" at the beginning of each line.
Here is the result of the conversion from Wiki to HTML:
This is a callout.
Use "@" at the beginning of each line.
To display a block quote, use the percent "%" character at the beginning of the lines:
%'''Note:''' %This is a blockquote. %Use "%" at the beginning of each line.
Here is the result of the conversion from Wiki to HTML:
Note:
This is a blockquote.
Use "%" at the beginning of each line.
Displaying Links
You can display external links in 3 different manners:
- Note Link
- Normal Link
- Labeled Link
For instance:
Note Link: Go to Novell[http://www.novell.com] or Novell Support[http://support.novell.com]! Normal Link: [http://www.novell.com http://www.novell.com] Labeled Link: [http://www.novell.com Novell Website]
Here is the result of the conversion from Wiki to HTML:
Note Link: Go to Novell[1] or Novell Support[2]!
Normal Link: http://www.novell.com
Labeled Link: Novell Website
Displaying Tables
Using the "!" separator, you can easily display a basic table without a header:
!aaa!bbb!ccc!ddd!eee !aaa!bbb!ccc!ddd!eee !aaa!bbb!ccc!ddd!eee !aaa!bbb!ccc!ddd!eee !aaa!bbb!ccc!ddd!eee
Here is the result of the conversion from Wiki to HTML:
| aaa | bbb | ccc | ddd | eee |
| aaa | bbb | ccc | ddd | eee |
| aaa | bbb | ccc | ddd | eee |
| aaa | bbb | ccc | ddd | eee |
| aaa | bbb | ccc | ddd | eee |
Use the pipe "|" separator on the first line to display a horizontal header:
| aaa | bbb | ccc | ddd | eee ! aaa ! bbb ! ccc ! ddd ! eee ! aaa ! bbb ! ccc ! ddd ! eee ! aaa ! bbb ! ccc ! ddd ! eee ! aaa ! bbb ! ccc ! ddd ! eee
Here is the result of the conversion from Wiki to HTML:
| aaa | bbb | ccc | ddd | eee |
|---|---|---|---|---|
| aaa | bbb | ccc | ddd | eee |
| aaa | bbb | ccc | ddd | eee |
| aaa | bbb | ccc | ddd | eee |
| aaa | bbb | ccc | ddd | eee |
Use an underscore "_" separator at the beginning of each line to display a vertical header:
_ aaa ! aaa ! aaa ! aaa ! aaa _ bbb ! bbb ! bbb ! bbb ! bbb _ ccc ! ccc ! ccc ! ccc ! ccc _ ddd ! ddd ! ddd ! ddd ! ddd _ eee ! eee ! eee ! eee ! eee
Here is the result of the conversion from Wiki to HTML:
| aaa | aaa | aaa | aaa | aaa |
|---|---|---|---|---|
| bbb | bbb | bbb | bbb | bbb |
| ccc | ccc | ccc | ccc | ccc |
| ddd | ddd | ddd | ddd | ddd |
| eee | eee | eee | eee | eee |
Technical Details
The WikiParser class analyzes the Wiki content, line by line. It uses regular expressions to detect Wiki patterns and converts the Wiki to HTML. There are two types or regular expressions used:
- line patterns, to detect for instance preformatted code, lists, definition lists, tables, etc.
- character patterns, to detect for instance links, emphasizes, inline code, force breaks
Here are the line pattern definitions in the original class:
$line_regexes = array(
'preformat'=>'^\s(.*?)$',
'definitionlist'=>'^([\;\:])\s*(.*?)$',
'newline'=>'^$',
'list'=>'^([\*\#]+)(.*?)$',
'sections'=>'^(={1,6})(.*?)(={1,6})$',
'horizontalrule'=>'^----$',
);
In the new class I added blockquotes, callouts, tables, "coolbanner," and table of contents:
$line_regexes = array(
'preformat'=>'^\s(.*?)$',
'blockquote'=>'^%(.*?)$',
'callout'=>'^@(.*?)$',
'table'=>'^([!\|_])(.*?)$',
'definitionlist'=>'^([\;\:])\s*(.*?)$',
'newline'=>'^$',
'list'=>'^([\*\#\o]+) (.*?)$',
'sections'=>'^(={1,6})(.*?)(={1,6})$',
'horizontalrule'=>'^----$',
'coolbanner'=>'^\{\*cool_solutions\}$',
'toc'=>'^\{\{__TOC__\}\}',
);
You can see here that block quotes start with the "%" character, callouts start with the "@" character, and tables start with "|", "!" or "_" characters. When you add a new line pattern in this array, such as "toc", you must build a function handle_toc that will do something with the regular expression matches.
To automatically build a Table of Contents, I added code in the handle_sections that detects the sections and their levels to build an array. For each section, I store an array containing the content, the level (to be able to generate h1, h2, etc.), and the anchor, which is the content without spaces, without non-alpha characters, and all lowercase.
function handle_sections($matches) {
$level = strlen($matches[1]);
$content = trim( $matches[2] );
$this->stop = true;
// build the anchor
$anchor = preg_replace( "/[^a-zA-Z]/", "", $content );
$anchor = strtolower( $anchor );
// add to toc
$this->toc[ $this->tocnb ] = array( $content, $anchor, $level );
$this->tocnb++;
// avoid accidental run-on emphasis
return $this->emphasize_off() . "<a name=\"$anchor\"></a><h{$level}>{$content}</h{$level}>\n";
}
Then, when the string {{__TOC__}} is detected, the handle_toc method goes through the array. (Remember the first part of the article about building your own scripts.) Then it gets the level, the anchor that will be prefixed by "#" in the URL, and the content to build the table:
function handle_toc($matches) {
$output = "<h3>Table of Contents</h3>\n";
ksort( $this->toc );
foreach( $this->toc as $k=>$v )
{
for( $i = 0 ; $i < $v[2] - 1 ; $i++ ) $output .= " ";
$output .= "<a href=\"#{$v[1]}\">{$v[0]}</a><br/>\n";
}
return $output;
}
Here are the character pattern definitions from the original class:
$char_regexes = array(
'internallink'=>'('.
'\[\['. // opening brackets
'(([^\]]*?)\:)?'. // namespace (if any)
'([^\]]*?)'. // target
'(\|([^\]]*?))?'. // title (if any)
'\]\]'. // closing brackets
'([a-z]+)?'. // any suffixes
')',
'externallink'=>'('.
'\['.
'([^\]]*?)'.
'(\s+[^\]]*?)?'.
'\]'.
')',
'emphasize'=>'(\'{2,5})',
'eliminate'=>'(__TOC__|__NOTOC__|__NOEDITSECTION__)',
'variable'=>'('. '\{\{' . '([^\}]*?)' . '\}\}' . ')',
);
In the new class, I removed some of the definitions and added code and forcebeaks:
$char_regexes = array(
'internallink'=>'('.
'\[\['. // opening brackets
'(([^\]]*?)\:)?'. // namespace (if any)
'([^\]]*?)'. // target
'(\|([^\]]*?))?'. // title (if any)
'\]\]'. // closing brackets
'([a-z]+)?'. // any suffixes
')',
'externallink'=>'('.
'\['.
'([^\]]*?)'.
'(\s+[^\]]*?)?'.
'\]'.
')',
'emphasize'=>'(\'{2,4})',
'code'=>'(\$(.+?)\$)',
'forcebreak'=>'(\/\/\/)',
I);
Once again, if you add a new character pattern, like "code" or "forcebreak", you must define the methods handle_code and handle_forcebreak. Here are some simple examples:
function handle_forcebreak($matches) {
return "<br/>\n";
}
function handle_code($matches) {
return "<code>".$matches[2]."</code>";
}
Conclusion
I hope that you will be able to write your CoolSolutions article faster thanks to the Wiki format. You can convert your files on the command line using the following command:
wiki2cool> ./convert.php article.txt > article.html
Don't hesitate to use the online converter available at http://wiki2cool.kalfane.org or install one on your server by just copying the content of the archive in an Apache/Php folder. You will be able to select different samples depending on what you want to see. Here are some screenshots:

Here is the result of the submission:


Also, don't hesitate to have a look at the Wiki source of this article that you will find in the file article.txt. If you add new Wiki components in the WikiParser class, keep me posted! Happy writing!
| Attachment | Size |
|---|---|
| wiki2cool.zip | 156.07 KB |






0