Support updating ranges with contents with different size.

This commit is contained in:
Sergio Martínez Portela 2020-12-20 12:14:58 +01:00
parent ebecc5feca
commit 83710a4fc1
5 changed files with 89 additions and 37 deletions

View File

@ -76,17 +76,33 @@ def get_tokens(value):
class RangeInRaw: class RangeInRaw:
def __init__(self, content, start, end): def __init__(self, content, start_token, end_token):
self._content = content self._content = content
self._start = start self._start_id = id(start_token)
self._end = end self._end_id = id(end_token)
def update_range(self, contents): def update_range(self, new_contents):
if len(contents) == (self._end) - self._start: # Find start token
for i in range(self._start, self._end): for start_idx, tok in enumerate(self._content.contents):
self._content.contents[i] = contents[i - self._start] if id(tok) == self._start_id:
break
else: else:
raise NotImplementedError() raise Exception("Start token not found")
# Find end token
for offset, tok in enumerate(self._content.contents[start_idx:]):
if id(tok) == self._end_id:
break
else:
raise Exception("End token not found")
# Remove old contents
for i in range(1, offset):
self._content.contents.pop(start_idx + 1)
# Add new ones
for i, element in enumerate(new_contents):
self._content.contents.insert(start_idx + i + 1, element)
def get_links_from_content(content): def get_links_from_content(content):
@ -99,11 +115,11 @@ def get_links_from_content(content):
if isinstance(tok, LinkToken): if isinstance(tok, LinkToken):
if tok.tok_type == LinkTokenType.OPEN_LINK: if tok.tok_type == LinkTokenType.OPEN_LINK:
in_link = True in_link = True
open_link_token = i + 1 open_link_token = tok
elif tok.tok_type == LinkTokenType.OPEN_DESCRIPTION: elif tok.tok_type == LinkTokenType.OPEN_DESCRIPTION:
in_description = True in_description = True
elif tok.tok_type == LinkTokenType.CLOSE: elif tok.tok_type == LinkTokenType.CLOSE:
rng = RangeInRaw(content, open_link_token, i) rng = RangeInRaw(content, open_link_token, tok)
yield Link( yield Link(
"".join(link_value), "".join(link_value),
"".join(link_description) if in_description else None, "".join(link_description) if in_description else None,

View File

@ -1,20 +1,9 @@
from .org_dom import ( from .org_dom import (Bold, Code, Headline, Italic, Line, RawLine, Strike,
Bold, Text, Underlined, Verbatim)
Code,
Headline,
Italic,
Line,
RawLine,
Strike,
Text,
Underlined,
Verbatim,
)
def get_hl_raw_contents(doc: Headline) -> str: def get_hl_raw_contents(doc: Headline) -> str:
lines = [] lines = []
for content in doc.contents: for content in doc.contents:
lines.append(get_raw_contents(content)) lines.append(get_raw_contents(content))

View File

@ -11,3 +11,7 @@
This is a [[https://codigoparallevar.com/1][web link]]. This is a [[https://codigoparallevar.com/1][web link]].
This is a /italized [[https://codigoparallevar.com/2][web link]]/. This is a /italized [[https://codigoparallevar.com/2][web link]]/.
This is a link with no description to [[* First level]].
This is [[id:03-markup-first-level-id][a link to a section by id]].

View File

@ -200,12 +200,19 @@ class TestSerde(unittest.TestCase):
doc = load(f) doc = load(f)
links = list(doc.get_links()) links = list(doc.get_links())
self.assertEqual(len(links), 2) self.assertEqual(len(links), 4)
self.assertEqual(links[0].value, "https://codigoparallevar.com/1") self.assertEqual(links[0].value, "https://codigoparallevar.com/1")
self.assertEqual(links[0].description, "web link") self.assertEqual(links[0].description, "web link")
self.assertEqual(links[1].value, "https://codigoparallevar.com/2") self.assertEqual(links[1].value, "https://codigoparallevar.com/2")
self.assertEqual(links[1].description, "web link") self.assertEqual(links[1].description, "web link")
self.assertEqual(links[2].value, "* First level")
self.assertEqual(links[2].description, None)
self.assertEqual(links[3].value, "id:03-markup-first-level-id")
self.assertEqual(links[3].description, "a link to a section by id")
ex = Dom( ex = Dom(
props=[ props=[
("TITLE", "03-Links"), ("TITLE", "03-Links"),
@ -238,17 +245,34 @@ class TestSerde(unittest.TestCase):
), ),
".\n", ".\n",
), ),
SPAN("\n"),
SPAN(
" This is a link with no description to ",
WEB_LINK(None, "* First level"),
".\n",
),
SPAN("\n"),
SPAN(
" This is ",
WEB_LINK(
"a link to a section by id",
"id:03-markup-first-level-id",
),
".\n",
),
], ],
) )
), ),
) )
ex.assert_matches(self, doc)
def test_update_links_file_03(self): def test_update_links_file_03(self):
with open(os.path.join(DIR, "03-links.org")) as f: with open(os.path.join(DIR, "03-links.org")) as f:
doc = load(f) doc = load(f)
links = list(doc.get_links()) links = list(doc.get_links())
self.assertEqual(len(links), 2) self.assertEqual(len(links), 4)
self.assertEqual(links[0].value, "https://codigoparallevar.com/1") self.assertEqual(links[0].value, "https://codigoparallevar.com/1")
self.assertEqual(links[0].description, "web link") self.assertEqual(links[0].description, "web link")
links[0].value = "https://codigoparallevar.com/1-updated" links[0].value = "https://codigoparallevar.com/1-updated"
@ -259,6 +283,16 @@ class TestSerde(unittest.TestCase):
links[1].value = "https://codigoparallevar.com/2-updated" links[1].value = "https://codigoparallevar.com/2-updated"
links[1].description = "web link #2 with update" links[1].description = "web link #2 with update"
self.assertEqual(links[2].value, "* First level")
self.assertEqual(links[2].description, None)
links[2].value = "* Non-existent level"
links[2].description = "a description now"
self.assertEqual(links[3].value, "id:03-markup-first-level-id")
self.assertEqual(links[3].description, "a link to a section by id")
links[3].value = "id:03-markup-non-existent-level-id"
links[3].description = None
ex = Dom( ex = Dom(
props=[ props=[
("TITLE", "03-Links"), ("TITLE", "03-Links"),
@ -295,6 +329,21 @@ class TestSerde(unittest.TestCase):
), ),
".\n", ".\n",
), ),
SPAN("\n"),
SPAN(
" This is a link with no description to ",
WEB_LINK("a description now", "* Non-existent level"),
".\n",
),
SPAN("\n"),
SPAN(
" This is ",
WEB_LINK(
None,
"id:03-markup-non-existent-level-id",
),
".\n",
),
], ],
) )
), ),

View File

@ -2,17 +2,8 @@ import collections
import unittest import unittest
from datetime import datetime from datetime import datetime
from org_dom import ( from org_dom import (Bold, Code, Italic, Line, Strike, Text, Underlined,
Bold, Verbatim, get_raw_contents)
Code,
Italic,
Line,
Strike,
Text,
Underlined,
Verbatim,
get_raw_contents,
)
def timestamp_to_datetime(ts): def timestamp_to_datetime(ts):
@ -209,7 +200,10 @@ class WEB_LINK:
self.link = link self.link = link
def get_raw(self): def get_raw(self):
return "[[{}][{}]]".format(self.link, self.text) if self.text:
return "[[{}][{}]]".format(self.link, self.text)
else:
return "[[{}]]".format(self.link)
def assertEqual(self, test_case, other): def assertEqual(self, test_case, other):
test_case.assertTrue(isinstance(other, WebLink)) test_case.assertTrue(isinstance(other, WebLink))