diff --git a/Script.org b/Script.org index 051fa58..6ea2470 100644 --- a/Script.org +++ b/Script.org @@ -245,7 +245,12 @@ OU Le mode =--refaire= exige un fichier =refaire.json= et écrit dans =BRnot=. - Les documents sont limités à 32 000 pixels de haut, comme pour =BGnot=. + Les documents sont limités à 32 000 pixels de haut par défaut, comme + pour =BGnot=. Pour modifier cette limite commune, définir + =ANNOTATION_MAX_HEIGHT_PX = 32000= dans =config.py= avec la hauteur + souhaitée (entier strictement positif, en pixels). + Le réglage s'applique aux prochaines générations ; utiliser + =--overwrite= pour régénérer les documents déjà présents. Les grandes copies sont découpées entre les labels en =Part1=, =Part2=, etc., dans leur dossier =CopieXX=. L'export les nomme =CopieXX Part1.pdf=, etc. Importer toutes les parties avant de lancer =read-annotations= : @@ -258,7 +263,8 @@ OU réponses par question. Enregistrées dans =BGnot= - Les groupes visent une hauteur maximale de 32 000 pixels. Si le bloc + Les groupes visent la hauteur maximale =ANNOTATION_MAX_HEIGHT_PX= + (32 000 pixels par défaut). Si le bloc d'un seul élève dépasse cette limite, il reste entier dans un groupe dédié, même lorsqu'il ne contient qu'une seule réponse. diff --git a/copienator/annotation_documents.py b/copienator/annotation_documents.py index d3ae489..13faa27 100644 --- a/copienator/annotation_documents.py +++ b/copienator/annotation_documents.py @@ -1,9 +1,12 @@ """Locate tablet documents, including the parts of a large checked copy.""" from pathlib import Path +from copienator.configuration import ANNOTATION_MAX_HEIGHT_PX from copienator.json_io import read_json -MAX_HEIGHT_PX = 32000 +if type(ANNOTATION_MAX_HEIGHT_PX) is not int or ANNOTATION_MAX_HEIGHT_PX <= 0: + raise ValueError("ANNOTATION_MAX_HEIGHT_PX must be a positive integer (pixels)") +MAX_HEIGHT_PX = ANNOTATION_MAX_HEIGHT_PX def copy_documents(directory: Path) -> list[Path]: diff --git a/copienator/configuration.py b/copienator/configuration.py index 5e36388..8b3dede 100644 --- a/copienator/configuration.py +++ b/copienator/configuration.py @@ -39,6 +39,7 @@ THINKING_LEVEL_PRO = "high" ALWAYS_CROP = False ANNOTATION_MARGIN_LEFT = 300 ANNOTATION_LOW_MARGIN_LEFT = 400 +ANNOTATION_MAX_HEIGHT_PX = 32000 SHOW_PERSONAL_STEPS = False RETURN_JPEG_ENABLED = True RETURN_PDF_ENABLED = True diff --git a/default_config.py b/default_config.py index a1f2834..8812f7a 100644 --- a/default_config.py +++ b/default_config.py @@ -10,6 +10,10 @@ IMPORT_DIR = Path("Import") ANNOTATION_MARGIN_LEFT = 300 ANNOTATION_LOW_MARGIN_LEFT = 400 +# Hauteur maximale des documents Bnot et des groupes BGnot, en pixels. +# BGnot conserve entier un bloc d'élève qui dépasse cette limite. +ANNOTATION_MAX_HEIGHT_PX = 32000 + # Fichiers à inclure dans A Rendre (les sources d'annotations sont conservées). RETURN_JPEG_ENABLED = True RETURN_PDF_ENABLED = True @@ -95,7 +99,6 @@ LATEX_BEFORE = r"""\documentclass[varwidth=24.8cm,margin=0.4cm]{standalone} \usepackage[T1]{fontenc} \usepackage{lmodern} \usepackage{amsmath, amssymb} -\usepackage{commands} \usepackage{minted} \usepackage{graphicx} \usepackage{enumitem} @@ -122,7 +125,6 @@ LATEX_ANOT_BEFORE = Template( \usepackage{lmodern} % Enables arbitrary font scaling \usepackage{amsmath, amssymb} \usepackage{mathabx} % larger inline operators. -\usepackage{commands} %\usepackage{anyfontsize} % replaced by lmodern \begin{document} \fontsize{${fontsize}}{${line_spacing}}\selectfont diff --git a/tests/test_annotation_height_config.py b/tests/test_annotation_height_config.py new file mode 100644 index 0000000..052ac97 --- /dev/null +++ b/tests/test_annotation_height_config.py @@ -0,0 +1,40 @@ +"""The personal configuration controls both annotation generators.""" +import os +from pathlib import Path +import subprocess +import sys +import tempfile +import unittest + + +class AnnotationHeightConfigTests(unittest.TestCase): + def load_generators(self, setting): + with tempfile.TemporaryDirectory() as directory: + config = Path(directory) / "config.py" + config.write_text("from default_config import *\n" + setting, encoding="utf-8") + return subprocess.run( + [sys.executable, "-c", + "from copienator.commands import annotating_by_label as grouped; " + "from copienator.commands import annotating_with_checks as checks; " + "print(grouped.MAX_HEIGHT_PX, checks.MAX_HEIGHT_PX)"], + cwd=Path(__file__).resolve().parents[1], + env={**os.environ, "COPIENATOR_CONFIG": str(config)}, + capture_output=True, text=True, check=False, + ) + + def test_custom_height_reaches_both_generators(self): + result = self.load_generators("ANNOTATION_MAX_HEIGHT_PX = 16000\n") + self.assertEqual(result.returncode, 0, result.stderr) + self.assertEqual(result.stdout.strip(), "16000 16000") + + def test_older_configuration_keeps_current_default(self): + result = self.load_generators("del ANNOTATION_MAX_HEIGHT_PX\n") + self.assertEqual(result.returncode, 0, result.stderr) + self.assertEqual(result.stdout.strip(), "32000 32000") + + def test_invalid_heights_are_rejected(self): + for value in ("0", "-1", "1.5", "True", "'32000'"): + with self.subTest(value=value): + result = self.load_generators(f"ANNOTATION_MAX_HEIGHT_PX = {value}\n") + self.assertNotEqual(result.returncode, 0) + self.assertIn("ANNOTATION_MAX_HEIGHT_PX must be a positive integer", result.stderr)