orgmunge 0.2.1__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: orgmunge
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Programmatically modify Orgmode documents
5
5
  License: MIT
6
6
  Author: durableOne
@@ -136,21 +136,25 @@ compromising your information. See [[https://github.com/durableOne/redactOrg][re
136
136
  values. The properties are parsed from the =PROPERTIES= drawer if
137
137
  it exists. This attribute can also be set by the user (the value
138
138
  supplied must be a dict).
139
- 2. =headline= returns the heading's headline. This attribute can also
139
+ 2. =inherited_properties=. Same format as the =properties= dict but
140
+ contains only properties inherited from ancestors.
141
+ 3. =tags= returns a list of all tags (those explicitly defined for
142
+ this heading and those inherited)
143
+ 4. =headline= returns the heading's headline. This attribute can also
140
144
  be set by a user (the value must be a [[*Headline Objects][Headline]] instance).
141
- 3. =scheduling= is a [[*Scheduling Objects][Scheduling]] object containing information about
145
+ 5. =scheduling= is a [[*Scheduling Objects][Scheduling]] object containing information about
142
146
  =SCHEDULED/DEADLINE/CLOSED= timestamps of the heading, if any. Can
143
147
  also be set by the user (the value must be a Scheduling instance).
144
- 4. =drawers= is a list of [[*Drawer Objects][Drawer]] objects containing the drawers
148
+ 6. =drawers= is a list of [[*Drawer Objects][Drawer]] objects containing the drawers
145
149
  associated with this heading. When you update the heading's
146
150
  =properties= attribute, the =PROPERTIES= drawer is updated the next
147
151
  time you access it.
148
- 5. =children= returns a list of Heading objects that are the direct
152
+ 7. =children= returns a list of Heading objects that are the direct
149
153
  children of this heading.
150
- 6. =parent= returns the parent heading of the current one. If the
154
+ 8. =parent= returns the parent heading of the current one. If the
151
155
  current heading is a top-level heading, the root heading will be
152
156
  returned.
153
- 7. =sibling= returns the sibling heading of the current one that comes
157
+ 9. =sibling= returns the sibling heading of the current one that comes
154
158
  before it in the tree, if any. The reason this is the sibling
155
159
  heading that is formally tracked is because it's the one that
156
160
  would adopt the current heading whenever the current heading is
@@ -159,34 +163,37 @@ compromising your information. See [[https://github.com/durableOne/redactOrg][re
159
163
  #+begin_src python
160
164
  siblings = [c for c in current_heading.parent.children if c is not current_heading]
161
165
  #+end_src
162
- 8. =level= is the heading's level, with 1 being the top level and each
163
- sub-level after that being incremented by 1 (the heading's level
164
- is the number of "stars" before its headline).
166
+ 10. =level= is the heading's level, with 1 being the top level and each
167
+ sub-level after that being incremented by 1 (the heading's level
168
+ is the number of "stars" before its headline).
165
169
  - Important methods:
166
170
  1. =clocking=. This returns a list of [[*Clocking Objects][Clocking]] objects, parsed
167
171
  from the heading's =LOGBOOK= drawer, if any. You can also pass the
168
172
  optional boolean parameter =include_children=, which, when True,
169
173
  includes clocking information of this heading's children as well.
170
- 2. =add_child= accepts a Heading object to add as a child to the
174
+ 2. =get_all_properties=. This returns a dict of all properties of the
175
+ heading, whether directly defined or inherited from the heading's
176
+ ancestors. The latest-defined value of a property wins over.
177
+ 3. =add_child= accepts a Heading object to add as a child to the
171
178
  current heading. The optional boolean parameter =new= should be set
172
179
  to =True= when this is a new heading that was created and needs to
173
180
  be assigned a parent. It should be set to =False= (default) when
174
181
  the addition of a child is due to a promotion/demotion operation.
175
- 3. =remove_child= accepts a heading object and deletes it from the
182
+ 4. =remove_child= accepts a heading object and deletes it from the
176
183
  current heading's children if it's a child of the current
177
184
  heading.
178
- 4. =promote= promotes the current heading one level. If the heading has
185
+ 5. =promote= promotes the current heading one level. If the heading has
179
186
  children, they would be orphaned so this raises a
180
187
  =ValueError=. Technically, Org allows you to have, say, level 3
181
188
  headings under a level 1 heading, but =orgmunge= does not allow
182
189
  this to make parsing the tree easier.
183
- 5. =promote_tree= promotes the current heading and all its
190
+ 6. =promote_tree= promotes the current heading and all its
184
191
  descendants. Use this if the heading you want to promote has
185
192
  children.
186
- 6. =demote= demotes the current heading one level. If the current
193
+ 7. =demote= demotes the current heading one level. If the current
187
194
  heading has no sibling to adopt it, the demotion attempt fails
188
195
  and raises a =ValueError=.
189
- 7. =demote_tree= is the equivalent of =promote_tree= for demotion.
196
+ 8. =demote_tree= is the equivalent of =promote_tree= for demotion.
190
197
  *** Headline Objects
191
198
  - Important attributes:
192
199
  1. =done= is a boolean attribute that determines whether the headline
@@ -120,21 +120,25 @@ compromising your information. See [[https://github.com/durableOne/redactOrg][re
120
120
  values. The properties are parsed from the =PROPERTIES= drawer if
121
121
  it exists. This attribute can also be set by the user (the value
122
122
  supplied must be a dict).
123
- 2. =headline= returns the heading's headline. This attribute can also
123
+ 2. =inherited_properties=. Same format as the =properties= dict but
124
+ contains only properties inherited from ancestors.
125
+ 3. =tags= returns a list of all tags (those explicitly defined for
126
+ this heading and those inherited)
127
+ 4. =headline= returns the heading's headline. This attribute can also
124
128
  be set by a user (the value must be a [[*Headline Objects][Headline]] instance).
125
- 3. =scheduling= is a [[*Scheduling Objects][Scheduling]] object containing information about
129
+ 5. =scheduling= is a [[*Scheduling Objects][Scheduling]] object containing information about
126
130
  =SCHEDULED/DEADLINE/CLOSED= timestamps of the heading, if any. Can
127
131
  also be set by the user (the value must be a Scheduling instance).
128
- 4. =drawers= is a list of [[*Drawer Objects][Drawer]] objects containing the drawers
132
+ 6. =drawers= is a list of [[*Drawer Objects][Drawer]] objects containing the drawers
129
133
  associated with this heading. When you update the heading's
130
134
  =properties= attribute, the =PROPERTIES= drawer is updated the next
131
135
  time you access it.
132
- 5. =children= returns a list of Heading objects that are the direct
136
+ 7. =children= returns a list of Heading objects that are the direct
133
137
  children of this heading.
134
- 6. =parent= returns the parent heading of the current one. If the
138
+ 8. =parent= returns the parent heading of the current one. If the
135
139
  current heading is a top-level heading, the root heading will be
136
140
  returned.
137
- 7. =sibling= returns the sibling heading of the current one that comes
141
+ 9. =sibling= returns the sibling heading of the current one that comes
138
142
  before it in the tree, if any. The reason this is the sibling
139
143
  heading that is formally tracked is because it's the one that
140
144
  would adopt the current heading whenever the current heading is
@@ -143,34 +147,37 @@ compromising your information. See [[https://github.com/durableOne/redactOrg][re
143
147
  #+begin_src python
144
148
  siblings = [c for c in current_heading.parent.children if c is not current_heading]
145
149
  #+end_src
146
- 8. =level= is the heading's level, with 1 being the top level and each
147
- sub-level after that being incremented by 1 (the heading's level
148
- is the number of "stars" before its headline).
150
+ 10. =level= is the heading's level, with 1 being the top level and each
151
+ sub-level after that being incremented by 1 (the heading's level
152
+ is the number of "stars" before its headline).
149
153
  - Important methods:
150
154
  1. =clocking=. This returns a list of [[*Clocking Objects][Clocking]] objects, parsed
151
155
  from the heading's =LOGBOOK= drawer, if any. You can also pass the
152
156
  optional boolean parameter =include_children=, which, when True,
153
157
  includes clocking information of this heading's children as well.
154
- 2. =add_child= accepts a Heading object to add as a child to the
158
+ 2. =get_all_properties=. This returns a dict of all properties of the
159
+ heading, whether directly defined or inherited from the heading's
160
+ ancestors. The latest-defined value of a property wins over.
161
+ 3. =add_child= accepts a Heading object to add as a child to the
155
162
  current heading. The optional boolean parameter =new= should be set
156
163
  to =True= when this is a new heading that was created and needs to
157
164
  be assigned a parent. It should be set to =False= (default) when
158
165
  the addition of a child is due to a promotion/demotion operation.
159
- 3. =remove_child= accepts a heading object and deletes it from the
166
+ 4. =remove_child= accepts a heading object and deletes it from the
160
167
  current heading's children if it's a child of the current
161
168
  heading.
162
- 4. =promote= promotes the current heading one level. If the heading has
169
+ 5. =promote= promotes the current heading one level. If the heading has
163
170
  children, they would be orphaned so this raises a
164
171
  =ValueError=. Technically, Org allows you to have, say, level 3
165
172
  headings under a level 1 heading, but =orgmunge= does not allow
166
173
  this to make parsing the tree easier.
167
- 5. =promote_tree= promotes the current heading and all its
174
+ 6. =promote_tree= promotes the current heading and all its
168
175
  descendants. Use this if the heading you want to promote has
169
176
  children.
170
- 6. =demote= demotes the current heading one level. If the current
177
+ 7. =demote= demotes the current heading one level. If the current
171
178
  heading has no sibling to adopt it, the demotion attempt fails
172
179
  and raises a =ValueError=.
173
- 7. =demote_tree= is the equivalent of =promote_tree= for demotion.
180
+ 8. =demote_tree= is the equivalent of =promote_tree= for demotion.
174
181
  *** Headline Objects
175
182
  - Important attributes:
176
183
  1. =done= is a boolean attribute that determines whether the headline
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "orgmunge"
3
- version = "0.2.1"
3
+ version = "0.2.2"
4
4
  description = "Programmatically modify Orgmode documents"
5
5
  authors = ["durableOne <era31asj@gmail.com>"]
6
6
  license = "MIT"
@@ -135,7 +135,6 @@ class Priority:
135
135
  return False
136
136
  else:
137
137
  return str(self) == str(other)
138
-
139
138
  class Headline:
140
139
  def __init__(self, todos, level: str, comment: bool = False,
141
140
  todo: Optional[str] = None, priority: Optional[str] = None,
@@ -159,10 +158,10 @@ class Headline:
159
158
  raise AttributeError("Can't set the 'done' attribute")
160
159
 
161
160
  def _is_done(self):
162
- if self.todo in self._done_states:
163
- return True
164
- elif self.todo is None or self.todo in self._todo_states:
161
+ if self.todo is None or self.todo in self._todo_states:
165
162
  return False
163
+ elif self.todo in self._done_states:
164
+ return True
166
165
  else:
167
166
  raise ValueError(f"Uncategorized todo state {self.todo}")
168
167
 
@@ -252,7 +251,6 @@ class Headline:
252
251
  return False
253
252
  else:
254
253
  return str(self) == str(other)
255
-
256
254
  class TimeStamp:
257
255
  def __init__(self, timestamp_str: str):
258
256
  is_active = re.search(Lexer.ATIMESTAMP, timestamp_str)
@@ -376,7 +374,6 @@ class TimeStamp:
376
374
  return False
377
375
  else:
378
376
  return str(self) == str(other)
379
-
380
377
  class Scheduling:
381
378
  _closed = None
382
379
  _scheduled = None
@@ -442,7 +439,6 @@ class Scheduling:
442
439
  return False
443
440
  else:
444
441
  return str(self) == str(other)
445
-
446
442
  class Drawer:
447
443
  def __init__(self, drawer_string: str):
448
444
  self.name = re.sub(r':', '', drawer_string.split('\n')[0])
@@ -458,7 +454,6 @@ class Drawer:
458
454
  return False
459
455
  else:
460
456
  return str(self) == str(other)
461
-
462
457
  class Clocking:
463
458
  def __init__(self, start_time: str, end_time: Optional[str] = None):
464
459
  self._start_time = dt.strptime(start_time, ORG_TIME_FORMAT)
@@ -526,7 +521,6 @@ class Clocking:
526
521
  return False
527
522
  else:
528
523
  return str(self) == str(other)
529
-
530
524
  class Heading():
531
525
  def __init__(self, headline: Headline, contents: Tuple[Scheduling, List[Drawer], str]):
532
526
  self._headline = headline
@@ -534,6 +528,7 @@ class Heading():
534
528
  self._children = []
535
529
  self._parent = None
536
530
  self._sibling = None
531
+ self._inherited_properties = dict()
537
532
  if self.body:
538
533
  self.timestamps = [TimeStamp(t[0]) for t in re.findall(fr'({Lexer.ATIMESTAMP}|{Lexer.ITIMESTAMP})', self.body)]
539
534
  if self._drawers:
@@ -580,6 +575,27 @@ class Heading():
580
575
  def _get_properties_string(self) -> str:
581
576
  return "\n".join([f":{k}:{' '*7}{v}" for k, v in self.properties.items()])
582
577
 
578
+ @property
579
+ def inherited_properties(self):
580
+ if not self._inherited_properties:
581
+ if self.parent:
582
+ self._inherited_properties = {**self.parent.inherited_properties, **self.parent.properties}
583
+ return self._inherited_properties
584
+
585
+ @inherited_properties.setter
586
+ def inherited_properties(self, _):
587
+ raise AttributeError("Can't set the inherited properties of a heading")
588
+
589
+ @property
590
+ def tags(self):
591
+ self_tags = self.headline.tags or []
592
+ parent_tags = (self.parent.tags if self.parent else None) or []
593
+ return list(set(self_tags + parent_tags))
594
+
595
+ @tags.setter
596
+ def tags(self, _):
597
+ raise AttributeError("Can't set the tags of a heading, use headline instead.")
598
+
583
599
  @property
584
600
  def properties(self):
585
601
  return self._properties
@@ -593,6 +609,9 @@ class Heading():
593
609
  for key in val:
594
610
  self._properties[key] = val[key]
595
611
 
612
+ def get_all_properties(self) -> Dict[str, str]:
613
+ return {**self.inherited_properties, **self.properties}
614
+
596
615
  def clocking(self, include_children: bool = False) -> List[Clocking]:
597
616
  "Return the clocking information of the given headline and possibly its children."
598
617
  own_clocking = self._get_clocking_info()
File without changes
File without changes