Coverage for src/crawler/cmds/mixed_citation.py: 95%
49 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-09-23 14:47 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-09-23 14:47 +0000
1"""
2Helpers to create an xml string for mixed citations
5"""
7from lxml import etree
8from lxml.builder import E
9from lxml.etree import Element
10from ptf.cmds.xml.jats.jats_parser import parse_mixed_citation_into_ref
11from ptf.cmds.xml.xml_utils import escape
12from ptf.display.resolver import extids_formats, reverse_extids_hrefs
15class GenericRefElement:
16 name: str
17 elements: list["str | GenericRefElement"]
18 attributes: dict[str, str]
20 def __init__(self) -> None:
21 super().__init__()
22 self.elements = []
23 self.attributes = {}
25 def get_xml_element(self):
26 xml_elements: list[str | Element] = []
28 for item in self.elements:
29 if isinstance(item, str):
30 xml_elements.append(item)
31 else:
32 xml_elements.append(item.get_xml_element())
34 return E(self.name, *xml_elements, **self.attributes)
36 def get_xml_string(self):
37 """
38 Make sure the hierarchy of the objects (self.elements) is valid JATS
39 before calling this function
40 """
41 return etree.tostring(self.get_xml_element(), pretty_print=True).decode()
44def find_extlink(url: str):
45 for pattern in reverse_extids_hrefs:
46 if url.startswith(pattern):
47 type = reverse_extids_hrefs[pattern]
48 content = url.removeprefix(pattern)
49 return type, content
50 return None, None
53class ExtLinkXml(GenericRefElement):
54 """How to use :
55 ```py
56 url = "https://doi.org/10.1017/S0143385700002364"
57 extlink = ExtLinkXml(url)
58 citation_builder.elements.append(url)
59 ```
60 """
62 name = "ext-link"
64 def __init__(self, url: str, content: str | None = None, type: str = "uri") -> None:
65 super().__init__()
67 if not content: 67 ↛ 68line 67 didn't jump to line 68 because the condition on line 67 was never true
68 content = url
70 if type not in extids_formats: 70 ↛ 75line 70 didn't jump to line 75 because the condition on line 70 was always true
71 type_found, content_found = find_extlink(url)
72 type = type_found or type
73 content = content_found or content
75 self.attributes["ext-link-type"] = type
76 self.attributes["href"] = url
78 self.elements.append(escape(content))
81class MixedCitation(GenericRefElement):
82 """
83 ```py
84 citation_builder = MixedCitation()
86 citation_builder.label = "[1]"
88 persongroup = GenericXMLTemplate()
89 persongroup.name = "person-group"
90 persongroup.elements.append("Michel B.")
91 citation_builder.elements.append(persongroup)
93 citation_builder.elements.append("untagged string to put between")
95 year_builder = Year()
96 year.elements.append("2020")
97 citation_builder.elements.append(year)
99 mixedcitation.get_jats_ref()
100 ```
101 """
103 name = "mixed-citation"
104 label: str | None = None
106 def get_jats_ref(self):
107 citation_xml = self.get_xml_string()
108 return parse_mixed_citation_into_ref(citation_xml, label=self.label)