#!/usr/bin/perl

# Convert plan pages from emacs planner-mode to org-mode
#
# Copyright (C) 2012  Andreas Hirczy <mailto:ahi@itp.tugraz.at>
#
# Time-stamp: "2012-12-04 13:21:21 (ahi)"

# 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 <http://www.gnu.org/licenses/>.


=pod

=head1 NAME

muse2org - convert plan pages from emacs planner mode to org-mode

=head1 SYNOPSYS

muse2org

=head1 DESCRIPTION

B<muse2org> was written to convert all project planning data from I<Emacs>
I<planner-mode> (basing on I<muse-mode>) to Emacs I<org-mode>.  The program
tries to iterate over every plan page in your current working directory
(skipping day pages) and creating org file in a subdiretory org. It converts
some planner entries to their org-mode equivalent while copying the rest of
the file verbatim.

B<muse2org> is a perl script intended to be used outside of emacs and allows
me to play with orgmode using "live" data while still continue work with
planner.

Those entries are converted:

=over

=item *

tasks - including status and priority; links to day pages are converted to
either an F<SCHEDULED> active date or an F<CLOSED> inactive date.

=item *

links to mail messages in Gnus

=item *

links to bbdb entries (might be flaky)

=back

Since I never had much information on I<day pages>, I did not care for them.
B<Be aware: Notes on day pages will not be transferred!> Feel free to provide
me with code snippets for inclusion, but you are basically on your own.

=head1 OPTIONS

B<None> - any parameter given on the command line presents this documentation
message.

=head1 SEE ALSO

=head2 Emacs Org Mode

L<http://orgmode.org/>

The Org Manual: L<http://orgmode.org/org.html>

Org Mode - Organize Your Life In Plain Text!
L<http://doc.norang.ca/org-mode.html>

=head2 Planner Mode

L<http://www.emacswiki.org/emacs/PlannerMode>

L<http://www.emacswiki.org/emacs/PlannerModeMethods>

=head2 other migration tools

Worg: Can I migrate from Planner? -
L<http://orgmode.org/worg/org-faq.html#sec-5-14>

L<http://www.c0t0d0s0.de/plan2org/plan2org.pl> did not work for me out of the
box, since my tasks are marked with priority and task number. Otherwise
plan2org is similar in spirit to this program.

L<https://github.com/jave/planner-org-freundschaft> seems to be used in an
interactive way - transfering incrementally single tasks or small pieces of
information to org as seen fit by the user. Not usable for me, but might be
much better suited to the task when most of your information is on day pages.

=head1 LICENSE

Copyright 2012, Andreas Hirczy <ahi@itp.tugraz.at>

B<muse2org> is distributed under the GNU General Public License.  B<muse2org>
is available from L<http://itp.tugraz.at/~ahi/Computer/SW/muse2org>

=head2 GNU General Public License

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 L<http://www.gnu.org/licenses/>.

=cut

if (scalar @ARGV) {
  use Pod::Usage;
  pod2usage(-exitstatus => 0, -verbose => 2);
}

# Destination Directory for Org-Files
$destination = "./org";
mkdir $destination;

# Maps planner task states to org states
%statemap = (
	     'C' => 'CANCELLED', # (cancelled)
	     'D' => 'TODO',      # (delegated) ???
	     'P' => 'WAITING',   # (pending)
	     'X' => 'DONE',      # (done)
	     '_' => 'TODO',      # (open)
	     'o' => 'NEXT',      # (in progress)
	    );


foreach $muse (glob("*.muse")) {
  # dont convert day pages
  next if ($muse =~ /\d{4}\.\d{2}\.\d{2}\.muse/);

  # find name for org file
  my $org=$destination . "/" . $muse;
  $org =~ s/.muse$/.org/;

  convert($muse, $org);
}
exit 0;

# CONVERT a single existing planner file ($muse) to a new org-file ($org)
sub convert {
  my ($muse, $org) = @_;
  print "converting $muse to $org ...\n";
  open (MUSE, "<", $muse) or die "cannot open < $muse";
  open (ORG,  ">", $org ) or die "cannot open > $org";

  while (<MUSE>) {
    s/ \{\{Tasks:\d+\}\}//;                        # strip task-IDs

    # convert tasks
    s/^\#([ABC])[\d ]{3}([_X]) /** $statemap{$2} [#$1] /;

    # convert links to day pages to timestamps
    if ((/ TODO /) or (/ WAITING /) or (/ STARTED /)) {
      s/ \(\[\[(\d{4})\.(\d{2})\.(\d{2})\]\]\)/\n   SCHEDULED: <$1-$2-$3>/;
    }
    if ((/ DONE /) or (/ CANCELLED /)) {
      s/ \(\[\[(\d{4})\.(\d{2})\.(\d{2})\]\]\)/\n   CLOSED: [$1-$2-$3]/;
    }

    # convert links to BBDB, GNUS, ....
    s/bbdb:\/\//bbdb:/;
    s/gnus:\/\/([\w+:]+)\/<(.*)\>/gnus:$1#$2/; # TODO works for me but check this better ############

    # convert muse-mode links [[foobar]] -> [[file:foobar.org][foobar]]
    s/\[\[([^:\\\/\[\]]*)\]\]/\[\[file:$1\.org\]\[$1\]\]/g;

    # convert other muse-mode links: [[foo][bar]] -> [[file:foo.org][bar]]
    s/\[\[([^:\\\/\[\]]*)\]\[(.*)\]\]/\[\[file:$1\.org\]\[$2\]\]/g;

    print ORG $_;
  }

  close MUSE;
  close ORG;
}
