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): колонтитулы и параметры печати
Ключи header и footer описывают колонтитул: три слота (left, center, right), общий шрифт и вертикальное выравнивание, признак вывода и страница, с которой печатать. Ключ printSettings — плоский набор параметров печати с именами тегов платформы; порядок компилятор выставляет сам, незнакомый ключ отвергает. Слот устроен как ячейка: ссылка на формат плюс текст. Текст бывает двух видов, и это не текст против шаблона, а обычная строка против форматированной: у форматированной разметка живёт прямо в содержимом (<b>жирный</>, <fontsize 12>, <colorstyle -16>), поэтому она возится как есть. Признак вывода и стартовая страница лежат в формате как <height> и <width>, но читаются только у записи с <height>: палитра дедуплицирована, и колонтитул без своих настроек ссылается на чужую запись, где <width> — ширина колонки (637 таких ссылок против 153 своих). Перенос строки внутри текста колонтитула платформа хранит голым LF при CRLF во всём остальном файле — единственное такое место в документе, поэтому содержимое пишется одной строкой вывода. Формат колонтитула регистрируется до отсева неиспользуемых шрифтов: иначе шрифт, на который ссылается только колонтитул, выбрасывался бы из палитры. Стенд Колонтитулы собирается байт в байт обоими портами и добавлен в платформенные фикстуры. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1e0b82d419
commit
702a3b6a8d
@@ -64,6 +64,8 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-compile.ps1" -J
|
||||
namedAreas: [{ name, rows, cols }],
|
||||
rowGroups: [{ rows, name, collapsed, titleLocation }],
|
||||
columnGroups: [{ cols, name, collapsed, titleLocation }],
|
||||
header: { left, center, right, font, verticalAlignment, show, startPage }, footer: { … },
|
||||
printSettings: { pageOrientation, topMargin, …, fitToPage, firstPageNumber },
|
||||
columnSets: { name: { columns, columnWidths, columnStyles } }
|
||||
}
|
||||
```
|
||||
@@ -83,6 +85,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/mxl-compile.ps1" -J
|
||||
- `rowspan` — объединение строк вниз (rowStyle учитывает занятые ячейки)
|
||||
- Содержимое ячейки задаётся одним из ключей: `param` — параметр заполнения, `text` — статический текст, `template` — текст со вставками `[Параметр]`
|
||||
- `rowGroups`/`columnGroups` — группы строк и колонок (сворачиваются кнопкой на полях): плоский список диапазонов, вложенность выражена вхождением одного в другой
|
||||
- `header`/`footer` — колонтитулы: три слота (`left`/`center`/`right`), общий шрифт и вертикальное выравнивание; текст может нести поля `[&НомерСтраницы]`, `[&Дата]`
|
||||
- `note` — всплывающая подсказка у ячейки: строка, объект языков или `{ text, style, autoSize, box }`
|
||||
- `valueType` делает ячейку полем ввода (`"Number(15,3,nonneg)"`, `"String(10)"`, `"CatalogRef.Валюты"`, составной через ` + `); текста в такой ячейке быть не может, значение задаётся ключом `value`
|
||||
|
||||
|
||||
@@ -89,6 +89,8 @@
|
||||
| `columnSets` | нет | — | Дополнительные колоночные раскладки (см. `styles.md`) |
|
||||
| `rowGroups` | нет | — | Группы строк (см. ниже) |
|
||||
| `columnGroups` | нет | — | Группы колонок (см. ниже) |
|
||||
| `header` / `footer` | нет | — | Верхний и нижний колонтитулы (см. ниже) |
|
||||
| `printSettings` | нет | — | Параметры печати (см. ниже) |
|
||||
|
||||
## Области (`areas[]`)
|
||||
|
||||
@@ -296,6 +298,56 @@
|
||||
Координаты ячейки в примечании не задаются. `autoSize` и `box` независимы: при автоподгоне
|
||||
размера положение окошка всё равно хранится.
|
||||
|
||||
## Колонтитулы
|
||||
|
||||
У верхнего и нижнего колонтитула по три слота — `left`, `center`, `right` — и общие настройки:
|
||||
|
||||
```json
|
||||
"header": {
|
||||
"font": "мелкий",
|
||||
"verticalAlignment": "Bottom",
|
||||
"startPage": 2,
|
||||
"left": "Слева\nвторая строка",
|
||||
"center": "Стр. [&НомерСтраницы] из [&СтраницВсего]",
|
||||
"right": { "ru": "Справа", "en": "Right" }
|
||||
},
|
||||
"footer": {
|
||||
"show": false,
|
||||
"center": { "formatted": "<b>Итог</> <colorstyle -16>красным</>" }
|
||||
}
|
||||
```
|
||||
|
||||
| Поле | По умолч. | Описание |
|
||||
|------|-----------|----------|
|
||||
| `left`, `center`, `right` | — | Текст слота: строка, объект «язык → текст» или `{ "formatted": … }` |
|
||||
| `font` | — | Имя шрифта из `fonts` — на весь колонтитул |
|
||||
| `verticalAlignment` | — | Положение текста по вертикали: `Top`, `Center`, `Bottom` |
|
||||
| `show` | `true` | Выводить ли колонтитул |
|
||||
| `startPage` | `1` | Страница, с которой колонтитул печатается |
|
||||
|
||||
Текст может быть многострочным (`\n`) и содержать поля `[&НомерСтраницы]`, `[&СтраницВсего]`,
|
||||
`[&Дата]`, `[&Время]` — платформа подставляет их при печати. `{ "formatted": … }` — форматированная
|
||||
строка: разметка живёт прямо в тексте (`<b>жирный</>`, `<fontsize 12>`, `<colorstyle -16>`).
|
||||
|
||||
## Параметры печати
|
||||
|
||||
Плоский объект; имя ключа совпадает с именем свойства в выгрузке:
|
||||
|
||||
```json
|
||||
"printSettings": {
|
||||
"pageOrientation": "Landscape",
|
||||
"topMargin": 500, "leftMargin": 500, "bottomMargin": 500, "rightMargin": 500,
|
||||
"headerSize": 1000, "footerSize": 1000,
|
||||
"fitToPage": true, "firstPageNumber": 7
|
||||
}
|
||||
```
|
||||
|
||||
Допустимые ключи: `pageOrientation`, `scale`, `collate`, `copies`, `perPage`, `topMargin`,
|
||||
`leftMargin`, `bottomMargin`, `rightMargin`, `headerSize`, `footerSize`, `fitToPage`,
|
||||
`blackAndWhite`, `printerName`, `paper`, `paperSource`, `pageWidth`, `pageHeight`, `duplexType`,
|
||||
`pagePlacementAlternation`, `firstPageNumber`. Незнакомый ключ — ошибка. Порядок в объекте не
|
||||
важен: компилятор пишет свойства в том порядке, что и платформа.
|
||||
|
||||
## Группы строк и колонок
|
||||
|
||||
Диапазон строк или колонок, который сворачивается кнопкой на полях. Задаются плоским списком;
|
||||
@@ -339,7 +391,7 @@ XML не возвращается.
|
||||
|
||||
- объединения, не привязанные к ячейке (по всей высоте или ширине документа);
|
||||
- рисунки и картинки, в том числе штрихкоды;
|
||||
- колонтитулы, параметры печати, область печати.
|
||||
- область печати.
|
||||
|
||||
Пересборка макета из DSL — это полная перегенерация, а не точечная правка XML, поэтому
|
||||
diff после round-trip обычно шире фактической доработки.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# mxl-compile v1.44 — Compile 1C spreadsheet from JSON
|
||||
# mxl-compile v1.45 — Compile 1C spreadsheet from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -1485,9 +1485,108 @@ foreach ($area in $def.areas) {
|
||||
}
|
||||
}
|
||||
|
||||
# 7d-ter. Колонтитулы. Шесть слотов: left/center/right у верхнего и нижнего. Слот устроен
|
||||
# как ячейка — ссылка на формат плюс текст, — а формат несёт то, что в диалоге задаётся на весь
|
||||
# колонтитул: шрифт, вертикальное выравнивание, признак вывода (<height> 1/-1) и страницу,
|
||||
# с которой колонтитул печатается (<width>).
|
||||
$script:headerSlots = @('left', 'center', 'right')
|
||||
|
||||
function Get-HeaderFormatIndex {
|
||||
param($hf)
|
||||
if ($null -eq $hf) { return 0 }
|
||||
$props = @{}
|
||||
if ($hf.font -and $fontMap.Contains("$($hf.font)")) { $props['font'] = $fontMap["$($hf.font)"] }
|
||||
# Признак вывода и стартовая страница осмысленны только вместе: платформа пишет их парой.
|
||||
$props['height'] = if ($hf.show -eq $false -or "$($hf.show)" -eq 'false') { -1 } else { 1 }
|
||||
$props['width'] = if ($hf.startPage) { [int]$hf.startPage } else { 1 }
|
||||
if ($hf.verticalAlignment) { $props['verticalAlignment'] = "$($hf.verticalAlignment)" }
|
||||
return Register-Format $props
|
||||
}
|
||||
|
||||
function Emit-HeaderSlot {
|
||||
param([string]$tag, $value, [int]$fmtIdx)
|
||||
if ($null -eq $value) { return }
|
||||
# Форматированная строка платформы — тот же текст, только разметка живёт внутри содержимого
|
||||
# (<b>жирный</>, <fontsize 12>…), поэтому возим её как есть и различаем именем тега.
|
||||
$formatted = $false
|
||||
$text = $value
|
||||
if ($value -is [System.Management.Automation.PSCustomObject] -and $null -ne $value.formatted) {
|
||||
$formatted = $true
|
||||
$text = $value.formatted
|
||||
}
|
||||
$pairs = @()
|
||||
if ($text -is [System.Collections.IDictionary]) {
|
||||
foreach ($k in $text.Keys) { $pairs += @{ Lang = "$k"; Text = "$($text[$k])" } }
|
||||
} elseif ($text -is [System.Management.Automation.PSCustomObject]) {
|
||||
foreach ($pr in $text.PSObject.Properties) { $pairs += @{ Lang = $pr.Name; Text = "$($pr.Value)" } }
|
||||
} else {
|
||||
foreach ($l in $textLanguages) { $pairs += @{ Lang = $l; Text = "$text" } }
|
||||
}
|
||||
$textTag = if ($formatted) { 'tfl' } else { 'tl' }
|
||||
X "`t<$tag>"
|
||||
X "`t`t<f>$fmtIdx</f>"
|
||||
if ($pairs.Count -eq 0) {
|
||||
X "`t`t<$textTag/>"
|
||||
} else {
|
||||
X "`t`t<$textTag>"
|
||||
foreach ($pr in $pairs) {
|
||||
X "`t`t`t<v8:item>"
|
||||
X "`t`t`t`t<v8:lang>$($pr.Lang)</v8:lang>"
|
||||
# Перенос строки внутри колонтитула платформа хранит голым LF, тогда как весь файл
|
||||
# идёт CRLF. Пишем содержимое одной строкой вывода, чтобы перенос не переписался.
|
||||
X "`t`t`t`t<v8:content>$(Esc-XmlText $pr.Text)</v8:content>"
|
||||
X "`t`t`t</v8:item>"
|
||||
}
|
||||
X "`t`t</$textTag>"
|
||||
}
|
||||
X "`t</$tag>"
|
||||
}
|
||||
|
||||
# Параметры печати. Имя ключа совпадает с именем тега в выгрузке, как у свойств стиля.
|
||||
# Порядок снят с корпуса (2350 макетов): платформа пишет теги строго в этой последовательности.
|
||||
function Get-PrintSettingsOrder {
|
||||
return @(
|
||||
'pageOrientation', 'scale', 'collate', 'copies', 'perPage',
|
||||
'topMargin', 'leftMargin', 'bottomMargin', 'rightMargin', 'headerSize', 'footerSize',
|
||||
'fitToPage', 'blackAndWhite', 'printerName', 'paper', 'paperSource',
|
||||
'pageWidth', 'pageHeight', 'duplexType', 'pagePlacementAlternation', 'firstPageNumber'
|
||||
)
|
||||
}
|
||||
|
||||
function Emit-PrintSettings {
|
||||
param($ps)
|
||||
if ($null -eq $ps) { return }
|
||||
$order = Get-PrintSettingsOrder
|
||||
$known = @{}
|
||||
foreach ($k in $order) { $known[$k] = $true }
|
||||
foreach ($pr in $ps.PSObject.Properties) {
|
||||
if (-not $known.ContainsKey($pr.Name)) {
|
||||
[Console]::Error.WriteLine("printSettings: unknown key `"$($pr.Name)`". Allowed: $($order -join ', ')")
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
$emitted = @()
|
||||
foreach ($tag in $order) {
|
||||
$v = $ps.$tag
|
||||
if ($null -eq $v) { continue }
|
||||
if ($v -is [bool]) { $v = if ($v) { 'true' } else { 'false' } }
|
||||
$emitted += "`t`t<$tag>$(Esc-XmlText "$v")</$tag>"
|
||||
}
|
||||
if ($emitted.Count -eq 0) { return }
|
||||
X "`t<printSettings>"
|
||||
foreach ($line in $emitted) { X $line }
|
||||
X "`t</printSettings>"
|
||||
}
|
||||
|
||||
# Формат по умолчанию — последняя запись палитры (см. выше).
|
||||
$defaultFormatIndex = Register-Format @{ width = $defaultWidth }
|
||||
|
||||
# Формат колонтитула заводим здесь же: он идёт в палитре следом за умолчанием, и он
|
||||
# обязан попасть в реестр ДО отсева неиспользуемых шрифтов — иначе шрифт колонтитула,
|
||||
# на который больше никто не ссылается, будет выброшен.
|
||||
$headerFmt = Get-HeaderFormatIndex $def.header
|
||||
$footerFmt = Get-HeaderFormatIndex $def.footer
|
||||
|
||||
# Шрифт, на который не ссылается ни один формат, платформа в палитру не кладёт: у макета
|
||||
# без оформления элемента <font> нет вовсе. Мы же всегда заводили Arial 10 по умолчанию.
|
||||
# Отбрасываем неиспользуемые и перенумеровываем ссылки — индексы шрифтов позиционные.
|
||||
@@ -2037,6 +2136,14 @@ if ($def.namedAreas) {
|
||||
}
|
||||
}
|
||||
|
||||
# 7d-ter. Колонтитулы: шесть слотов идут после строк и перед скалярными свойствами документа.
|
||||
foreach ($slot in $script:headerSlots) {
|
||||
if ($def.header) { Emit-HeaderSlot "$($slot)Header" $def.header.$slot $headerFmt }
|
||||
}
|
||||
foreach ($slot in $script:headerSlots) {
|
||||
if ($def.footer) { Emit-HeaderSlot "$($slot)Footer" $def.footer.$slot $footerFmt }
|
||||
}
|
||||
|
||||
# 7e-bis. Группировки строк и колонок. Платформа хранит их плоским списком диапазонов;
|
||||
# вложенность выражена вхождением одного диапазона в другой, а частичных пересечений не
|
||||
# бывает вовсе (корпус: 40 620 886 пар непересекающихся, 599 958 вложенных, 0 частичных).
|
||||
@@ -2156,6 +2263,8 @@ X "`t<vgRows>$totalRowCount</vgRows>"
|
||||
Emit-Groups 'vg' $rowGroups
|
||||
Emit-Groups 'hg' $colGroups
|
||||
|
||||
Emit-PrintSettings $def.printSettings
|
||||
|
||||
# 7f. Merges
|
||||
foreach ($m in $merges) {
|
||||
X "`t<merge>"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-compile v1.44 — Compile 1C spreadsheet from JSON
|
||||
# mxl-compile v1.45 — Compile 1C spreadsheet from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import hashlib
|
||||
@@ -1462,9 +1462,92 @@ def main():
|
||||
if note:
|
||||
register_note_format(note)
|
||||
|
||||
# Колонтитулы. Шесть слотов: left/center/right у верхнего и нижнего. Слот устроен как
|
||||
# ячейка — ссылка на формат плюс текст, — а формат несёт то, что в диалоге задаётся на весь
|
||||
# колонтитул: шрифт, вертикальное выравнивание, признак вывода (<height> 1/-1) и страницу,
|
||||
# с которой колонтитул печатается (<width>).
|
||||
def header_format_index(hf):
|
||||
if not hf:
|
||||
return 0
|
||||
props = {}
|
||||
if hf.get('font') and str(hf['font']) in font_map:
|
||||
props['font'] = font_map[str(hf['font'])]
|
||||
# Признак вывода и стартовая страница осмысленны только вместе: платформа пишет их парой.
|
||||
props['height'] = -1 if (hf.get('show') is False or str(hf.get('show')).lower() == 'false') else 1
|
||||
props['width'] = int(hf['startPage']) if hf.get('startPage') else 1
|
||||
if hf.get('verticalAlignment'):
|
||||
props['verticalAlignment'] = str(hf['verticalAlignment'])
|
||||
return register_format(props)
|
||||
|
||||
def emit_header_slot(lines, tag, value, fmt_idx):
|
||||
if value is None:
|
||||
return
|
||||
# Форматированная строка платформы — тот же текст, только разметка живёт внутри
|
||||
# содержимого (<b>жирный</>, <fontsize 12>…), поэтому возим её как есть и различаем
|
||||
# именем тега.
|
||||
formatted = isinstance(value, dict) and value.get('formatted') is not None
|
||||
text = value['formatted'] if formatted else value
|
||||
if isinstance(text, dict):
|
||||
pairs = [(str(k), str(v)) for k, v in text.items()]
|
||||
else:
|
||||
pairs = [(lang, str(text)) for lang in text_languages]
|
||||
text_tag = 'tfl' if formatted else 'tl'
|
||||
lines.append(f'\t<{tag}>')
|
||||
lines.append(f'\t\t<f>{fmt_idx}</f>')
|
||||
if not pairs:
|
||||
lines.append(f'\t\t<{text_tag}/>')
|
||||
else:
|
||||
lines.append(f'\t\t<{text_tag}>')
|
||||
for lang, content in pairs:
|
||||
lines.append('\t\t\t<v8:item>')
|
||||
lines.append(f'\t\t\t\t<v8:lang>{lang}</v8:lang>')
|
||||
# Перенос строки внутри колонтитула платформа хранит голым LF, тогда как весь
|
||||
# файл идёт CRLF. Содержимое кладём одним элементом списка, чтобы перенос
|
||||
# не переписался при склейке строк документа.
|
||||
lines.append(f'\t\t\t\t<v8:content>{esc_xml_text(content)}</v8:content>')
|
||||
lines.append('\t\t\t</v8:item>')
|
||||
lines.append(f'\t\t</{text_tag}>')
|
||||
lines.append(f'\t</{tag}>')
|
||||
|
||||
# Параметры печати. Имя ключа совпадает с именем тега в выгрузке, как у свойств стиля.
|
||||
# Порядок снят с корпуса (2350 макетов): платформа пишет теги строго в этой последовательности.
|
||||
def print_settings_order():
|
||||
return ('pageOrientation', 'scale', 'collate', 'copies', 'perPage',
|
||||
'topMargin', 'leftMargin', 'bottomMargin', 'rightMargin', 'headerSize', 'footerSize',
|
||||
'fitToPage', 'blackAndWhite', 'printerName', 'paper', 'paperSource',
|
||||
'pageWidth', 'pageHeight', 'duplexType', 'pagePlacementAlternation', 'firstPageNumber')
|
||||
|
||||
def emit_print_settings(lines, ps):
|
||||
if not ps:
|
||||
return
|
||||
order = print_settings_order()
|
||||
for key in ps:
|
||||
if key not in order:
|
||||
print(f'printSettings: unknown key "{key}". Allowed: {", ".join(order)}', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
emitted = []
|
||||
for tag in order:
|
||||
v = ps.get(tag)
|
||||
if v is None:
|
||||
continue
|
||||
if isinstance(v, bool):
|
||||
v = 'true' if v else 'false'
|
||||
emitted.append(f'\t\t<{tag}>{esc_xml_text(str(v))}</{tag}>')
|
||||
if not emitted:
|
||||
return
|
||||
lines.append('\t<printSettings>')
|
||||
lines.extend(emitted)
|
||||
lines.append('\t</printSettings>')
|
||||
|
||||
# Формат по умолчанию — последняя запись палитры (см. выше).
|
||||
default_format_index = register_format({'width': default_width})
|
||||
|
||||
# Формат колонтитула заводим здесь же: он идёт в палитре следом за умолчанием, и он
|
||||
# обязан попасть в реестр ДО отсева неиспользуемых шрифтов — иначе шрифт колонтитула,
|
||||
# на который больше никто не ссылается, будет выброшен.
|
||||
header_fmt = header_format_index(defn.get('header'))
|
||||
footer_fmt = header_format_index(defn.get('footer'))
|
||||
|
||||
# Шрифт, на который не ссылается ни один формат, платформа в палитру не кладёт: у макета
|
||||
# без оформления элемента <font> нет вовсе. Мы же всегда заводили Arial 10 по умолчанию.
|
||||
# Отбрасываем неиспользуемые и перенумеровываем ссылки — индексы шрифтов позиционные.
|
||||
@@ -1953,6 +2036,14 @@ def main():
|
||||
'EndCol': cols[1] - 1 if cols else -1,
|
||||
})
|
||||
|
||||
# 7d-ter. Колонтитулы: шесть слотов идут после строк и перед скалярными свойствами документа.
|
||||
for slot in ('left', 'center', 'right'):
|
||||
if defn.get('header'):
|
||||
emit_header_slot(lines, f'{slot}Header', defn['header'].get(slot), header_fmt)
|
||||
for slot in ('left', 'center', 'right'):
|
||||
if defn.get('footer'):
|
||||
emit_header_slot(lines, f'{slot}Footer', defn['footer'].get(slot), footer_fmt)
|
||||
|
||||
# 7e-bis. Группировки строк и колонок. Платформа хранит их плоским списком диапазонов;
|
||||
# вложенность выражена вхождением одного диапазона в другой, а частичных пересечений не
|
||||
# бывает вовсе (корпус: 40 620 886 пар непересекающихся, 599 958 вложенных, 0 частичных).
|
||||
@@ -2063,6 +2154,8 @@ def main():
|
||||
emit_groups(lines, 'vg', row_groups)
|
||||
emit_groups(lines, 'hg', col_groups)
|
||||
|
||||
emit_print_settings(lines, defn.get('printSettings'))
|
||||
|
||||
# 7f. Merges
|
||||
for m in merges:
|
||||
lines.append('\t<merge>')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# mxl-decompile v1.24 — Decompile 1C spreadsheet to JSON
|
||||
# mxl-decompile v1.25 — Decompile 1C spreadsheet to JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -265,6 +265,68 @@ function Get-Format {
|
||||
return $rawFormats[$idx - 1]
|
||||
}
|
||||
|
||||
# --- 4a. Колонтитулы и параметры печати ---
|
||||
# Слот колонтитула устроен как ячейка: ссылка на формат плюс текст. Признак вывода и стартовую
|
||||
# страницу читаем только у записи, где есть <height>: палитра дедуплицирована, и колонтитул без
|
||||
# своих настроек ссылается на чужую запись, где <width> — ширина колонки, а не номер страницы.
|
||||
function Read-HeaderPart {
|
||||
param([string]$suffix)
|
||||
$out = [ordered]@{}
|
||||
$fmtIdx = $null
|
||||
foreach ($slot in @('left', 'center', 'right')) {
|
||||
$el = $root.SelectSingleNode("d:$slot$suffix", $ns)
|
||||
if (-not $el) { continue }
|
||||
if ($null -eq $fmtIdx) {
|
||||
$fNode = $el.SelectSingleNode("d:f", $ns)
|
||||
$fmtIdx = if ($fNode) { [int]$fNode.InnerText } else { 0 }
|
||||
}
|
||||
foreach ($textTag in @('tl', 'tfl')) {
|
||||
$t = $el.SelectSingleNode("d:$textTag", $ns)
|
||||
if (-not $t) { continue }
|
||||
$byLang = [ordered]@{}
|
||||
foreach ($it in $t.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 { '' })
|
||||
}
|
||||
$value = Get-DslText $byLang
|
||||
$out[$slot] = if ($textTag -ceq 'tfl') { [ordered]@{ formatted = $value } } else { $value }
|
||||
break
|
||||
}
|
||||
}
|
||||
if ($out.Count -eq 0 -and $null -eq $fmtIdx) { return $null }
|
||||
$fmt = if ($fmtIdx) { Get-Format $fmtIdx } else { $null }
|
||||
if ($fmt) {
|
||||
$props = $fmt.Props
|
||||
$head = [ordered]@{}
|
||||
if ($fmt.FontIdx -ge 0) { $head["font"] = $fontNames[$fmt.FontIdx] }
|
||||
if ($props.Contains('height')) {
|
||||
if ("$($props['height'])" -ceq '-1') { $head["show"] = $false }
|
||||
$w = if ($props.Contains('width')) { [int]$props['width'] } else { 1 }
|
||||
if ($w -ne 1) { $head["startPage"] = $w }
|
||||
}
|
||||
if ($props.Contains('verticalAlignment')) { $head["verticalAlignment"] = $props['verticalAlignment'] }
|
||||
foreach ($k in $out.Keys) { $head[$k] = $out[$k] }
|
||||
$out = $head
|
||||
}
|
||||
return $out
|
||||
}
|
||||
|
||||
$printSettings = $null
|
||||
$psNode = $root.SelectSingleNode("d:printSettings", $ns)
|
||||
if ($psNode) {
|
||||
$printSettings = [ordered]@{}
|
||||
foreach ($c in $psNode.ChildNodes) {
|
||||
if ($c.NodeType -ne [System.Xml.XmlNodeType]::Element) { continue }
|
||||
$v = $c.InnerText.Trim()
|
||||
$i = 0
|
||||
if ($v -ceq 'true') { $printSettings[$c.get_LocalName()] = $true }
|
||||
elseif ($v -ceq 'false') { $printSettings[$c.get_LocalName()] = $false }
|
||||
elseif ([int]::TryParse($v, [ref]$i)) { $printSettings[$c.get_LocalName()] = $i }
|
||||
else { $printSettings[$c.get_LocalName()] = $v }
|
||||
}
|
||||
}
|
||||
|
||||
# --- 4b. Группировки строк и колонок ---
|
||||
# Платформа хранит их плоским списком диапазонов, родитель раньше детей. Число уровней
|
||||
# (<vgLevels>) не читаем: оно выводится из вложенности — совпало на всех 1797 макетах.
|
||||
@@ -1477,6 +1539,14 @@ foreach ($g in ($rowGroups + $colGroups)) {
|
||||
if ($rowGroups.Count -gt 0) { $result["rowGroups"] = [array]$rowGroups }
|
||||
if ($colGroups.Count -gt 0) { $result["columnGroups"] = [array]$colGroups }
|
||||
|
||||
# Читаем здесь, а не в разделе 4a: тексту колонтитула нужен свод языков макета, который
|
||||
# становится известен только после разбора строк.
|
||||
$headerPart = Read-HeaderPart 'Header'
|
||||
$footerPart = Read-HeaderPart 'Footer'
|
||||
if ($headerPart) { $result["header"] = $headerPart }
|
||||
if ($footerPart) { $result["footer"] = $footerPart }
|
||||
if ($printSettings) { $result["printSettings"] = $printSettings }
|
||||
|
||||
$result["areas"] = [array]$dslAreas
|
||||
|
||||
# Именованные области, не выразимые блоком, — координатами. Тип не пишем: он выводится
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-decompile v1.24 — Decompile 1C spreadsheet to JSON
|
||||
# mxl-decompile v1.25 — Decompile 1C spreadsheet to JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -431,6 +431,67 @@ def main():
|
||||
return None
|
||||
return raw_formats[idx - 1]
|
||||
|
||||
# --- 4a. Колонтитулы и параметры печати ---
|
||||
# Слот колонтитула устроен как ячейка: ссылка на формат плюс текст. Признак вывода и стартовую
|
||||
# страницу читаем только у записи, где есть <height>: палитра дедуплицирована, и колонтитул без
|
||||
# своих настроек ссылается на чужую запись, где <width> — ширина колонки, а не номер страницы.
|
||||
def read_header_part(suffix):
|
||||
slots = OrderedDict()
|
||||
fmt_idx = None
|
||||
for slot in ('left', 'center', 'right'):
|
||||
el = find(root, f'd:{slot}{suffix}')
|
||||
if el is None:
|
||||
continue
|
||||
if fmt_idx is None:
|
||||
fmt_idx = int_of(find(el, 'd:f'))
|
||||
for text_tag in ('tl', 'tfl'):
|
||||
t = find(el, 'd:' + text_tag)
|
||||
if t is None:
|
||||
continue
|
||||
by_lang = OrderedDict()
|
||||
for it in findall(t, 'v8:item'):
|
||||
lang = text_of(find(it, 'v8:lang')) or ''
|
||||
by_lang[lang] = text_of(find(it, 'v8:content')) or ''
|
||||
value = get_dsl_text(by_lang)
|
||||
slots[slot] = OrderedDict([('formatted', value)]) if text_tag == 'tfl' else value
|
||||
break
|
||||
if not slots and fmt_idx is None:
|
||||
return None
|
||||
fmt = get_format(fmt_idx) if fmt_idx else None
|
||||
if not fmt:
|
||||
return slots
|
||||
head = OrderedDict()
|
||||
if fmt["FontIdx"] >= 0:
|
||||
head["font"] = font_names.get(fmt["FontIdx"], "default")
|
||||
props = fmt["Props"]
|
||||
if 'height' in props:
|
||||
if str(props['height']) == '-1':
|
||||
head["show"] = False
|
||||
width = int(props.get('width', 1))
|
||||
if width != 1:
|
||||
head["startPage"] = width
|
||||
if 'verticalAlignment' in props:
|
||||
head["verticalAlignment"] = props['verticalAlignment']
|
||||
head.update(slots)
|
||||
return head
|
||||
|
||||
print_settings = None
|
||||
ps_node = find(root, 'd:printSettings')
|
||||
if ps_node is not None:
|
||||
print_settings = OrderedDict()
|
||||
for c in ps_node:
|
||||
name = etree.QName(c).localname
|
||||
v = (c.text or '').strip()
|
||||
if v == 'true':
|
||||
print_settings[name] = True
|
||||
elif v == 'false':
|
||||
print_settings[name] = False
|
||||
else:
|
||||
try:
|
||||
print_settings[name] = int(v)
|
||||
except ValueError:
|
||||
print_settings[name] = v
|
||||
|
||||
# --- 4b. Группировки строк и колонок ---
|
||||
# Платформа хранит их плоским списком диапазонов, родитель раньше детей. Число уровней
|
||||
# (<vgLevels>) не читаем: оно выводится из вложенности — совпало на всех 1797 макетах.
|
||||
@@ -1472,6 +1533,17 @@ def main():
|
||||
if col_groups:
|
||||
result["columnGroups"] = col_groups
|
||||
|
||||
# Читаем здесь, а не в разделе 4a: тексту колонтитула нужен свод языков макета, который
|
||||
# становится известен только после разбора строк.
|
||||
header_part = read_header_part('Header')
|
||||
footer_part = read_header_part('Footer')
|
||||
if header_part:
|
||||
result["header"] = header_part
|
||||
if footer_part:
|
||||
result["footer"] = footer_part
|
||||
if print_settings:
|
||||
result["printSettings"] = print_settings
|
||||
|
||||
result["areas"] = dsl_areas
|
||||
|
||||
# Именованные области, не выразимые блоком, — координатами. Тип не пишем: он выводится
|
||||
|
||||
@@ -601,7 +601,40 @@ current-config не объявляет, поэтому вынести объяв
|
||||
обратные, ячейки продолжают ссылаться на записи со старыми ширинами. Из итогового XML это
|
||||
значение не выводится — воспроизводить его не нужно.
|
||||
|
||||
## Группировки строк и колонок
|
||||
## Колонтитулы и параметры печати
|
||||
|
||||
```xml
|
||||
<leftHeader>
|
||||
<f>2</f> <!-- формат: шрифт, выравнивание, признак вывода, стартовая страница -->
|
||||
<tl><v8:item><v8:lang>ru</v8:lang><v8:content>Слева</v8:content></v8:item></tl>
|
||||
</leftHeader>
|
||||
…
|
||||
<printSettings>
|
||||
<topMargin>1000</topMargin> … <firstPageNumber>15</firstPageNumber>
|
||||
</printSettings>
|
||||
```
|
||||
|
||||
Шесть элементов идут после строк и перед `<templateMode>`: `leftHeader`, `centerHeader`,
|
||||
`rightHeader`, `leftFooter`, `centerFooter`, `rightFooter`. Пишутся не комплектом: `leftHeader`
|
||||
есть у 1 013 макетов, остальные — у 677–790.
|
||||
|
||||
| Наблюдение | Данные корпуса |
|
||||
|---|---|
|
||||
| текст слота | `<tl>` — обычная строка, `<tfl>` — форматированная (разметка внутри содержимого: `<b>…</>`, `<fontsize 12>`, `<colorstyle -16>`) |
|
||||
| формат слота | `<height>` = признак вывода (`1` / `-1`), `<width>` = страница, с которой печатать, плюс шрифт и `verticalAlignment` |
|
||||
| формат общий на колонтитул | у 674 макетов из 677; разный у трёх |
|
||||
| формат делится с другими владельцами | 637 против 153 «только колонтитулы» — палитра дедуплицирована, поэтому `<width>` в чужой записи означает ширину колонки, а не страницу |
|
||||
|
||||
**Ловушка:** перенос строки внутри текста колонтитула платформа хранит голым LF, тогда как весь
|
||||
остальной файл идёт CRLF. Это единственное место документа с другим переводом строки.
|
||||
|
||||
`printSettings` (2 350 макетов) — плоский набор в фиксированном порядке: `pageOrientation` ·
|
||||
`scale` · `collate` · `copies` · `perPage` · `topMargin` · `leftMargin` · `bottomMargin` ·
|
||||
`rightMargin` · `headerSize` · `footerSize` · `fitToPage` · `blackAndWhite` · `printerName` ·
|
||||
`paper` · `paperSource` · `pageWidth` · `pageHeight` · `duplexType` · `pagePlacementAlternation` ·
|
||||
`firstPageNumber`. Номер первой страницы принадлежит именно параметрам печати, а не колонтитулу.
|
||||
|
||||
## Группы строк и колонок
|
||||
|
||||
```xml
|
||||
<vgLevels>2</vgLevels>
|
||||
@@ -616,7 +649,7 @@ current-config не объявляет, поэтому вынести объяв
|
||||
<hg>…</hg> <!-- то же для колонок -->
|
||||
```
|
||||
|
||||
Строки группируются часто (1 797 макетов, 170 967 группировок), колонки — почти никогда
|
||||
Строки группируются часто (1 797 макетов, 170 967 групп), колонки — почти никогда
|
||||
(1 макет, 1 группировка). Порядок документных тегов: `height` → `vgLevels` → `vgRows` → `vg` →
|
||||
`hg`; `vgLevels` пишется только при наличии группировок.
|
||||
|
||||
|
||||
+53
-1
@@ -89,6 +89,8 @@
|
||||
| `columnSets` | нет | — | Дополнительные колоночные раскладки (см. `mxl-dsl-styles.md`) |
|
||||
| `rowGroups` | нет | — | Группы строк (см. ниже) |
|
||||
| `columnGroups` | нет | — | Группы колонок (см. ниже) |
|
||||
| `header` / `footer` | нет | — | Верхний и нижний колонтитулы (см. ниже) |
|
||||
| `printSettings` | нет | — | Параметры печати (см. ниже) |
|
||||
|
||||
## Области (`areas[]`)
|
||||
|
||||
@@ -302,6 +304,56 @@
|
||||
и компилятор проставляет это сам. `autoSize` и `box` независимы: при автоподгоне размера
|
||||
положение окошка всё равно хранится.
|
||||
|
||||
## Колонтитулы
|
||||
|
||||
У верхнего и нижнего колонтитула по три слота — `left`, `center`, `right` — и общие настройки:
|
||||
|
||||
```json
|
||||
"header": {
|
||||
"font": "мелкий",
|
||||
"verticalAlignment": "Bottom",
|
||||
"startPage": 2,
|
||||
"left": "Слева\nвторая строка",
|
||||
"center": "Стр. [&НомерСтраницы] из [&СтраницВсего]",
|
||||
"right": { "ru": "Справа", "en": "Right" }
|
||||
},
|
||||
"footer": {
|
||||
"show": false,
|
||||
"center": { "formatted": "<b>Итог</> <colorstyle -16>красным</>" }
|
||||
}
|
||||
```
|
||||
|
||||
| Поле | По умолч. | Описание |
|
||||
|------|-----------|----------|
|
||||
| `left`, `center`, `right` | — | Текст слота: строка, объект «язык → текст» или `{ "formatted": … }` |
|
||||
| `font` | — | Имя шрифта из `fonts` — на весь колонтитул |
|
||||
| `verticalAlignment` | — | Положение текста по вертикали: `Top`, `Center`, `Bottom` |
|
||||
| `show` | `true` | Выводить ли колонтитул |
|
||||
| `startPage` | `1` | Страница, с которой колонтитул печатается |
|
||||
|
||||
Текст может быть многострочным (`\n`) и содержать поля `[&НомерСтраницы]`, `[&СтраницВсего]`,
|
||||
`[&Дата]`, `[&Время]` — платформа подставляет их при печати. `{ "formatted": … }` — форматированная
|
||||
строка: разметка живёт прямо в тексте (`<b>жирный</>`, `<fontsize 12>`, `<colorstyle -16>`).
|
||||
|
||||
## Параметры печати
|
||||
|
||||
Плоский объект; имя ключа совпадает с именем свойства в выгрузке:
|
||||
|
||||
```json
|
||||
"printSettings": {
|
||||
"pageOrientation": "Landscape",
|
||||
"topMargin": 500, "leftMargin": 500, "bottomMargin": 500, "rightMargin": 500,
|
||||
"headerSize": 1000, "footerSize": 1000,
|
||||
"fitToPage": true, "firstPageNumber": 7
|
||||
}
|
||||
```
|
||||
|
||||
Допустимые ключи: `pageOrientation`, `scale`, `collate`, `copies`, `perPage`, `topMargin`,
|
||||
`leftMargin`, `bottomMargin`, `rightMargin`, `headerSize`, `footerSize`, `fitToPage`,
|
||||
`blackAndWhite`, `printerName`, `paper`, `paperSource`, `pageWidth`, `pageHeight`, `duplexType`,
|
||||
`pagePlacementAlternation`, `firstPageNumber`. Незнакомый ключ — ошибка. Порядок в объекте не
|
||||
важен: компилятор пишет свойства в том порядке, что и платформа.
|
||||
|
||||
## Группы строк и колонок
|
||||
|
||||
Диапазон строк или колонок, который сворачивается кнопкой на полях. Задаются плоским списком;
|
||||
@@ -347,7 +399,7 @@ XML не возвращается.
|
||||
|
||||
- объединения, не привязанные к ячейке (по всей высоте или ширине документа);
|
||||
- рисунки и картинки, в том числе штрихкоды;
|
||||
- колонтитулы, параметры печати, область печати.
|
||||
- область печати.
|
||||
|
||||
Пересборка макета из DSL — это полная перегенерация, а не точечная правка XML, поэтому
|
||||
diff после round-trip обычно шире фактической доработки.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "Ошибка: неизвестный ключ параметров печати",
|
||||
"input": {
|
||||
"columns": 1,
|
||||
"areas": [{ "rows": [["a"]] }],
|
||||
"printSettings": { "topMargin": 500, "marginTop": 500 }
|
||||
},
|
||||
"params": { "outputPath": "Template.xml" },
|
||||
"expectError": "printSettings: unknown key \"marginTop\""
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?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>1</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>
|
||||
<leftHeader>
|
||||
<f>2</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Слева</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</leftHeader>
|
||||
<centerHeader>
|
||||
<f>2</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Стр. [&НомерСтраницы] из [&СтраницВсего]. Дата [&Дата][&Время]</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</centerHeader>
|
||||
<rightHeader>
|
||||
<f>2</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Справа</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</rightHeader>
|
||||
<leftFooter>
|
||||
<f>3</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Нижний слева</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</leftFooter>
|
||||
<centerFooter>
|
||||
<f>3</f>
|
||||
<tfl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content><b>Форматируемая</> <fontsize 12><colorstyle -16>строка</></></v8:content>
|
||||
</v8:item>
|
||||
</tfl>
|
||||
</centerFooter>
|
||||
<rightFooter>
|
||||
<f>3</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Нижний справа</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</rightFooter>
|
||||
<templateMode>true</templateMode>
|
||||
<defaultFormatIndex>1</defaultFormatIndex>
|
||||
<height>1</height>
|
||||
<vgRows>1</vgRows>
|
||||
<printSettings>
|
||||
<topMargin>1000</topMargin>
|
||||
<leftMargin>1000</leftMargin>
|
||||
<bottomMargin>1000</bottomMargin>
|
||||
<rightMargin>1000</rightMargin>
|
||||
<headerSize>1200</headerSize>
|
||||
<footerSize>1000</footerSize>
|
||||
<firstPageNumber>15</firstPageNumber>
|
||||
</printSettings>
|
||||
<font faceName="Arial" height="8" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
|
||||
<format>
|
||||
<width>72</width>
|
||||
</format>
|
||||
<format>
|
||||
<font>0</font>
|
||||
<height>-1</height>
|
||||
<width>2</width>
|
||||
<verticalAlignment>Center</verticalAlignment>
|
||||
</format>
|
||||
<format>
|
||||
<font>0</font>
|
||||
<height>1</height>
|
||||
<width>21</width>
|
||||
<verticalAlignment>Top</verticalAlignment>
|
||||
</format>
|
||||
</document>
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "Колонтитулы и параметры печати",
|
||||
"input": {
|
||||
"columns": 2,
|
||||
"fonts": { "мелкий": { "face": "Arial", "size": 8 } },
|
||||
"areas": [{ "rows": [["Отчёт"]] }],
|
||||
"header": {
|
||||
"font": "мелкий",
|
||||
"verticalAlignment": "Bottom",
|
||||
"startPage": 2,
|
||||
"left": "Слева\nвторая строка",
|
||||
"center": "Стр. [&НомерСтраницы] из [&СтраницВсего]",
|
||||
"right": { "ru": "Справа", "en": "Right" }
|
||||
},
|
||||
"footer": {
|
||||
"font": "мелкий",
|
||||
"verticalAlignment": "Top",
|
||||
"show": false,
|
||||
"center": { "formatted": "<b>Итог</> <colorstyle -16>красным</>" }
|
||||
},
|
||||
"printSettings": {
|
||||
"pageOrientation": "Landscape",
|
||||
"topMargin": 500, "leftMargin": 500, "bottomMargin": 500, "rightMargin": 500,
|
||||
"headerSize": 1000, "footerSize": 1000,
|
||||
"fitToPage": true, "blackAndWhite": false, "firstPageNumber": 7
|
||||
}
|
||||
},
|
||||
"params": { "outputPath": "Template.xml" }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "Раундтрип макета ПЛАТФОРМЫ байт в байт: Колонтитулы",
|
||||
"setup": "fixture:platform-roundtrip",
|
||||
"preRun": [
|
||||
{ "script": "mxl-decompile/scripts/mxl-decompile",
|
||||
"args": { "-TemplatePath": "Колонтитулы.xml", "-OutputPath": "back.json" },
|
||||
"cwd": "{workDir}" }
|
||||
],
|
||||
"params": { "outputPath": "out.xml" },
|
||||
"noSnapshot": "эталон — файл платформы, сверяется expect.filesEqual",
|
||||
"expect": { "filesEqual": { "actual": "out.xml", "expected": "Колонтитулы.xml" } },
|
||||
"inputFrom": "back.json"
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?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>
|
||||
<leftHeader>
|
||||
<f>2</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Слева
|
||||
вторая строка</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</leftHeader>
|
||||
<centerHeader>
|
||||
<f>2</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Стр. [&НомерСтраницы] из [&СтраницВсего]</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</centerHeader>
|
||||
<rightHeader>
|
||||
<f>2</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Справа</v8:content>
|
||||
</v8:item>
|
||||
<v8:item>
|
||||
<v8:lang>en</v8:lang>
|
||||
<v8:content>Right</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</rightHeader>
|
||||
<centerFooter>
|
||||
<f>3</f>
|
||||
<tfl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content><b>Итог</> <colorstyle -16>красным</></v8:content>
|
||||
</v8:item>
|
||||
</tfl>
|
||||
</centerFooter>
|
||||
<templateMode>true</templateMode>
|
||||
<defaultFormatIndex>1</defaultFormatIndex>
|
||||
<height>1</height>
|
||||
<vgRows>1</vgRows>
|
||||
<printSettings>
|
||||
<pageOrientation>Landscape</pageOrientation>
|
||||
<topMargin>500</topMargin>
|
||||
<leftMargin>500</leftMargin>
|
||||
<bottomMargin>500</bottomMargin>
|
||||
<rightMargin>500</rightMargin>
|
||||
<headerSize>1000</headerSize>
|
||||
<footerSize>1000</footerSize>
|
||||
<fitToPage>true</fitToPage>
|
||||
<blackAndWhite>false</blackAndWhite>
|
||||
<firstPageNumber>7</firstPageNumber>
|
||||
</printSettings>
|
||||
<font faceName="Arial" height="8" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
|
||||
<format>
|
||||
<width>10</width>
|
||||
</format>
|
||||
<format>
|
||||
<font>0</font>
|
||||
<height>1</height>
|
||||
<width>2</width>
|
||||
<verticalAlignment>Bottom</verticalAlignment>
|
||||
</format>
|
||||
<format>
|
||||
<font>0</font>
|
||||
<height>-1</height>
|
||||
<width>1</width>
|
||||
<verticalAlignment>Top</verticalAlignment>
|
||||
</format>
|
||||
</document>
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "Roundtrip — колонтитулы и параметры печати",
|
||||
"preRun": [
|
||||
{ "script": "mxl-compile/scripts/mxl-compile",
|
||||
"input": {
|
||||
"columns": 2,
|
||||
"fonts": { "мелкий": { "face": "Arial", "size": 8 } },
|
||||
"areas": [{ "rows": [["Отчёт"]] }],
|
||||
"header": { "font": "мелкий", "verticalAlignment": "Bottom", "startPage": 2,
|
||||
"left": "Слева\nвторая строка", "center": "Стр. [&НомерСтраницы]" },
|
||||
"footer": { "font": "мелкий", "show": false,
|
||||
"center": { "formatted": "<b>Итог</>" } },
|
||||
"printSettings": { "pageOrientation": "Landscape", "fitToPage": true, "firstPageNumber": 7 }
|
||||
},
|
||||
"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,83 @@
|
||||
<?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>
|
||||
<leftHeader>
|
||||
<f>2</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Слева
|
||||
вторая строка</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</leftHeader>
|
||||
<centerHeader>
|
||||
<f>2</f>
|
||||
<tl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Стр. [&НомерСтраницы]</v8:content>
|
||||
</v8:item>
|
||||
</tl>
|
||||
</centerHeader>
|
||||
<centerFooter>
|
||||
<f>3</f>
|
||||
<tfl>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content><b>Итог</></v8:content>
|
||||
</v8:item>
|
||||
</tfl>
|
||||
</centerFooter>
|
||||
<templateMode>true</templateMode>
|
||||
<defaultFormatIndex>1</defaultFormatIndex>
|
||||
<height>1</height>
|
||||
<vgRows>1</vgRows>
|
||||
<printSettings>
|
||||
<pageOrientation>Landscape</pageOrientation>
|
||||
<fitToPage>true</fitToPage>
|
||||
<firstPageNumber>7</firstPageNumber>
|
||||
</printSettings>
|
||||
<font faceName="Arial" height="8" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
|
||||
<format>
|
||||
<width>10</width>
|
||||
</format>
|
||||
<format>
|
||||
<font>0</font>
|
||||
<height>1</height>
|
||||
<width>2</width>
|
||||
<verticalAlignment>Bottom</verticalAlignment>
|
||||
</format>
|
||||
<format>
|
||||
<font>0</font>
|
||||
<height>-1</height>
|
||||
<width>1</width>
|
||||
</format>
|
||||
</document>
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"columns": 2,
|
||||
"defaultWidth": 10,
|
||||
"fonts": { "default": { "face": "Arial", "size": 8 } },
|
||||
"styles": {},
|
||||
"header": { "font": "default", "startPage": 2, "verticalAlignment": "Bottom", "left": "Слева\nвторая строка", "center": "Стр. [&НомерСтраницы]" },
|
||||
"footer": { "font": "default", "show": false, "center": { "formatted": "<b>Итог</>" } },
|
||||
"printSettings": { "pageOrientation": "Landscape", "fitToPage": true, "firstPageNumber": 7 },
|
||||
"areas": [{ "rows": [["Отчёт"]] }]
|
||||
}
|
||||
Reference in New Issue
Block a user