diff --git a/packtools/sps/formats/sps_xml/ref.py b/packtools/sps/formats/sps_xml/ref.py index 304659a93..4ae3603ca 100644 --- a/packtools/sps/formats/sps_xml/ref.py +++ b/packtools/sps/formats/sps_xml/ref.py @@ -1,52 +1,93 @@ -""" -data = { - "ref-id": "B1", - "label": "1", - "mixed-citation": "Aires M, Paz AA, Perosa CT. Situação de saúde...", - "publication-type": "journal", - "article-title": "Situação de saúde e grau de...", - "chapter-title": "The epidemiology of idiopathic inflammatory bowel disease.", - "source": "Rev Gaucha Enferm", - "edition": "4th ed", - "publisher-loc": "Rio de Janeiro", - "publisher-name": "Universidade Federal do Paraná", - "volume": "30", - "issue": "3", - "data-title": "Estudos de genes em ratos albinos na América Latina", - "version": "23 jan.", - "series": "Second International Workshop", - "day": "22", - "month": "10", - "year": "2009", - "fpage": "192", - "lpage": "199", - "ext-link": [ - { - "ext-link-type": "uri", - "xlink:href": "http://socialsciences.scielo.org", - "text": "http://socialsciences.scielo.org" - } - ] - "pub-ids": [ - { - "pub-id-type": "pmid", - "text": "15867408" - } - ] - "dates-in-citation": [ - { - "content-type": "updated", - "text": "2006 Jul 20" - } - ] -} - -""" - import xml.etree.ElementTree as ET -def build_ref(data): +def build_ref(data, node=None): + """ + Builds an XML element representing a bibliographic reference. + + Args: + data (dict): A dictionary containing reference details with the following structure: + - "ref-id" (str): Unique identifier for the reference (required). + - "label" (str): Label for the reference, e.g., "1" (optional). + - "mixed-citation" (str): Mixed content citation text (optional). + - "publication-type" (str): Type of publication, e.g., "journal", "book" (required). + - Additional bibliographic keys (optional): + - "article-title", "chapter-title", "source", "edition", "publisher-loc", + "publisher-name", "series", "day", "month", "year", "volume", "issue", + "data-title", "version", "fpage", "lpage". + - "ext-link" (list): A list of dictionaries, each containing: + - "ext-link-type" (str): Type of external link (e.g., "uri") (required). + - "xlink:href" (str): URL or URI of the external link (required). + - "text" (str): Display text for the link (optional). + - "pub-ids" (list): A list of dictionaries, each containing: + - "pub-id-type" (str): Type of publication ID (e.g., "pmid") (required). + - "text" (str): Value of the publication ID (required). + - "dates-in-citation" (list): A list of dictionaries, each containing: + - "content-type" (str): Type of date, e.g., "updated" (required). + - "text" (str): Date value in text format (required). + node (dict, optional): A dictionary containing additional XML elements to include in + the reference. For example: + - "person-group" (list): A list of XML elements representing authors or editors. + + Returns: + xml.etree.ElementTree.Element: An XML element representing the reference. + + Raises: + ValueError: If required fields are missing, including: + - "ref-id". + - "publication-type". + - "ext-link-type" and "xlink:href" for external links. + - "pub-id-type" for publication IDs. + - "content-type" for dates in citation. + + Example input: + data = { + "ref-id": "B1", + "label": "1", + "mixed-citation": "Aires M, Paz AA, Perosa CT. Situação de saúde...", + "publication-type": "journal", + "article-title": "Situação de saúde e grau de...", + "source": "Rev Gaucha Enferm", + "volume": "30", + "issue": "3", + "fpage": "192", + "lpage": "199", + "ext-link": [ + { + "comment": "Disponível em: ", + "ext-link-type": "uri", + "xlink:href": "http://example.com", + "text": "http://example.com" + } + ], + "pub-ids": [ + { + "pub-id-type": "pmid", + "text": "12345678" + } + ] + } + node = { + "person-group": [ET.Element("person-group", attrib={"person-group-type": "author"})] + } + + Example output: + + + Aires M, Paz AA, Perosa CT. Situação de saúde... + + Situação de saúde e grau de... + Rev Gaucha Enferm + 30 + 3 + 192 + 199 + http://example.com + 12345678 + + + + """ if not (id_text := data.get("ref-id")): raise ValueError("attribute ref-id is required") @@ -63,6 +104,10 @@ def build_ref(data): ref_elem, "element-citation", attrib={"publication-type": publication_type} ) + if node: + for person_group in node.get("person-group") or []: + element_citation_elem.append(person_group) + basic_keys = ( "article-title", "chapter-title", @@ -92,12 +137,18 @@ def build_ref(data): if not ext_link_type or not xlink_href: raise ValueError("ext-link-type and xlink:href are required") - if ext_link_text := ext_link.get("text"): - ET.SubElement( - element_citation_elem, - "ext-link", - attrib={"ext-link-type": ext_link_type, "xlink:href": xlink_href}, - ).text = ext_link_text + ext_link_text = ext_link.get("text") + comment = ext_link.get("comment") + + if ext_link_text: + ext_link_attributes = {"ext-link-type": ext_link_type, "xlink:href": xlink_href} + + if comment: + comment_elem = ET.SubElement(element_citation_elem, "comment") + comment_elem.text = comment + ET.SubElement(comment_elem, "ext-link", attrib=ext_link_attributes).text = ext_link_text + else: + ET.SubElement(element_citation_elem, "ext-link", attrib=ext_link_attributes).text = ext_link_text for pub_id in data.get("pub-ids") or []: pub_id_type = pub_id.get("pub-id-type") diff --git a/tests/sps/formats/sps_xml/test_ref.py b/tests/sps/formats/sps_xml/test_ref.py index c3d95b3e2..698836bec 100644 --- a/tests/sps/formats/sps_xml/test_ref.py +++ b/tests/sps/formats/sps_xml/test_ref.py @@ -172,6 +172,33 @@ def test_build_ref_ext_link_text_None(self): generated_xml_str = ET.tostring(ref_elem, encoding="unicode", method="xml") self.assertEqual(generated_xml_str.strip(), expected_xml_str.strip()) + def test_build_ref_ext_link_in_comment(self): + self.maxDiff = None + data = { + "ref-id": "B1", + "publication-type": "journal", + "ext-link": [ + { + "ext-link-type": "uri", + "xlink:href": "http://socialsciences.scielo.org", + "text": "http://socialsciences.scielo.org", + "comment": "Disponível em: " + } + ] + } + expected_xml_str = ( + '' + '' + '' + 'Disponível em: http://socialsciences.scielo.org' + '' + '' + '' + ) + ref_elem = build_ref(data) + generated_xml_str = ET.tostring(ref_elem, encoding="unicode", method="xml") + self.assertEqual(generated_xml_str.strip(), expected_xml_str.strip()) + class TestBuildRefPubId(unittest.TestCase): def test_build_ref_pub_id(self): @@ -319,3 +346,42 @@ def test_build_ref_date_in_citation_text_None(self): ref_elem = build_ref(data) generated_xml_str = ET.tostring(ref_elem, encoding="unicode", method="xml") self.assertEqual(generated_xml_str.strip(), expected_xml_str.strip()) + + +class TestBuildRefPersonGroup(unittest.TestCase): + def test_build_ref_person_group(self): + data = { + "ref-id": "B1", + "publication-type": "journal", + } + node = { + "person-group": [ + ET.fromstring( + '' + '' + 'Einstein' + 'Albert' + 'Prof.' + 'Neto' + '' + '' + ) + ] + } + expected_xml_str = ( + '' + '' + '' + '' + 'Einstein' + 'Albert' + 'Prof.' + 'Neto' + '' + '' + '' + '' + ) + ref_elem = build_ref(data, node) + generated_xml_str = ET.tostring(ref_elem, encoding="unicode", method="xml") + self.assertEqual(generated_xml_str.strip(), expected_xml_str.strip())