From b2779dbc4103ee9fafef2f143075e575ec13cfe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Thu, 10 Dec 2020 00:12:13 +0100 Subject: [PATCH] Improve Timestamp and TimeRange handling. --- org_dom/org_dom.py | 18 ++++++++++++++---- tests/05-dates.org | 16 ++++++++++++++++ tests/test_dom.py | 7 +++++++ 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 tests/05-dates.org diff --git a/org_dom/org_dom.py b/org_dom/org_dom.py index 3f6442a..bd9bec8 100644 --- a/org_dom/org_dom.py +++ b/org_dom/org_dom.py @@ -313,6 +313,10 @@ def token_from_type(tok_type): return ModeToMarker[tok_type] +def parse_org_time_range(start, end): + return TimeRange(parse_org_time(start), parse_org_time(end)) + + def parse_org_time(value): if m := ACTIVE_TIME_STAMP_RE.match(value): active = True @@ -348,11 +352,15 @@ def parse_org_time(value): int(m.group("month")), int(m.group("day")), m.group("dow"), - int(m.group("start_hour")), - int(m.group("start_minute")), + int(m.group("start_hour")) if m.group("start_hour") else None, + int(m.group("start_minute")) if m.group("start_minute") else None, ) +def timerange_to_string(tr: TimeRange): + return timestamp_to_string(tr.start_time) + "--" + timestamp_to_string(tr.end_time) + + def timestamp_to_string(ts): date = "{year}-{month:02d}-{day:02d}".format( year=ts.year, month=ts.month, day=ts.day @@ -803,6 +811,8 @@ class OrgDom: if isinstance(prop.value, Timestamp): value = timestamp_to_string(prop.value) + elif isinstance(prop.value, TimeRange): + value = timerange_to_string(prop.value) else: value = prop.value @@ -1012,8 +1022,8 @@ class OrgDomReader: if (value.count(">--<") == 1) or (value.count("]--[") == 1): # Time ranges with two different dates # @TODO properly consider "=> DURATION" section - chunks = value.split("=").split("--") - as_time_range = parse_org_time(chunks[0], chunks[1]) + start, end = value.split("=")[0].split("--") + as_time_range = parse_org_time_range(start, end) if (as_time_range[0] is not None) and (as_time_range[1] is not None): value = TimeRange(as_time_range[0], as_time_range[1]) elif as_time := parse_org_time(value): diff --git a/tests/05-dates.org b/tests/05-dates.org new file mode 100644 index 0000000..ec128e0 --- /dev/null +++ b/tests/05-dates.org @@ -0,0 +1,16 @@ +#+TITLE: 05-Dates +#+DESCRIPTION: Simple org file +#+TODO: TODO(t) PAUSED(p) | DONE(d) + +* Headline properties +:PROPERTIES: +:JUST_DAY: [2020-12-10] +:DAY_AND_WEEKDAY: [2020-12-10 Xov] +:DAY_AND_HOUR: [2020-12-10 Xov 00:02] +:JUST_DAY_TIME_RANGE: [2020-12-10]--[2020-12-11] +:JUST_DAY_TIME_RANGE_NEGATIVE: [2020-12-11]--[2020-12-10] +:DAY_AND_WEEKDAY_TIME_RANGE: [2020-12-10 Xov]--[2020-12-11 Ven] +:DAY_AND_WEEKDAY_TIME_RANGE_NEGATIVE: [2020-12-11 Ven]--[2020-12-10 Xov] +:DAY_AND_HOUR_TIME_RANGE: [2020-12-10 00:02]--[2020-12-11 00:30] +:DAY_AND_HOUR_TIME_RANGE_NEGATIVE: [2020-12-10 00:30]--[2020-12-11 00:02] +:END: diff --git a/tests/test_dom.py b/tests/test_dom.py index 7dc23ee..8b2a453 100644 --- a/tests/test_dom.py +++ b/tests/test_dom.py @@ -278,3 +278,10 @@ class TestSerde(unittest.TestCase): self.assertEqual( snippets[1].result, "This is another test\n" + "with two lines too" ) + + def test_mimic_write_file_05(self): + with open(os.path.join(DIR, "05-dates.org")) as f: + orig = f.read() + doc = loads(orig) + + self.assertEqual(dumps(doc), orig)