import re
class BBCodeParser:
def __init__(self):
# On défini ici les balises BBcode et leur équivalent en html
self.bbcode_patterns = {
r'\[b\](.*?)\[/b\]': r'\1',
r'\[i\](.*?)\[/i\]': r'\1',
r'\[u\](.*?)\[/u\]': r'\1',
r'\[s\](.*?)\[/s\]': r'\1',
r'\[url=(.*?)\](.*?)\[/url\]': r'\2',
r'\[url\](.*?)\[/url\]': r'\1',
r'\[url=(.*?)(?:\s+class=(.*?))?\](.*?)\[/url\]': lambda m: f'{{m.group(3)}}',
r'\[url\](?:\s+class=(.*?))?\](.*?)\[/url\]': lambda m: f'{{m.group(2)}}',
r'\[img alt=(.*?)\](.*?)\[/img\]': r'',
r'\[img\](.*?)\[/img\]': r'
',
r'\[list\](.*?)\[/list\]': r'
\1
', r'\[center\](.*?)\[/center\]': r'{escaped_content}'''
def parse(self, text):
# Protège temporairement le contenu des balises [code]
code_blocks = []
def save_code(match):
code_blocks.append(match.group(0))
return f'@@CODE_BLOCK_{len(code_blocks)-1}@@'
text = re.sub(r'\[code(?:=.*?)?\].*?\[/code\]', save_code, text, flags=re.DOTALL)
# Parse les autres BBCodes
for bbcode, html in self.bbcode_patterns.items():
if callable(html):
text = re.sub(bbcode, html, text, flags=re.DOTALL)
else:
text = re.sub(bbcode, html, text, flags=re.DOTALL)
# Restaure les blocs de code
for i, code_block in enumerate(code_blocks):
if '=' in code_block: # code avec langage spécifié
lang = re.match(r'\[code=(.*?)\]', code_block).group(1)
content = re.search(r'\[code=.*?\](.*?)\[/code\]', code_block, re.DOTALL).group(1)
else: # code sans langage
lang = 'none'
content = re.search(r'\[code\](.*?)\[/code\]', code_block, re.DOTALL).group(1)
text = text.replace(f'@@CODE_BLOCK_{i}@@', self._handle_code(content, lang))
return text