#!/usr/bin/env python3 import argparse, os, shutil import docutils.core def basename(fname): '''Returns the name of the guide from either its name or its directory''' if os.path.isdir(os.path.join('guides',fname)): return fname elif os.path.isdir(fname): return os.path.basename(os.path.abspath(fname)) else: msg = '%s is not a valid directory' % fname raise argparse.ArgumentTypeError(msg) def build_latex(guide): '''Builds the LaTeX source for the guide''' src_dir = os.path.join('guides',guide) tools_dir = 'tools' build_dir = os.path.join('build',guide) tex_name = guide+'.tex' # Check if we need to (re)build rebuild = False try: tex_time = os.stat(os.path.join(build_dir,tex_name)).st_mtime # the source has changed? for dirpath, dirnames, filenames in os.walk(src_dir): for src_file in filenames: src_time = os.stat(os.path.join(dirpath,src_file)).st_mtime if src_time > tex_time: rebuild = True break # a template has changed? for dirpath, dirnames, filenames in os.walk(tools_dir): for src_file in filenames: src_time = os.stat(os.path.join(dirpath,src_file)).st_mtime if src_time > tex_time: rebuild = True break except (IOError,OSError): rebuild = True if not rebuild: return None # Build the LaTeX source s_files = [] for dirpath, dirnames, filenames in os.walk(src_dir): s_files += [os.path.join(dirpath,fn) for fn in filenames if fn.endswith(('.txt','.rst'))] s_files.sort() source = "" for fname in s_files: fp = open(fname,'rt') try: source += fp.read() except IOError: pass finally: fp.close() if not os.path.isdir(build_dir): os.mkdir(build_dir) fp = open(os.path.join(build_dir,tex_name),'wb') fp.write(docutils.core.publish_string(source, writer_name='latex', settings_overrides={'language_code': 'it', 'documentoptions': 'a6paper,twoside', 'stylesheet': 'lmodern', 'template': os.path.join(tools_dir,'booklet-A6.template.tex'), 'hyperlink-color': '0'})) fp.close() def build_pdf(guide): '''Builds the A6 PDF for the guide''' build_dir = os.path.join('build',guide) dist_dir = os.path.join('dist','PDF') tex_name = guide+'.tex' pdf_name = guide+'.pdf' # check for prerequisites build_latex(guide) # Check if we need to (re)build tex_time = os.stat(os.path.join(build_dir,tex_name)).st_mtime try: pdf_time = os.stat(os.path.join(dist_dir,pdf_name)).st_mtime if pdf_time > tex_time: return None except OSError: pass if not os.path.isdir(dist_dir): os.mkdir(dist_dir) os.chdir(build_dir) try: if os.system('pdflatex '+tex_name) == 0: if os.system('pdflatex '+tex_name) == 0: os.system('pdflatex '+tex_name) except OSError: return False finally: os.chdir('../../') try: shutil.move(os.path.join(build_dir,pdf_name), os.path.join(dist_dir,pdf_name)) except IOError: return False def build_nup_pdf(guide): '''Builds the nup-ed PDF for the guide''' dist_dir = os.path.join('dist','PDF') pdf_name = guide+'.pdf' nup_name = guide+'-A6suA4.pdf' # check for prerequisites build_pdf(guide) # Check if we need to (re)build pdf_time = os.stat(os.path.join(dist_dir,pdf_name)).st_mtime try: nup_time = os.stat(os.path.join(dist_dir,nup_name)).st_mtime if nup_time > pdf_time: return None except OSError: pass try: os.system('pdfnup --paper a4paper --nup 2x2 --keepinfo -o '+ os.path.join(dist_dir,nup_name)+ ' '+ os.path.join(dist_dir,pdf_name)+ ' "16,1,14,3,2,15,4,13,12,5,10,7,11,6,8,9" ') except OSError: return False def main(): parser = argparse.ArgumentParser(description='Build a distribution format of a 1800 words article', epilog='Prerequisites of required formats are build automatically, but you may want to build the LaTeX source first, edit it by hand and then build the rest.') parser.add_argument('guide', nargs='+', type=basename, help='Source directory of the article') parser.add_argument('-l','--latex',action='store_true', help='Generate LaTeX source') parser.add_argument('-p','--pdf',action='store_true', help='Generate PDF') parser.add_argument('-n','--nup-pdf',action='store_true', help='Generate nup-ed A4 PDF') args = parser.parse_args() for guide in args.guide: if args.latex: build_latex(guide) if args.pdf: build_pdf(guide) if args.nup_pdf: build_nup_pdf(guide) if __name__ == '__main__': main()