| @@ -160,6 +160,9 @@ def guess_type(text: str) -> str: |
| 160 | | 160 | |
| 161 | def cue_plan(text: str) -> tuple[str, str]: | 161 | def cue_plan(text: str) -> tuple[str, str]: |
| 162 | """(type, description) d'une indication « Type — description » ; sans type reconnu, on le devine.""" | 162 | """(type, description) d'une indication « Type — description » ; sans type reconnu, on le devine.""" |
| | 163 | + alone = next((t for t in PLAN_TYPES if t.lower() == text.strip().lower()), None) |
| | 164 | + if alone: |
| | 165 | + return alone, "" |
| 163 | parts = _CUE_SPLIT.split(text, maxsplit=1) | 166 | parts = _CUE_SPLIT.split(text, maxsplit=1) |
| 164 | if len(parts) == 2: | 167 | if len(parts) == 2: |
| 165 | known = next((t for t in PLAN_TYPES if t.lower() == parts[0].strip().lower()), None) | 168 | known = next((t for t in PLAN_TYPES if t.lower() == parts[0].strip().lower()), None) |
| @@ -168,6 +171,21 @@ def cue_plan(text: str) -> tuple[str, str]: |
| 168 | return guess_type(text), text.strip() | 171 | return guess_type(text), text.strip() |
| 169 | | 172 | |
| 170 | | 173 | |
| | 174 | +def _split_cues(md: str) -> tuple[list[str], str]: |
| | 175 | + """Les indications [VISUEL : …] d'un bloc (le bloc entier, ou des lignes collées au texte) et le texte restant.""" |
| | 176 | + m = _CUE.match(md.strip()) |
| | 177 | + if m: |
| | 178 | + return [m.group(1)], "" |
| | 179 | + cues, lines = [], [] |
| | 180 | + for line in md.split("\n"): |
| | 181 | + m = _CUE.match(line.strip()) |
| | 182 | + if m: |
| | 183 | + cues.append(m.group(1)) |
| | 184 | + else: |
| | 185 | + lines.append(line) |
| | 186 | + return cues, "\n".join(lines).strip("\n") |
| | 187 | + |
| | 188 | + |
| 171 | def _extract_cues(data: dict) -> bool: | 189 | def _extract_cues(data: dict) -> bool: |
| 172 | """Les lignes [VISUEL : …] deviennent des plans du paragraphe qui suit (à défaut, qui précède).""" | 190 | """Les lignes [VISUEL : …] deviennent des plans du paragraphe qui suit (à défaut, qui précède).""" |
| 173 | blocks, pending, found = [], [], False | 191 | blocks, pending, found = [], [], False |
| @@ -179,11 +197,13 @@ def _extract_cues(data: dict) -> bool: |
| 179 | pending.clear() | 197 | pending.clear() |
| 180 | | 198 | |
| 181 | for b in data["blocks"]: | 199 | for b in data["blocks"]: |
| 182 | - m = _CUE.match(b["md"].strip()) | 200 | + cues, md = _split_cues(b["md"]) |
| 183 | - if m: | 201 | + if cues: |
| 184 | - pending.append(" ".join(m.group(1).split())) | 202 | + pending += [" ".join(c.split()) for c in cues] |
| 185 | found = True | 203 | found = True |
| 186 | - continue | 204 | + if not md.strip(): |
| | 205 | + continue |
| | 206 | + b = {**b, "md": md} |
| 187 | if pending and not b["md"].lstrip().startswith("#"): | 207 | if pending and not b["md"].lstrip().startswith("#"): |
| 188 | attach(b["id"]) | 208 | attach(b["id"]) |
| 189 | blocks.append(b) | 209 | blocks.append(b) |