deckbro 0.0.2
Generate playing cards deck from python config and SVG templates.
Requires Python: >=3.12
Keywords: deck, card, html

## deckbro

deckbro is a python library to generate cards deck using HTML templates. 

*/!\ This software has not been toroughly tested. Please carefully check its outputs before sending them for expensive operations as quality printing.*

**Key features :**
- Uses HTML as templates.
- Declarative semantics, for ease of use
- Parametric and extendable model through Python
- Generates SVG for cards, as well as pdf sheets grouping cards ready for double-sided printing
- Any card and sheet format
- Tools to auto-fit text in element.

**Caveats :**
- You have to do the layout work. But using HTML/CSS/JS so not too hard.
- Not able to easily compose HTML for now. Should not be too much of a hindrance and should be improved overtime.
- Sheet layout not automated. Should be improved over time.
- While it should be possible to make it work, at least partially, on any system, it is only designed and tested for Linux. No plan to improve it by myself unless a lot of people request it. MR and Forks are welcome. Be sure to open an issue/message me before starting to work on a MR, so I can confirm this will be accepted or not beforehand.

## Install 

You can either install sources or download from PyPI.

```pip install deckbro```

In addition you will need to have :

- Inkscape
- pdfunite
- Chromium
- pdftocairo (usually provided along Poppler, itself provided alongside Inkscape)

installed on the computer and invokable from cli.

## Quick overview

Here is a summary of the example contained in `examples/base` directory.

We define a template for a card face : 

```html
<!DOCTYPE html>

<html>
<head>
    <link rel="stylesheet" href="template.css" /> <!--provided by deckbro -->
    <script src="template.js"></script> <!-- provided by deckbro -->
</head>
<style>
    @page {
        margin: 0;
        padding: 0;
        size: 600px 800px;
    }
</style>
<body id="body" style="padding: 0px; margin: 0px; width: 600px; height:800px; color:#1e1e1e; font-family: sans-serif;">
    <div style="padding : 20px; margin: 0px; background-color : #1e1e1e; height: 100%; border-radius: 20px; box-sizing: border-box;">
        <div class="fit-text" style="font-size: 60px; font-weight: bold; text-align: center; vertical-align: middle; height: 10%; background-color: white; border-radius: 20px;">
            TITLE  <!-- TITLE is a placeholder -->
        </div>
        <div style="height: 50%;">
            <div style="display: flex; align-items: center; justify-content: center; height: 100%;">
                <img src="magician.svg" height="300px" width="300px" style="margin: auto;"> <!-- magician.svg is a placeholder -->
            </div>
        </div>
        <div class="fit-text" style="font-size: 30px; border-radius: 20px; background-color: white; height: 40%; box-sizing: border-box; padding: 20px;">
            DESCRIPTION <!-- DESCRIPTION is a placeholder -->
        </div>
    </div>
</body>

</html>
```

That we can use in a python file to declare a deck :

```python
from deckbro.deck import Card, Deck
from deckbro.html import HTMLFile, StrSub
from deckbro.render import render

#dimensions of cards
Deck.instance().config.cards.width = 60 
Deck.instance().config.cards.height = 80


# we can use the power or Python to build our faces. A face is a composition of HTMLnodes
#here is front side
def front(title : str, image : str, description : str) -> StrSub:

   
    return StrSub(  # replace strings in HTML
        HTMLFile("deck/front.html"), #Take html from front.html
        {
            "TITLE" : title, #TITLE becomes title
            "DESCRIPTION" : description, #etc...
            "magician.svg" : image, # we define another image
        }
    )

# here is back side.
def back() -> HTMLFile :
    return HTMLFile("deck/back.html")

#Then we register a card with a front and a back.
Card("magician",
    front("Magician", "magician.svg", "A magical being able to magically vaporize enemies with their FIREBALLS."),
    back()
)

#and more cards.
Card("enchanter",
    front("Enchanter", "enchanter.svg", "A complex being, capable of vowing durable enchantments on themselves, others, places, and items. Some even say that they are able to enchant spells. Enchanting magic is a very complicated topic, which requires years of training for one to master. The strongest enchanters can even bend reality. See, one of them automatically reduced the font size of this text so it fits in the card !"),
    back()
) 

# ...

#finally, we export deck. It renders SVG file for each card, as well as A4 pdf sheets for double sided printing.
render()
```

Run the script and Voilà !

Here are some of the cards fronts generated : 

<img src="./examples/base/expected/gen_magician.svg" alt="magician" width="400"/>
<img src="./examples/base/expected/gen_enchanter.svg" alt="enchanter" width="400"/>


You can also see the [generated printing sheets](./examples/base/expected/gen_sheets.pdf)