diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index afba2f3..0021acd 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -871,8 +871,12 @@ class ListItem: self.tag = tag self.content = content + @property + def text_start_pos(self): + return len(self.indentation) + 1 # Indentation + bullet + def append_line(self, line): - self.content += parse_content_block('\n' + line[len(self.indentation):]).contents + self.content += parse_content_block('\n' + line).contents TableRow = collections.namedtuple( "TableRow", @@ -1617,10 +1621,7 @@ def dump_contents(raw): bullet = raw.bullet if raw.bullet else raw.counter + raw.counter_sep content_full = token_list_to_raw(raw.content) content_lines = content_full.split('\n') - content = '\n'.join([content_lines[0], *[ - raw.indentation + line - for line in content_lines[1:] - ]]) + content = '\n'.join(content_lines) checkbox = f"[{raw.checkbox_value}]" if raw.checkbox_value else "" tag = f"{raw.tag_indentation}{token_list_to_raw(raw.tag or '')}::" if raw.tag or raw.tag_indentation else "" return ( @@ -2148,12 +2149,15 @@ class OrgDocReader: nonlocal list_item nonlocal list_item_indentation if list_item: - if line.startswith(list_item_indentation): + if ((line[:list_item.text_start_pos].strip() == '') + or (len(line.strip()) == 0) + ): list_item.append_line(line) added = True - elif len(line.strip()) > 0: + else: list_item = None list_item_indentation = None + if not added: self.add_raw_line(linenum, line) @@ -2164,6 +2168,8 @@ class OrgDocReader: if m := END_BLOCK_RE.match(line): self.add_end_block_line(linenum, m) in_block = False + list_item_indentation = None + list_item = None else: add_raw_line_with_possible_indentation(linenum, line) @@ -2180,25 +2186,37 @@ class OrgDocReader: elif m := BEGIN_BLOCK_RE.match(line): self.add_begin_block_line(linenum, m) in_block = True + list_item_indentation = None + list_item = None elif m := END_BLOCK_RE.match(line): self.add_end_block_line(linenum, m) in_block = False + list_item_indentation = None + list_item = None # Generic properties elif m := KEYWORDS_RE.match(line): self.add_keyword_line(linenum, m) elif m := DRAWER_END_RE.match(line): self.add_drawer_end_line(linenum, line, m) in_drawer = False + list_item_indentation = None + list_item = None elif (not in_drawer) and (m := DRAWER_START_RE.match(line)): self.add_property_drawer_line(linenum, line, m) in_drawer = True + list_item_indentation = None + list_item = None elif (not in_drawer) and (m := RESULTS_DRAWER_RE.match(line)): self.add_results_drawer_line(linenum, line, m) in_drawer = True + list_item_indentation = None + list_item = None elif m := NODE_PROPERTIES_RE.match(line): self.add_node_properties_line(linenum, m) elif line.strip().startswith('|'): self.add_table_line(linenum, line) + list_item_indentation = None + list_item = None # Not captured else: add_raw_line_with_possible_indentation(linenum, line) diff --git a/tests/06-lists.org b/tests/06-lists.org index af4b056..0c5448e 100644 --- a/tests/06-lists.org +++ b/tests/06-lists.org @@ -63,3 +63,13 @@ Also with markup - This is another list item... that has content on multiple lines + + Text after a multiline element + + - This is another + multiline list + + #+begin_quote + With a block element inside + #+end_quote + diff --git a/tests/test_org.py b/tests/test_org.py index 1f642cb..21b6518 100644 --- a/tests/test_org.py +++ b/tests/test_org.py @@ -551,7 +551,7 @@ class TestSerde(unittest.TestCase): MarkerToken(closing=False, tok_type=MarkerType.UNDERLINED_MODE), "markup", MarkerToken(closing=True, tok_type=MarkerType.UNDERLINED_MODE), - ".", + ".", "\n" ], ) @@ -567,7 +567,7 @@ class TestSerde(unittest.TestCase): self.assertEqual(lists2[0][0].counter, "1") self.assertEqual(lists2[0][0].counter_sep, ".") - self.assertEqual(lists2[0][1].content, ["Second element"]) + self.assertEqual(lists2[0][1].content, ["Second element", "\n"]) self.assertEqual(lists2[0][1].counter, "2") self.assertEqual(lists2[0][1].counter_sep, ".") @@ -575,7 +575,7 @@ class TestSerde(unittest.TestCase): self.assertEqual(lists2[1][0].counter, "1") self.assertEqual(lists2[1][0].counter_sep, ")") - self.assertEqual(lists2[1][1].content, ["Second element"]) + self.assertEqual(lists2[1][1].content, ["Second element", "\n"]) self.assertEqual(lists2[1][1].counter, "2") self.assertEqual(lists2[1][1].counter_sep, ")") @@ -583,13 +583,16 @@ class TestSerde(unittest.TestCase): # ... lists4 = hl4.getLists() print(lists4) - self.assertEqual(len(lists4), 1) + self.assertEqual(len(lists4), 2) - self.assertEqual(lists4[0][0].content, ["This is a list item...", "\n that spans multiple lines"]) + self.assertEqual(lists4[0][0].content, ["This is a list item...", "\n that spans multiple lines", "\n"]) self.assertEqual(lists4[0][0].bullet, "-") - self.assertEqual(lists4[0][1].content, ["This is another list item...", "\n that has content on multiple lines"]) + self.assertEqual(lists4[0][1].content, ["This is another list item...", "\n that has content on multiple lines", "\n"]) self.assertEqual(lists4[0][1].bullet, "-") + self.assertEqual(lists4[1][0].content, ["This is another", "\n multiline list", "\n"]) + self.assertEqual(lists4[1][0].bullet, "-") + def test_org_roam_07(self): with open(os.path.join(DIR, "07-org-roam-v2.org")) as f: orig = f.read()