Compare commits

..

4 Commits

Author SHA1 Message Date
Sergio Martínez Portela
da2d8c8c6d Add org-todo-keywords environment to programatically set states.
Some checks failed
Testing / pytest (push) Successful in 41s
Testing / mypy (push) Failing after 32s
Testing / stability-extra-test (push) Successful in 25s
2024-07-20 14:42:41 +02:00
Sergio Martínez Portela
4c169f5d47 Add (passing) test to read TODO/DONE states from file. 2024-07-20 14:42:20 +02:00
Sergio Martínez Portela
f4d63c2f93 Add (failing) test. 2024-07-20 14:41:09 +02:00
Sergio Martínez Portela
a56ac018a8 Prepare for PyPI pushising, bumb version.
Some checks failed
Testing / pytest (push) Successful in 25s
Testing / mypy (push) Failing after 30s
Testing / stability-extra-test (push) Successful in 22s
2024-07-19 20:01:27 +02:00
5 changed files with 59 additions and 9 deletions

3
.gitignore vendored
View File

@ -139,3 +139,6 @@ dmypy.json
# Cython debug symbols # Cython debug symbols
cython_debug/ cython_debug/
# Files for PyPI publishing
README.md

View File

@ -17,8 +17,12 @@ from . import dom
DEBUG_DIFF_CONTEXT = 10 DEBUG_DIFF_CONTEXT = 10
DEFAULT_TODO_KEYWORDS = ["TODO"]
DEFAULT_DONE_KEYWORDS = ["DONE"]
BASE_ENVIRONMENT = { BASE_ENVIRONMENT = {
"org-footnote-section": "Footnotes", "org-footnote-section": "Footnotes",
"org-todo-keywords": ' '.join(DEFAULT_TODO_KEYWORDS) + ' | ' + ' '.join(DEFAULT_DONE_KEYWORDS),
"org-options-keywords": ( "org-options-keywords": (
"ARCHIVE:", "ARCHIVE:",
"AUTHOR:", "AUTHOR:",
@ -52,9 +56,6 @@ BASE_ENVIRONMENT = {
), ),
} }
DEFAULT_TODO_KEYWORDS = ["TODO"]
DEFAULT_DONE_KEYWORDS = ["DONE"]
HEADLINE_TAGS_RE = re.compile(r"((:(\w|[0-9_@#%])+)+:)\s*$") HEADLINE_TAGS_RE = re.compile(r"((:(\w|[0-9_@#%])+)+:)\s*$")
HEADLINE_RE = re.compile(r"^(?P<stars>\*+)(?P<spacing>\s+)(?P<line>.*?)$") HEADLINE_RE = re.compile(r"^(?P<stars>\*+)(?P<spacing>\s+)(?P<line>.*?)$")
KEYWORDS_RE = re.compile( KEYWORDS_RE = re.compile(
@ -1864,17 +1865,27 @@ def dump_delimiters(line: DelimiterLine):
class OrgDoc: class OrgDoc:
def __init__( def __init__(
self, headlines, keywords, contents, list_items, structural, properties self, headlines, keywords, contents, list_items, structural, properties,
environment=BASE_ENVIRONMENT,
): ):
self.todo_keywords = DEFAULT_TODO_KEYWORDS self.todo_keywords = DEFAULT_TODO_KEYWORDS
self.done_keywords = DEFAULT_DONE_KEYWORDS self.done_keywords = DEFAULT_DONE_KEYWORDS
keywords_set_in_file = False
for keyword in keywords: for keyword in keywords:
if keyword.key in ("TODO", "SEQ_TODO"): if keyword.key in ("TODO", "SEQ_TODO"):
todo_kws, done_kws = re.sub(r"\([^)]+\)", "", keyword.value).split("|", 1) todo_kws, done_kws = re.sub(r"\([^)]+\)", "", keyword.value).split("|", 1)
self.todo_keywords = re.sub(r"\s{2,}", " ", todo_kws.strip()).split() self.todo_keywords = re.sub(r"\s{2,}", " ", todo_kws.strip()).split()
self.done_keywords = re.sub(r"\s{2,}", " ", done_kws.strip()).split() self.done_keywords = re.sub(r"\s{2,}", " ", done_kws.strip()).split()
keywords_set_in_file = True
if not keywords_set_in_file and 'org-todo-keywords' in environment:
# Read keywords from environment
todo_kws, done_kws = re.sub(r"\([^)]+\)", "", environment['org-todo-keywords']).split("|", 1)
self.todo_keywords = re.sub(r"\s{2,}", " ", todo_kws.strip()).split()
self.done_keywords = re.sub(r"\s{2,}", " ", done_kws.strip()).split()
self.keywords: List[Property] = keywords self.keywords: List[Property] = keywords
self.contents: List[RawLine] = contents self.contents: List[RawLine] = contents
@ -2050,7 +2061,7 @@ class OrgDoc:
class OrgDocReader: class OrgDocReader:
def __init__(self): def __init__(self, environment=BASE_ENVIRONMENT):
self.headlines: List[HeadlineDict] = [] self.headlines: List[HeadlineDict] = []
self.keywords: List[Keyword] = [] self.keywords: List[Keyword] = []
self.headline_hierarchy: List[Optional[HeadlineDict]] = [] self.headline_hierarchy: List[Optional[HeadlineDict]] = []
@ -2061,6 +2072,7 @@ class OrgDocReader:
self.structural: List = [] self.structural: List = []
self.properties: List = [] self.properties: List = []
self.current_drawer: Optional[List] = None self.current_drawer: Optional[List] = None
self.environment = environment
def finalize(self): def finalize(self):
return OrgDoc( return OrgDoc(
@ -2070,6 +2082,7 @@ class OrgDocReader:
self.list_items, self.list_items,
self.structural, self.structural,
self.properties, self.properties,
self.environment,
) )
## Construction ## Construction
@ -2258,7 +2271,7 @@ class OrgDocReader:
self.current_drawer.append(Property(linenum, match, key, value, None)) self.current_drawer.append(Property(linenum, match, key, value, None))
def read(self, s, environment): def read(self, s):
lines = s.split("\n") lines = s.split("\n")
line_count = len(lines) line_count = len(lines)
reader = enumerate(lines) reader = enumerate(lines)
@ -2349,8 +2362,8 @@ class OrgDocReader:
def loads(s, environment=BASE_ENVIRONMENT, extra_cautious=True): def loads(s, environment=BASE_ENVIRONMENT, extra_cautious=True):
reader = OrgDocReader() reader = OrgDocReader(environment)
reader.read(s, environment) reader.read(s)
doc = reader.finalize() doc = reader.finalize()
if extra_cautious: # Check that all options can be properly re-serialized if extra_cautious: # Check that all options can be properly re-serialized
after_dump = dumps(doc) after_dump = dumps(doc)

View File

@ -5,6 +5,8 @@ set -eu
cd "`dirname $0`" cd "`dirname $0`"
cd .. cd ..
pandoc README.org -o README.md # PyPI doesn't accept Org files
python setup.py sdist python setup.py sdist
twine upload --verbose dist/* twine upload --verbose dist/*

View File

@ -2,7 +2,7 @@ from setuptools import setup
setup( setup(
name="org-rw", name="org-rw",
version="0.0.1.dev1", version="0.0.2",
description="Library to de/serialize org-files and manipulate them.", description="Library to de/serialize org-files and manipulate them.",
author="kenkeiras", author="kenkeiras",
author_email="kenkeiras@codigoparallevar.com", author_email="kenkeiras@codigoparallevar.com",

View File

@ -794,6 +794,38 @@ class TestSerde(unittest.TestCase):
self.assertEqual(dumps(doc), orig) self.assertEqual(dumps(doc), orig)
def test_add_todo_keywords_programatically(self):
orig = '''* NEW_TODO_STATE First entry
* NEW_DONE_STATE Second entry'''
doc = loads(orig, environment={
'org-todo-keywords': "NEW_TODO_STATE | NEW_DONE_STATE"
})
self.assertEqual(doc.headlines[0].is_todo, True)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[1].is_todo, False)
self.assertEqual(doc.headlines[1].is_done, True)
self.assertEqual(dumps(doc), orig)
def test_add_todo_keywords_in_file(self):
orig = '''#+TODO: NEW_TODO_STATE | NEW_DONE_STATE
* NEW_TODO_STATE First entry
* NEW_DONE_STATE Second entry'''
doc = loads(orig, environment={
'org-todo-keywords': "NEW_TODO_STATE | NEW_DONE_STATE"
})
self.assertEqual(doc.headlines[0].is_todo, True)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[1].is_todo, False)
self.assertEqual(doc.headlines[1].is_done, True)
self.assertEqual(dumps(doc), orig)
def print_tree(tree, indentation=0, headline=None): def print_tree(tree, indentation=0, headline=None):
for element in tree: for element in tree: