Skip to content

TexnoMagic Cookbook

A quick introduction to TexnoMagic Python module and CLI using examples.

Where to put your Alphabets

Even though you can work with Alphabets at any location, it's convenient to put them into expected paths where TexnoMagic looks by default.

You can view alphabets paths using CLI:

texnomagic paths
user alphabets: /home/runner/.local/share/WordsOfPower/user/alphabets (exists)
mods alphabets: /home/runner/.local/share/WordsOfPower/mods/alphabets (doesn't 
exist)

It's recommended to use the user path for your Alphabets.

You can create and list user alphabets dir using CLI:

texnomagic paths --abcs user --mkdir
/home/runner/.local/share/WordsOfPower/user/alphabets

Or open the dir using system file explorer:

texnomagic paths -a user -o

Get an Alphabet (TexnoLatin)

We'll be working with TexnoLatin reference Alphabet in all the examples and it's used for TexnoMagic testing as well.

Here's some bash to clone latest TexnoLatin into expected user path:

cd $(texnomagic paths --abcs user --mkdir)
git clone https://github.com/texnoforge/texnolatin/

Ensure the Alphabet is visible:

texnomagic abc list
# 1 user alphabets @ /home/runner/.local/share/WordsOfPower/user/alphabets
TexnoLatin: 24 symbols

Load Alphabet

It's recommended to access individual Symbols and Drawings (data) through TexnoMagicAlphabet class.

Load Alphabet from standard paths

All further examples use get_alphabet_or_fail helper function to quickly get TexnoMagicAlphabet instance from standard paths by name like this:

from texnomagic.cli_common import get_alphabet_or_fail

abc = get_alphabet_or_fail("texnolatin")

print(abc)
TexnoLatin: 24 symbols

get_alphabet_or_fail is a convenience wrapper which auto-loads the Alphabet or prints a pretty error message and exists when Alphabet isn't found.

See texnomagic/cli_common.py for details and inspiration.

Load Alphabet from current dir

You can use get_alphabet_or_fail without path argument to look for an Alphabet in current directory and its parents:

from texnomagic.cli_common import get_alphabet_or_fail

abc = get_alphabet_or_fail()

Or you can use find_alphabet_at_path directly to search any path:

from pathlib import Path
from texnomagic.abc import find_alphabet_at_path

abc_path = Path('alphabets/texnolatin/symbols/fire')
abc = find_alphabet_at_path(abc_path)
abc.load()

print(abc)
TexnoLatin: 24 symbols

Load Alphabet from any path

You can load Alphabet directly by passing its path to TexnoMagicAlphabet and calling load method:

from pathlib import Path
from texnomagic.abc import TexnoMagicAlphabet

abc_path = Path('alphabets/texnolatin')
abc = TexnoMagicAlphabet(path=abc_path)
abc.load()

print(abc)
TexnoLatin: 24 symbols

List Symbols from Alphabet

CLI:

texnomagic symbol list texnolatin
# 24 symbols @ 
/home/runner/.local/share/WordsOfPower/user/alphabets/texnolatin/symbols
ignis (fire): SVG image, 29 drawings, GMM model (n_gauss: 8, score_avg: -12.9)
gelu (ice): SVG image, 29 drawings, GMM model (n_gauss: 9, score_avg: -12.7)
aqua (water): SVG image, 24 drawings, GMM model (n_gauss: 12, score_avg: -11.6)
aer (air): SVG image, 48 drawings, GMM model (n_gauss: 10, score_avg: -12.3)
fulgur (electro): SVG image, 39 drawings, GMM model (n_gauss: 5, score_avg: 
-12.3)
terra (earth): SVG image, 27 drawings, GMM model (n_gauss: 4, score_avg: -12.2)
vita (life): SVG image, 37 drawings, GMM model (n_gauss: 4, score_avg: -12.4)
mors (death): SVG image, 28 drawings, GMM model (n_gauss: 4, score_avg: -12.5)
sagitta (bolt): SVG image, 39 drawings, GMM model (n_gauss: 2, score_avg: -11.9)
sphaera (ball): SVG image, 34 drawings, GMM model (n_gauss: 8, score_avg: -11.7)
spatium (space): SVG image, 30 drawings, GMM model (n_gauss: 16, score_avg: 
-12.3)
conus (cone): SVG image, 29 drawings, GMM model (n_gauss: 5, score_avg: -12.2)
torrens (beam): SVG image, 22 drawings, GMM model (n_gauss: 8, score_avg: -11.7)
ego (self): SVG image, 29 drawings, GMM model (n_gauss: 14, score_avg: -12.5)
amica (friend): SVG image, 42 drawings, GMM model (n_gauss: 7, score_avg: -12.5)
hostis (enemy): SVG image, 38 drawings, GMM model (n_gauss: 7, score_avg: -12.6)
prope (close): SVG image, 27 drawings, GMM model (n_gauss: 2, score_avg: -12.0)
procul (far): SVG image, 45 drawings, GMM model (n_gauss: 2, score_avg: -12.0)
fortis (strong): SVG image, 31 drawings, GMM model (n_gauss: 8, score_avg: 
-12.3)
infirmus (weak): SVG image, 25 drawings, GMM model (n_gauss: 8, score_avg: 
-12.2)
magnus (big): SVG image, 39 drawings, GMM model (n_gauss: 3, score_avg: -12.6)
parvus (small): SVG image, 32 drawings, GMM model (n_gauss: 3, score_avg: -12.7)
celer (fast): SVG image, 31 drawings, GMM model (n_gauss: 6, score_avg: -12.8)
tardus (slow): SVG image, 35 drawings, GMM model (n_gauss: 6, score_avg: -12.5)

Python:

from texnomagic.cli_common import get_alphabet_or_fail

abc = get_alphabet_or_fail("texnolatin")
for symbol in abc.symbols:
    print(symbol)
ignis (fire)
gelu (ice)
aqua (water)
aer (air)
fulgur (electro)
terra (earth)
vita (life)
mors (death)
sagitta (bolt)
sphaera (ball)
spatium (space)
conus (cone)
torrens (beam)
ego (self)
amica (friend)
hostis (enemy)
prope (close)
procul (far)
fortis (strong)
infirmus (weak)
magnus (big)
parvus (small)
celer (fast)
tardus (slow)

List Drawings of Symbol

Use ALPHABET:SYMBOL syntax to select a specific Symbol.

CLI:

texnomagic drawing list texnolatin/fire
fire_1709239728798.csv: 227 points, 1 curves, 8 kB
fire_1709588014524.csv: 110 points, 1 curves, 4 kB
fire_1709501601465.csv: 92 points, 1 curves, 4 kB
fire_1709332562598.csv: 711 points, 1 curves, 26 kB
fire_1710079121173.csv: 466 points, 4 curves, 17 kB
fire_1709229817510.csv: 115 points, 1 curves, 5 kB
fire_1709471244496.csv: 105 points, 1 curves, 4 kB
fire_1709229788382.csv: 135 points, 1 curves, 5 kB
fire_1709332548305.csv: 480 points, 1 curves, 18 kB
fire_1709478169231.csv: 132 points, 1 curves, 5 kB
fire_1709416663416.csv: 127 points, 1 curves, 5 kB
fire_1709501625734.csv: 201 points, 1 curves, 8 kB
fire_1709332604781.csv: 432 points, 1 curves, 16 kB
fire_1709416630930.csv: 113 points, 1 curves, 4 kB
fire_1709538199887.csv: 211 points, 1 curves, 8 kB
fire_1709416667312.csv: 115 points, 1 curves, 4 kB
fire_1709501509004.csv: 110 points, 1 curves, 4 kB
fire_1709229865605.csv: 98 points, 1 curves, 4 kB
fire_1709571045075.csv: 62 points, 1 curves, 3 kB
fire_1709231416786.csv: 51 points, 1 curves, 2 kB
fire_1709571040678.csv: 64 points, 1 curves, 3 kB
fire_1710023927370.csv: 104 points, 1 curves, 4 kB
fire_1710079109175.csv: 512 points, 2 curves, 19 kB
fire_1709332540122.csv: 698 points, 1 curves, 25 kB
fire_1709231398891.csv: 55 points, 1 curves, 2 kB
fire_1709416639519.csv: 125 points, 1 curves, 5 kB
fire_1709538240512.csv: 148 points, 1 curves, 6 kB
fire_1709321796565.csv: 242 points, 1 curves, 9 kB
fire_1709334725070.csv: 443 points, 1 curves, 16 kB

average: 223.6 points, 1.1 curves, 7 kB

total: 6484.0 points, 33.0 curves, 227 kB, 29 drawings

Python:

from texnomagic.cli_common import get_alphabet_or_fail

abc = get_alphabet_or_fail("texnolatin")
symbol = abc.get_symbol("fire")
for drawing in symbol.drawings:
    drawing.load_curves()
    print(drawing)
fire_1709239728798.csv: 227 points, 1 curves
fire_1709588014524.csv: 110 points, 1 curves
fire_1709501601465.csv: 92 points, 1 curves
fire_1709332562598.csv: 711 points, 1 curves
fire_1710079121173.csv: 466 points, 4 curves
fire_1709229817510.csv: 115 points, 1 curves
fire_1709471244496.csv: 105 points, 1 curves
fire_1709229788382.csv: 135 points, 1 curves
fire_1709332548305.csv: 480 points, 1 curves
fire_1709478169231.csv: 132 points, 1 curves
fire_1709416663416.csv: 127 points, 1 curves
fire_1709501625734.csv: 201 points, 1 curves
fire_1709332604781.csv: 432 points, 1 curves
fire_1709416630930.csv: 113 points, 1 curves
fire_1709538199887.csv: 211 points, 1 curves
fire_1709416667312.csv: 115 points, 1 curves
fire_1709501509004.csv: 110 points, 1 curves
fire_1709229865605.csv: 98 points, 1 curves
fire_1709571045075.csv: 62 points, 1 curves
fire_1709231416786.csv: 51 points, 1 curves
fire_1709571040678.csv: 64 points, 1 curves
fire_1710023927370.csv: 104 points, 1 curves
fire_1710079109175.csv: 512 points, 2 curves
fire_1709332540122.csv: 698 points, 1 curves
fire_1709231398891.csv: 55 points, 1 curves
fire_1709416639519.csv: 125 points, 1 curves
fire_1709538240512.csv: 148 points, 1 curves
fire_1709321796565.csv: 242 points, 1 curves
fire_1709334725070.csv: 443 points, 1 curves

Render Drawing as a raster Image

You can render any Drawing into a PIL.Image for display or further processing.

To display a Drawing in 200x200 pixels resolution:

CLI

texnomagic drawing render -r 200 alphabets/texnolatin/symbols/fire/drawings/fire_1709229865605.csv

Python:

from texnomagic.cli_common import get_alphabet_or_fail
from texnomagic.render import render_drawing

abc = get_alphabet_or_fail("texnolatin")
symbol = abc.get_symbol("friend")
drawing = symbol.random_drawing()
image = render_drawing(drawing, res=200)
print(image)
<PIL.Image.Image image mode=L size=200x200 at 0x7F2D5020A330>

You can also display the image interactively:

image.show()

Or save it to a PNG file:

image.save('fire.png')

You can also easily convert the image into numpy.array and do what you want with it, for example use it to train neural networks using your own code:

import numpy as np

from texnomagic.cli_common import get_alphabet_or_fail
from texnomagic.render import render_drawing

abc = get_alphabet_or_fail("texnolatin")
symbol = abc.get_symbol("friend")
drawing = symbol.random_drawing()
image = render_drawing(drawing, res=16)
image_array = np.array(image)
print(f'Array shape: {image_array.shape}')
print(image_array)
Array shape: (16, 16)
[[  0   0   0   0   0 255   0   0   0   0 255   0   0   0   0   0]
 [  0   0   0   0   0 255   0   0   0   0 255   0   0   0   0   0]
 [  0   0   0   0   0 255   0   0   0   0 255   0   0   0   0   0]
 [  0   0   0   0   0 255   0   0   0   0 255   0   0   0   0   0]
 [  0   0   0   0   0 255   0   0   0   0 255   0   0   0   0   0]
 [  0   0   0   0   0 255   0   0   0   0 255   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
 [255 255   0   0   0   0   0   0   0   0   0   0   0   0   0 255]
 [  0 255   0   0   0   0   0   0   0   0   0   0   0   0 255 255]
 [  0 255   0   0   0   0   0   0   0   0   0   0   0   0 255   0]
 [  0 255   0   0   0   0   0   0   0   0   0   0   0   0 255   0]
 [  0 255 255   0   0   0   0   0   0   0   0   0   0 255 255   0]
 [  0   0 255 255   0   0   0   0   0   0   0 255 255 255   0   0]
 [  0   0   0 255 255 255   0   0   0   0 255 255   0   0   0   0]
 [  0   0   0   0   0 255 255 255 255 255 255   0   0   0   0   0]]