Taking advantage of the new org-batch-agenda-csv functionality, I've
written a little Python script for exporting an org agenda to PDF,
using LaTeX as an intermediary. Currently, it's a bit of a crude
'worksforme' implementation that could be cleaned up a lot and made
more general. Quite a bit of stuff is hardcoded into some LaTeX
headers/footers that are stored as python strings at the top of the
file. Still, it's at the point that it is, in principle, useful, and
I thought I'd post it here for some feedback before putting it on my
website, announcing on the 43Folders board, etc.
#!/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()
--
+-----------------------------------------------------------+
| Jason F. McBrayer [EMAIL PROTECTED] |
| If someone conquers a thousand times a thousand others in |
| battle, and someone else conquers himself, the latter one |
| is the greatest of all conquerors. --- The Dhammapada |
_______________________________________________
Emacs-orgmode mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/emacs-orgmode