Commit 21e2b258 authored by Benoît Bryon's avatar Benoît Bryon

Introduced workflow to generate printable PDF from game sources.

parent 1bcc8e65
Synkrominos (c) by Benoît Bryon <benoit@marmelune.net>, 2020
Primary contributors are copyright holders:
* Benoît Bryon <benoit@marmelune.net>
* Sylvain Lebosquain
* Delphine Saint Quentin <delphinesq@yahoo.fr>
Synkrominos is licensed under a
Creative Commons Attribution-ShareAlike 4.0 License.
See <https://creativecommons.org/licenses/by-sa/4.0/>.
\ No newline at end of file
# Synkrominos
Un jeu de cartes pour faciliter les réunions - http://synkrominos.com
\ No newline at end of file
###########
Synkrominos
###########
Synkrominos est un support visuel pour faciliter les réunions.
Synkrominos est disponible en prévente : http://synkrominos.com
Ce projet est distribué sous licence CC BY-SA 4.0.
Le présent dossier contient les sources du projet.
Les contributions sont bienvenues !
************
Installation
************
.. note::
En effet la partie logicielle du projet en est à ses débuts.
Une première étape consiste à partager l'environnement de développement
de l'auteur initial du code dans un dépôt public. À ce stade, les recettes
fournies (ci-dessous) sont documentées au minimum et ciblent l'environnement
de travail de l'auteur. Les échanges avec utilisateurs et contributeurs
permettront d'en améliorer la portabilité !
Si vous êtes motivé-e pour utiliser et/ou contribuer à ce projet,
n'hésitez donc pas à contacter Benoît Bryon <benoit@marmelune.net> !
* Logiciels requis :
* calligra-libs (Krita)
* Inkscape
* Python
* ``pip install -r requirements.txt``
* Polices : installer les polices présentes dans le dossier ``fonts``
************
Localisation
************
Quelques commandes utiles pour la gestion des traductions :
.. code:: sh
# Quand les sources ont changé, mettre à jour le .pot
pybabel extract --mapping=babel.ini --output=locale/messages.pot .
# ... puis les .po
pybabel update --input-file=locale/messages.pot --output-dir=locale --locale=fr
# Quand les .po ont été édités (i.e. les textes traduits), générer les .mo
# Note : ceci est automatiquement réalisé par generate.py.
mkdir -p var/locale/fr/LC_MESSAGES && pybabel compile --input-file=locale/fr/LC_MESSAGES/messages.po --directory=var/locale --locale=fr
# Ajouter une nouvelle langue <LOCALE>
pybabel init --input-file=locale/messages.pot --output-dir=locale --locale=<LOCALE>
*********************************
Générer les fichiers d'impression
*********************************
Pour générer les fichiers d'impression :
* Compiler les fichiers de langue (.mo), voir ci-dessus.
* Exécuter le script de génération via ``python generate.py``
Les fichiers sont générés dans un dossier ``var``, créé automatiquement dans le dossier de travail.
**********
Références
**********
* Site web : http://synkrominos.com
\ No newline at end of file
[jinja2: svg/**.svg]
encoding = utf-8
[jinja2: cards.json]
encoding = utf-8
\ No newline at end of file
{# Jinja2 #}
[
{
"template": "svg/front.svg",
"data": {
"id": "welcome_front",
"category": "energy",
"title": "{% trans %}Welcome{% endtrans %}",
"description": "{% trans %}<strong>Be welcome!</strong><br />Meet up<br />casual discussions.{% endtrans %}"
}
},
{
"template": "svg/front.svg",
"data": {
"id": "intention_front",
"category": "path",
"title": "{% trans %}Intention{% endtrans %}",
"description": "{% trans %}<strong>What do we meet for?</strong><br />Which invitation<br />we honour?{% endtrans %}"
}
}
]
\ No newline at end of file
#!/usr/bin/python
# coding=utf-8
"""
[ ] Charger le .mo FR ou EN dans generate.py
[ ] Ajouter suffixes dans les noms de fichier ou préfixe dossier
"""
from __future__ import print_function
import argparse
import json
import subprocess
from babel.support import Translations
import jinja2
import pathlib
def compile_locale(locale):
"""Make sure .mo file is available for given ``locale``."""
output_dir = pathlib.Path("var/locale/{locale}/LC_MESSAGES".format(locale=locale))
try:
output_dir.mkdir(parents=True)
except OSError:
pass
mo_file = output_dir / "messages.mo"
if not mo_file.exists():
command = "pybabel compile --input-file=locale/{locale}/LC_MESSAGES/messages.po --directory=var/locale --locale={locale}".format(
locale=locale,
)
print(command)
subprocess.call(command, shell=True)
def html2svg(value):
value = value.replace(u"<strong>", u"<tspan style=\"font-weight:bold;\">")
value = value.replace(u"</strong>", "</tspan>")
value = value.replace(u"<br />", "</tspan><tspan sodipodi:role=\"line\">")
return value
def jinja2_environment(locale):
"""Setup and return Jinja2 environment."""
env = jinja2.Environment(
loader=jinja2.FileSystemLoader('.'),
extensions=['jinja2.ext.i18n'],
)
env.filters['html2svg'] = html2svg
env.globals = {
'locale': locale,
}
# i18n
locale_dir = "var/locale"
msgdomain = "messages"
locales = [locale] # List of locales in order of priority.
translations = Translations.load(locale_dir, locales)
env.install_gettext_translations(translations)
return env
def load_cards(locale):
"""Return list of cards data."""
jinja2_env = jinja2_environment(locale=locale)
template = jinja2_env.get_template('cards.json')
context_data = {}
cards_json = template.render(**context_data)
card_list = json.loads(cards_json)
return card_list
def kra2png(code, locale):
"""Generate PNG files from Krita sources."""
output_dir = pathlib.Path("var/img")
try:
output_dir.mkdir(parents=True)
except OSError:
pass
command = "calligraconverter img/{code}.kra var/img/{code}.png"
command = command.format(
code=code,
)
print(command)
subprocess.call(command, shell=True)
def template2svg(card, locale):
"""Generate .svg files from templates."""
jinja2_env = jinja2_environment(locale=locale)
template = jinja2_env.get_template(card['template'])
output_dir = pathlib.Path("var/svg")
try:
output_dir.mkdir(parents=True)
except OSError:
pass
with open("var/svg/{code}_{locale}.svg".format(code=card['data']['id'], locale=locale), "w") as file_out:
context_data = card['data']
context_data['illustration_path'] = "file://{working_dir}/img/{id}.png".format(
working_dir=pathlib.Path("var").resolve(),
id=context_data['id'],
)
for part in template.generate(**context_data):
file_out.write(part.encode('utf-8'))
def svg2pdf(code, locale):
"""Generate .pdf files from SVG sources."""
output_dir = pathlib.Path("var/pdf")
try:
output_dir.mkdir(parents=True)
except OSError:
pass
command = "inkscape --without-gui --file=var/svg/{code}_{locale}.svg --export-area-page --export-dpi=300 --export-text-to-path --export-pdf=var/pdf/{code}_{locale}.pdf"
command = command.format(
code=code,
locale=locale,
)
print(command)
subprocess.call(command, shell=True)
def main():
parser = argparse.ArgumentParser(description='Generate printable PDF files from sources.')
parser.add_argument(
'--locale',
dest='locale',
default='fr',
type=str,
choices=['fr'],
help='Localization, e.g. language.',
)
args = parser.parse_args()
print("### READING CARD LIST AND DATA FROM cards.json")
compile_locale(args.locale)
card_list = load_cards(locale=args.locale)
for card_item in card_list:
print("")
print("### PROCESSING \"{code}\"".format(code=card_item['data']['id']))
kra2png(code=card_item['data']['id'], locale=args.locale)
template2svg(card=card_item, locale=args.locale)
svg2pdf(code=card_item['data']['id'], locale=args.locale)
print("")
print("### DONE :)")
if __name__ == "__main__":
main()
\ No newline at end of file
# French translations for PROJECT.
# Copyright (C) 2020 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2020-01-17 17:28+0100\n"
"PO-Revision-Date: 2020-01-17 14:40+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: fr\n"
"Language-Team: fr <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.8.0\n"
#: cards.json:8
msgid "Welcome"
msgstr "Accueil"
#: cards.json:9
msgid "<strong>Be welcome!</strong><br />Meet up<br />casual discussions."
msgstr "<strong>Bienvenue !</strong><br />Rencontres et retrouvailles<br />papotages informels."
#: cards.json:17
msgid "Intention"
msgstr "Intention"
#: cards.json:18
msgid ""
"<strong>What do we meet for?</strong><br />Which invitation<br />we "
"honour?"
msgstr ""
"<strong>Quelle intention</strong><br /><strong>nous rassemble ?</strong><br />À quelle "
"invitation<br />avons-nous répondu ?"
# Translations template for PROJECT.
# Copyright (C) 2020 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2020-01-17 17:28+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.8.0\n"
#: cards.json:8
msgid "Welcome"
msgstr ""
#: cards.json:9
msgid "<strong>Be welcome!</strong><br />Meet up<br />casual discussions."
msgstr ""
#: cards.json:17
msgid "Intention"
msgstr ""
#: cards.json:18
msgid ""
"<strong>What do we meet for?</strong><br />Which invitation<br />we "
"honour?"
msgstr ""
Babel
Jinja2
pathlib
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment