Created
December 29, 2024 15:59
-
-
Save ZoomTen/b45e387733cc5f1df05bcc148c85ac4a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
##[ | |
An extremely basic BBcode parser | |
Not quite ready for the works. | |
Will turn into a package later | |
Supports no parameters yet. | |
2 blank lines = 1 manual line break | |
3 blank lines = 2 manual line break | |
and so on | |
]## | |
from strutils import nil | |
proc bbCode2Html*(input: string): string = | |
let text = strutils.strip(input) | |
var rendered: string | |
var inBracket = false | |
var isEndCommand = false | |
var commandBuffer = "" | |
var bracketStack: seq[string] = @[] | |
var numCharactersEncountered = 0 | |
var blankLinesEncountered = 0 | |
for i in text: | |
if i == '\n': | |
inc(blankLinesEncountered) | |
if blankLinesEncountered > 1: | |
rendered.add "<br>" | |
else: | |
blankLinesEncountered = 0 | |
case i | |
of '[': | |
# lookahead one character | |
let lookaheadIndex = numCharactersEncountered + 1 | |
if lookaheadIndex > (len(text) - 1): | |
# there is no other character! | |
rendered.add '[' | |
else: | |
if text[lookaheadIndex] == '[': | |
# this is an escaped [ | |
rendered.add '[' | |
elif text[lookaheadIndex] in ({'a' .. 'z'}): | |
# we have a command | |
inBracket = true | |
elif text[lookaheadIndex] == '/': | |
# we have an ending command | |
inBracket = true | |
isEndCommand = true | |
of ']': | |
if inBracket: | |
if isEndCommand: | |
isEndCommand = false | |
let commandTerm = bracketStack.pop() | |
assert(commandTerm == commandBuffer) | |
rendered.add( | |
case commandTerm | |
of "center": "</div>" | |
of "big": "</span>" | |
of "ul": "</ul>" | |
of "li": "</li>" | |
of "b": "</b>" | |
of "i": "</i>" | |
of "u": "</u>" | |
else: "" | |
) | |
else: | |
bracketStack.add commandBuffer | |
rendered.add( | |
case commandBuffer | |
of "center": "<div class=\"bbcode-center\">" | |
of "big": "<span class=\"bbcode-big\">" | |
of "ul": "<ul class=\"proper-list\">" | |
of "li": "<li>" | |
of "b": "<b>" | |
of "i": "<i>" | |
of "u": "<u>" | |
else: "" | |
) | |
commandBuffer.setLen(0) | |
inBracket = false | |
else: | |
# lookahead one character | |
let lookaheadIndex = numCharactersEncountered + 1 | |
if lookaheadIndex > (len(text) - 1): | |
# there is no other character! | |
if inBracket: | |
# clean up | |
inBracket = false | |
else: | |
rendered.add ']' | |
else: | |
if text[lookaheadIndex] == ']': | |
# this is an escaped ] | |
rendered.add ']' | |
of '<': | |
rendered.add "<" | |
of '>': | |
rendered.add ">" | |
of '&': | |
rendered.add "&" | |
else: | |
if inBracket: | |
if i in {'a' .. 'z'}: | |
commandBuffer.add i | |
else: | |
rendered.add i | |
inc(numCharactersEncountered) | |
assert(not inBracket) | |
assert(not isEndCommand) | |
assert(len(bracketStack) < 1) | |
assert(numCharactersEncountered == len(text)) | |
return rendered |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment