fontcase 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fontcase/__init__.py +11 -0
- fontcase/catalog.py +70 -0
- fontcase/cli.py +39 -0
- fontcase/data/catalog.json +1502 -0
- fontcase-0.1.0.dist-info/METADATA +57 -0
- fontcase-0.1.0.dist-info/RECORD +9 -0
- fontcase-0.1.0.dist-info/WHEEL +4 -0
- fontcase-0.1.0.dist-info/entry_points.txt +2 -0
- fontcase-0.1.0.dist-info/licenses/LICENSE +5 -0
fontcase/__init__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""fontcase: catálogo offline de fontes do Google Fonts."""
|
|
2
|
+
from .catalog import (
|
|
3
|
+
all_fonts, categories, by_category, get, search,
|
|
4
|
+
css_url, css_import, css_font_family, random_font,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.0"
|
|
8
|
+
__all__ = [
|
|
9
|
+
"all_fonts", "categories", "by_category", "get", "search",
|
|
10
|
+
"css_url", "css_import", "css_font_family", "random_font",
|
|
11
|
+
]
|
fontcase/catalog.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import json, random
|
|
3
|
+
from functools import lru_cache
|
|
4
|
+
from importlib import resources
|
|
5
|
+
from typing import Dict, List, Optional
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@lru_cache(maxsize=1)
|
|
9
|
+
def all_fonts() -> List[Dict]:
|
|
10
|
+
"""Retorna todas as fontes do catálogo."""
|
|
11
|
+
text = resources.files("fontcase").joinpath("data/catalog.json").read_text(encoding="utf-8")
|
|
12
|
+
return json.loads(text)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def categories() -> List[str]:
|
|
16
|
+
"""Lista de categorias, em ordem alfabética."""
|
|
17
|
+
return sorted({f["category"] for f in all_fonts()})
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def by_category(category: str) -> List[Dict]:
|
|
21
|
+
"""Fontes de uma categoria."""
|
|
22
|
+
return [f for f in all_fonts() if f["category"] == category]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get(family: str) -> Optional[Dict]:
|
|
26
|
+
"""Busca uma fonte pelo nome exato (sem diferenciar maiúsculas)."""
|
|
27
|
+
fam = family.strip().lower()
|
|
28
|
+
for f in all_fonts():
|
|
29
|
+
if f["family"].lower() == fam or f["slug"] == fam:
|
|
30
|
+
return f
|
|
31
|
+
return None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def search(query: str = "", category: Optional[str] = None) -> List[Dict]:
|
|
35
|
+
"""Busca por trecho do nome, com filtro opcional de categoria."""
|
|
36
|
+
q = query.strip().lower()
|
|
37
|
+
return [
|
|
38
|
+
f for f in all_fonts()
|
|
39
|
+
if q in f["family"].lower() and (category is None or f["category"] == category)
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _need(family: str) -> Dict:
|
|
44
|
+
font = get(family)
|
|
45
|
+
if font is None:
|
|
46
|
+
raise KeyError(f"Fonte não encontrada: {family!r}")
|
|
47
|
+
return font
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def css_url(family: str) -> str:
|
|
51
|
+
"""URL do CSS do Google Fonts."""
|
|
52
|
+
return _need(family)["css"]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def css_import(family: str) -> str:
|
|
56
|
+
"""Linha @import pronta para colar em um CSS."""
|
|
57
|
+
return f"@import url('{css_url(family)}');"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def css_font_family(family: str) -> str:
|
|
61
|
+
"""Valor para a propriedade font-family."""
|
|
62
|
+
return _need(family)["css_stack"]
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def random_font(category: Optional[str] = None) -> Dict:
|
|
66
|
+
"""Uma fonte aleatória, opcionalmente dentro de uma categoria."""
|
|
67
|
+
pool = by_category(category) if category else all_fonts()
|
|
68
|
+
if not pool:
|
|
69
|
+
raise ValueError(f"Categoria sem fontes: {category!r}")
|
|
70
|
+
return random.choice(pool)
|
fontcase/cli.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from . import catalog
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def main(argv=None) -> int:
|
|
6
|
+
p = argparse.ArgumentParser(prog="fontcase", description="Catálogo de fontes")
|
|
7
|
+
sub = p.add_subparsers(dest="cmd", required=True)
|
|
8
|
+
sub.add_parser("categories", help="lista categorias")
|
|
9
|
+
s = sub.add_parser("search", help="busca fontes")
|
|
10
|
+
s.add_argument("query", nargs="?", default="")
|
|
11
|
+
s.add_argument("-c", "--category")
|
|
12
|
+
sh = sub.add_parser("show", help="mostra detalhes e CSS de uma fonte")
|
|
13
|
+
sh.add_argument("family")
|
|
14
|
+
r = sub.add_parser("random", help="fonte aleatória")
|
|
15
|
+
r.add_argument("-c", "--category")
|
|
16
|
+
a = p.parse_args(argv)
|
|
17
|
+
|
|
18
|
+
if a.cmd == "categories":
|
|
19
|
+
for c in catalog.categories():
|
|
20
|
+
print(c)
|
|
21
|
+
elif a.cmd == "search":
|
|
22
|
+
for f in catalog.search(a.query, a.category):
|
|
23
|
+
print(f"{f['family']} [{f['category']}]")
|
|
24
|
+
elif a.cmd == "show":
|
|
25
|
+
f = catalog.get(a.family)
|
|
26
|
+
if not f:
|
|
27
|
+
print("Fonte não encontrada")
|
|
28
|
+
return 1
|
|
29
|
+
print(f"{f['family']} ({f['category']})\n{f['page']}\n")
|
|
30
|
+
print(catalog.css_import(a.family))
|
|
31
|
+
print(f"font-family: {f['css_stack']};")
|
|
32
|
+
elif a.cmd == "random":
|
|
33
|
+
f = catalog.random_font(a.category)
|
|
34
|
+
print(f"{f['family']} [{f['category']}]")
|
|
35
|
+
return 0
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
raise SystemExit(main())
|