diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index 99ac122..686525b 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -752,11 +752,20 @@ class Headline: return times @property - def tags(self): - if isinstance(self.parent, OrgDoc): - return list(self.shallow_tags) - else: - return list(self.shallow_tags) + self.parent.tags + def tags(self) -> list[str]: + parent_tags = self.parent.tags + if self.doc.environment.get("org-use-tag-inheritance"): + accepted_tags = [] + for tag in self.doc.environment.get("org-use-tag-inheritance"): + if tag in parent_tags: + accepted_tags.append(tag) + parent_tags = accepted_tags + + elif self.doc.environment.get("org-tags-exclude-from-inheritance"): + for tag in self.doc.environment.get("org-tags-exclude-from-inheritance"): + if tag in parent_tags: + parent_tags.remove(tag) + return list(self.shallow_tags) + parent_tags def add_tag(self, tag: str): self.shallow_tags.append(tag) @@ -2237,6 +2246,7 @@ class OrgDoc: ): self.todo_keywords = [HeadlineState(name=kw) for kw in DEFAULT_TODO_KEYWORDS] self.done_keywords = [HeadlineState(name=kw) for kw in DEFAULT_DONE_KEYWORDS] + self.environment = environment keywords_set_in_file = False for keyword in keywords: @@ -2280,6 +2290,17 @@ class OrgDoc: def path(self): return self._path + @property + def tags(self) -> list[str]: + for kw in self.keywords: + if kw.key == "FILETAGS": + return kw.value.strip(":").split(":") + return [] + + @property + def shallow_tags(self) -> list[str]: + return self.tags + ## Querying def get_links(self): for headline in self.headlines: diff --git a/tests/13-tags.org b/tests/13-tags.org new file mode 100644 index 0000000..c61ccdf --- /dev/null +++ b/tests/13-tags.org @@ -0,0 +1,13 @@ +#+TITLE: 13-Tags +#+DESCRIPTION: Simple org file to test tags +#+FILETAGS: :filetag: + +* Level 1 :h1tag: + :PROPERTIES: + :ID: 13-tags + :CREATED: [2020-01-01 Wed 01:01] + :END: + +** Level2 :h2tag: +* Level 1-1 :otherh1tag: +** Level2 :otherh2tag: diff --git a/tests/test_org.py b/tests/test_org.py index 6a54395..f27185b 100644 --- a/tests/test_org.py +++ b/tests/test_org.py @@ -865,6 +865,92 @@ class TestSerde(unittest.TestCase): self.assertEqual(dumps(doc), orig) + def test_mimic_write_file_13(self): + with open(os.path.join(DIR, "13-tags.org")) as f: + orig = f.read() + doc = loads(orig) + + self.assertEqual(dumps(doc), orig) + + def test_tag_property_read_13(self): + with open(os.path.join(DIR, "13-tags.org")) as f: + orig = f.read() + doc = loads(orig) + + self.assertEqual(doc.tags, ["filetag"]) + + h1_1, h1_2 = doc.getTopHeadlines() + self.assertEqual(sorted(h1_1.tags), ["filetag", "h1tag"]) + self.assertEqual(sorted(h1_2.tags), ["filetag", "otherh1tag"]) + + h1_1_h2 = h1_1.children[0] + self.assertEqual(sorted(h1_1_h2.tags), ["filetag", "h1tag", "h2tag"]) + + h1_2_h2 = h1_2.children[0] + self.assertEqual(sorted(h1_2_h2.tags), ["filetag", "otherh1tag", "otherh2tag"]) + + def test_shallow_tag_property_read_13(self): + with open(os.path.join(DIR, "13-tags.org")) as f: + orig = f.read() + doc = loads(orig) + + self.assertEqual(doc.shallow_tags, ["filetag"]) + + h1_1, h1_2 = doc.getTopHeadlines() + self.assertEqual(sorted(h1_1.shallow_tags), ["h1tag"]) + self.assertEqual(sorted(h1_2.shallow_tags), ["otherh1tag"]) + + h1_1_h2 = h1_1.children[0] + self.assertEqual(sorted(h1_1_h2.shallow_tags), ["h2tag"]) + + h1_2_h2 = h1_2.children[0] + self.assertEqual(sorted(h1_2_h2.shallow_tags), ["otherh2tag"]) + + def test_exclude_tags_from_inheritance_property_read_13(self): + with open(os.path.join(DIR, "13-tags.org")) as f: + orig = f.read() + doc = loads( + orig, + { + "org-tags-exclude-from-inheritance": ("h1tag", "otherh2tag"), + }, + ) + + self.assertEqual(doc.tags, ["filetag"]) + + h1_1, h1_2 = doc.getTopHeadlines() + self.assertEqual(sorted(h1_1.tags), ["filetag", "h1tag"]) + self.assertEqual(sorted(h1_2.tags), ["filetag", "otherh1tag"]) + + h1_1_h2 = h1_1.children[0] + self.assertEqual(sorted(h1_1_h2.tags), ["filetag", "h2tag"]) + + h1_2_h2 = h1_2.children[0] + self.assertEqual(sorted(h1_2_h2.tags), ["filetag", "otherh1tag", "otherh2tag"]) + + def test_select_tags_to_inheritance_property_read_13(self): + with open(os.path.join(DIR, "13-tags.org")) as f: + orig = f.read() + doc = loads( + orig, + { + "org-tags-exclude-from-inheritance": ("h1tag", "otherh2tag"), + "org-use-tag-inheritance": ("h1tag",), + }, + ) + + self.assertEqual(doc.tags, ["filetag"]) + + h1_1, h1_2 = doc.getTopHeadlines() + self.assertEqual(sorted(h1_1.tags), ["h1tag"]) + self.assertEqual(sorted(h1_2.tags), ["otherh1tag"]) + + h1_1_h2 = h1_1.children[0] + self.assertEqual(sorted(h1_1_h2.tags), ["h1tag", "h2tag"]) + + h1_2_h2 = h1_2.children[0] + self.assertEqual(sorted(h1_2_h2.tags), ["otherh2tag"]) + def print_tree(tree, indentation=0, headline=None): for element in tree: