Skip to content

Commit

Permalink
treat filetags as tags + make file properties case insensitive
Browse files Browse the repository at this point in the history
  • Loading branch information
karlicoss committed Nov 6, 2020
1 parent ab521ce commit 65465ad
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
26 changes: 17 additions & 9 deletions orgparse/node.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re
import itertools
from typing import List, Iterable, Iterator, Optional, Union, Tuple, cast, Dict, Set
from typing import List, Iterable, Iterator, Optional, Union, Tuple, cast, Dict, Set, Sequence
try:
from collections.abc import Sequence
except ImportError:
Expand Down Expand Up @@ -146,21 +146,24 @@ def parse_property(line: str) -> Tuple[Optional[str], Optional[PropertyValue]]:
RE_PROP = re.compile(r'^\s*:(.*?):\s*(.*?)\s*$')


def parse_comment(line):
def parse_comment(line: str): # -> Optional[Tuple[str, Sequence[str]]]: # todo wtf?? it says 'ABCMeta isn't subscriptable??'
"""
Parse special comment such as ``#+SEQ_TODO``
>>> parse_comment('#+SEQ_TODO: TODO | DONE')
('SEQ_TODO', 'TODO | DONE')
('SEQ_TODO', ['TODO | DONE'])
>>> parse_comment('# not a special comment') # None
>>> parse_comment('#+FILETAGS: :tag1:tag2:')
('FILETAGS', ['tag1', 'tag2'])
"""
match = re.match(r'\s*#\+', line)
if match:
end = match.end(0)
comment = line[end:].split(':')
if len(comment) == 2:
return (comment[0], comment[1].strip())
if len(comment) >= 2:
return (comment[0], [c.strip() for c in comment[1:] if len(c.strip()) > 0])
return None


def parse_seq_todo(line):
Expand Down Expand Up @@ -642,8 +645,9 @@ def _parse_comments(self):
for line in self._lines:
parsed = parse_comment(line)
if parsed:
(key, val) = parsed
special_comments.setdefault(key, []).append(val)
(key, vals) = parsed
key = key.upper() # case insensitive, so keep as uppercase
special_comments.setdefault(key, []).extend(vals)
self._special_comments = special_comments
# parse TODO keys and store in OrgEnv
for todokey in ['TODO', 'SEQ_TODO', 'TYP_TODO']:
Expand Down Expand Up @@ -770,14 +774,14 @@ def get_file_property_list(self, property):
"""
Return a list of the selected property
"""
vals = self._special_comments.get(property, None)
vals = self._special_comments.get(property.upper(), None)
return [] if vals is None else vals

def get_file_property(self, property):
"""
Return a single element of the selected property or None if it doesn't exist
"""
vals = self._special_comments.get(property, None)
vals = self._special_comments.get(property.upper(), None)
if vals is None:
return None
elif len(vals) == 1:
Expand Down Expand Up @@ -805,6 +809,10 @@ def _body_lines(self) -> List[str]: # type: ignore[override]
def heading(self) -> str:
return ''

def _get_tags(self, inher=False) -> Set[str]:
filetags = self.get_file_property_list('FILETAGS')
return set(filetags)

@property
def level(self):
return 0
Expand Down
19 changes: 17 additions & 2 deletions orgparse/tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def test_root() -> None:
assert len(root.children) == 1
# todo not sure if should strip special comments??
assert root.body.endswith('Whatever\n# comment')
assert root.heading == ''


def test_stars():
Expand Down Expand Up @@ -119,13 +120,14 @@ def test_get_file_property():
root = loads(content)
assert root.get_file_property('Nosuchproperty') is None
assert root.get_file_property_list('TITLE') == ['Test title']
assert root.get_file_property('TITLE') == 'Test title'
# also it's case insensitive
assert root.get_file_property('title') == 'Test title'
assert root.get_file_property_list('Nosuchproperty') == []

def test_get_file_property_multivalued():
content = """ #+TITLE: Test
#+OTHER: Test title
#+TITLE: alternate title
#+title: alternate title
* Node 1
test 1
Expand All @@ -141,3 +143,16 @@ def test_get_file_property_multivalued():
with pytest.raises(RuntimeError):
# raises because there are multiple of them
root.get_file_property('TITLE')

def test_filetags_are_tags() -> None:
content = '''
#+FILETAGS: :f1:f2:
* heading :h1:
** child :f2:
'''.strip()
root = loads(content)
# breakpoint()
assert root.tags == {'f1', 'f2'}
child = root.children[0].children[0]
assert child.tags == {'f1', 'f2', 'h1'}

0 comments on commit 65465ad

Please sign in to comment.