diff --git a/scripts/profile_sync.py b/scripts/profile_sync.py index 7dcee12b..17ea9426 100644 --- a/scripts/profile_sync.py +++ b/scripts/profile_sync.py @@ -305,6 +305,7 @@ PROSE_CITE_RE = re.compile( r":(?P\d+(?:-\d+)?)" ) PROSE_LIST_ITEM_RE = re.compile(r"\d+[.)](?:\s|$)") +PROSE_WRAPPED_RANGE_RE = re.compile(r":\d+(?:-\d+)?(?:[,)\s]|$)") PROSE_CONT_RE = re.compile(r",(?P\d+(?:-\d+)?)(?![\w-])(?!\.\d)") # A spaced continuation is accepted only for a range: `x.c:55-71, 80-147` # follows the source_ref convention, while `x.c:100, 200 files` is prose. @@ -464,6 +465,11 @@ def _prose_runs( line = own.rstrip() boundary = len(line) following = lines[number + 1].lstrip() if number + 1 < len(lines) else "" + if PROSE_WRAPPED_RANGE_RE.match(following) and line[-1:].isalnum(): + # The break can fall before the colon too: jgenesis wraps + # `.../src/config.rs` then `:76-78,95-99` on the next line. + line += following + following = "" # A numbered list after a colon (abuse: `setup.cpp:` then `1. -datadir`) # is not a range. if not following[:1].isdigit() or PROSE_LIST_ITEM_RE.match(following): diff --git a/tests/test_profile_sync.py b/tests/test_profile_sync.py index f8c415e2..9701e9e2 100644 --- a/tests/test_profile_sync.py +++ b/tests/test_profile_sync.py @@ -3546,6 +3546,20 @@ class TestWrappedProse(unittest.TestCase): {"libretro.cpp:2372-2373, 2429-2433": True, "c.c:5-6, 40-41": True}, ) + def test_a_break_before_the_colon_is_read_whole(self): + # jgenesis wrote `(frontend/.../config.rs` then `:76-78,95-99)` on the + # next line, and the citation was never collected. + text = PROSE_SAMPLE.replace( + "files:", + "cfg: |\n Read from the config (src/config.rs\n :76-78,95-99) at start.\nfiles:", + ) + runs = { + c.ref: c.wrapped + for c in profile_sync.collect_citations(yaml.safe_load(text)) + if c.field == "cfg" + } + self.assertEqual(runs, {"src/config.rs:76-78,95-99": True}) + def test_a_wrapped_run_that_moves_holds_the_pin(self): parts = [ PartResult(RefPart("libretro.cpp", 2372, 2373, "2372-2373"),