regex
Full documentation pages are generated for docstring
reference only and may contain symbols imported from other
modules. Imported symbols are not distinguished from locally
defined symbols and will appear in any module that they are
imported into. For better information on where symbols should
be imported from, review the sourcecode on the
github.
FoSpy.parsing.regex
BLOCK_HEADER = build_block_header_regex(
SYNTAX["block_header"]
)
CALC_COMMENT_LINE = build_calc_comment_regex(
SYNTAX["calc_comment"]
)
COMMENT_LINE = build_comment_regex(SYNTAX['comment'])
EMBEDDED_END
module-attribute
EMBEDDED_END = build_embedded_end_regex(SYNTAX['embedded'])
EMBEDDED_START
module-attribute
EMBEDDED_START = build_embedded_start_regex(
SYNTAX["embedded"]
)
KEY_VALUE
module-attribute
KEY_VALUE = build_key_value_regex(SYNTAX['key_value'])
LOOP_KEY
module-attribute
LOOP_KEY = build_loop_key_regex(SYNTAX['key_value'])
NESTED_START
module-attribute
NESTED_START = build_nested_start_regex(SYNTAX['nested'])
SYNTAX
module-attribute
SYNTAX = {
"block_header": {
"single": {"open": "[", "close": "]"},
"list": {"open": "[[", "close": "]]"},
},
"nested": {"open": "[", "close": "]"},
"embedded": {
"open": "{{{",
"close": "END FOS EMBED }}}",
"prefix": "#",
},
"key_value": {
"delimiter": ":",
"require_value": True,
"prefix": False,
},
"comment": {"prefix": "//", "allow_leading_ws": True},
"calc_comment": {
"prefix": "!",
"allow_leading_ws": True,
},
"indent_size": 4,
}
Debug
Source code in FoSpy/_debug.py
| class Debug:
def __init__(self):
self.on = False
frame = inspect.currentframe().f_back
self.module_name = frame.f_globals.get("__name__", "<unknown>")
self.label = f"|(Debug message from {self.module_name})"
self.label_width = len(self.label)
def _get_text_width(self, module=None):
if module:
label = f"|(Debug message from {module} via {self.module_name})"
label_width = len(label)
else:
label = self.label
label_width = self.label_width
text_width = DEBUG_WIDTH - label_width
return text_width, label, label_width
def msg(self,msg, module=None):
if not self.on:
return
text_width, label, label_width = self._get_text_width(module)
wrapped = textwrap.fill(str(msg), width=text_width)
for line in wrapped.splitlines():
print(f'{line:<{text_width}}{label:>{label_width}}')
def pmsg(self,msg,module=None,**kwargs):
if not self.on:
return
text_width, label, label_width = self._get_text_width(module)
buf = io.StringIO()
pprint(msg,stream=buf, width=text_width,**kwargs)
txt = buf.getvalue()
for line in txt.splitlines():
print(f'{line:<{text_width}}{label:>{label_width}}')
|
label
instance-attribute
label = f'|(Debug message from {self.module_name})'
label_width
instance-attribute
label_width = len(self.label)
module_name
instance-attribute
module_name = frame.f_globals.get('__name__', '<unknown>')
__init__
Source code in FoSpy/_debug.py
| def __init__(self):
self.on = False
frame = inspect.currentframe().f_back
self.module_name = frame.f_globals.get("__name__", "<unknown>")
self.label = f"|(Debug message from {self.module_name})"
self.label_width = len(self.label)
|
_get_text_width
_get_text_width(module=None)
Source code in FoSpy/_debug.py
| def _get_text_width(self, module=None):
if module:
label = f"|(Debug message from {module} via {self.module_name})"
label_width = len(label)
else:
label = self.label
label_width = self.label_width
text_width = DEBUG_WIDTH - label_width
return text_width, label, label_width
|
msg
Source code in FoSpy/_debug.py
| def msg(self,msg, module=None):
if not self.on:
return
text_width, label, label_width = self._get_text_width(module)
wrapped = textwrap.fill(str(msg), width=text_width)
for line in wrapped.splitlines():
print(f'{line:<{text_width}}{label:>{label_width}}')
|
pmsg
pmsg(msg, module=None, **kwargs)
Source code in FoSpy/_debug.py
| def pmsg(self,msg,module=None,**kwargs):
if not self.on:
return
text_width, label, label_width = self._get_text_width(module)
buf = io.StringIO()
pprint(msg,stream=buf, width=text_width,**kwargs)
txt = buf.getvalue()
for line in txt.splitlines():
print(f'{line:<{text_width}}{label:>{label_width}}')
|
build_block_header_regex(spec)
Source code in FoSpy/parsing/regex.py
| def build_block_header_regex(spec):
single = spec["single"]
list_ = spec["list"]
pattern = (
rf"^(?:"
rf"{re.escape(list_['open'])}(?P<list_name>[^\]]+){re.escape(list_['close'])}"
rf"|"
rf"{re.escape(single['open'])}(?P<single_name>[^\]]+){re.escape(single['close'])}"
rf")$"
)
return re.compile(pattern)
|
build_calc_comment_regex(spec)
Example:
// ## Calculated MW: 123.45 g/mol
Source code in FoSpy/parsing/regex.py
| def build_calc_comment_regex(spec):
"""
Matches calculated comments of the form:
<comment_prefix> <calc_prefix> <text>
Example:
// ## Calculated MW: 123.45 g/mol
"""
comment_prefix = re.escape(SYNTAX["comment"]["prefix"])
calc_prefix = re.escape(spec["prefix"])
# Allow leading whitespace before the comment prefix
return re.compile(
rf"^\s*{comment_prefix}\s+{calc_prefix}\s+(?P<text>.*)$"
)
|
build_comment_regex(spec)
Source code in FoSpy/parsing/regex.py
| def build_comment_regex(spec):
prefix = re.escape(spec["prefix"]) # usually "//"
allow_ws = spec.get("allow_leading_ws", True)
if allow_ws:
pattern = rf"^\s*{prefix}(?P<text>.*)$"
else:
pattern = rf"^{prefix}(?P<text>.*)$"
return re.compile(pattern)
|
build_embedded_end_regex
build_embedded_end_regex(spec)
Source code in FoSpy/parsing/regex.py
| def build_embedded_end_regex(spec):
prefix = re.escape(spec["prefix"])
close_tok = re.escape(spec["close"])
pattern = rf"^{prefix}*\s*{close_tok}\s*$"
return re.compile(pattern)
|
build_embedded_start_regex
build_embedded_start_regex(spec)
Source code in FoSpy/parsing/regex.py
| def build_embedded_start_regex(spec):
open_tok = re.escape(SYNTAX["embedded"]["open"])
return re.compile(rf".*{open_tok}.*")
|
build_key_value_regex
build_key_value_regex(spec)
Source code in FoSpy/parsing/regex.py
| def build_key_value_regex(spec):
delim = re.escape(spec["delimiter"])
prefix = spec.get("prefix")
# Key cannot contain the delimiter
if prefix:
prefix_esc = re.escape(prefix)
key_pattern = rf"{prefix_esc}(?P<key>[^{delim}]+)"
else:
key_pattern = rf"(?P<key>[^{delim}]+)"
if spec["require_value"]:
pattern = rf"^{key_pattern}\s*{delim}\s*(?P<val>.+)$"
else:
pattern = rf"^{key_pattern}\s*{delim}\s*(?P<val>.*)$"
return re.compile(pattern)
|
build_loop_key_regex
build_loop_key_regex(spec)
Source code in FoSpy/parsing/regex.py
| def build_loop_key_regex(spec):
prefix = spec.get("prefix")
delim = re.escape(spec["delimiter"])
if prefix:
# Require key followed by prefix, e.g. "key_"
prefix = re.escape(prefix)
pattern = rf"^(?P<key>[^{prefix}]+){prefix}$"
else:
# Default: delimiter before key, e.g. ":key"
pattern = rf"^{delim}(?P<key>[^{delim}]+)$"
return re.compile(pattern)
|
build_nested_start_regex
build_nested_start_regex(spec)
Source code in FoSpy/parsing/regex.py
| def build_nested_start_regex(spec):
open_bracket = re.escape(spec["open"]) # usually "["
pattern = (
rf"^{open_bracket}"
rf"(?P<list>{open_bracket})?"
rf"(?P<rest>.*)$"
)
return re.compile(pattern)
|
refresh
Source code in FoSpy/parsing/regex.py
| def refresh():
global BLOCK_HEADER, KEY_VALUE, COMMENT_LINE, CALC_COMMENT_LINE, NESTED_START, LOOP_KEY, EMBEDDED_START, EMBEDDED_END
BLOCK_HEADER = build_block_header_regex(SYNTAX["block_header"])
KEY_VALUE = build_key_value_regex(SYNTAX["key_value"])
COMMENT_LINE = build_comment_regex(SYNTAX["comment"])
CALC_COMMENT_LINE = build_calc_comment_regex(SYNTAX["calc_comment"])
NESTED_START = build_nested_start_regex(SYNTAX["nested"])
LOOP_KEY = build_loop_key_regex(SYNTAX["key_value"])
COMMENT_LINE = build_comment_regex(SYNTAX["comment"])
EMBEDDED_START = build_embedded_start_regex(SYNTAX["embedded"])
EMBEDDED_END = build_embedded_end_regex(SYNTAX["embedded"])
|
Matches calculated comments of the form