feat(mxl-compile,mxl-decompile): колонтитулы и параметры печати

Ключи header и footer описывают колонтитул: три слота (left, center,
right), общий шрифт и вертикальное выравнивание, признак вывода и
страница, с которой печатать. Ключ printSettings — плоский набор
параметров печати с именами тегов платформы; порядок компилятор
выставляет сам, незнакомый ключ отвергает.

Слот устроен как ячейка: ссылка на формат плюс текст. Текст бывает двух
видов, и это не текст против шаблона, а обычная строка против
форматированной: у форматированной разметка живёт прямо в содержимом
(<b>жирный</>, <fontsize 12>, <colorstyle -16>), поэтому она возится как
есть. Признак вывода и стартовая страница лежат в формате как <height>
и <width>, но читаются только у записи с <height>: палитра
дедуплицирована, и колонтитул без своих настроек ссылается на чужую
запись, где <width> — ширина колонки (637 таких ссылок против 153 своих).

Перенос строки внутри текста колонтитула платформа хранит голым LF при
CRLF во всём остальном файле — единственное такое место в документе,
поэтому содержимое пишется одной строкой вывода.

Формат колонтитула регистрируется до отсева неиспользуемых шрифтов:
иначе шрифт, на который ссылается только колонтитул, выбрасывался бы
из палитры.

Стенд Колонтитулы собирается байт в байт обоими портами и добавлен
в платформенные фикстуры.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-08-15 17:07:54 +03:00
co-authored by Claude Opus 5
parent 1e0b82d419
commit 702a3b6a8d
16 changed files with 881 additions and 8 deletions
+35 -2
View File
@@ -601,7 +601,40 @@ current-config не объявляет, поэтому вынести объяв
обратные, ячейки продолжают ссылаться на записи со старыми ширинами. Из итогового XML это
значение не выводится — воспроизводить его не нужно.
## Группировки строк и колонок
## Колонтитулы и параметры печати
```xml
<leftHeader>
<f>2</f> <!-- формат: шрифт, выравнивание, признак вывода, стартовая страница -->
<tl><v8:item><v8:lang>ru</v8:lang><v8:content>Слева</v8:content></v8:item></tl>
</leftHeader>
<printSettings>
<topMargin>1000</topMargin><firstPageNumber>15</firstPageNumber>
</printSettings>
```
Шесть элементов идут после строк и перед `<templateMode>`: `leftHeader`, `centerHeader`,
`rightHeader`, `leftFooter`, `centerFooter`, `rightFooter`. Пишутся не комплектом: `leftHeader`
есть у 1 013 макетов, остальные — у 677–790.
| Наблюдение | Данные корпуса |
|---|---|
| текст слота | `<tl>` — обычная строка, `<tfl>` — форматированная (разметка внутри содержимого: `<b>…</>`, `<fontsize 12>`, `<colorstyle -16>`) |
| формат слота | `<height>` = признак вывода (`1` / `-1`), `<width>` = страница, с которой печатать, плюс шрифт и `verticalAlignment` |
| формат общий на колонтитул | у 674 макетов из 677; разный у трёх |
| формат делится с другими владельцами | 637 против 153 «только колонтитулы» — палитра дедуплицирована, поэтому `<width>` в чужой записи означает ширину колонки, а не страницу |
**Ловушка:** перенос строки внутри текста колонтитула платформа хранит голым LF, тогда как весь
остальной файл идёт CRLF. Это единственное место документа с другим переводом строки.
`printSettings` (2 350 макетов) — плоский набор в фиксированном порядке: `pageOrientation` ·
`scale` · `collate` · `copies` · `perPage` · `topMargin` · `leftMargin` · `bottomMargin` ·
`rightMargin` · `headerSize` · `footerSize` · `fitToPage` · `blackAndWhite` · `printerName` ·
`paper` · `paperSource` · `pageWidth` · `pageHeight` · `duplexType` · `pagePlacementAlternation` ·
`firstPageNumber`. Номер первой страницы принадлежит именно параметрам печати, а не колонтитулу.
## Группы строк и колонок
```xml
<vgLevels>2</vgLevels>
@@ -616,7 +649,7 @@ current-config не объявляет, поэтому вынести объяв
<hg></hg> <!-- то же для колонок -->
```
Строки группируются часто (1 797 макетов, 170 967 группировок), колонки — почти никогда
Строки группируются часто (1 797 макетов, 170 967 групп), колонки — почти никогда
(1 макет, 1 группировка). Порядок документных тегов: `height``vgLevels``vgRows``vg`
`hg`; `vgLevels` пишется только при наличии группировок.
+53 -1
View File
@@ -89,6 +89,8 @@
| `columnSets` | нет | — | Дополнительные колоночные раскладки (см. `mxl-dsl-styles.md`) |
| `rowGroups` | нет | — | Группы строк (см. ниже) |
| `columnGroups` | нет | — | Группы колонок (см. ниже) |
| `header` / `footer` | нет | — | Верхний и нижний колонтитулы (см. ниже) |
| `printSettings` | нет | — | Параметры печати (см. ниже) |
## Области (`areas[]`)
@@ -302,6 +304,56 @@
и компилятор проставляет это сам. `autoSize` и `box` независимы: при автоподгоне размера
положение окошка всё равно хранится.
## Колонтитулы
У верхнего и нижнего колонтитула по три слота — `left`, `center`, `right` — и общие настройки:
```json
"header": {
"font": "мелкий",
"verticalAlignment": "Bottom",
"startPage": 2,
"left": "Слева\nвторая строка",
"center": "Стр. [&НомерСтраницы] из [&СтраницВсего]",
"right": { "ru": "Справа", "en": "Right" }
},
"footer": {
"show": false,
"center": { "formatted": "<b>Итог</> <colorstyle -16>красным</>" }
}
```
| Поле | По умолч. | Описание |
|------|-----------|----------|
| `left`, `center`, `right` | — | Текст слота: строка, объект «язык → текст» или `{ "formatted": … }` |
| `font` | — | Имя шрифта из `fonts` — на весь колонтитул |
| `verticalAlignment` | — | Положение текста по вертикали: `Top`, `Center`, `Bottom` |
| `show` | `true` | Выводить ли колонтитул |
| `startPage` | `1` | Страница, с которой колонтитул печатается |
Текст может быть многострочным (`\n`) и содержать поля `[&НомерСтраницы]`, `[&СтраницВсего]`,
`[&Дата]`, `[&Время]` — платформа подставляет их при печати. `{ "formatted": … }` — форматированная
строка: разметка живёт прямо в тексте (`<b>жирный</>`, `<fontsize 12>`, `<colorstyle -16>`).
## Параметры печати
Плоский объект; имя ключа совпадает с именем свойства в выгрузке:
```json
"printSettings": {
"pageOrientation": "Landscape",
"topMargin": 500, "leftMargin": 500, "bottomMargin": 500, "rightMargin": 500,
"headerSize": 1000, "footerSize": 1000,
"fitToPage": true, "firstPageNumber": 7
}
```
Допустимые ключи: `pageOrientation`, `scale`, `collate`, `copies`, `perPage`, `topMargin`,
`leftMargin`, `bottomMargin`, `rightMargin`, `headerSize`, `footerSize`, `fitToPage`,
`blackAndWhite`, `printerName`, `paper`, `paperSource`, `pageWidth`, `pageHeight`, `duplexType`,
`pagePlacementAlternation`, `firstPageNumber`. Незнакомый ключ — ошибка. Порядок в объекте не
важен: компилятор пишет свойства в том порядке, что и платформа.
## Группы строк и колонок
Диапазон строк или колонок, который сворачивается кнопкой на полях. Задаются плоским списком;
@@ -347,7 +399,7 @@ XML не возвращается.
- объединения, не привязанные к ячейке (по всей высоте или ширине документа);
- рисунки и картинки, в том числе штрихкоды;
- колонтитулы, параметры печати, область печати.
- область печати.
Пересборка макета из DSL — это полная перегенерация, а не точечная правка XML, поэтому
diff после round-trip обычно шире фактической доработки.