emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: jmcbray@carcosa.net (Jason F. McBrayer)
To: emacs-orgmode <emacs-orgmode@gnu.org>
Subject: A little agenda printer script
Date: Mon, 21 May 2007 09:39:36 -0400	[thread overview]
Message-ID: <m1sl9qmh2f.fsf@bertrand.carcosa.net> (raw)

[-- Attachment #1: Type: text/plain, Size: 592 bytes --]

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.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: org agenda to pdf python script --]
[-- Type: text/x-python, Size: 4626 bytes --]

#!/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()

[-- Attachment #3: Type: text/plain, Size: 316 bytes --]



-- 
+-----------------------------------------------------------+
| Jason F. McBrayer                    jmcbray@carcosa.net  |
| 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    |

[-- Attachment #4: Type: text/plain, Size: 149 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

             reply	other threads:[~2007-05-21 13:39 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-21 13:39 Jason F. McBrayer [this message]
2007-05-21 23:32 ` A little agenda printer script Bastien
2007-05-22 13:16   ` Jason F. McBrayer
2007-05-22  5:00 ` Carsten Dominik
2007-05-22 13:11   ` Jason F. McBrayer
2007-05-23  8:13     ` Carsten Dominik
2007-05-24 21:45 ` Xavier Maillard
2007-06-03 20:05   ` Jason F. McBrayer
2007-06-03 20:17     ` Leo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m1sl9qmh2f.fsf@bertrand.carcosa.net \
    --to=jmcbray@carcosa.net \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).