[cheatsheet] Splitted into sections, added navigation
This commit is contained in:
parent
e7ec8229e1
commit
9a978d8984
@ -21,6 +21,8 @@ END INTRO
|
||||
|
||||
BEGIN TABLE
|
||||
|
||||
SECTION Podstawy
|
||||
|
||||
n Kategoria
|
||||
m Musique
|
||||
p Python
|
||||
@ -63,6 +65,36 @@ r return x + y
|
||||
r end
|
||||
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
|
||||
m 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 poprzez zapis 'operator jak '* w przykładzie
|
||||
|
||||
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
|
||||
n Iteracja po elementach tablicy
|
||||
m for (up 5) [ i | say i ]
|
||||
p for i in range(5):
|
||||
p print(i)
|
||||
r (0..4).each do |i|
|
||||
r puts i
|
||||
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
|
||||
c Podobnie jak w przypadku instrukcji warunkowej, Musique używa funkcji.
|
||||
|
||||
n Sortowanie tablicy
|
||||
m xs := sort [1; 5; 3; 3; 2]
|
||||
p xs = sorted([1, 5, 3, 3, 2])
|
||||
r xs = [1, 5, 3, 3, 2].sort
|
||||
|
||||
|
||||
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
|
||||
|
3
scripts/code-size.sh
Executable file
3
scripts/code-size.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
cloc src/*.cc include/*.hh lib/midi/include lib/midi/src
|
@ -1,9 +1,20 @@
|
||||
import argparse
|
||||
import os
|
||||
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>
|
||||
@ -14,15 +25,16 @@ HTML_TEMPLATE = string.Template("""<!DOCTYPE html>
|
||||
</head>
|
||||
<body>
|
||||
<p>$intro</p>
|
||||
<table> $table </table>
|
||||
<nav> <ol> $nav </ol> </nav>
|
||||
<section> $body </section>
|
||||
</body>
|
||||
</html>
|
||||
""")
|
||||
|
||||
def parse_table(lines: list):
|
||||
def parse_table(lines: list[str]) -> list[Section]:
|
||||
previus_column_type = None
|
||||
rows, order = [{}], []
|
||||
current_row = rows[0]
|
||||
sections = []
|
||||
current_section = None
|
||||
|
||||
# Each nonblank matches this regular expression /(\S*)\s(.*)/
|
||||
# where first capture is type of column (essentialy column id) and
|
||||
@ -35,27 +47,34 @@ def parse_table(lines: list):
|
||||
sep = line.find(' ')
|
||||
column_type, cell_content = line[:sep].strip(), line[sep:]
|
||||
|
||||
if column_type not in order:
|
||||
order.append(column_type)
|
||||
if column_type == "SECTION":
|
||||
sections.append(Section(name=cell_content))
|
||||
current_section = sections[-1]
|
||||
continue
|
||||
|
||||
if previus_column_type != column_type and column_type in current_row:
|
||||
rows.append({})
|
||||
current_row = rows[-1]
|
||||
assert current_section is not None, "Define SECTION before table entries"
|
||||
|
||||
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)
|
||||
current_row[column_type] = cell
|
||||
current_section.rows[-1][column_type] = cell
|
||||
previus_column_type = column_type
|
||||
|
||||
# Eliminate common whitespace prefix in given column type (not all whitespace
|
||||
# prefix since examples in Python may have significant whitespace)
|
||||
for row in rows:
|
||||
for cell in row.values():
|
||||
prefix_whitespace = min(len(s) - len(s.lstrip()) for s in cell)
|
||||
for i, s in enumerate(cell):
|
||||
cell[i] = s[prefix_whitespace:]
|
||||
for section in sections:
|
||||
for row in section.rows:
|
||||
for cell in row.values():
|
||||
prefix_whitespace = min(len(s) - len(s.lstrip()) for s in cell)
|
||||
for i, s in enumerate(cell):
|
||||
cell[i] = s[prefix_whitespace:]
|
||||
|
||||
return rows, order
|
||||
return sections
|
||||
|
||||
def compile_template(*, template_path: str, target_path: str):
|
||||
# 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 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):
|
||||
if i == 0:
|
||||
line = ["<th>" + ' '.join(row[k]) + "</th>" for k in columns_order]
|
||||
else:
|
||||
line = []
|
||||
for column in columns_order:
|
||||
val = row.get(column, [])
|
||||
line.append('<td><pre><code>' + '<br/>'.join(val) + '</code></pre></td>')
|
||||
nav = ""
|
||||
for section in sections:
|
||||
nav += f"<li><a href=\"#{section.ref}\">{section.name}</a></li>"
|
||||
|
||||
table += "<tr>\n" + '\n'.join(line) + "\n</tr>\n"
|
||||
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:
|
||||
line = ["<th>" + ' '.join(row[k]) + "</th>" for k in section.order]
|
||||
else:
|
||||
line = []
|
||||
for column in section.order:
|
||||
val = row.get(column, [])
|
||||
line.append('<td><pre><code>' + '<br/>'.join(val) + '</code></pre></td>')
|
||||
|
||||
table += "<tr>\n" + '\n'.join(line) + "\n</tr>\n"
|
||||
|
||||
table += "\n</table></p>\n"
|
||||
body += table
|
||||
|
||||
|
||||
final = HTML_TEMPLATE.substitute({
|
||||
"title": title,
|
||||
"body": body,
|
||||
"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:
|
||||
|
Loading…
Reference in New Issue
Block a user