From 72d5cadb96dbf8a5d6d72b2734190c1f86facd73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Tue, 3 Aug 2021 22:13:41 +0200 Subject: [PATCH 1/3] Improve NODE_PROPERTIES parsing. --- org_rw/org_rw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index 413c7c7..800b46e 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -56,7 +56,7 @@ KEYWORDS_RE = re.compile( DRAWER_START_RE = re.compile(r"^(?P\s*):([^:]+):(?P\s*)$") DRAWER_END_RE = re.compile(r"^(?P\s*):END:(?P\s*)$", re.I) NODE_PROPERTIES_RE = re.compile( - r"^(?P\s*):(?P[^ +:]+)(?P\+)?:(?P\s*)(?P.+)$" + r"^(?P\s*):(?P[^ ()+:]+)(?P\+)?:(?P\s*)(?P.+)$" ) RAW_LINE_RE = re.compile(r"^\s*([^\s#:*]|$)") BASE_TIME_STAMP_RE = r"(?P\d{4})-(?P\d{2})-(?P\d{2})( ?(?P[^ ]+))?( (?P\d{1,2}):(?P\d{1,2})(-+(?P\d{1,2}):(?P\d{1,2}))?)?(?P (?P(\+|\+\+|\.\+|-|--))(?P\d+)(?P[hdwmy]))?" From 3b6358c1950e5d201673315ac910792c63a758a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Tue, 3 Aug 2021 22:15:38 +0200 Subject: [PATCH 2/3] Add method to get OrgDoc property. --- org_rw/org_rw.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index 800b46e..47843bf 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -1292,6 +1292,13 @@ class OrgDoc: for content in self.contents: yield from get_links_from_content(content) + def get_property(self, name: str, default=None): + for prop in self.keywords: + if prop.key == name: + return prop.value + + return default + def getProperties(self): return self.keywords From 6943ebad7c881f1ff8fc5d0a0a87b1174ea7360b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Tue, 3 Aug 2021 22:37:03 +0200 Subject: [PATCH 3/3] Add support for org-roam-v2 style files. --- org_rw/org_rw.py | 40 +++++++++++++++++++++++++++++++++++----- tests/07-org-roam-v2.org | 13 +++++++++++++ tests/test_org.py | 12 ++++++++++++ 3 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 tests/07-org-roam-v2.org diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index 47843bf..e26ee01 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -1261,7 +1261,9 @@ def parse_headline(hl, doc, parent) -> Headline: class OrgDoc: - def __init__(self, headlines, keywords, contents, list_items): + def __init__( + self, headlines, keywords, contents, list_items, structural, properties + ): self.todo_keywords = DEFAULT_TODO_KEYWORDS self.done_keywords = DEFAULT_DONE_KEYWORDS @@ -1275,6 +1277,8 @@ class OrgDoc: self.keywords: List[Property] = keywords self.contents: List[RawLine] = contents self.list_items: List[ListItem] = list_items + self.structural: List = structural + self.properties: List = properties self._path = None self.headlines: List[Headline] = list( map(lambda hl: parse_headline(hl, self, self), headlines) @@ -1292,13 +1296,20 @@ class OrgDoc: for content in self.contents: yield from get_links_from_content(content) - def get_property(self, name: str, default=None): + def get_keywords(self, name: str, default=None): for prop in self.keywords: if prop.key == name: return prop.value return default + def get_property(self, name: str, default=None): + for prop in self.properties: + if prop.key == name: + return prop.value + + return default + def getProperties(self): return self.keywords @@ -1453,6 +1464,12 @@ class OrgDoc: def dump(self): lines = [] + for prop in self.properties: + lines.append(self.dump_property(prop)) + + for struct in self.structural: + lines.append(self.dump_structural(struct)) + for kw in self.keywords: lines.append(self.dump_kw(kw)) @@ -1476,9 +1493,18 @@ class OrgDocReader: self.contents: List[RawLine] = [] self.delimiters: List[DelimiterLine] = [] self.list_items: List[ListItem] = [] + self.structural: List = [] + self.properties: List = [] def finalize(self): - return OrgDoc(self.headlines, self.keywords, self.contents, self.list_items) + return OrgDoc( + self.headlines, + self.keywords, + self.contents, + self.list_items, + self.structural, + self.properties, + ) ## Construction def add_headline(self, linenum: int, match: re.Match) -> int: @@ -1569,8 +1595,12 @@ class OrgDocReader: self.headline_hierarchy[-1]["delimiters"].append(line) def add_property_drawer_line(self, linenum: int, line: str, match: re.Match) -> int: - self.current_drawer = self.headline_hierarchy[-1]["properties"] - self.headline_hierarchy[-1]["structural"].append((linenum, line)) + if len(self.headline_hierarchy) == 0: + self.current_drawer = self.properties + self.structural.append((linenum, line)) + else: + self.current_drawer = self.headline_hierarchy[-1]["properties"] + self.headline_hierarchy[-1]["structural"].append((linenum, line)) def add_results_drawer_line(self, linenum: int, line: str, match: re.Match) -> int: self.current_drawer = self.headline_hierarchy[-1]["results"] diff --git a/tests/07-org-roam-v2.org b/tests/07-org-roam-v2.org new file mode 100644 index 0000000..0707560 --- /dev/null +++ b/tests/07-org-roam-v2.org @@ -0,0 +1,13 @@ +:PROPERTIES: +:ID: 515054a9-ced8-4119-a844-71726f80dedf +:END: +#+title: 07-org-roam-v2 + +* Subnode +:PROPERTIES: +:CREATED: [2021-08-03 Mar 22:12] +:ID: 419f4651-21c8-4166-b8d5-692c34be9f93 +:END: + +** Sub sub node +- This has no ID diff --git a/tests/test_org.py b/tests/test_org.py index 6bdda48..2a09c7c 100644 --- a/tests/test_org.py +++ b/tests/test_org.py @@ -488,3 +488,15 @@ class TestSerde(unittest.TestCase): self.assertEqual(lists2[1][1].content, " Second element") self.assertEqual(lists2[1][1].counter, "2") self.assertEqual(lists2[1][1].counter_sep, ")") + + def test_org_roam_07(self): + with open(os.path.join(DIR, "07-org-roam-v2.org")) as f: + orig = f.read() + doc = loads(orig) + + self.assertEqual(doc.get_property("ID"), "515054a9-ced8-4119-a844-71726f80dedf") + + self.assertEqual(len(doc.getTopHeadlines()), 1) + hl = doc.getTopHeadlines()[0] + self.assertEqual(hl.get_property("ID"), "419f4651-21c8-4166-b8d5-692c34be9f93") + self.assertEqual(len(hl.children), 1)