# Final output: `A Rendre` This documents the current implementation, as of 2026-09-12. The return folder referred to as « À rendre » is named **`A Rendre`** on disk. JPEG files use the extension **`.jpg`**, not `.jpeg`. ## Left space for Gemini comments `config.py` (or the file selected by `COPIENATOR_CONFIG`) can override: ```python ANNOTATION_MARGIN_LEFT = 300 ANNOTATION_LOW_MARGIN_LEFT = 400 ``` These are added pixels at the 200 dpi annotation rendering scale. An answer uses the larger margin if any of its source fragments has a measured left margin below 20 mm (half the standard 40 mm). Unknown or insufficiently written pages retain the normal spacing. The 600 px comment width is unchanged, so comments can still overlap handwriting on pages with very little whitespace. Automatic `crop-labels` saves per-page measurements in the Cutleft schema. `split-answers` records source pages, crop rectangles and remaining margins in `*.layout.json` files beside answer PDFs. Those files follow copies, manual merges and vertical cuts. PDF fingerprints prevent using stale measurements after files are replaced. Legacy schemas and manual/full-page Cutleft runs without measurements keep the normal spacing. For an existing evaluation, rerun automatic `crop-labels`, `split-answers`, and annotation generation with overwrite to populate and use this metadata. Do this before handwritten review: existing Bnot/BGnot/BRnot annotation batches save their rendering geometry and reuse it when read back, even after settings change. Older batches without saved geometry keep their original 300 px offset. Do not overwrite a batch that still contains handwritten corrections to import. All fragments of one answer share one left offset. BGnot pads narrower answer images with white without resizing handwriting; fitting the wider document to screen or paper may reduce the displayed scale, and return-PDF page breaks can change. The extra space is also used by Anot and Bnot. ## Files and their sources After grouped correction and review: ```sh python -m copienator read-grouped Interro python -m copienator giving-names Interro BGnot ``` The expected layout for a copy is: ```text Interro/A Rendre/ └── Student Name (01)/ ├── Student Name.jpg ├── Student Name.pdf ├── score.json ├── info.json └── answers/ # when individual answer export is enabled ├── 001 - Ex 1.jpg └── 002 - Ex 2.jpg ``` The name comes from `Copies/Copie01.json` (`name`), with filename sanitization. The copy ID distinguishes folders even when several copies have the same name. `giving-names` links the full JPEG, PDF and score file (or copies them when links are unavailable). It writes `info.json` and optionally composes the individual answer JPEGs. | Return file | Source under `BGnot/Copie01/` | Contents | | --- | --- | --- | | `Student Name.jpg` | `Concat.jpg` | Full continuous image of the compiled answers and corrections. | | `Student Name.pdf` | `Concat_F.pdf` | Filtered, paginated correction with context, questions and solutions. | | `score.json` | `score.json` | Per-question scores, including questions omitted from the filtered PDF. | | `info.json` | `info.json` | Answer presence, empty-answer classification, PDF membership and score. | | `answers/*.jpg` | Final per-label JPEGs selected by `info.json` | One annotated answer, including empty scans, with optional supplementary material. | ## Enabling or disabling outputs Set these independent options in `config.py` (the defaults also apply when absent from an older personal configuration): ```python RETURN_JPEG_ENABLED = True RETURN_PDF_ENABLED = True RETURN_ANSWERS_ENABLED = False RETURN_ANSWERS_CONTEXT = False RETURN_ANSWERS_QUESTION = True RETURN_ANSWERS_SOLUTION = False ``` The personal `config.py` enables `RETURN_ANSWERS_ENABLED`; the distributed default is `False`. Set a full-output option to `False`, then rerun `giving-names` to omit that file from `A Rendre`. For each prepared copy, any existing named return file of a disabled type is removed, including a symlink or fallback copy. Its annotation source remains intact. These options control return publication, not intermediate rendering or scoring. `score.json` and `info.json` are always included and have no disabling options. Cleanup allows the JPEG to be absent when disabled, still requires `score.json`, and preserves return PDFs when present. ## Individual answer JPEGs With `RETURN_ANSWERS_ENABLED = True`, `giving-names` generates an `answers/` subdirectory inside each student's return folder. It includes **every present compiled answer**, even a perfect answer omitted from the filtered PDF. Scans marked `empty-answer` are included; labels without an answer are excluded. Every JPEG contains the final annotated student answer, including retained feedback and extracted handwriting. The three supplementary options independently prepend, in this order: 1. Applicable context PDFs, if `RETURN_ANSWERS_CONTEXT` is enabled. 2. The question, if `RETURN_ANSWERS_QUESTION` is enabled (the default). 3. The model solution, if `RETURN_ANSWERS_SOLUTION` is enabled. 4. The annotated student answer, always. These use the same `Text2`/`Sol2` sources as the filtered PDF. Missing supplements are skipped; an unreadable existing file fails the export. They are concatenated vertically on white, without PDF pagination or its black/blue borders. The options affect only these individual images, not the full JPEG or filtered PDF. Disabling all supplements produces just the annotated answer. Filenames use natural label order, a three-digit minimum sequence number, and a sanitized label (`001 - Ex 1.jpg`). Numbering prevents filename collisions when labels differ only by characters forbidden in filenames. JSON keys retain exact labels. The managed `answers/` directory is replaced on successful generation, so removed answers do not leave stale images; failures preserve the previous directory. Disabling the option clears this directory on the next `giving-names` run. Separate storage keeps these images out of the personal final-mark stamping step, which reads only JPEGs directly inside the student's folder. Recompile annotations once before exporting old evaluations with this option: the compiler now saves every final answer block and writes `info.json` next to them. For the grouped workflow, run `read-grouped`, then `giving-names`. This avoids reconstructing a reviewed answer from outdated correction data. ## `info.json`: per-question information Every label in `score.json` has an object containing exactly four fields: ```json { "Ex 1": {"present": true, "not_empty": true, "touched": false, "score": "4"}, "Ex 2": {"present": true, "not_empty": true, "touched": true, "score": "2"}, "Empty": {"present": true, "not_empty": false, "touched": false, "score": "0"}, "Absent": {"present": false, "not_empty": false, "touched": false, "score": ""} } ``` - `present`: an answer entry exists for this student and label in the compilation data. A supplied answer judged empty still has `present: true`. A body removed by manual annotation edits has `present: false`. - `not_empty`: the answer was not marked `empty-answer` and was successfully compiled. Absent answers have `not_empty: false`. When individual export is enabled, every `present` answer gets a JPEG, including those with `not_empty: false`. Image retention alone does not change the empty classification. These fields describe the answer regardless of export settings. - `touched`: the answer appears in the compiled filtered `Concat_F.pdf`, using the actual selection including handwriting and selective redo preservation. It is not a flag for human edits. Empty and absent answers have `false`. - `score`: the same value as `score.json` (normally a numeric string, or `""` for an unpopulated score). Editing scores requires recompilation to update the images; return publication uses current `score.json` values for this field. `info.json` is always exported, even when individual JPEGs or the named PDF are disabled. `touched` tracks BGnot filtered-PDF membership. In `Anot` and `Bnot` flows, all `touched` values remain false. Bnot also produces a filtered, paginated PDF with context, questions and solutions, alongside its filtered JPEG. This file replaces `touched.json` and the internal `answer_labels.json` manifest. Recompile old annotations, then run `giving-names`; successful regeneration and publication remove the obsolete files from their respective folders. Missing or malformed metadata requires recompilation rather than guessing answer presence from scores. Cleanup preserves `info.json` alongside `score.json`. ## JPEG: the full compiled correction The JPEG stacks the rendered answer blocks vertically in natural label order (for example, Ex 2 precedes Ex 10). Each block contains the scanned answer, its label and score, retained global and local feedback, and detected handwritten review annotations. Local feedback can include red rectangles and comments in the left margin. Review checkboxes are applied as actions rather than reproduced as controls; internal error labels are hidden during recompilation. The result is one RGB image of variable height, with no page breaks. It contains all successfully compiled answer blocks, including answers scored 4 with no remaining feedback. “Full” refers to those answer blocks, not the original scan pages or every question in the statement. Missing/unrenderable answers cannot be included. Empty-answer scans are retained individually but excluded from the combined and filtered documents. The grouped compiler refuses to publish a new set when compilation is incomplete. The JPEG does not prepend the question, context or model solution PDFs. ## PDF: a different selection and layout **The PDF is not a PDF conversion of the JPEG.** During an ordinary full grouped recompilation, an answer is omitted only when all three conditions hold: - Its score is at least 4. - Every feedback item is marked `to_delete` (also true for an empty feedback list). - There are no significant detected handwritten annotations for that answer. Thus, a 4/4 answer with retained feedback or handwriting still appears. Scores for omitted answers remain in `score.json`, and their answer blocks remain in the JPEG. Handwriting significance currently means more than 20 pixels with alpha greater than 50 in the extracted annotation layer. For each retained answer, the PDF stacks the following available material: 1. Applicable context PDFs from `Text2/CTXT first_label -> last_label.pdf`. 2. The question from `Text2/