WIP: Add support for updating a headline whole text contents #4
@ -1,4 +1,5 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import difflib
|
import difflib
|
||||||
import logging
|
import logging
|
||||||
@ -7,7 +8,6 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
from typing import (
|
from typing import (
|
||||||
Dict,
|
Dict,
|
||||||
Iterator,
|
Iterator,
|
||||||
@ -860,7 +860,9 @@ class Headline:
|
|||||||
# No need to finalize as we can take the data from the reader instead of from a doc
|
# No need to finalize as we can take the data from the reader instead of from a doc
|
||||||
if len(reader.headlines) > 0:
|
if len(reader.headlines) > 0:
|
||||||
# Probably can be done by just adding the headlines to this one's children
|
# Probably can be done by just adding the headlines to this one's children
|
||||||
raise NotImplementedError('new headlines on raw contents not supported yet. This probably should be simple, see comment on code.')
|
raise NotImplementedError(
|
||||||
|
"new headlines on raw contents not supported yet. This probably should be simple, see comment on code."
|
||||||
|
)
|
||||||
|
|
||||||
for kw in reader.keywords:
|
for kw in reader.keywords:
|
||||||
self.keywords.append(offset_linenum(self.start_line + 1, kw))
|
self.keywords.append(offset_linenum(self.start_line + 1, kw))
|
||||||
@ -879,7 +881,6 @@ class Headline:
|
|||||||
|
|
||||||
# Environment is not used, as it's known
|
# Environment is not used, as it's known
|
||||||
|
|
||||||
|
|
||||||
def get_element_in_line(self, linenum):
|
def get_element_in_line(self, linenum):
|
||||||
for line in self.contents:
|
for line in self.contents:
|
||||||
if linenum == line.linenum:
|
if linenum == line.linenum:
|
||||||
@ -1077,9 +1078,7 @@ Keyword = collections.namedtuple(
|
|||||||
Property = collections.namedtuple(
|
Property = collections.namedtuple(
|
||||||
"Property", ("linenum", "match", "key", "value", "options")
|
"Property", ("linenum", "match", "key", "value", "options")
|
||||||
)
|
)
|
||||||
Structural = collections.namedtuple(
|
Structural = collections.namedtuple("Structural", ("linenum", "line"))
|
||||||
"Structural", ("linenum", "line")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ListItem:
|
class ListItem:
|
||||||
@ -1129,13 +1128,16 @@ TableRow = collections.namedtuple(
|
|||||||
)
|
)
|
||||||
|
|
||||||
ItemWithLineNum = Union[Keyword, RawLine, Property, ListItem, Structural]
|
ItemWithLineNum = Union[Keyword, RawLine, Property, ListItem, Structural]
|
||||||
|
|
||||||
|
|
||||||
def offset_linenum(offset: int, item: ItemWithLineNum) -> ItemWithLineNum:
|
def offset_linenum(offset: int, item: ItemWithLineNum) -> ItemWithLineNum:
|
||||||
if isinstance(item, ListItem):
|
if isinstance(item, ListItem):
|
||||||
item.linenum += offset
|
item.linenum += offset
|
||||||
return item
|
return item
|
||||||
|
|
||||||
assert isinstance(item, (Keyword, RawLine, Property, Structural)), \
|
assert isinstance(
|
||||||
"Expected (Keyword|RawLine|Property|Structural), found {}".format(item)
|
item, (Keyword, RawLine, Property, Structural)
|
||||||
|
), "Expected (Keyword|RawLine|Property|Structural), found {}".format(item)
|
||||||
return item._replace(linenum=item.linenum + offset)
|
return item._replace(linenum=item.linenum + offset)
|
||||||
|
|
||||||
|
|
||||||
|
@ -903,8 +903,8 @@ class TestSerde(unittest.TestCase):
|
|||||||
|
|
||||||
# Update
|
# Update
|
||||||
lines = list(doc.dump_headline(hl, recursive=False))
|
lines = list(doc.dump_headline(hl, recursive=False))
|
||||||
assert lines[0].startswith('* ') # Title, skip it
|
assert lines[0].startswith("* ") # Title, skip it
|
||||||
content = '\n'.join(lines[1:])
|
content = "\n".join(lines[1:])
|
||||||
hl.update_raw_contents(content)
|
hl.update_raw_contents(content)
|
||||||
|
|
||||||
# Check after update
|
# Check after update
|
||||||
@ -914,7 +914,7 @@ class TestSerde(unittest.TestCase):
|
|||||||
with open(os.path.join(DIR, "13-update-reparse-test.org")) as f:
|
with open(os.path.join(DIR, "13-update-reparse-test.org")) as f:
|
||||||
doc = load(f)
|
doc = load(f)
|
||||||
|
|
||||||
expected_hl_contents = ''' :PROPERTIES:
|
expected_hl_contents = """ :PROPERTIES:
|
||||||
:ID: 13-update-reparse-first-level-id
|
:ID: 13-update-reparse-first-level-id
|
||||||
:CREATED: [2020-01-01 Wed 01:01]
|
:CREATED: [2020-01-01 Wed 01:01]
|
||||||
:END:
|
:END:
|
||||||
@ -924,12 +924,12 @@ class TestSerde(unittest.TestCase):
|
|||||||
- With a sublist
|
- With a sublist
|
||||||
|
|
||||||
Something after the list.
|
Something after the list.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
hl = doc.getTopHeadlines()[0]
|
hl = doc.getTopHeadlines()[0]
|
||||||
lines = list(doc.dump_headline(hl, recursive=False))
|
lines = list(doc.dump_headline(hl, recursive=False))
|
||||||
assert lines[0].startswith('* ') # Title, skip it
|
assert lines[0].startswith("* ") # Title, skip it
|
||||||
content = '\n'.join(lines[1:])
|
content = "\n".join(lines[1:])
|
||||||
self.assertEqual(content, expected_hl_contents)
|
self.assertEqual(content, expected_hl_contents)
|
||||||
|
|
||||||
# Check after update
|
# Check after update
|
||||||
@ -937,17 +937,17 @@ class TestSerde(unittest.TestCase):
|
|||||||
self.assertEqual(content, expected_hl_contents)
|
self.assertEqual(content, expected_hl_contents)
|
||||||
|
|
||||||
# Check after dump and reload
|
# Check after dump and reload
|
||||||
with tempfile.NamedTemporaryFile('wt') as f:
|
with tempfile.NamedTemporaryFile("wt") as f:
|
||||||
save = org_rw.dumps(doc)
|
save = org_rw.dumps(doc)
|
||||||
f.write(save)
|
f.write(save)
|
||||||
f.flush()
|
f.flush()
|
||||||
|
|
||||||
with open(f.name, 'rt') as reader:
|
with open(f.name, "rt") as reader:
|
||||||
reloaded = org_rw.load(reader)
|
reloaded = org_rw.load(reader)
|
||||||
re_hl = reloaded.getTopHeadlines()[0]
|
re_hl = reloaded.getTopHeadlines()[0]
|
||||||
lines = list(doc.dump_headline(hl, recursive=False))
|
lines = list(doc.dump_headline(hl, recursive=False))
|
||||||
assert lines[0].startswith('* ') # Title, skip it
|
assert lines[0].startswith("* ") # Title, skip it
|
||||||
content = '\n'.join(lines[1:])
|
content = "\n".join(lines[1:])
|
||||||
self.assertEqual(content, expected_hl_contents)
|
self.assertEqual(content, expected_hl_contents)
|
||||||
|
|
||||||
def test_mimic_write_file_13(self):
|
def test_mimic_write_file_13(self):
|
||||||
|
@ -67,7 +67,12 @@ class HL:
|
|||||||
self.content = content
|
self.content = content
|
||||||
self.children = children
|
self.children = children
|
||||||
|
|
||||||
def assert_matches(self, test_case: unittest.TestCase, doc, accept_trailing_whitespace_changes=False):
|
def assert_matches(
|
||||||
|
self,
|
||||||
|
test_case: unittest.TestCase,
|
||||||
|
doc,
|
||||||
|
accept_trailing_whitespace_changes=False,
|
||||||
|
):
|
||||||
test_case.assertEqual(self.title, get_raw(doc.title))
|
test_case.assertEqual(self.title, get_raw(doc.title))
|
||||||
|
|
||||||
# Check properties
|
# Check properties
|
||||||
@ -85,7 +90,9 @@ class HL:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if accept_trailing_whitespace_changes:
|
if accept_trailing_whitespace_changes:
|
||||||
test_case.assertEqual(get_raw_contents(doc).rstrip(), self.get_raw().rstrip())
|
test_case.assertEqual(
|
||||||
|
get_raw_contents(doc).rstrip(), self.get_raw().rstrip()
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
test_case.assertEqual(get_raw_contents(doc), self.get_raw())
|
test_case.assertEqual(get_raw_contents(doc), self.get_raw())
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user