#!/usr/bin/python # # pyagenda -- export an org agenda to PDF # # (c) 2007, Jason F. McBrayer # Version: 1.0 # This file is a stand-alone program. # # Legalese: # pyagenda 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 2, or (at your option) # any later version. # # pyagenda 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. # # Documentation: # pyagenda is a short python program for taking a formatted agenda # from org-mode (via org-batch-agenda-csv) and producing a PDF-format # planner page that can be inserted in a planner binder. Run # 'pyagenda --help' for usage. # # Currently, this is only a crude 'worksforme' implementation, with # many things being hardcoded. It produces an output file named # cmdkey.pdf where 'cmdkey' is the key given to # org-agenda-custom-commands. Not all arbitrary searches will work. # Be aware that it may overwrite cmdkey.tex, cmdkey.log, cmdkey.aux, # etc. The output size is hardcoded to 5.5x8.0in, which is suitable # for a Circa or Rollabind junior sized planner. The output is not # suitable for daily/weekly agenda views, and does not present all the # information it could. If you want to change any of the output, edit # the TEX_* constants. # # TODO: # 1. Use safer tmpfile handling. # 2. Nicer command-line handling. # 3. Prettier output, including use of more of the information # passed by org-batch-agenda-csv. # import csv import sys import os from subprocess import Popen, PIPE, call EMACS = 'emacs' INIT_FILE = "~/.emacs.d/init.el" # Most people should use "~/.emacs" instead AGENDA_COMMAND = '(org-batch-agenda-csv "%s")' TEX_HEADER = """ \\documentclass[twoside, american]{article} \\usepackage[T1]{fontenc} \\usepackage[latin1]{inputenc} \\usepackage{pslatex} \\usepackage{geometry} \\geometry{verbose,paperwidth=5.5in,paperheight=8in,tmargin=0.25in,bmargin=0.25in,lmargin=0.5in,rmargin=0.25in} \\pagestyle{empty} \\setlength{\\parskip}{\\medskipamount} \\setlength{\\parindent}{0pt} \\usepackage{calc} \\makeatletter \\newcommand{\\myline}[1]{ {#1 \\hrule width \\columnwidth } } \\usepackage{babel} \\makeatother \\begin{document} \\part*{\\textsf{Actions}\\hfill{}%% \\framebox{\\begin{minipage}[t][1em][t]{0.25\\paperwidth}%% \\textsf{%s} \\hfill{}%% \\end{minipage}}%% \\protect \\\\ } \\myline{\\normalsize} """ TEX_FOOTER = """ \\end{document} """ TEX_ITEM = """ %% \\framebox{\\begin{minipage}[c][0.5em][c]{0.5em}%% \\hfill{}%% \\end{minipage}}%% %% \\begin{minipage}[c][1em]{1em}%% \\hfill{}%% \\end{minipage}%% \\textsf{%s}\\\\ \\myline{\\normalsize} """ class AgendaItem(object): def __init__(self, data=None): if data: self.category = data[0] self.headline = data[1] self.type = data[2] self.todo = data[3] self.tags = data[4].split(':') self.date = data[5] self.time = data[6] self.extra = data[7] self.prio = data[8] self.fullprio = data[9] def get_agenda_items(cmdkey): output = Popen([EMACS, "-batch", "-l", INIT_FILE, "-eval", AGENDA_COMMAND % cmdkey ], stdout=PIPE, stderr=PIPE) reader = csv.reader(output.stdout) items = [] for row in reader: items.append(AgendaItem(row)) return items def usage(): print "Usage: pyagenda 'cmd-key' [label]" print " cmd-key is an org agenda custom command key, or an " print " org-agenda tags/todo match string." print " label (optional) is a context label to be printed " print " at the top of your agenda page." def main(): try: search = sys.argv[1] except IndexError: usage() sys.exit(1) if search == "--help" or search == "-h": usage() sys.exit(0) try: label = sys.argv[2] except IndexError: label = "" texfile = file(search + ".tex", 'w') texfile.write(TEX_HEADER % label + "\n") for item in get_agenda_items(search): texfile.write(TEX_ITEM % item.headline.replace('&', r'\&') + "\n" ) texfile.write(TEX_FOOTER) texfile.close() call(['pdflatex', texfile.name], stdout=PIPE, stderr=PIPE) os.unlink(texfile.name) os.unlink(search + ".aux") os.unlink(search + ".log") if __name__ == '__main__': main()