From a49b2c2726f16532f0d00f5c4e95b498aac04e5e Mon Sep 17 00:00:00 2001 From: Bill Hlavacek Date: Sun, 10 May 2026 15:48:07 -0600 Subject: [PATCH] Don't collapse `\` line continuations inside commented BNGL lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `BNGFile.strip_actions` folds trailing-backslash line continuations before the action parser sees them, but the previous regex didn't respect comments: a commented-out # foo()=if(t<42,0,\ immediately above a live foo()=if(t<42,9.899,\ glued both into the comment, and the live definition silently disappeared from the rendered `.bngl` (and from any `.net` BNG2.pl generated downstream). Fix: anchor the regex to start-of-line and require no `#` between that and the trailing `\` — comment lines keep their continuation markers as part of the comment body, which is what BNG2.pl itself does. --- bionetgen/modelapi/bngfile.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/bionetgen/modelapi/bngfile.py b/bionetgen/modelapi/bngfile.py index a601a374..e916e0c4 100644 --- a/bionetgen/modelapi/bngfile.py +++ b/bionetgen/modelapi/bngfile.py @@ -150,10 +150,20 @@ def strip_actions(self, model_path, folder) -> str: with open(model_path, "r", encoding="UTF-8") as mf: # read and strip actions mstr = mf.read() - # TODO: Clean this up _a lot_ - # this removes any new line escapes (\ \n) to continue - # to another line, so we can just remove the action lines - mstr = re.sub(r"\\\n", "", mstr) + # Collapse `\` line continuations before stripping + # action lines, so the action parser sees the same logical + # command boundaries as BNG. + # + # Only collapse `\` that appears before any `#` on its line. + # A continuation marker after the comment introducer is part + # of the comment body in BNG2.pl — collapsing it would glue + # the next physical line (often a real definition) into the + # comment, dropping it from the model. Repro: a commented-out + # `# foo()=if(t<42,0,\` immediately above a live + # `foo()=if(t<42,9.899,\` definition would silently lose the + # live function from the regenerated `.bngl` (and from any + # `.net` BNG2.pl generated downstream). + mstr = re.sub(r"^([^#\n]*)\\\n", r"\1", mstr, flags=re.MULTILINE) mlines = mstr.split("\n") stripped_lines = list(filter(lambda x: self._not_action(x), mlines)) # remove spaces, actions don't allow them