]> git.donarmstrong.com Git - liborg-parser-perl.git/blob - lib/Org/Parser.pm
Import original source of Org-Parser 0.23
[liborg-parser-perl.git] / lib / Org / Parser.pm
1 package Org::Parser;
2
3 use 5.010;
4 use Moo;
5
6 use File::Slurp;
7 use Org::Document;
8 use Scalar::Util qw(blessed);
9
10 our $VERSION = '0.23'; # VERSION
11
12 sub parse {
13     my ($self, $arg, $opts) = @_;
14     die "Please specify a defined argument to parse()\n" unless defined($arg);
15
16     $opts //= {};
17
18     my $str;
19     my $r = ref($arg);
20     if (!$r) {
21         $str = $arg;
22     } elsif ($r eq 'ARRAY') {
23         $str = join "", @$arg;
24     } elsif ($r eq 'GLOB' || blessed($arg) && $arg->isa('IO::Handle')) {
25         $str = join "", <$arg>;
26     } elsif ($r eq 'CODE') {
27         my @chunks;
28         while (defined(my $chunk = $arg->())) {
29             push @chunks, $chunk;
30         }
31         $str = join "", @chunks;
32     } else {
33         die "Invalid argument, please supply a ".
34             "string|arrayref|coderef|filehandle\n";
35     }
36     Org::Document->new(from_string=>$str, time_zone=>$opts->{time_zone});
37 }
38
39 sub parse_file {
40     my ($self, $filename, $opts) = @_;
41     $self->parse(scalar read_file($filename), $opts);
42 }
43
44 1;
45 # ABSTRACT: Parse Org documents
46
47
48 =pod
49
50 =head1 NAME
51
52 Org::Parser - Parse Org documents
53
54 =head1 VERSION
55
56 version 0.23
57
58 =head1 SYNOPSIS
59
60  use 5.010;
61  use Org::Parser;
62  my $orgp = Org::Parser->new();
63
64  # parse a file
65  my $doc = $orgp->parse_file("$ENV{HOME}/todo.org");
66
67  # parse a string
68  $doc = $orgp->parse(<<EOF);
69  #+TODO: TODO | DONE CANCELLED
70  <<<radio target>>>
71  * heading1a
72  ** TODO heading2a
73  SCHEDULED: <2011-03-31 Thu>
74  [[some][link]]
75  ** DONE heading2b
76  [2011-03-18 ]
77  this will become a link: radio target
78  * TODO heading1b *bold*
79  - some
80  - plain
81  - list
82  - [ ] with /checkbox/
83    * and
84    * sublist
85  * CANCELLED heading1c
86  + definition :: list
87  + another :: def
88  EOF
89
90  # walk the document tree
91  $doc->walk(sub {
92      my ($el) = @_;
93      return unless $el->isa('Org::Element::Headline');
94      say "heading level ", $el->level, ": ", $el->title->as_string;
95  });
96
97 will print something like:
98
99  heading level 1: heading1a
100  heading level 2: heading2a
101  heading level 2: heading2b *bold*
102  heading level 1: heading1b
103  heading level 1: heading1c
104
105 A command-line utility (in a separate distribution: L<App::OrgUtils>) is
106 available for debugging:
107
108  % dump-org-structure ~/todo.org
109  Document:
110    Setting: "#+TODO: TODO | DONE CANCELLED\n"
111    RadioTarget: "<<<radio target>>>"
112    Text: "\n"
113    Headline: l=1
114      (title)
115      Text: "heading1a"
116      (children)
117      Headline: l=2 todo=TODO
118        (title)
119        Text: "heading2a"
120        (children)
121        Text: "SCHEDULED: "
122  ...
123
124 =head1 DESCRIPTION
125
126 This module parses Org documents. See http://orgmode.org/ for more details on
127 Org documents.
128
129 This module uses L<Log::Any> logging framework.
130
131 This module uses L<Moo> object system.
132
133 See C<todo.org> in the distribution for the list of already- and not yet
134 implemented stuffs.
135
136 =head1 ATTRIBUTES
137
138 =head1 METHODS
139
140 =head2 new()
141
142 Create a new parser instance.
143
144 =head2 $orgp->parse($str | $arrayref | $coderef | $filehandle, $opts) => $doc
145
146 Parse document (which can be contained in a scalar $str, an array of lines
147 $arrayref, a subroutine which will be called for chunks until it returns undef,
148 or a filehandle).
149
150 Returns L<Org::Document> object.
151
152 If 'handler' attribute is specified, will call handler repeatedly during
153 parsing. See the 'handler' attribute for more details.
154
155 Will die if there are syntax errors in documents.
156
157 $opts is a hashref and can contain these keys: C<time_zone> (will be passed to
158 Org::Document's constructor).
159
160 =head2 $orgp->parse_file($filename, $opts) => $doc
161
162 Just like parse(), but will load document from file instead.
163
164 =head1 FAQ
165
166 =head2 Why? Just as only perl can parse Perl, only org-mode can parse Org anyway!
167
168 True. I'm only targetting good enough. As long as I can parse/process all my Org
169 notes and todo files, I have no complaints.
170
171 =head2 It's too slow!
172
173 Parser is completely regex-based at the moment (I plan to use L<Marpa> someday).
174 Performance is quite lousy but I'm not annoyed enough at the moment to overhaul
175 it.
176
177 =head1 SEE ALSO
178
179 L<Org::Document>
180
181 =head1 AUTHOR
182
183 Steven Haryanto <stevenharyanto@gmail.com>
184
185 =head1 COPYRIGHT AND LICENSE
186
187 This software is copyright (c) 2012 by Steven Haryanto.
188
189 This is free software; you can redistribute it and/or modify it under
190 the same terms as the Perl 5 programming language system itself.
191
192 =cut
193
194
195 __END__
196
197
198 1;