# Спецификация MXL DSL — JSON-формат описания табличного документа

Компактный JSON-формат для описания макетов табличных документов 1С (SpreadsheetDocument). Используется навыком `/mxl-compile` (JSON → XML).

## Пример

```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", "align": "center" },
    "label": { "font": "bold" },
    "bordered": { "border": "all" },
    "bordered-right": { "border": "all", "align": "right" },
    "total-right": { "font": "bold", "border": "top", "align": "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` | да | — | Количество колонок |
| `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"`) |
| `fonts` | нет | — | Именованные шрифты (если не задано, создаётся Arial 10) |
| `styles` | нет | `{}` | Именованные стили |
| `areas` | да | — | Массив именованных областей (порядок = порядок в документе) |

## Шрифты (`fonts.<name>`)

| Поле | По умолч. | Описание |
|------|-----------|----------|
| `face` | `"Arial"` | Имя шрифта |
| `size` | `10` | Размер |
| `bold` | `false` | Жирный |
| `italic` | `false` | Курсив |
| `underline` | `false` | Подчёркнутый |
| `strikeout` | `false` | Зачёркнутый |

Шрифт `"default"` используется когда стиль не указывает шрифт явно. Если не определён, создаётся автоматически (Arial 10).

## Стили (`styles.<name>`)

| Поле | По умолч. | Описание |
|------|-----------|----------|
| `font` | `"default"` | Ссылка на имя шрифта |
| `align` | — | `left`, `center`, `right` |
| `valign` | — | `top`, `center` |
| `border` | — | Стороны рамки: `all`, `top`, `bottom`, `left`, `right`, `none`. Через запятую: `"top,bottom"` |
| `borderWidth` | `"thin"` | Толщина рамки: `thin` (1px) или `thick` (2px) |
| `wrap` | `false` | Перенос текста |
| `format` | — | Формат данных 1С: `"ЧЦ=15; ЧДЦ=2"`, `"ДФ=dd.MM.yyyy"` и т.д. |

## Области (`areas[]`)

| Поле | Обяз. | Описание |
|------|:-----:|----------|
| `name` | да | Имя области для `Макет.ПолучитьОбласть("Имя")` |
| `rows` | да | Массив строк |

## Строки (`rows[]`)

| Поле | По умолч. | Описание |
|------|-----------|----------|
| `height` | — | Высота строки (если не задана, используется авто) |
| `rowStyle` | — | Стиль для ВСЕХ колонок (заполняет пустоты рамками) |
| `cells` | `[]` | Массив ячеек |
| `empty` | — | Количество подряд идущих пустых строк (заменяет N отдельных `{}`) |

Строка без `cells` и `rowStyle` → пустая строка. `{ "empty": 3 }` эквивалентно трём `{}`.

## Ячейки (`cells[]`)

| Поле | Обяз. | По умолч. | Описание |
|------|:-----:|-----------|----------|
| `col` | да | — | Позиция колонки (1-based) |
| `span` | нет | `1` | Объединение по горизонтали (количество колонок) |
| `rowspan` | нет | `1` | Объединение по вертикали (количество строк) |
| `style` | нет | rowStyle | Стиль ячейки (переопределяет rowStyle) |
| `param` | нет | — | Параметр заполнения |
| `detail` | нет | — | Параметр расшифровки (только с `param`) |
| `text` | нет | — | Статический текст |
| `template` | нет | — | Шаблонный текст с `[Параметр]` |

### Тип заполнения

Определяется автоматически по содержимому ячейки:
- `param` → fillType=Parameter
- `template` → fillType=Template
- `text` → fillType=Text
- ничего → без fillType (пустая ячейка или рамка)

## `rowStyle` — автозаполнение

Когда задан `rowStyle`, компилятор создаёт ячейки для ВСЕХ колонок строки. Позиции без явных ячеек заполняются пустыми ячейками с указанным стилем. Это обеспечивает сплошные рамки в табличных строках.

Если в предыдущих строках той же области есть ячейки с `rowspan`, их колонки при автозаполнении пропускаются.

## Ограничения

Текущая версия не поддерживает:
- Множественные наборы колонок (`columnsID`)
- Области типа Columns / Rectangle
- Рисунки (штрихкоды, картинки)
- Фон ячеек
