here, because it doesn't match
# if no newline was made before < < < %s
\n'
def paragraph_emit(self, node):
return '\n%s
\n' % self.emit_children(node)
def table_row_emit(self, node):
return '\n%s \n' % self.emit_children(node)
def table_cell_emit(self, node):
return '\t%s \n' % self.emit_children(node)
def table_head_emit(self, node):
return '\t%s \n' % self.emit_children(node)
# --------------------------------------------------------------------------
def _typeface(self, node, tag):
return '<%(tag)s>%(data)s%(tag)s>' % {
"tag": tag,
"data": self.emit_children(node),
}
# TODO: How can we generalize that:
def emphasis_emit(self, node):
return self._typeface(node, tag="i")
def strong_emit(self, node):
return self._typeface(node, tag="strong")
def monospace_emit(self, node):
return self._typeface(node, tag="tt")
def superscript_emit(self, node):
return self._typeface(node, tag="sup")
def subscript_emit(self, node):
return self._typeface(node, tag="sub")
def underline_emit(self, node):
return self._typeface(node, tag="u")
def small_emit(self, node):
return self._typeface(node, tag="small")
def delete_emit(self, node):
return self._typeface(node, tag="del")
# --------------------------------------------------------------------------
def header_emit(self, node):
header = f'%s
' % self.html_escape(node.content)
def link_emit(self, node):
target = node.content
if node.children:
inside = self.emit_children(node)
else:
inside = self.html_escape(target)
return f'{inside}'
def image_emit(self, node):
target = node.content
text = self.attr_escape(self.get_text(node))
if not self.strict:
try:
if "|" in text:
title, size_str = text.split("|", 1)
if not title:
title = target
w_str, h_str = size_str.split("x", 1)
width = int(w_str.strip())
height = int(h_str.strip())
return '' % (
self.attr_escape(target), title, title, width, height)
except BaseException:
pass
return f''
def macro_emit(self, node):
# print(node.debug())
macro_name = node.macro_name
text = node.content
macro = None
args = node.macro_args
try:
macro_kwargs = string2dict(args)
except ValueError:
exc_info = sys.exc_info()
return self.error(
f"Wrong macro arguments: {json.dumps(args)} for macro '{macro_name}' (maybe wrong macro tag syntax?)",
exc_info
)
macro_kwargs["text"] = text
exc_info = None
if isinstance(self.macros, dict):
try:
macro = self.macros[macro_name]
except KeyError:
exc_info = sys.exc_info()
else:
try:
macro = getattr(self.macros, macro_name)
except AttributeError:
exc_info = sys.exc_info()
if macro is None:
return self.error(
f"Macro '{macro_name}' doesn't exist",
exc_info
)
try:
result = macro(**macro_kwargs)
except TypeError as err:
msg = f"Macro '{macro_name}' error: {err}"
exc_info = sys.exc_info()
if self.verbose > 1:
if self.verbose > 2:
raise
# Inject more information about the macro in traceback
etype, evalue, etb = exc_info
import inspect
try:
filename = inspect.getfile(macro)
except TypeError:
pass
else:
try:
sourceline = inspect.getsourcelines(macro)[0][0].strip()
except IOError as err:
evalue = etype(f"{evalue} (error getting sourceline: {err} from {filename})")
else:
evalue = etype(f"{evalue} (sourceline: {sourceline!r} from {filename})")
exc_info = etype, evalue, etb
return self.error(msg, exc_info)
except Exception as err:
return self.error(
f"Macro '{macro_name}' error: {err}",
exc_info=sys.exc_info()
)
if not isinstance(result, str):
msg = f"Macro '{macro_name}' doesn't return a unicode string!"
if self.verbose > 1:
msg += f" - returns: {result!r}, type {type(result)!r}"
return self.error(msg)
if node.kind == "macro_block":
result += "\n"
return result
macro_inline_emit = macro_emit
macro_block_emit = macro_emit
def break_emit(self, node):
if node.parent.kind == "list_item":
return "
\n" + "\t" * node.parent.level
elif node.parent.kind in ("table_head", "table_cell"):
return "
\n\t\t"
else:
return "
\n"
def line_emit(self, node):
return "\n"
def pre_block_emit(self, node):
""" pre block, with newline at the end """
return "%s
\n" % self.html_escape(node.content)
def pre_inline_emit(self, node):
""" pre without newline at the end """
return "%s" % self.html_escape(node.content)
def default_emit(self, node):
"""Fallback function for emitting unknown nodes."""
raise NotImplementedError(f"Node '{node.kind}' unknown")
def emit_children(self, node):
"""Emit all the children of a node."""
return ''.join([self.emit_node(child) for child in node.children])
def emit_node(self, node):
"""Emit a single node."""
#print("%s_emit: %r" % (node.kind, node.content))
emit = getattr(self, f'{node.kind}_emit', self.default_emit)
return emit(node)
def emit(self):
"""Emit the document represented by self.root DOM tree."""
document = self.emit_node(self.root).strip()
if self.toc is not None:
return self.toc.emit(document)
else:
return document
def error(self, text, exc_info=None):
"""
Error Handling.
"""
if self.verbose > 1 and exc_info:
exc_type, exc_value, exc_traceback = exc_info
exception = "".join(traceback.format_exception(exc_type, exc_value, exc_traceback))
self.stderr.write(exception)
if self.verbose > 0:
return f"[Error: {text}]\n"
else:
# No error output
return ""
if __name__ == "__main__":
txt = """Local test
<