from html import escape
from IPython.core.display import display
from IPython.core.display import HTML
from graphbrain import hedge
from graphbrain.meaning.case_generators import InteractiveCaseGenerator
TYPE_COLORS = {'C': '#268bd2',
'M': '#dc322f',
'B': '#859900',
'P': '#cb4b16',
'T': '#d33682',
'J': '#b58900',
'R': '#eee8d5',
'S': '#6c71c4'}
def _edge2html_show(edge, style='indented', indent=False, close=True,
close_html=''):
ret_close_html = ''
if indent:
main_tag = 'div'
margin = 'margin-left:20px;'
else:
main_tag = 'span'
margin = ''
et = edge.type()[0]
if et == 'R':
color = '#303030'
else:
color = TYPE_COLORS[edge.type()[0]]
color_html = 'color:{}'.format(color)
if edge.is_atom():
html = '<span style="{}">{}</span>'.format(
color_html, escape(str(edge.root())))
if len(edge.parts()) > 1:
escaped_codes = '/'.join(edge.parts()[1:])
escaped_codes = escape(escaped_codes).strip()
html = '{}<span style="color:#000000;font-weight:lighter">/{}'\
'</span>'.format(html, escaped_codes)
else:
et = edge.type()[0]
arity = len(edge)
contains_edges = any(not child.is_atom() for child in edge)
color_html = 'color:{}'.format(color)
# render opening symbol
html = '<span style="font-weight:bold">(</span>'
close_html = '</{}>'.format(main_tag)
# render edge children
for i in range(arity):
child = edge[i]
# first edge (connector)?
if i == 0:
child_indent = False
sep = ''
# not connector
else:
# indent depending on style
if style == 'indented':
# edges with only two items are rendered in one line
child_indent = arity > 2
if child_indent and child.is_atom() and not contains_edges:
child_indent = False
elif style == 'oneline':
child_indent = False
sep = ' '
if child.is_atom():
child_html, _ = _edge2html_show(child,
style=style,
indent=child_indent)
else:
# Do not render closing html of children that are the last
# edge in a hyperedge. Instead, let some higher-level edge
# render it to avoid ugly multi-line staircases when closing
# a sequence of edges.
child_close = i < arity - 1
child_html, child_cl_html = _edge2html_show(
child,
style=style,
indent=child_indent,
close=child_close)
# accumulate close_html of child
close_html = '{}{}'.format(child_cl_html, close_html)
html = '{}{}{}'.format(html, sep, child_html)
# if closing html should not be rendered at the end of this edge
# representation, then return it to the parent
if not close:
ret_close_html = close_html
close_html = ''
# render close symbol
html = '{}<span style="{}">'.format(html, color_html)
html = '{}<span style="font-weight:bold">)</span></span>'.format(html)
# render edge
html = '<{} style="{}{}">{}{}'.format(
main_tag, margin, color_html, html, close_html)
return html, ret_close_html
[docs]def show(edge, style='indented'):
"""Displays a representation of the edge in the notebook.
Keyword arguments:
style -- render style ('indented', 'line')
(default: 'indented')
"""
edge = hedge(edge)
html = _edge2html_show(edge, style=style)[0]
display(HTML(html))
def _edge2html_vblocks(edge):
tcolor = TYPE_COLORS[edge.type()[0]]
if edge.is_atom():
html_root = '<span style="color:#fdf6e3;font-weight:bold">{}'\
'</span>'.format(edge.root())
parts = '/'.join(edge.parts()[1:])
html_parts = '<span style="color:#eee8d5;font-weight:lighter">/{}'\
'</span>'.format(parts)
html = '<div style="padding:5px;background-color:{};'\
'border:2px solid #fdf6e3;border-radius:10px">{}{}'\
'</div>'.format(tcolor, html_root, html_parts)
return html
elif len(edge) == 2 or all(subedge.is_atom() for subedge in edge):
conn_html = _edge2html_vblocks(edge[0])
arg_htmls = ['<div style="display: table-cell;vertical-align: middle"'
'>{}</div>'.format(_edge2html_vblocks(arg))
for arg in edge[1:]]
html = '<div style="display:table;border:2px solid #fdf6e3;'\
'background-color:{};border-radius:10px;padding:3px">'\
'<div style="display:table-row">'\
'<div style="display: table-cell; vertical-align: middle;'\
'background-color:{};padding-left:5px">{}</div>'\
'<div style="display: table-cell; vertical-align: middle;'\
'background-color:{};padding:5px">'\
'<div style="display:table-row">{}</div></div>'\
'</div></div>'.format(
tcolor,
tcolor,
conn_html,
tcolor,
'<div style="width:5px"></div>'.join(arg_htmls))
return html
else:
conn_html = _edge2html_vblocks(edge[0])
arg_htmls = ['<div>{}</div>'.format(_edge2html_vblocks(arg))
for arg in edge[1:]]
html = '<div style="display:table;border:2px solid #fdf6e3;'\
'background-color:{};border-radius:10px;padding:3px">'\
'<div style="display:table-row">'\
'<div style="display: table-cell; vertical-align: top;'\
'background-color:{};padding:5px">{}</div>'\
'<div style="display: table-cell; vertical-align: top;'\
'background-color:{};padding:5px">'\
'<div style="display:table-row">{}</div></div>'\
'</div></div>'.format(
tcolor,
tcolor,
conn_html,
tcolor,
'<div style="height:5px"></div>'.join(arg_htmls))
return html
def vblocks(edge, subtypes=False, argroles=True, namespaces=False):
edge = hedge(edge)
sedge = edge.simplify(subtypes=subtypes,
argroles=argroles,
namespaces=namespaces)
html = _edge2html_vblocks(sedge)
html = '<div style="background-color:#fcfcfc; padding:50px">{}'\
'</div>'.format(html)
display(HTML(html))
def _edge2html_blocks(edge):
tcolor = TYPE_COLORS[edge.type()[0]]
if edge.is_atom():
html_root = '<span style="color:#fdf6e3;font-weight:bold">{}'\
'</span>'.format(edge.root())
parts = '/'.join(edge.parts()[1:])
html_parts = '<span style="color:#eee8d5;font-weight:lighter">/{}'\
'</span>'.format(parts)
html = '<div style="padding:5px;background-color:{};'\
'border:2px solid #fdf6e3; border-radius:10px;'\
'text-align:center">{}{}</div>'.format(
tcolor, html_root, html_parts)
return html
elif len(edge) > 2:
conn_html = _edge2html_blocks(edge[0])
arg_htmls = ['<div style="display: table-cell;vertical-align: middle">'
'{}</div>'.format(_edge2html_blocks(arg))
for arg in edge[1:]]
html = '<div style="display:table;border:2px solid #fdf6e3;'\
'background-color:{};border-radius:10px;padding:3px">'\
'<div style="display:table-row">'\
'<div style="display: table-cell; vertical-align: middle;'\
'background-color:{};padding-left:5px">{}</div>'\
'<div style="display: table-cell; vertical-align: middle;'\
'background-color:{};padding:5px">'\
'<div style="display:table-row">{}</div></div>'\
'</div></div>'.format(
tcolor,
tcolor,
conn_html,
tcolor,
'<div style="width:5px"></div>'.join(arg_htmls))
return html
else:
conn_html = _edge2html_blocks(edge[0])
arg_htmls = ['<div style="display: table-row">{}</div>'.format(
_edge2html_blocks(arg))
for arg in edge[1:]]
html = '<div style="display:table;border:2px solid #fdf6e3;'\
'background-color:{};border-radius:10px;padding:8px">'\
'<div style="display:table-row">'\
'<div style="display: table-row; vertical-align: top;'\
'background-color:{};padding:5px">{}</div>'\
'<div style="display: table-row; height:8px"></div>'\
'<div style="display: table-row; vertical-align: top;'\
'background-color:{};padding:5px">'\
'<div style="display:table">{}</div></div>'\
'</div></div>'.format(
tcolor,
tcolor,
conn_html,
tcolor,
'<div style="height:5px"></div>'.join(arg_htmls))
return html
def blocks(edge, subtypes=False, argroles=True, namespaces=False):
edge = hedge(edge)
sedge = edge.simplify(subtypes=subtypes,
argroles=argroles,
namespaces=namespaces)
html = _edge2html_blocks(sedge)
html = '<div style="background-color:#fcfcfc; padding:50px">{}'\
'</div>'.format(html)
display(HTML(html))
def interactive_case_generator(tests, extractor, case=None, keywords=None):
return InteractiveCaseGenerator(tests, extractor).run(case=case,
keywords=keywords)