From 67185657c13c9042bce1bdce72da63a0b776cba6 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Wed, 5 Aug 2026 19:22:43 +0300 Subject: [PATCH] =?UTF-8?q?refactor(=D1=8D=D0=BC=D0=B8=D1=82=D1=82=D0=B5?= =?UTF-8?q?=D1=80=D1=8B):=20=D0=BA=D0=BE=D0=BF=D0=B8=D0=B8=20=D0=BA=D0=B0?= =?UTF-8?q?=D0=BD=D0=BE=D0=BD-writer'=D0=B0=20=D0=BF=D1=80=D0=B8=D0=B2?= =?UTF-8?q?=D0=B5=D0=B4=D0=B5=D0=BD=D1=8B=20=D0=BA=20=D0=BE=D0=B4=D0=BD?= =?UTF-8?q?=D0=BE=D0=BC=D1=83=20=D0=B2=D0=B8=D0=B4=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Навыки автономны, общей библиотеки нет — значит копии функции записи должны быть буквально одинаковыми, иначе теряется смысл копипасты. PS-порт дисциплину держал (7 копий байт-в-байт), а py разъехались: три варианта имени параметра, два стиля кавычек, у cfe-borrow ещё и другое имя функции (save_xml_file). Сведено к одной форме: имя write_xml_file, параметр content, одинаковое тело. Различаются ровно две вещи, и обе осмысленные: вызов локального базового writer'а (имена исторические — write_utf8_bom / write_text_with_bom / save_text_bom) и одна строка примечания там, где у навыка есть исключение (модуль .bsl, HTML). Текст комментария в PS выровнен с docstring'ом py: раньше он описывал ПРИЧИНУ (here-string наследует LF), а не правило, и после правки py ports разъехались по смыслу. Синтаксис остаётся разным по природе языков: в py docstring (в портах их 421 против 73 функций с #-комментарием — это местная норма), в PS — #. Windows 641/641 обоими портами. Co-Authored-By: Claude Opus 5 --- .claude/skills/cf-init/scripts/cf-init.ps1 | 8 ++--- .claude/skills/cf-init/scripts/cf-init.py | 11 ++++--- .../skills/cfe-borrow/scripts/cfe-borrow.py | 33 ++++++++++--------- .claude/skills/cfe-init/scripts/cfe-init.ps1 | 8 ++--- .claude/skills/cfe-init/scripts/cfe-init.py | 9 ++--- .claude/skills/epf-init/scripts/init.ps1 | 8 ++--- .claude/skills/epf-init/scripts/init.py | 11 ++++--- .claude/skills/erf-init/scripts/init.ps1 | 8 ++--- .claude/skills/erf-init/scripts/init.py | 11 ++++--- .claude/skills/form-add/scripts/form-add.ps1 | 10 +++--- .claude/skills/form-add/scripts/form-add.py | 14 ++++---- .claude/skills/help-add/scripts/add-help.ps1 | 10 +++--- .claude/skills/help-add/scripts/add-help.py | 12 ++++--- .../template-add/scripts/add-template.ps1 | 10 +++--- .../template-add/scripts/add-template.py | 13 +++++--- 15 files changed, 102 insertions(+), 74 deletions(-) diff --git a/.claude/skills/cf-init/scripts/cf-init.ps1 b/.claude/skills/cf-init/scripts/cf-init.ps1 index 63c09165..7efe03ac 100644 --- a/.claude/skills/cf-init/scripts/cf-init.ps1 +++ b/.claude/skills/cf-init/scripts/cf-init.ps1 @@ -242,10 +242,10 @@ if (-not (Test-Path $extDir)) { # --- Write files with UTF-8 BOM --- $enc = New-Object System.Text.UTF8Encoding($true) -# Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце -# файла. Скелет собирается here-string'ами, а .ps1 хранится с LF — отсюда LF и -# смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в -# скелете нет. Модули .bsl и текстовые макеты через эту функцию НЕ пишутся. +# XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. +# +# Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать +# копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. function Write-XmlFile([string]$path, [string]$text, $encoding) { $t = ($text -replace "`r`n", "`n") -replace "`n", "`r`n" [System.IO.File]::WriteAllText($path, $t.TrimEnd("`r", "`n"), $encoding) diff --git a/.claude/skills/cf-init/scripts/cf-init.py b/.claude/skills/cf-init/scripts/cf-init.py index fecbd4fe..11ea0d9f 100644 --- a/.claude/skills/cf-init/scripts/cf-init.py +++ b/.claude/skills/cf-init/scripts/cf-init.py @@ -15,12 +15,15 @@ def write_utf8_bom(path, content): f.write(content) def write_xml_file(path, content): - # Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце - # файла. Скелет собирается тройными кавычками, а .py хранится с LF — отсюда LF и - # смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в - # скелете нет. Модули .bsl и текстовые макеты через неё НЕ пишутся. + """XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. + + Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать + копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. + """ text = content.replace('\r\n', '\n').replace('\n', '\r\n').rstrip('\r\n') write_utf8_bom(path, text) + + def main(): sys.stdout.reconfigure(encoding="utf-8") sys.stderr.reconfigure(encoding="utf-8") diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py index 2625d241..bd94c3fd 100644 --- a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py +++ b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py @@ -430,13 +430,16 @@ def save_text_bom(path, text): fh.write(text) -def save_xml_file(path, text): - """XML в каноне выгрузки Конфигуратора: CRLF, без перевода строки в конце. +def write_xml_file(path, content): + """XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. - Для файлов, которые мы СОЗДАЁМ. Правило: создаём — пишем канон, правим - существующий — наследуем его стиль (см. save_text_bom). + Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать + копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. + + Только для файлов, которые СОЗДАЁМ: правка существующего наследует его стиль. """ - save_text_bom(path, text.replace("\r\n", "\n").replace("\n", "\r\n").rstrip("\r\n")) + text = content.replace('\r\n', '\n').replace('\n', '\r\n').rstrip('\r\n') + save_text_bom(path, text) def new_guid(): @@ -1153,7 +1156,7 @@ def main(): target_dir = os.path.join(ext_dir, CHILD_TYPE_DIR_MAP[rt["TypeName"]]) os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{rt['ObjName']}.xml") - save_xml_file(target_file, borrowed_xml) + write_xml_file(target_file, borrowed_xml) add_to_child_objects(rt["TypeName"], rt["ObjName"]) borrowed_files.append(target_file) info(f" Auto-borrowed: {rt['TypeName']}.{rt['ObjName']}") @@ -1218,7 +1221,7 @@ def main(): t_target_dir = os.path.join(ext_dir, CHILD_TYPE_DIR_MAP[target_type_name]) os.makedirs(t_target_dir, exist_ok=True) t_target_file = os.path.join(t_target_dir, f"{target_obj_name}.xml") - save_xml_file(t_target_file, t_borrowed_xml) + write_xml_file(t_target_file, t_borrowed_xml) add_to_child_objects(target_type_name, target_obj_name) borrowed_files.append(t_target_file) info(f" Auto-borrowed for deep path: {target_type_name}.{target_obj_name}") @@ -1242,7 +1245,7 @@ def main(): s_target_dir = os.path.join(ext_dir, CHILD_TYPE_DIR_MAP[srt["TypeName"]]) os.makedirs(s_target_dir, exist_ok=True) s_target_file = os.path.join(s_target_dir, f"{srt['ObjName']}.xml") - save_xml_file(s_target_file, s_borrowed_xml) + write_xml_file(s_target_file, s_borrowed_xml) add_to_child_objects(srt["TypeName"], srt["ObjName"]) borrowed_files.append(s_target_file) info(f" Auto-borrowed (deep): {srt['TypeName']}.{srt['ObjName']}") @@ -1299,7 +1302,7 @@ def main(): os.makedirs(form_meta_dir, exist_ok=True) form_meta_file = os.path.join(form_meta_dir, f"{form_name}.xml") - save_xml_file(form_meta_file, "\n".join(form_meta_lines)) + write_xml_file(form_meta_file, "\n".join(form_meta_lines)) info(f" Created: {form_meta_file}") # 5. Generate Form.xml with BaseForm @@ -1385,7 +1388,7 @@ def main(): target_dir = os.path.join(ext_dir, "CommonPictures") os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{pic_name}.xml") - save_xml_file(target_file, borrowed_xml) + write_xml_file(target_file, borrowed_xml) add_to_child_objects("CommonPicture", pic_name) auto_borrowed_pics.append(pic_name) borrowed_files.append(target_file) @@ -1434,7 +1437,7 @@ def main(): target_dir = os.path.join(ext_dir, "StyleItems") os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{style_name}.xml") - save_xml_file(target_file, borrowed_xml) + write_xml_file(target_file, borrowed_xml) add_to_child_objects("StyleItem", style_name) borrowed_files.append(target_file) info(f" Auto-borrowed: StyleItem.{style_name}") @@ -1498,7 +1501,7 @@ def main(): target_dir = os.path.join(ext_dir, "Enums") os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{enum_name}.xml") - save_xml_file(target_file, borrowed_xml) + write_xml_file(target_file, borrowed_xml) add_to_child_objects("Enum", enum_name) borrowed_files.append(target_file) info(f" Auto-borrowed: Enum.{enum_name} (with {len(ev_xmls)} EnumValue(s))") @@ -1592,7 +1595,7 @@ def main(): form_xml_dir = os.path.join(form_meta_dir, form_name, "Ext") os.makedirs(form_xml_dir, exist_ok=True) form_xml_file = os.path.join(form_xml_dir, "Form.xml") - save_xml_file(form_xml_file, "".join(parts)) + write_xml_file(form_xml_file, "".join(parts)) info(f" Created: {form_xml_file}") # 6. Create empty Module.bsl — but NEVER overwrite an existing one (re-borrow must @@ -1676,7 +1679,7 @@ def main(): target_dir = os.path.join(ext_dir, dir_name) os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{obj_name}.xml") - save_xml_file(target_file, borrowed_xml) + write_xml_file(target_file, borrowed_xml) info(f" Created: {target_file}") add_to_child_objects(type_name, obj_name) @@ -1703,7 +1706,7 @@ def main(): os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{obj_name}.xml") - save_xml_file(target_file, borrowed_xml) + write_xml_file(target_file, borrowed_xml) info(f" Created: {target_file}") add_to_child_objects(type_name, obj_name) diff --git a/.claude/skills/cfe-init/scripts/cfe-init.ps1 b/.claude/skills/cfe-init/scripts/cfe-init.ps1 index 563f9649..d8790ecd 100644 --- a/.claude/skills/cfe-init/scripts/cfe-init.ps1 +++ b/.claude/skills/cfe-init/scripts/cfe-init.ps1 @@ -255,10 +255,10 @@ if (-not (Test-Path $langDir)) { # --- Write files with UTF-8 BOM --- $enc = New-Object System.Text.UTF8Encoding($true) -# Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце -# файла. Скелет собирается here-string'ами, а .ps1 хранится с LF — отсюда LF и -# смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в -# скелете нет. Модули .bsl и текстовые макеты через эту функцию НЕ пишутся. +# XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. +# +# Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать +# копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. function Write-XmlFile([string]$path, [string]$text, $encoding) { $t = ($text -replace "`r`n", "`n") -replace "`n", "`r`n" [System.IO.File]::WriteAllText($path, $t.TrimEnd("`r", "`n"), $encoding) diff --git a/.claude/skills/cfe-init/scripts/cfe-init.py b/.claude/skills/cfe-init/scripts/cfe-init.py index 2fdc1f23..8fde8d35 100644 --- a/.claude/skills/cfe-init/scripts/cfe-init.py +++ b/.claude/skills/cfe-init/scripts/cfe-init.py @@ -16,10 +16,11 @@ def write_utf8_bom(path, content): f.write(content) def write_xml_file(path, content): - # Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце - # файла. Скелет собирается тройными кавычками, а .py хранится с LF — отсюда LF и - # смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в - # скелете нет. Модули .bsl и текстовые макеты через неё НЕ пишутся. + """XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. + + Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать + копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. + """ text = content.replace('\r\n', '\n').replace('\n', '\r\n').rstrip('\r\n') write_utf8_bom(path, text) diff --git a/.claude/skills/epf-init/scripts/init.ps1 b/.claude/skills/epf-init/scripts/init.ps1 index 7ad5480d..799c6165 100644 --- a/.claude/skills/epf-init/scripts/init.ps1 +++ b/.claude/skills/epf-init/scripts/init.ps1 @@ -64,10 +64,10 @@ $extDir = Join-Path $processorDir "Ext" New-Item -ItemType Directory -Path $extDir -Force | Out-Null $enc = New-Object System.Text.UTF8Encoding($true) -# Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце -# файла. Скелет собирается here-string'ами, а .ps1 хранится с LF — отсюда LF и -# смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в -# скелете нет. Модули .bsl и текстовые макеты через эту функцию НЕ пишутся. +# XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. +# +# Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать +# копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. function Write-XmlFile([string]$path, [string]$text, $encoding) { $t = ($text -replace "`r`n", "`n") -replace "`n", "`r`n" [System.IO.File]::WriteAllText($path, $t.TrimEnd("`r", "`n"), $encoding) diff --git a/.claude/skills/epf-init/scripts/init.py b/.claude/skills/epf-init/scripts/init.py index 971a4514..2e6cd688 100644 --- a/.claude/skills/epf-init/scripts/init.py +++ b/.claude/skills/epf-init/scripts/init.py @@ -15,12 +15,15 @@ def write_utf8_bom(path, content): f.write(content) def write_xml_file(path, content): - # Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце - # файла. Скелет собирается тройными кавычками, а .py хранится с LF — отсюда LF и - # смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в - # скелете нет. Модули .bsl и текстовые макеты через неё НЕ пишутся. + """XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. + + Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать + копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. + """ text = content.replace('\r\n', '\n').replace('\n', '\r\n').rstrip('\r\n') write_utf8_bom(path, text) + + def main(): sys.stdout.reconfigure(encoding="utf-8") sys.stderr.reconfigure(encoding="utf-8") diff --git a/.claude/skills/erf-init/scripts/init.ps1 b/.claude/skills/erf-init/scripts/init.ps1 index eb40eff4..ebf060d5 100644 --- a/.claude/skills/erf-init/scripts/init.ps1 +++ b/.claude/skills/erf-init/scripts/init.ps1 @@ -98,10 +98,10 @@ $extDir = Join-Path $reportDir "Ext" New-Item -ItemType Directory -Path $extDir -Force | Out-Null $enc = New-Object System.Text.UTF8Encoding($true) -# Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце -# файла. Скелет собирается here-string'ами, а .ps1 хранится с LF — отсюда LF и -# смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в -# скелете нет. Модули .bsl и текстовые макеты через эту функцию НЕ пишутся. +# XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. +# +# Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать +# копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. function Write-XmlFile([string]$path, [string]$text, $encoding) { $t = ($text -replace "`r`n", "`n") -replace "`n", "`r`n" [System.IO.File]::WriteAllText($path, $t.TrimEnd("`r", "`n"), $encoding) diff --git a/.claude/skills/erf-init/scripts/init.py b/.claude/skills/erf-init/scripts/init.py index 81c3616c..d1aab39b 100644 --- a/.claude/skills/erf-init/scripts/init.py +++ b/.claude/skills/erf-init/scripts/init.py @@ -15,12 +15,15 @@ def write_utf8_bom(path, content): f.write(content) def write_xml_file(path, content): - # Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце - # файла. Скелет собирается тройными кавычками, а .py хранится с LF — отсюда LF и - # смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в - # скелете нет. Модули .bsl и текстовые макеты через неё НЕ пишутся. + """XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. + + Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать + копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. + """ text = content.replace('\r\n', '\n').replace('\n', '\r\n').rstrip('\r\n') write_utf8_bom(path, text) + + def main(): sys.stdout.reconfigure(encoding="utf-8") sys.stderr.reconfigure(encoding="utf-8") diff --git a/.claude/skills/form-add/scripts/form-add.ps1 b/.claude/skills/form-add/scripts/form-add.ps1 index b0a5e9a2..042bd162 100644 --- a/.claude/skills/form-add/scripts/form-add.ps1 +++ b/.claude/skills/form-add/scripts/form-add.ps1 @@ -337,10 +337,12 @@ $formMetaXml = @" "@ -# Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце -# файла. Скелет собирается here-string'ами, а .ps1 хранится с LF — отсюда LF и -# смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в -# скелете нет. Модули .bsl и текстовые макеты через эту функцию НЕ пишутся. +# XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. +# +# Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать +# копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. +# +# Модуль .bsl сюда НЕ идёт — он пишется отдельно. function Write-XmlFile([string]$path, [string]$text, $encoding) { $t = ($text -replace "`r`n", "`n") -replace "`n", "`r`n" [System.IO.File]::WriteAllText($path, $t.TrimEnd("`r", "`n"), $encoding) diff --git a/.claude/skills/form-add/scripts/form-add.py b/.claude/skills/form-add/scripts/form-add.py index a0d38e1b..a02b3f68 100644 --- a/.claude/skills/form-add/scripts/form-add.py +++ b/.claude/skills/form-add/scripts/form-add.py @@ -265,14 +265,16 @@ def write_text_with_bom(path, text): f.write(text) -def write_xml_file(path, text): - """XML в каноне выгрузки Конфигуратора: CRLF, без перевода строки в конце. +def write_xml_file(path, content): + """XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. - Скелет формы собирается литералами с \n. Сплошная нормализация здесь - безопасна: многострочных текстовых узлов в скелете нет. Модуль .bsl - пишется отдельно, через write_text_with_bom. + Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать + копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. + + Модуль .bsl сюда НЕ идёт — он пишется отдельно. """ - write_text_with_bom(path, text.replace("\r\n", "\n").replace("\n", "\r\n").rstrip("\r\n")) + text = content.replace('\r\n', '\n').replace('\n', '\r\n').rstrip('\r\n') + write_text_with_bom(path, text) def main(): diff --git a/.claude/skills/help-add/scripts/add-help.ps1 b/.claude/skills/help-add/scripts/add-help.ps1 index a7b714b1..15a60f38 100644 --- a/.claude/skills/help-add/scripts/add-help.ps1 +++ b/.claude/skills/help-add/scripts/add-help.ps1 @@ -195,10 +195,12 @@ $helpXml = @" "@ -# Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце -# файла. Скелет собирается here-string'ами, а .ps1 хранится с LF — отсюда LF и -# смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в -# скелете нет. Модули .bsl и текстовые макеты через эту функцию НЕ пишутся. +# XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. +# +# Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать +# копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. +# +# HTML-страница сюда НЕ идёт — платформа хранит её с LF. function Write-XmlFile([string]$path, [string]$text, $encoding) { $t = ($text -replace "`r`n", "`n") -replace "`n", "`r`n" [System.IO.File]::WriteAllText($path, $t.TrimEnd("`r", "`n"), $encoding) diff --git a/.claude/skills/help-add/scripts/add-help.py b/.claude/skills/help-add/scripts/add-help.py index aef7f272..4384fab5 100644 --- a/.claude/skills/help-add/scripts/add-help.py +++ b/.claude/skills/help-add/scripts/add-help.py @@ -263,12 +263,16 @@ def write_text_with_bom(path, text): f.write(text) -def write_xml_file(path, text): - """XML в каноне выгрузки Конфигуратора: CRLF, без перевода строки в конце. +def write_xml_file(path, content): + """XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. - Для Help.xml. HTML-страница сюда НЕ идёт — у неё свой канон (LF). + Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать + копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. + + HTML-страница сюда НЕ идёт — платформа хранит её с LF. """ - write_text_with_bom(path, text.replace("\r\n", "\n").replace("\n", "\r\n").rstrip("\r\n")) + text = content.replace('\r\n', '\n').replace('\n', '\r\n').rstrip('\r\n') + write_text_with_bom(path, text) def main(): diff --git a/.claude/skills/template-add/scripts/add-template.ps1 b/.claude/skills/template-add/scripts/add-template.ps1 index d7f1a02e..b0229cf7 100644 --- a/.claude/skills/template-add/scripts/add-template.ps1 +++ b/.claude/skills/template-add/scripts/add-template.ps1 @@ -260,10 +260,12 @@ $templateMetaXml = @" "@ -# Канон выгрузки Конфигуратора: CRLF в разделителях строк, без перевода в конце -# файла. Скелет собирается here-string'ами, а .ps1 хранится с LF — отсюда LF и -# смешанный EOL. Нормализация здесь безопасна: многострочных текстовых узлов в -# скелете нет. Модули .bsl и текстовые макеты через эту функцию НЕ пишутся. +# XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. +# +# Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать +# копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. +# +# HTML-макет сюда НЕ идёт — платформа хранит его с LF. function Write-XmlFile([string]$path, [string]$text, $encoding) { $t = ($text -replace "`r`n", "`n") -replace "`n", "`r`n" [System.IO.File]::WriteAllText($path, $t.TrimEnd("`r", "`n"), $encoding) diff --git a/.claude/skills/template-add/scripts/add-template.py b/.claude/skills/template-add/scripts/add-template.py index ef419d9b..fe51006f 100644 --- a/.claude/skills/template-add/scripts/add-template.py +++ b/.claude/skills/template-add/scripts/add-template.py @@ -256,13 +256,16 @@ def write_text_with_bom(path, text): f.write(text) -def write_xml_file(path, text): - """XML в каноне выгрузки Конфигуратора: CRLF, без перевода строки в конце. +def write_xml_file(path, content): + """XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце. - Для XML-макетов (SpreadsheetDocument, DataCompositionSchema) и Template.xml. - HTML-макет сюда НЕ идёт — у него свой канон (LF). + Копия этой функции есть в каждом навыке-эмиттере (навыки автономны). Держать + копии одинаковыми — сознательно: разошедшиеся копии сводят на нет весь смысл. + + HTML-макет сюда НЕ идёт — платформа хранит его с LF. """ - write_text_with_bom(path, text.replace("\r\n", "\n").replace("\n", "\r\n").rstrip("\r\n")) + text = content.replace('\r\n', '\n').replace('\n', '\r\n').rstrip('\r\n') + write_text_with_bom(path, text) def detect_format_version(d):