REBOL [
Title: "BBcode"
Date: 5-Jan-2009/1:06:26+1:00
Name: 'bbcode
Version: 0.1.0
File: %bbcode.r
Author: "David 'Oldes' Oliva"
Email: oliva.david@seznam.cz
Home: http://box.lebeda.ws/~hmm/
Owner: none
Rights: none
Needs: none
Tabs: 4
Usage: [
test-cases: [
{text [b]bold[/b] abc} {text bold abc}
{text [b]bold [i]italic[/b]} {text bold italic}
{[s]strikethrough text[/s]} {strikethrough text}
{[url]http://example.org[/url]} {http://example.org}
{[url=http://example.com]Example[/url]} {Example}
{[url=http://example.com][b]Example[/url]} {Example}
{[b][ul][li]Jenny[/li][li]Alex[/li][li]Beth[/li][/ul][/b]} {- Jenny
- Alex
- Beth
}
{[ul][li]bla[li]bla} {- bla
- bla
}
{[ul][li][b]bla[li]bla} {- bla
- bla
}
{[ul][li]bla[li][ol][li]bla[/ol]} {- bla
- bla
}
{[code]xx[b]yy[/b]zz[/code]} {xx[b]yy[/b]zz
}
{[list][*]aaa[*]bbb[/list]} {- aaa
- bbb
}
{[list=a][*]aaa[*]bbb[/list]} {- aaa
- bbb
}
{[list=A][*]aaa[*]bbb[/list]} {- aaa
- bbb
}
{[/b]} {}
{aa[b="]bb} {aa[b="]bb}
{[quote]blabla} {}
{[quote=Carl]blabla} {}
{[img]http://www.google.com/intl/en_ALL/images/logo.gif[/img]} {
}
{[url=http://http://www.google.com/][img]http://www.google.com/intl/en_ALL/images/logo.gif[/url][/img]}
{
}
{[img]1.gif [img]2.gif} {
}
{text [size=tiny]tiny} {text tiny}
{[h1]header[/h1]} {header
}
{[color]ee[/color][color=#F00]red[color=#00FF00]green} {eeredgreen}
{} {<a>}
{multi^/line} {multi^/
line}
{invalid [size]size[/size]} {invalid size}
{[align=right]right} {right}
{[email]x@x.cz[/email] [email=x@x.cz]email [b]me[/email]} {x@x.cz email me}
]
foreach [src result] test-cases [
print ["<==" src]
print ["==>" tmp: bbcode src]
print either tmp = result ["OK"][join "ERR " result]
print "---"
]
]
Purpose: {Basic BBCode implementation. For more info about BBCode check http://en.wikipedia.org/wiki/BBCode}
Comment: none
History: [
0.1.0 5-Jan-2009 "Initial version"
]
Type: [tool dialect function]
Library: [
level: 'advanced
platform: 'all
type: [tool dialect function]
domain: [dialects files html markup parse text text-processing web]
]
Content: none
]
ctx-bbcode: context [
ch-normal: complement charset "[<^/"
ch-attribute: complement charset {"'<>]}
ch-hexa: charset [#"a" - #"f" #"A" - #"F" #"0" - #"9"]
ch-name: charset [#"a" - #"z" #"A" - #"Z" #"*" #"0" - #"9"]
ch-url: charset [#"a" - #"z" #"A" - #"Z" #"0" - #"9" "./:~+-%#\_=&?@"]
opened-tags: copy []
rl-attribute: [#"=" copy attr any ch-attribute]
allow-html-tags?: false
attr: none
html: copy ""
close-tags: func[tags [block!]][
foreach tag head reverse tags [
append html case [
tag = "url" [""]
find ["list" "color" "quote" "size" "align" "email"] tag [""]
true [
rejoin ["" tag ">"]
]
]
]
]
enabled-tags: [
"b" "i" "s" "u" "del" "h1" "h2" "h3" "h4" "h5"
"ins" "dd" "dt" "ol" "ul" "li" "url" "list" "*"
"color" "quote" "img" "size" "rebol" "align" "email"
]
set 'bbcode func["Converts BBCode markup into HTML" code [string! binary! file! url!] "Input with BBCode tags" /local tmp tag][
clear html
if any [file? code url? code][code: read/binary code]
parse/all code [
any [
(attr: none)
copy tmp some ch-normal (append html tmp)
|
"[url]" copy tmp some ch-url opt "[/url]" (
append html rejoin [{} tmp {}]
)
|
"[email]" copy tmp some ch-url opt "[/email]" (
append html rejoin [{} tmp {}]
)
|
"[img]" copy tmp some ch-url opt "[/img]" (
append html rejoin [{
}]
)
|
"[code]" copy tmp to "[/code]" thru "]" (
append html rejoin [{} tmp {
}]
)
|
"[rebol]" copy tmp to "[/rebol]" thru "]" (
append html rejoin [{} tmp {
}]
;TODO: add REBOL code colorizer
)
|
#"[" [
;normal opening tags
copy tag some ch-name opt rl-attribute
#"]" (
if tag = "*" [tag: "li"]
append html either find enabled-tags tag [
if find ["li"] tag [
;closed already opened tag
if all [
tmp: find/last opened-tags tag
none? find tmp "ol"
none? find tmp "ul"
][
close-tags copy tmp
clear tmp
]
]
append opened-tags tag
switch/default tag [
"url" [rejoin [{}]]
"color" [
either all [attr parse attr [
#"#" [6 ch-hexa | 3 ch-hexa]
]][
append opened-tags "span"
rejoin [{}]
][
;;Should the invalid tag be visible?
;rejoin either attr [
; ["[" tag "=" attr "]"]
;][ ["[" tag "]"] ]
""
]
]
"quote" [
append opened-tags ["fieldset" "blockquote"]
either attr [
rejoin [{