Fontbakery: Render Markdown on the text terminal output

Created on 21 Jun 2019  Â·  12Comments  Â·  Source: googlefonts/fontbakery

it would be nice to use Markdown syntax for everything and then render it into something more beautiful than what we get now in cases like this:

Captura de Tela 2019-06-21 às 14 50 13

P3 Soon

Most helpful comment

screenshot-md-example

All 12 comments

For the specific case of rendering tables, we could use box-drawing characteres as was often used on MS-DOS programs like this:
68747470733a2f2f63646e2e7261776769742e636f6d2f70696f74726d75726163682f7474792d626f782f6d61737465722f6173736574732f7474792d626f782d64726177696e672e706e67

Maybe with some python code equivalent to this:
https://github.com/piotrmurach/tty-box

+1 for fontbakery reminding me of Rogue

I took some free time this weekend to experiment with this funny idea. I got the following markdown table from our hinting_impact check and drafted some python routines to render them as ascii-art tables:

|  | Foo-Regular.ttf |
|:--- | ---:|
| Dehinted Size | 12.1kb |
| Hinted Size | 21.8kb |
| Increase | 9.8kb |
| Change   | 81.0 % |

| | Foo-Regular.ttf |
|:--- | ---:|
| Dehinted Size | 12.1kb |
| Hinted Size | 21.8kb |
| Increase | 9.8kb |
| Change | 81.0 % |

Screenshot at 2019-06-23 12:22:33

How do you access this hinting impact check Felipe?

@aurium, here's the issue describing the markdown table parsing/rendering task

I'll look for the table drawing routines in my hard-drive and post them here soon

here's an early prototype. Feel free to reuse this code in a pull request:

def hinting_impact(font, ttfautohint_stats):
  """Show hinting filesize impact.

     Current implementation simply logs useful info
     but there's no fail scenario for this checker."""

  hinted = ttfautohint_stats["hinted_size"]
  dehinted = ttfautohint_stats["dehinted_size"]
  increase = hinted - dehinted
  change = (float(hinted)/dehinted - 1) * 100

  def filesize_formatting(s):
    if s < 1024:
      return f"{s} bytes"
    elif s < 1024*1024:
      return "{:.1f}kb".format(s/1024)
    else:
      return "{:.1f}Mb".format(s/(1024*1024))

  hinted_size = filesize_formatting(hinted)
  dehinted_size = filesize_formatting(dehinted)
  increase = filesize_formatting(increase)

  results_table = "Hinting filesize impact:\n\n"
  results_table += f"|  | {font} |\n"
  results_table += "|:--- | ---:|\n"
  results_table += f"| Dehinted Size | {dehinted_size} |\n"
  results_table += f"| Hinted Size | {hinted_size} |\n"
  results_table += f"| Increase | {increase} |\n"
  results_table += f"| Change   | {change:.1f} % |\n"
  return results_table



def add_border(buf, width, height):
  #top border
  newbuf = u"\u2554" + (width-2)*u"\u2550" + u"\u2557\n"

  #content
  for line in buf.split('\n'):
    newbuf += u"\u2551" + line + " "*max(0, width - len(line) - 2) + u"\u2551\n"

  #whitespace
  for i in range(max(0, height - len(buf.split('\n')) -2)):
    newbuf += u"\u2551" + " "*(width-2) + u"\u2551\n"

  #bottom border
  newbuf += u"\u255A" + (width-2)*u"\u2550" + u"\u255D\n"

  return newbuf

def padded(widths, cells):
  padded_cells = []
  for i, cell in enumerate(cells):
    padded_cells.append(cell + " "*max(0, widths[i]-len(cell)))
  return padded_cells


def render_table(lines):
  table = []
  widths = []
  for line in lines:
    cells = line.split("|")
    cells.pop(0)
    cells.pop(-1)
    table.append(cells)
    for i, cell in enumerate(cells):
      if i >= len(widths):
        widths.append(len(cell))
      else:
        widths[i] = max(widths[i], len(cell))

  # compute total table width:
  width = len(widths) + 1
  for w in widths:
   width += w

  #top border
  newbuf = u"\u2554" + u"\u2564".join([w*u"\u2550" for w in widths]) + u"\u2557\n"

  #header
  newbuf += u"\u2551" + u"\u2502".join(padded(widths, table[0])) + u"\u2551\n"

  #header separator
  newbuf += u"\u255F" + u"\u253C".join([w*u"\u2500" for w in widths]) + u"\u2562\n"

  #table body
  for i in range(2,len(table)):
    newbuf += u"\u2551" + u"\u2502".join(padded(widths, table[i])) + u"\u2551\n"

  #bottom border
  newbuf += u"\u255A" + u"\u2567".join([w*u"\u2550" for w in widths]) + u"\u255D\n"

  return newbuf

def render_markdown(buf):
  new_buf=""
  table_lines = []
  for line in buf.split('\n'):
    if '|' in line:
      table_lines.append(line)
    else:
      if table_lines:
        new_buf += render_table(table_lines)
        table_lines = []
      new_buf += line + "\n"
  return new_buf

stats = {
  'hinted_size': 22345,
  'dehinted_size': 12345,
}

input_str = hinting_impact("Foo-Regular.ttf", stats)
output = render_markdown(input_str)

print (input_str)

print (add_border(output, 80, 20))

Hi folks,

I'm working on this, and i think makes sense to parse status messages as MD and rich.markdown will help a lot. Unluckily that lib does not recognizes MD tables.

I just make a MD Table parser to work with rich and The table itself can be printed with rich.table. I have my beliefs about how a table must to be printed on a console. I'm against borders and horizontal lines that will only steal space. We can understand the table using zebra background and a special bg to headers.

However, I will be happy to know what kind of vertical separator you prefer.

I'm putting 3 options below and you can vote with :+1: or :-1: emoji reaction on the comment top-right corner.

_(Hey, sure, you can comment against my beliefs if you disagree. I'm open to listen.)_

No explicit separator (there is enough margin)
table-no-sep

Light separator
table-light-sep

Hard (or bold) separator
table-hard-sep

screenshot-md-example

Was this page helpful?
0 / 5 - 0 ratings