"""Sentences with citation fields (Zotero / Mendeley / EndNote), links or superscript citations inside: rewritten
around them; the fields stay exactly as they were (live, never retyped)."""
import os
import docx
import pytest
from docx.oxml import parse_xml
os.environ.setdefault("SKIP_MODEL_LOAD", "1")
import fast as F # noqa: E402
import smart as S # noqa: E402
W = 'xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"'
def _run(text, extra=""):
return f'{extra}{text}'
def _zotero(result):
return [f'',
f' ADDIN ZOTERO_ITEM CSL_CITATION {{"id":1}} ',
f'', _run(result),
f'']
def _para(doc, xml_runs):
p = doc.add_paragraph()
for x in xml_runs:
p._p.append(parse_xml(x))
return p
class _Block:
"""What fast._jobs gets for one paragraph (one sentence spanning it)."""
kind = "para"
def __init__(self, p):
self.el = p._p
import docx_report as DX
self.raw = DX.para_text(p._p)
self.sents, self.cspans, self.scores = [self.raw.strip()], [(0, len(self.raw.rstrip()))], [0.99]
def _doc_with(xml_runs):
d = docx.Document()
return d, _para(d, xml_runs)
def test_a_zotero_citation_in_the_middle_stays_live_and_the_words_around_it_change():
d, p = _doc_with([_run("As reported by "), *_zotero("(Smith et al., 2020)"),
_run(" the proposed method improves fault detection accuracy considerably.")])
b = _Block(p)
around = {}
jobs, locked = F._jobs([b], 0.5, around=around)
assert locked == 0 and len(jobs) == 1
text = jobs[0][2]
assert text == "As reported by [REF1] the proposed method improves fault detection accuracy considerably."
segs, refs = around[(id(b), 0)]
assert refs == ["(Smith et al., 2020)"]
assert F._replace_around(b, segs, "Smith and colleagues [REF1] show the method lifts fault detection accuracy a lot.")
xml = p._p.xml
assert "ADDIN ZOTERO_ITEM" in xml and xml.count('w:fldCharType="begin"') == 1 # the field is untouched
import docx_report as DX
assert DX.para_text(p._p) == ("Smith and colleagues (Smith et al., 2020) show the method lifts fault detection "
"accuracy a lot.")
def test_versions_that_move_drop_or_repeat_a_citation_are_not_used():
d, p = _doc_with([*_zotero("(Lee, 2019)"), _run(" found that training on augmented data improves recall by 7%.")])
b = _Block(p)
around = {}
jobs, _ = F._jobs([b], 0.5, around=around)
segs = around[(id(b), 0)][0]
assert F._fits(segs, "[REF1] reported that augmented training data raise recall by 7%.") is not None
assert F._fits(segs, "Augmented training data raise recall by 7% [REF1].") is None # words before the field
assert F._fits(segs, "Augmented training data raise recall by 7%.") is None # citation dropped
assert F._fits(segs, "[REF1] and [REF1] reported a 7% gain.") is None # repeated
def test_links_and_superscript_citations_are_kept_too():
link = (f'' + _run("WHO report") + '')
sup = _run("12", '')
d, p = _doc_with([_run("The "), f'{link}', _run(" shows that incidence rose sharply"), sup,
_run(" across all regions during the last decade.")])
b = _Block(p)
around = {}
jobs, locked = F._jobs([b], 0.5, around=around)
assert locked == 0
segs, refs = around[(id(b), 0)]
assert refs == ["WHO report", "12"]
assert F._replace_around(b, segs, "The [REF1] indicates a steep rise in incidence[REF2] in every region over "
"the past ten years.")
xml = p._p.xml
assert "w:hyperlink" in xml and 'w:vertAlign w:val="superscript"' in xml
import docx_report as DX
assert DX.para_text(p._p).startswith("The WHO report indicates a steep rise in incidence12 in every region")
def test_sentences_with_equations_stay_locked():
d, p = _doc_with([_run("The loss is defined as "),
''
'L=x', _run(" and it is minimised with gradient descent in training.")])
b = _Block(p)
around = {}
jobs, locked = F._jobs([b], 0.5, around=around)
assert jobs == [] or all((id(b), 0) not in around for _ in jobs)