Compare commits
11 Commits
6710775882
...
9c54f83ec7
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9c54f83ec7 | ||
![]() |
123f5c9115 | ||
ae1aa7bf9c | |||
78bd091e61 | |||
![]() |
3b90723250 | ||
![]() |
506a17dc5c | ||
![]() |
0bdb29a278 | ||
![]() |
8b4e12ea2e | ||
![]() |
dbac8b2d6e | ||
![]() |
c0fc78fe33 | ||
![]() |
9c04717a12 |
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
12
tests/14-titles.org
Normal 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
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user