forked from kenkeiras/org-rw
Apply autoformatting with black.
This commit is contained in:
parent
d5f8d76aeb
commit
1d71d1a3c3
@ -63,6 +63,7 @@ INACTIVE_TIME_STAMP_RE = re.compile(r"\[{}\]".format(BASE_TIME_STAMP_RE))
|
|||||||
# BASE_TIME_RANGE_RE = (r'(?P<start_year>\d{4})-(?P<start_month>\d{2})-(?P<start_day>\d{2}) (?P<start_dow>[^ ]+)((?P<start_hour>\d{1,2}):(?P<start_minute>\d{1,2}))?',
|
# BASE_TIME_RANGE_RE = (r'(?P<start_year>\d{4})-(?P<start_month>\d{2})-(?P<start_day>\d{2}) (?P<start_dow>[^ ]+)((?P<start_hour>\d{1,2}):(?P<start_minute>\d{1,2}))?',
|
||||||
# r'(?P<end_year>\d{4})-(?P<end_month>\d{2})-(?P<end_day>\d{2}) (?P<end_dow>[^ ]+)((?P<end_hour>\d{1,2}):(?P<end_minute>\d{1,2}))?')
|
# r'(?P<end_year>\d{4})-(?P<end_month>\d{2})-(?P<end_day>\d{2}) (?P<end_dow>[^ ]+)((?P<end_hour>\d{1,2}):(?P<end_minute>\d{1,2}))?')
|
||||||
|
|
||||||
|
|
||||||
def get_tokens(value):
|
def get_tokens(value):
|
||||||
if isinstance(value, Text):
|
if isinstance(value, Text):
|
||||||
return value.contents
|
return value.contents
|
||||||
@ -70,6 +71,7 @@ def get_tokens(value):
|
|||||||
return [value.line]
|
return [value.line]
|
||||||
raise Exception("Unknown how to get tokens from: {}".format(value))
|
raise Exception("Unknown how to get tokens from: {}".format(value))
|
||||||
|
|
||||||
|
|
||||||
def get_links_from_content(content):
|
def get_links_from_content(content):
|
||||||
in_link = False
|
in_link = False
|
||||||
in_description = False
|
in_description = False
|
||||||
@ -85,7 +87,7 @@ def get_links_from_content(content):
|
|||||||
elif tok.tok_type == LinkTokenType.CLOSE:
|
elif tok.tok_type == LinkTokenType.CLOSE:
|
||||||
in_link = False
|
in_link = False
|
||||||
in_description = False
|
in_description = False
|
||||||
yield Link(''.join(link_value), ''.join(link_description))
|
yield Link("".join(link_value), "".join(link_description))
|
||||||
link_value = []
|
link_value = []
|
||||||
link_description = []
|
link_description = []
|
||||||
elif isinstance(tok, str) and in_link:
|
elif isinstance(tok, str) and in_link:
|
||||||
@ -94,8 +96,25 @@ def get_links_from_content(content):
|
|||||||
else:
|
else:
|
||||||
link_value.append(tok)
|
link_value.append(tok)
|
||||||
|
|
||||||
|
|
||||||
class Headline:
|
class Headline:
|
||||||
def __init__(self, start_line, depth, orig, properties, keywords, priority_start, priority, title_start, title, tags_start, tags, contents, children, structural):
|
def __init__(
|
||||||
|
self,
|
||||||
|
start_line,
|
||||||
|
depth,
|
||||||
|
orig,
|
||||||
|
properties,
|
||||||
|
keywords,
|
||||||
|
priority_start,
|
||||||
|
priority,
|
||||||
|
title_start,
|
||||||
|
title,
|
||||||
|
tags_start,
|
||||||
|
tags,
|
||||||
|
contents,
|
||||||
|
children,
|
||||||
|
structural,
|
||||||
|
):
|
||||||
self.start_line = start_line
|
self.start_line = start_line
|
||||||
self.depth = depth
|
self.depth = depth
|
||||||
self.orig = orig
|
self.orig = orig
|
||||||
@ -115,6 +134,7 @@ class Headline:
|
|||||||
for content in self.contents:
|
for content in self.contents:
|
||||||
yield from get_links_from_content(content)
|
yield from get_links_from_content(content)
|
||||||
|
|
||||||
|
|
||||||
RawLine = collections.namedtuple("RawLine", ("linenum", "line"))
|
RawLine = collections.namedtuple("RawLine", ("linenum", "line"))
|
||||||
Keyword = collections.namedtuple(
|
Keyword = collections.namedtuple(
|
||||||
"Keyword", ("linenum", "match", "key", "value", "options")
|
"Keyword", ("linenum", "match", "key", "value", "options")
|
||||||
@ -140,6 +160,7 @@ class MarkerType(Enum):
|
|||||||
UNDERLINED_MODE = 0b10000
|
UNDERLINED_MODE = 0b10000
|
||||||
VERBATIM_MODE = 0b100000
|
VERBATIM_MODE = 0b100000
|
||||||
|
|
||||||
|
|
||||||
MARKERS = {
|
MARKERS = {
|
||||||
"*": MarkerType.BOLD_MODE,
|
"*": MarkerType.BOLD_MODE,
|
||||||
"~": MarkerType.CODE_MODE,
|
"~": MarkerType.CODE_MODE,
|
||||||
@ -157,14 +178,17 @@ for tok, mode in MARKERS.items():
|
|||||||
MarkerToken = collections.namedtuple("MarkerToken", ("closing", "tok_type"))
|
MarkerToken = collections.namedtuple("MarkerToken", ("closing", "tok_type"))
|
||||||
LinkToken = collections.namedtuple("LinkToken", ("tok_type"))
|
LinkToken = collections.namedtuple("LinkToken", ("tok_type"))
|
||||||
|
|
||||||
|
|
||||||
class LinkTokenType(Enum):
|
class LinkTokenType(Enum):
|
||||||
OPEN_LINK = 3
|
OPEN_LINK = 3
|
||||||
OPEN_DESCRIPTION = 5
|
OPEN_DESCRIPTION = 5
|
||||||
CLOSE = 4
|
CLOSE = 4
|
||||||
|
|
||||||
|
|
||||||
BEGIN_PROPERTIES = "OPEN_PROPERTIES"
|
BEGIN_PROPERTIES = "OPEN_PROPERTIES"
|
||||||
END_PROPERTIES = "CLOSE_PROPERTIES"
|
END_PROPERTIES = "CLOSE_PROPERTIES"
|
||||||
|
|
||||||
|
|
||||||
def token_from_type(tok_type):
|
def token_from_type(tok_type):
|
||||||
return ModeToMarker[tok_type]
|
return ModeToMarker[tok_type]
|
||||||
|
|
||||||
@ -258,9 +282,9 @@ class Link:
|
|||||||
|
|
||||||
def get_raw(self):
|
def get_raw(self):
|
||||||
if self.description:
|
if self.description:
|
||||||
return '[[{}][{}]]'.format(self.value, self.description)
|
return "[[{}][{}]]".format(self.value, self.description)
|
||||||
else:
|
else:
|
||||||
return '[[{}]]'.format(self.value)
|
return "[[{}]]".format(self.value)
|
||||||
|
|
||||||
|
|
||||||
class Text:
|
class Text:
|
||||||
@ -278,16 +302,16 @@ class Text:
|
|||||||
contents.append(chunk)
|
contents.append(chunk)
|
||||||
elif isinstance(chunk, LinkToken):
|
elif isinstance(chunk, LinkToken):
|
||||||
if chunk.tok_type == LinkTokenType.OPEN_LINK:
|
if chunk.tok_type == LinkTokenType.OPEN_LINK:
|
||||||
contents.append('[[')
|
contents.append("[[")
|
||||||
elif chunk.tok_type == LinkTokenType.OPEN_DESCRIPTION:
|
elif chunk.tok_type == LinkTokenType.OPEN_DESCRIPTION:
|
||||||
contents.append('][')
|
contents.append("][")
|
||||||
else:
|
else:
|
||||||
assert chunk.tok_type == LinkTokenType.CLOSE
|
assert chunk.tok_type == LinkTokenType.CLOSE
|
||||||
contents.append(']]')
|
contents.append("]]")
|
||||||
else:
|
else:
|
||||||
assert isinstance(chunk, MarkerToken)
|
assert isinstance(chunk, MarkerToken)
|
||||||
contents.append(token_from_type(chunk.tok_type))
|
contents.append(token_from_type(chunk.tok_type))
|
||||||
return ''.join(contents)
|
return "".join(contents)
|
||||||
|
|
||||||
|
|
||||||
class Bold:
|
class Bold:
|
||||||
@ -417,62 +441,67 @@ def tokenize_contents(contents: str):
|
|||||||
tokens.append((TOKEN_TYPE_TEXT, "".join(text)))
|
tokens.append((TOKEN_TYPE_TEXT, "".join(text)))
|
||||||
text = []
|
text = []
|
||||||
|
|
||||||
|
|
||||||
cursor = enumerate(contents)
|
cursor = enumerate(contents)
|
||||||
for i, char in cursor:
|
for i, char in cursor:
|
||||||
has_changed = False
|
has_changed = False
|
||||||
|
|
||||||
# Possible link opening
|
# Possible link opening
|
||||||
if char == '[':
|
if char == "[":
|
||||||
if (len(contents) > i + 3
|
if (
|
||||||
|
len(contents) > i + 3
|
||||||
# At least 3 characters more to open and close a link
|
# At least 3 characters more to open and close a link
|
||||||
and contents[i + 1] == '['):
|
and contents[i + 1] == "["
|
||||||
close = contents.find(']', i)
|
):
|
||||||
|
close = contents.find("]", i)
|
||||||
|
|
||||||
if close != -1 and contents[close + 1] == ']':
|
if close != -1 and contents[close + 1] == "]":
|
||||||
# Link with no description
|
# Link with no description
|
||||||
cut_string()
|
cut_string()
|
||||||
|
|
||||||
in_link = True
|
in_link = True
|
||||||
tokens.append((TOKEN_TYPE_OPEN_LINK, None))
|
tokens.append((TOKEN_TYPE_OPEN_LINK, None))
|
||||||
assert '[' == (next(cursor)[1])
|
assert "[" == (next(cursor)[1])
|
||||||
last_link_start = i
|
last_link_start = i
|
||||||
continue
|
continue
|
||||||
if close != -1 and contents[close + 1] == '[':
|
if close != -1 and contents[close + 1] == "[":
|
||||||
# Link with description?
|
# Link with description?
|
||||||
|
|
||||||
close = contents.find(']', close + 1)
|
close = contents.find("]", close + 1)
|
||||||
if close != -1 and contents[close + 1] == ']':
|
if close != -1 and contents[close + 1] == "]":
|
||||||
# No match here means this is not an Org link
|
# No match here means this is not an Org link
|
||||||
cut_string()
|
cut_string()
|
||||||
|
|
||||||
in_link = True
|
in_link = True
|
||||||
tokens.append((TOKEN_TYPE_OPEN_LINK, None))
|
tokens.append((TOKEN_TYPE_OPEN_LINK, None))
|
||||||
assert '[' == (next(cursor)[1])
|
assert "[" == (next(cursor)[1])
|
||||||
last_link_start = i
|
last_link_start = i
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Possible link close or open of description
|
# Possible link close or open of description
|
||||||
if char == ']' and in_link:
|
if char == "]" and in_link:
|
||||||
if contents[i + 1] == ']':
|
if contents[i + 1] == "]":
|
||||||
cut_string()
|
cut_string()
|
||||||
|
|
||||||
tokens.append((TOKEN_TYPE_CLOSE_LINK, None))
|
tokens.append((TOKEN_TYPE_CLOSE_LINK, None))
|
||||||
assert ']' == (next(cursor)[1])
|
assert "]" == (next(cursor)[1])
|
||||||
in_link = False
|
in_link = False
|
||||||
in_link_description = False
|
in_link_description = False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if contents[i + 1] == '[' and not in_link_description:
|
if contents[i + 1] == "[" and not in_link_description:
|
||||||
cut_string()
|
cut_string()
|
||||||
|
|
||||||
tokens.append((TOKEN_TYPE_OPEN_DESCRIPTION, None))
|
tokens.append((TOKEN_TYPE_OPEN_DESCRIPTION, None))
|
||||||
assert '[' == (next(cursor)[1])
|
assert "[" == (next(cursor)[1])
|
||||||
continue
|
continue
|
||||||
|
|
||||||
raise Exception("Link cannot contain ']' not followed by '[' or ']'. Starting with {}".format(contents[last_link_start:i + 10]))
|
raise Exception(
|
||||||
|
"Link cannot contain ']' not followed by '[' or ']'. Starting with {}".format(
|
||||||
|
contents[last_link_start : i + 10]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if (in_link and not in_link_description):
|
if in_link and not in_link_description:
|
||||||
# Link's pointer have no formatting
|
# Link's pointer have no formatting
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
from .org_dom import (Bold, Code, Headline, Italic, Line, RawLine, Strike,
|
from .org_dom import (
|
||||||
Text, Underlined, Verbatim)
|
Bold,
|
||||||
|
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:
|
||||||
@ -8,7 +18,7 @@ def get_hl_raw_contents(doc: Headline) -> str:
|
|||||||
for content in doc.contents:
|
for content in doc.contents:
|
||||||
lines.append(get_raw_contents(content))
|
lines.append(get_raw_contents(content))
|
||||||
|
|
||||||
raw = ''.join(lines)
|
raw = "".join(lines)
|
||||||
return raw
|
return raw
|
||||||
|
|
||||||
|
|
||||||
@ -19,9 +29,11 @@ def get_rawline_contents(doc: RawLine) -> str:
|
|||||||
def get_span_contents(doc: Line) -> str:
|
def get_span_contents(doc: Line) -> str:
|
||||||
return doc.get_raw()
|
return doc.get_raw()
|
||||||
|
|
||||||
|
|
||||||
def get_text_contents(doc: Text) -> str:
|
def get_text_contents(doc: Text) -> str:
|
||||||
return doc.get_raw()
|
return doc.get_raw()
|
||||||
|
|
||||||
|
|
||||||
def get_raw_contents(doc) -> str:
|
def get_raw_contents(doc) -> str:
|
||||||
if isinstance(doc, Headline):
|
if isinstance(doc, Headline):
|
||||||
return get_hl_raw_contents(doc)
|
return get_hl_raw_contents(doc)
|
||||||
@ -30,8 +42,8 @@ def get_raw_contents(doc) -> str:
|
|||||||
if isinstance(doc, Line):
|
if isinstance(doc, Line):
|
||||||
return get_span_contents(doc)
|
return get_span_contents(doc)
|
||||||
if isinstance(doc, list):
|
if isinstance(doc, list):
|
||||||
return ''.join([get_raw_contents(chunk) for chunk in doc])
|
return "".join([get_raw_contents(chunk) for chunk in doc])
|
||||||
if isinstance(doc, (Text, Bold, Code, Italic, Strike, Underlined, Verbatim)):
|
if isinstance(doc, (Text, Bold, Code, Italic, Strike, Underlined, Verbatim)):
|
||||||
return doc.get_raw()
|
return doc.get_raw()
|
||||||
print('Unhandled type: ' + str(doc))
|
print("Unhandled type: " + str(doc))
|
||||||
raise NotImplementedError('Unhandled type: ' + str(doc))
|
raise NotImplementedError("Unhandled type: " + str(doc))
|
||||||
|
18
setup.py
18
setup.py
@ -1,15 +1,15 @@
|
|||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='org-dom',
|
name="org-dom",
|
||||||
version='0.0.1',
|
version="0.0.1",
|
||||||
description=
|
description="Library to de/serialize org-files and manipulate them in a DOM-like manner.",
|
||||||
'Library to de/serialize org-files and manipulate them in a DOM-like manner.',
|
author="kenkeiras",
|
||||||
author='kenkeiras',
|
author_email="kenkeiras@codigoparallevar.com",
|
||||||
author_email='kenkeiras@codigoparallevar.com',
|
license="Apache License 2.0",
|
||||||
license='Apache License 2.0',
|
packages=["org_dom"],
|
||||||
packages=['org_dom'],
|
|
||||||
scripts=[],
|
scripts=[],
|
||||||
include_package_data=False,
|
include_package_data=False,
|
||||||
install_requires=[],
|
install_requires=[],
|
||||||
zip_safe=True)
|
zip_safe=True,
|
||||||
|
)
|
||||||
|
@ -4,37 +4,60 @@ import unittest
|
|||||||
from datetime import datetime as DT
|
from datetime import datetime as DT
|
||||||
|
|
||||||
from org_dom import dumps, load, loads
|
from org_dom import dumps, load, loads
|
||||||
from utils.dom_assertions import (BOLD, CODE, HL, ITALIC, SPAN, STRIKE,
|
|
||||||
UNDERLINED, VERBATIM, WEB_LINK, Dom, Tokens)
|
from utils.dom_assertions import (
|
||||||
|
BOLD,
|
||||||
|
CODE,
|
||||||
|
HL,
|
||||||
|
ITALIC,
|
||||||
|
SPAN,
|
||||||
|
STRIKE,
|
||||||
|
UNDERLINED,
|
||||||
|
VERBATIM,
|
||||||
|
WEB_LINK,
|
||||||
|
Dom,
|
||||||
|
Tokens,
|
||||||
|
)
|
||||||
|
|
||||||
DIR = os.path.dirname(os.path.abspath(__file__))
|
DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
class TestSerde(unittest.TestCase):
|
class TestSerde(unittest.TestCase):
|
||||||
def test_simple_file_01(self):
|
def test_simple_file_01(self):
|
||||||
with open(os.path.join(DIR, '01-simple.org')) as f:
|
with open(os.path.join(DIR, "01-simple.org")) as f:
|
||||||
doc = load(f)
|
doc = load(f)
|
||||||
|
|
||||||
ex = Dom(props=[('TITLE', '01-Simple'),
|
ex = Dom(
|
||||||
('DESCRIPTION', 'Simple org file'),
|
props=[
|
||||||
('TODO', 'TODO(t) PAUSED(p) | DONE(d)')],
|
("TITLE", "01-Simple"),
|
||||||
children=(HL(
|
("DESCRIPTION", "Simple org file"),
|
||||||
'First level',
|
("TODO", "TODO(t) PAUSED(p) | DONE(d)"),
|
||||||
props=[
|
],
|
||||||
('ID', '01-simple-first-level-id'),
|
children=(
|
||||||
('CREATED', DT(2020, 1, 1, 1, 1)),
|
HL(
|
||||||
],
|
"First level",
|
||||||
content=' First level content\n',
|
props=[
|
||||||
children=[
|
("ID", "01-simple-first-level-id"),
|
||||||
HL('Second level',
|
("CREATED", DT(2020, 1, 1, 1, 1)),
|
||||||
props=[('ID', '01-simple-second-level-id')],
|
],
|
||||||
content='\n Second level content\n',
|
content=" First level content\n",
|
||||||
|
children=[
|
||||||
|
HL(
|
||||||
|
"Second level",
|
||||||
|
props=[("ID", "01-simple-second-level-id")],
|
||||||
|
content="\n Second level content\n",
|
||||||
children=[
|
children=[
|
||||||
HL('Third level',
|
HL(
|
||||||
props=[('ID', '01-simple-third-level-id')],
|
"Third level",
|
||||||
content='\n Third level content\n')
|
props=[("ID", "01-simple-third-level-id")],
|
||||||
])
|
content="\n Third level content\n",
|
||||||
])))
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
ex.assert_matches(self, doc)
|
ex.assert_matches(self, doc)
|
||||||
|
|
||||||
@ -55,119 +78,180 @@ class TestSerde(unittest.TestCase):
|
|||||||
self.assertEqual(dumps(doc), orig)
|
self.assertEqual(dumps(doc), orig)
|
||||||
|
|
||||||
def test_markup_file_02(self):
|
def test_markup_file_02(self):
|
||||||
self.maxDiff = 10000
|
with open(os.path.join(DIR, "02-markup.org")) as f:
|
||||||
with open(os.path.join(DIR, '02-markup.org')) as f:
|
|
||||||
doc = load(f)
|
doc = load(f)
|
||||||
|
|
||||||
ex = Dom(props=[('TITLE', '02-Markup'),
|
ex = Dom(
|
||||||
('DESCRIPTION', 'Simple org file to test markup'),
|
props=[
|
||||||
('TODO', 'TODO(t) PAUSED(p) | DONE(d)')],
|
("TITLE", "02-Markup"),
|
||||||
children=(HL('First level',
|
("DESCRIPTION", "Simple org file to test markup"),
|
||||||
props=[
|
("TODO", "TODO(t) PAUSED(p) | DONE(d)"),
|
||||||
('ID', '02-markup-first-level-id'),
|
],
|
||||||
('CREATED', DT(2020, 1, 1, 1, 1)),
|
children=(
|
||||||
],
|
HL(
|
||||||
content=[
|
"First level",
|
||||||
SPAN(" This is a ", BOLD("bold phrase"),
|
props=[
|
||||||
".\n"),
|
("ID", "02-markup-first-level-id"),
|
||||||
SPAN("\n"),
|
("CREATED", DT(2020, 1, 1, 1, 1)),
|
||||||
SPAN(" This is a ",
|
],
|
||||||
VERBATIM("verbatim phrase"), ".\n"),
|
content=[
|
||||||
SPAN("\n"),
|
SPAN(" This is a ", BOLD("bold phrase"), ".\n"),
|
||||||
SPAN(" This is a ", ITALIC("italic phrase"),
|
SPAN("\n"),
|
||||||
".\n"),
|
SPAN(" This is a ", VERBATIM("verbatim phrase"), ".\n"),
|
||||||
SPAN("\n"),
|
SPAN("\n"),
|
||||||
SPAN(" This is a ",
|
SPAN(" This is a ", ITALIC("italic phrase"), ".\n"),
|
||||||
STRIKE("strike-through phrase"), ".\n"),
|
SPAN("\n"),
|
||||||
SPAN("\n"),
|
SPAN(" This is a ", STRIKE("strike-through phrase"), ".\n"),
|
||||||
SPAN(" This is a ",
|
SPAN("\n"),
|
||||||
UNDERLINED("underlined phrase"), ".\n"),
|
SPAN(" This is a ", UNDERLINED("underlined phrase"), ".\n"),
|
||||||
SPAN("\n"),
|
SPAN("\n"),
|
||||||
SPAN(" This is a ", CODE("code phrase"),
|
SPAN(" This is a ", CODE("code phrase"), ".\n"),
|
||||||
".\n"),
|
SPAN("\n"),
|
||||||
|
SPAN(
|
||||||
SPAN("\n"),
|
" This is a nested ",
|
||||||
SPAN(" This is a nested ", BOLD(["bold ", VERBATIM(["verbatim ", ITALIC(["italic ", STRIKE(["strike ", UNDERLINED(["underlined ", CODE("code ."), " ."]), " ."]), " ."]), " ."]), " ."])),
|
BOLD(
|
||||||
SPAN("\n"),
|
[
|
||||||
|
"bold ",
|
||||||
SPAN("\n"),
|
VERBATIM(
|
||||||
# THIS IS INTERLEAVED, not nested
|
[
|
||||||
SPAN([" This is a interleaved ",
|
"verbatim ",
|
||||||
Tokens.BOLD_START,
|
ITALIC(
|
||||||
"bold ",
|
[
|
||||||
Tokens.VERBATIM_START,
|
"italic ",
|
||||||
"verbatim ",
|
STRIKE(
|
||||||
Tokens.ITALIC_START,
|
[
|
||||||
"italic ",
|
"strike ",
|
||||||
Tokens.STRIKE_START,
|
UNDERLINED(
|
||||||
"strike ",
|
[
|
||||||
Tokens.UNDERLINED_START,
|
"underlined ",
|
||||||
"underlined ",
|
CODE("code ."),
|
||||||
Tokens.CODE_START,
|
" .",
|
||||||
"code .",
|
]
|
||||||
Tokens.BOLD_END,
|
),
|
||||||
" .",
|
" .",
|
||||||
Tokens.VERBATIM_END,
|
]
|
||||||
" .",
|
),
|
||||||
Tokens.ITALIC_END,
|
" .",
|
||||||
" .",
|
]
|
||||||
Tokens.STRIKE_END,
|
),
|
||||||
" .",
|
" .",
|
||||||
Tokens.UNDERLINED_END,
|
]
|
||||||
" .",
|
),
|
||||||
Tokens.CODE_END,
|
" .",
|
||||||
"\n"]),
|
]
|
||||||
|
),
|
||||||
SPAN("\n"),
|
),
|
||||||
SPAN(" This is a _ non-underlined phrase because an incorrectly placed content _.\n"),
|
SPAN("\n"),
|
||||||
SPAN("\n"),
|
SPAN("\n"),
|
||||||
|
# THIS IS INTERLEAVED, not nested
|
||||||
SPAN(" This is a _ non-underlined phrase because an incorrectly placed content beginning_.\n"),
|
SPAN(
|
||||||
SPAN("\n"),
|
[
|
||||||
|
" This is a interleaved ",
|
||||||
SPAN(""),
|
Tokens.BOLD_START,
|
||||||
SPAN(" This is a _non-underlined phrase because an incorrectly placed content end _.\n"),
|
"bold ",
|
||||||
SPAN("\n"),
|
Tokens.VERBATIM_START,
|
||||||
|
"verbatim ",
|
||||||
SPAN(""),
|
Tokens.ITALIC_START,
|
||||||
SPAN(" This is a _non-underlined phrase because the lack of an end.\n"),
|
"italic ",
|
||||||
SPAN("\n"),
|
Tokens.STRIKE_START,
|
||||||
|
"strike ",
|
||||||
SPAN("\n"),
|
Tokens.UNDERLINED_START,
|
||||||
SPAN(" This is a _non-underlined phrase because an empty line between beginning and\n"),
|
"underlined ",
|
||||||
SPAN("\n"),
|
Tokens.CODE_START,
|
||||||
|
"code .",
|
||||||
SPAN(""),
|
Tokens.BOLD_END,
|
||||||
SPAN(" end._\n"),
|
" .",
|
||||||
])))
|
Tokens.VERBATIM_END,
|
||||||
|
" .",
|
||||||
|
Tokens.ITALIC_END,
|
||||||
|
" .",
|
||||||
|
Tokens.STRIKE_END,
|
||||||
|
" .",
|
||||||
|
Tokens.UNDERLINED_END,
|
||||||
|
" .",
|
||||||
|
Tokens.CODE_END,
|
||||||
|
"\n",
|
||||||
|
]
|
||||||
|
),
|
||||||
|
SPAN("\n"),
|
||||||
|
SPAN(
|
||||||
|
" This is a _ non-underlined phrase because an incorrectly placed content _.\n"
|
||||||
|
),
|
||||||
|
SPAN("\n"),
|
||||||
|
SPAN(
|
||||||
|
" This is a _ non-underlined phrase because an incorrectly placed content beginning_.\n"
|
||||||
|
),
|
||||||
|
SPAN("\n"),
|
||||||
|
SPAN(""),
|
||||||
|
SPAN(
|
||||||
|
" This is a _non-underlined phrase because an incorrectly placed content end _.\n"
|
||||||
|
),
|
||||||
|
SPAN("\n"),
|
||||||
|
SPAN(""),
|
||||||
|
SPAN(
|
||||||
|
" This is a _non-underlined phrase because the lack of an end.\n"
|
||||||
|
),
|
||||||
|
SPAN("\n"),
|
||||||
|
SPAN("\n"),
|
||||||
|
SPAN(
|
||||||
|
" This is a _non-underlined phrase because an empty line between beginning and\n"
|
||||||
|
),
|
||||||
|
SPAN("\n"),
|
||||||
|
SPAN(""),
|
||||||
|
SPAN(" end._\n"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
ex.assert_matches(self, doc)
|
ex.assert_matches(self, doc)
|
||||||
|
|
||||||
def test_links_file_03(self):
|
def test_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), 2)
|
||||||
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")
|
||||||
ex = Dom(props=[('TITLE', '03-Links'),
|
ex = Dom(
|
||||||
('DESCRIPTION', 'Simple org file to test links'),
|
props=[
|
||||||
('TODO', 'TODO(t) PAUSED(p) | DONE(d)')],
|
("TITLE", "03-Links"),
|
||||||
children=(HL('First level',
|
("DESCRIPTION", "Simple org file to test links"),
|
||||||
props=[
|
("TODO", "TODO(t) PAUSED(p) | DONE(d)"),
|
||||||
('ID', '03-markup-first-level-id'),
|
],
|
||||||
('CREATED', DT(2020, 1, 1, 1, 1)),
|
children=(
|
||||||
],
|
HL(
|
||||||
content=[
|
"First level",
|
||||||
SPAN(" This is a ", WEB_LINK("web link", "https://codigoparallevar.com/1"),
|
props=[
|
||||||
".\n"),
|
("ID", "03-markup-first-level-id"),
|
||||||
SPAN("\n"),
|
("CREATED", DT(2020, 1, 1, 1, 1)),
|
||||||
SPAN(" This is a ", ITALIC(["italized ", WEB_LINK("web link", "https://codigoparallevar.com/2")]),
|
],
|
||||||
".\n"),
|
content=[
|
||||||
])))
|
SPAN(
|
||||||
|
" This is a ",
|
||||||
|
WEB_LINK("web link", "https://codigoparallevar.com/1"),
|
||||||
|
".\n",
|
||||||
|
),
|
||||||
|
SPAN("\n"),
|
||||||
|
SPAN(
|
||||||
|
" This is a ",
|
||||||
|
ITALIC(
|
||||||
|
[
|
||||||
|
"italized ",
|
||||||
|
WEB_LINK(
|
||||||
|
"web link", "https://codigoparallevar.com/2"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
".\n",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
ex.assert_matches(self, doc)
|
ex.assert_matches(self, doc)
|
||||||
|
@ -2,8 +2,17 @@ import collections
|
|||||||
import unittest
|
import unittest
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from org_dom import (Bold, Code, Italic, Line, Strike, Text, Underlined,
|
from org_dom import (
|
||||||
Verbatim, get_raw_contents)
|
Bold,
|
||||||
|
Code,
|
||||||
|
Italic,
|
||||||
|
Line,
|
||||||
|
Strike,
|
||||||
|
Text,
|
||||||
|
Underlined,
|
||||||
|
Verbatim,
|
||||||
|
get_raw_contents,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def timestamp_to_datetime(ts):
|
def timestamp_to_datetime(ts):
|
||||||
|
Loading…
Reference in New Issue
Block a user