[cheatsheet] Splitted into sections, added navigation

This commit is contained in:
Robert Bendun 2022-09-21 19:32:31 +02:00
parent e7ec8229e1
commit 9a978d8984
3 changed files with 125 additions and 53 deletions

View File

@ -21,6 +21,8 @@ END INTRO
BEGIN TABLE BEGIN TABLE
SECTION Podstawy
n Kategoria n Kategoria
m Musique m Musique
p Python p Python
@ -63,6 +65,36 @@ r return x + y
r end r end
c Musique nie rozróżnia funkcji anonimowych i zadeklarowanych c Musique nie rozróżnia funkcji anonimowych i zadeklarowanych
n Instrukcja warunkowa
m if (n == 42)
m [ say 1 ]
m [ say 2 ]
p if n == 42:
p print(1)
p else:
p print(2)
r if n == 42
r puts 1
r else
r puts 2
r end
c Musique nie posiada instrukcji warunkowej, a funkcję if,
c która przyjmuje wartość logiczną i dwa bloki (funkcje anonimowe)
c - jeden z nich zostanie wykonany jeśli warunek jest prawdziwy,
c a drugi jeśli jest fałszywy.
n Wyrażenie warunkowe
m x := if (n == 42) [1] [2]
p x = 1 if n == 42 else 2
r x = n == 42 ? 1 : 2
SECTION Tablice
n Kategoria
m Musique
p Python
r Ruby (SonicPi)
c Komentarz
n Tablice n Tablice
m x = [1; 2; 3; 4] m x = [1; 2; 3; 4]
p x = [1, 2, 3, 4] p x = [1, 2, 3, 4]
@ -104,25 +136,30 @@ r [*1..5].inject(:*)
c Musique pozwala zmienić dowolny operator w funkcję c Musique pozwala zmienić dowolny operator w funkcję
c poprzez zapis 'operator jak '* w przykładzie c poprzez zapis 'operator jak '* w przykładzie
n Instrukcja warunkowa n Iteracja po elementach tablicy
m if (n == 42) m for (up 5) [ i | say i ]
m [ say 1 ] p for i in range(5):
m [ say 2 ] p print(i)
p if n == 42: r (0..4).each do |i|
p print(1) r puts i
p else:
p print(2)
r if n == 42
r puts 1
r else
r puts 2
r end r end
c Musique nie posiada instrukcji warunkowej, a funkcję if, c Podobnie jak w przypadku instrukcji warunkowej, Musique używa funkcji.
c która przyjmuje wartość logiczną i dwa bloki (funkcje anonimowe)
c - jeden z nich zostanie wykonany jeśli warunek jest prawdziwy, n Sortowanie tablicy
c a drugi jeśli jest fałszywy. m xs := sort [1; 5; 3; 3; 2]
n Wyrażenie warunkowe p xs = sorted([1, 5, 3, 3, 2])
m x := if (n == 42) [1] [2] r xs = [1, 5, 3, 3, 2].sort
p x = 1 if n == 42 else 2
r x = n == 42 ? 1 : 2
n Sortowanie wielu tablic w jedną
m xs := sort [1; 5; 3; 3; 2]
m [3; 4; 5] 1 2 3
p xs = sorted(itertools.chain(
p [1, 5, 3, 3, 2], [3, 4, 5],
p [1], [2], [3]
p ))
c Wiele operacji na tablicach może być wykonywane na dowolnej kombinacji
c tablic i pojedyńczych wartości. Tworzy to jedną tablicę wykoniową.
END TABLE END TABLE

3
scripts/code-size.sh Executable file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
cloc src/*.cc include/*.hh lib/midi/include lib/midi/src

View File

@ -1,9 +1,20 @@
import argparse import argparse
import os import os
import string import string
import collections import dataclasses
Directive = collections.namedtuple("Directive", "line_number type content") @dataclasses.dataclass
class Section:
name: str
rows: list = dataclasses.field(default_factory=lambda: [{}])
order: list = dataclasses.field(default_factory=list)
ref: str = ""
@dataclasses.dataclass
class Directive:
line_number: int
type: str
content: str
HTML_TEMPLATE = string.Template("""<!DOCTYPE html> HTML_TEMPLATE = string.Template("""<!DOCTYPE html>
<html> <html>
@ -14,15 +25,16 @@ HTML_TEMPLATE = string.Template("""<!DOCTYPE html>
</head> </head>
<body> <body>
<p>$intro</p> <p>$intro</p>
<table> $table </table> <nav> <ol> $nav </ol> </nav>
<section> $body </section>
</body> </body>
</html> </html>
""") """)
def parse_table(lines: list): def parse_table(lines: list[str]) -> list[Section]:
previus_column_type = None previus_column_type = None
rows, order = [{}], [] sections = []
current_row = rows[0] current_section = None
# Each nonblank matches this regular expression /(\S*)\s(.*)/ # Each nonblank matches this regular expression /(\S*)\s(.*)/
# where first capture is type of column (essentialy column id) and # where first capture is type of column (essentialy column id) and
@ -35,27 +47,34 @@ def parse_table(lines: list):
sep = line.find(' ') sep = line.find(' ')
column_type, cell_content = line[:sep].strip(), line[sep:] column_type, cell_content = line[:sep].strip(), line[sep:]
if column_type not in order: if column_type == "SECTION":
order.append(column_type) sections.append(Section(name=cell_content))
current_section = sections[-1]
continue
if previus_column_type != column_type and column_type in current_row: assert current_section is not None, "Define SECTION before table entries"
rows.append({})
current_row = rows[-1]
cell = current_row.get(column_type, []) if column_type not in current_section.order:
current_section.order.append(column_type)
if previus_column_type != column_type and column_type in current_section.rows[-1]:
current_section.rows.append({})
cell = current_section.rows[-1].get(column_type, [])
cell.append(cell_content) cell.append(cell_content)
current_row[column_type] = cell current_section.rows[-1][column_type] = cell
previus_column_type = column_type previus_column_type = column_type
# Eliminate common whitespace prefix in given column type (not all whitespace # Eliminate common whitespace prefix in given column type (not all whitespace
# prefix since examples in Python may have significant whitespace) # prefix since examples in Python may have significant whitespace)
for row in rows: for section in sections:
for row in section.rows:
for cell in row.values(): for cell in row.values():
prefix_whitespace = min(len(s) - len(s.lstrip()) for s in cell) prefix_whitespace = min(len(s) - len(s.lstrip()) for s in cell)
for i, s in enumerate(cell): for i, s in enumerate(cell):
cell[i] = s[prefix_whitespace:] cell[i] = s[prefix_whitespace:]
return rows, order return sections
def compile_template(*, template_path: str, target_path: str): def compile_template(*, template_path: str, target_path: str):
# Read template file and separate it into lines # Read template file and separate it into lines
@ -98,27 +117,40 @@ def compile_template(*, template_path: str, target_path: str):
assert intro_source is not None assert intro_source is not None
assert title is not None assert title is not None
rows, columns_order = parse_table(lines=table_source) sections = parse_table(lines=table_source)
table = "" for section in sections:
section.ref = section.name.replace(" ", "_")
for i, row in enumerate(rows): nav = ""
for section in sections:
nav += f"<li><a href=\"#{section.ref}\">{section.name}</a></li>"
body = ""
for section in sections:
table = f"<p><h2 id=\"{section.ref}\">{section.name}</h2><table>\n"
for i, row in enumerate(section.rows):
if i == 0: if i == 0:
line = ["<th>" + ' '.join(row[k]) + "</th>" for k in columns_order] line = ["<th>" + ' '.join(row[k]) + "</th>" for k in section.order]
else: else:
line = [] line = []
for column in columns_order: for column in section.order:
val = row.get(column, []) val = row.get(column, [])
line.append('<td><pre><code>' + '<br/>'.join(val) + '</code></pre></td>') line.append('<td><pre><code>' + '<br/>'.join(val) + '</code></pre></td>')
table += "<tr>\n" + '\n'.join(line) + "\n</tr>\n" table += "<tr>\n" + '\n'.join(line) + "\n</tr>\n"
table += "\n</table></p>\n"
body += table
final = HTML_TEMPLATE.substitute({ final = HTML_TEMPLATE.substitute({
"title": title, "body": body,
"css": "\n".join(css_source), "css": "\n".join(css_source),
"table": table, "intro": "\n".join(intro_source),
"intro": "\n".join(intro_source) "nav": nav,
"title": title,
}) })
with open(target_path, "w") as f: with open(target_path, "w") as f: