From fba03c4fb6b4b04788dfc4993ebc18d8ad20e436 Mon Sep 17 00:00:00 2001 From: Johan Hidding Date: Tue, 9 Jul 2024 13:07:52 +0200 Subject: [PATCH] create an alias for code blocks that have both file and id tags; fix #46 --- entangled/document.py | 6 +++ entangled/markdown_reader.py | 6 +++ entangled/tangle.py | 3 ++ test/test_id_and_file_target.py | 70 +++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 test/test_id_and_file_target.py diff --git a/entangled/document.py b/entangled/document.py index 9c35ad5..26ee2e2 100644 --- a/entangled/document.py +++ b/entangled/document.py @@ -57,11 +57,17 @@ class ReferenceMap: default_factory=lambda: defaultdict(list) ) targets: set[str] = field(default_factory=set) + alias: dict[str, str] = field(default_factory=dict) def names(self) -> Iterable[str]: return self.index.keys() def by_name(self, n: str) -> Iterable[CodeBlock]: + if n not in self.index and n not in self.alias: + raise AttributeError(name=n, obj=self) + if n not in self.index: + return self.by_name(self.alias[n]) + return (self.map[r] for r in self.index[n]) def new_id(self, filename: str, name: str) -> ReferenceId: diff --git a/entangled/markdown_reader.py b/entangled/markdown_reader.py index 6c974a1..fb308d5 100644 --- a/entangled/markdown_reader.py +++ b/entangled/markdown_reader.py @@ -130,6 +130,12 @@ def on_close_codeblock(self, m: re.Match): self.reference_map[ref] = code if target_file is not None: self.reference_map.targets.add(target_file) + + # when both target_file and block_id are given, + # make an alias + if target_file is not None and block_id is not None: + self.reference_map.alias[target_file] = block_id + self.content.append(ref) self.current_content = [] diff --git a/entangled/tangle.py b/entangled/tangle.py index 31033f4..c2d11d6 100644 --- a/entangled/tangle.py +++ b/entangled/tangle.py @@ -119,6 +119,9 @@ def tangle_ref( if annotation is None: annotation = config.annotation + if ref_name in refs.alias: + ref_name = refs.alias[ref_name] + if ref_name not in refs: raise KeyError(ref_name) v = _visited or Visitor() diff --git a/test/test_id_and_file_target.py b/test/test_id_and_file_target.py new file mode 100644 index 0000000..2f35c60 --- /dev/null +++ b/test/test_id_and_file_target.py @@ -0,0 +1,70 @@ +from entangled.markdown_reader import MarkdownReader +from entangled.tangle import tangle_ref, AnnotationMethod + +md_in = """ +``` {.rust file=test1.rs #blockid1} +fn main() { + println!("Hello, World!"); +} +``` + +``` {.rust #blockid2 file=test2.rs} +fn main() { + println!("Hello, World!"); +} +``` + +``` {.rust #blockid3 file=test3.rs} +fn fac(i: u64) -> u64 { + result: u64 = 1; + for j in 1..i { + result *= j; + } + return result; +} +``` + +``` {.rust #blockid3} +fn main() { + println!("42! = {}", fac(42)); +} +``` +""" + +result1_out = result2_out = """ +fn main() { + println!("Hello, World!"); +} +""" + +result3_out = """ +fn fac(i: u64) -> u64 { + result: u64 = 1; + for j in 1..i { + result *= j; + } + return result; +} +fn main() { + println!("42! = {}", fac(42)); +} +""" + +def test_id_and_file_target(): + mr = MarkdownReader("-") + mr.run(md_in) + + content1, _ = tangle_ref(mr.reference_map, "blockid1", AnnotationMethod.NAKED) + assert content1.strip() == result1_out.strip() + content2, _ = tangle_ref(mr.reference_map, "blockid2", AnnotationMethod.NAKED) + assert content2.strip() == result2_out.strip() + content3, _ = tangle_ref(mr.reference_map, "blockid3", AnnotationMethod.NAKED) + assert content3.strip() == result3_out.strip() + + assert mr.reference_map.targets == {"test1.rs", "test2.rs", "test3.rs"} + for i in range(1, 4): + ref = f"test{i}.rs" + bid = f"blockid{i}" + c, _ = tangle_ref(mr.reference_map, ref, AnnotationMethod.NAKED) + d, _ = tangle_ref(mr.reference_map, ref, AnnotationMethod.NAKED) + assert c == d