2
0
Fork 0

Added a tag loader class.

This commit is contained in:
Thomas Touhey 2018-05-24 21:57:42 +02:00
parent 2c2ce72719
commit 5920a0860d
No known key found for this signature in database
GPG Key ID: 2ECEB0517AD947FB
18 changed files with 108 additions and 102 deletions

View File

@ -40,6 +40,7 @@ __test_cases = {
'[left]': '',
'[left]lol[/]hi': '<div class="align-left"><p>lol</p></div><p>hi</p>',
'a[justify]b': '<p>a</p><div class="align-justify"><p>b</p></div>',
'a[i]': '<p>a</p>',
'a[i][justify]b': '<p>a</p>' \
'<div class="align-justify"><p><i>b</i></p></div>',
'a[i]k[center]b': '<p>a<i>k</i></p>' \

View File

@ -4,7 +4,7 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutBlockTag as _TextoutBlockTag
from ..tags import TextoutBlockTag as _TextoutBlockTag
__all__ = ["TextoutAlignTag"]

View File

@ -4,7 +4,7 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutBlockTag as _TextoutBlockTag, \
from ..tags import TextoutBlockTag as _TextoutBlockTag, \
TextoutInlineTag as _TextoutInlineTag
__all__ = ["TextoutCodeTag", "TextoutInlineCodeTag", "TextoutNoEvalTag"]

View File

@ -4,7 +4,7 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutBlockTag as _TextoutBlockTag
from ..tags import TextoutBlockTag as _TextoutBlockTag
from html import escape as _htmlescape
__all__ = ["TextoutImageTag", "TextoutAdminImageTag"]

View File

@ -4,7 +4,7 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutInlineTag as _TextoutInlineTag
from ..tags import TextoutInlineTag as _TextoutInlineTag
import re as _re
__all__ = ["TextoutLabelTag", "TextoutTargetTag"]

View File

@ -4,7 +4,7 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutInlineTag as _TextoutInlineTag
from ..tags import TextoutInlineTag as _TextoutInlineTag
from html import escape as _htmlescape
__all__ = ["TextoutLinkTag", "TextoutProfileTag"]

View File

@ -4,7 +4,7 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutBlockTag as _TextoutBlockTag
from ..tags import TextoutBlockTag as _TextoutBlockTag
__all__ = ["TextoutProgressTag"]

View File

@ -4,9 +4,9 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutBlockTag as _TextoutBlockTag
from ..tags import TextoutBlockTag as _TextoutBlockTag
from html import escape as _htmlescape
from ...smileys import htmlsmileys as _htmlsmileys
from ..smileys import htmlsmileys as _htmlsmileys
__all__ = ["TextoutQuoteTag"]

View File

@ -4,7 +4,7 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutInlineTag as _TextoutInlineTag
from ..tags import TextoutInlineTag as _TextoutInlineTag
import string as _string
__all__ = ["TextoutRotTag"]

View File

@ -4,7 +4,7 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutBlockTag as _TextoutBlockTag
from ..tags import TextoutBlockTag as _TextoutBlockTag
from html import escape as _htmlescape
__all__ = ["TextoutShowTag"]

View File

@ -4,9 +4,9 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutBlockTag as _TextoutBlockTag
from ..tags import TextoutBlockTag as _TextoutBlockTag
from html import escape as _htmlescape
from ...smileys import htmlsmileys as _htmlsmileys
from ..smileys import htmlsmileys as _htmlsmileys
__all__ = ["TextoutSpoilerTag"]

View File

@ -4,8 +4,8 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutInlineTag as _TextoutInlineTag
from ...color import get_color
from ..tags import TextoutInlineTag as _TextoutInlineTag
from ..color import get_color
__all__ = ["TextoutTextTag"]

View File

@ -4,7 +4,7 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutBlockTag as _TextoutBlockTag
from ..tags import TextoutBlockTag as _TextoutBlockTag
__all__ = ["TextoutTitleTag"]

View File

@ -4,7 +4,7 @@
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
from ..base import TextoutBlockTag as _TextoutBlockTag
from ..tags import TextoutBlockTag as _TextoutBlockTag
import re as _re
import urllib.parse as _urlparse
from html import escape as _htmlescape

86
textoutpc/tags/base.py → textoutpc/tags.py Executable file → Normal file
View File

@ -3,22 +3,28 @@
# Copyright (C) 2018 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
""" Base class for textout tags. For your class to be used as a textout tag,
you have to make it inherit one of these (usually `TextoutBlockTag`
or `TextoutInlineTag`). """
""" Base classes to use with tags in textoutpc, with a manager class.
For your tag to be used as a textoutpc tag, you have to make it
inherit one of the `TextoutBlockTag` or `TextoutInlineTag` classes.
Making separate tag modules is possible through the manager class,
which allows not to hardcode the tags into the module. """
import inspect as _inspect
from functools import partial as _p
from inspect import getargspec as _getargspec
from inspect import ismodule as _ismod, isclass as _isclass, \
getargspec as _getargspec, getfullargspec as _getfullargspec, \
currentframe as _currentframe, getouterframes as _getouterframes
from importlib import import_module as _importmod
__all__ = ["TextoutTag", "TextoutBlockTag", "TextoutInlineTag",
__all__ = ["TextoutTags", "TextoutTag", "TextoutBlockTag", "TextoutInlineTag",
"TextoutParagraphTag"]
def _getargscount(func):
try:
return len(_inspect.getfullargspec(func).args)
return len(_getfullargspec(func).args)
except:
return len(_inspect.getargspec(func).args)
return len(_getargspec(func).args)
# ---
# Main base tag class.
@ -147,4 +153,68 @@ class TextoutParagraphTag(TextoutBlockTag):
def end_html(self):
return '</p>'
# ---
# Tag extractor.
# ---
class TextoutTags:
""" Tag manager.
Object responsible for getting the tags. """
def __init__(self, *modules):
self._aliases = {}
for mod in modules:
self.import_tags(mod)
def __extract_tags(self, module):
""" Extract tags from a module. """
tags = []
# Obtain the list of properties from the module.
try:
ds = module.__all__
except:
ds = dir(module)
# Get the submodules from the module (usually different files in the
# tags module folder).
for submodule in (obj for name, obj in ((nm, getattr(module, nm)) \
for nm in ds) if (name == '__init__' or name[0] != '_') \
and _ismod(obj)):
obtained = self.__extract_tags(submodule)
tags += [tag for tag in obtained \
if not any(tag is x for x in tags)]
del obtained
# Extract the tags from the current module.
for tag in (obj for name, obj in ((nm, getattr(module, nm)) \
for nm in ds) if name[0] != '_' and _isclass(obj) \
and issubclass(obj, TextoutTag)):
tags.append(tag)
return tags
def import_tags(self, module):
""" Import tags from a dedicated module. """
if not _ismod(module):
module = _importmod(module,
_getouterframes(_currentframe(), 1)[0].name)
for tag in self.__extract_tags(module):
for alias in tag.aliases:
self._aliases[alias] = tag
def get_tag(self, name, value, output_type = 'html', tweaks = {}):
""" Initialize a tag. """
try:
als = self._aliases[name]
return als(name, value, output_type, tweaks)
except:
return None
# End of file.

View File

@ -1,73 +0,0 @@
#!/usr/bin/env python3
#******************************************************************************
# Copyright (C) 2018 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
# This file is part of the textoutpc project, which is MIT-licensed.
#******************************************************************************
""" Tag helpers for the translate utilities.
As we ought to be able to make separate tag modules, this module
does not hardcode the imports and makes it possible to import any
custom module to isolate some tags from the others and make the
`textoutpc` a generic module for BBcode.
"""
from inspect import ismodule as _ismod, isclass as _isclass
from .base import TextoutTag as _TextoutTag, TextoutBlockTag, \
TextoutInlineTag, TextoutParagraphTag
__all__ = ["TextoutParagraphTag", "TextoutBlockTag", "TextoutInlineTag",
"get_tag"]
# ---
# Gathering of the tags.
# ---
def _extract_tags(module):
""" Load all tags from a module. """
tags = []
# Obtain the list of properties from the module.
try:
ds = module.__all__
except:
ds = dir(module)
# Get the submodules from the module (usually different files in the
# tags module folder).
for submodule in (obj for name, obj in ((nm, getattr(module, nm)) \
for nm in ds) if (name == '__init__' or name[0] != '_') \
and _ismod(obj)):
obtained = _extract_tags(submodule)
tags += [tag for tag in obtained if not any(tag is x for x in tags)]
del obtained
# Extract the tags from the current module.
for tag in (obj for name, obj in ((nm, getattr(module, nm)) for nm in ds) \
if name[0] != '_' and _isclass(obj) and issubclass(obj, _TextoutTag)):
tags.append(tag)
return tags
_tags = _extract_tags(__import__("builtin", \
{'__name__': __name__ + '.__init__'}, level=1))
_aliases = {alias: tag for alias, tag in \
[(alias, tag) for tag in _tags for alias in tag.aliases]}
# ---
# Function to get a tag.
# ---
def get_tag(name, value, output_type = 'html', tweaks = {}):
""" Find a tag using its name. """
try:
als = _aliases[name]
als = als(name, value, output_type, tweaks)
return als
except:
return None
# End of file.

View File

@ -10,14 +10,20 @@
import string as _string
from copy import deepcopy as _deepcopy
from html import escape as _htmlescape
from importlib import import_module as _importmod
from .tags import TextoutBlockTag as _TextoutBlockTag, \
TextoutParagraphTag as _TextoutParagraphTag, get_tag as _get_tag
TextoutParagraphTag as _TextoutParagraphTag, TextoutTags as _Tags
from .stream import TextoutStream as _TextoutStream
from .smileys import htmlsmileys as _htmlsmileys
from .urls import htmlurls as _htmlurls
__all__ = ["Translator"]
# Builtin tags.
_builtin_tags = _Tags(_importmod('..builtin_tags', __name__))
# ---
# Tweaks interface.
# ---
@ -133,7 +139,8 @@ class Translator:
You can even chain calls as the `process()` method returns
the output stream object. """
def __init__(self, inp, outp, output_type = 'html', tweaks = {}):
def __init__(self, inp, outp, output_type = 'html', \
tweaks = {}, tags = _builtin_tags):
""" Initializer. """
if not output_type in ('html', 'lightscript'):
@ -141,6 +148,7 @@ class Translator:
self.output_type = output_type
self.tweaks = _TweaksDictionary(tweaks)
self.tags = tags
self.inp = inp
self.outp = outp
@ -540,7 +548,7 @@ class Translator:
# Then we want to end the tags, and reset them in case we're going
# to use them.
self.queue = inlines + blocks
self.queue = inlines[::-1] + blocks[::-1]
while self.queue:
dat = self.queue.pop(0)
tag = dat.tag
@ -665,8 +673,8 @@ class Translator:
# Get the initialized tag with the name and value.
# If the tag is unknown, output the full thing and just go on.
tag = _get_tag(tagdata.name, tagdata.value, self.output_type,
self.tweaks)
tag = self.tags.get_tag(tagdata.name, tagdata.value,
self.output_type, self.tweaks)
if not tag:
self.put_text(tagdata.full)
continue