Some utilities for ClammingPy.
Module clamming
Class ClamUtils
Description
Constructor
Create a ClamUtils instance.
View Source
def __init__(self):
"""Create a ClamUtils instance."""
self.markdowner = None
self.lexer = None
self.formatter = None
if len(HTML) == 0:
self.markdowner = markdown2.Markdown()
self.formatter = pygments_formatter.HtmlFormatter(**ClamUtils.HTML_FORMATTER_ARGS)
self.lexer = pygments_lexers.PythonLexer()
Public functions
get_class
Return a class object by its name, regardless of import context.
This method searches for a class within a module, whether the module
has been imported from a package, from a local test, or executed as
a script. It first checks already-loaded modules (sys.modules
),
then attempts a safe import using importlib
.
This approach ensures stability both for installed packages
(e.g., clamming
) and for local tests (e.g., tests.test_clamutils
).
Parameters
- class_name: (str) Name of the class to retrieve.
- module_name: (str|None) Name of the module where to look for the class. If None, defaults to the caller’s module.
Returns
- (class|None) Class object if found, otherwise None.
View Source
@staticmethod
def get_class(class_name: str, module_name: str | None=None) -> Any:
"""Return a class object by its name, regardless of import context.
This method searches for a class within a module, whether the module
has been imported from a package, from a local test, or executed as
a script. It first checks already-loaded modules (``sys.modules``),
then attempts a safe import using ``importlib``.
This approach ensures stability both for installed packages
(e.g., ``clamming``) and for local tests (e.g., ``tests.test_clamutils``).
:param class_name: (str) Name of the class to retrieve.
:param module_name: (str|None) Name of the module where to look for the class.
If None, defaults to the caller’s module.
:return: (class|None) Class object if found, otherwise None.
"""
if module_name is None:
frame = inspect.currentframe()
caller = frame.f_back if frame else None
module_name = caller.f_globals.get('__name__', '__main__') if caller else '__main__'
module = None
if module_name in sys.modules:
module = sys.modules[module_name]
else:
try:
module = importlib.import_module(module_name)
except ModuleNotFoundError:
main_module = sys.modules.get('__main__')
spec = getattr(main_module, '__spec__', None)
if spec is not None and hasattr(spec, 'name'):
alt_name = getattr(spec, 'name')
module = sys.modules.get(alt_name, None)
if module is None:
logging.warning('get_class(): module not found: %s', module_name)
return None
class_inst = getattr(module, class_name, None)
if class_inst is None:
logging.debug('get_class(): class not found: %s in %s', class_name, module_name)
return None
if not inspect.isclass(class_inst):
logging.debug('get_class(): "%s" found in %s but is not a class.', class_name, module_name)
return None
return class_inst
markdown_convert
Return HTML of the given markdown content.
Parameters
- md: (str) A standard-limited markdown content
Returns
- (str) The HTML content
View Source
def markdown_convert(self, md):
"""Return HTML of the given markdown content.
:param md: (str) A standard-limited markdown content
:return: (str) The HTML content
"""
if len(HTML) > 0:
logging.warning(f'Markdown to HTML conversion is disabled: {HTML}')
return ''
return self.markdowner.convert(md)
markdown_to_html
Turn a markdown content into HTML.
Parameters
- content: (str) A complex markdown content
Returns
- (str) The HTML content
View Source
def markdown_to_html(self, content):
"""Turn a markdown content into HTML.
:param content: (str) A complex markdown content
:return: (str) The HTML content
"""
if len(HTML) > 0:
logging.warning(f'Markdown to HTML conversion is disabled: {HTML}')
return ''
h = list()
code = list()
md = list()
i = 0
all_lines = content.split('\n')
while i < len(all_lines):
line = all_lines[i]
if line.strip().startswith('```') is True:
has_language = len(line.strip()) == 3
if len(md) > 0:
h.append(self.markdowner.convert('\n'.join(md)))
md = list()
line = ''
while line.strip().startswith('```') is False:
code.append(line)
i = i + 1
if i >= len(all_lines):
break
line = all_lines[i]
if len(code) > 0:
if has_language is True:
h.append('<pre>')
h.append('\n'.join(code))
h.append('</pre>')
else:
h.append(pygments_highlight('\n'.join(code), self.lexer, self.formatter))
code = list()
else:
idx = self.__is_code(line)
if idx != -1:
if len(md) > 0:
h.append(self.markdowner.convert('\n'.join(md)))
md = list()
if idx > 0:
code.append(line[idx:])
else:
code.append(line)
else:
if len(code) > 0:
h.append(pygments_highlight('\n'.join(code), self.lexer, self.formatter))
code = list()
md.append(line)
i = i + 1
if len(code) > 0:
h.append(pygments_highlight('\n'.join(code), self.lexer, self.formatter))
if len(md) > 0:
h.append(self.markdowner.convert('\n'.join(md)))
html_result = '\n'.join(h)
return html_result.replace('<p></p>', '')
source_to_html
Turn a source code content into HTML.
Parameters
- source: (str) The source code content
Returns
- (str) The HTML content
View Source
def source_to_html(self, source):
"""Turn a source code content into HTML.
:param source: (str) The source code content
:return: (str) The HTML content
"""
if len(HTML) > 0:
logging.warning('Source code to HTML conversion is disabled: {:s}'.format(HTML))
return ''
return pygments_highlight(source, self.lexer, self.formatter)
Protected functions
__is_code
View Source
@staticmethod
def __is_code(line):
entry = line.strip()
if entry.startswith('>>>') is True:
return line.index('>') - 1
if entry.startswith('> ') is True:
return line.index('>') - 1
return -1