Files
cc-1c-skills/docs/mxl-dsl-spec.md
T
Nick Shirokov e10421d18e docs(mxl-compile): выправить примеры каскада по проверке компилятором
Прогнал каждый json-блок инструкций и спецификации через компилятор
и валидатор, фрагменты достраивая до минимального макета. Нашлось:

- пример колоночных раскладок показывал области с "rows": [] — макет
  с именованными областями поверх нуля строк, валидатор на нём ругается;
- шапка таблицы в примере SKILL.md была записана пятью объектами с col
  там, где хватает позиционного списка строк.

Оба поправлены; раундтрип примера подтверждает, что форма каноническая —
декомпилятор возвращает её же.
2026-08-17 13:01:50 +03:00

693 lines
43 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Спецификация MXL DSL — JSON-формат описания табличного документа
Компактный JSON-формат для описания макетов табличных документов 1С (SpreadsheetDocument). Используется навыками `/mxl-compile` (JSON → XML) и `/mxl-decompile` (XML → JSON).
## Пример
```json
{
"columns": 10,
"defaultWidth": 30,
"columnWidths": { "1": 15, "2-8": 40, "9-10": 50 },
"fonts": {
"default": { "face": "Arial", "size": 10 },
"bold": { "face": "Arial", "size": 10, "bold": true },
"header": { "face": "Arial", "size": 14, "bold": true }
},
"styles": {
"default": {},
"header": { "font": "header", "horizontalAlignment": "Center" },
"label": { "font": "bold" },
"bordered": { "border": "Solid" },
"bordered-right": { "border": "Solid", "horizontalAlignment": "Right" },
"total-right": { "font": "bold", "topBorder": "Solid", "horizontalAlignment": "Right" }
},
"areas": [
{
"name": "Заголовок",
"rows": [
{ "height": 20, "cells": [
{ "col": 1, "span": 10, "style": "header", "param": "ТекстЗаголовка" }
]}
]
},
{
"name": "ШапкаТаблицы",
"rows": [
{ "rowStyle": "bordered", "cells": [
{ "col": 1, "text": "№" },
{ "col": 2, "span": 6, "text": "Наименование" },
{ "col": 9, "text": "Кол-во" },
{ "col": 10, "text": "Сумма" }
]}
]
},
{
"name": "Строка",
"rows": [
{ "rowStyle": "bordered", "cells": [
{ "col": 1, "param": "НомерСтроки" },
{ "col": 2, "span": 6, "param": "Товар", "detail": "Номенклатура" },
{ "col": 9, "style": "bordered-right", "param": "Количество" },
{ "col": 10, "style": "bordered-right", "param": "Сумма" }
]}
]
},
{
"name": "Итого",
"rows": [
{ "cells": [
{ "col": 8, "span": 2, "style": "total-right", "text": "Итого:" },
{ "col": 10, "style": "total-right", "param": "Всего" }
]}
]
}
]
}
```
## Верхний уровень
| Поле | Обяз. | По умолч. | Описание |
|------|:-----:|-----------|----------|
| `columns` | да | — | Количество колонок в раскладке по умолчанию. `0` допустимо: значит, все строки живут в раскладках из `columnSets` |
| `page` | нет | — | Формат страницы: `"A4-landscape"` (780), `"A4-portrait"` (540) или число. Автоматически вычисляет `defaultWidth` из суммы пропорций `"Nx"` |
| `defaultWidth` | нет | 10 | Ширина колонок по умолчанию. Игнорируется если задан `page` и все колонки используют `"Nx"` |
| `columnWidths` | нет | `{}` | Ширины колонок. Ключи 1-based: `"1"`, `"3-14"`, `"5,7,9"`. Значения: число (абсолют) или `"Nx"` (множитель от defaultWidth, напр. `"2x"`, `"0.5x"`) |
| `columnStyles` | нет | — | Оформление колонок: те же ключи, значение — имя стиля (см. «Оформление») |
| `textLanguages` | нет | `["ru"]` | Языки, на которых пишется текст, заданный строкой (см. ниже) |
| `fonts` | нет | — | Именованные шрифты (если не задано, создаётся Arial 10) |
| `styles` | нет | `{}` | Именованные стили (см. «Оформление») |
| `areas` | да | — | Массив областей — диапазонов подряд идущих строк (порядок = порядок в документе); имя необязательно |
| `namedAreas` | нет | — | Именованные области, заданные координатами (см. ниже) |
| `columnSets` | нет | — | Дополнительные колоночные раскладки (см. «Колоночные раскладки») |
| `rowGroups` | нет | — | Группы строк (см. ниже) |
| `columnGroups` | нет | — | Группы колонок (см. ниже) |
| `header` / `footer` | нет | — | Верхний и нижний колонтитулы (см. ниже) |
| `printSettings` | нет | — | Параметры печати (см. ниже) |
| `pictures` | нет | — | Палитра картинок: ссылки на библиотеку платформы или данные (см. ниже) |
| `drawings` | нет | — | Рисунки: картинки, фигуры, надписи (см. ниже) |
## Области (`areas[]`)
| Поле | Обяз. | Описание |
|------|:-----:|----------|
| `name` | нет | Имя области для `Макет.ПолучитьОбласть("Имя")` |
| `columnSet` | нет | Ссылка на раскладку из `columnSets` |
| `rows` | да | Массив строк |
Макет собирается из областей — диапазонов подряд идущих строк. Имя делает область именованной: она доступна в коде как `Макет.ПолучитьОбласть("Имя")` и занимает строки своего диапазона. **Область без имени** — просто кусок сетки: так описываются строки, не принадлежащие ни одной именованной области.
## Именованные области координатами (`namedAreas[]`)
Для областей, которые диапазоном подряд идущих строк не описываются: полоса колонок, прямоугольник, ячейка, а также пересекающиеся с другими.
| Поле | Обяз. | Описание |
|------|:-----:|----------|
| `name` | да | Имя области |
| `rows` | \* | Строки: число или диапазон `"N-M"`, 1-based |
| `cols` | \* | Колонки: число или диапазон `"N-M"`, 1-based |
| `columnSet` | нет | Колоночная раскладка области. Без ключа выводится из накрытых строк, `""` — привязки нет |
\* Обязательна хотя бы одна из осей.
**Тип области не указывается** — он следует из того, какие оси заданы, как в `ТабличныйДокумент.Область()`: только строки → полоса строк, только колонки → полоса колонок, обе оси → прямоугольник, одиночные значения по обеим осям → одна ячейка.
```json
"namedAreas": [
{ "name": "ОбластьПечатиПоВысоте", "rows": "1-48" },
{ "name": "ОбластьПечатиПоШирине", "cols": "1-35" },
{ "name": "HZY", "rows": 9, "cols": "16-17" }
]
```
Диапазон — та же грамматика, что у `columnWidths`, но **только** число или `"N-M"`: список через запятую запрещён, область непрерывна. Имя обязательно, и хотя бы одна ось должна быть задана; нарушение любого из этих правил → ненулевой код выхода и сообщение в stderr.
## Строки (`rows[]`)
| Поле | По умолч. | Описание |
|------|-----------|----------|
| `height` | — | Высота строки (если не задана, используется авто) |
| `hidden` | `false` | Скрыть строку |
| `rowStyle` | — | Стиль строки: ложится и на саму строку, и на ВСЕ её колонки (заполняет пустоты рамками) |
| `cells` | `[]` | Массив ячеек |
| `empty` | — | Количество подряд идущих пустых строк (заменяет N отдельных `{}`) |
Строка без `cells` и `rowStyle` → пустая строка. `{ "empty": 3 }` эквивалентно трём `{}`.
`height` и `hidden` — собственные свойства строки: у ячейки таких нет, и в её оформление они
не попадают. Всё остальное оформление строки задаётся через `rowStyle`.
### Короткая форма: список ячеек позиционно
Список ячеек можно записывать позиционно — позиция определяется порядком, `col` не указывается.
Если у строки нет своих свойств, такой список и есть строка; если нужны `height`, `hidden`
или `rowStyle` — тот же список кладётся в `cells`.
| Элемент | Значение |
|---------|----------|
| `"текст"` | Статический текст (`text`) |
| `{ "ru": "…", "en": "…" }` | Тот же текст на нескольких языках |
| `"{Имя}"` | Параметр (`param`) |
| `">"` | Продолжение ячейки слева — увеличивает её `span` |
| `"|"` | Продолжение ячейки сверху — увеличивает её `rowspan` |
| `null` | Пустая колонка: позиция занята, ячейка не создаётся |
| `{ ... }` | Обычная ячейка **без** `col`; нужна для `style`, `detail`, `template` |
Объект-элемент трактуется по его ключам: если среди них есть ключ ячейки (`span`, `rowspan`,
`style`, `param`, `detail`, `text`, `template`, `valueType`, `controlType`, `value`,
`control`) — объект
описывает
свойства ячейки. Иначе он целиком считается её текстом, а его ключи — идентификаторами языков.
```json
"rows": [
["Вид", "Остаток", ">", "Итог"],
["|", "начало", "конец", "|"],
["{Вид}", "{Нач}", "{Кон}", "{Итог}"]
]
```
Здесь «Вид» и «Итог» объединены по вертикали на две строки, «Остаток» — по горизонтали на две колонки.
```json
{ "rowStyle": "итог", "cells": [null, null, null, "Итого:", "{Всего}"] }
```
Ограничение у формы одно: ею не выразить текст, совпадающий с `">"`, `"|"` или с шаблоном
`"{...}"` — такие ячейки записываются объектом с ключом `text`.
Маркеру нужно, что продолжать: `">"` требует ячейку слева в той же строке, `"|"` — ячейку сверху. Объектный элемент не должен нести `col`: позиция уже задана порядком. Число элементов не может превышать `columns`. Нарушение любого из этих правил → ненулевой код выхода и сообщение в stderr.
## Ячейки (`cells[]`)
| Поле | Обяз. | По умолч. | Описание |
|------|:-----:|-----------|----------|
| `col` | да | — | Позиция колонки (1-based). В короткой форме строки не указывается — позиция берётся из порядка |
| `span` | нет | `1` | Объединение по горизонтали (количество колонок) |
| `rowspan` | нет | `1` | Объединение по вертикали (количество строк) |
| `style` | нет | rowStyle | Стиль ячейки (переопределяет rowStyle) |
| `param` | нет | — | Параметр заполнения |
| `detail` | нет | — | Параметр расшифровки. Самостоятельный ключ: ставится и на ячейку без `param` — с текстом, пустую или поле ввода |
| `text` | нет | — | Статический текст. Строка или объект `{ ru, en }` — см. ниже |
| `template` | нет | — | Шаблонный текст с `[Параметр]`. Строка или объект, как `text` |
| `valueType` | нет | — | Тип значения: ячейка становится полем ввода (см. ниже) |
| `controlType` | нет | `input` | Элемент управления поля ввода: `input` или `checkbox`. Только вместе с `valueType` |
| `value` | нет | — | Значение в поле ввода. Только вместе с `valueType` |
| `control` | нет | — | Настройки элемента управления в записи платформы (base64). Раундтрип, не для ручного авторинга |
| `note` | нет | — | Примечание к ячейке (см. ниже) |
### Содержимое ячейки
Задаётся ровно одним из ключей, объявлять способ заполнения отдельно не нужно:
- `param` — параметр заполнения;
- `template` — текст со вставками `[Параметр]`;
- `text` — статический текст;
- ничего — пустая ячейка (нужна, например, ради рамки).
### Текст на нескольких языках
`text` и `template` принимают строку или объект «язык → текст». Объект даёт по надписи на каждый язык, в порядке ключей. Строка означает один и тот же текст на всех языках макета — по умолчанию только русский.
```json
{ "col": 1, "text": "Наименование" }
{ "col": 2, "text": { "ru": "Поставщик", "en": "Supplier" } }
```
Набор языков задаётся документным ключом `textLanguages`:
```json
{ "columns": 3, "textLanguages": ["ru", "en"], "areas": [] }
```
С таким объявлением `"Наименование"` из примера выше даст надпись и под `ru`, и под `en`.
Ключ ни на что в конфигурации не смотрит — это просто список языков, на которые разворачивается строка.
Пустая строка — это текст: ячейка с `"text": ""` даёт пустую надпись, а не ячейку без текста.
## Ячейка-поле ввода
Ячейка может не показывать текст, а принимать значение от пользователя — так делают макеты для
ввода данных. Достаточно задать тип значения:
```json
{ "col": 1, "valueType": "Number(15,3,nonneg)" }
{ "col": 2, "valueType": "String(10)" }
{ "col": 3, "valueType": "Boolean", "controlType": "checkbox" }
{ "col": 4, "valueType": "CatalogRef.Валюты" }
{ "col": 5, "valueType": "Boolean + String + Date + CatalogRef.Валюты" }
{ "col": 6, "valueType": "AnyRef" }
```
Грамматика типа:
| Запись | Значение |
|---|---|
| `Boolean` | булево |
| `String`, `String(10)`, `String(10,fixed)` | строка; без длины — неограниченная, `fixed` — фиксированной длины |
| `Number`, `Number(15,3)`, `Number(15,3,nonneg)` | число; без параметров — без ограничения разрядности, `nonneg` — неотрицательное |
| `Date`, `DateTime`, `Time` | дата, дата со временем, время |
| `CatalogRef.Валюты`, `DocumentRef.Реализация`, `EnumRef.Статусы`, `DefinedType.Сумма` | ссылочный тип |
| `CatalogRef`, `DocumentRef`, `AnyRef` | категория целиком: любая ссылка этого вида |
| `A + B` | составной тип; повтор одного примитива недопустим |
Русские имена принимаются наравне с английскими: `Число(15,3)`, `Строка(10)`,
`СправочникСсылка.Валюты`.
`text` и `template` в такой ячейке недопустимы — платформа не показывает текст там, где вводится
значение. `param` и `detail` допустимы: они описывают заполнение и расшифровку, а не содержимое.
Пустой тип `"valueType": ""` — «ячейка содержит значение», но тип не ограничен.
Значение поля ввода задаётся ключом `value`, и его тип выражается литералом JSON: строка —
строкой, число — числом, булево — `true`/`false`. Приведения к объявленному типу **не
происходит**: платформа хранит значение с его собственным типом и совпадать с объявленным он
не обязан (у ссылочного и составного типа значение всегда строковое). Пустая строка означает
пустое значение объявленного типа. Дата записывается строкой в формате `ГГГГ-ММ-ДДTчч:мм:сс`
и читается как дата только у ячейки, объявленной датой.
```json
{ "col": 1, "valueType": "Number(15,3)", "value": 12.5 }
{ "col": 2, "valueType": "String(10)", "value": "5" }
{ "col": 3, "valueType": "Boolean", "value": true }
{ "col": 4, "valueType": "DateTime", "value": "" }
```
`controlType` нужен редко: умолчание платформы — поле ввода, и оно применяется ко всем типам,
включая `Boolean`. Флажок задаётся явно. Значение `"none"` (тега элемента управления нет вовсе) —
форма раундтрипа, для ручного авторинга не нужна.
## Примечание к ячейке
Всплывающая подсказка, которую платформа показывает при наведении. Задаётся ключом `note`
строкой, объектом «язык → текст» или полной формой:
```json
{ "col": 1, "text": "Итого", "note": "Сумма без НДС" }
{ "col": 2, "note": { "ru": "на дату документа", "en": "as of the document date" } }
{ "col": 3, "note": { "text": "не более 20%", "style": "жёлтая-подсказка" } }
{ "col": 4, "note": { "text": "…", "autoSize": false,
"box": { "top": 58, "left": -175, "bottom": 362, "right": 478 } } }
```
Объект трактуется по ключам — так же, как текст ячейки в короткой форме строки: есть ключ
примечания (`text`, `style`, `box`, `autoSize`, `anchor`) → это описание примечания, иначе ключи
считаются идентификаторами языков.
| Поле | По умолч. | Описание |
|------|-----------|----------|
| `text` | — | Текст подсказки: строка или объект «язык → текст» |
| `style` | стиль подсказки | Имя стиля из `styles`; без него — оформление, которое даёт Конфигуратор |
| `autoSize` | `true` | Подгонять ли размер окошка под текст |
| `box` | канонический | Смещения окошка: `top`, `left` — положение, `bottom`, `right` — размер |
| `anchor` | `{ row: 1, col: 1 }` | Якорь начала окошка. Раундтрип, не для ручного авторинга |
Координаты ячейки в примечании не задаются — платформа привязывает конец окошка к самой ячейке,
и компилятор проставляет это сам. `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`. Незнакомый ключ — ошибка. Порядок в объекте не
важен: компилятор пишет свойства в том порядке, что и платформа.
## Группы строк и колонок
Диапазон строк или колонок, который сворачивается кнопкой на полях. Задаются плоским списком;
вложенность выражена вхождением одного диапазона в другой:
```json
"rowGroups": [
{ "rows": "2-4" },
{ "rows": 3 },
{ "rows": 5, "name": "Итоговая", "collapsed": true, "titleLocation": "begin" }
],
"columnGroups": [
{ "cols": "2-3", "name": { "ru": "Показатели", "en": "Values" } },
{ "cols": 3 }
]
```
| Поле | Обяз. | По умолч. | Описание |
|------|:-----:|-----------|----------|
| `rows` / `cols` | да | — | Диапазон 1-based: число или `"N-M"` |
| `name` | нет | — | Имя группы: строка или объект «язык → текст» |
| `collapsed` | нет | `false` | Свёрнута ли группа при открытии |
| `titleLocation` | нет | `auto` | Расположение заголовка: `begin`, `end`, `auto` |
Диапазоны либо вложены, либо не пересекаются — частичное пересечение платформа не хранит, и
компилятор отвергает его с ненулевым кодом выхода. Число уровней вложенности считается само.
Порядок в списке не важен: компилятор пишет группы так же, как платформа, — родитель
раньше вложенных, по возрастанию начала.
## Рисунки и картинки
Рисунок — объект поверх сетки ячеек: картинка, фигура или надпись. Его положение задают два
якоря: ячейка плюс смещение в точках от её левого верхнего угла.
```json
"pictures": {
"знак": { "ref": "v8ui:Стоп48" },
"логотип": { "data": "iVBORw0KGgo...", "transparent": { "x": 24, "y": 29 } }
},
"drawings": [
{ "type": "Picture", "picture": "логотип", "name": "Логотип",
"begin": { "row": 1, "col": 1 },
"end": { "row": 3, "col": 2, "dy": 34, "dx": 115 },
"pictureSize": "Proportionally", "detail": "ПараметрРасшифровки" },
{ "type": "Rectangle", "style": "заливка",
"line": { "style": "Dashed", "width": 2 },
"sides": { "left": true, "top": true, "right": false, "bottom": false },
"begin": { "row": 5, "col": 1 }, "end": { "row": 6, "col": 3 } },
{ "type": "Text", "text": { "ru": "Подпись", "en": "Signature" },
"begin": { "row": 8, "col": 1 }, "end": { "row": 8, "col": 3, "dy": 12 } }
]
```
| Поле | Обяз. | По умолч. | Описание |
|------|:-----:|-----------|----------|
| `type` | нет | `Picture` | `Picture`, `Rectangle`, `Ellipse`, `Line`, `Text`, `Chart`, `GanttChart` |
| `begin` / `end` | да | — | Якоря: `row`, `col` (1-based) и смещения `dy`, `dx` в точках |
| `picture` | нет | — | Имя записи из `pictures` |
| `pictureSize` | нет | `Stretch` | Как картинка заполняет прямоугольник: `Stretch`, `AutoSize`, `Proportionally`, `RealSize` |
| `text` | нет | — | Надпись: строка или объект «язык → текст» |
| `name` | нет | — | Имя рисунка, по которому к нему обращаются из кода |
| `detail` | нет | — | Параметр расшифровки |
| `style` | нет | — | Именованный стиль: заливка, шрифт, выравнивание надписи |
| `line` | нет | — | Линия рисунка (она же его рамка) — как `border` у ячейки |
| `sides` | нет | — | Какие стороны рамки видны: `left`, `top`, `right`, `bottom` |
| `id` | нет | номер по порядку | Идентификатор рисунка |
| `zOrder` | нет | номер по порядку | Порядок перекрытия: чем больше, тем выше |
Порядок в списке `drawings` — порядок в документе; кто кого перекрывает, задаёт `zOrder`.
Запись в `pictures` — либо ссылка (`ref`), либо сами данные в base64 (`data`). Ссылкой
задаются и предопределённая картинка платформы, и общая картинка конфигурации — пишутся они
одинаково, префиксом `v8ui:`. Пустая запись `{}` — картинка не задана, такое в макетах встречается.
Прозрачность задаётся ключом `transparent` в одной из двух форм: `false` — прозрачного фона
нет; `{ "x": …, "y": … }` — прозрачным считается цвет пикселя с этими координатами внутри
картинки (по флажку «прозрачный фон» Конфигуратор берёт её правый нижний пиксель).
Одну запись `pictures` могут использовать несколько рисунков — данные в макете не дублируются.
## `rowStyle` — оформление строки
Стиль применяется ко ВСЕЙ ширине строки: позиции без явных ячеек получают тот же стиль. Так в табличных строках получаются сплошные рамки. Он же становится оформлением самой строки — именно так платформа хранит строку, оформленную целиком.
Стиль конкретной ячейки (`style`) перекрывает `rowStyle` для этой ячейки.
Если в предыдущих строках той же области есть ячейки с `rowspan`, их колонки при автозаполнении пропускаются.
## Оформление: шрифты, стили, цвета, рамки
Оформление в табличном документе — одна сущность на всех: ячейка, строка и колонка ссылаются
на один и тот же именованный стиль. Ячейка — ключом `style`, строка — `rowStyle`, колонка —
через `columnStyles`.
### Шрифты (`fonts.<name>`)
| Поле | По умолч. | Описание |
|------|-----------|----------|
| `face` | `"Arial"` | Имя шрифта |
| `size` | `10` | Размер (бывает дробным: `8.3`) |
| `bold` | `false` | Жирный |
| `italic` | `false` | Курсив |
| `underline` | `false` | Подчёркнутый |
| `strikeout` | `false` | Зачёркнутый |
Шрифт `"default"` используется, когда стиль не указывает шрифт явно. Если не определён,
создаётся автоматически (Arial 10).
Вместо собственного описания шрифт может быть **ссылкой** — на элемент стиля конфигурации
или на системный шрифт. Тогда у него единственное поле:
```json
"fonts": {
"основной": { "ref": "style:TextFont" },
"системный": { "ref": "sys:DefaultGUIFont" }
}
```
Это та же запись, что у шрифта в описании формы.
### Стили (`styles.<name>`)
Ключ стиля — имя свойства так, как оно называется в выгрузке. Ниже частые; полный
перечень — в разделе «Полный список свойств стиля».
| Поле | Описание |
|------|----------|
| `font` | Ссылка на имя из `fonts` |
| `horizontalAlignment` | `Left`, `Center`, `Right`, `Justify`, `Auto` |
| `verticalAlignment` | `Top`, `Center`, `Bottom` |
| `textPlacement` | Что делать с длинным текстом: `Wrap` (перенос), `Cut` (обрезать), `Block`, `Auto` |
| `backColor` | Цвет фона (см. «Цвет») |
| `textColor` | Цвет текста |
| `border`, `leftBorder`, `topBorder`, `rightBorder`, `bottomBorder` | Рамка (см. «Рамка») |
| `borderColor` | Цвет рамки |
| `format` | Формат данных 1С: `"ЧЦ=15; ЧДЦ=2"`, `"ДФ=dd.MM.yyyy"` |
| `hidden` | Скрыть |
| `protection` | Защита от редактирования |
| `indent` | Отступ |
| `textOrientation` | Поворот текста, в десятых долях градуса (`900` = 90°) |
Значения перечислений регистр не различают: `"center"` и `"Center"` равнозначны.
```json
"styles": {
"шапка": {
"font": "жирный",
"horizontalAlignment": "Center",
"verticalAlignment": "Center",
"textPlacement": "Wrap",
"backColor": "#EBEBEB"
},
"итог": { "font": "жирный", "topBorder": "Solid", "horizontalAlignment": "Right" }
}
```
### Цвет
Строка в одной из четырёх форм — это нотация самой платформы:
| Форма | Значение |
|-------|----------|
| `#RRGGBB` | RGB-hex, напр. `#FFFFC0` |
| `style:ИмяСтиля` | Элемент стиля конфигурации или платформы, напр. `style:FormBackColor` |
| `web:Имя` | Цвет из web-палитры, напр. `web:Gainsboro`, `web:FireBrick` |
| `win:Имя` | Системный цвет Windows, напр. `win:ButtonText` |
Имя должно существовать в своей палитре — несуществующее платформа отвергнет при загрузке.
### Рамка
Пять ключей: `border` — все четыре стороны сразу, `leftBorder` / `topBorder` / `rightBorder` /
`bottomBorder` — по отдельности. Значение одинаковое у всех:
| Запись | Значение |
|--------|----------|
| `"Solid"` | Стиль линии, ширина 1 |
| `{ "style": "Solid", "width": 2 }` | Стиль и ширина |
Стили линии: `None`, `Solid`, `Dotted`, `Dashed`, `DashDotted`, `DashDottedDotted`,
`ThinDashed`, `LargeDashed`, `ThickDashed`, `Double`. Конфигуратор предлагает разные наборы
в разных местах — у рамки ячейки одни, у линии рисунка другие, — но палитра одна на документ.
Задавать стороны по отдельности можно всегда: если все четыре совпали, компилятор сам свернёт
их в один `border` — так это хранит платформа.
```json
"рамка-снизу": { "bottomBorder": "Dotted" },
"рамка-вокруг": { "border": { "style": "Solid", "width": 2 } }
```
### Стиль колонки (`columnStyles`)
Колонка несёт то же оформление, что ячейка и строка. Ключи — та же грамматика диапазонов,
что у `columnWidths`; значение — имя стиля.
```json
"columnWidths": { "1": 30, "2-3": 15 },
"columnStyles": { "1": "по-центру", "4": "скрытая" }
```
Внутри `columnSets` работает тот же ключ. Ширина и стиль независимы: колонка может иметь
только ширину, только стиль или и то, и другое.
## Колоночные раскладки (`columnSets`)
Группа строк может иметь собственные ширины колонок — в 1С это «индивидуальная ширина колонок».
Документные `columns` и `columnWidths` описывают раскладку по умолчанию; дополнительные
объявляются в `columnSets`, а область ссылается на нужную ключом `columnSet` — так же, как
ячейка ссылается на `styles` через `style`.
```json
{
"columns": 52,
"columnWidths": { "1": 8 },
"columnSets": {
"таблица": { "columns": 52, "columnWidths": { "1": 7, "2-52": 24 } }
},
"areas": [
{ "name": "Шапка", "rows": [["Отчёт о продажах"]] },
{ "name": "ТабличнаяЧасть", "columnSet": "таблица",
"rows": [["№", "Номенклатура"]] }
]
}
```
Раскладка описывается той же парой полей, что и документная: `columns` — количество колонок
(у раскладок оно обычно разное), `columnWidths` — ширины. Ключ словаря — имя раскладки;
в макетах, полученных декомпиляцией, это идентификатор из исходного файла, при описании
с нуля — любая строка.
Все строки области получают раскладку области, поэтому одна область не может смешивать
раскладки. Позиции колонок (`col`, `span`) проверяются по ширине раскладки СВОЕЙ области,
а не документной.
Ссылка на необъявленную раскладку → ненулевой код выхода и сообщение в stderr.
## Полный список свойств стиля
Имя ключа совпадает с именем свойства в выгрузке — исключений нет. Частые свойства
с примерами — в разделе «Оформление», здесь полный перечень.
Тип значения:
- **число** — целое;
- **да/нет** — `true` / `false`;
- **перечисление** — одно из указанных, регистр не важен;
- **цвет** — `#RRGGBB`, `style:Имя`, `web:Имя`, `win:Имя`;
- **линия** — `"Solid"` либо `{ style, width }`;
- **текст** — строка (разворачивается на языки макета).
### Текст и выравнивание
| Ключ | Тип | Значение |
|------|-----|----------|
| `font` | имя | Ссылка на имя из `fonts` |
| `horizontalAlignment` | перечисление | `Left`, `Center`, `Right`, `Justify`, `Auto` |
| `verticalAlignment` | перечисление | `Top`, `Center`, `Bottom` |
| `textPlacement` | перечисление | `Wrap`, `Cut`, `Block`, `Auto` |
| `textOrientation` | число | Поворот в десятых долях градуса: `900` = 90° |
| `textColor` | цвет | Цвет текста |
| `indent` | число | Отступ текста |
| `autoIndent` | число | Автоматический отступ |
| `format` | текст | Формат данных: `"ЧЦ=15; ЧДЦ=2"` |
| `editFormat` | текст | Формат редактирования |
| `mask` | текст | Маска ввода |
| `markNegatives` | да/нет | Выделять отрицательные |
### Фон и рамка
| Ключ | Тип | Значение |
|------|-----|----------|
| `backColor` | цвет | Цвет фона |
| `pattern` | перечисление | `WithoutPattern`, `Solid`, `Pattern1``Pattern17` (в Конфигураторе «Узор 1» … «Узор 17») |
| `patternColor` | цвет | Цвет узора |
| `border` | линия | Все четыре стороны |
| `leftBorder`, `topBorder`, `rightBorder`, `bottomBorder` | линия | Отдельная сторона |
| `borderColor` | цвет | Цвет рамки |
### Поведение
| Ключ | Тип | Значение |
|------|-----|----------|
| `hidden` | да/нет | Скрыть |
| `protection` | да/нет | Защита от редактирования |
| `print` | да/нет | Выводить на печать |
| `hyperLink` | да/нет | Гиперссылка |
| `detailsUse` | перечисление | Использование расшифровки: `Cell`, `Row`, `WithoutProcessing` |
| `autoMarkIncomplete` | да/нет | Автоотметка незаполненного |
| `bySelectedColumns` | да/нет | По выделенным колонкам |
| `columnSizeChange` | перечисление | `Normal`, `QuickChange` |
| `autoWidthCalculation` | да/нет | Автоматический расчёт ширины |
| `widthWeightFactor` | число | Весовой коэффициент ширины |
### Картинка в ячейке
| Ключ | Тип | Значение |
|------|-----|----------|
| `picIndex` | число | Номер картинки |
| `pictureSizeMode` | перечисление | `AutoSize`, `Proportionally`, `RealSize` |
| `picHorizontalAlignment` | перечисление | `Auto`, `Center`, `Left`, `Right` |
| `picVerticalAlignment` | перечисление | `Top`, `Center`, `Bottom` |
| `textPosition` | перечисление | Положение текста относительно картинки: `Auto`, `Top`, `Right`, `Bottom` |
### Чего в стиле нет
- `width` — свойство колонки, задаётся через `columnWidths`;
- `height` — свойство строки, задаётся ключом `height` у строки;
- `fillType` — выводится из того, каким ключом задано содержимое ячейки
(`text` / `param` / `template`);
- `containsValue`, `valueType`, `controlType` — свойства конкретной ячейки, а не общего
оформления: задаются ключами ячейки `valueType` и `controlType`;
- линия рисунка и её стороны — свойства рисунка: задаются его ключами `line` и `sides`
(у ячейки такого свойства нет вовсе).
## Ограничения
DSL описывает не все конструкции табличного документа. Перечисленное ниже **теряется при
round-trip** (`/mxl-decompile``/mxl-compile`): в JSON оно не попадает, в сгенерированный
XML не возвращается.
- объединения, не привязанные к ячейке (по всей высоте или ширине документа);
- настройки диаграмм (`Chart`, `GanttChart`) — сам рисунок сохраняется, его содержимое нет;
- область печати.
Пересборка макета из DSL — это полная перегенерация, а не точечная правка XML, поэтому
diff после round-trip обычно шире фактической доработки.
Отдельно про побайтовое совпадение. В макетах, которые долго правили в Конфигураторе,
встречаются следы прежних состояний: формат ячейки может нести ширину колонки, которая с тех
пор изменилась. Такие значения не описывают итоговый документ и из него не выводятся, поэтому
собранный XML совпадёт с исходным не всегда — при полностью сохранённом содержании.