Compare commits

...

11 Commits

Author SHA1 Message Date
Sergio Martínez Portela
9c54f83ec7 revert: Remove old implementation change.
Some checks failed
Testing / pytest (push) Failing after 20s
Testing / mypy (push) Successful in 35s
Testing / style-formatting (push) Successful in 18s
Testing / style-sorted-imports (push) Successful in 16s
Testing / stability-extra-test (push) Successful in 19s
This is reverted as it doesn't return accurately the information that's on the org-mode file.
2025-04-16 00:06:13 +02:00
Sergio Martínez Portela
123f5c9115 test: Propose tests for title parsing changes. 2025-04-16 00:05:24 +02:00
ae1aa7bf9c Merge branch 'develop' into fix/strip-title 2025-04-15 21:57:53 +00:00
78bd091e61 Merge pull request 'Multiple fixes on loader due to extended tests.' (#15) from fixes/loading into develop
All checks were successful
Testing / pytest (push) Successful in 20s
Testing / mypy (push) Successful in 27s
Testing / style-formatting (push) Successful in 23s
Testing / style-sorted-imports (push) Successful in 19s
Testing / stability-extra-test (push) Successful in 23s
Reviewed-on: #15
2025-04-15 21:56:51 +00:00
Sergio Martínez Portela
3b90723250 format: Automatic formatting fixes.
All checks were successful
Testing / pytest (push) Successful in 23s
Testing / mypy (push) Successful in 28s
Testing / style-formatting (push) Successful in 23s
Testing / style-sorted-imports (push) Successful in 19s
Testing / stability-extra-test (push) Successful in 26s
2025-02-09 16:50:52 +01:00
Sergio Martínez Portela
506a17dc5c fix(org_rw): Ensure closing delimiters are same subtype as openers. 2025-02-09 16:50:52 +01:00
Sergio Martínez Portela
0bdb29a278 Don't cut delimiter lines out of get_lines_between(). 2025-02-09 16:50:52 +01:00
Sergio Martínez Portela
8b4e12ea2e Add dom.TableRow.get_raw() support. 2025-02-09 16:50:52 +01:00
Sergio Martínez Portela
dbac8b2d6e feat(dom): Add support for generic drawer outputs. 2025-02-09 16:50:52 +01:00
Sergio Martínez Portela
c0fc78fe33 fix(gitea): Fix build with newer images. 2025-02-09 14:13:28 +01:00
Sergio Martínez Portela
9c04717a12 Fix support of code blocks outside headlines.
Some checks failed
Testing / pytest (push) Failing after 1m11s
Testing / mypy (push) Failing after 17s
Testing / style-formatting (push) Failing after 15s
Testing / style-sorted-imports (push) Failing after 16s
Testing / stability-extra-test (push) Failing after 20s
2025-02-09 13:49:09 +01:00
6 changed files with 89 additions and 12 deletions

View File

@ -9,8 +9,8 @@ jobs:
- name: Check out repository code - name: Check out repository code
uses: actions/checkout@v3 uses: actions/checkout@v3
- run: apt-get update && apt-get install -y python3-pip - run: apt-get update && apt-get install -y python3-pip
- run: pip install -e . - run: pip install --break-system-package -e .
- run: pip install pytest - run: pip install --break-system-package pytest
- run: pytest - run: pytest
mypy: mypy:
@ -19,8 +19,8 @@ jobs:
- name: Check out repository code - name: Check out repository code
uses: actions/checkout@v3 uses: actions/checkout@v3
- run: apt-get update && apt-get install -y python3-pip - run: apt-get update && apt-get install -y python3-pip
- run: pip install -e . - run: pip install --break-system-package -e .
- run: pip install mypy - run: pip install --break-system-package mypy
- run: mypy org_rw --check-untyped-defs - run: mypy org_rw --check-untyped-defs
style-formatting: style-formatting:
@ -29,8 +29,8 @@ jobs:
- name: Check out repository code - name: Check out repository code
uses: actions/checkout@v3 uses: actions/checkout@v3
- run: apt-get update && apt-get install -y python3-pip - run: apt-get update && apt-get install -y python3-pip
- run: pip install -e . - run: pip install --break-system-package -e .
- run: pip install black - run: pip install --break-system-package black
- run: black --check . - run: black --check .
style-sorted-imports: style-sorted-imports:
@ -39,8 +39,8 @@ jobs:
- name: Check out repository code - name: Check out repository code
uses: actions/checkout@v3 uses: actions/checkout@v3
- run: apt-get update && apt-get install -y python3-pip - run: apt-get update && apt-get install -y python3-pip
- run: pip install -e . - run: pip install --break-system-package -e .
- run: pip install isort - run: pip install --break-system-package isort
- run: isort --profile black --check . - run: isort --profile black --check .
stability-extra-test: stability-extra-test:
@ -49,5 +49,5 @@ jobs:
- name: Check out repository code - name: Check out repository code
uses: actions/checkout@v3 uses: actions/checkout@v3
- run: apt-get update && apt-get install -y git-core python3-pip - run: apt-get update && apt-get install -y git-core python3-pip
- run: pip install -e . - run: pip install --break-system-package -e .
- run: bash extra-tests/check_all.sh - run: bash extra-tests/check_all.sh

View File

@ -24,6 +24,14 @@ class ResultsDrawerNode(DrawerNode):
return "<Results: {}>".format(len(self.children)) return "<Results: {}>".format(len(self.children))
class GenericDrawerNode(DrawerNode):
def __init__(self, drawer_name):
self.drawer_name = drawer_name
def __repr__(self):
return "<Drawer{}: {}>".format(self.drawer_name, len(self.children))
class PropertyNode: class PropertyNode:
def __init__(self, key, value): def __init__(self, key, value):
self.key = key self.key = key
@ -62,12 +70,18 @@ class TableSeparatorRow:
def __init__(self, orig=None): def __init__(self, orig=None):
self.orig = orig self.orig = orig
def get_raw(self):
return get_raw_contents(self.orig)
class TableRow: class TableRow:
def __init__(self, cells, orig=None): def __init__(self, cells, orig=None):
self.cells = cells self.cells = cells
self.orig = orig self.orig = orig
def get_raw(self):
return get_raw_contents(self.orig)
class Text: class Text:
def __init__(self, content): def __init__(self, content):

View File

@ -122,6 +122,7 @@ NON_FINISHED_GROUPS = (
dom.ListGroupNode, dom.ListGroupNode,
dom.ResultsDrawerNode, dom.ResultsDrawerNode,
dom.PropertyDrawerNode, dom.PropertyDrawerNode,
dom.GenericDrawerNode,
) )
FREE_GROUPS = (dom.CodeBlock,) FREE_GROUPS = (dom.CodeBlock,)
@ -414,6 +415,7 @@ class Headline:
if ( if (
isinstance(line, DelimiterLine) isinstance(line, DelimiterLine)
and line.delimiter_type == DelimiterLineType.END_BLOCK and line.delimiter_type == DelimiterLineType.END_BLOCK
and line.type_data.subtype == current_node.header.type_data.subtype
): ):
start = current_node.header.linenum start = current_node.header.linenum
end = line.linenum end = line.linenum
@ -635,6 +637,13 @@ class Headline:
assert current_node is None assert current_node is None
current_node = dom.ResultsDrawerNode() 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 # TODO: Allow indentation of these blocks inside others
indentation_tree = [current_node] indentation_tree = [current_node]
tree.append(current_node) tree.append(current_node)
@ -862,9 +871,24 @@ class Headline:
yield from get_links_from_content(item.content) yield from get_links_from_content(item.content)
def get_lines_between(self, start, end): 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: 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): def get_contents(self, format):
if format == "raw": if format == "raw":
@ -1792,7 +1816,7 @@ def token_list_to_plaintext(tok_list) -> str:
else: else:
assert isinstance(chunk, MarkerToken) assert isinstance(chunk, MarkerToken)
return "".join(contents).strip() return "".join(contents)
def token_list_to_raw(tok_list): def token_list_to_raw(tok_list):
@ -2303,6 +2327,7 @@ class OrgDoc:
list_items, list_items,
structural, structural,
properties, properties,
delimiters,
environment=BASE_ENVIRONMENT, environment=BASE_ENVIRONMENT,
): ):
self.todo_keywords = [HeadlineState(name=kw) for kw in DEFAULT_TODO_KEYWORDS] self.todo_keywords = [HeadlineState(name=kw) for kw in DEFAULT_TODO_KEYWORDS]
@ -2332,6 +2357,7 @@ class OrgDoc:
self.list_items: List[ListItem] = list_items self.list_items: List[ListItem] = list_items
self.structural: List = structural self.structural: List = structural
self.properties: List = properties self.properties: List = properties
self.delimiters: List = delimiters
self._path = None self._path = None
self.headlines: List[Headline] = list( self.headlines: List[Headline] = list(
map(lambda hl: parse_headline(hl, self, self), headlines) map(lambda hl: parse_headline(hl, self, self), headlines)
@ -2502,6 +2528,9 @@ class OrgDoc:
for struct in self.structural: for struct in self.structural:
lines.append(dump_structural(struct)) lines.append(dump_structural(struct))
for content in self.delimiters:
lines.append(dump_delimiters(content))
for kw in self.keywords: for kw in self.keywords:
lines.append(dump_kw(kw)) lines.append(dump_kw(kw))
@ -2539,6 +2568,7 @@ class OrgDocReader:
self.list_items, self.list_items,
self.structural, self.structural,
self.properties, self.properties,
self.delimiters,
self.environment, self.environment,
) )

View File

@ -9,6 +9,7 @@ from .org_rw import (
ListItem, ListItem,
RawLine, RawLine,
Strike, Strike,
TableRow,
Text, Text,
Underlined, Underlined,
Verbatim, Verbatim,
@ -50,6 +51,8 @@ def get_raw_contents(doc) -> str:
return doc.get_raw() return doc.get_raw()
if isinstance(doc, ListItem): if isinstance(doc, ListItem):
return dump_contents(doc)[1] return dump_contents(doc)[1]
if isinstance(doc, TableRow):
return dump_contents(doc)[1]
print("Unhandled type: " + str(doc)) print("Unhandled type: " + str(doc))
raise NotImplementedError("Unhandled type: " + str(doc)) raise NotImplementedError("Unhandled type: " + str(doc))

12
tests/14-titles.org Normal file
View File

@ -0,0 +1,12 @@
#+TITLE: 14-Simple
#+DESCRIPTION: Org file to evaluate titles
#+TODO: TODO(t) PAUSED(p) | DONE(d)
* Simple title
* Simple title with tags :tag:
* Simple title with trailing space
* Simple title with leading space

View File

@ -955,6 +955,24 @@ class TestSerde(unittest.TestCase):
h1_2_h2 = h1_2.children[0] h1_2_h2 = h1_2.children[0]
self.assertEqual(sorted(h1_2_h2.tags), ["otherh2tag"]) self.assertEqual(sorted(h1_2_h2.tags), ["otherh2tag"])
def test_titles_file(self):
with open(os.path.join(DIR, "14-titles.org")) as f:
doc = load(f)
h1, h2, h3, h4 = doc.getTopHeadlines()
self.assertEqual(h1.title.get_text(), "Simple title")
self.assertEqual(h2.title.get_text(), "Simple title with tags")
self.assertEqual(h3.title.get_text(), "Simple title with trailing space")
self.assertEqual(h4.title.get_text(), "Simple title with leading space")
def test_mimic_write_file_14(self):
"""A goal of this library is to be able to update a file without changing parts not directly modified."""
with open(os.path.join(DIR, "14-titles.org")) as f:
orig = f.read()
doc = loads(orig)
self.assertEqual(dumps(doc), orig)
def test_update_headline_from_none_to_todo(self): def test_update_headline_from_none_to_todo(self):
orig = "* First entry" orig = "* First entry"
doc = loads(orig) doc = loads(orig)