mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-17 16:50:30 +03:00
feat(mxl-compile,mxl-decompile): рисунки и палитра картинок
Рисунок поверх сетки — картинка, фигура, надпись — теперь описывается в DSL и возвращается из макета: два якоря «ячейка + смещение», тип, ссылка на картинку, надпись, расшифровка, имя, порядок перекрытия. Оформление рисунка разложено надвое: общее (заливка, шрифт, выравнивание) берётся из именованного стиля, а линия и её стороны — собственные ключи рисунка. У ячейки таких свойств не бывает: все 2 135 записей палитры с ними принадлежат рисункам. Палитра картинок: ссылка на библиотеку платформы, данные base64, пустая запись «картинка не задана» (151 в корпусе) и координата пикселя прозрачного цвета (tx/ty — проверено, это не размеры картинки). Заодно: висячий пустой колонтитул в ps1-порте (пустой словарь в PowerShell истинен, порты расходились на 3 макетах из 40) и проверка индекса формата рисунка в mxl-validate. Стенды Рисунки, Рисунки2, КартинкаВЯчейке проходят раундтрип байт в байт в обоих портах; на 35 корпусных макетах с рисунками расхождение сократилось у всех 35.
This commit is contained in:
@@ -66,7 +66,10 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-compile.ps1" -J
|
||||
columnGroups: [{ cols, name, collapsed, titleLocation }],
|
||||
header: { left, center, right, font, verticalAlignment, show, startPage }, footer: { … },
|
||||
printSettings: { pageOrientation, topMargin, …, fitToPage, firstPageNumber },
|
||||
columnSets: { name: { columns, columnWidths, columnStyles } }
|
||||
columnSets: { name: { columns, columnWidths, columnStyles } },
|
||||
pictures: { name: { ref } | { data, transparent, transparentPixel } | {} },
|
||||
drawings: [{ type, begin: { row, col, dy, dx }, end: { … }, picture, pictureSize,
|
||||
text, name, detail, style, line, sides, id, zOrder }]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -87,6 +90,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-compile.ps1" -J
|
||||
- `rowGroups`/`columnGroups` — группы строк и колонок (сворачиваются кнопкой на полях): плоский список диапазонов, вложенность выражена вхождением одного в другой
|
||||
- `header`/`footer` — колонтитулы: три слота (`left`/`center`/`right`), общий шрифт и вертикальное выравнивание; текст может нести поля `[&НомерСтраницы]`, `[&Дата]`
|
||||
- `note` — всплывающая подсказка у ячейки: строка, объект языков или `{ text, style, autoSize, box }`
|
||||
- `drawings` — рисунки поверх сетки (картинка, фигура, надпись): положение задают два якоря «ячейка + смещение в точках», картинка берётся по имени из `pictures`
|
||||
- `valueType` делает ячейку полем ввода (`"Number(15,3,nonneg)"`, `"String(10)"`, `"CatalogRef.Валюты"`, составной через ` + `); текста в такой ячейке быть не может, значение задаётся ключом `value`
|
||||
|
||||
Двухуровневая шапка массивами:
|
||||
|
||||
@@ -91,6 +91,8 @@
|
||||
| `columnGroups` | нет | — | Группы колонок (см. ниже) |
|
||||
| `header` / `footer` | нет | — | Верхний и нижний колонтитулы (см. ниже) |
|
||||
| `printSettings` | нет | — | Параметры печати (см. ниже) |
|
||||
| `pictures` | нет | — | Палитра картинок: ссылки на библиотеку платформы или данные (см. ниже) |
|
||||
| `drawings` | нет | — | Рисунки: картинки, фигуры, надписи (см. ниже) |
|
||||
|
||||
## Области (`areas[]`)
|
||||
|
||||
@@ -376,6 +378,54 @@
|
||||
Диапазоны либо вложены, либо не пересекаются: частичное пересечение — ошибка. Порядок в списке
|
||||
не важен, число уровней вложенности считается само.
|
||||
|
||||
## Рисунки и картинки
|
||||
|
||||
Рисунок — объект поверх сетки ячеек: картинка, фигура или надпись. Его положение задают два
|
||||
якоря: ячейка плюс смещение в точках от её левого верхнего угла.
|
||||
|
||||
```json
|
||||
"pictures": {
|
||||
"знак": { "ref": "v8ui:Стоп48" },
|
||||
"логотип": { "data": "iVBORw0KGgo...", "transparent": false }
|
||||
},
|
||||
"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`). Пустая запись `{}` — картинка не задана, такое в макетах встречается.
|
||||
С данными сочетаются `transparent` (прозрачность включена) и `transparentPixel`
|
||||
(`{ "x": …, "y": … }` — координата пикселя, чей цвет считается прозрачным).
|
||||
|
||||
Одну запись `pictures` могут использовать несколько рисунков — данные в макете не дублируются.
|
||||
|
||||
## `rowStyle` — оформление строки
|
||||
|
||||
Стиль применяется ко ВСЕЙ ширине строки: позиции без явных ячеек получают тот же стиль. Так в табличных строках получаются сплошные рамки. Он же становится оформлением самой строки — именно так платформа хранит строку, оформленную целиком.
|
||||
@@ -391,7 +441,7 @@ round-trip** (`/mxl-decompile` → `/mxl-compile`): в JSON оно не попа
|
||||
XML не возвращается.
|
||||
|
||||
- объединения, не привязанные к ячейке (по всей высоте или ширине документа);
|
||||
- рисунки и картинки, в том числе штрихкоды;
|
||||
- настройки диаграмм (`Chart`, `GanttChart`) — сам рисунок сохраняется, его содержимое нет;
|
||||
- область печати.
|
||||
|
||||
Пересборка макета из DSL — это полная перегенерация, а не точечная правка XML, поэтому
|
||||
|
||||
@@ -64,8 +64,6 @@
|
||||
| `picHorizontalAlignment` | перечисление | `Auto`, `Center`, `Left`, `Right` |
|
||||
| `picVerticalAlignment` | перечисление | `Top`, `Center`, `Bottom` |
|
||||
| `textPosition` | перечисление | Положение текста относительно картинки: `Auto`, `Top`, `Right`, `Bottom` |
|
||||
| `drawingBorder` | число | Рамка рисунка |
|
||||
| `drawingHaveLeftBorder`, `drawingHaveTopBorder`, `drawingHaveRightBorder`, `drawingHaveBottomBorder` | да/нет | Наличие стороны рамки рисунка |
|
||||
|
||||
## Чего в стиле нет
|
||||
|
||||
@@ -74,4 +72,6 @@
|
||||
- `fillType` — выводится из того, каким ключом задано содержимое ячейки
|
||||
(`text` / `param` / `template`);
|
||||
- `containsValue`, `valueType`, `controlType` — свойства конкретной ячейки, а не общего
|
||||
оформления: задаются ключами ячейки `valueType` и `controlType` (см. `dsl-spec.md`).
|
||||
оформления: задаются ключами ячейки `valueType` и `controlType`;
|
||||
- линия рисунка и её стороны — свойства рисунка: задаются его ключами `line` и `sides`
|
||||
(у ячейки такого свойства нет вовсе) (см. `dsl-spec.md`).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# mxl-compile v1.47 — Compile 1C spreadsheet from JSON
|
||||
# mxl-compile v1.48 — Compile 1C spreadsheet from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -287,11 +287,15 @@ if (-not $hasDefault) {
|
||||
$script:lineRegistry = @()
|
||||
|
||||
function Get-LineKey {
|
||||
# Вид линии входит в ключ: одинаковые по стилю линии рамки ячейки и рисунка — РАЗНЫЕ записи,
|
||||
# у них разный xsi:type.
|
||||
param($ln)
|
||||
return "$($ln.Style)|$($ln.Width)|$($ln.Gap)"
|
||||
return "$($ln.Style)|$($ln.Width)|$($ln.Gap)|$($ln.Kind)"
|
||||
}
|
||||
|
||||
function Register-Line {
|
||||
# Запись палитры линий типизирована: у рамки ячейки xsi:type Cell, у линии рисунка Drawing.
|
||||
# Вид выводится из свойства, которое на линию ссылается, — отдельного ключа в DSL не нужно.
|
||||
param($ln)
|
||||
$key = Get-LineKey $ln
|
||||
for ($i = 0; $i -lt $script:lineRegistry.Count; $i++) {
|
||||
@@ -589,7 +593,11 @@ function Resolve-Style {
|
||||
continue
|
||||
}
|
||||
switch ($kinds[$tag]) {
|
||||
'line' { $props[$tag] = Register-Line (ConvertTo-LineValue $val $where) }
|
||||
'line' {
|
||||
$lnVal = ConvertTo-LineValue $val $where
|
||||
$lnVal['Kind'] = if ($tag -ceq 'drawingBorder') { 'Drawing' } else { 'Cell' }
|
||||
$props[$tag] = Register-Line $lnVal
|
||||
}
|
||||
'bool' { $props[$tag] = if ($val -eq $true -or "$val" -eq 'true') { 'true' } else { 'false' } }
|
||||
'int' { $props[$tag] = [int]$val }
|
||||
'enum' {
|
||||
@@ -1023,15 +1031,15 @@ function Get-FormatMlTags {
|
||||
# line — ссылка в палитру <line>; color — #RRGGBB / style: / web: / win:
|
||||
# ml — многоязычная строка; enum — замкнутый список (см. Get-FormatEnumValues)
|
||||
# containsValue / valueType / controlType сюда НЕ входят: это свойства конкретной ячейки,
|
||||
# а стиль — сущность общая, один на многие ячейки.
|
||||
# а стиль — сущность общая, один на многие ячейки. По той же причине здесь нет линии рисунка
|
||||
# (drawingBorder, drawingHave*Border): на корпусе все 2 135 записей с ними принадлежат только
|
||||
# рисункам, у ячейки такого свойства не бывает — они задаются ключами самого рисунка.
|
||||
function Get-FormatTagKind {
|
||||
return @{
|
||||
'autoIndent' = 'int'; 'autoMarkIncomplete' = 'bool'; 'autoWidthCalculation' = 'bool'
|
||||
'backColor' = 'color'; 'border' = 'line'; 'borderColor' = 'color'
|
||||
'bottomBorder' = 'line'; 'bySelectedColumns' = 'bool'; 'columnSizeChange' = 'enum'
|
||||
'detailsUse' = 'enum'; 'drawingBorder' = 'int'
|
||||
'drawingHaveBottomBorder' = 'bool'; 'drawingHaveLeftBorder' = 'bool'
|
||||
'drawingHaveRightBorder' = 'bool'; 'drawingHaveTopBorder' = 'bool'
|
||||
'detailsUse' = 'enum'
|
||||
'editFormat' = 'ml'; 'fillType' = 'enum'; 'font' = 'int'; 'format' = 'ml'
|
||||
'height' = 'int'; 'hidden' = 'bool'; 'horizontalAlignment' = 'enum'
|
||||
'hyperLink' = 'bool'; 'indent' = 'int'; 'leftBorder' = 'line'
|
||||
@@ -1582,6 +1590,100 @@ function Emit-PrintSettings {
|
||||
X "`t</printSettings>"
|
||||
}
|
||||
|
||||
# Палитра картинок. Ресурс хранится двумя способами: ссылкой на библиотеку платформы
|
||||
# (ref="v8ui:Имя") либо данными base64 прямо в макете (9 905 из 9 988 картинок корпуса).
|
||||
# На неё ссылаются и рисунки (pictureIndex), и ячейки (picIndex в стиле) — индекс 1-based.
|
||||
$pictureNames = @{} # имя из DSL → 1-based индекс
|
||||
$pictureEntries = @()
|
||||
|
||||
if ($def.pictures) {
|
||||
foreach ($pr in $def.pictures.PSObject.Properties) {
|
||||
# Пустая запись — законная картинка «не задана»: в корпусе таких 151, ровно по одной
|
||||
# на макет. Ошибкой считаем только запись с непонятным содержимым.
|
||||
$entry = @{ Ref = ''; Data = ''; Transparent = ''; PixelX = ''; PixelY = '' }
|
||||
if ($pr.Value.ref) { $entry.Ref = "$($pr.Value.ref)" }
|
||||
if ($null -ne $pr.Value.data) { $entry.Data = "$($pr.Value.data)" }
|
||||
if ($null -ne $pr.Value.transparent) {
|
||||
$entry.Transparent = if ($pr.Value.transparent -eq $true -or "$($pr.Value.transparent)" -eq 'true') { 'true' } else { 'false' }
|
||||
}
|
||||
if ($null -ne $pr.Value.transparentPixel) {
|
||||
$entry.PixelX = "$([int]$pr.Value.transparentPixel.x)"
|
||||
$entry.PixelY = "$([int]$pr.Value.transparentPixel.y)"
|
||||
}
|
||||
if (-not $entry.Ref -and -not $entry.Data -and
|
||||
($entry.Transparent -or $entry.PixelX)) {
|
||||
[Console]::Error.WriteLine("pictures[$($pr.Name)]: 'transparent' and 'transparentPixel' require 'data'")
|
||||
exit 1
|
||||
}
|
||||
$pictureEntries += $entry
|
||||
$pictureNames[$pr.Name] = $pictureEntries.Count
|
||||
}
|
||||
}
|
||||
|
||||
# Рисунки: своя геометрия из двух якорей, тип, ссылка на картинку, текст, расшифровка.
|
||||
# id и zOrder — данные, а не позиция: на корпусе они расходятся у 8 253 рисунков из 11 268.
|
||||
$drawingTypes = @('Picture', 'Rectangle', 'Ellipse', 'Line', 'Text', 'Chart', 'GanttChart')
|
||||
$drawings = @()
|
||||
$drawingIdx = 0
|
||||
foreach ($dr in $def.drawings) {
|
||||
$drawingIdx++
|
||||
$where = "drawings[$drawingIdx]"
|
||||
$type = if ($dr.type) { "$($dr.type)" } else { 'Picture' }
|
||||
$canonType = @($drawingTypes | Where-Object { $_ -eq $type })[0]
|
||||
if (-not $canonType) {
|
||||
[Console]::Error.WriteLine("${where}: unknown drawing 'type' `"$type`". Allowed: $($drawingTypes -join ', ')")
|
||||
exit 1
|
||||
}
|
||||
$picIdx = 0
|
||||
if ($dr.picture) {
|
||||
if (-not $pictureNames.ContainsKey("$($dr.picture)")) {
|
||||
[Console]::Error.WriteLine("${where}: unknown 'picture' `"$($dr.picture)`" — not declared in pictures")
|
||||
exit 1
|
||||
}
|
||||
$picIdx = $pictureNames["$($dr.picture)"]
|
||||
}
|
||||
# Оформление рисунка: общее — из именованного стиля, чисто рисуночное (линия и её стороны)
|
||||
# — своими ключами, поверх стиля. Тот же приём, что у ячейки с fillType и значением.
|
||||
$props = @{}
|
||||
if ($dr.style) { $props = Resolve-Style -styleName "$($dr.style)" -fillType "" }
|
||||
if ($null -ne $dr.line) {
|
||||
$lnVal = ConvertTo-LineValue $dr.line $where
|
||||
$lnVal['Kind'] = 'Drawing'
|
||||
$props['drawingBorder'] = Register-Line $lnVal
|
||||
}
|
||||
foreach ($side in @('left', 'top', 'right', 'bottom')) {
|
||||
$v = $dr.sides.$side
|
||||
if ($null -ne $v) {
|
||||
$tag = 'drawingHave' + $side.Substring(0,1).ToUpperInvariant() + $side.Substring(1) + 'Border'
|
||||
$props[$tag] = if ($v -eq $true -or "$v" -eq 'true') { 'true' } else { 'false' }
|
||||
}
|
||||
}
|
||||
$fmtIdx = 0
|
||||
if ($props.Count -gt 0) { $fmtIdx = Register-Format $props }
|
||||
function Get-Anchor {
|
||||
param($node, [string]$rowKey, [string]$colKey)
|
||||
return @{
|
||||
Row = if ($node -and $null -ne $node.row) { [int]$node.row - 1 } else { 0 }
|
||||
Col = if ($node -and $null -ne $node.col) { [int]$node.col - 1 } else { 0 }
|
||||
Dy = if ($node -and $null -ne $node.dy) { [int]$node.dy } else { 0 }
|
||||
Dx = if ($node -and $null -ne $node.dx) { [int]$node.dx } else { 0 }
|
||||
}
|
||||
}
|
||||
$drawings += @{
|
||||
Type = $canonType
|
||||
Id = if ($null -ne $dr.id) { [int]$dr.id } else { $drawingIdx }
|
||||
ZOrder = if ($null -ne $dr.zOrder) { [int]$dr.zOrder } else { $drawingIdx }
|
||||
FormatIdx = $fmtIdx
|
||||
Detail = $dr.detail
|
||||
Text = $dr.text
|
||||
Begin = Get-Anchor $dr.begin
|
||||
End = Get-Anchor $dr.end
|
||||
PictureSize = if ($dr.pictureSize) { "$($dr.pictureSize)" } else { 'Stretch' }
|
||||
PictureIdx = $picIdx
|
||||
Name = $dr.name
|
||||
}
|
||||
}
|
||||
|
||||
# Формат по умолчанию — последняя запись палитры (см. выше).
|
||||
$defaultFormatIndex = Register-Format @{ width = $defaultWidth }
|
||||
|
||||
@@ -2173,6 +2275,47 @@ if ($def.namedAreas) {
|
||||
}
|
||||
}
|
||||
|
||||
# 7d-bis2. Рисунки идут сразу после строк, до колонтитулов. Порядок тегов снят с корпуса:
|
||||
# у всех 11 268 рисунков он один и тот же.
|
||||
foreach ($dr in $drawings) {
|
||||
X "`t<drawing>"
|
||||
X "`t`t<drawingType>$($dr.Type)</drawingType>"
|
||||
X "`t`t<id>$($dr.Id)</id>"
|
||||
X "`t`t<formatIndex>$($dr.FormatIdx)</formatIndex>"
|
||||
if ($dr.Detail) { X "`t`t<detailParameter>$($dr.Detail)</detailParameter>" }
|
||||
if ($null -ne $dr.Text) {
|
||||
$pairs = @()
|
||||
if ($dr.Text -is [System.Management.Automation.PSCustomObject]) {
|
||||
foreach ($pr in $dr.Text.PSObject.Properties) { $pairs += @{ Lang = $pr.Name; Text = "$($pr.Value)" } }
|
||||
} else {
|
||||
foreach ($l in $textLanguages) { $pairs += @{ Lang = $l; Text = "$($dr.Text)" } }
|
||||
}
|
||||
X "`t`t<text>"
|
||||
foreach ($pr in $pairs) {
|
||||
X "`t`t`t<v8:item>"
|
||||
X "`t`t`t`t<v8:lang>$($pr.Lang)</v8:lang>"
|
||||
X "`t`t`t`t<v8:content>$(Esc-XmlText $pr.Text)</v8:content>"
|
||||
X "`t`t`t</v8:item>"
|
||||
}
|
||||
X "`t`t</text>"
|
||||
}
|
||||
X "`t`t<beginRow>$($dr.Begin.Row)</beginRow>"
|
||||
X "`t`t<beginRowOffset>$($dr.Begin.Dy)</beginRowOffset>"
|
||||
X "`t`t<endRow>$($dr.End.Row)</endRow>"
|
||||
X "`t`t<endRowOffset>$($dr.End.Dy)</endRowOffset>"
|
||||
X "`t`t<beginColumn>$($dr.Begin.Col)</beginColumn>"
|
||||
X "`t`t<beginColumnOffset>$($dr.Begin.Dx)</beginColumnOffset>"
|
||||
X "`t`t<endColumn>$($dr.End.Col)</endColumn>"
|
||||
X "`t`t<endColumnOffset>$($dr.End.Dx)</endColumnOffset>"
|
||||
# autoSize у рисунка на корпусе всегда false (11 268 из 11 268), «АвтоРазмер» из
|
||||
# диалога уходит в pictureSize.
|
||||
X "`t`t<autoSize>false</autoSize>"
|
||||
X "`t`t<pictureSize>$($dr.PictureSize)</pictureSize>"
|
||||
X "`t`t<zOrder>$($dr.ZOrder)</zOrder>"
|
||||
if ($dr.PictureIdx -gt 0) { X "`t`t<pictureIndex>$($dr.PictureIdx)</pictureIndex>" }
|
||||
X "`t</drawing>"
|
||||
}
|
||||
|
||||
# 7d-ter. Колонтитулы: шесть слотов идут после строк и перед скалярными свойствами документа.
|
||||
foreach ($slot in $script:headerSlots) {
|
||||
if ($def.header) { Emit-HeaderSlot "$($slot)Header" $def.header.$slot $headerFmt }
|
||||
@@ -2294,9 +2437,15 @@ $colGroups = Get-Groups 'columnGroups' 'cols'
|
||||
# 7e. Scalar metadata
|
||||
X "`t<templateMode>true</templateMode>"
|
||||
X "`t<defaultFormatIndex>$defaultFormatIndex</defaultFormatIndex>"
|
||||
X "`t<height>$totalRowCount</height>"
|
||||
# Рисунок расширяет документ, не создавая строк: на стендах высота равна нижней границе
|
||||
# самого нижнего рисунка, при том что строк записана всего одна.
|
||||
$docHeight = $totalRowCount
|
||||
foreach ($dr in $drawings) {
|
||||
if (($dr.End.Row + 1) -gt $docHeight) { $docHeight = $dr.End.Row + 1 }
|
||||
}
|
||||
X "`t<height>$docHeight</height>"
|
||||
if ($rowGroups.Count -gt 0) { X "`t<vgLevels>$(Get-GroupLevels $rowGroups)</vgLevels>" }
|
||||
X "`t<vgRows>$totalRowCount</vgRows>"
|
||||
X "`t<vgRows>$docHeight</vgRows>"
|
||||
Emit-Groups 'vg' $rowGroups
|
||||
Emit-Groups 'hg' $colGroups
|
||||
|
||||
@@ -2324,8 +2473,20 @@ function Get-OrdinalKey {
|
||||
param([string]$name)
|
||||
return (($name.ToLowerInvariant().ToCharArray() | ForEach-Object { '{0:X4}' -f [int]$_ }) -join '')
|
||||
}
|
||||
# Имя рисунка — namedItem другого типа, но список общий: на корпусе оба вида отсортированы
|
||||
# вместе по имени во всех 266 макетах с именованными рисунками.
|
||||
foreach ($dr in $drawings) {
|
||||
if ($dr.Name) { $namedItems += @{ Name = "$($dr.Name)"; DrawingId = $dr.Id } }
|
||||
}
|
||||
$sortedNamedItems = @($namedItems | Sort-Object -Property @{ Expression = { Get-OrdinalKey $_.Name } })
|
||||
foreach ($ni in $sortedNamedItems) {
|
||||
if ($ni.DrawingId) {
|
||||
X "`t<namedItem xsi:type=`"NamedItemDrawing`">"
|
||||
X "`t`t<name>$($ni.Name)</name>"
|
||||
X "`t`t<drawingID>$($ni.DrawingId)</drawingID>"
|
||||
X "`t</namedItem>"
|
||||
continue
|
||||
}
|
||||
# Тип области выводится из указанных осей, как в ТабличныйДокумент.Область():
|
||||
# нет колонок → полоса строк, нет строк → полоса колонок, обе → прямоугольник.
|
||||
$hasRows = $ni.BeginRow -ge 0
|
||||
@@ -2347,7 +2508,8 @@ foreach ($ni in $sortedNamedItems) {
|
||||
# 7h. Line palette
|
||||
foreach ($ln in $script:lineRegistry) {
|
||||
X "`t<line width=`"$($ln.Width)`" gap=`"$($ln.Gap)`">"
|
||||
X "`t`t<v8ui:style xsi:type=`"v8ui:SpreadsheetDocumentCellLineType`">$($ln.Style)</v8ui:style>"
|
||||
$lineKind = if ($ln.Kind -ceq 'Drawing') { 'SpreadsheetDocumentDrawingLineType' } else { 'SpreadsheetDocumentCellLineType' }
|
||||
X "`t`t<v8ui:style xsi:type=`"v8ui:$lineKind`">$($ln.Style)</v8ui:style>"
|
||||
X "`t</line>"
|
||||
}
|
||||
|
||||
@@ -2404,7 +2566,31 @@ foreach ($key in $formatRegistry.Keys) {
|
||||
X "`t</format>"
|
||||
}
|
||||
|
||||
# 7k. Close document
|
||||
# 7k. Палитра картинок — последний блок документа. Индекс здесь 0-based, а ссылки
|
||||
# на него (pictureIndex рисунка, picIndex стиля) 1-based.
|
||||
$picIdx = 0
|
||||
foreach ($pic in $pictureEntries) {
|
||||
X "`t<picture>"
|
||||
X "`t`t<index>$picIdx</index>"
|
||||
if ($pic.Ref) {
|
||||
X "`t`t<picture ref=`"$(Esc-Xml $pic.Ref)`"/>"
|
||||
} elseif (-not $pic.Data) {
|
||||
X "`t`t<picture/>"
|
||||
} else {
|
||||
$attr = if ($pic.Transparent) { " t=`"$($pic.Transparent)`"" } else { '' }
|
||||
if ($pic.PixelX) { $attr += " tx=`"$($pic.PixelX)`" ty=`"$($pic.PixelY)`"" }
|
||||
# Данные платформа переносит по строкам тем же переводом, что и весь файл, —
|
||||
# в отличие от блоба настроек элемента управления, где перенос голый LF.
|
||||
$parts = @("$($pic.Data)" -split "`r?`n")
|
||||
$parts[0] = "`t`t<picture$attr>$($parts[0])"
|
||||
$parts[-1] = "$($parts[-1])</picture>"
|
||||
foreach ($line in $parts) { X $line }
|
||||
}
|
||||
X "`t</picture>"
|
||||
$picIdx++
|
||||
}
|
||||
|
||||
# 7l. Close document
|
||||
X '</document>'
|
||||
|
||||
# --- 8. Write output ---
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-compile v1.47 — Compile 1C spreadsheet from JSON
|
||||
# mxl-compile v1.48 — Compile 1C spreadsheet from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import hashlib
|
||||
@@ -355,14 +355,14 @@ def format_tag_kind():
|
||||
line — ссылка в палитру <line>; color — #RRGGBB / style: / web: / win:
|
||||
ml — многоязычная строка; enum — замкнутый список (см. format_enum_values).
|
||||
containsValue / valueType / controlType сюда НЕ входят: это свойства конкретной ячейки,
|
||||
а стиль — сущность общая, один на многие ячейки."""
|
||||
а стиль — сущность общая, один на многие ячейки. По той же причине здесь нет линии рисунка
|
||||
(drawingBorder, drawingHave*Border): на корпусе все 2 135 записей с ними принадлежат только
|
||||
рисункам, у ячейки такого свойства не бывает — они задаются ключами самого рисунка."""
|
||||
return {
|
||||
'autoIndent': 'int', 'autoMarkIncomplete': 'bool', 'autoWidthCalculation': 'bool',
|
||||
'backColor': 'color', 'border': 'line', 'borderColor': 'color',
|
||||
'bottomBorder': 'line', 'bySelectedColumns': 'bool', 'columnSizeChange': 'enum',
|
||||
'detailsUse': 'enum', 'drawingBorder': 'int',
|
||||
'drawingHaveBottomBorder': 'bool', 'drawingHaveLeftBorder': 'bool',
|
||||
'drawingHaveRightBorder': 'bool', 'drawingHaveTopBorder': 'bool',
|
||||
'detailsUse': 'enum',
|
||||
'editFormat': 'ml', 'fillType': 'enum', 'font': 'int', 'format': 'ml',
|
||||
'height': 'int', 'hidden': 'bool', 'horizontalAlignment': 'enum',
|
||||
'hyperLink': 'bool', 'indent': 'int', 'leftBorder': 'line',
|
||||
@@ -382,8 +382,8 @@ def format_enum_values():
|
||||
'detailsUse': ['Cell', 'Row', 'WithoutProcessing'],
|
||||
'fillType': ['Parameter', 'Template', 'Text'],
|
||||
'horizontalAlignment': ['Auto', 'Center', 'Justify', 'Left', 'Right'],
|
||||
'pattern': ['Pattern7', 'Pattern10', 'Pattern12', 'Pattern13', 'Pattern14',
|
||||
'Pattern16', 'Solid', 'WithoutPattern'],
|
||||
# Узоры платформа нумерует подряд, без семантических имён: «Узор 1» … «Узор 17».
|
||||
'pattern': ['WithoutPattern', 'Solid', 'Pattern1', 'Pattern2', 'Pattern3', 'Pattern4', 'Pattern5', 'Pattern6', 'Pattern7', 'Pattern8', 'Pattern9', 'Pattern10', 'Pattern11', 'Pattern12', 'Pattern13', 'Pattern14', 'Pattern15', 'Pattern16', 'Pattern17'],
|
||||
'picHorizontalAlignment': ['Auto', 'Center', 'Left', 'Right'],
|
||||
'picVerticalAlignment': ['Bottom', 'Center', 'Top'],
|
||||
'pictureSizeMode': ['AutoSize', 'Proportionally', 'RealSize'],
|
||||
@@ -872,9 +872,12 @@ def main():
|
||||
line_registry = []
|
||||
|
||||
def register_line(ln):
|
||||
key = (ln['Style'], str(ln['Width']), ln['Gap'])
|
||||
# Запись палитры линий типизирована: у рамки ячейки xsi:type Cell, у линии рисунка
|
||||
# Drawing. Вид входит в ключ, иначе одинаковые по стилю линии двух видов слились бы.
|
||||
key = (ln['Style'], str(ln['Width']), ln['Gap'], ln.get('Kind', 'Cell'))
|
||||
for i, existing in enumerate(line_registry):
|
||||
if (existing['Style'], str(existing['Width']), existing['Gap']) == key:
|
||||
if (existing['Style'], str(existing['Width']), existing['Gap'],
|
||||
existing.get('Kind', 'Cell')) == key:
|
||||
return i
|
||||
line_registry.append(ln)
|
||||
return len(line_registry) - 1
|
||||
@@ -1122,7 +1125,9 @@ def main():
|
||||
continue
|
||||
kind = kinds[tag]
|
||||
if kind == 'line':
|
||||
props[tag] = register_line(to_line_value(val, where))
|
||||
ln_val = to_line_value(val, where)
|
||||
ln_val['Kind'] = 'Drawing' if tag == 'drawingBorder' else 'Cell'
|
||||
props[tag] = register_line(ln_val)
|
||||
elif kind == 'bool':
|
||||
props[tag] = 'true' if (val is True or str(val) == 'true') else 'false'
|
||||
elif kind == 'int':
|
||||
@@ -1542,6 +1547,87 @@ def main():
|
||||
lines.extend(emitted)
|
||||
lines.append('\t</printSettings>')
|
||||
|
||||
# Палитра картинок. Ресурс хранится двумя способами: ссылкой на библиотеку платформы
|
||||
# (ref="v8ui:Имя") либо данными base64 прямо в макете (9 905 из 9 988 картинок корпуса).
|
||||
# На неё ссылаются и рисунки (pictureIndex), и ячейки (picIndex в стиле) — индекс 1-based.
|
||||
picture_names = {}
|
||||
picture_entries = []
|
||||
for pic_name, pic_def in (defn.get('pictures') or {}).items():
|
||||
# Пустая запись — законная картинка «не задана»: в корпусе таких 151, ровно по одной
|
||||
# на макет. Ошибкой считаем только запись с непонятным содержимым.
|
||||
entry = {'Ref': '', 'Data': '', 'Transparent': '', 'PixelX': '', 'PixelY': ''}
|
||||
if pic_def.get('ref'):
|
||||
entry['Ref'] = str(pic_def['ref'])
|
||||
if pic_def.get('data') is not None:
|
||||
entry['Data'] = str(pic_def['data'])
|
||||
if pic_def.get('transparent') is not None:
|
||||
entry['Transparent'] = 'true' if (pic_def['transparent'] is True
|
||||
or str(pic_def['transparent']).lower() == 'true') else 'false'
|
||||
if pic_def.get('transparentPixel') is not None:
|
||||
entry['PixelX'] = str(int(pic_def['transparentPixel'].get('x', 0)))
|
||||
entry['PixelY'] = str(int(pic_def['transparentPixel'].get('y', 0)))
|
||||
if not entry['Ref'] and not entry['Data'] and (entry['Transparent'] or entry['PixelX']):
|
||||
print(f"pictures[{pic_name}]: 'transparent' and 'transparentPixel' require 'data'", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
picture_entries.append(entry)
|
||||
picture_names[pic_name] = len(picture_entries)
|
||||
|
||||
# Рисунки: своя геометрия из двух якорей, тип, ссылка на картинку, текст, расшифровка.
|
||||
# id и zOrder — данные, а не позиция: на корпусе они расходятся у 8 253 рисунков из 11 268.
|
||||
DRAWING_TYPES = ('Picture', 'Rectangle', 'Ellipse', 'Line', 'Text', 'Chart', 'GanttChart')
|
||||
|
||||
def drawing_anchor(node):
|
||||
node = node or {}
|
||||
return {
|
||||
'Row': int(node['row']) - 1 if node.get('row') is not None else 0,
|
||||
'Col': int(node['col']) - 1 if node.get('col') is not None else 0,
|
||||
'Dy': int(node['dy']) if node.get('dy') is not None else 0,
|
||||
'Dx': int(node['dx']) if node.get('dx') is not None else 0,
|
||||
}
|
||||
|
||||
drawings = []
|
||||
for idx, dr in enumerate(defn.get('drawings') or [], start=1):
|
||||
where = f'drawings[{idx}]'
|
||||
dtype = str(dr.get('type') or 'Picture')
|
||||
canon_type = next((t for t in DRAWING_TYPES if t.lower() == dtype.lower()), None)
|
||||
if canon_type is None:
|
||||
print(f'{where}: unknown drawing \'type\' "{dtype}". Allowed: {", ".join(DRAWING_TYPES)}',
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
pic_idx = 0
|
||||
if dr.get('picture'):
|
||||
if str(dr['picture']) not in picture_names:
|
||||
print(f'{where}: unknown \'picture\' "{dr["picture"]}" — not declared in pictures',
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
pic_idx = picture_names[str(dr['picture'])]
|
||||
# Оформление рисунка: общее — из именованного стиля, чисто рисуночное (линия и её
|
||||
# стороны) — своими ключами, поверх стиля. Тот же приём, что у ячейки с fillType.
|
||||
props = resolve_style(str(dr['style']), '') if dr.get('style') else {}
|
||||
if dr.get('line') is not None:
|
||||
ln_val = to_line_value(dr['line'], where)
|
||||
ln_val['Kind'] = 'Drawing'
|
||||
props['drawingBorder'] = register_line(ln_val)
|
||||
for side in ('left', 'top', 'right', 'bottom'):
|
||||
v = (dr.get('sides') or {}).get(side)
|
||||
if v is not None:
|
||||
tag = 'drawingHave' + side.capitalize() + 'Border'
|
||||
props[tag] = 'true' if (v is True or str(v).lower() == 'true') else 'false'
|
||||
fmt_idx = register_format(props) if props else 0
|
||||
drawings.append({
|
||||
'Type': canon_type,
|
||||
'Id': int(dr['id']) if dr.get('id') is not None else idx,
|
||||
'ZOrder': int(dr['zOrder']) if dr.get('zOrder') is not None else idx,
|
||||
'FormatIdx': fmt_idx,
|
||||
'Detail': dr.get('detail'),
|
||||
'Text': dr.get('text'),
|
||||
'Begin': drawing_anchor(dr.get('begin')),
|
||||
'End': drawing_anchor(dr.get('end')),
|
||||
'PictureSize': str(dr.get('pictureSize') or 'Stretch'),
|
||||
'PictureIdx': pic_idx,
|
||||
'Name': dr.get('name'),
|
||||
})
|
||||
|
||||
# Формат по умолчанию — последняя запись палитры (см. выше).
|
||||
default_format_index = register_format({'width': default_width})
|
||||
|
||||
@@ -2065,6 +2151,45 @@ def main():
|
||||
'ColumnSet': na_set,
|
||||
})
|
||||
|
||||
# 7d-bis2. Рисунки идут сразу после строк, до колонтитулов. Порядок тегов снят с корпуса:
|
||||
# у всех 11 268 рисунков он один и тот же.
|
||||
for dr in drawings:
|
||||
lines.append('\t<drawing>')
|
||||
lines.append(f'\t\t<drawingType>{dr["Type"]}</drawingType>')
|
||||
lines.append(f'\t\t<id>{dr["Id"]}</id>')
|
||||
lines.append(f'\t\t<formatIndex>{dr["FormatIdx"]}</formatIndex>')
|
||||
if dr['Detail']:
|
||||
lines.append(f'\t\t<detailParameter>{dr["Detail"]}</detailParameter>')
|
||||
if dr['Text'] is not None:
|
||||
value = dr['Text']
|
||||
if isinstance(value, dict):
|
||||
pairs = [(str(k), str(v)) for k, v in value.items()]
|
||||
else:
|
||||
pairs = [(lang, str(value)) for lang in text_languages]
|
||||
lines.append('\t\t<text>')
|
||||
for lang, content in pairs:
|
||||
lines.append('\t\t\t<v8:item>')
|
||||
lines.append(f'\t\t\t\t<v8:lang>{lang}</v8:lang>')
|
||||
lines.append(f'\t\t\t\t<v8:content>{esc_xml_text(content)}</v8:content>')
|
||||
lines.append('\t\t\t</v8:item>')
|
||||
lines.append('\t\t</text>')
|
||||
lines.append(f'\t\t<beginRow>{dr["Begin"]["Row"]}</beginRow>')
|
||||
lines.append(f'\t\t<beginRowOffset>{dr["Begin"]["Dy"]}</beginRowOffset>')
|
||||
lines.append(f'\t\t<endRow>{dr["End"]["Row"]}</endRow>')
|
||||
lines.append(f'\t\t<endRowOffset>{dr["End"]["Dy"]}</endRowOffset>')
|
||||
lines.append(f'\t\t<beginColumn>{dr["Begin"]["Col"]}</beginColumn>')
|
||||
lines.append(f'\t\t<beginColumnOffset>{dr["Begin"]["Dx"]}</beginColumnOffset>')
|
||||
lines.append(f'\t\t<endColumn>{dr["End"]["Col"]}</endColumn>')
|
||||
lines.append(f'\t\t<endColumnOffset>{dr["End"]["Dx"]}</endColumnOffset>')
|
||||
# autoSize у рисунка на корпусе всегда false (11 268 из 11 268), «АвтоРазмер» из
|
||||
# диалога уходит в pictureSize.
|
||||
lines.append('\t\t<autoSize>false</autoSize>')
|
||||
lines.append(f'\t\t<pictureSize>{dr["PictureSize"]}</pictureSize>')
|
||||
lines.append(f'\t\t<zOrder>{dr["ZOrder"]}</zOrder>')
|
||||
if dr['PictureIdx'] > 0:
|
||||
lines.append(f'\t\t<pictureIndex>{dr["PictureIdx"]}</pictureIndex>')
|
||||
lines.append('\t</drawing>')
|
||||
|
||||
# 7d-ter. Колонтитулы: шесть слотов идут после строк и перед скалярными свойствами документа.
|
||||
for slot in ('left', 'center', 'right'):
|
||||
if defn.get('header'):
|
||||
@@ -2176,10 +2301,15 @@ def main():
|
||||
# 7e. Scalar metadata
|
||||
lines.append(f'\t<templateMode>true</templateMode>')
|
||||
lines.append(f'\t<defaultFormatIndex>{default_format_index}</defaultFormatIndex>')
|
||||
lines.append(f'\t<height>{total_row_count}</height>')
|
||||
# Рисунок расширяет документ, не создавая строк: на стендах высота равна нижней границе
|
||||
# самого нижнего рисунка, при том что строк записана всего одна.
|
||||
doc_height = total_row_count
|
||||
for dr in drawings:
|
||||
doc_height = max(doc_height, dr['End']['Row'] + 1)
|
||||
lines.append(f'\t<height>{doc_height}</height>')
|
||||
if row_groups:
|
||||
lines.append(f'\t<vgLevels>{group_levels(row_groups)}</vgLevels>')
|
||||
lines.append(f'\t<vgRows>{total_row_count}</vgRows>')
|
||||
lines.append(f'\t<vgRows>{doc_height}</vgRows>')
|
||||
emit_groups(lines, 'vg', row_groups)
|
||||
emit_groups(lines, 'hg', col_groups)
|
||||
|
||||
@@ -2200,7 +2330,19 @@ def main():
|
||||
# с несколькими элементами иного порядка нет ни разу. Сортировка регистронезависимая и
|
||||
# ординальная (в ps1 поэтому нельзя Sort-Object — он сортирует по текущей культуре).
|
||||
# NB: имён с «ё» в выборке не встретилось, этот случай не проверен.
|
||||
# Имя рисунка — namedItem другого типа, но список общий: на корпусе оба вида отсортированы
|
||||
# вместе по имени во всех 266 макетах с именованными рисунками.
|
||||
for dr in drawings:
|
||||
if dr['Name']:
|
||||
named_items.append({'Name': str(dr['Name']), 'DrawingId': dr['Id']})
|
||||
|
||||
for ni in sorted(named_items, key=lambda x: str(x['Name']).lower()):
|
||||
if ni.get('DrawingId'):
|
||||
lines.append('\t<namedItem xsi:type="NamedItemDrawing">')
|
||||
lines.append(f'\t\t<name>{ni["Name"]}</name>')
|
||||
lines.append(f'\t\t<drawingID>{ni["DrawingId"]}</drawingID>')
|
||||
lines.append('\t</namedItem>')
|
||||
continue
|
||||
# Тип области выводится из указанных осей, как в ТабличныйДокумент.Область():
|
||||
# нет колонок → полоса строк, нет строк → полоса колонок, обе → прямоугольник.
|
||||
has_rows = int(ni['BeginRow']) >= 0
|
||||
@@ -2222,7 +2364,9 @@ def main():
|
||||
# 7h. Line palette
|
||||
for ln in line_registry:
|
||||
lines.append(f'\t<line width="{ln["Width"]}" gap="{ln["Gap"]}">')
|
||||
lines.append(f'\t\t<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">{ln["Style"]}</v8ui:style>')
|
||||
line_kind = ('SpreadsheetDocumentDrawingLineType' if ln.get('Kind') == 'Drawing'
|
||||
else 'SpreadsheetDocumentCellLineType')
|
||||
lines.append(f'\t\t<v8ui:style xsi:type="v8ui:{line_kind}">{ln["Style"]}</v8ui:style>')
|
||||
lines.append('\t</line>')
|
||||
|
||||
# 7i. Font palette
|
||||
@@ -2275,7 +2419,28 @@ def main():
|
||||
|
||||
lines.append('\t</format>')
|
||||
|
||||
# 7k. Close document
|
||||
# 7k. Палитра картинок — последний блок документа. Индекс здесь 0-based, а ссылки
|
||||
# на него (pictureIndex рисунка, picIndex стиля) 1-based.
|
||||
for pic_i, pic in enumerate(picture_entries):
|
||||
lines.append('\t<picture>')
|
||||
lines.append(f'\t\t<index>{pic_i}</index>')
|
||||
if pic['Ref']:
|
||||
lines.append(f'\t\t<picture ref="{esc_xml(pic["Ref"])}"/>')
|
||||
elif not pic['Data']:
|
||||
lines.append('\t\t<picture/>')
|
||||
else:
|
||||
attr = f' t="{pic["Transparent"]}"' if pic['Transparent'] else ''
|
||||
if pic['PixelX']:
|
||||
attr += f' tx="{pic["PixelX"]}" ty="{pic["PixelY"]}"'
|
||||
# Данные платформа переносит по строкам тем же переводом, что и весь файл, —
|
||||
# в отличие от блоба настроек элемента управления, где перенос голый LF.
|
||||
parts = str(pic['Data']).replace('\r\n', '\n').split('\n')
|
||||
parts[0] = f'\t\t<picture{attr}>{parts[0]}'
|
||||
parts[-1] = f'{parts[-1]}</picture>'
|
||||
lines.extend(parts)
|
||||
lines.append('\t</picture>')
|
||||
|
||||
# 7l. Close document
|
||||
lines.append('</document>')
|
||||
|
||||
# --- 8. Write output ---
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# mxl-decompile v1.26 — Decompile 1C spreadsheet to JSON
|
||||
# mxl-decompile v1.27 — Decompile 1C spreadsheet to JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -41,7 +41,7 @@ function Get-FormatTagKind {
|
||||
'autoIndent' = 'int'; 'autoMarkIncomplete' = 'bool'; 'autoWidthCalculation' = 'bool'
|
||||
'backColor' = 'color'; 'border' = 'line'; 'borderColor' = 'color'
|
||||
'bottomBorder' = 'line'; 'bySelectedColumns' = 'bool'; 'columnSizeChange' = 'enum'
|
||||
'detailsUse' = 'enum'; 'drawingBorder' = 'int'
|
||||
'detailsUse' = 'enum'; 'drawingBorder' = 'line'
|
||||
'drawingHaveBottomBorder' = 'bool'; 'drawingHaveLeftBorder' = 'bool'
|
||||
'drawingHaveRightBorder' = 'bool'; 'drawingHaveTopBorder' = 'bool'
|
||||
'editFormat' = 'ml'; 'fillType' = 'enum'; 'font' = 'int'; 'format' = 'ml'
|
||||
@@ -265,6 +265,98 @@ function Get-Format {
|
||||
return $rawFormats[$idx - 1]
|
||||
}
|
||||
|
||||
# --- 4-bis. Палитра картинок и рисунки ---
|
||||
# Картинка хранится ссылкой на библиотеку либо данными base64; ссылки на палитру (у рисунка
|
||||
# pictureIndex, у ячейки picIndex) — 1-based, сам <index> — 0-based.
|
||||
$picturesOut = [ordered]@{}
|
||||
$pictureKey = @{}
|
||||
$picI = 0
|
||||
foreach ($picNode in $root.SelectNodes("d:picture", $ns)) {
|
||||
$inner = $picNode.SelectSingleNode("d:picture", $ns)
|
||||
if (-not $inner) { continue }
|
||||
$picI++
|
||||
$name = "pic$picI"
|
||||
$entry = [ordered]@{}
|
||||
if ($inner.GetAttribute('ref')) {
|
||||
$entry["ref"] = $inner.GetAttribute('ref')
|
||||
} elseif (($inner.InnerText).Trim()) {
|
||||
# System.Xml переводы строк в тексте не нормализует, а lxml нормализует: без этой
|
||||
# замены порты дали бы разный JSON на одном и том же файле.
|
||||
$entry["data"] = ($inner.InnerText -replace "`r`n", "`n").Trim()
|
||||
if ($inner.HasAttribute('t')) { $entry["transparent"] = ($inner.GetAttribute('t') -ceq 'true') }
|
||||
# Пиксель прозрачного цвета: координата внутри самой картинки (проверено —
|
||||
# это не её размеры). В корпусе встречается без атрибута t.
|
||||
if ($inner.HasAttribute('tx')) {
|
||||
$entry["transparentPixel"] = [ordered]@{
|
||||
x = [int]$inner.GetAttribute('tx')
|
||||
y = [int]$inner.GetAttribute('ty')
|
||||
}
|
||||
}
|
||||
}
|
||||
$picturesOut[$name] = $entry
|
||||
$pictureKey[$picI] = $name
|
||||
}
|
||||
|
||||
$drawingNames = @{}
|
||||
foreach ($niNode in $root.SelectNodes("d:namedItem", $ns)) {
|
||||
if ($niNode.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance") -cne 'NamedItemDrawing') { continue }
|
||||
$idN = $niNode.SelectSingleNode("d:drawingID", $ns)
|
||||
$nmN = $niNode.SelectSingleNode("d:name", $ns)
|
||||
$drawingNames[$(if ($idN) { $idN.InnerText } else { '' })] = $(if ($nmN) { $nmN.InnerText } else { '' })
|
||||
}
|
||||
|
||||
$drawingsOut = @()
|
||||
$drI = 0
|
||||
foreach ($dr in $root.SelectNodes("d:drawing", $ns)) {
|
||||
$drI++
|
||||
$item = [ordered]@{}
|
||||
$tN = $dr.SelectSingleNode("d:drawingType", $ns)
|
||||
$item["type"] = if ($tN) { $tN.InnerText } else { 'Picture' }
|
||||
$idN = $dr.SelectSingleNode("d:id", $ns)
|
||||
$did = if ($idN) { $idN.InnerText } else { "$drI" }
|
||||
if ($did -cne "$drI") { $item["id"] = [int]$did }
|
||||
$zN = $dr.SelectSingleNode("d:zOrder", $ns)
|
||||
$zorder = if ($zN) { $zN.InnerText } else { "$drI" }
|
||||
if ($zorder -cne "$drI") { $item["zOrder"] = [int]$zorder }
|
||||
if ($drawingNames.ContainsKey($did)) { $item["name"] = $drawingNames[$did] }
|
||||
$piN = $dr.SelectSingleNode("d:pictureIndex", $ns)
|
||||
if ($piN -and $pictureKey.ContainsKey([int]$piN.InnerText)) {
|
||||
$item["picture"] = $pictureKey[[int]$piN.InnerText]
|
||||
}
|
||||
$dpN = $dr.SelectSingleNode("d:detailParameter", $ns)
|
||||
if ($dpN -and $dpN.InnerText) { $item["detail"] = $dpN.InnerText }
|
||||
$tEl = $dr.SelectSingleNode("d:text", $ns)
|
||||
if ($tEl) {
|
||||
$byLang = [ordered]@{}
|
||||
foreach ($it in $tEl.SelectNodes("v8:item", $ns)) {
|
||||
$l = $it.SelectSingleNode("v8:lang", $ns)
|
||||
$cnt = $it.SelectSingleNode("v8:content", $ns)
|
||||
$byLang[$(if ($l) { $l.InnerText } else { '' })] = $(if ($cnt) { $cnt.InnerText } else { '' })
|
||||
}
|
||||
$item["text"] = $byLang
|
||||
}
|
||||
# Оформление разбирается позже: линию нужно развернуть в описание, а помощник для
|
||||
# этого появляется вместе с палитрой стилей.
|
||||
$fN = $dr.SelectSingleNode("d:formatIndex", $ns)
|
||||
foreach ($pair in @(@('begin', 'beginRowOffset', 'beginColumnOffset'), @('end', 'endRowOffset', 'endColumnOffset'))) {
|
||||
$prefix = $pair[0]
|
||||
$rN = $dr.SelectSingleNode("d:$($prefix)Row", $ns)
|
||||
$cN = $dr.SelectSingleNode("d:$($prefix)Column", $ns)
|
||||
$dyN = $dr.SelectSingleNode("d:$($pair[1])", $ns)
|
||||
$dxN = $dr.SelectSingleNode("d:$($pair[2])", $ns)
|
||||
$item[$prefix] = [ordered]@{
|
||||
row = $(if ($rN) { [int]$rN.InnerText } else { 0 }) + 1
|
||||
col = $(if ($cN) { [int]$cN.InnerText } else { 0 }) + 1
|
||||
dy = $(if ($dyN) { [int]$dyN.InnerText } else { 0 })
|
||||
dx = $(if ($dxN) { [int]$dxN.InnerText } else { 0 })
|
||||
}
|
||||
}
|
||||
$psN = $dr.SelectSingleNode("d:pictureSize", $ns)
|
||||
if ($psN -and $psN.InnerText -cne 'Stretch') { $item["pictureSize"] = $psN.InnerText }
|
||||
$item["_fmt"] = if ($fN) { [int]$fN.InnerText } else { 0 }
|
||||
$drawingsOut += , $item
|
||||
}
|
||||
|
||||
# --- 4a. Колонтитулы и параметры печати ---
|
||||
# Слот колонтитула устроен как ячейка: ссылка на формат плюс текст. Признак вывода и стартовую
|
||||
# страницу читаем только у записи, где есть <height>: палитра дедуплицирована, и колонтитул без
|
||||
@@ -640,7 +732,11 @@ function Get-DslText {
|
||||
# общий на многие ячейки, а они индивидуальны. Компилятор таких ключей не знает, так что
|
||||
# в DSL они были чистым шумом.
|
||||
$nonStyleTags = @('width', 'height', 'fillType', 'font',
|
||||
'containsValue', 'valueType', 'controlType')
|
||||
'containsValue', 'valueType', 'controlType',
|
||||
# Линия рисунка и её стороны — свойства рисунка, а не общего оформления:
|
||||
# на корпусе все 2 135 записей с ними принадлежат только рисункам.
|
||||
'drawingBorder', 'drawingHaveLeftBorder', 'drawingHaveTopBorder',
|
||||
'drawingHaveRightBorder', 'drawingHaveBottomBorder')
|
||||
$borderTags = @('border', 'leftBorder', 'topBorder', 'rightBorder', 'bottomBorder')
|
||||
|
||||
function ConvertTo-DslLine {
|
||||
@@ -793,6 +889,20 @@ foreach ($r in ($rowData.Keys | Sort-Object { [int]$_ } | ForEach-Object { $rowD
|
||||
}
|
||||
}
|
||||
|
||||
# Формат рисунка — ещё один владелец записи палитры, наравне с ячейкой, строкой, колонкой
|
||||
# и примечанием: без этого оформление рисунка теряло имя и вырезалось как неиспользуемое.
|
||||
foreach ($item in $drawingsOut) {
|
||||
$fi = [int]$item['_fmt']
|
||||
if ($fi -le 0) { continue }
|
||||
$dfmt = Get-Format $fi
|
||||
if (-not $dfmt) { continue }
|
||||
if ((Get-StyleProps $dfmt).Count -gt 0 -or $dfmt.FontIdx -ge 0) {
|
||||
$dkey = Get-StyleKey $dfmt
|
||||
if (-not $styleKeys.Contains($dkey)) { $styleKeys[$dkey] = $dfmt }
|
||||
$formatToStyleKey[$fi] = $dkey
|
||||
}
|
||||
}
|
||||
|
||||
# Оформление строки без её собственных свойств: скрытие уезжает инлайном к height,
|
||||
# поэтому в именованный стиль попадать не должно.
|
||||
function Get-RowStyleFmt {
|
||||
@@ -1519,6 +1629,15 @@ foreach ($cs in $columnSets) {
|
||||
if ($name) { $usedStyles[$name] = $true }
|
||||
}
|
||||
}
|
||||
# Рисунок — пятый владелец формата. Имя ему присваивается позже, при сборке результата,
|
||||
# поэтому здесь считаем его из ссылки на палитру: иначе стиль рисунка вырежется как
|
||||
# неиспользуемый, а ссылка на него останется висячей.
|
||||
foreach ($item in $drawingsOut) {
|
||||
$fi = [int]$item['_fmt']
|
||||
if ($fi -le 0) { continue }
|
||||
$dname = Get-StyleName $fi
|
||||
if ($dname -cne 'default') { $usedStyles[$dname] = $true }
|
||||
}
|
||||
$toRemove = @($styleDefs.Keys | Where-Object { -not $usedStyles.ContainsKey($_) })
|
||||
foreach ($s in $toRemove) { $styleDefs.Remove($s)
|
||||
}
|
||||
@@ -1553,10 +1672,44 @@ if ($colGroups.Count -gt 0) { $result["columnGroups"] = [array]$colGroups }
|
||||
# становится известен только после разбора строк.
|
||||
$headerPart = Read-HeaderPart 'Header'
|
||||
$footerPart = Read-HeaderPart 'Footer'
|
||||
if ($headerPart) { $result["header"] = $headerPart }
|
||||
if ($footerPart) { $result["footer"] = $footerPart }
|
||||
# Пустой словарь в PowerShell истинен, поэтому проверяем именно наполнение: макет со ссылкой
|
||||
# на общую запись палитры, но без своих настроек колонтитула, иначе получал в DSL пустой ключ.
|
||||
if ($headerPart -and $headerPart.Count -gt 0) { $result["header"] = $headerPart }
|
||||
if ($footerPart -and $footerPart.Count -gt 0) { $result["footer"] = $footerPart }
|
||||
if ($printSettings) { $result["printSettings"] = $printSettings }
|
||||
|
||||
# Оформление рисунка: линия и её стороны — его собственные ключи, общее — именованный стиль.
|
||||
# Порядок ключей задаём здесь же, чтобы он не зависел от того, что разбиралось раньше.
|
||||
$drawingsOrdered = @()
|
||||
foreach ($item in $drawingsOut) {
|
||||
$fmtIdx = [int]$item['_fmt']
|
||||
$item.Remove('_fmt')
|
||||
if ($item.Contains("text")) { $item["text"] = Get-DslText $item["text"] }
|
||||
$lineVal = $null
|
||||
$sides = [ordered]@{}
|
||||
if ($fmtIdx -gt 0) {
|
||||
$dfmt = Get-Format $fmtIdx
|
||||
$props = if ($dfmt) { $dfmt.Props } else { @{} }
|
||||
if ($props.Contains('drawingBorder')) { $lineVal = ConvertTo-DslLine ([int]$props['drawingBorder']) }
|
||||
foreach ($side in @('Left', 'Top', 'Right', 'Bottom')) {
|
||||
$tag = "drawingHave${side}Border"
|
||||
if ($props.Contains($tag)) { $sides[$side.ToLowerInvariant()] = ($props[$tag] -ceq 'true') }
|
||||
}
|
||||
$dname = Get-StyleName $fmtIdx
|
||||
if ($dname -cne 'default') { $item["style"] = $dname }
|
||||
}
|
||||
if ($null -ne $lineVal) { $item["line"] = $lineVal }
|
||||
if ($sides.Count -gt 0) { $item["sides"] = $sides }
|
||||
$outItem = [ordered]@{}
|
||||
foreach ($key in @('type', 'id', 'zOrder', 'name', 'picture', 'detail', 'text',
|
||||
'style', 'line', 'sides', 'begin', 'end', 'pictureSize')) {
|
||||
if ($item.Contains($key)) { $outItem[$key] = $item[$key] }
|
||||
}
|
||||
$drawingsOrdered += , $outItem
|
||||
}
|
||||
if ($picturesOut.Count -gt 0) { $result["pictures"] = $picturesOut }
|
||||
if ($drawingsOrdered.Count -gt 0) { $result["drawings"] = [array]$drawingsOrdered }
|
||||
|
||||
$result["areas"] = [array]$dslAreas
|
||||
|
||||
# Именованные области, не выразимые блоком, — координатами. Тип не пишем: он выводится
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-decompile v1.26 — Decompile 1C spreadsheet to JSON
|
||||
# mxl-decompile v1.27 — Decompile 1C spreadsheet to JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -79,7 +79,7 @@ def format_tag_kind():
|
||||
'autoIndent': 'int', 'autoMarkIncomplete': 'bool', 'autoWidthCalculation': 'bool',
|
||||
'backColor': 'color', 'border': 'line', 'borderColor': 'color',
|
||||
'bottomBorder': 'line', 'bySelectedColumns': 'bool', 'columnSizeChange': 'enum',
|
||||
'detailsUse': 'enum', 'drawingBorder': 'int',
|
||||
'detailsUse': 'enum', 'drawingBorder': 'line',
|
||||
'drawingHaveBottomBorder': 'bool', 'drawingHaveLeftBorder': 'bool',
|
||||
'drawingHaveRightBorder': 'bool', 'drawingHaveTopBorder': 'bool',
|
||||
'editFormat': 'ml', 'fillType': 'enum', 'font': 'int', 'format': 'ml',
|
||||
@@ -431,6 +431,77 @@ def main():
|
||||
return None
|
||||
return raw_formats[idx - 1]
|
||||
|
||||
# --- 4-bis. Палитра картинок и рисунки ---
|
||||
# Картинка хранится ссылкой на библиотеку либо данными base64; ссылки на палитру (у рисунка
|
||||
# pictureIndex, у ячейки picIndex) — 1-based, сам <index> — 0-based.
|
||||
pictures_out = OrderedDict()
|
||||
picture_key = {}
|
||||
for pic_i, pic_node in enumerate(findall(root, "d:picture"), start=1):
|
||||
inner = find(pic_node, "d:picture")
|
||||
if inner is None:
|
||||
continue
|
||||
name = f'pic{pic_i}'
|
||||
entry = OrderedDict()
|
||||
if inner.get("ref"):
|
||||
entry["ref"] = inner.get("ref")
|
||||
elif (inner.text or "").strip():
|
||||
entry["data"] = (inner.text or "").strip()
|
||||
if inner.get("t") is not None:
|
||||
entry["transparent"] = inner.get("t") == "true"
|
||||
# Пиксель прозрачного цвета: координата внутри самой картинки (проверено —
|
||||
# это не её размеры). В корпусе встречается без атрибута t.
|
||||
if inner.get("tx") is not None:
|
||||
entry["transparentPixel"] = OrderedDict([("x", int(inner.get("tx"))),
|
||||
("y", int(inner.get("ty") or 0))])
|
||||
pictures_out[name] = entry
|
||||
picture_key[pic_i] = name
|
||||
|
||||
drawing_names = {}
|
||||
for ni_node in findall(root, "d:namedItem"):
|
||||
if (ni_node.get(f'{{{XSI_NS}}}type') or '') == 'NamedItemDrawing':
|
||||
drawing_names[text_of(find(ni_node, "d:drawingID")) or ''] = text_of(find(ni_node, "d:name")) or ''
|
||||
|
||||
drawings_out = []
|
||||
for dr_i, dr in enumerate(findall(root, "d:drawing"), start=1):
|
||||
item = OrderedDict()
|
||||
item["type"] = text_of(find(dr, "d:drawingType")) or "Picture"
|
||||
did = text_of(find(dr, "d:id")) or str(dr_i)
|
||||
if did != str(dr_i):
|
||||
item["id"] = int(did)
|
||||
zorder = text_of(find(dr, "d:zOrder")) or str(dr_i)
|
||||
if zorder != str(dr_i):
|
||||
item["zOrder"] = int(zorder)
|
||||
if did in drawing_names:
|
||||
item["name"] = drawing_names[did]
|
||||
pic_ref = text_of(find(dr, "d:pictureIndex"))
|
||||
if pic_ref and int(pic_ref) in picture_key:
|
||||
item["picture"] = picture_key[int(pic_ref)]
|
||||
detail = text_of(find(dr, "d:detailParameter"))
|
||||
if detail:
|
||||
item["detail"] = detail
|
||||
t_el = find(dr, "d:text")
|
||||
if t_el is not None:
|
||||
by_lang = OrderedDict()
|
||||
for it in findall(t_el, "v8:item"):
|
||||
by_lang[text_of(find(it, "v8:lang")) or ''] = text_of(find(it, "v8:content")) or ''
|
||||
item["text"] = by_lang
|
||||
# Оформление разбирается позже: линию нужно развернуть в описание, а помощник для
|
||||
# этого появляется вместе с палитрой стилей.
|
||||
fmt_idx = int_of(find(dr, "d:formatIndex"))
|
||||
|
||||
def anchor(prefix, off_row, off_col):
|
||||
return OrderedDict([("row", int_of(find(dr, f'd:{prefix}Row')) + 1),
|
||||
("col", int_of(find(dr, f'd:{prefix}Column')) + 1),
|
||||
("dy", int_of(find(dr, f'd:{off_row}'))),
|
||||
("dx", int_of(find(dr, f'd:{off_col}')))])
|
||||
item["begin"] = anchor("begin", "beginRowOffset", "beginColumnOffset")
|
||||
item["end"] = anchor("end", "endRowOffset", "endColumnOffset")
|
||||
psize = text_of(find(dr, "d:pictureSize"))
|
||||
if psize and psize != "Stretch":
|
||||
item["pictureSize"] = psize
|
||||
item["_fmt"] = fmt_idx
|
||||
drawings_out.append(item)
|
||||
|
||||
# --- 4a. Колонтитулы и параметры печати ---
|
||||
# Слот колонтитула устроен как ячейка: ссылка на формат плюс текст. Признак вывода и стартовую
|
||||
# страницу читаем только у записи, где есть <height>: палитра дедуплицирована, и колонтитул без
|
||||
@@ -790,7 +861,11 @@ def main():
|
||||
# общий на многие ячейки, а они индивидуальны. Компилятор таких ключей не знает, так что
|
||||
# в DSL они были чистым шумом.
|
||||
NON_STYLE_TAGS = ("width", "height", "fillType", "font",
|
||||
"containsValue", "valueType", "controlType")
|
||||
"containsValue", "valueType", "controlType",
|
||||
# Линия рисунка и её стороны — свойства рисунка, а не общего оформления:
|
||||
# на корпусе все 2 135 записей с ними принадлежат только рисункам.
|
||||
"drawingBorder", "drawingHaveLeftBorder", "drawingHaveTopBorder",
|
||||
"drawingHaveRightBorder", "drawingHaveBottomBorder")
|
||||
BORDER_TAGS = ("border", "leftBorder", "topBorder", "rightBorder", "bottomBorder")
|
||||
|
||||
def line_to_dsl(idx):
|
||||
@@ -934,6 +1009,19 @@ def main():
|
||||
style_keys[nkey] = nfmt
|
||||
format_to_style_key[cell["Note"]["FormatIdx"]] = nkey
|
||||
|
||||
# Формат рисунка — ещё один владелец записи палитры, наравне с ячейкой, строкой, колонкой
|
||||
# и примечанием: без этого оформление рисунка теряло имя и вырезалось как неиспользуемое.
|
||||
for _item in drawings_out:
|
||||
_fi = _item.get("_fmt") or 0
|
||||
if not _fi:
|
||||
continue
|
||||
_fmt = get_format(_fi)
|
||||
if _fmt and (style_props(_fmt) or _fmt["FontIdx"] >= 0):
|
||||
_key = get_style_key(_fmt)
|
||||
if _key not in style_keys:
|
||||
style_keys[_key] = _fmt
|
||||
format_to_style_key[_fi] = _key
|
||||
|
||||
def row_style_fmt(fmt):
|
||||
"""Оформление строки без её собственных свойств: скрытие уезжает инлайном к height,
|
||||
поэтому в именованный стиль попадать не должно."""
|
||||
@@ -1509,6 +1597,15 @@ def main():
|
||||
for name in column_styles_of(cs).values():
|
||||
if name:
|
||||
used_styles.add(name)
|
||||
# Рисунок — пятый владелец формата. Имя ему присваивается позже, при сборке результата,
|
||||
# поэтому здесь считаем его из ссылки на палитру: иначе стиль рисунка вырежется как
|
||||
# неиспользуемый, а ссылка на него останется висячей.
|
||||
for _item in drawings_out:
|
||||
_fi = _item.get("_fmt") or 0
|
||||
if _fi:
|
||||
_name = get_style_name(_fi)
|
||||
if _name != "default":
|
||||
used_styles.add(_name)
|
||||
to_remove = [s for s in style_defs if s not in used_styles]
|
||||
for s in to_remove:
|
||||
del style_defs[s]
|
||||
@@ -1552,6 +1649,43 @@ def main():
|
||||
if print_settings:
|
||||
result["printSettings"] = print_settings
|
||||
|
||||
# Оформление рисунка: линия и её стороны — его собственные ключи, общее — именованный стиль.
|
||||
# Порядок ключей задаём здесь же, чтобы он не зависел от того, что разбиралось раньше.
|
||||
ordered = []
|
||||
for item in drawings_out:
|
||||
fmt_idx = item.pop("_fmt", 0)
|
||||
if "text" in item:
|
||||
item["text"] = get_dsl_text(item["text"])
|
||||
line_val = None
|
||||
sides = OrderedDict()
|
||||
if fmt_idx:
|
||||
fmt = get_format(fmt_idx)
|
||||
props = fmt["Props"] if fmt else {}
|
||||
if "drawingBorder" in props:
|
||||
line_val = line_to_dsl(int(props["drawingBorder"]))
|
||||
for side in ("Left", "Top", "Right", "Bottom"):
|
||||
tag = f'drawingHave{side}Border'
|
||||
if tag in props:
|
||||
sides[side.lower()] = props[tag] == "true"
|
||||
name = get_style_name(fmt_idx)
|
||||
if name != "default":
|
||||
item["style"] = name
|
||||
if line_val is not None:
|
||||
item["line"] = line_val
|
||||
if sides:
|
||||
item["sides"] = sides
|
||||
out_item = OrderedDict()
|
||||
for key in ("type", "id", "zOrder", "name", "picture", "detail", "text",
|
||||
"style", "line", "sides", "begin", "end", "pictureSize"):
|
||||
if key in item:
|
||||
out_item[key] = item[key]
|
||||
ordered.append(out_item)
|
||||
drawings_out = ordered
|
||||
if pictures_out:
|
||||
result["pictures"] = pictures_out
|
||||
if drawings_out:
|
||||
result["drawings"] = drawings_out
|
||||
|
||||
result["areas"] = dsl_areas
|
||||
|
||||
# Именованные области, не выразимые блоком, — координатами. Тип не пишем: он выводится
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# mxl-validate v1.6 — Validate 1C spreadsheet
|
||||
# mxl-validate v1.7 — Validate 1C spreadsheet
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Alias('Path')]
|
||||
@@ -408,6 +408,16 @@ foreach ($drawing in $root.SelectNodes("d:drawing", $nsMgr)) {
|
||||
Report-Error "Drawing id=${drawId}: pictureIndex=$picIdx > picture count ($pictureCount)"
|
||||
}
|
||||
}
|
||||
# Оформление рисунка — такая же запись палитры форматов, как у ячейки, и висячая
|
||||
# ссылка на неё так же валит загрузку макета.
|
||||
$fmtIdxNode = $drawing.SelectSingleNode("d:formatIndex", $nsMgr)
|
||||
if ($fmtIdxNode) {
|
||||
$fmtIdx = [int]$fmtIdxNode.InnerText
|
||||
if ($fmtIdx -gt $formatCount) {
|
||||
$drawId = $drawing.SelectSingleNode("d:id", $nsMgr).InnerText
|
||||
Report-Error "Drawing id=${drawId}: formatIndex=$fmtIdx > format palette size ($formatCount)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# --- Check 13: value cells (input fields) ---
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-validate v1.6 — Validate 1C spreadsheet document Template.xml
|
||||
# mxl-validate v1.7 — Validate 1C spreadsheet document Template.xml
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
"""Validates spreadsheet Template.xml: height, palette refs, column/row indices, areas, merges."""
|
||||
import sys, os, argparse
|
||||
@@ -405,6 +405,16 @@ def main():
|
||||
draw_id = draw_id_node.text if draw_id_node is not None else '?'
|
||||
r.error(f'Drawing id={draw_id}: pictureIndex={pic_idx} > picture count ({picture_count})')
|
||||
|
||||
# Оформление рисунка — такая же запись палитры форматов, как у ячейки, и висячая
|
||||
# ссылка на неё так же валит загрузку макета.
|
||||
fmt_idx_node = drawing.find(f'{{{NS_D}}}formatIndex')
|
||||
if fmt_idx_node is not None and fmt_idx_node.text:
|
||||
fmt_idx = int(fmt_idx_node.text)
|
||||
if fmt_idx > format_count:
|
||||
draw_id_node = drawing.find(f'{{{NS_D}}}id')
|
||||
draw_id = draw_id_node.text if draw_id_node is not None else '?'
|
||||
r.error(f'Drawing id={draw_id}: formatIndex={fmt_idx} > format palette size ({format_count})')
|
||||
|
||||
# --- Check 13: value cells (input fields) ---
|
||||
# Свойства containsValue/valueType/controlType принадлежат ЯЧЕЙКЕ: на корпусе ERP
|
||||
# (370 197 ссылок) на такие записи палитры ссылаются только <f>, ни строка, ни колонка,
|
||||
|
||||
@@ -708,15 +708,85 @@ current-config не объявляет, поэтому вынести объяв
|
||||
подсказки (`verticalAlignment: Top` + `style:ToolTipTextColor` + `style:ToolTipBackColor`),
|
||||
105 — он же с заливкой `#FFFAD9`.
|
||||
|
||||
## Ресурсы картинок
|
||||
## Палитра картинок
|
||||
|
||||
Идёт последним блоком документа. Внутренний `<index>` 0-based, а ссылки на него — 1-based:
|
||||
`<pictureIndex>` у рисунка, `picIndex` в записи формата у картинки в ячейке.
|
||||
|
||||
```xml
|
||||
<picture>
|
||||
<index>0</index>
|
||||
<picture ref="v8ui:Штрихкод"/> <!-- ссылка на предопределённую картинку -->
|
||||
<picture ref="v8ui:Штрихкод"/> <!-- ссылка на библиотеку картинок платформы -->
|
||||
</picture>
|
||||
<picture>
|
||||
<index>1</index>
|
||||
<picture t="false">iVBORw0KGgoAAAANSUhEUgAAAG4AAAA2CAIAAACp5Ds2AAAAAXNSR0IArs4c6QAA
|
||||
AARnQUlBAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAA</picture>
|
||||
</picture>
|
||||
```
|
||||
|
||||
Данные base64 платформа переносит по строкам тем же переводом, что и весь файл (CRLF), —
|
||||
в отличие от блоба настроек элемента управления, где перенос голый LF.
|
||||
|
||||
Атрибуты внутреннего `<picture>` по корпусу ERP (10 130 записей):
|
||||
|
||||
| Вид | Сколько | Смысл |
|
||||
|-----|--------:|-------|
|
||||
| данные без атрибутов | 9 896 | картинка хранится в макете |
|
||||
| `<picture/>` | 151 | картинка не задана; ровно по одной такой записи на макет |
|
||||
| `ref="v8ui:Имя"` | 83 | ссылка на библиотеку картинок платформы |
|
||||
| `tx`, `ty` при данных | 9 | координата пикселя внутри картинки (проверено: это НЕ её размеры — у `tx=97 ty=83` сама картинка 368×117) |
|
||||
|
||||
Атрибут `t` (прозрачность) в корпусе не встречается, но платформа его пишет: `t="false"`
|
||||
появляется у картинки, вставленной в ячейку.
|
||||
|
||||
## Рисунки
|
||||
|
||||
Рисунок — объект поверх сетки: картинка, фигура, надпись, диаграмма. Лежит в `<drawing>`
|
||||
перед палитрами; геометрия задана двумя якорями «ячейка + смещение в точках».
|
||||
|
||||
```xml
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>3</id>
|
||||
<zOrder>3</zOrder>
|
||||
<beginRow>1</beginRow>
|
||||
<beginColumn>1</beginColumn>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endRow>3</endRow>
|
||||
<endColumn>2</endColumn>
|
||||
<endRowOffset>34</endRowOffset>
|
||||
<endColumnOffset>115</endColumnOffset>
|
||||
<formatIndex>4</formatIndex>
|
||||
<pictureSize>Proportionally</pictureSize>
|
||||
<pictureIndex>2</pictureIndex>
|
||||
<detailParameter>Расшифровка</detailParameter>
|
||||
</drawing>
|
||||
```
|
||||
|
||||
Координаты строк и колонок здесь 0-based, в отличие от `<i>` ячейки. `<id>` и `<zOrder>`
|
||||
самостоятельны: на корпусе они расходятся у 8 253 рисунков из 11 268, так что выводить их
|
||||
из порядка следования нельзя. `<pictureSize>Stretch</pictureSize>` — умолчание, пишется всегда.
|
||||
|
||||
Имя рисунка хранится отдельно, среди именованных элементов:
|
||||
|
||||
```xml
|
||||
<namedItem xsi:type="NamedItemDrawing">
|
||||
<name>Логотип</name>
|
||||
<drawingID>3</drawingID>
|
||||
</namedItem>
|
||||
```
|
||||
|
||||
Оформление рисунка — обычная запись палитры форматов, но с собственными тегами: `drawingBorder`
|
||||
(ссылка в палитру линий, вид `SpreadsheetDocumentDrawingLineType`) и
|
||||
`drawingHaveLeftBorder` / `drawingHaveTopBorder` / `drawingHaveRightBorder` /
|
||||
`drawingHaveBottomBorder`. У ячейки таких свойств не бывает: все 2 135 записей корпуса с ними
|
||||
принадлежат рисункам. Остальное в записи — общие свойства (заливка, шрифт, выравнивание).
|
||||
|
||||
Тело диаграмм (`Chart`, `GanttChart`) лежит в том же `<drawing>` в отдельном пространстве имён
|
||||
и здесь не разбирается.
|
||||
|
||||
## Типичная структура макета печатной формы
|
||||
|
||||
Печатная форма обычно состоит из именованных горизонтальных областей:
|
||||
|
||||
@@ -64,8 +64,6 @@
|
||||
| `picHorizontalAlignment` | перечисление | `Auto`, `Center`, `Left`, `Right` |
|
||||
| `picVerticalAlignment` | перечисление | `Top`, `Center`, `Bottom` |
|
||||
| `textPosition` | перечисление | Положение текста относительно картинки: `Auto`, `Top`, `Right`, `Bottom` |
|
||||
| `drawingBorder` | число | Рамка рисунка |
|
||||
| `drawingHaveLeftBorder`, `drawingHaveTopBorder`, `drawingHaveRightBorder`, `drawingHaveBottomBorder` | да/нет | Наличие стороны рамки рисунка |
|
||||
|
||||
## Чего в стиле нет
|
||||
|
||||
@@ -74,4 +72,6 @@
|
||||
- `fillType` — выводится из того, каким ключом задано содержимое ячейки
|
||||
(`text` / `param` / `template`);
|
||||
- `containsValue`, `valueType`, `controlType` — свойства конкретной ячейки, а не общего
|
||||
оформления: задаются ключами ячейки `valueType` и `controlType`.
|
||||
оформления: задаются ключами ячейки `valueType` и `controlType`;
|
||||
- линия рисунка и её стороны — свойства рисунка: задаются его ключами `line` и `sides`
|
||||
(у ячейки такого свойства нет вовсе).
|
||||
|
||||
+51
-1
@@ -91,6 +91,8 @@
|
||||
| `columnGroups` | нет | — | Группы колонок (см. ниже) |
|
||||
| `header` / `footer` | нет | — | Верхний и нижний колонтитулы (см. ниже) |
|
||||
| `printSettings` | нет | — | Параметры печати (см. ниже) |
|
||||
| `pictures` | нет | — | Палитра картинок: ссылки на библиотеку платформы или данные (см. ниже) |
|
||||
| `drawings` | нет | — | Рисунки: картинки, фигуры, надписи (см. ниже) |
|
||||
|
||||
## Области (`areas[]`)
|
||||
|
||||
@@ -384,6 +386,54 @@
|
||||
Порядок в списке не важен: компилятор пишет группы так же, как платформа, — родитель
|
||||
раньше вложенных, по возрастанию начала.
|
||||
|
||||
## Рисунки и картинки
|
||||
|
||||
Рисунок — объект поверх сетки ячеек: картинка, фигура или надпись. Его положение задают два
|
||||
якоря: ячейка плюс смещение в точках от её левого верхнего угла.
|
||||
|
||||
```json
|
||||
"pictures": {
|
||||
"знак": { "ref": "v8ui:Стоп48" },
|
||||
"логотип": { "data": "iVBORw0KGgo...", "transparent": false }
|
||||
},
|
||||
"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`). Пустая запись `{}` — картинка не задана, такое в макетах встречается.
|
||||
С данными сочетаются `transparent` (прозрачность включена) и `transparentPixel`
|
||||
(`{ "x": …, "y": … }` — координата пикселя, чей цвет считается прозрачным).
|
||||
|
||||
Одну запись `pictures` могут использовать несколько рисунков — данные в макете не дублируются.
|
||||
|
||||
## `rowStyle` — оформление строки
|
||||
|
||||
Стиль применяется ко ВСЕЙ ширине строки: позиции без явных ячеек получают тот же стиль. Так в табличных строках получаются сплошные рамки. Он же становится оформлением самой строки — именно так платформа хранит строку, оформленную целиком.
|
||||
@@ -399,7 +449,7 @@ round-trip** (`/mxl-decompile` → `/mxl-compile`): в JSON оно не попа
|
||||
XML не возвращается.
|
||||
|
||||
- объединения, не привязанные к ячейке (по всей высоте или ширине документа);
|
||||
- рисунки и картинки, в том числе штрихкоды;
|
||||
- настройки диаграмм (`Chart`, `GanttChart`) — сам рисунок сохраняется, его содержимое нет;
|
||||
- область печати.
|
||||
|
||||
Пересборка макета из DSL — это полная перегенерация, а не точечная правка XML, поэтому
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "Рисунки: типы, картинки, линия, стороны, расшифровка",
|
||||
"input": {
|
||||
"columns": 4,
|
||||
"styles": {
|
||||
"заливка": { "backColor": "web:LightYellow" }
|
||||
},
|
||||
"pictures": {
|
||||
"стоп": { "ref": "v8ui:Стоп48" },
|
||||
"точка": { "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg==", "transparent": false }
|
||||
},
|
||||
"areas": [{ "rows": [["Бланк"]] }],
|
||||
"drawings": [
|
||||
{ "type": "Picture", "picture": "стоп", "name": "Знак",
|
||||
"begin": { "row": 1, "col": 1, "dy": 0, "dx": 0 },
|
||||
"end": { "row": 2, "col": 2, "dy": 20, "dx": 40 },
|
||||
"pictureSize": "Proportionally" },
|
||||
{ "type": "Picture", "picture": "точка", "detail": "ПараметрРасшифровки",
|
||||
"begin": { "row": 3, "col": 1 },
|
||||
"end": { "row": 3, "col": 2, "dy": 34, "dx": 115 } },
|
||||
{ "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": "Ellipse", "line": "Solid",
|
||||
"begin": { "row": 8, "col": 1 }, "end": { "row": 9, "col": 2 } },
|
||||
{ "type": "Line", "zOrder": 9,
|
||||
"begin": { "row": 11, "col": 1 }, "end": { "row": 11, "col": 4 } },
|
||||
{ "type": "Text", "id": 42, "text": { "ru": "Подпись", "en": "Signature" },
|
||||
"begin": { "row": 13, "col": 1 }, "end": { "row": 13, "col": 3, "dy": 12 } }
|
||||
]
|
||||
},
|
||||
"params": { "outputPath": "Template.xml" }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "Ошибка: прозрачность задана у картинки без данных",
|
||||
"input": {
|
||||
"columns": 2,
|
||||
"pictures": { "пусто": { "transparent": true } },
|
||||
"areas": [{ "rows": [["Бланк"]] }]
|
||||
},
|
||||
"params": { "outputPath": "Template.xml" },
|
||||
"expectError": "pictures[пусто]: 'transparent' and 'transparentPixel' require 'data'"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "Ошибка: рисунок ссылается на необъявленную картинку",
|
||||
"input": {
|
||||
"columns": 2,
|
||||
"areas": [{ "rows": [["Бланк"]] }],
|
||||
"drawings": [
|
||||
{ "type": "Picture", "picture": "нет-такой",
|
||||
"begin": { "row": 1, "col": 1 }, "end": { "row": 2, "col": 2 } }
|
||||
]
|
||||
},
|
||||
"params": { "outputPath": "Template.xml" },
|
||||
"expectError": "drawings[1]: unknown 'picture' \"нет-такой\" — not declared in pictures"
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<languageSettings>
|
||||
<currentLanguage>ru</currentLanguage>
|
||||
<defaultLanguage>ru</defaultLanguage>
|
||||
<languageInfo>
|
||||
<id>ru</id>
|
||||
<code>Русский</code>
|
||||
<description>Русский</description>
|
||||
</languageInfo>
|
||||
<languageInfo>
|
||||
<id>en</id>
|
||||
<code>Английский</code>
|
||||
<description>Английский</description>
|
||||
</languageInfo>
|
||||
</languageSettings>
|
||||
<columns>
|
||||
<size>5</size>
|
||||
</columns>
|
||||
<rowsItem>
|
||||
<index>0</index>
|
||||
<row>
|
||||
<empty>true</empty>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>1</id>
|
||||
<formatIndex>0</formatIndex>
|
||||
<detailParameter>ПараметрРасшифровки</detailParameter>
|
||||
<beginRow>1</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>3</endRow>
|
||||
<endRowOffset>34</endRowOffset>
|
||||
<beginColumn>1</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>115</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>1</zOrder>
|
||||
<pictureIndex>1</pictureIndex>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>2</id>
|
||||
<formatIndex>1</formatIndex>
|
||||
<beginRow>6</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>8</endRow>
|
||||
<endRowOffset>34</endRowOffset>
|
||||
<beginColumn>1</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>115</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>RealSize</pictureSize>
|
||||
<zOrder>2</zOrder>
|
||||
<pictureIndex>1</pictureIndex>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>3</id>
|
||||
<formatIndex>2</formatIndex>
|
||||
<beginRow>12</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>14</endRow>
|
||||
<endRowOffset>34</endRowOffset>
|
||||
<beginColumn>1</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>115</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Proportionally</pictureSize>
|
||||
<zOrder>3</zOrder>
|
||||
<pictureIndex>1</pictureIndex>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>4</id>
|
||||
<formatIndex>3</formatIndex>
|
||||
<beginRow>18</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>20</endRow>
|
||||
<endRowOffset>34</endRowOffset>
|
||||
<beginColumn>1</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>115</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Tile</pictureSize>
|
||||
<zOrder>4</zOrder>
|
||||
<pictureIndex>1</pictureIndex>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>5</id>
|
||||
<formatIndex>0</formatIndex>
|
||||
<beginRow>23</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>25</endRow>
|
||||
<endRowOffset>34</endRowOffset>
|
||||
<beginColumn>1</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>115</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>AutoSize</pictureSize>
|
||||
<zOrder>5</zOrder>
|
||||
<pictureIndex>1</pictureIndex>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>6</id>
|
||||
<formatIndex>0</formatIndex>
|
||||
<beginRow>28</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>30</endRow>
|
||||
<endRowOffset>34</endRowOffset>
|
||||
<beginColumn>1</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>115</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>ByFontSize</pictureSize>
|
||||
<zOrder>6</zOrder>
|
||||
<pictureIndex>1</pictureIndex>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>7</id>
|
||||
<formatIndex>1</formatIndex>
|
||||
<beginRow>1</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>2</endRow>
|
||||
<endRowOffset>31</endRowOffset>
|
||||
<beginColumn>3</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>3</endColumn>
|
||||
<endColumnOffset>60</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>7</zOrder>
|
||||
<pictureIndex>2</pictureIndex>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Line</drawingType>
|
||||
<id>8</id>
|
||||
<formatIndex>4</formatIndex>
|
||||
<beginRow>7</beginRow>
|
||||
<beginRowOffset>19</beginRowOffset>
|
||||
<endRow>4</endRow>
|
||||
<endRowOffset>24</endRowOffset>
|
||||
<beginColumn>2</beginColumn>
|
||||
<beginColumnOffset>106</beginColumnOffset>
|
||||
<endColumn>4</endColumn>
|
||||
<endColumnOffset>103</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>8</zOrder>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Rectangle</drawingType>
|
||||
<id>9</id>
|
||||
<formatIndex>5</formatIndex>
|
||||
<beginRow>8</beginRow>
|
||||
<beginRowOffset>36</beginRowOffset>
|
||||
<endRow>12</endRow>
|
||||
<endRowOffset>10</endRowOffset>
|
||||
<beginColumn>2</beginColumn>
|
||||
<beginColumnOffset>108</beginColumnOffset>
|
||||
<endColumn>4</endColumn>
|
||||
<endColumnOffset>125</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>9</zOrder>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Ellipse</drawingType>
|
||||
<id>10</id>
|
||||
<formatIndex>6</formatIndex>
|
||||
<beginRow>14</beginRow>
|
||||
<beginRowOffset>22</beginRowOffset>
|
||||
<endRow>17</endRow>
|
||||
<endRowOffset>12</endRowOffset>
|
||||
<beginColumn>2</beginColumn>
|
||||
<beginColumnOffset>134</beginColumnOffset>
|
||||
<endColumn>4</endColumn>
|
||||
<endColumnOffset>139</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>10</zOrder>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Text</drawingType>
|
||||
<id>11</id>
|
||||
<formatIndex>7</formatIndex>
|
||||
<text>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Текст</v8:content>
|
||||
</v8:item>
|
||||
</text>
|
||||
<beginRow>19</beginRow>
|
||||
<beginRowOffset>38</beginRowOffset>
|
||||
<endRow>23</endRow>
|
||||
<endRowOffset>17</endRowOffset>
|
||||
<beginColumn>2</beginColumn>
|
||||
<beginColumnOffset>101</beginColumnOffset>
|
||||
<endColumn>4</endColumn>
|
||||
<endColumnOffset>146</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>11</zOrder>
|
||||
</drawing>
|
||||
<templateMode>true</templateMode>
|
||||
<defaultFormatIndex>8</defaultFormatIndex>
|
||||
<height>31</height>
|
||||
<vgRows>31</vgRows>
|
||||
<namedItem xsi:type="NamedItemDrawing">
|
||||
<name>Звездочка</name>
|
||||
<drawingID>7</drawingID>
|
||||
</namedItem>
|
||||
<line width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentDrawingLineType">None</v8ui:style>
|
||||
</line>
|
||||
<line width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentDrawingLineType">Dashed</v8ui:style>
|
||||
</line>
|
||||
<line width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentDrawingLineType">DashDottedDotted</v8ui:style>
|
||||
</line>
|
||||
<line width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentDrawingLineType">DashDotted</v8ui:style>
|
||||
</line>
|
||||
<format>
|
||||
<drawingBorder>0</drawingBorder>
|
||||
</format>
|
||||
<format>
|
||||
<backColor xmlns:d3p1="http://v8.1c.ru/8.1/data/ui/colors/web">d3p1:HoneyDew</backColor>
|
||||
</format>
|
||||
<format>
|
||||
<patternColor>style:SpecialTextColor</patternColor>
|
||||
<pattern>Pattern4</pattern>
|
||||
</format>
|
||||
<format>
|
||||
<verticalAlignment>Top</verticalAlignment>
|
||||
<backColor>style:FieldBackColor</backColor>
|
||||
</format>
|
||||
<format>
|
||||
<drawingBorder>1</drawingBorder>
|
||||
<verticalAlignment>Top</verticalAlignment>
|
||||
<backColor>style:FieldBackColor</backColor>
|
||||
</format>
|
||||
<format>
|
||||
<drawingBorder>2</drawingBorder>
|
||||
<verticalAlignment>Top</verticalAlignment>
|
||||
<backColor>style:FieldBackColor</backColor>
|
||||
</format>
|
||||
<format>
|
||||
<drawingBorder>3</drawingBorder>
|
||||
<verticalAlignment>Top</verticalAlignment>
|
||||
<backColor>style:FieldBackColor</backColor>
|
||||
</format>
|
||||
<format>
|
||||
<width>72</width>
|
||||
</format>
|
||||
<picture>
|
||||
<index>0</index>
|
||||
<picture ref="v8ui:Стоп48"/>
|
||||
</picture>
|
||||
<picture>
|
||||
<index>1</index>
|
||||
<picture t="false">iVBORw0KGgoAAAANSUhEUgAAABkAAAAeCAYAAADZ7LXbAAAAAXNSR0IArs4c6QAA
|
||||
AARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAE9SURBVEhL7ZOh
|
||||
coQwEIb7tBExmBjEGUwNBhGDiUH0DWIQmJgYREwM5gwCcwZT83cLuWlhrhOCqOJT
|
||||
uwszX3Y3ecM/cEmSuCRJXJIkTkmszJFLG7I4JyQ9JGNgTFJ0jFOddCVJyi5kcaKS
|
||||
XmZgPIdyc6gAj7ZA0T5CBsyuhqDustqFypaoZPjIwZfxCNRP0aChhzWcrUS2fOe4
|
||||
6XEt7jg8Lt9rNGWJxk/wWkFpj8k3KMsGuvfhr9ek74RGs3bGqbNQi5Akme8W1hnI
|
||||
jIGLGp2zcPefXf1FVPI5GqhCLKfPnm/jMWAIezcVXQzqShQKZlpre6ISffseDQmq
|
||||
X4/PVKhMiAm7iOi/9zZUtsTHNXkYt701rubgu4WMNEa6Ey9JXzzRCDq1aEIWw56R
|
||||
eChaPMsURcc41UkqlySJS5IA8AW5c2KJOTY6eAAAAABJRU5ErkJggg==</picture>
|
||||
</picture>
|
||||
</document>
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "Картинки: пустая запись и пиксель прозрачного цвета",
|
||||
"input": {
|
||||
"columns": 2,
|
||||
"pictures": {
|
||||
"пусто": {},
|
||||
"точка": {
|
||||
"data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg==",
|
||||
"transparent": true,
|
||||
"transparentPixel": { "x": 3, "y": 5 }
|
||||
}
|
||||
},
|
||||
"areas": [{ "rows": [["Бланк"]] }],
|
||||
"drawings": [
|
||||
{ "type": "Picture", "picture": "точка",
|
||||
"begin": { "row": 1, "col": 1 }, "end": { "row": 2, "col": 2 } }
|
||||
]
|
||||
},
|
||||
"params": { "outputPath": "Template.xml" }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "Раундтрип макета ПЛАТФОРМЫ байт в байт: Рисунки2",
|
||||
"setup": "fixture:platform-roundtrip",
|
||||
"preRun": [
|
||||
{ "script": "mxl-decompile/scripts/mxl-decompile",
|
||||
"args": { "-TemplatePath": "Рисунки2.xml", "-OutputPath": "back.json" },
|
||||
"cwd": "{workDir}" }
|
||||
],
|
||||
"params": { "outputPath": "out.xml" },
|
||||
"noSnapshot": "эталон — файл платформы, сверяется expect.filesEqual",
|
||||
"expect": { "filesEqual": { "actual": "out.xml", "expected": "Рисунки2.xml" } },
|
||||
"inputFrom": "back.json"
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<languageSettings>
|
||||
<currentLanguage>ru</currentLanguage>
|
||||
<defaultLanguage>ru</defaultLanguage>
|
||||
<languageInfo>
|
||||
<id>ru</id>
|
||||
<code>Русский</code>
|
||||
<description>Русский</description>
|
||||
</languageInfo>
|
||||
</languageSettings>
|
||||
<columns>
|
||||
<size>4</size>
|
||||
</columns>
|
||||
<rowsItem>
|
||||
<index>0</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>0</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Бланк</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>1</id>
|
||||
<formatIndex>0</formatIndex>
|
||||
<beginRow>0</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>1</endRow>
|
||||
<endRowOffset>20</endRowOffset>
|
||||
<beginColumn>0</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>40</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Proportionally</pictureSize>
|
||||
<zOrder>1</zOrder>
|
||||
<pictureIndex>1</pictureIndex>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>2</id>
|
||||
<formatIndex>0</formatIndex>
|
||||
<detailParameter>ПараметрРасшифровки</detailParameter>
|
||||
<beginRow>2</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>2</endRow>
|
||||
<endRowOffset>34</endRowOffset>
|
||||
<beginColumn>0</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>115</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>2</zOrder>
|
||||
<pictureIndex>2</pictureIndex>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Rectangle</drawingType>
|
||||
<id>3</id>
|
||||
<formatIndex>1</formatIndex>
|
||||
<beginRow>4</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>5</endRow>
|
||||
<endRowOffset>0</endRowOffset>
|
||||
<beginColumn>0</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>2</endColumn>
|
||||
<endColumnOffset>0</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>3</zOrder>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Ellipse</drawingType>
|
||||
<id>4</id>
|
||||
<formatIndex>2</formatIndex>
|
||||
<beginRow>7</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>8</endRow>
|
||||
<endRowOffset>0</endRowOffset>
|
||||
<beginColumn>0</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>0</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>4</zOrder>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Line</drawingType>
|
||||
<id>5</id>
|
||||
<formatIndex>0</formatIndex>
|
||||
<beginRow>10</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>10</endRow>
|
||||
<endRowOffset>0</endRowOffset>
|
||||
<beginColumn>0</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>3</endColumn>
|
||||
<endColumnOffset>0</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>9</zOrder>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Text</drawingType>
|
||||
<id>42</id>
|
||||
<formatIndex>0</formatIndex>
|
||||
<text>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Подпись</v8:content>
|
||||
</v8:item>
|
||||
<v8:item>
|
||||
<v8:lang>en</v8:lang>
|
||||
<v8:content>Signature</v8:content>
|
||||
</v8:item>
|
||||
</text>
|
||||
<beginRow>12</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>12</endRow>
|
||||
<endRowOffset>12</endRowOffset>
|
||||
<beginColumn>0</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>2</endColumn>
|
||||
<endColumnOffset>0</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>6</zOrder>
|
||||
</drawing>
|
||||
<templateMode>true</templateMode>
|
||||
<defaultFormatIndex>3</defaultFormatIndex>
|
||||
<height>13</height>
|
||||
<vgRows>13</vgRows>
|
||||
<namedItem xsi:type="NamedItemDrawing">
|
||||
<name>Знак</name>
|
||||
<drawingID>1</drawingID>
|
||||
</namedItem>
|
||||
<line width="2" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentDrawingLineType">Dashed</v8ui:style>
|
||||
</line>
|
||||
<line width="1" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentDrawingLineType">Solid</v8ui:style>
|
||||
</line>
|
||||
<format>
|
||||
<drawingBorder>0</drawingBorder>
|
||||
<drawingHaveLeftBorder>true</drawingHaveLeftBorder>
|
||||
<drawingHaveTopBorder>true</drawingHaveTopBorder>
|
||||
<drawingHaveRightBorder>false</drawingHaveRightBorder>
|
||||
<drawingHaveBottomBorder>false</drawingHaveBottomBorder>
|
||||
<backColor xmlns:d3p1="http://v8.1c.ru/8.1/data/ui/colors/web">d3p1:LightYellow</backColor>
|
||||
</format>
|
||||
<format>
|
||||
<drawingBorder>1</drawingBorder>
|
||||
</format>
|
||||
<format>
|
||||
<width>10</width>
|
||||
</format>
|
||||
<picture>
|
||||
<index>0</index>
|
||||
<picture ref="v8ui:Стоп48"/>
|
||||
</picture>
|
||||
<picture>
|
||||
<index>1</index>
|
||||
<picture t="false">iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg==</picture>
|
||||
</picture>
|
||||
</document>
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<languageSettings>
|
||||
<currentLanguage>ru</currentLanguage>
|
||||
<defaultLanguage>ru</defaultLanguage>
|
||||
<languageInfo>
|
||||
<id>ru</id>
|
||||
<code>Русский</code>
|
||||
<description>Русский</description>
|
||||
</languageInfo>
|
||||
</languageSettings>
|
||||
<columns>
|
||||
<size>2</size>
|
||||
</columns>
|
||||
<rowsItem>
|
||||
<index>0</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>0</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Бланк</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>1</id>
|
||||
<formatIndex>0</formatIndex>
|
||||
<beginRow>0</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>1</endRow>
|
||||
<endRowOffset>0</endRowOffset>
|
||||
<beginColumn>0</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>0</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>1</zOrder>
|
||||
<pictureIndex>2</pictureIndex>
|
||||
</drawing>
|
||||
<templateMode>true</templateMode>
|
||||
<defaultFormatIndex>1</defaultFormatIndex>
|
||||
<height>2</height>
|
||||
<vgRows>2</vgRows>
|
||||
<format>
|
||||
<width>10</width>
|
||||
</format>
|
||||
<picture>
|
||||
<index>0</index>
|
||||
<picture/>
|
||||
</picture>
|
||||
<picture>
|
||||
<index>1</index>
|
||||
<picture t="true" tx="3" ty="5">iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg==</picture>
|
||||
</picture>
|
||||
</document>
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "Roundtrip — рисунки и палитра картинок",
|
||||
"preRun": [
|
||||
{ "script": "mxl-compile/scripts/mxl-compile",
|
||||
"input": {
|
||||
"columns": 4,
|
||||
"styles": { "заливка": { "backColor": "web:LightYellow" } },
|
||||
"pictures": {
|
||||
"стоп": { "ref": "v8ui:Стоп48" },
|
||||
"пусто": {}
|
||||
},
|
||||
"areas": [{ "rows": [["Бланк"]] }],
|
||||
"drawings": [
|
||||
{ "type": "Picture", "picture": "стоп", "name": "Знак",
|
||||
"begin": { "row": 1, "col": 1 }, "end": { "row": 2, "col": 2, "dy": 20, "dx": 40 },
|
||||
"pictureSize": "Proportionally" },
|
||||
{ "type": "Rectangle", "style": "заливка", "line": { "style": "Dashed", "width": 2 },
|
||||
"sides": { "left": true, "top": true, "right": false, "bottom": false },
|
||||
"begin": { "row": 4, "col": 1 }, "end": { "row": 5, "col": 3 } },
|
||||
{ "type": "Text", "id": 42, "text": { "ru": "Подпись", "en": "Signature" },
|
||||
"begin": { "row": 7, "col": 1 }, "end": { "row": 7, "col": 3, "dy": 12 } }
|
||||
]
|
||||
},
|
||||
"args": { "-JsonPath": "{inputFile}", "-OutputPath": "Template.xml" },
|
||||
"cwd": "{workDir}" }
|
||||
],
|
||||
"params": { "templatePath": "Template.xml" },
|
||||
"args_extra": ["-OutputPath", "{workDir}/back.json"],
|
||||
"expect": { "files": ["back.json"], "stdoutContains": "[OK] Decompiled:" }
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<languageSettings>
|
||||
<currentLanguage>ru</currentLanguage>
|
||||
<defaultLanguage>ru</defaultLanguage>
|
||||
<languageInfo>
|
||||
<id>ru</id>
|
||||
<code>Русский</code>
|
||||
<description>Русский</description>
|
||||
</languageInfo>
|
||||
</languageSettings>
|
||||
<columns>
|
||||
<size>4</size>
|
||||
</columns>
|
||||
<rowsItem>
|
||||
<index>0</index>
|
||||
<row>
|
||||
<c>
|
||||
<c>
|
||||
<f>0</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Бланк</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</c>
|
||||
</c>
|
||||
</row>
|
||||
</rowsItem>
|
||||
<drawing>
|
||||
<drawingType>Picture</drawingType>
|
||||
<id>1</id>
|
||||
<formatIndex>0</formatIndex>
|
||||
<beginRow>0</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>1</endRow>
|
||||
<endRowOffset>20</endRowOffset>
|
||||
<beginColumn>0</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>1</endColumn>
|
||||
<endColumnOffset>40</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Proportionally</pictureSize>
|
||||
<zOrder>1</zOrder>
|
||||
<pictureIndex>1</pictureIndex>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Rectangle</drawingType>
|
||||
<id>2</id>
|
||||
<formatIndex>1</formatIndex>
|
||||
<beginRow>3</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>4</endRow>
|
||||
<endRowOffset>0</endRowOffset>
|
||||
<beginColumn>0</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>2</endColumn>
|
||||
<endColumnOffset>0</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>2</zOrder>
|
||||
</drawing>
|
||||
<drawing>
|
||||
<drawingType>Text</drawingType>
|
||||
<id>42</id>
|
||||
<formatIndex>0</formatIndex>
|
||||
<text>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Подпись</v8:content>
|
||||
</v8:item>
|
||||
<v8:item>
|
||||
<v8:lang>en</v8:lang>
|
||||
<v8:content>Signature</v8:content>
|
||||
</v8:item>
|
||||
</text>
|
||||
<beginRow>6</beginRow>
|
||||
<beginRowOffset>0</beginRowOffset>
|
||||
<endRow>6</endRow>
|
||||
<endRowOffset>12</endRowOffset>
|
||||
<beginColumn>0</beginColumn>
|
||||
<beginColumnOffset>0</beginColumnOffset>
|
||||
<endColumn>2</endColumn>
|
||||
<endColumnOffset>0</endColumnOffset>
|
||||
<autoSize>false</autoSize>
|
||||
<pictureSize>Stretch</pictureSize>
|
||||
<zOrder>3</zOrder>
|
||||
</drawing>
|
||||
<templateMode>true</templateMode>
|
||||
<defaultFormatIndex>2</defaultFormatIndex>
|
||||
<height>7</height>
|
||||
<vgRows>7</vgRows>
|
||||
<namedItem xsi:type="NamedItemDrawing">
|
||||
<name>Знак</name>
|
||||
<drawingID>1</drawingID>
|
||||
</namedItem>
|
||||
<line width="2" gap="false">
|
||||
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentDrawingLineType">Dashed</v8ui:style>
|
||||
</line>
|
||||
<format>
|
||||
<drawingBorder>0</drawingBorder>
|
||||
<drawingHaveLeftBorder>true</drawingHaveLeftBorder>
|
||||
<drawingHaveTopBorder>true</drawingHaveTopBorder>
|
||||
<drawingHaveRightBorder>false</drawingHaveRightBorder>
|
||||
<drawingHaveBottomBorder>false</drawingHaveBottomBorder>
|
||||
<backColor xmlns:d3p1="http://v8.1c.ru/8.1/data/ui/colors/web">d3p1:LightYellow</backColor>
|
||||
</format>
|
||||
<format>
|
||||
<width>10</width>
|
||||
</format>
|
||||
<picture>
|
||||
<index>0</index>
|
||||
<picture ref="v8ui:Стоп48"/>
|
||||
</picture>
|
||||
<picture>
|
||||
<index>1</index>
|
||||
<picture/>
|
||||
</picture>
|
||||
</document>
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"columns": 4,
|
||||
"defaultWidth": 10,
|
||||
"fonts": {},
|
||||
"styles": { "bg": { "backColor": "web:LightYellow" } },
|
||||
"pictures": { "pic1": { "ref": "v8ui:Стоп48" }, "pic2": {} },
|
||||
"drawings": [
|
||||
{ "type": "Picture", "name": "Знак", "picture": "pic1", "begin": { "row": 1, "col": 1, "dy": 0, "dx": 0 }, "end": { "row": 2, "col": 2, "dy": 20, "dx": 40 }, "pictureSize": "Proportionally" },
|
||||
{ "type": "Rectangle", "style": "bg", "line": { "style": "Dashed", "width": 2 }, "sides": { "left": true, "top": true, "right": false, "bottom": false }, "begin": { "row": 4, "col": 1, "dy": 0, "dx": 0 }, "end": { "row": 5, "col": 3, "dy": 0, "dx": 0 } },
|
||||
{ "type": "Text", "id": 42, "text": { "ru": "Подпись", "en": "Signature" }, "begin": { "row": 7, "col": 1, "dy": 0, "dx": 0 }, "end": { "row": 7, "col": 3, "dy": 12, "dx": 0 } }
|
||||
],
|
||||
"areas": [{ "rows": [["Бланк"]] }]
|
||||
}
|
||||
Reference in New Issue
Block a user