PKÇ ÍFÂ7“CCdevoir/__init__.py#!/usr/bin/env python3 # Copyright Louis Paternault 2014-2015 # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . 1 """Set up working environments to edit a file""" VERSION = "0.1.1" __COPYRIGHT__ = "(C) 2014 Louis Paternault. GNU GPL 3 or later." PK¡³9HC˜±¸IIdevoir/main.py#!/usr/bin/env python3 # Copyright Louis Paternault 2011-2015 # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . 1 """Set up working environments to edit a file Example of configuration file, to edit .tex files. This supposes that template ~/.devoir/templates/pdf exists. > $ cat ~/.devoir/ftplugins/tex.cfg > [config] > > cwd = {dirname} > > [process] > > pre = test -e {basename}.pdf || cp {configdir}/templates/pdf {basename}.pdf > cmd1 = evince {basename}.pdf & > cmd2 = screen $EDITOR {basename}.tex > cmd3 = screen latexmk -pvc {basename} """ import argparse import configparser import glob import logging import os import shutil import subprocess import sys import devoir LOGGER = logging.getLogger(devoir.__name__) LOGGER.addHandler(logging.StreamHandler()) DEVOIRRC = os.path.expanduser('~/.devoir') class DevoirException(Exception): """Generic exception for this program.""" pass class NoPlugin(DevoirException): """No plugin found.""" def __init__(self, extension, filenames): super().__init__() self.extension = extension self.filenames = filenames def __str__(self): return "No plugin found for extension '{}' (I tried {}).".format( self.extension, ",".join([ "'{}'".format(filename) for filename in self.filenames ]), ) def load_plugin(extension): """Load plugin for extension. The plugin (as a dict of its options), filled with default values if necessary.""" config = configparser.ConfigParser() config.read_dict({ 'process': {}, 'config': { 'cwd': '.', }, }) filename = os.path.join( DEVOIRRC, 'ftplugins', '{}.cfg'.format(extension) ) if not os.path.exists(filename): raise NoPlugin(extension, [filename]) config.read([filename]) return config def commandline_parser(): """Return an argument parser""" parser = argparse.ArgumentParser( description="Prepare working environment to edit a file." ) parser.add_argument( '--version', action='version', version='%(prog)s ' + devoir.VERSION, ) parser.add_argument( 'template', nargs="?", help=( "Template to use: if set, this file is copied as FILE before " "editing it" ), default=None ) parser.add_argument( 'file', nargs=1, help="File to edit." ) return parser def get_extension(filename): """Return (dirname, basename, extension). The extension is the actual or guessed extension of the argument. - If filename has an extension (i.e. ends with dot-something), return it. - Otherwise, if only one plugin matches filename (i.e. if there exist only one plugin 'foo' such that file 'filename.foo' exists, return this extension. - Otherwise, raise an exception. """ if '.' in os.path.basename(filename): splitted = os.path.basename(filename).split('.') return ( os.path.dirname(filename), '.'.join(splitted[0:-1]), splitted[-1], ) possible = [] for plugin_name in glob.glob(os.path.join(DEVOIRRC, 'ftplugins', '*.cfg')): extension = os.path.basename(plugin_name)[0:-len('.cfg')] if os.path.exists('{}.{}'.format(filename, extension)): possible.append(extension) if len(possible) == 1: return ( os.path.dirname(filename), os.path.basename(filename), possible[0], ) raise Exception('No file named "{}".'.format(filename)) def main(): """Main function""" try: options = commandline_parser().parse_args(sys.argv[1:]) template, filename = options.template, options.file[0] (dirname, basename, extension) = get_extension(filename) filename = '{}.{}'.format(os.path.join(dirname, basename), extension) plugin = load_plugin(extension) # Copy template if not os.path.exists(filename): if not template: template = os.path.join( DEVOIRRC, 'templates', format(extension) ) if os.path.exists(template): shutil.copyfile(template, filename) else: # Just touch the file with open(filename, 'w') as __file: pass # Building format dictionary format_dict = { 'basename': basename, 'dirname': os.path.abspath(dirname), 'filename' : filename, 'configdir': DEVOIRRC, } # Process for command in plugin['process'].items(): command = command[1].format(**format_dict) sys.stderr.write('{}\n'.format(command)) subprocess.call( os.path.expandvars(command), shell=True, cwd=plugin['config']['cwd'].format(**format_dict), ) except DevoirException as error: LOGGER.error(str(error)) sys.exit(1) sys.exit(0) if __name__ == "__main__": main() PKÛ³9H9–x4ÆÆ&Devoir-0.1.1.dist-info/DESCRIPTION.rstDevoir — Quickly set up a working environment to edit a file ============================================================ |sources| |pypi| |documentation| |license| When editing a LaTeX file, I want the file being edited with `vim `_, the compiled file displayed using a pdf viewer, and latex being run whenever something changes, using `latexmk `_. But wait, there is more. - I often start a LaTeX document by copying an existing one, as a template. - The pdf file may or may not exist when I start working: if I have already been working on this file before, the pdf file exists; if not, it does not exists, and my pdf viewer won't start on a non-existing file. This program aims to automate all this process. I built it to process LaTeX files, but it should work with other files too. What's new? ----------- See `changelog `_. Download and install -------------------- See the end of list for a (quick and dirty) Debian package. * From sources: * Download: https://pypi.python.org/pypi/devoir * Install (in a `virtualenv`, if you do not want to mess with your distribution installation system):: python3 setup.py install * From pip:: pip install devoir * Quick and dirty Debian (and Ubuntu?) package This requires `stdeb `_ to be installed:: python3 setup.py --command-packages=stdeb.command bdist_deb sudo dpkg -i deb_dist/devoir-_all.deb Documentation ------------- * The compiled documentation is available on `readthedocs `_ * To compile it from source, download and run:: cd doc && make html .. |documentation| image:: http://readthedocs.org/projects/devoir/badge :target: http://devoir.readthedocs.org .. |pypi| image:: https://img.shields.io/pypi/v/devoir.svg :target: http://pypi.python.org/pypi/devoir .. |license| image:: https://img.shields.io/pypi/l/devoir.svg :target: http://www.gnu.org/licenses/gpl-3.0.html .. |sources| image:: https://img.shields.io/badge/sources-devoir-brightgreen.svg :target: http://git.framasoft.org/spalax/devoir PKÔ³9H~é°©--'Devoir-0.1.1.dist-info/entry_points.txt[console_scripts] devoir = devoir.main:main PKÛ³9H¯°$Devoir-0.1.1.dist-info/metadata.json{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Console", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Intended Audience :: End Users/Desktop", "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Utilities"], "extensions": {"python.commands": {"wrap_console": {"devoir": "devoir.main:main"}}, "python.details": {"contacts": [{"email": "spalax@gresille.org", "name": "Louis Paternault", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://git.framasoft.org/spalax/devoir"}}, "python.exports": {"console_scripts": {"devoir": "devoir.main:main"}}}, "generator": "bdist_wheel (0.26.0)", "license": "GPLv3 or any later version", "metadata_version": "2.0", "name": "Devoir", "summary": "Quickly set up a working environment to edit a file.", "version": "0.1.1"}PKÔ³9HžÙ¡$Devoir-0.1.1.dist-info/top_level.txtdevoir PK-QRF“×2Devoir-0.1.1.dist-info/zip-safe PKÛ³9H}À‚¼\\Devoir-0.1.1.dist-info/WHEELWheel-Version: 1.0 Generator: bdist_wheel (0.26.0) Root-Is-Purelib: true Tag: py3-none-any PKÛ³9H·]å0Í Í Devoir-0.1.1.dist-info/METADATAMetadata-Version: 2.0 Name: Devoir Version: 0.1.1 Summary: Quickly set up a working environment to edit a file. Home-page: https://git.framasoft.org/spalax/devoir Author: Louis Paternault Author-email: spalax@gresille.org License: GPLv3 or any later version Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) Classifier: Intended Audience :: End Users/Desktop Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Topic :: Utilities Devoir — Quickly set up a working environment to edit a file ============================================================ |sources| |pypi| |documentation| |license| When editing a LaTeX file, I want the file being edited with `vim `_, the compiled file displayed using a pdf viewer, and latex being run whenever something changes, using `latexmk `_. But wait, there is more. - I often start a LaTeX document by copying an existing one, as a template. - The pdf file may or may not exist when I start working: if I have already been working on this file before, the pdf file exists; if not, it does not exists, and my pdf viewer won't start on a non-existing file. This program aims to automate all this process. I built it to process LaTeX files, but it should work with other files too. What's new? ----------- See `changelog `_. Download and install -------------------- See the end of list for a (quick and dirty) Debian package. * From sources: * Download: https://pypi.python.org/pypi/devoir * Install (in a `virtualenv`, if you do not want to mess with your distribution installation system):: python3 setup.py install * From pip:: pip install devoir * Quick and dirty Debian (and Ubuntu?) package This requires `stdeb `_ to be installed:: python3 setup.py --command-packages=stdeb.command bdist_deb sudo dpkg -i deb_dist/devoir-_all.deb Documentation ------------- * The compiled documentation is available on `readthedocs `_ * To compile it from source, download and run:: cd doc && make html .. |documentation| image:: http://readthedocs.org/projects/devoir/badge :target: http://devoir.readthedocs.org .. |pypi| image:: https://img.shields.io/pypi/v/devoir.svg :target: http://pypi.python.org/pypi/devoir .. |license| image:: https://img.shields.io/pypi/l/devoir.svg :target: http://www.gnu.org/licenses/gpl-3.0.html .. |sources| image:: https://img.shields.io/badge/sources-devoir-brightgreen.svg :target: http://git.framasoft.org/spalax/devoir PKÛ³9HTë«.//Devoir-0.1.1.dist-info/RECORDDevoir-0.1.1.dist-info/DESCRIPTION.rst,sha256=i2qI3lcrJGanlRY3X35GM4YE9LXK0qBK49HnpsNa9_M,2246 Devoir-0.1.1.dist-info/METADATA,sha256=NP-m6jGaTYc-VB9vUmbr1PS-vQGA4nt2UElYJZYdz_w,3021 Devoir-0.1.1.dist-info/RECORD,, Devoir-0.1.1.dist-info/WHEEL,sha256=zX7PHtH_7K-lEzyK75et0UBa3Bj8egCBMXe1M4gc6SU,92 Devoir-0.1.1.dist-info/entry_points.txt,sha256=M7Sd0rPSFK3dfmob2mqJH-_cJntTiyGOjy-2bc3UUgU,45 Devoir-0.1.1.dist-info/metadata.json,sha256=F-4RM6gYziUTXVEqVJqXnAN9nhL-mJ7FqcEcGsmktvI,1028 Devoir-0.1.1.dist-info/top_level.txt,sha256=PZL2ZHeR--LnwPNWmwBn5O8PM0lpJsOii2HdWZY8ztg,7 Devoir-0.1.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 devoir/__init__.py,sha256=4x5x_cQs29h7nYu6_wa-c-4Ocq96FXxm9HKGXP_FFOI,835 devoir/main.py,sha256=Exu9HNnHAQ_voZdkhFCmFI5nFhtw6C02Il9AjE-ndX8,5961 PKÇ ÍFÂ7“CCdevoir/__init__.pyPK¡³9HC˜±¸IIsdevoir/main.pyPKÛ³9H9–x4ÆÆ&èDevoir-0.1.1.dist-info/DESCRIPTION.rstPKÔ³9H~é°©--'ò#Devoir-0.1.1.dist-info/entry_points.txtPKÛ³9H¯°$d$Devoir-0.1.1.dist-info/metadata.jsonPKÔ³9HžÙ¡$ª(Devoir-0.1.1.dist-info/top_level.txtPK-QRF“×2ó(Devoir-0.1.1.dist-info/zip-safePKÛ³9H}À‚¼\\1)Devoir-0.1.1.dist-info/WHEELPKÛ³9H·]å0Í Í Ç)Devoir-0.1.1.dist-info/METADATAPKÛ³9HTë«.//Ñ5Devoir-0.1.1.dist-info/RECORDPK ø;9