2.2.1 - 2026/09/03 - the commercial license is rewritten and now costs nothing: commercial use is granted to everyone, free of charge, with no contract and nothing to buy, in exchange for taking the software as is -- what replaces the fee is a request, anchored in the preamble and in section 6 and twice marked as no condition of the grant, to support the project voluntarily (suggestion: 10-20 EUR per month and user) through GitHub Sponsors or Ko-fi; the grant is perpetual and irrevocable per version, gains an express patent license, and keeps one restriction -- the software may not be sold as such, while its use inside paid products is expressly allowed; the German text is the authoritative one (disputes go to Aachen, where the court's language is German) and the English is a translation; noncommercial use is unchanged under PolyForm Noncommercial 1.0.0
2.2.0 - 2026/09/02 - convert_video no longer converts an MP4 into an MP4: the format is already the one being produced, so an .mp4 input now yields only the poster frame and the metadata, which is what it is accepted for; before, an MP4 beside its own output was saved by the exists-check but one written to a --output directory was re-encoded for nothing, and --force in place handed ffmpeg the same path to read and to write (both scripts, .py and .sh; the decision is now covered by tests that record the ffmpeg calls instead of running them)
2.2.0 - docs/tools.md read through against the code: convert_video.sh was undocumented though it ships and does the same as the .py, the -o/--output and -f/--force options of both were missing, mp4 was absent from the list of accepted inputs, ffprobe was not named as a requirement beside ffmpeg, and the three files each run produces were not described; the page now says it covers the six scripts the distribution ships and nothing else
2.2.0 - the unused ImageElement is gone from the shared element layer: it was never subclassed and never instantiated -- PowerPoint explicitly declined it and Word uses StructuredElement -- and its one method printed 'to be implemented'; Scriptum.element no longer exports the name
2.2.0 - a marker can donate its indentation to what is added there: `<marker:content takeindent/>` shifts every paragraph and table of the added block by the marker's indent less the block's own first line, so a blueprint from `<section:template>` -- which carries the indent of nowhere in particular -- no longer lands at the left margin between paragraphs sitting well inside a subsection; the shift is relative, so a block that indents internally keeps its shape and a table moves with its caption, and the marker's indent is read as Word shows it, whether written on the paragraph or inherited from its style; the flag sits on the marker because one blueprint is added at many markers of many depths; nothing but the indentation is taken, and Word only
2.2.0 - a value written at a text block that has NO placeholders is reported at INFO instead of WARNING: with no placeholder to name, writing at the block is the only way to add it at a marker -- an entry needs a value and neither `- text:foo:` nor `- text:foo: {}` is accepted -- so the words going nowhere is expected rather than a mistake; a block that does have placeholders still warns and names them, that being nearly always a slip; the limitation itself is now stated in docs/rdf.md, and the text case carries `text:prefilled` as the example end to end
2.2.0 - every message the package and the shipped scripts print now names its level in upper case: `Warning:` in the pptx template loader and `Error:`/`Warning:` across scripts/check_docx.py, scripts/check_pptx.py and scripts/convert_video.py were the last mixed-case ones, against WARNING:/ERROR:/INFO: everywhere else
2.2.0 - a stored reference no longer dates itself by its month: the comparison collapsed digits and weekday names but not month names, so three deck references captured in August broke on the morning of 1 September with '#. Aug #' against '#. Sep #'; a date format that spells any part of itself in letters now collapses that part too
2.2.0 - a value written at a text block instead of at one of its placeholders is reported rather than dropped: `- text:complex: some words` puts the words nowhere, since the block carries its own text, and the run now names the block, quotes what was dropped and lists the placeholders it could have gone to; the loader cannot catch this because it never sees the template, and the same line is right when the address is a plain tag
2.2.0 - a modifier that names no value class of its own carries words: `description: {file: caption.txt}` on a picture writes what the file says instead of 'unclear what to do', and a file-backed value written into a tag that shares its run with surrounding words no longer replaces them
2.2.0 - a `text:` block from `<section:template>` can be filled: any tag standing inside the block is a placeholder the document names by its own name (`- text:complex: {placeholder:one: a text, placeholder:two: {file: note.txt}}`), namespaced or bare, and a placeholder may carry anything a fill may; such an address needs no source key, since the block already carries its text, while every other namespace still requires one; a placeholder the document does not name is blanked, and the block's closing tag no longer ships as literal text at the end of it
2.2.0 - new `ManagedDocx.structure(rdf)`: builds only the step that creates and places the instances and leaves everything else alone, so the saved file shows what the run made of the document -- each clone with the instance number it is addressed by (`id=1`, `id=2`), the unused blueprints still standing and still flagged, every marker entry already in front of its marker, and no value filled, so every fill tag is still readable as an address; Word only, a PowerPoint slide being created during the fill (docs/Intro.md section 5)
2.2.0 - `breakbefore` no longer puts a page break in front of the FIRST instance of a block, only in front of the ones that follow it: instance 1 starts where the blueprint stands and needs no break to get there, and a block flagged this way but used once now gets none at all (04_examples/essay lost the third break in front of its first content section, where its own template already carries two; 04_examples/wordreport and 02_basetest/docx_basic/simple lost the single break in front of each of their three flagged blocks) -- to start the first one on a fresh page too, put a page break in the template in front of the blueprint
2.2.0 - a Word template without a `<section:template>` builds instead of failing: the removal step used to call delete() on the section it had just failed to find, so such a template died on an AttributeError at the very end of an otherwise finished run; it now warns once that nothing can be added from that section and notes that blueprints flagged `template` elsewhere in the document are unaffected
2.2.0 - docs/tags.md and docs/Intro.md read through against the code: `breakbefore` fires for every instance including the first, not only for repeats (both files said otherwise); a Word template requires a `<section:template>` but not a `<section:title>`; the `=` bullet named a `name=` argument nothing reads and left out `id=`, the instance number; the ladder's last rung and the `<ignore:.. all below/>` tag were missing from the predefined-tag list
2.1.0 - 2026/08/31 - no behaviour change, a test fix: test_parameter_case1 asserted the .nv timestamp as '2019-08-28 14:44:25', which is that instant in CEST only, so the suite failed on any machine in another time zone (the first CI run, on UTC runners, said 12:44:25); the instant is now pinned absolutely and the rendering against the local clock the way DateValue documents it — a timestamp is naive local time and no time zone is ever attached, which is unchanged
2.1.0 - an address that names a block the template does not hold at that place is diagnosed in one line instead of two: it names the block, the parent that does not hold it and the parent that does (`Nothing to apply at <address> - 'x' holds no 'y'; it stands under <where>, and an address is positional`), the redundant `No exact match` in list notation is gone, and `No such parent structure:` is now worded `cannot find parent structure` like the same event everywhere else; the per-task reports that follow are unchanged, being how you see how much content a misplaced entry dropped
2.1.0 - the documentation says what has always been true of a container address: it is positional, so a block is only reachable where the template holds it — a `sub3section:step` standing under `subsection:alpha` cannot be addressed under `subsection:beta`, and that entry is dropped with warnings; a marker is the one way to place content the template has nowhere else, its entries being looked up by name, which is what `<section:template>` exists for (docs/rdf.md, docs/Intro.md)
2.1.0 - repeating a block requires its opening tag to carry the `template` argument: a block without it is filled where it stands, and a second instance of it is refused with one message naming the block and the argument to add; before, the documentation promised any block could be repeated while the lookup only ever searched flagged blocks, so the attempt failed with 'No such template in document' plus one 'cannot find parent structure' per fill inside the instance that was never made
2.1.0 - a repeated block lands directly behind the instance it repeats, so the paragraphs a template holds between two blocks stay behind every instance; before, a second instance was placed before the next unused sibling block -- with the template prose threaded in between -- and a repeat of the last block of a section fell through to the section end, past its closing text
2.1.0 - a block flagged template is never content, uniformly: instance 1 of an in-content table:/image:/text: blueprint is a clone standing exactly where the blueprint stood (the document reads the same), an unused in-content blueprint no longer ships with its sample text, and an add-only use of a colliding template name fills the clone at the marker -- the warning about that split went with the split; before, only section-ladder blueprints followed the clone-first rule
2.1.0 - import Scriptum no longer touches python-docx or python-pptx: each back end loads on first use of ManagedDocx/ManagedPptx, and a missing or broken library raises a ModuleNotFoundError naming the package and its pip install line at that point of use (before, a 'Skip ... generation' print at import and the name simply absent); only when both libraries are unavailable does the import itself warn -- the tool then reads report documents but cannot generate anything
2.1.0 - an add at a marker that is its template name's only use, while a same-named flagged blueprint stands in the content, is warned about: the lookup clones the collision winner to the marker but the fill follows the ::1 address into the in-content blueprint, so the clone ships empty -- the warning names the add and where the fill lands (behaviour unchanged; fill instance 1 in place first, or rename one of the templates)
2.1.0 - an empty CSV cell -- written empty, or missing from a short row -- fills its table cell with a blank, overwriting whatever sample text the template's table carries there; before, short rows left their tail cells untouched and the template text showed through
2.1.0 - a multi-line text file arrives in the document with its line breaks as written; before, every break in the file became a blank line (the reader joined readlines() -- which keep their newlines -- with another newline), unnoticed while every text fixture was a single line
2.1.0 - a color modifier paints the font of the text its fill writes, in Word and PowerPoint alike: direct, _global_, text-file and parameter-file fills, and PowerPoint template clones added at a marker; the paint lands exactly on the run that received the text, so template text around the tag keeps its own colour (before, colours parsed and diagnosed but no back end consumed them)
2.1.0 - a pptx finish=True run no longer opens a visible PowerPoint window: the deck is opened WithWindow=False, the re-save and the PDF export work as before, and a PowerPoint the user already has open keeps its own windows untouched
2.1.0 - a Windows install without the [windows] extra keeps working docx and pptx generation: win32com is imported at finish time instead of module import (before, both back ends vanished with 'Skip ... generation'); finish=True without pywin32 names the missing extra and leaves the document saved but unfinished, and off Windows the finishing note comes without touching win32com at all
2.0.0 - 2026/08/24 - the report data file is a YAML document (.yaml); the hand-written .rdf text format and its parser are removed; scripts/rdf2yaml.py converts an existing .rdf base as a starting point
2.0.0 - default date formats are ISO 8601 ('%Y-%m-%d', '%Y-%m-%d %H:%M:%S') instead of the locale forms '%x'/'%c'; a date that does not read as a date is refused
2.0.0 - removed *timeformat, a setting from an early version that was never implemented
2.0.0 - an add at a marker finds a template block flagged anywhere in the document, the template section first and any ambiguity warned; before, only section:template was searched
2.0.0 - text and parameter files (text: fills, .nv/.par) are read as UTF-8, like the CSV files always were; the platform-default read made a document with umlauts or symbols behave differently per machine, and on Windows ANSI a UTF-8 text fill was dropped silently
2.0.0 - a pptx finish=True run works again: the finishing pass used Word's Close(SaveChanges=True), which PowerPoint's Close() does not accept, so the re-save and the PDF export always failed silently; PowerPoint now really rewrites the deck and createpdf delivers its PDF
1.2.1 - 2025/11/30 - early package fix
1.2.0 - 2025/11/28 - first PyPi release
2025/November - LICENSES and distribution
2025/October - main rewrite and test coverage
2021/January - added some documentation
2020/October - added to Gitlab (internal)
2020/September - PPTX rewritten
2020/August - DOCX working
2020/Mai    - first implementation, PPTX working
2019/Mai    - initial idea and some tests
