#!/usr/bin/python # -*- coding:utf-8 -*- import argparse import re import random import time from os import path, makedirs from jinja2 import Environment, FileSystemLoader LICENSES = {'CC-by-sa-2.0': 'license-cc-by-sa-2.0', } TEMPLATES = { 'beamer': {'fragment': 'frame.tex', 'fragment_pratique': 'frame-pratique.tex', 'master': 'main-beamer.tex'}, 'article': {'fragment': 'fragment.tex', 'fragment_pratique': 'fragment-pratique.tex', 'master': 'main-article.tex'} } LATEX_SUBS = [(re.compile('_'), '\\_'), ] def get_unique_name(base): now = time.localtime() year = str(now[0]) month = str(now[1]).rjust(2, '0') day = str(now[2]).rjust(2, '0') rand = str(random.randint(0, 100)).rjust(2, '0') return '-'.join([base, year, month, day, rand]).decode('utf-8') def escape_tex(value): newval = value for pattern, replacement in LATEX_SUBS: newval = pattern.sub(replacement, newval) return newval def main(): def init(args): """ init function """ root = '../' if args.directory: root = root + re.sub(r'[\w-]+/?', '../', args.directory) else: root = '../' name = args.name if name: if path.splitext(name)[1] == '': name = name.decode('utf-8') + u'.tex' else: name = get_unique_name('formation') title = args.title if not title: title = u'FIXME' else: title = title.decode('utf-8') author = args.author if not author: author = u'Cadoles' else: author = author.decode('utf-8') client = args.client if not client: client = u'FIXME' else: client = client.decode('utf-8') directory = args.directory if not directory: directory = '' license = LICENSES.get(args.license, 'license-cc-by-sa-2.0') document_class = args.format content = 'sli' if document_class == 'beamer' else 'rep' env = {'root': root, 'class': document_class, 'content': content, 'title': title, 'author': author, 'client': client, 'license': license} master = TEMPLATES[document_class]['master'] master_dir = path.join('presentations', directory) programme_dir = path.join(master_dir, 'programme') resources = [(path.join('presentations', directory), master), (programme_dir, 'contenu.tex'), (programme_dir, 'duree.tex'), (programme_dir, 'evaluation.tex'), (programme_dir, 'moyens.tex'), (programme_dir, 'objectifs.tex'), (programme_dir, 'prerequis.tex'), (programme_dir, 'public.tex'), ] #('slides', 'license-cc-by-sa-2.0.tex'), #('slides', 'preambule.tex'), #('slides', 'title.tex')] for directory, template_file in resources: template = jinja_env.get_template(template_file) rendered_template = template.render(**env) if not path.exists(directory): makedirs(directory) template_dest_name = name if template_file == master else template_file with open(path.join(directory, template_dest_name), 'w') as rendered_file: rendered_file.write(rendered_template.encode('utf-8')) def update(args): """ update function """ re_class = re.compile(r'\\documentclass\{(?P.*)\}') #skbconfig_re = re.compile(r'\\skbconfig\[\s*root\s*=\s*(?P.*),\s*rep\s*=\s*(?P.*),\s*pub\s*=\s*(?P.*),\s*fig\s*=\s*(?P.*),\s*sli\s*=\s*(?P.*),\s*acr\s*=\s*(?P.*),\s*bib\s*=\s*(?P.*),\s*\]\{skblocal.tex\}', re.M) skbconfig_re = re.compile(r'\\skbconfig\[\n\s*root\s*=\s*(?P.*),\n\s*rep\s*=\s*(?P.*),\n\s*pub\s*=\s*(?P.*),\n\s*fig\s*=\s*(?P.*),\n\s*sli\s*=\s*(?P.*),\n\s*acr\s*=\s*(?P.*),\n\s*bib\s*=\s*(?P.*)\n\s*\]\{skblocal.tex\}', re.M) skbinput_re = re.compile(r'[^%]\\skbinput\[from=(?P.*?)(,.*)?\]\{(?P.*?)\}', re.M) with open(args.master, 'r') as master: tex_master = master.read() tex_class = re_class.search(tex_master) tex_skbconfig = skbconfig_re.search(tex_master) tex_skbinputs = skbinput_re.finditer(tex_master) fragment = TEMPLATES[tex_class.group('document_class')]['fragment'] fragment_pratique = TEMPLATES[tex_class.group('document_class')]['fragment_pratique'] for skbinput in tex_skbinputs: rep = path.dirname(skbinput.group('tex')) rep = path.join(tex_skbconfig.group(skbinput.group('rep')), rep) tex_name = path.basename(skbinput.group('tex')) basename = '{0}.tex'.format(tex_name) dest = path.join(rep, basename) if not path.isfile(dest): print(dest) if not path.isdir(rep): makedirs(rep) template = jinja_env.get_template(fragment_pratique if tex_name.endswith('-pratique') else fragment) env = {'title': basename, 'subtitle': '', 'name': dest} rendered_template = template.render(**env) with open(dest, 'w') as rendered_file: rendered_file.write(rendered_template.encode('utf-8')) def outline(args): """ outline creation """ section_re = re.compile(r'\\section\{(?P.*?)\}') part_re = re.compile(r'\\part\{(?P.*?)}') subsection_re = re.compile(r'\\subsection\{(?P.*?)\}') with open(args.master, 'r') as master_tex: master = master_tex.read() parts = part_re.finditer(master) section = section_re.finditer(master) subsection_re = subsection_re.finditer(master) jinja_loader = FileSystemLoader('./templates') jinja_env = Environment(loader=jinja_loader, block_start_string='((*', block_end_string='*))', variable_start_string='(((', variable_end_string=')))', comment_start_string='((=', comment_end_string='=))', trim_blocks=True) jinja_env.filters['escape_tex'] = escape_tex parser = argparse.ArgumentParser(description="Préparation des fichiers tex") subparsers = parser.add_subparsers(help='Aide des sous-commandes') parser_init = subparsers.add_parser('init', help='Initialisation du fichier maître') parser_init.add_argument('-f', '--format', help="Format du document", required=True) parser_init.add_argument('-n', '--name', help="Nom du fichier à créer", required=True) parser_init.add_argument('-a', '--author', help="Auteur de la formation") parser_init.add_argument('-c', '--client', help="Client") parser_init.add_argument('-t', '--title', help="Titre de la formation") parser_init.add_argument('-l', '--license', help="Termes de mise à disposition de la formation") parser_init.add_argument('-d', '--directory', help="Sous-répertoires où créer le fichier", required=True) parser_init.set_defaults(func=init) parser_update = subparsers.add_parser('update', help='Mise à jour des fichiers inclus') parser_update.add_argument('-m', '--master', help="Emplacement du fichier maître", required=True) parser_update.set_defaults(func=update) parser_outline = subparsers.add_parser('outline', help="Création du programme à partir du fichier maître") parser_outline.add_argument('-m', '--master', help="Emplacement du fichier maître", required=True) parser_outline.set_defaults(func=outline) args = parser.parse_args() args.func(args) if __name__ == '__main__': main()