mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-15 15:59:00 +03:00
feat(mxl-compile,mxl-decompile): шрифт ссылкой на стиль или системный
Шрифт бывает не собственным описанием, а ссылкой: на элемент стиля конфигурации
(style:) или на системный шрифт (sys:). Своих атрибутов у такого шрифта нет, и мы
превращали его в пустую запись — faceName="" height="0". ps1 при сборке подставлял
туда Arial 10, то есть подменял данные молча.
В корпусе таких шрифтов 272 в 213 макетах из 10 924: StyleItem 209, WindowsFont 63.
Запись — та же, что у шрифта в описании формы: { "ref": "style:TextFont" }.
kind выводится из префикса, ключом быть не обязан.
Синтетический стенд показал деталь, которую по корпусу было не разглядеть: префикс
sys в корне документа не объявлен, поэтому платформа дописывает объявление xmlns
прямо на узел шрифта — тот же приём, что с цветами из web-палитры.
Порты после этого сошлись ПОЛНОСТЬЮ: на пилоте из 40 макетов совпадают и JSON
декомпиляторов, и собранный XML. Макет со шрифтами добавлен в побайтовую
регрессию, стенд 8 из 13.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0a8671a166
commit
98bcf79b41
@@ -18,6 +18,18 @@
|
||||
Шрифт `"default"` используется, когда стиль не указывает шрифт явно. Если не определён,
|
||||
создаётся автоматически (Arial 10).
|
||||
|
||||
Вместо собственного описания шрифт может быть **ссылкой** — на элемент стиля конфигурации
|
||||
или на системный шрифт. Тогда у него единственное поле:
|
||||
|
||||
```json
|
||||
"fonts": {
|
||||
"основной": { "ref": "style:TextFont" },
|
||||
"системный": { "ref": "sys:DefaultGUIFont" }
|
||||
}
|
||||
```
|
||||
|
||||
Это та же запись, что у шрифта в описании формы.
|
||||
|
||||
## Стили (`styles.<name>`)
|
||||
|
||||
Ключ стиля — имя свойства так, как оно называется в выгрузке. Ниже частые; полный список
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# mxl-compile v1.39 — Compile 1C spreadsheet from JSON
|
||||
# mxl-compile v1.40 — Compile 1C spreadsheet from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -232,8 +232,21 @@ function Format-Num {
|
||||
return [System.Convert]::ToString($v, [System.Globalization.CultureInfo]::InvariantCulture)
|
||||
}
|
||||
|
||||
# Шрифт бывает не собственным, а ссылкой: на элемент стиля конфигурации (style:) или на
|
||||
# системный шрифт (sys:). Вид ссылки определяет kind, и он выводится из префикса.
|
||||
function Get-FontRefKind {
|
||||
param([string]$ref)
|
||||
if ($ref -like 'sys:*') { return 'WindowsFont' }
|
||||
return 'StyleItem'
|
||||
}
|
||||
|
||||
function Add-Font {
|
||||
param([string]$name, $fontDef)
|
||||
if ($fontDef.ref) {
|
||||
$script:fontMap[$name] = $script:fontEntries.Count
|
||||
$script:fontEntries += @{ Ref = "$($fontDef.ref)"; Kind = (Get-FontRefKind "$($fontDef.ref)") }
|
||||
return
|
||||
}
|
||||
$face = if ($fontDef.face) { $fontDef.face } else { "Arial" }
|
||||
$size = if ($fontDef.size) { ConvertTo-FontSize $fontDef.size } else { 10 }
|
||||
$bold = if ($fontDef.bold -eq $true) { "true" } else { "false" }
|
||||
@@ -1618,6 +1631,16 @@ foreach ($ln in $script:lineRegistry) {
|
||||
|
||||
# 7i. Font palette
|
||||
foreach ($fe in $fontEntries) {
|
||||
if ($fe.Ref) {
|
||||
# Префикс sys в корне документа не объявлен, поэтому платформа дописывает объявление
|
||||
# прямо на узел — тот же приём, что с цветами из web-палитры.
|
||||
if ($fe.Ref -like 'sys:*') {
|
||||
X "`t<font xmlns:sys=`"http://v8.1c.ru/8.1/data/ui/fonts/system`" ref=`"$(Esc-Xml $fe.Ref)`" kind=`"$($fe.Kind)`"/>"
|
||||
} else {
|
||||
X "`t<font ref=`"$(Esc-Xml $fe.Ref)`" kind=`"$($fe.Kind)`"/>"
|
||||
}
|
||||
continue
|
||||
}
|
||||
X "`t<font faceName=`"$($fe.Face)`" height=`"$(Format-Num $fe.Size)`" bold=`"$($fe.Bold)`" italic=`"$($fe.Italic)`" underline=`"$($fe.Underline)`" strikeout=`"$($fe.Strikeout)`" kind=`"Absolute`" scale=`"100`"/>"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-compile v1.38 — Compile 1C spreadsheet from JSON
|
||||
# mxl-compile v1.39 — Compile 1C spreadsheet from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import hashlib
|
||||
@@ -480,7 +480,17 @@ def main():
|
||||
font_map = {} # name -> 0-based index
|
||||
font_entries = [] # list of dicts
|
||||
|
||||
def font_ref_kind(ref):
|
||||
"""Шрифт бывает не собственным, а ссылкой: на элемент стиля конфигурации (style:)
|
||||
или на системный шрифт (sys:). Вид ссылки определяет kind, он выводится из префикса."""
|
||||
return 'WindowsFont' if ref.startswith('sys:') else 'StyleItem'
|
||||
|
||||
def add_font(name, font_def):
|
||||
if font_def and font_def.get('ref'):
|
||||
ref = str(font_def['ref'])
|
||||
font_map[name] = len(font_entries)
|
||||
font_entries.append({'Ref': ref, 'Kind': font_ref_kind(ref)})
|
||||
return
|
||||
face = font_def.get('face', 'Arial') if font_def else 'Arial'
|
||||
size = to_font_size(font_def.get('size', 10)) if font_def else 10
|
||||
bold = 'true' if font_def and font_def.get('bold') is True else 'false'
|
||||
@@ -1564,6 +1574,15 @@ def main():
|
||||
|
||||
# 7i. Font palette
|
||||
for fe in font_entries:
|
||||
if fe.get('Ref'):
|
||||
# Префикс sys в корне документа не объявлен, поэтому платформа дописывает
|
||||
# объявление прямо на узел — тот же приём, что с цветами из web-палитры.
|
||||
if fe['Ref'].startswith('sys:'):
|
||||
lines.append(f' <font xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system"'
|
||||
f' ref="{esc_xml(fe["Ref"])}" kind="{fe["Kind"]}"/>')
|
||||
else:
|
||||
lines.append(f' <font ref="{esc_xml(fe["Ref"])}" kind="{fe["Kind"]}"/>')
|
||||
continue
|
||||
lines.append(f'\t<font faceName="{fe["Face"]}" height="{fe["Size"]}" bold="{fe["Bold"]}" italic="{fe["Italic"]}" underline="{fe["Underline"]}" strikeout="{fe["Strikeout"]}" kind="Absolute" scale="100"/>')
|
||||
|
||||
# 7j. Format palette
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# mxl-decompile v1.19 — Decompile 1C spreadsheet to JSON
|
||||
# mxl-decompile v1.20 — Decompile 1C spreadsheet to JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -97,6 +97,9 @@ function ConvertTo-FontSize {
|
||||
$rawFonts = @()
|
||||
foreach ($fNode in $root.SelectNodes("d:font", $ns)) {
|
||||
$rawFonts += @{
|
||||
# Шрифт бывает ссылкой на элемент стиля (style:) или системный шрифт (sys:) —
|
||||
# тогда своих атрибутов у него нет, и без этого он превращался в пустую запись.
|
||||
Ref = $fNode.GetAttribute("ref")
|
||||
Face = $fNode.GetAttribute("faceName")
|
||||
Size = ConvertTo-FontSize $fNode.GetAttribute("height")
|
||||
Bold = $fNode.GetAttribute("bold") -eq "true"
|
||||
@@ -454,6 +457,7 @@ if ($rawFonts.Count -gt 0) {
|
||||
|
||||
function Get-FontKey {
|
||||
param($f)
|
||||
if ($f.Ref) { return "ref=$($f.Ref)" }
|
||||
return "$($f.Face)|$($f.Size)|$($f.Bold)|$($f.Italic)|$($f.Underline)|$($f.Strikeout)"
|
||||
}
|
||||
|
||||
@@ -473,7 +477,11 @@ for ($i = 1; $i -lt $rawFonts.Count; $i++) {
|
||||
|
||||
$name = $null
|
||||
|
||||
if ($f.Face -eq $df.Face -and $f.Size -eq $df.Size) {
|
||||
if ($f.Ref) {
|
||||
# Имя из ссылки: style:SmallTextFont → small-text-font-подобное читаемое имя не даёт
|
||||
# ничего сверх самой ссылки, поэтому берём часть после префикса.
|
||||
$name = ($f.Ref -replace '^[^:]+:', '').ToLowerInvariant()
|
||||
} elseif ($f.Face -eq $df.Face -and $f.Size -eq $df.Size) {
|
||||
if ($f.Bold -and -not $df.Bold -and -not $f.Italic -and -not $f.Underline -and -not $f.Strikeout) {
|
||||
$name = "bold"
|
||||
} elseif ($f.Italic -and -not $df.Italic -and -not $f.Bold) {
|
||||
@@ -1115,6 +1123,7 @@ if ($colWidthMap.Count -gt 0) {
|
||||
$fontsOut = [ordered]@{}
|
||||
foreach ($name in $fontDefs.Keys) {
|
||||
$f = $fontDefs[$name]
|
||||
if ($f.Ref) { $fontsOut[$name] = [ordered]@{ ref = $f.Ref }; continue }
|
||||
$fOut = [ordered]@{ face = $f.Face; size = $f.Size }
|
||||
if ($f.Bold) { $fOut["bold"] = $true }
|
||||
if ($f.Italic) { $fOut["italic"] = $true }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# mxl-decompile v1.19 — Decompile 1C spreadsheet to JSON
|
||||
# mxl-decompile v1.20 — Decompile 1C spreadsheet to JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -267,6 +267,9 @@ def main():
|
||||
raw_fonts = []
|
||||
for f_node in findall(root, "d:font"):
|
||||
raw_fonts.append({
|
||||
# Шрифт бывает ссылкой на элемент стиля (style:) или системный шрифт (sys:) —
|
||||
# тогда своих атрибутов у него нет, и без этого он превращался в пустую запись.
|
||||
"Ref": f_node.get("ref", ""),
|
||||
"Face": f_node.get("faceName", ""),
|
||||
"Size": to_font_size(f_node.get("height", "0")),
|
||||
"Bold": f_node.get("bold") == "true",
|
||||
@@ -610,6 +613,10 @@ def main():
|
||||
font_defs["default"] = raw_fonts[0]
|
||||
|
||||
def get_font_key(f):
|
||||
# Ссылку различаем по ней самой: своих атрибутов у такого шрифта нет, и без этого
|
||||
# две РАЗНЫЕ ссылки схлопывались в одну как «пустые».
|
||||
if f.get("Ref"):
|
||||
return "ref=" + f["Ref"]
|
||||
return f"{f['Face']}|{f['Size']}|{f['Bold']}|{f['Italic']}|{f['Underline']}|{f['Strikeout']}"
|
||||
|
||||
font_key_map = {}
|
||||
@@ -628,7 +635,10 @@ def main():
|
||||
|
||||
name = None
|
||||
|
||||
if f["Face"] == df["Face"] and f["Size"] == df["Size"]:
|
||||
if f.get("Ref"):
|
||||
# Имя из ссылки: читаемее самой ссылки ничего не придумать.
|
||||
name = f["Ref"].split(":", 1)[1].lower()
|
||||
elif f["Face"] == df["Face"] and f["Size"] == df["Size"]:
|
||||
if f["Bold"] and not df["Bold"] and not f["Italic"] and not f["Underline"] and not f["Strikeout"]:
|
||||
name = "bold"
|
||||
elif f["Italic"] and not df["Italic"] and not f["Bold"]:
|
||||
@@ -1117,6 +1127,9 @@ def main():
|
||||
|
||||
fonts_out = OrderedDict()
|
||||
for name, f in font_defs.items():
|
||||
if f.get("Ref"):
|
||||
fonts_out[name] = OrderedDict([("ref", f["Ref"])])
|
||||
continue
|
||||
f_out = OrderedDict()
|
||||
f_out["face"] = f["Face"]
|
||||
f_out["size"] = f["Size"]
|
||||
|
||||
Reference in New Issue
Block a user