>>
Auf Proggen.org wurde letztens ein neuer Wettbewerb eröffnet. Die Aufgabe lautet, “irgendwie” die BB-Codes von phpBB nach DokuWiki-Syntax umzuwandeln. Ich begann mit PHP und hatte die Aufgabe auch schon nach 8h gelöst. Es wandelt “alle” in einem Text enthaltene BB-Codes, welche über die Kommandozeile übergeben werden, zu der entsprechenden Wiki Syntax um.
Die Datei wäre folgende(RegEx Rox!)
Unten sind die jeweiligen Skripts als Download angeboten.
#! /usr/bin/php
<?php
/**
* BBcode helper class
*
* @package BBcode
* @category Helper
* @author darksider3(http://www.darksider3.de)
* @copyright (c) 2013
* @license GPL v3
*/
/*@DEBUG=print_r(getArgs($_SERVER['argv']));*/
class bbcode {
/**
*
* This function parses BBcode tag to wiki code
*
* It parses (only if it is in valid format e.g. an email must to be
* as example@example.ext or similar) the text with BBcode and
* translates in the relative wiki code.
*
* @param string $text
* @param boolean $advanced his var describes if the parser run in advanced mode (only *simple* bbcode is parsed).
* @return string
*/
public static function towiki($text,$advanced=FALSE,$charset='utf8'){
//special chars
$text = @htmlspecialchars($text, ENT_QUOTES);
/**
* This array contains the main static bbcode
* @var array $basic_bbcode
*/
$basic_bbcode = array(
'[b]', '[/b]',
'[i]', '[/i]',
'[u]', '[/u]',
'[s]','[/s]',
'[list]','[/list]',
'[*]', '[*]',
'[]', '[]'
);
/**
* This array contains the main static bbcode's WIKI
* @var array $basic_wiki
*/
$basic_wiki = array(
'**', '**',
'//', '//',
'__', '__',
'<s>', '</s>',
'','',
' *',' ',
'',''
);
/**
*
* Parses basic bbcode, used str_replace since seems to be the fastest
*/
$text = str_replace($basic_bbcode, $basic_wiki, $text);
//advanced BBCODE
if ($advanced)
{
/**
* This array contains the advanced static bbcode
* @var array $advanced_bbcode
*/
$advanced_bbcode = array(
'#\[color=([a-zA-Z]*|\#?[0-9a-fA-F]{6})](.+)\[/color\]#Usi',
'#\[size=([0-9][0-9]?)](.+)\[/size\]#Usi',
'#\[quote](\r\n)?(.+?)\[/quote]#si',
'#\[quote=(.*?)](\r\n)?(.+?)\[/quote]#si',
'#\[url\](.+)\[\/url\]#Usi',
'#\[url=(.+)\](.+)\[\/url\]#Usi',
'#\[email]([\w\.\-]+@[a-zA-Z0-9\-]+\.?[a-zA-Z0-9\-]*\.\w{1,4})\[/email]#Usi',
'#\[email=([\w\.\-]+@[a-zA-Z0-9\-]+\.?[a-zA-Z0-9\-]*\.\w{1,4})](.+)\[/email]#Usi',
'#\[img](.+)\[/img]#Usi',
'#\[img=(.+)](.+)\[/img]#Usi',
'#\[code](\r\n)?(.+?)(\r\n)?\[/code]#si'
);
/**
* This array contains the advanced static bbcode's WIKI
* @var array $advanced_WIKI
*/
$advanced_wiki = array(
'',
'',
"<div class=\"quote\"><span class=\"quoteby\">Zitat:</span>\r\n$2</div>",
"<div class=\"quote\"><span class=\"quoteby\">Zitat von <b>$1</b>:</span>\r\n$3</div>",
'[[$1|$1]]',
'[[$1|$2]]',
'[[mailto: $1|$1]]',
'[[mailto: $1|$2]]',
'{{$1|$1}}',
'{{$1|$2}}',
'<code>$2</code>');
$text = preg_replace($advanced_bbcode, $advanced_wiki,$text);
}
//before return convert line breaks to WIKI
return bbcode::nl2br($text);
}
/**
*
* removes bbcode from text
* @param string $text
* @return string text cleaned
*/
public static function remove($text)
{
return strip_tags(str_replace(array('[',']'), array('⌈','⌉'), $text));
}
/**
*
* Inserts WIKI line breaks before all newlines in a string
* @param string $var
*/
public static function nl2br($var)
{
return str_replace(array('\\r\\n','\r\\n','r\\n','\r\n', '\n', '\r'), '\\\\', nl2br($var));
}
}
/*
* Function that does parse all command-line Options.
*
*/
function getArgs($args) {
$out = array();
$last_arg = null;
for($i = 1, $il = sizeof($args); $i < $il; $i++) {
if( (bool)preg_match("/^--(.+)/", $args[$i], $match) ) {
$parts = explode("=", $match[1]);
$key = preg_replace("/[^a-z0-9]+/", "", $parts[0]);
if(isset($parts[1])) {
$out[$key] = $parts[1];
}
else {
$out[$key] = true;
}
$last_arg = $key;
}
else if( (bool)preg_match("/^-([a-zA-Z0-9]+)/", $args[$i], $match) ) {
for( $j = 0, $jl = strlen($match[1]); $j < $jl; $j++ ) {
$key = $match[1]{$j};
$out[$key] = true;
}
$last_arg = $key;
}
else if($last_arg !== null) {
$out[$last_arg] = $args[$i];
}
}
return $out;
}
$text=getArgs($_SERVER['argv']);
if(!array_key_exists("text", $text))
die("Cant find option --text \"[b]TEXT[/b]\"\n");
$wikitex=new bbcode;
$text=$text["text"];
$text=$wikitex->towiki($text, true);
print_r($text . "\n");
?>
Den Text, den ich dafür nutzte ist Hier auffindbar.
Später, da mir langweilig war, habe ich etwas ähnliches mit sed geschrieben. Dies ist kein sed-Skript, sondern mit der “Inline”-Funktion geschaffen, da ich mit sed noch nicht viel Erfahrung besitze. Dies ist auch der Grund, warum bei mir bisher nur Einfache BB-Codes konvertiert werden… Hier auch das SH-Skript dazu:
#!/bin/bash
#b code
sed -i 's/\[b\]/\*\*/gi' $1 -u && sed -i 's/\[\/b]/\*\*/gi' $1 -u
#u
sed -i 's/\[u\]/__/gi' $1 -u && sed -i 's/\[\/u\]/__/gi' $1 -u
#i
sed -i 's/\[i\]/\/\//gi' $1 -u && sed -i 's/\[\/i\]/\/\//gi' $1 -u
#*
sed -i 's/\[\*\]/ \*/gi' $1 -u
#list
sed -i 's/\[list\]/ /gi' $1 -u && sed -i 's/\[\/list\]/ /gi' $1 -u
#code
sed -i 's/\[code\]/\<code\>/gi' $1 -u && sed -i 's/\[\/code\]/\<\/code\>/gi' $1 -u
#url
sed -i 's/\[url\]/\[\[/gi' $1 -u && sed -i 's/\[\/url\]/\]\]/gi' $1 -u
Weiß jemand, wie ich bei sed Backreferences erstellen kann? Also etwas, was in Perl etwa wie dass hier( (.+) ) aussehen würde.
Außerdem möchte ich mich entschuldigen für die späte Freischaltung der Kommentare beim letzten Artikel. Mir dafür aber Vorzuwerfen, dass ich jemanden Zensieren würde geht eindeutig zu weit ..
Nun, ich hoffe das dies irgendjemandem Helfen könnte!
Anhang
Die erwähnten Skripts
Datei: tux.txt – BBcode BeispielBBcode Beispiel
Sedscript als Text-Datei.sedscript
bbcode.php(.txt)