1 package Org::Element::Headline;
6 extends 'Org::Element';
8 our $VERSION = '0.23'; # VERSION
10 has level => (is => 'rw');
11 has title => (is => 'rw');
12 has todo_priority => (is => 'rw');
13 has tags => (is => 'rw');
14 has is_todo => (is => 'rw');
15 has is_done => (is => 'rw');
16 has todo_state => (is => 'rw');
17 has progress => (is => 'rw');
19 sub header_as_string {
21 return $self->_str if defined $self->_str;
25 $self->is_todo ? $self->todo_state." " : "",
26 $self->todo_priority ? "[#".$self->todo_priority."] " : "",
27 $self->title->as_string,
28 $self->tags && @{$self->tags} ?
29 " :".join(":", @{$self->tags}).":" : "",
35 $self->header_as_string . $self->children_as_string;
39 my ($self, $name, $search_parent) = @_;
40 my @res = @{ $self->tags // [] };
43 my ($el, $parent) = @_;
44 return 1 unless $parent->isa('Org::Element::Headline');
46 for (@{ $parent->tags }) {
47 push @res, $_ unless $_ ~~ @res;
52 for (@{ $self->document->tags }) {
53 push @res, $_ unless $_ ~~ @res;
58 sub get_active_timestamp {
61 for my $s ($self->title, $self) {
67 $ats = $el if $el->isa('Org::Element::Timestamp') &&
79 return 1 unless $self->children;
82 for my $child (@{ $self->children }) {
85 return if defined($res);
87 if ($el->isa('Org::Element::Headline')) {
100 my ($self, $num_levels) = @_;
102 return if $num_levels == 0;
103 die "Please specify a positive number of levels" if $num_levels < 0;
105 for my $i (1..$num_levels) {
107 my $l = $self->level;
114 my $parent = $self->parent;
115 my $siblings = $parent->children;
116 my $pos = $self->seniority;
118 # our children stay as children
120 # our right sibling headline(s) become children
122 my $s = $siblings->[$pos+1];
123 last unless $s && $s->isa('Org::Element::Headline')
125 $self->children([]) unless defined $self->children;
126 push @{$self->children}, $s;
127 splice @$siblings, $pos+1, 1;
131 # our parent headline can become sibling if level is the same
132 if ($parent->isa('Org::Element::Headline') && $parent->level == $l) {
133 splice @$siblings, $pos, 1;
134 my $gparent = $parent->parent;
135 splice @{$gparent->children}, $parent->seniority+1, 0, $self;
136 $self->parent($gparent);
143 my ($self, $num_levels) = @_;
145 return if $num_levels == 0;
146 die "Please specify a positive number of levels" if $num_levels < 0;
148 for my $i (1..$num_levels) {
150 my $l = $self->level;
156 # prev sibling can become parent
157 my $ps = $self->prev_sibling;
158 if ($ps && $ps->isa('Org::Element::Headline') && $ps->level < $l) {
159 splice @{$self->parent->children}, $self->seniority, 1;
160 $ps->children([]) if !defined($ps->children);
161 push @{$ps->children}, $self;
169 my ($self, $num_levels) = @_;
171 return if $num_levels == 0;
172 die "Please specify a positive number of levels" if $num_levels < 0;
174 for my $i (1..$num_levels) {
175 last if $self->level <= 1;
176 $_->promote_node() for $self->find('Headline');
181 my ($self, $num_levels) = @_;
183 return if $num_levels == 0;
184 die "Please specify a positive number of levels" if $num_levels < 0;
186 for my $i (1..$num_levels) {
187 $_->demote_node() for $self->find('Headline');
192 # ABSTRACT: Represent Org headline
199 Org::Element::Headline - Represent Org headline
207 Derived from L<Org::Element>.
213 Level of headline (e.g. 1, 2, 3). Corresponds to the number of bullet stars.
217 L<Org::Element::Text> representing the headline title
219 =head2 todo_priority => STR
221 String (optional) representing priority.
225 Arrayref (optional) containing list of defined tags.
227 =head2 is_todo => BOOL
229 Whether this headline is a TODO item.
231 =head2 is_done => BOOL
233 Whether this TODO item is in a done state (state which requires no more action,
234 e.g. DONE). Only meaningful if headline is a TODO item.
236 =head2 todo_state => STR
240 =head2 progress => STR
246 =for Pod::Coverage header_as_string as_string
248 =head2 $el->get_tags() => ARRAY
250 Get tags for this headline. A headline can define tags or inherit tags from its
251 parent headline (or from document).
253 =head2 $el->get_active_timestamp() => ELEMENT
255 Get the first active timestamp element for this headline, either in the title or
256 in the child elements.
258 =head2 $el->is_leaf() => BOOL
260 Returns true if element doesn't contain subtrees.
262 =head2 $el->promote_node([$num_levels])
264 Promote (decrease the level) of this headline node. $level specifies number of
265 levels, defaults to 1. Won't further promote if already at level 1.
269 ** h2 <-- promote 1 level
284 =head2 $el->demote_node([$num_levels])
286 Does the opposite of promote_node().
288 =head2 $el->promote_branch([$num_levels])
290 Like promote_node(), but all children headlines will also be promoted.
294 ** h2 <-- promote 1 level
313 =head2 $el->demote_branch([$num_levels])
315 Does the opposite of promote_branch().
319 Steven Haryanto <stevenharyanto@gmail.com>
321 =head1 COPYRIGHT AND LICENSE
323 This software is copyright (c) 2012 by Steven Haryanto.
325 This is free software; you can redistribute it and/or modify it under
326 the same terms as the Perl 5 programming language system itself.