diff --git a/.claude/skills/mxl-compile/SKILL.md b/.claude/skills/mxl-compile/SKILL.md index d0f9cb80..2dc8ed5e 100644 --- a/.claude/skills/mxl-compile/SKILL.md +++ b/.claude/skills/mxl-compile/SKILL.md @@ -41,59 +41,131 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-compile.ps1" -J **Если макет создаётся по изображению** (скриншот, скан печатной формы) — сначала вызвать `/img-grid` для наложения сетки, по ней определить границы колонок и пропорции, затем использовать `"Nx"` ширины + `"page"` для автоматического расчёта размеров. -## JSON-схема DSL +## Что читать под задачу -Ниже — компактная структура и ключевые правила, достаточные для типового макета. Подробности читать по необходимости: +Ниже — всё, что нужно для типового макета. Остальное лежит по файлу на задачу, читать нужно +только свой: -| Что нужно | Файл | +| Задача | Файл | |---|---| -| Полные таблицы полей, развёрнутый пример, ограничения формата | `reference/dsl-spec.md` | -| Шрифты, стили, цвета, рамки, колоночные раскладки и стили колонок | `reference/styles.md` | -| Полный перечень свойств стиля | `reference/format-properties.md` | +| Свойство стиля вне частых: отступ, защита, узор, маска, формат редактирования | `reference/style-properties.md` | +| Область, не описываемая диапазоном строк; свои ширины колонок у части документа | `reference/layout.md` | +| Колонтитулы, ориентация, поля, масштаб | `reference/print.md` | +| Картинка, фигура или надпись поверх сетки; картинка в ячейке | `reference/drawings.md` | +| Ячейки для ввода данных пользователем | `reference/input-cells.md` | +| Сворачиваемые группы строк или колонок | `reference/groups.md` | +| Всплывающая подсказка у ячейки | `reference/notes.md` | -Краткая структура: +## Пример -``` -{ columns, page, defaultWidth, columnWidths, columnStyles, - fonts: { name: { face, size, bold, italic, underline, strikeout } | { ref } }, - styles: { name: { font, horizontalAlignment, verticalAlignment, textPlacement, - backColor, textColor, border, borderColor, format, hidden } }, - areas: [{ name, columnSet, rows: [{ height, hidden, rowStyle, cells: [ - { col, span, rowspan, style, param, detail, text, template, valueType, controlType, value, note } - ]}]}], - namedAreas: [{ name, rows, cols }], - rowGroups: [{ rows, name, collapsed, titleLocation }], - columnGroups: [{ cols, name, collapsed, titleLocation }], - header: { left, center, right, font, verticalAlignment, show, startPage }, footer: { … }, - printSettings: { pageOrientation, topMargin, …, fitToPage, firstPageNumber }, - columnSets: { name: { columns, columnWidths, columnStyles } }, - pictures: { name: { ref } | { data } | {} + transparent: false | { x, y } }, - drawings: [{ type, begin: { row, col, dy, dx }, end: { … }, picture, pictureSize, - text, name, detail, style, line, sides, id, zOrder }] +```json +{ + "columns": 5, + "columnWidths": { "1": 5, "2": 40, "3-5": 12 }, + "fonts": { "жирный": { "face": "Arial", "size": 10, "bold": true } }, + "styles": { + "шапка": { "font": "жирный", "horizontalAlignment": "Center", "textPlacement": "Wrap", "border": "Solid" }, + "клетка": { "border": "Solid" }, + "число": { "border": "Solid", "horizontalAlignment": "Right", "format": "ЧЦ=15; ЧДЦ=2" }, + "итог": { "font": "жирный", "horizontalAlignment": "Right", "topBorder": "Solid" } + }, + "areas": [ + { "name": "Заголовок", "rows": [ + { "height": 20, "cells": [{ "col": 1, "span": 5, "style": "шапка", "param": "ЗаголовокОтчёта" }] }, + {} + ]}, + { "name": "ШапкаТаблицы", "rows": [ + { "rowStyle": "шапка", "cells": [ + { "col": 1, "text": "№" }, { "col": 2, "text": "Номенклатура" }, + { "col": 3, "text": "Количество" }, { "col": 4, "text": "Цена" }, { "col": 5, "text": "Сумма" } + ]} + ]}, + { "name": "Строка", "rows": [ + { "rowStyle": "клетка", "cells": [ + { "col": 1, "param": "НомерСтроки" }, + { "col": 2, "param": "Товар", "detail": "Номенклатура" }, + { "col": 3, "style": "число", "param": "Количество" }, + { "col": 4, "style": "число", "param": "Цена" }, + { "col": 5, "style": "число", "param": "Сумма" } + ]} + ]}, + { "name": "Итого", "rows": [ + [null, null, null, { "style": "итог", "text": "Итого:" }, { "style": "итог", "param": "Всего" }] + ]} + ] } ``` -Ключевые правила: -- `page` — формат страницы (`"A4-landscape"`, `"A4-portrait"` или число). Автоматически вычисляет `defaultWidth` из суммы пропорций `"Nx"` -- `name` у области в `areas` необязателен: область без имени — просто кусок сетки, именованной она не станет -- `namedAreas` — области, которые не описываются диапазоном подряд идущих строк: полоса колонок, прямоугольник, ячейка. Тип не указывается, он следует из того, какие оси заданы -- `columnSet` у области — ссылка на раскладку из `columnSets`, когда группе строк нужны свои ширины колонок; без него действует документная раскладка -- Ключ стиля — имя свойства как в выгрузке; `columnStyles` вешает стиль на колонку так же, как `style` на ячейку -- Рамка — `border` (все стороны) или `leftBorder`/`topBorder`/`rightBorder`/`bottomBorder`; значение `"Solid"` либо `{ style, width }` -- `rowStyle` — стиль строки: ложится и на строку, и на все её колонки, заполняя пустоты (рамки по всей ширине) -- `height` и `hidden` — собственные свойства строки, у ячейки таких нет -- `empty` в строке — шорткат для N подряд пустых строк (`{ "empty": 3 }` = три `{}`) -- Строку можно писать массивом ячеек — позиция из порядка, `col` не нужен: `"текст"`, `"{Имя}"` — параметр, `">"` — продолжить ячейку слева, `"|"` — сверху, `null` — пропуск колонки -- `col` — 1-based позиция колонки -- `rowspan` — объединение строк вниз (rowStyle учитывает занятые ячейки) -- Содержимое ячейки задаётся одним из ключей: `param` — параметр заполнения, `text` — статический текст, `template` — текст со вставками `[Параметр]` -- `rowGroups`/`columnGroups` — группы строк и колонок (сворачиваются кнопкой на полях): плоский список диапазонов, вложенность выражена вхождением одного в другой -- `header`/`footer` — колонтитулы: три слота (`left`/`center`/`right`), общий шрифт и вертикальное выравнивание; текст может нести поля `[&НомерСтраницы]`, `[&Дата]` -- `note` — всплывающая подсказка у ячейки: строка, объект языков или `{ text, style, autoSize, box }` -- `drawings` — рисунки поверх сетки (картинка, фигура, надпись): положение задают два якоря «ячейка + смещение в точках», картинка берётся по имени из `pictures` -- `valueType` делает ячейку полем ввода (`"Number(15,3,nonneg)"`, `"String(10)"`, `"CatalogRef.Валюты"`, составной через ` + `); текста в такой ячейке быть не может, значение задаётся ключом `value` +Область «Итого» записана короткой формой: позиция берётся из порядка, `col` не нужен. + +## Структура DSL + +``` +{ columns, page, defaultWidth, columnWidths, columnStyles, textLanguages, + fonts: { имя: { face, size, bold, italic, underline, strikeout } | { ref } }, + styles: { имя: { font, horizontalAlignment, verticalAlignment, textPlacement, + border, leftBorder, topBorder, rightBorder, bottomBorder, + borderColor, backColor, textColor, format } }, + areas: [{ name, columnSet, rows: [ + { height, hidden, rowStyle, empty, cells: [ + { col, span, rowspan, style, param, detail, text, template, note, + valueType, controlType, value, pictureParameter } ] } ] }], + namedAreas, columnSets, rowGroups, columnGroups, header, footer, printSettings, + pictures, drawings +} +``` + +Верхний уровень: `columns` обязателен, остальное по необходимости. + +| Ключ | Описание | +|---|---| +| `columns` | Количество колонок раскладки по умолчанию | +| `page` | Формат страницы: `"A4-landscape"` (780), `"A4-portrait"` (540) или число. Сам вычисляет `defaultWidth` из суммы пропорций `"Nx"` | +| `defaultWidth` | Ширина колонок по умолчанию (10) | +| `columnWidths` | Ширины: ключи 1-based (`"1"`, `"3-14"`, `"5,7,9"`), значение — число или `"2x"` (доля от `defaultWidth`) | +| `columnStyles` | Стиль на колонку целиком: те же ключи диапазонов, значение — имя стиля | +| `textLanguages` | Языки, на которые разворачивается текст, заданный строкой (по умолчанию `["ru"]`) | +| `areas` | Области — диапазоны подряд идущих строк, в порядке документа | + +## Области, строки, ячейки + +**Область** (`areas[]`) — диапазон подряд идущих строк: `name` (необязательно; с именем область +доступна как `Макет.ПолучитьОбласть("Имя")`) и `rows`. Область без имени — просто кусок сетки. + +**Строка** (`rows[]`): `height`, `hidden`, `rowStyle`, `cells`. Пустая строка — `{}`, +а `{ "empty": 3 }` заменяет три подряд. `height` и `hidden` — свойства самой строки, у ячейки +таких нет. + +**Ячейка** (`cells[]`): + +| Ключ | Описание | +|---|---| +| `col` | Позиция колонки, 1-based | +| `span` / `rowspan` | Объединение вправо / вниз | +| `style` | Имя стиля; перекрывает `rowStyle` для этой ячейки | +| `param` | Параметр заполнения — `Область.Параметры.Имя = …` | +| `text` | Статический текст: строка или объект «язык → текст» | +| `template` | Текст со вставками `[Параметр]` | +| `detail` | Параметр расшифровки; ставится и без `param` | + +Содержимое задаётся ровно одним ключом из `param` / `text` / `template`; ячейка без них — +пустая (нужна, например, ради рамки). Пустая строка `"text": ""` — это тоже текст, а не +отсутствие текста. + +### Короткая форма: строка массивом + +Позиция берётся из порядка, `col` не нужен: + +| Элемент | Значение | +|---|---| +| `"текст"` | Статический текст | +| `{ "ru": "…", "en": "…" }` | Тот же текст на нескольких языках | +| `"{Имя}"` | Параметр заполнения | +| `">"` | Продолжение ячейки слева — увеличивает её `span` | +| `"|"` | Продолжение ячейки сверху — увеличивает её `rowspan` | +| `null` | Пропуск колонки | +| `{ … }` | Обычная ячейка без `col` — когда нужны `style`, `detail`, `template` | -Двухуровневая шапка массивами: ```json "rows": [ ["Вид", "Остаток", ">", "Итог"], @@ -101,3 +173,52 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-compile.ps1" -J ["{Вид}", "{Нач}", "{Кон}", "{Итог}"] ] ``` + +Здесь «Вид» и «Итог» объединены по вертикали, «Остаток» — по горизонтали на две колонки. +Короткой формой не задать `height` и `rowStyle` — это свойства строки. + +### `rowStyle` — оформление строки + +Стиль ложится на ВСЮ ширину строки: колонки без явных ячеек получают его тоже — так выходят +сплошные рамки в табличной части. Он же становится оформлением самой строки. Ячейки с `rowspan` +из предыдущих строк при этом пропускаются. + +## Оформление + +Ячейка, строка и колонка ссылаются на один и тот же именованный стиль: ячейка — ключом `style`, +строка — `rowStyle`, колонка — через `columnStyles`. + +**Шрифт** (`fonts.<имя>`): `face` (Arial), `size` (10), `bold`, `italic`, `underline`, +`strikeout`. Либо ссылка вместо описания: `{ "ref": "style:TextFont" }`, +`{ "ref": "sys:DefaultGUIFont" }`. Шрифт `"default"` берётся, когда стиль не указал свой. + +**Частые ключи стиля** — имя ключа совпадает с именем свойства в выгрузке, значения перечислений +регистр не различают: + +| Ключ | Значение | +|---|---| +| `font` | Имя из `fonts` | +| `horizontalAlignment` | `Left`, `Center`, `Right`, `Justify`, `Auto` | +| `verticalAlignment` | `Top`, `Center`, `Bottom` | +| `textPlacement` | Длинный текст: `Wrap` (перенос), `Cut` (обрезать), `Block`, `Auto` | +| `border` | Рамка со всех сторон | +| `leftBorder`, `topBorder`, `rightBorder`, `bottomBorder` | Отдельная сторона | +| `borderColor` | Цвет рамки | +| `backColor`, `textColor` | Цвет фона и текста | +| `format` | Формат данных 1С: `"ЧЦ=15; ЧДЦ=2"`, `"ДФ=dd.MM.yyyy"` | + +**Рамка**: `"Solid"` (ширина 1) либо `{ "style": "Solid", "width": 2 }`. Стили линии: `None`, +`Solid`, `Dotted`, `Dashed`, `DashDotted`, `DashDottedDotted`, `ThinDashed`, `LargeDashed`, +`ThickDashed`, `Double`. Стороны можно задавать по отдельности всегда: совпавшие четыре +компилятор свернёт сам. + +**Цвет** — нотация платформы: `#RRGGBB`, `style:ИмяСтиля` (элемент стиля конфигурации), +`web:Имя`, `win:Имя`. Несуществующее имя платформа отвергнет при загрузке. + +```json +"styles": { + "шапка": { "font": "жирный", "horizontalAlignment": "Center", "backColor": "#EBEBEB" }, + "рамка": { "border": { "style": "Solid", "width": 2 } }, + "снизу": { "bottomBorder": "Dotted" } +} +``` diff --git a/.claude/skills/mxl-compile/reference/drawings.md b/.claude/skills/mxl-compile/reference/drawings.md new file mode 100644 index 00000000..782914e9 --- /dev/null +++ b/.claude/skills/mxl-compile/reference/drawings.md @@ -0,0 +1,49 @@ +# Рисунки и картинки + +Рисунок — объект поверх сетки ячеек: картинка, фигура или надпись. Его положение задают два +якоря: ячейка плюс смещение в точках от её левого верхнего угла. + +```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` могут использовать несколько рисунков — данные в макете не дублируются. diff --git a/.claude/skills/mxl-compile/reference/dsl-spec.md b/.claude/skills/mxl-compile/reference/dsl-spec.md deleted file mode 100644 index 442a43bc..00000000 --- a/.claude/skills/mxl-compile/reference/dsl-spec.md +++ /dev/null @@ -1,455 +0,0 @@ -# Спецификация MXL DSL — JSON-формат описания табличного документа - -Компактный JSON-формат для описания макетов табличных документов 1С (SpreadsheetDocument). Используется навыком `/mxl-compile` (JSON → XML). - -Оформление — шрифты, стили, цвета, рамки, колоночные раскладки — в `styles.md`; -полный перечень свойств стиля — в `format-properties.md`. - -## Пример - -```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` | нет | — | Оформление колонок: те же ключи, значение — имя стиля (см. `styles.md`) | -| `textLanguages` | нет | `["ru"]` | Языки, на которых пишется текст, заданный строкой (см. ниже) | -| `fonts` | нет | — | Именованные шрифты (если не задано, создаётся Arial 10) | -| `styles` | нет | `{}` | Именованные стили (см. `styles.md`) | -| `areas` | да | — | Массив областей — диапазонов подряд идущих строк (порядок = порядок в документе); имя необязательно | -| `namedAreas` | нет | — | Именованные области, заданные координатами (см. ниже) | -| `columnSets` | нет | — | Дополнительные колоночные раскладки (см. `styles.md`) | -| `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` не указывается. - -| Элемент | Значение | -|---------|----------| -| `"текст"` | Статический текст (`text`) | -| `{ "ru": "…", "en": "…" }` | Тот же текст на нескольких языках | -| `"{Имя}"` | Параметр (`param`) | -| `">"` | Продолжение ячейки слева — увеличивает её `span` | -| `"|"` | Продолжение ячейки сверху — увеличивает её `rowspan` | -| `null` | Пустая колонка: позиция занята, ячейка не создаётся | -| `{ ... }` | Обычная ячейка **без** `col`; нужна для `style`, `detail`, `template` | - -Объект-элемент трактуется по его ключам: если среди них есть ключ ячейки (`span`, `rowspan`, -`style`, `param`, `detail`, `text`, `template`, `valueType`, `controlType`, `value`, -`note`) — объект -описывает -свойства ячейки. Иначе он целиком считается её текстом, а его ключи — идентификаторами языков. - -```json -"rows": [ - ["Вид", "Остаток", ">", "Итог"], - ["|", "начало", "конец", "|"], - ["{Вид}", "{Нач}", "{Кон}", "{Итог}"] -] -``` -Здесь «Вид» и «Итог» объединены по вертикали на две строки, «Остаток» — по горизонтали на две колонки. - -Ограничения короткой формы: -- не задать `height` и `rowStyle` — это свойства строки, а не ячейки; -- не выразить текст, совпадающий с `">"`, `"|"` или с шаблоном `"{...}"`. - -Маркеру нужно, что продолжать: `">"` требует ячейку слева в той же строке, `"|"` — ячейку сверху. Объектный элемент не должен нести `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` | -| `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`. Флажок задаётся явно. - -## Примечание к ячейке - -Всплывающая подсказка, которую платформа показывает при наведении. Задаётся ключом `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`) → это описание примечания, иначе ключи -считаются идентификаторами языков. - -| Поле | По умолч. | Описание | -|------|-----------|----------| -| `text` | — | Текст подсказки: строка или объект «язык → текст» | -| `style` | стиль подсказки | Имя стиля из `styles`; без него — оформление, которое даёт Конфигуратор | -| `autoSize` | `true` | Подгонять ли размер окошка под текст | -| `box` | — | Смещения окошка: `top`, `left` — положение, `bottom`, `right` — размер. Без ключа окошко встаёт стандартно | - -Координаты ячейки в примечании не задаются. `autoSize` и `box` независимы: при автоподгоне -размера положение окошка всё равно хранится. - -## Колонтитулы - -У верхнего и нижнего колонтитула по три слота — `left`, `center`, `right` — и общие настройки: - -```json -"header": { - "font": "мелкий", - "verticalAlignment": "Bottom", - "startPage": 2, - "left": "Слева\nвторая строка", - "center": "Стр. [&НомерСтраницы] из [&СтраницВсего]", - "right": { "ru": "Справа", "en": "Right" } -}, -"footer": { - "show": false, - "center": { "formatted": "Итог красным" } -} -``` - -| Поле | По умолч. | Описание | -|------|-----------|----------| -| `left`, `center`, `right` | — | Текст слота: строка, объект «язык → текст» или `{ "formatted": … }` | -| `font` | — | Имя шрифта из `fonts` — на весь колонтитул | -| `verticalAlignment` | — | Положение текста по вертикали: `Top`, `Center`, `Bottom` | -| `show` | `true` | Выводить ли колонтитул | -| `startPage` | `1` | Страница, с которой колонтитул печатается | - -Текст может быть многострочным (`\n`) и содержать поля `[&НомерСтраницы]`, `[&СтраницВсего]`, -`[&Дата]`, `[&Время]` — платформа подставляет их при печати. `{ "formatted": … }` — форматированная -строка: разметка живёт прямо в тексте (`жирный`, ``, ``). - -## Параметры печати - -Плоский объект; имя ключа совпадает с именем свойства в выгрузке: - -```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`, их колонки при автозаполнении пропускаются. - -## Ограничения - -DSL описывает не все конструкции табличного документа. Перечисленное ниже **теряется при -round-trip** (`/mxl-decompile` → `/mxl-compile`): в JSON оно не попадает, в сгенерированный -XML не возвращается. - -- объединения, не привязанные к ячейке (по всей высоте или ширине документа); -- настройки диаграмм (`Chart`, `GanttChart`) — сам рисунок сохраняется, его содержимое нет; -- область печати. - -Пересборка макета из DSL — это полная перегенерация, а не точечная правка XML, поэтому -diff после round-trip обычно шире фактической доработки. - -Отдельно про побайтовое совпадение. В макетах, которые долго правили в Конфигураторе, -встречаются следы прежних состояний: формат ячейки может нести ширину колонки, которая с тех -пор изменилась. Такие значения не описывают итоговый документ и из него не выводятся, поэтому -собранный XML совпадёт с исходным не всегда — при полностью сохранённом содержании. diff --git a/.claude/skills/mxl-compile/reference/groups.md b/.claude/skills/mxl-compile/reference/groups.md new file mode 100644 index 00000000..dfe48f8f --- /dev/null +++ b/.claude/skills/mxl-compile/reference/groups.md @@ -0,0 +1,26 @@ +# Группы строк и колонок + +Диапазон строк или колонок, который сворачивается кнопкой на полях. Задаются плоским списком; +вложенность выражена вхождением одного диапазона в другой: + +```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` | + +Диапазоны либо вложены, либо не пересекаются: частичное пересечение — ошибка. Порядок в списке +не важен, число уровней вложенности считается само. diff --git a/.claude/skills/mxl-compile/reference/input-cells.md b/.claude/skills/mxl-compile/reference/input-cells.md new file mode 100644 index 00000000..34142191 --- /dev/null +++ b/.claude/skills/mxl-compile/reference/input-cells.md @@ -0,0 +1,48 @@ +# Ячейки-поля ввода + +Ячейка может не показывать текст, а принимать значение от пользователя — так делают макеты для +ввода данных. Достаточно задать тип значения: + +```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`. Флажок задаётся явно. diff --git a/.claude/skills/mxl-compile/reference/layout.md b/.claude/skills/mxl-compile/reference/layout.md new file mode 100644 index 00000000..587b8f88 --- /dev/null +++ b/.claude/skills/mxl-compile/reference/layout.md @@ -0,0 +1,73 @@ +# Разметка: области координатами и колоночные раскладки + +Читать, когда область не описывается диапазоном подряд идущих строк или когда части документа нужны разные ширины колонок. + +## Именованные области координатами (`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. + +## Колоночные раскладки (`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. + +## Стиль колонки (`columnStyles`) + +Колонка несёт то же оформление, что ячейка и строка. Ключи — та же грамматика диапазонов, +что у `columnWidths`; значение — имя стиля. + +```json +"columnWidths": { "1": 30, "2-3": 15 }, +"columnStyles": { "1": "по-центру", "4": "скрытая" } +``` + +Внутри `columnSets` работает тот же ключ. Ширина и стиль независимы: колонка может иметь +только ширину, только стиль или и то, и другое. diff --git a/.claude/skills/mxl-compile/reference/notes.md b/.claude/skills/mxl-compile/reference/notes.md new file mode 100644 index 00000000..b5c29242 --- /dev/null +++ b/.claude/skills/mxl-compile/reference/notes.md @@ -0,0 +1,26 @@ +# Примечания к ячейкам + +Всплывающая подсказка, которую платформа показывает при наведении. Задаётся ключом `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`) → это описание примечания, иначе ключи +считаются идентификаторами языков. + +| Поле | По умолч. | Описание | +|------|-----------|----------| +| `text` | — | Текст подсказки: строка или объект «язык → текст» | +| `style` | стиль подсказки | Имя стиля из `styles`; без него — оформление, которое даёт Конфигуратор | +| `autoSize` | `true` | Подгонять ли размер окошка под текст | +| `box` | — | Смещения окошка: `top`, `left` — положение, `bottom`, `right` — размер. Без ключа окошко встаёт стандартно | + +Координаты ячейки в примечании не задаются. `autoSize` и `box` независимы: при автоподгоне +размера положение окошка всё равно хранится. diff --git a/.claude/skills/mxl-compile/reference/print.md b/.claude/skills/mxl-compile/reference/print.md new file mode 100644 index 00000000..96962575 --- /dev/null +++ b/.claude/skills/mxl-compile/reference/print.md @@ -0,0 +1,53 @@ +# Печать: колонтитулы и параметры страницы + +Читать, когда макет готовят к печати: повторяющиеся надписи сверху и снизу, ориентация, поля, масштаб. + +## Колонтитулы + +У верхнего и нижнего колонтитула по три слота — `left`, `center`, `right` — и общие настройки: + +```json +"header": { + "font": "мелкий", + "verticalAlignment": "Bottom", + "startPage": 2, + "left": "Слева\nвторая строка", + "center": "Стр. [&НомерСтраницы] из [&СтраницВсего]", + "right": { "ru": "Справа", "en": "Right" } +}, +"footer": { + "show": false, + "center": { "formatted": "Итог красным" } +} +``` + +| Поле | По умолч. | Описание | +|------|-----------|----------| +| `left`, `center`, `right` | — | Текст слота: строка, объект «язык → текст» или `{ "formatted": … }` | +| `font` | — | Имя шрифта из `fonts` — на весь колонтитул | +| `verticalAlignment` | — | Положение текста по вертикали: `Top`, `Center`, `Bottom` | +| `show` | `true` | Выводить ли колонтитул | +| `startPage` | `1` | Страница, с которой колонтитул печатается | + +Текст может быть многострочным (`\n`) и содержать поля `[&НомерСтраницы]`, `[&СтраницВсего]`, +`[&Дата]`, `[&Время]` — платформа подставляет их при печати. `{ "formatted": … }` — форматированная +строка: разметка живёт прямо в тексте (`жирный`, ``, ``). + +## Параметры печати + +Плоский объект; имя ключа совпадает с именем свойства в выгрузке: + +```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`. Незнакомый ключ — ошибка. Порядок в объекте не +важен: компилятор пишет свойства в том порядке, что и платформа. diff --git a/.claude/skills/mxl-compile/reference/format-properties.md b/.claude/skills/mxl-compile/reference/style-properties.md similarity index 86% rename from .claude/skills/mxl-compile/reference/format-properties.md rename to .claude/skills/mxl-compile/reference/style-properties.md index 3c18ccf5..96918d9a 100644 --- a/.claude/skills/mxl-compile/reference/format-properties.md +++ b/.claude/skills/mxl-compile/reference/style-properties.md @@ -1,7 +1,8 @@ -# Полный список свойств стиля +# Свойства стиля: полный перечень -Имя ключа совпадает с именем свойства в выгрузке — исключений нет. Частые свойства -с примерами — в `styles.md`, здесь полный перечень. +Читать, когда нужного свойства нет среди частых, описанных в SKILL.md: отступы, защита, узор, маска, формат редактирования, поведение при выводе. + +Имя ключа совпадает с именем свойства в выгрузке — исключений нет. Тип значения: @@ -57,6 +58,9 @@ ## Картинка в ячейке +Ключи ниже задают картинку внутри ячейки; сама палитра картинок и рисунки поверх сетки — +в `reference/drawings.md`. + | Ключ | Тип | Значение | |------|-----|----------| | `picIndex` | число | Номер картинки | @@ -74,4 +78,4 @@ - `containsValue`, `valueType`, `controlType` — свойства конкретной ячейки, а не общего оформления: задаются ключами ячейки `valueType` и `controlType`; - линия рисунка и её стороны — свойства рисунка: задаются его ключами `line` и `sides` - (у ячейки такого свойства нет вовсе) (см. `dsl-spec.md`). + (`reference/drawings.md`); у ячейки такого свойства нет вовсе. diff --git a/.claude/skills/mxl-compile/reference/styles.md b/.claude/skills/mxl-compile/reference/styles.md deleted file mode 100644 index 5974a890..00000000 --- a/.claude/skills/mxl-compile/reference/styles.md +++ /dev/null @@ -1,147 +0,0 @@ -# Оформление: шрифты, стили, колонки - -Оформление в табличном документе — одна сущность на всех: ячейка, строка и колонка ссылаются -на один и тот же именованный стиль. Ячейка — ключом `style`, строка — `rowStyle`, колонка — -через `columnStyles`. - -## Шрифты (`fonts.`) - -| Поле | По умолч. | Описание | -|------|-----------|----------| -| `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.`) - -Ключ стиля — имя свойства так, как оно называется в выгрузке. Ниже частые; полный список -из 44 свойств — в `format-properties.md`. - -| Поле | Описание | -|------|----------| -| `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 } } -``` - -## Колоночные раскладки (`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. - -## Стиль колонки (`columnStyles`) - -Колонка несёт то же оформление, что ячейка и строка. Ключи — та же грамматика диапазонов, -что у `columnWidths`; значение — имя стиля. - -```json -"columnWidths": { "1": 30, "2-3": 15 }, -"columnStyles": { "1": "по-центру", "4": "скрытая" } -``` - -Внутри `columnSets` работает тот же ключ. Ширина и стиль независимы: колонка может иметь -только ширину, только стиль или и то, и другое. diff --git a/.claude/skills/mxl-decompile/SKILL.md b/.claude/skills/mxl-decompile/SKILL.md index 9faf7bc1..a232571b 100644 --- a/.claude/skills/mxl-decompile/SKILL.md +++ b/.claude/skills/mxl-decompile/SKILL.md @@ -41,4 +41,24 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-decompile.ps1" 3. Вызвать `/mxl-compile` для генерации нового Template.xml 4. Вызвать `/mxl-validate` для проверки -Формат JSON на выходе — тот же DSL, что принимает `/mxl-compile`; его полное описание живёт в навыке `/mxl-compile`. +Формат JSON на выходе — тот же DSL, что принимает `/mxl-compile`; его описание живёт в навыке `/mxl-compile`. + +## Что нужно знать о пересборке + +Правка через DSL — это полная перегенерация макета, а не точечное изменение XML. Поэтому +diff после цикла «декомпиляция → компиляция» обычно шире фактической доработки, даже когда +содержание сохранено целиком. + +Побайтового совпадения с исходником ждать не всегда стоит. В макетах, которые долго правили +в Конфигураторе, остаются следы прежних состояний: например, формат ячейки несёт ширину +колонки, которая с тех пор изменилась. Из итогового документа такие значения не выводятся, +и в пересобранный файл они не возвращаются. + +Не переживают цикл вовсе (в JSON не попадают, в XML не возвращаются): + +- объединения, не привязанные к ячейке — по всей высоте или ширине документа; +- настройки диаграмм (`Chart`, `GanttChart`) — сам рисунок сохраняется, его содержимое нет; +- область печати. + +Если задача — сохранить чужой макет как есть и поправить в нём малое, сверяйте результат +`/mxl-info` или diff-ом: перечисленное выше нужно вернуть руками.