From 9b319a90dc5f46b55ff55ed021a61190b8553ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Mon, 30 Sep 2024 23:11:21 +0200 Subject: [PATCH 1/3] Read names for code blocks. --- org_rw/org_rw.py | 13 ++++++++++++- tests/04-code.org | 1 + tests/test_org.py | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index d7d6ad8..7129393 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -882,6 +882,12 @@ class Headline: sections = [] arguments = None + names_by_line = {} + for kw in self.keywords: + if kw.key == "NAME": + names_by_line[kw.linenum] = kw.value + + name = None for delimiter in self.delimiters: if ( delimiter.delimiter_type == DelimiterLineType.BEGIN_BLOCK @@ -890,6 +896,12 @@ class Headline: line_start = delimiter.linenum inside_code = True arguments = delimiter.arguments + + name_line = line_start - 1 + if name_line in names_by_line: + name = names_by_line[name_line] + else: + name = None elif ( delimiter.delimiter_type == DelimiterLineType.END_BLOCK and delimiter.type_data.subtype.lower() == "src" @@ -960,7 +972,6 @@ class Headline: results = [] for section in sections: - name = None content = section["content"] code_result = section.get("result", None) arguments = section.get("arguments", None) diff --git a/tests/04-code.org b/tests/04-code.org index 956d961..7af3aed 100644 --- a/tests/04-code.org +++ b/tests/04-code.org @@ -9,6 +9,7 @@ :CREATED: [2020-01-01 Wed 01:01] :END: +#+NAME: first-code-name #+BEGIN_SRC shell :results verbatim echo "This is a test" echo "with two lines" diff --git a/tests/test_org.py b/tests/test_org.py index f27185b..5a0bc53 100644 --- a/tests/test_org.py +++ b/tests/test_org.py @@ -480,6 +480,7 @@ class TestSerde(unittest.TestCase): snippets = list(doc.get_code_snippets()) self.assertEqual(len(snippets), 3) + self.assertEqual(snippets[0].name, "first-code-name") self.assertEqual( snippets[0].content, 'echo "This is a test"\n' @@ -494,6 +495,7 @@ class TestSerde(unittest.TestCase): "This is a test\n" + "with two lines", ) + self.assertEqual(snippets[1].name, None) self.assertEqual( snippets[1].content, 'echo "This is another test"\n' @@ -504,6 +506,7 @@ class TestSerde(unittest.TestCase): snippets[1].result, "This is another test\n" + "with two lines too" ) + self.assertEqual(snippets[2].name, None) self.assertEqual( snippets[2].content, "/* This code has to be escaped to\n" From 8fe3c27595d16584f72c01f9834378df0b8eec2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Mon, 30 Sep 2024 23:11:21 +0200 Subject: [PATCH 2/3] Read names for code blocks. --- org_rw/org_rw.py | 21 +++++++++++++++++++-- tests/04-code.org | 1 + tests/test_org.py | 3 +++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index d7d6ad8..c5ae4f7 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -882,6 +882,12 @@ class Headline: sections = [] arguments = None + names_by_line = {} + for kw in self.keywords: + if kw.key == "NAME": + names_by_line[kw.linenum] = kw.value + + name = None for delimiter in self.delimiters: if ( delimiter.delimiter_type == DelimiterLineType.BEGIN_BLOCK @@ -890,6 +896,12 @@ class Headline: line_start = delimiter.linenum inside_code = True arguments = delimiter.arguments + + name_line = line_start - 1 + if name_line in names_by_line: + name = names_by_line[name_line] + else: + name = None elif ( delimiter.delimiter_type == DelimiterLineType.END_BLOCK and delimiter.type_data.subtype.lower() == "src" @@ -910,8 +922,10 @@ class Headline: "line_last": end - 1, "content": contents, "arguments": arguments, + "name": name, } ) + name = None arguments = None line_start = None @@ -960,13 +974,16 @@ class Headline: results = [] for section in sections: - name = None content = section["content"] code_result = section.get("result", None) arguments = section.get("arguments", None) + name = section.get("name", None) results.append( CodeSnippet( - name=name, content=content, result=code_result, arguments=arguments + content=content, + result=code_result, + arguments=arguments, + name=name, ) ) diff --git a/tests/04-code.org b/tests/04-code.org index 956d961..7af3aed 100644 --- a/tests/04-code.org +++ b/tests/04-code.org @@ -9,6 +9,7 @@ :CREATED: [2020-01-01 Wed 01:01] :END: +#+NAME: first-code-name #+BEGIN_SRC shell :results verbatim echo "This is a test" echo "with two lines" diff --git a/tests/test_org.py b/tests/test_org.py index f27185b..5a0bc53 100644 --- a/tests/test_org.py +++ b/tests/test_org.py @@ -480,6 +480,7 @@ class TestSerde(unittest.TestCase): snippets = list(doc.get_code_snippets()) self.assertEqual(len(snippets), 3) + self.assertEqual(snippets[0].name, "first-code-name") self.assertEqual( snippets[0].content, 'echo "This is a test"\n' @@ -494,6 +495,7 @@ class TestSerde(unittest.TestCase): "This is a test\n" + "with two lines", ) + self.assertEqual(snippets[1].name, None) self.assertEqual( snippets[1].content, 'echo "This is another test"\n' @@ -504,6 +506,7 @@ class TestSerde(unittest.TestCase): snippets[1].result, "This is another test\n" + "with two lines too" ) + self.assertEqual(snippets[2].name, None) self.assertEqual( snippets[2].content, "/* This code has to be escaped to\n" From 66ccb662117aa034365dcef470f74738d52738a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Mart=C3=ADnez=20Portela?= Date: Mon, 30 Sep 2024 23:39:43 +0200 Subject: [PATCH 3/3] Explicitly extract code block language. --- org_rw/org_rw.py | 10 +++++++++- tests/test_org.py | 5 ++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index c5ae4f7..8cb3855 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -113,7 +113,7 @@ BEGIN_BLOCK_RE = re.compile(r"^\s*#\+BEGIN_(?P[^ ]+)(?P.*)$" END_BLOCK_RE = re.compile(r"^\s*#\+END_(?P[^ ]+)\s*$", re.I) RESULTS_DRAWER_RE = re.compile(r"^\s*:results:\s*$", re.I) CodeSnippet = collections.namedtuple( - "CodeSnippet", ("name", "content", "result", "arguments") + "CodeSnippet", ("name", "content", "result", "language", "arguments") ) # Groupings @@ -916,12 +916,19 @@ class Headline: # the content parsing must be re-thinked contents = contents[:-1] + language = None + if arguments is not None: + arguments = arguments.strip() + if " " in arguments: + language = arguments[: arguments.index(" ")] + arguments = arguments[arguments.index(" ") + 1 :] sections.append( { "line_first": start + 1, "line_last": end - 1, "content": contents, "arguments": arguments, + "language": language, "name": name, } ) @@ -983,6 +990,7 @@ class Headline: content=content, result=code_result, arguments=arguments, + language=language, name=name, ) ) diff --git a/tests/test_org.py b/tests/test_org.py index 5a0bc53..ad35b89 100644 --- a/tests/test_org.py +++ b/tests/test_org.py @@ -481,6 +481,7 @@ class TestSerde(unittest.TestCase): snippets = list(doc.get_code_snippets()) self.assertEqual(len(snippets), 3) self.assertEqual(snippets[0].name, "first-code-name") + self.assertEqual(snippets[0].language, "shell") self.assertEqual( snippets[0].content, 'echo "This is a test"\n' @@ -488,7 +489,7 @@ class TestSerde(unittest.TestCase): + "exit 0 # Exit successfully", ) self.assertEqual( - snippets[0].arguments.split(), ["shell", ":results", "verbatim"] + snippets[0].arguments.split(), [":results", "verbatim"] ) self.assertEqual( snippets[0].result, @@ -496,6 +497,7 @@ class TestSerde(unittest.TestCase): ) self.assertEqual(snippets[1].name, None) + self.assertEqual(snippets[1].language, "shell") self.assertEqual( snippets[1].content, 'echo "This is another test"\n' @@ -507,6 +509,7 @@ class TestSerde(unittest.TestCase): ) self.assertEqual(snippets[2].name, None) + self.assertEqual(snippets[2].language, "c") self.assertEqual( snippets[2].content, "/* This code has to be escaped to\n"