Coverage for src/ptf/cmds/xml/citation_html.py: 91%
347 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-05 09:56 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-05 09:56 +0000
1from django.conf import settings
3from ptf.cmds.xml.xml_base import RefBase
4from ptf.cmds.xml.xml_utils import make_links_clickable
5from ptf.model_data import ContributorDict
6from ptf.utils import get_display_name
8# Bug fixed:
9# 1. article_title / chapter_title
10# TODO: 02/05/2020. Restore the line in comment below. There's a bug in production
11# # “ is inside the <span>, but ” is outside
12# 2. authors. if there is no author, there is still a span in HTML
13# 3. institution is ignored in citation_html (except JEP)
14# 4. month is ignored in citation_html (except JEP)
15# 5. series. suffix is set to '</span>' but the opening <span> is missing
16# 6. volume JEP. ", " is inside the <span> of the volume
19REF_JEP_STYLE = getattr(settings, "REF_JEP_STYLE", False)
20REF_ALCO_STYLE = getattr(settings, "REF_ALCO_STYLE", False)
21REF_PCJ_STYLE = getattr(settings, "REF_PCJ_STYLE", False)
24def helper_decorate_text(text, prefix, suffix):
25 if text is None or text == "":
26 return ""
28 text = prefix + text + suffix
29 return text
32def get_html_from(tag, ref_data):
33 text = ""
35 fct_name = "get_html_from_" + tag.replace("-", "_")
36 if fct_name in globals() and callable(globals()[fct_name]):
37 text += globals()[fct_name](ref_data)
38 else:
39 fct_name = "add_prefix_to_html_from_" + tag.replace("-", "_")
40 if fct_name in globals() and callable(globals()[fct_name]): 40 ↛ 43line 40 didn't jump to line 43 because the condition on line 40 was always true
41 text += globals()[fct_name](ref_data)
43 fct_name = "add_span_class_to_html_from_" + tag.replace("-", "_")
44 if fct_name in globals() and callable(globals()[fct_name]):
45 text = globals()[fct_name](text, ref_type=ref_data.type)
47 return text
50def get_html_from_authors(ref_data: RefBase):
51 """
52 authors may have <etal/> that require 2 spans
53 We cannot use the add_prefix_ then add_span_class_ functions
55 :param ref_data:
56 :return:
57 """
58 contribs = ref_data.get_authors()
59 text = get_html_from_contribs(contribs, with_span=True) if contribs else ""
61 return text
64def get_html_from_contribs(contribs: list[ContributorDict], is_editor=False, with_span=False):
65 text = ""
66 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
67 ref_pcj_style = getattr(settings, "REF_PCJ_STYLE", False)
68 i = 1
69 size = len(contribs)
71 if with_span and not is_editor:
72 text = '<span class="citation-author">'
74 for contrib in contribs:
75 first_name = contrib["first_name"]
76 if (ref_jep_style or ref_pcj_style) and first_name:
77 # JEP_STYLE: Only the first name initials are used
78 words = first_name.split() # first_name may have multiple words
79 initials = []
80 for word in words:
81 parts = word.split("-") # a first_name may be composed (ex: "Jean-Pierre")
82 word = "-".join([f"{part[0]}." for part in parts if part])
83 initials.append(word)
84 first_name = " ".join(initials)
86 string_name = get_display_name(
87 contrib["prefix"],
88 first_name,
89 contrib["last_name"],
90 contrib["suffix"],
91 contrib["string_name"],
92 )
94 if i > 1:
95 if i == size and contrib["contrib_xml"] == "<etal/>": 95 ↛ 96line 95 didn't jump to line 96 because the condition on line 95 was never true
96 text += '</span> <span class="citation_etal">'
97 elif i == size and ref_jep_style:
98 text += " & "
99 elif ref_jep_style: 99 ↛ 100line 99 didn't jump to line 100 because the condition on line 99 was never true
100 text += ", "
101 else:
102 text += "; "
104 if contrib["contrib_xml"] == "<etal/>": 104 ↛ 105line 104 didn't jump to line 105 because the condition on line 104 was never true
105 text += "et al."
106 else:
107 text += string_name
108 i += 1
110 if is_editor:
111 if len(contribs) > 1: 111 ↛ 114line 111 didn't jump to line 114 because the condition on line 111 was always true
112 text += ", eds."
113 else:
114 text += ", ed."
115 elif with_span: 115 ↛ 118line 115 didn't jump to line 118 because the condition on line 115 was always true
116 text += "</span>"
118 return text
121def get_html_from_pages(ref_data):
122 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
123 if ref_jep_style and ref_data.type == "book": 123 ↛ 124line 123 didn't jump to line 124 because the condition on line 123 was never true
124 return ""
126 text = helper_decorate_text(ref_data.size, ", ", " pages")
128 if not text and ref_data.fpage:
129 fpage_int = lpage_int = 0
131 try:
132 fpage_int = int(ref_data.fpage)
133 except ValueError:
134 pass
136 try:
137 lpage_int = int(ref_data.lpage)
138 except ValueError:
139 pass
141 if lpage_int > 0 and lpage_int - fpage_int >= 1 and not ref_jep_style:
142 text += ", pp. "
143 else:
144 text += ", p. "
146 text += ref_data.fpage
147 if ref_data.lpage:
148 text += "-" + ref_data.lpage
150 if not text and ref_data.page_range:
151 prefix = ", pp. "
152 suffix = ""
153 if ref_jep_style: 153 ↛ 154line 153 didn't jump to line 154 because the condition on line 153 was never true
154 prefix = ", p. "
155 text += helper_decorate_text(ref_data.page_range, prefix, suffix)
157 return text
160def get_html_from_source(ref_data):
161 with_article_or_chapter_title = ref_data.article_title_tex or ref_data.chapter_title_tex
162 value_html = add_prefix_to_html_from_source(ref_data)
163 text = add_span_class_to_html_from_source(
164 value_html,
165 ref_type=ref_data.type,
166 with_article_or_chapter_title=with_article_or_chapter_title,
167 )
169 return text
172def add_prefix_to_html_from_annotation(ref_data):
173 if ref_data.type in ["phdthesis", "masterthesis", "mastersthesis"]:
174 prefix = ", "
175 suffix = ""
176 else:
177 prefix = " ("
178 suffix = ")"
180 text = helper_decorate_text(ref_data.annotation, prefix, suffix)
181 return text
184def add_prefix_to_html_from_article_title(ref_data):
185 prefix = " "
186 suffix = ""
187 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
189 if ref_jep_style: 189 ↛ 190line 189 didn't jump to line 190 because the condition on line 189 was never true
190 prefix = " - “"
191 suffix = "”"
193 text = helper_decorate_text(ref_data.article_title_tex, prefix, suffix)
194 return text
197def add_prefix_to_html_from_authors(ref_data: RefBase):
198 contribs = ref_data.get_authors()
199 text = get_html_from_contribs(contribs) if contribs else ""
200 return text
203def add_prefix_to_html_from_chapter_title(ref_data):
204 prefix = " "
205 suffix = ""
206 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
208 if ref_jep_style:
209 prefix = " - “"
210 suffix = "”"
212 text = helper_decorate_text(ref_data.chapter_title_tex, prefix, suffix)
213 return text
216def add_prefix_to_html_from_comment(ref_data):
217 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
219 if ref_jep_style:
220 prefix = ", "
221 suffix = ""
222 else:
223 if "(" in ref_data.comment:
224 prefix = " "
225 suffix = ""
226 else:
227 prefix = " ("
228 suffix = ")"
230 text = helper_decorate_text(ref_data.comment, prefix, suffix)
231 return text
234def add_prefix_to_html_from_editors(ref_data):
235 contribs = ref_data.get_editors()
236 text = get_html_from_contribs(contribs, is_editor=True) if contribs else ""
237 text = helper_decorate_text(text, " (", ")")
238 return text
241def add_prefix_to_html_from_eids(ref_data):
242 text = ""
243 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
245 for extid in ref_data.extids:
246 if extid[0] == "eid":
247 if ref_jep_style: 247 ↛ 248line 247 didn't jump to line 248 because the condition on line 247 was never true
248 text += ", article ID " + extid[1]
249 elif REF_ALCO_STYLE: 249 ↛ 250line 249 didn't jump to line 250 because the condition on line 249 was never true
250 text += ", Paper no. " + extid[1]
251 else:
252 text += ", " + extid[1]
253 return text
256def add_prefix_to_html_from_ext_links(ref_data):
257 text = ""
258 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
260 for link in ref_data.ext_links:
261 href = link["location"]
263 # bibitem with ext-links pointing to numdam.org have a numdam-id
264 # ext-links to doi.org are transformed in an extid
265 # We can ignore both cases
266 if "www.numdam.org" not in href and "doi.org" not in href and not ref_jep_style:
267 href = make_links_clickable(href, link["metadata"])
268 text += " " + href
269 return text
272def add_prefix_to_html_from_institution(ref_data):
273 text = helper_decorate_text(ref_data.institution, ", ", "")
274 return text
277def add_prefix_to_html_from_label(ref_data):
278 text = helper_decorate_text(ref_data.label, "", " ")
279 return text
282def add_prefix_to_html_from_month(ref_data):
283 text = helper_decorate_text(ref_data.month, ", ", "")
284 return text
287def add_prefix_to_html_from_number(ref_data):
288 text = helper_decorate_text(ref_data.issue, " no. ", "")
289 return text
292def add_prefix_to_html_from_publisher(ref_data):
293 text = helper_decorate_text(ref_data.publisher_name, ", ", "")
294 text += helper_decorate_text(ref_data.publisher_loc, ", ", "")
295 return text
298def add_prefix_to_html_from_series(ref_data):
299 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
301 if ref_data.chapter_title_tex or ref_data.article_title_tex:
302 if ref_jep_style and ref_data.type == "incollection":
303 prefix = ", "
304 suffix = ""
305 else:
306 prefix = " ("
307 suffix = ")"
308 else:
309 prefix = ", "
310 suffix = ""
312 text = helper_decorate_text(ref_data.series, prefix, suffix)
313 return text
316def add_prefix_to_html_from_source(ref_data):
317 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
318 ref_pcj_style = getattr(settings, "REF_PCJ_STYLE", False)
319 if ref_data.article_title_tex or ref_data.chapter_title_tex:
320 if ref_jep_style and ref_data.type == "incollection":
321 prefix = ", in "
322 elif ref_pcj_style and ref_data.type == "inbook": 322 ↛ 323line 322 didn't jump to line 323 because the condition on line 322 was never true
323 prefix = " In: "
324 else:
325 prefix = ", "
326 suffix = ""
327 else:
328 prefix = " "
329 suffix = ""
331 if ref_jep_style: 331 ↛ 332line 331 didn't jump to line 332 because the condition on line 331 was never true
332 prefix = " - "
333 if ref_data.type in ["unpublished", "misc"]:
334 prefix += "“"
335 suffix = "”"
337 text = helper_decorate_text(ref_data.source_tex, prefix, suffix)
338 return text
341def add_prefix_to_html_from_volume(ref_data):
342 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
344 if ref_jep_style:
345 if ref_data.type in ["incollection", "book"]: 345 ↛ 348line 345 didn't jump to line 348 because the condition on line 345 was always true
346 prefix = ", vol. "
347 else:
348 prefix = " "
349 else:
350 if ref_data.article_title_tex or ref_data.chapter_title_tex:
351 prefix = ", Volume "
352 else:
353 prefix = ", "
355 text = helper_decorate_text(ref_data.volume, prefix, "")
356 return text
359def add_prefix_to_html_from_year(ref_data):
360 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
362 if ref_jep_style and ref_data.type in ["phdthesis", "masterthesis", "mastersthesis"]: 362 ↛ 363line 362 didn't jump to line 363 because the condition on line 362 was never true
363 prefix = ", " if ref_data.month == "" else " "
364 suffix = ""
365 elif ref_data.type in ["incollection", "book", "misc"]:
366 prefix = ", "
367 suffix = ""
368 else:
369 prefix = " ("
370 suffix = ")"
372 text = helper_decorate_text(ref_data.year, prefix, suffix)
373 return text
376def add_span_class_to_html_from_article_title(value_html, **kwargs):
377 text = helper_decorate_text(value_html, '<span class="citation-document-title">', "</span>")
378 return text
381def add_span_class_to_html_from_authors(value_html, **kwargs):
382 text = helper_decorate_text(value_html, '<span class="citation-author">', "</span>")
383 return text
386def add_span_class_to_html_from_chapter_title(value_html, **kwargs):
387 text = helper_decorate_text(value_html, '<span class="citation-document-title">', "</span>")
388 return text
391def add_span_class_to_html_from_series(value_html, **kwargs):
392 # TODO: Check JEP for series (not span except for books: citation-publication-title-book (not found in CSS)
393 text = helper_decorate_text(value_html, '<span class="citation-series">', "</span>")
394 return text
397def add_span_class_to_html_from_source(value_html, **kwargs):
398 suffix = "</span>"
400 if "with_article_or_chapter_title" not in kwargs or kwargs["with_article_or_chapter_title"]:
401 prefix = '<span class="citation-publication-title">'
402 else:
403 prefix = '<span class="citation-document-title">'
405 text = helper_decorate_text(value_html, prefix, suffix)
406 return text
409def add_span_class_to_html_from_volume(value_html, **kwargs):
410 ref_jep_style = getattr(settings, "REF_JEP_STYLE", False)
412 if ref_jep_style and "ref_type" in kwargs and kwargs["ref_type"] in ["incollection", "book"]:
413 text = helper_decorate_text(
414 value_html, '<span class="citation-volume-incollection">', "</span>"
415 )
416 else:
417 text = helper_decorate_text(value_html, '<span class="citation-volume">', "</span>")
418 return text
421def get_citation_for_article(ref_data):
422 text = get_html_from("authors", ref_data)
423 text += get_html_from("article_title", ref_data)
424 text += get_html_from("source", ref_data)
425 text += get_html_from("series", ref_data)
426 text += get_html_from("volume", ref_data)
427 text += get_html_from("year", ref_data)
428 text += get_html_from("number", ref_data)
429 text += get_html_from("eids", ref_data)
430 text += get_html_from("pages", ref_data)
431 text += get_html_from("ext_links", ref_data)
432 return text
435def get_citation_for_book(ref_data):
436 text = get_html_from("authors", ref_data)
437 text += get_html_from("source", ref_data)
438 text += get_html_from("editors", ref_data)
439 text += get_html_from("series", ref_data)
440 text += get_html_from("volume", ref_data)
441 text += get_html_from("publisher", ref_data)
442 text += get_html_from("institution", ref_data)
443 text += get_html_from("year", ref_data)
444 text += get_html_from("number", ref_data)
445 text += get_html_from("eids", ref_data)
446 text += get_html_from("pages", ref_data)
447 text += get_html_from("ext_links", ref_data)
448 return text
451def get_citation_for_incollection(ref_data):
452 text = get_html_from("authors", ref_data)
454 # <title> becomes a <chapter-title> in JATS for inbook,
455 # but becomes a <source> for incollection.
456 # We can call get_html_from_chapter_title then get_html_from_source because 1 of them will be empty in both cases
457 text += get_html_from("chapter_title", ref_data)
458 text += get_html_from("source", ref_data)
460 # TODO: BUG in JATS; editors are not displayed for inbook
461 if ref_data.type != "inbook": 461 ↛ 464line 461 didn't jump to line 464 because the condition on line 461 was always true
462 text += get_html_from("editors", ref_data)
464 text += get_html_from("series", ref_data)
465 text += get_html_from("volume", ref_data)
466 text += get_html_from("publisher", ref_data)
467 text += get_html_from("institution", ref_data)
468 text += get_html_from("year", ref_data)
469 text += get_html_from("number", ref_data)
470 text += get_html_from("eids", ref_data)
471 text += get_html_from("pages", ref_data)
472 text += get_html_from("ext_links", ref_data)
473 return text
476def get_citation_for_misc(ref_data):
477 text = get_html_from("authors", ref_data)
479 # TODO: BUG in JATS ? article_title is used for misc but source for unpublished ?
480 text += get_html_from("article_title", ref_data)
481 text += get_html_from("source", ref_data)
482 text += get_html_from("series", ref_data)
483 text += get_html_from("volume", ref_data)
484 text += get_html_from("year", ref_data)
485 text += get_html_from("number", ref_data)
486 text += get_html_from("eids", ref_data)
487 text += get_html_from("pages", ref_data)
488 text += get_html_from("ext_links", ref_data)
489 return text
492def get_citation_for_thesis(ref_data):
493 text = get_html_from("authors", ref_data)
494 text += get_html_from("source", ref_data)
495 text += get_html_from("series", ref_data)
496 text += get_html_from("volume", ref_data)
498 text += get_html_from("annotation", ref_data)
499 text += get_html_from("institution", ref_data)
500 text += get_html_from("publisher", ref_data)
501 text += get_html_from("month", ref_data)
502 text += get_html_from("year", ref_data)
503 text += get_html_from("number", ref_data)
505 text += get_html_from("eids", ref_data)
506 text += get_html_from("pages", ref_data)
507 text += get_html_from("ext_links", ref_data)
509 return text
512def get_citation_html(ref_data):
513 text = get_html_from("label", ref_data)
515 # article - book - incollection inbook - thesis phdthesis masterthesis - misc unpublished
516 # manual techreport coursenotes proceedings ?
517 type_ = ref_data.type
519 if type_ in ("inbook", "inproceedings"):
520 type_ = "incollection"
521 elif "thesis" in type_:
522 type_ = "thesis"
523 elif type_ not in ("article", "book", "incollection"):
524 type_ = "misc"
526 fct_name = "get_citation_for_" + type_.replace("-", "_")
527 if fct_name in globals() and callable(globals()[fct_name]): 527 ↛ 530line 527 didn't jump to line 530 because the condition on line 527 was always true
528 text += globals()[fct_name](ref_data)
530 text += get_html_from("comment", ref_data)
532 if ref_data.type not in ["phdthesis", "masterthesis", "mastersthesis"]:
533 text += get_html_from("annotation", ref_data)
535 return text