python_arango_ogm.utils.md_util
1import base64 2from enum import Enum 3import json 4import textwrap 5 6from IPython.display import display, display_svg, HTML, Markdown, Latex, SVG 7from pygments import highlight 8from pygments.lexers import get_lexer_by_name 9from pygments.formatters import HtmlFormatter 10from jupyterlab_pygments import JupyterStyle 11# import qgrid 12 13from .str_util import squish_text 14 15PrettyFormats = Enum('PrettyFormats', 'json python') 16 17COL_SEP = ' | ' 18NEWLINE = "\r\n" 19CR = "\n" 20INDENT = ' ' 21 22PAD = "style='margin: 4em; padding 1em; vertical-align:top;'" 23CELL_HTML = f"<td {PAD}>%s</td>" 24ROW_HTML = f"<tr {PAD}>%s</tr>" 25TABLE_HTML = f"<table {PAD}>%s</table>" 26MIN_VISIBLE_ROWS = 8 27 28BG_HEADER = '#202B30' 29FG_HEADER = '#BBBBBB' 30 31BG_ROW = '#455A64' 32FG_ROW = '#BBBBBB' 33 34BG_ROWODD = '#769BAE' 35FG_ROWODD = '#222222' 36 37QGRID_CSS = f""" 38<style> 39 .q-grid {{ 40 background-color: {BG_HEADER}; 41 height: auto; 42 width: auto; 43 max-height: 600px; 44 }} 45 .q-grid .slick-header, .q-grid .slick-header-columns {{ 46 background-color: {BG_HEADER}; 47 }} 48 .q-grid .slick-header-column {{ 49 background-color: {BG_HEADER}; 50 color: {FG_HEADER}; 51 border-color: {FG_HEADER}; 52 }} 53 .q-grid .slick-row.odd {{ 54 background-color: {BG_ROWODD}; 55 color: {FG_ROWODD}; 56 border-color: {FG_ROWODD}; 57 }} 58 .q-grid .slick-row.even {{ 59 background-color: {BG_ROW}; 60 color: {FG_ROW}; 61 border-color: {FG_ROW}; 62 }} 63 .q-grid .slick-resizable-handle {{ 64 background-color: {BG_ROW}; 65 border-left-color: {BG_ROWODD}; 66 border-right-color: {BG_ROWODD}; 67 border-left-width: 1px; 68 border-right-width: 1px; 69 }} 70</style> 71""" 72 73def display_obj(obj): 74 display(obj) 75 76def display_html(html): 77 display_obj(HTML(html)) 78 79def render_svg(data, b64=True): 80 svg_data = str(base64.b64encode(data)) if b64 else data 81 # b64 = str(base64.b64encode(svg).decode('utf-8')) 82 display_obj(SVG(svg_data)) # , raw=raw) 83 84def init_df_grid_style(): 85 display_obj(HTML(QGRID_CSS)) 86 87def md(md_text, render=True): 88 markdown = Markdown(str(md_text)) 89 return display_obj(markdown) if render else markdown 90 91def md_code(md_code: any, syntax: str = '', escape=True, render=True, squish=False, simple=True): 92 md_txt = escape_md(md_code) if escape else str(md_code) 93 code_text = squish_text(md_txt) if squish else md_txt 94 code_text = textwrap.indent(code_text, INDENT) 95 if simple: 96 return md(f"`{code_text}`{NEWLINE}", render=render) 97 else: 98 return md(f"```{syntax}{NEWLINE}{code_text}{NEWLINE}```", render=render) 99 100def md_table(cols, vals, header=True): 101 md(table_md(cols, vals, header=header)) 102 103def md_list(rows, render=True, bullet='*', header=None): 104 bullets = [f"{bullet} {row}" for row in rows] 105 md_bullets = CR.join(bullets) 106 markdown = f"{header}{CR}{md_bullets}" if header else md_bullets 107 md(markdown, render=render) 108 109# Usage: horizontally('foo', 'bar', '`baz`') 110def horizontally(*items): 111 cells_html = ''.join([(CELL_HTML % item) for item in items]) 112 md(TABLE_HTML % (ROW_HTML % cells_html)) 113 114def vertically(*items): 115 rows_html = ''.join([(ROW_HTML % (CELL_HTML % item)) for item in items]) 116 md(TABLE_HTML % (rows_html)) 117 118# Add escape characters to string to avoid marking down: 119def escape_md(obj): 120 md = str(obj) 121 return md.replace('_', "\\_") 122 123def table_header_md(cols): 124 col_names = cols.values() if hasattr(cols, 'values') else cols 125 col_captions = [f"<th>{(col.title())}</th>" for col in col_names] 126 # md_cols = "<tr>%s</tr>" % COL_SEP.join(col_captions) 127 # md_sep = "| :--- " * len(col_names) + '|' 128 return "<tr>%s</tr>" % ''.join(col_captions) # f"{md_cols}{NEWLINE}{md_sep}" 129 130def table_body_md(cols, vals): 131 md_rows = [] 132 col_names = cols.keys() if hasattr(cols, 'keys') else cols 133 for row in vals: 134 row_vals = [f"<td>{str(row[col])}</td>" for col in col_names] 135 md_row = ''.join(row_vals) 136 md_rows.append("<tr>%s</tr>" % md_row) 137 138 return NEWLINE.join(md_rows) 139 140def table_md(cols, vals, caption=None, header=True): 141 md_rows = ['<table>'] 142 143 # if caption: md_rows.append(f"### {caption}") 144 if header: 145 md_rows.append(table_header_md(cols)) 146 147 md_rows.append(table_body_md(cols, vals)) 148 md_rows.append('</table>') 149 return NEWLINE.join(md_rows) 150 151def pretty_json(json, markdown=True): 152 return pretty(json, markdown=markdown, format=PrettyFormats.json) 153 154def pretty(code, markdown=True, format=PrettyFormats.python, render=True): 155 code_str = json.dumps(code, indent=2) if format == PrettyFormats.json else str(code) 156 formatter = HtmlFormatter(style=JupyterStyle) 157 # lexer = PythonLexer if format==PrettyFormats.PYTHON else JsonLexer 158 lexer = get_lexer_by_name("json", stripall=False) 159 html = highlight(code_str, lexer, formatter) 160 css = formatter.get_style_defs('.highlight') 161 html = f'<style>{css}</style><div class="highlight">{html}</div>' 162 return display_html(html) if markdown else html 163 164# def md_dataframe(df, heading=None, include_index: bool = False, render: bool = True, sortable: bool = False, filterable: bool = False, allrows: bool = False, plain: bool = False): 165# 166# if plain: 167# html = df.to_html(index=False) 168# if render: 169# return(HTML(html)) 170# else: 171# return html 172# else: 173# min_rows = len(df.index_name) + 2 if allrows else min(MIN_VISIBLE_ROWS, len(df.index_name) + 1) 174# widget = qgrid.show_grid(df, show_toolbar=False, grid_options=dict( 175# forceFitColumns=False, 176# syncColumnCellResize=True, 177# fullWidthRows=False, 178# minVisibleRows=min_rows, 179# sortable=sortable, 180# filterable=filterable, 181# )) 182# 183# header = f"## {heading}" if heading else None 184# if render: 185# if header: 186# md(header, render=render) 187# return(widget) 188# else: 189# return widget
class
PrettyFormats(enum.Enum):
Create a collection of name/value pairs.
Example enumeration:
>>> class Color(Enum):
... RED = 1
... BLUE = 2
... GREEN = 3
Access them by:
attribute access:
>>> Color.RED <Color.RED: 1>
value lookup:
>>> Color(1) <Color.RED: 1>
name lookup:
>>> Color['RED'] <Color.RED: 1>
Enumerations can be iterated over, and know how many members they have:
>>> len(Color)
3
>>> list(Color)
[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]
Methods can be added to enumerations, and members can have their own attributes -- see the documentation for details.
json =
<PrettyFormats.json: 1>
python =
<PrettyFormats.python: 2>
Inherited Members
- enum.Enum
- name
- value
COL_SEP =
' | '
NEWLINE =
'\r\n'
CR =
'\n'
INDENT =
' '
PAD =
"style='margin: 4em; padding 1em; vertical-align:top;'"
CELL_HTML =
"<td style='margin: 4em; padding 1em; vertical-align:top;'>%s</td>"
ROW_HTML =
"<tr style='margin: 4em; padding 1em; vertical-align:top;'>%s</tr>"
TABLE_HTML =
"<table style='margin: 4em; padding 1em; vertical-align:top;'>%s</table>"
MIN_VISIBLE_ROWS =
8
BG_HEADER =
'#202B30'
FG_HEADER =
'#BBBBBB'
BG_ROW =
'#455A64'
FG_ROW =
'#BBBBBB'
BG_ROWODD =
'#769BAE'
FG_ROWODD =
'#222222'
QGRID_CSS =
'\n<style>\n .q-grid {\n background-color: #202B30;\n height: auto;\n width: auto;\n max-height: 600px;\n }\n .q-grid .slick-header, .q-grid .slick-header-columns {\n background-color: #202B30;\n }\n .q-grid .slick-header-column {\n background-color: #202B30;\n color: #BBBBBB;\n border-color: #BBBBBB;\n }\n .q-grid .slick-row.odd {\n background-color: #769BAE;\n color: #222222;\n border-color: #222222;\n }\n .q-grid .slick-row.even {\n background-color: #455A64;\n color: #BBBBBB;\n border-color: #BBBBBB;\n }\n .q-grid .slick-resizable-handle {\n background-color: #455A64;\n border-left-color: #769BAE;\n border-right-color: #769BAE;\n border-left-width: 1px;\n border-right-width: 1px;\n }\n</style>\n'
def
display_obj(obj):
def
display_html(html):
def
render_svg(data, b64=True):
def
init_df_grid_style():
def
md(md_text, render=True):
def
md_code( md_code: <built-in function any>, syntax: str = '', escape=True, render=True, squish=False, simple=True):
92def md_code(md_code: any, syntax: str = '', escape=True, render=True, squish=False, simple=True): 93 md_txt = escape_md(md_code) if escape else str(md_code) 94 code_text = squish_text(md_txt) if squish else md_txt 95 code_text = textwrap.indent(code_text, INDENT) 96 if simple: 97 return md(f"`{code_text}`{NEWLINE}", render=render) 98 else: 99 return md(f"```{syntax}{NEWLINE}{code_text}{NEWLINE}```", render=render)
def
md_table(cols, vals, header=True):
def
md_list(rows, render=True, bullet='*', header=None):
def
horizontally(*items):
def
vertically(*items):
def
escape_md(obj):
def
table_header_md(cols):
124def table_header_md(cols): 125 col_names = cols.values() if hasattr(cols, 'values') else cols 126 col_captions = [f"<th>{(col.title())}</th>" for col in col_names] 127 # md_cols = "<tr>%s</tr>" % COL_SEP.join(col_captions) 128 # md_sep = "| :--- " * len(col_names) + '|' 129 return "<tr>%s</tr>" % ''.join(col_captions) # f"{md_cols}{NEWLINE}{md_sep}"
def
table_body_md(cols, vals):
131def table_body_md(cols, vals): 132 md_rows = [] 133 col_names = cols.keys() if hasattr(cols, 'keys') else cols 134 for row in vals: 135 row_vals = [f"<td>{str(row[col])}</td>" for col in col_names] 136 md_row = ''.join(row_vals) 137 md_rows.append("<tr>%s</tr>" % md_row) 138 139 return NEWLINE.join(md_rows)
def
table_md(cols, vals, caption=None, header=True):
141def table_md(cols, vals, caption=None, header=True): 142 md_rows = ['<table>'] 143 144 # if caption: md_rows.append(f"### {caption}") 145 if header: 146 md_rows.append(table_header_md(cols)) 147 148 md_rows.append(table_body_md(cols, vals)) 149 md_rows.append('</table>') 150 return NEWLINE.join(md_rows)
def
pretty_json(json, markdown=True):
155def pretty(code, markdown=True, format=PrettyFormats.python, render=True): 156 code_str = json.dumps(code, indent=2) if format == PrettyFormats.json else str(code) 157 formatter = HtmlFormatter(style=JupyterStyle) 158 # lexer = PythonLexer if format==PrettyFormats.PYTHON else JsonLexer 159 lexer = get_lexer_by_name("json", stripall=False) 160 html = highlight(code_str, lexer, formatter) 161 css = formatter.get_style_defs('.highlight') 162 html = f'<style>{css}</style><div class="highlight">{html}</div>' 163 return display_html(html) if markdown else html