Skip to content

BDDSM/onec-ordinary-forms

 
 

Repository files navigation

onec-ordinary-forms

Python tools for converting 1C ordinary form Form.bin into a Git-friendly source package and building it back.

English

What This Project Does

1C ordinary forms are stored inside Form.bin. That binary contains the form module, pictures, and the ordinary-form layout/control data in the platform's internal list-stream format. This is hard to review, diff, edit, and merge.

The goal of this project is to expose ordinary forms as source files that are close to managed-form source exports: readable XML for the form object model, Module.bsl as a separate file, and pictures as sidecar files.

The public source layout mirrors managed forms:

Forms/Form/Ext/Form.xml
Forms/Form/Ext/Form/Module.bsl
Forms/Form/Ext/Form/Items/<ElementName>/Picture.gif

Target Public XML

Form.xml is the public editable object model. It should describe the form with named controls and properties, not with raw platform records:

<Form>
  <Title>
    <Item lang="ru">Form title</Item>
  </Title>
  <Attributes>
    <Attribute name="InputValue">
      <Type>...</Type>
    </Attribute>
  </Attributes>
  <Pages>
    <Page name="Main">
      <Panel name="MainPanel">
        <Position left="8" top="8" right="640" bottom="480"/>
        <LabelDecoration name="Caption">
          <Title>
            <Item lang="ru">Caption text</Item>
          </Title>
        </LabelDecoration>
        <Button name="RunButton">
          <Title>
            <Item lang="ru">Run</Item>
          </Title>
          <Events>
            <Event name="Нажатие">Run</Event>
          </Events>
        </Button>
        <PictureDecoration name="Logo">
          <Picture file="Items/Logo/Picture.gif"/>
        </PictureDecoration>
      </Panel>
    </Page>
  </Pages>
</Form>

Control properties and events are type-specific and come from the platform help palette for ordinary controls. The XML should contain only values explicitly set on the form; platform defaults should stay implicit.

Public XML uses one English vocabulary for element and attribute names. Russian platform names for ordinary-form controls, properties, events, and value types belong in OrdinaryForm.xsd as xs:annotation/xs:appinfo metadata, not in a separate mapping file and not as public XML tag names.

The exact schema is still being expanded, but the target direction is fixed: public XML must be managed-form-like, named, and understandable to a 1C developer.

Reading Form.xml

The ordinary form source package is meant to be read from the top down:

  • Form.xml is the form object model.
  • Form/Module.bsl is the ordinary form module.
  • Form/Items/... contains extracted sidecar files such as pictures.

Inside Form.xml, the main sections are:

  • Title - localized form title.
  • Events - form-level event handlers, for example ПриОткрытии.
  • Attributes - form attributes and their 1C type descriptions.
  • Pages - top-level form pages and their nested controls.
  • control nodes such as Panel, InputField, Button, Table, CommandBar, LabelDecoration, and PictureDecoration.
  • Position - control geometry and bindings.
  • Action or Events under a control - handlers connected to that control.
  • Picture file="..." - a reference to a sidecar image next to the XML.

For example, a button is edited as a named object:

<Button name="RunButton" id="12">
  <Title>
    <Item lang="ru">Run</Item>
  </Title>
  <Position left="16" top="40" right="120" bottom="64"/>
  <Action name="RunButtonНажатие" title="Run button click"/>
</Button>

During build-bin, the writer serializes these named XML objects into the platform list-stream representation and then packs form and module into Form.bin. That container layer is internal; users edit Form.xml, Module.bsl, and sidecar files.

Internal Platform Pipeline

The target internal pipeline is symmetric:

Form.bin -> form raw stream -> ListInStream -> platform object model -> XSD-backed Form.xml
Form.xml -> platform object model -> ListOutStream -> form raw stream -> Form.bin

The schema layer is intentionally small and focused on ordinary forms:

  • OrdinaryForm.xsd describes the public Form.xml root, ordinary-form controls, reusable value/layout types, property/event vocabulary, and platform palette annotations;
  • PlatformConfigStructure.xsd records platform-derived configuration, metadata tree, type-domain, CompositeID, ValueToStringInternal/ ValueFromStringInternal, and serializer evidence used by the codec layer.

These codec concepts are not a public raw-stream dump. Full platform XSD extractions are kept as reproducible research artifacts under ignored scan-output/, not vendored into the package.

Regenerate platform schema evidence from a local platform mirror with:

python3 tools/extract_platform_xml_resources.py \
  --root <platform-bin-dir> \
  --out-dir scan-output/platform85/xml-clean \
  --schemas-only
python3 tools/vendor_platform_schemas.py \
  --resources-json scan-output/platform85/xml-clean/resources.json \
  --source-dir scan-output/platform85/xml-clean \
  --out-dir scan-output/platform85/vendor-check \
  --platform-version 8.5

What Must Not Be In Public XML

Public Form.xml must not contain raw or renamed platform dumps. The following are not acceptable public structures:

  • ObjectModel
  • ListStream
  • BracketStream
  • FormBin
  • LogicalStream
  • RawBracket
  • PlatformRecords
  • indexed trees such as Field kind="list" or Field kind="atom"
  • embedded base64 source streams
  • binary placeholders or other lossless/fallback stream copies

The parser/writer may use the platform list-stream format internally. Platform symbols such as cf_form_controls8, cf_form_controls_position8, and cf_form_controls_info8 identify ordinary-control payload formats in the platform mechanism. They are implementation details, not public XML nodes. If a value is needed for rebuild, it must be promoted to a named XML concept: a control, property, event, command, binding, picture reference, or type descriptor.

Passing 1C Designer validation is required, but not sufficient by itself: the public XML must also remain a clean object model, not a renamed raw stream.

Current strict 1C validation uses build-bin without a public template/fallback Form.bin: the ordinary Form.bin is built from object Form.xml, Module.bsl, and sidecar files. Before platform import, validation uses a copy of the source tree where the public ordinary Ext/Form.xml and Ext/Form/ sidecar directory are removed; for an ordinary form, the platform source layout keeps only Ext/Form.bin.

Русский

Что делает проект

Обычные формы 1С лежат внутри Form.bin. В этом бинарном файле находятся модуль формы, картинки и данные обычной формы во внутреннем list-stream / скобкоформате платформы. Такой файл сложно смотреть в Git, сравнивать, редактировать и мержить.

Цель проекта - разложить обычную форму в исходники примерно так же, как платформа раскладывает управляемую форму: человекочитаемый XML объектной модели, отдельный Module.bsl и картинки рядом.

Целевая структура файлов:

Forms/Form/Ext/Form.xml
Forms/Form/Ext/Form/Module.bsl
Forms/Form/Ext/Form/Items/<ИмяЭлемента>/Picture.gif

Целевой публичный XML

Form.xml - это публичная редактируемая объектная модель. Он должен описывать форму именованными элементами и свойствами, а не сырыми платформенными записями:

<Form>
  <Title>
    <Item lang="ru">Заголовок формы</Item>
  </Title>
  <Attributes>
    <Attribute name="ВходноеЗначение">
      <Type>...</Type>
    </Attribute>
  </Attributes>
  <Pages>
    <Page name="Основная">
      <Panel name="ОсновнаяПанель">
        <Position left="8" top="8" right="640" bottom="480"/>
        <LabelDecoration name="Надпись">
          <Title>
            <Item lang="ru">Текст надписи</Item>
          </Title>
        </LabelDecoration>
        <Button name="КнопкаВыполнить">
          <Title>
            <Item lang="ru">Выполнить</Item>
          </Title>
          <Events>
            <Event name="Нажатие">Выполнить</Event>
          </Events>
        </Button>
        <PictureDecoration name="Логотип">
          <Picture file="Items/Логотип/Picture.gif"/>
        </PictureDecoration>
      </Panel>
    </Page>
  </Pages>
</Form>

Публичный XML использует единый английский словарь элементов и свойств. Платформенные русские имена свойств, событий и типов обычной формы хранятся в OrdinaryForm.xsd как xs:annotation/xs:appinfo, а не отдельным mapping файлом и не публичными XML-тегами. В XML должны попадать только явно заданные значения; дефолты платформы остаются неявными.

Схема еще расширяется, но направление фиксированное: публичный XML должен быть похож на XML управляемой формы, быть именованным и понятным разработчику 1С.

Как читать Form.xml

Пакет исходников обычной формы читается сверху вниз:

  • Form.xml - объектная модель формы.
  • Form/Module.bsl - модуль обычной формы.
  • Form/Items/... - вынесенные рядом файлы, например картинки.

Внутри Form.xml основные разделы такие:

  • Title - локализованный заголовок формы.
  • Events - события самой формы, например ПриОткрытии.
  • Attributes - реквизиты формы и описания их типов 1С.
  • Pages - страницы формы и вложенные в них элементы.
  • узлы контролов: Panel, InputField, Button, Table, CommandBar, LabelDecoration, PictureDecoration и другие элементы палитры.
  • Position - геометрия элемента и привязки.
  • Action или Events внутри элемента - обработчики, подключенные к нему.
  • Picture file="..." - ссылка на картинку рядом с XML.

Например, кнопка редактируется как именованный объект:

<Button name="КнопкаВыполнить" id="12">
  <Title>
    <Item lang="ru">Выполнить</Item>
  </Title>
  <Position left="16" top="40" right="120" bottom="64"/>
  <Action name="КнопкаВыполнитьНажатие" title="Нажатие кнопки выполнить"/>
</Button>

При build-bin writer сериализует эти именованные XML-объекты во внутренний list-stream/скобкоформат платформы и затем упаковывает документы form и module в Form.bin. Этот контейнерный слой внутренний; пользователь редактирует Form.xml, Module.bsl и файлы рядом.

Внутренний платформенный конвейер

Целевой внутренний конвейер симметричный:

Form.bin -> raw-поток form -> ListInStream -> объектная модель платформы -> Form.xml по XSD
Form.xml -> объектная модель платформы -> ListOutStream -> raw-поток form -> Form.bin

Слой схем специально небольшой и сфокусирован на обычных формах:

  • OrdinaryForm.xsd описывает публичный корень Form.xml, элементы обычной формы, переиспользуемые типы значений/раскладки, единый английский словарь свойств/событий и аннотации платформенной палитры;
  • PlatformConfigStructure.xsd фиксирует платформенные сведения о структуре конфигурации, дереве метаданных, type-domain, CompositeID, ValueToStringInternal/ValueFromStringInternal и сведения о сериализаторах, используемые слоем кодека.

Эти понятия кодека не являются публичным дампом сырого потока. Полные извлечения платформенных XSD хранятся как воспроизводимые исследовательские артефакты в игнорируемом scan-output/, а не поставляются внутри пакета.

Обновить платформенные сведения для схем из локального зеркала платформы можно так:

python3 tools/extract_platform_xml_resources.py \
  --root <platform-bin-dir> \
  --out-dir scan-output/platform85/xml-clean \
  --schemas-only
python3 tools/vendor_platform_schemas.py \
  --resources-json scan-output/platform85/xml-clean/resources.json \
  --source-dir scan-output/platform85/xml-clean \
  --out-dir scan-output/platform85/vendor-check \
  --platform-version 8.5

Чего не должно быть в публичном XML

Публичный Form.xml не должен содержать сырые или переименованные дампы платформенного формата. Нельзя выводить наружу:

  • ObjectModel
  • ListStream
  • BracketStream
  • FormBin
  • LogicalStream
  • RawBracket
  • PlatformRecords
  • индексные деревья вроде Field kind="list" или Field kind="atom"
  • встроенные base64-потоки исходного файла
  • бинарные заглушки и другие побайтно-сохраняющие или резервные копии потоковых структур

Парсер и writer могут использовать list-stream/скобкоформат платформы внутри. Платформенные символы cf_form_controls8, cf_form_controls_position8, cf_form_controls_info8 являются идентификаторами форматов данных обычных контролов в типовом механизме платформы. Это внутренняя реализация, а не публичные XML-узлы. Если значение нужно для обратной сборки, его нужно поднять в именованное понятие XML: контрол, свойство, событие, команда, привязка, ссылка на картинку или описание типа.

Проверка через 1C Designer обязательна, но сама по себе недостаточна: публичный XML все равно должен оставаться чистой объектной моделью, а не переименованным сырым потоком.

Текущая строгая проверка 1C выполняется без публичного шаблонного или резервного Form.bin: build-bin собирает обычный Form.bin из объектного Form.xml, Module.bsl и файлов рядом. Перед импортом платформой используется копия исходной раскладки, где публичный Ext/Form.xml обычной формы и каталог Ext/Form/ удалены; для обычной формы в платформенной раскладке остается только Ext/Form.bin.

Status / Статус

Current release: 0.4.5.

Current implementation status:

  • read ordinary Form.bin containers;
  • dump readable object-model Form.xml;
  • extract Module.bsl and picture sidecars;
  • validate Form.xml against bundled schemas;
  • build ordinary Form.bin from the named XML package without a source Form.bin fallback in the public package;
  • preserve module payloads and typed Color/Font properties through repeated build/dump cycles without public raw sidecars;
  • scan local EPF/ERF corpora without committing private artifacts.

Текущий статус реализации:

  • чтение контейнеров обычных Form.bin;
  • выгрузка читаемого объектного Form.xml;
  • извлечение Module.bsl и файлов картинок рядом;
  • проверка Form.xml по встроенным схемам обычных форм;
  • сборка обычного Form.bin из именованного XML-пакета без исходного Form.bin как публичного резервного источника;
  • сохранение данных модуля и типизированных свойств Color/Font при повторных циклах сборки/разборки без публичных raw-sidecar файлов;
  • сканирование локальных EPF/ERF-корпусов без коммита приватных артефактов.

Validation status:

  • v0.4.5 stabilizes typed ordinary-form Color and Font round-trips: rebuilt extended base-info records are dumped again without losing TextColor, BackColor, BorderColor, or Font, and the first 100 UT forms with Color/Font are stable across repeated build/dump cycles.
  • v0.4.4 writes regular Panel page metadata with the platform 25-page capacity profile, fixing strict Designer load for XML-writer rebuilt forms that contain nested panel pages and typed ActiveXControl payloads.
  • v0.4.3 adds typed ordinary-form ActiveXControl XML/XSD support, including CLSID and state blobs, and preserves the PDF ActiveX control found in a direct Form.bin dump/build check.
  • v0.4.2 extends the v0.4.1 edit stabilization with strict platform-validated add Button and delete leaf LabelDecoration scenarios.
  • v0.4.1 preserves the v0.4.0 no-op rebuild baseline and adds a strict platform-validated XML add-control path for a paged LabelDecoration with id=max(existing)+1.
  • v0.4.0 has one UT ordinary list-form no-op dump/build byte-identical for the full Form.bin container, form payload, and module payload.
  • The first-50 UT corpus smoke currently has no exceptions and keeps module payloads stable, but only 1/50 forms are full byte-identical.
  • The next known mismatch class is a root format/profile length variant.

Статус проверок:

  • v0.4.5 стабилизирует обратную сборку типизированных Color и Font для обычных форм: расширенные base-info записи после rebuild снова выгружаются без потери TextColor, BackColor, BorderColor и Font, а первые 100 UT форм с Color/Font стабильны на повторных циклах build/dump.
  • v0.4.4 пишет metadata страниц обычного Panel через платформенный capacity-профиль на 25 страниц, что чинит строгую загрузку Designer для форм, пересобранных XML-writer-ом, с вложенными страницами панели и типизированным ActiveXControl.
  • v0.4.3 добавляет типизированную XML/XSD-поддержку обычного ActiveXControl, включая CLSID и state blobs, и сохраняет PDF ActiveX control в прямой проверке Form.bin dump/build.
  • v0.4.2 расширяет стабилизацию редактирования v0.4.1 строгими платформенными проверками добавления Button и удаления leaf LabelDecoration.
  • v0.4.1 сохраняет baseline обратной сборки v0.4.0 и добавляет строгую платформенную проверку добавления paged LabelDecoration из XML с id=max(existing)+1.
  • в v0.4.0 один UT-сценарий обратной сборки обычной list-form без изменений совпадает побайтно по всему контейнеру Form.bin, данным формы и данным модуля;
  • first-50 UT smoke сейчас проходит без исключений и сохраняет данные модулей, но полное побайтное совпадение есть только у 1/50 форм;
  • следующий известный класс расхождений - вариант длины корневого format/profile.

Automation:

  • CI runs on GitHub Actions for pushes, pull requests, and manual dispatch on Python 3.10, 3.11, and 3.12.
  • CI executes tests, CLI smoke, package build, and package metadata checks.
  • Release workflow runs for v* tags or manual dispatch with a tag input, rebuilds the package, rechecks it, and publishes GitHub Release assets.

Автоматизация:

  • CI запускается в GitHub Actions для push, pull request и manual dispatch на Python 3.10, 3.11 и 3.12;
  • CI выполняет тесты, CLI smoke, сборку пакета и проверку package metadata;
  • релизный workflow запускается для тегов v* или вручную с указанием тега, пересобирает пакет, проверяет его и публикует артефакты в GitHub Release.

Install

python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e '.[dev]'
make test

For the same checks used in CI:

PYTHONPATH=src pytest -q
make smoke
python -m build
python -m twine check dist/*

CLI

Dump an ordinary form binary:

onec-ordinary-forms dump-bin \
  --bin scan-output/exported/Object/Forms/Form/Ext/Form.bin \
  --out scan-output/exported/Object/Forms/Form/Ext/Form.xml

This writes:

scan-output/exported/Object/Forms/Form/Ext/Form.xml
scan-output/exported/Object/Forms/Form/Ext/Form/Module.bsl
scan-output/exported/Object/Forms/Form/Ext/Form/Items/<ElementName>/Picture.gif

Validate and format the XML:

onec-ordinary-forms validate --xml scan-output/exported/Object/Forms/Form/Ext/Form.xml
onec-ordinary-forms format-xml --xml scan-output/exported/Object/Forms/Form/Ext/Form.xml

Show bundled schemas:

onec-ordinary-forms schemas

Build Form.bin back from the object XML package:

onec-ordinary-forms build-bin \
  --xml scan-output/exported/Object/Forms/Form/Ext/Form.xml \
  --out-bin scan-output/rebuilt/Form.bin

Before platform import, use a copy of the source tree where the public ordinary Ext/Form.xml and Ext/Form/ sidecar directory are removed. The platform source layout for ordinary forms should contain Ext/Form.bin; managed forms keep their native Ext/Form.xml.

Use --asset-root only when sidecars are not next to the XML as <Form.xml without suffix>/....

Writer behavior is intentionally conservative while the named ordinary-form object model is being completed. The only public source contract is Form.xml with named form objects plus sidecars; old base-stream rebuild paths and raw diagnostic formats are not supported public workflows.

Diagnostic commands:

onec-ordinary-forms unpack-bin --bin Form.bin --out-dir scan-output/form-parts
onec-ordinary-forms pack-bin --parts-dir scan-output/form-parts --out-bin Form.bin
onec-ordinary-forms scan-corpus --root "<private-processors-dir>" --out-json scan-output/corpus.json

unpack-bin and pack-bin are diagnostics for Form.bin container research. They are not the target public source layout and should not be used as the editable representation of a form.

Python API

from onec_ordinary_forms import build_form_bin, dump_form_bin, validate_form_xml

dump_form_bin(
    "scan-output/exported/Object/Forms/Form/Ext/Form.bin",
    "scan-output/exported/Object/Forms/Form/Ext/Form.xml",
)

validate_form_xml("scan-output/exported/Object/Forms/Form/Ext/Form.xml")

build_form_bin(
    "scan-output/exported/Object/Forms/Form/Ext/Form.xml",
    "scan-output/rebuilt/Form.bin",
)

The default asset root is the XML path without the .xml suffix. For Forms/Form/Ext/Form.xml, sidecars are read from Forms/Form/Ext/Form/.

Platform Validation

For writer changes, validate rebuilt processors through the 1C platform, not only through metadata-level checks. The helper in tools/platform_validate_epf.sh runs Designer batch export and catches malformed ordinary form streams.

Private processors, platform exports, license configuration, and generated reports must stay in ignored local directories such as scan-output/, work/, or /tmp.

Documentation

Fixture Policy

Do not commit private EPF/ERF files, CF/DT dumps, platform archives, license files, OACS databases, generated platform exports, or customer metadata. The examples/fixtures/ directory is ignored except for .gitkeep.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 96.0%
  • Java 2.4%
  • Shell 1.4%
  • Makefile 0.2%