From df178d08d85ff97d0b00e068a06ec7e3efe3ec48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Sun, 9 Feb 2025 14:11:52 +0100 Subject: [PATCH 1/9] feat(dom): Add support for generic drawer outputs. --- org_rw/dom.py | 8 ++++++++ org_rw/org_rw.py | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/org_rw/dom.py b/org_rw/dom.py index f9ed40f..2ec06a5 100644 --- a/org_rw/dom.py +++ b/org_rw/dom.py @@ -24,6 +24,14 @@ class ResultsDrawerNode(DrawerNode): return "".format(len(self.children)) +class GenericDrawerNode(DrawerNode): + def __init__(self, drawer_name): + self.drawer_name = drawer_name + + def __repr__(self): + return "".format(self.drawer_name, len(self.children)) + + class PropertyNode: def __init__(self, key, value): self.key = key diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index ed1cf2c..2208f3c 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -122,6 +122,7 @@ NON_FINISHED_GROUPS = ( dom.ListGroupNode, dom.ResultsDrawerNode, dom.PropertyDrawerNode, + dom.GenericDrawerNode, ) FREE_GROUPS = (dom.CodeBlock,) @@ -636,6 +637,13 @@ class Headline: assert current_node is None current_node = dom.ResultsDrawerNode() + # TODO: Allow indentation of these blocks inside others + indentation_tree = [current_node] + tree.append(current_node) + elif content.strip().startswith(':') and content.strip().endswith(':'): + assert current_node is None + current_node = dom.GenericDrawerNode(content.strip().strip(':')) + # TODO: Allow indentation of these blocks inside others indentation_tree = [current_node] tree.append(current_node) From e07964af55aef4961a07ee62549d4d45fafb937e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Sun, 9 Feb 2025 16:25:39 +0100 Subject: [PATCH 2/9] Add `dom.TableRow.get_raw()` support. --- org_rw/dom.py | 7 +++++++ org_rw/utils.py | 3 +++ 2 files changed, 10 insertions(+) diff --git a/org_rw/dom.py b/org_rw/dom.py index 2ec06a5..623343c 100644 --- a/org_rw/dom.py +++ b/org_rw/dom.py @@ -70,12 +70,19 @@ class TableSeparatorRow: def __init__(self, orig=None): self.orig = orig + def get_raw(self): + return get_raw_contents(self.orig) + class TableRow: def __init__(self, cells, orig=None): self.cells = cells self.orig = orig + def get_raw(self): + return get_raw_contents(self.orig) + + class Text: def __init__(self, content): diff --git a/org_rw/utils.py b/org_rw/utils.py index 5b8b4e5..146a942 100644 --- a/org_rw/utils.py +++ b/org_rw/utils.py @@ -7,6 +7,7 @@ from .org_rw import ( Italic, Line, ListItem, + TableRow, RawLine, Strike, Text, @@ -50,6 +51,8 @@ def get_raw_contents(doc) -> str: return doc.get_raw() if isinstance(doc, ListItem): return dump_contents(doc)[1] + if isinstance(doc, TableRow): + return dump_contents(doc)[1] print("Unhandled type: " + str(doc)) raise NotImplementedError("Unhandled type: " + str(doc)) From 7375a69229a3c7c3689839eefbdc82742c659ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Sun, 9 Feb 2025 16:49:06 +0100 Subject: [PATCH 3/9] Don't cut delimiter lines out of `get_lines_between()`. --- org_rw/org_rw.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index 2208f3c..8839342 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -872,9 +872,24 @@ class Headline: yield from get_links_from_content(item.content) def get_lines_between(self, start, end): - for line in self.contents: + # @TODO: Generalize for other line types too. + everything = ( + [] + # + self.keywords + + self.contents + # + self.list_items + # + self.table_rows + # + self.properties + # + self.structural + + self.delimiters + ) + + for line in everything: if start <= line.linenum < end: - yield "".join(line.get_raw()) + if 'get_raw' in dir(line): + yield "".join(line.get_raw()) + else: + yield line.line def get_contents(self, format): if format == "raw": From 24dc516d64549505ba90efcc9714ed37e6212058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Sun, 9 Feb 2025 16:49:25 +0100 Subject: [PATCH 4/9] fix(org_rw): Ensure closing delimiters are same subtype as openers. --- org_rw/org_rw.py | 1 + 1 file changed, 1 insertion(+) diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index 8839342..f26ef94 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -415,6 +415,7 @@ class Headline: if ( isinstance(line, DelimiterLine) and line.delimiter_type == DelimiterLineType.END_BLOCK + and line.type_data.subtype == current_node.header.type_data.subtype ): start = current_node.header.linenum From dbac8b2d6e13942881bf55e07d42560274adec7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Sun, 9 Feb 2025 14:11:52 +0100 Subject: [PATCH 5/9] feat(dom): Add support for generic drawer outputs. --- org_rw/dom.py | 8 ++++++++ org_rw/org_rw.py | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/org_rw/dom.py b/org_rw/dom.py index f9ed40f..0b779b5 100644 --- a/org_rw/dom.py +++ b/org_rw/dom.py @@ -24,6 +24,14 @@ class ResultsDrawerNode(DrawerNode): return "".format(len(self.children)) +class GenericDrawerNode(DrawerNode): + def __init__(self, drawer_name): + self.drawer_name = drawer_name + + def __repr__(self): + return "".format(self.drawer_name, len(self.children)) + + class PropertyNode: def __init__(self, key, value): self.key = key diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index ed1cf2c..2208f3c 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -122,6 +122,7 @@ NON_FINISHED_GROUPS = ( dom.ListGroupNode, dom.ResultsDrawerNode, dom.PropertyDrawerNode, + dom.GenericDrawerNode, ) FREE_GROUPS = (dom.CodeBlock,) @@ -636,6 +637,13 @@ class Headline: assert current_node is None current_node = dom.ResultsDrawerNode() + # TODO: Allow indentation of these blocks inside others + indentation_tree = [current_node] + tree.append(current_node) + elif content.strip().startswith(':') and content.strip().endswith(':'): + assert current_node is None + current_node = dom.GenericDrawerNode(content.strip().strip(':')) + # TODO: Allow indentation of these blocks inside others indentation_tree = [current_node] tree.append(current_node) From 8b4e12ea2eb8ff754792492454be7a48fb2c1ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Sun, 9 Feb 2025 16:25:39 +0100 Subject: [PATCH 6/9] Add `dom.TableRow.get_raw()` support. --- org_rw/dom.py | 7 +++++++ org_rw/utils.py | 3 +++ 2 files changed, 10 insertions(+) diff --git a/org_rw/dom.py b/org_rw/dom.py index 0b779b5..61e0882 100644 --- a/org_rw/dom.py +++ b/org_rw/dom.py @@ -70,12 +70,19 @@ class TableSeparatorRow: def __init__(self, orig=None): self.orig = orig + def get_raw(self): + return get_raw_contents(self.orig) + class TableRow: def __init__(self, cells, orig=None): self.cells = cells self.orig = orig + def get_raw(self): + return get_raw_contents(self.orig) + + class Text: def __init__(self, content): diff --git a/org_rw/utils.py b/org_rw/utils.py index 5b8b4e5..146a942 100644 --- a/org_rw/utils.py +++ b/org_rw/utils.py @@ -7,6 +7,7 @@ from .org_rw import ( Italic, Line, ListItem, + TableRow, RawLine, Strike, Text, @@ -50,6 +51,8 @@ def get_raw_contents(doc) -> str: return doc.get_raw() if isinstance(doc, ListItem): return dump_contents(doc)[1] + if isinstance(doc, TableRow): + return dump_contents(doc)[1] print("Unhandled type: " + str(doc)) raise NotImplementedError("Unhandled type: " + str(doc)) From 0bdb29a2783a76898dd709b6c23ce25fbe3a498c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Sun, 9 Feb 2025 16:49:06 +0100 Subject: [PATCH 7/9] Don't cut delimiter lines out of `get_lines_between()`. --- org_rw/org_rw.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index 2208f3c..8839342 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -872,9 +872,24 @@ class Headline: yield from get_links_from_content(item.content) def get_lines_between(self, start, end): - for line in self.contents: + # @TODO: Generalize for other line types too. + everything = ( + [] + # + self.keywords + + self.contents + # + self.list_items + # + self.table_rows + # + self.properties + # + self.structural + + self.delimiters + ) + + for line in everything: if start <= line.linenum < end: - yield "".join(line.get_raw()) + if 'get_raw' in dir(line): + yield "".join(line.get_raw()) + else: + yield line.line def get_contents(self, format): if format == "raw": From 506a17dc5cc233d7f971db1a0765747e724610bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Sun, 9 Feb 2025 16:49:25 +0100 Subject: [PATCH 8/9] fix(org_rw): Ensure closing delimiters are same subtype as openers. --- org_rw/org_rw.py | 1 + 1 file changed, 1 insertion(+) diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index 8839342..f26ef94 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -415,6 +415,7 @@ class Headline: if ( isinstance(line, DelimiterLine) and line.delimiter_type == DelimiterLineType.END_BLOCK + and line.type_data.subtype == current_node.header.type_data.subtype ): start = current_node.header.linenum From 3b90723250dd7bde121eafbc5ed2bdf8d9dc125b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Sun, 9 Feb 2025 16:50:22 +0100 Subject: [PATCH 9/9] format: Automatic formatting fixes. --- org_rw/dom.py | 1 - org_rw/org_rw.py | 6 +++--- org_rw/utils.py | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/org_rw/dom.py b/org_rw/dom.py index 61e0882..baf0092 100644 --- a/org_rw/dom.py +++ b/org_rw/dom.py @@ -83,7 +83,6 @@ class TableRow: return get_raw_contents(self.orig) - class Text: def __init__(self, content): self.content = content diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index f26ef94..6baadd1 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -641,9 +641,9 @@ class Headline: # TODO: Allow indentation of these blocks inside others indentation_tree = [current_node] tree.append(current_node) - elif content.strip().startswith(':') and content.strip().endswith(':'): + elif content.strip().startswith(":") and content.strip().endswith(":"): assert current_node is None - current_node = dom.GenericDrawerNode(content.strip().strip(':')) + current_node = dom.GenericDrawerNode(content.strip().strip(":")) # TODO: Allow indentation of these blocks inside others indentation_tree = [current_node] @@ -887,7 +887,7 @@ class Headline: for line in everything: if start <= line.linenum < end: - if 'get_raw' in dir(line): + if "get_raw" in dir(line): yield "".join(line.get_raw()) else: yield line.line diff --git a/org_rw/utils.py b/org_rw/utils.py index 146a942..87f6712 100644 --- a/org_rw/utils.py +++ b/org_rw/utils.py @@ -7,9 +7,9 @@ from .org_rw import ( Italic, Line, ListItem, - TableRow, RawLine, Strike, + TableRow, Text, Underlined, Verbatim,