Release 0.4.4: form_xml_to_html v0.2.3 — прототипы форм 1С.
Дерево элементов, ASCII-макет, DataPath · тип в полях, копирование в буфер. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+118
-32
@@ -1,13 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
"""CLI: HTML-прототип управляемой формы 1С из Form.xml.
|
||||
"""CLI: HTML/текстовый прототип управляемой формы 1С из Form.xml.
|
||||
|
||||
Версия: 0.1.0
|
||||
Версия: 0.2.3
|
||||
Автор: Michael BAG <mk@p7net.ru>
|
||||
|
||||
Примеры:
|
||||
python3 form_xml_to_html.py -b crm3-26 -o Справочник.Номенклатура -f ФормаЭлемента
|
||||
python3 form_xml_to_html.py -c configs/form_prototype.crm3-26.json -f ФормаЭлемента
|
||||
python3 form_xml_to_html.py -b crm3-26.rhana -o Общие -f РК_ФормаНастроекРана
|
||||
python3 form_xml_to_html.py -b crm3-26 -o Справочник.Номенклатура -f ФормаЭлемента -p out/form-prototypes
|
||||
python3 form_xml_to_html.py -b crm3-26.rhana -o Общие -f РК_ФормаНастроекРана -O /tmp/form.html -T
|
||||
python3 form_xml_to_html.py -c configs/form_prototype.crm3-26.rhana.json -f РК_ФормаНастроекРана -T -M
|
||||
python3 form_xml_to_html.py -b crm3-26.rhana -o Общие -f РК_ФормаНастроекРана -T -M -t -O /tmp/form.txt
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -22,9 +23,11 @@ from export1c_help.form_prototype import (
|
||||
__email__,
|
||||
__version__,
|
||||
build_output_path,
|
||||
compose_text_report,
|
||||
default_search_roots,
|
||||
export_form_prototype,
|
||||
load_settings_file,
|
||||
parse_form,
|
||||
resolve_form_xml,
|
||||
)
|
||||
from export1c_help.resolve import ResolveError
|
||||
@@ -34,7 +37,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="form_xml_to_html",
|
||||
description=(
|
||||
"Собрать HTML-прототип формы 1С по -b/-o/-f "
|
||||
"HTML/текстовый прототип формы 1С по -b/-o/-f "
|
||||
f"(v{__version__}, {__author__})"
|
||||
),
|
||||
)
|
||||
@@ -58,14 +61,36 @@ def _build_parser() -> argparse.ArgumentParser:
|
||||
"-p",
|
||||
"--out-path",
|
||||
help=(
|
||||
"Каталог вывода: <out>/<конфа>/<тип>/<объект>/<форма>.html "
|
||||
"(по умолчанию out/form-prototypes)"
|
||||
"Каталог вывода HTML: <out>/<конфа>/<тип>/<объект>/<форма>.html"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"-O",
|
||||
"--out-file",
|
||||
help="Файл вывода (если нет -p): HTML или текст при -t",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-T",
|
||||
"--elements-tree",
|
||||
action="store_true",
|
||||
help="Дерево элементов (консоль / в HTML / в текстовый файл)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-M",
|
||||
"--text-maket",
|
||||
action="store_true",
|
||||
help="Текстовый макет «как в окне» (консоль / в HTML / в текстовый файл)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--text-only",
|
||||
action="store_true",
|
||||
help="Только текст в -O (без HTML); нужны -T и/или -M",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
help="JSON с параметрами (base, object, out_path, search_roots), без формы",
|
||||
help="JSON с параметрами (base, object, out_path, out_file, search_roots), без формы",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--version",
|
||||
@@ -75,19 +100,16 @@ def _build_parser() -> argparse.ArgumentParser:
|
||||
return parser
|
||||
|
||||
|
||||
def _resolve_out_path(raw: str | None, *, config_path: Path | None) -> Path:
|
||||
tool_root = Path(__file__).resolve().parent
|
||||
if not raw:
|
||||
return (tool_root / "out" / "form-prototypes").resolve()
|
||||
def _resolve_path(raw: str, *, config_path: Path | None) -> Path:
|
||||
path = Path(raw).expanduser()
|
||||
if path.is_absolute():
|
||||
return path.resolve()
|
||||
# Относительный путь: от cwd; если запускали с -c — также пробуем от каталога config
|
||||
cwd_path = (Path.cwd() / path).resolve()
|
||||
if path.parts[0] in (".", "..") or cwd_path.parent.exists():
|
||||
return cwd_path
|
||||
if config_path is not None:
|
||||
return (config_path.parent / path).resolve()
|
||||
tool_root = Path(__file__).resolve().parent
|
||||
return (tool_root / path).resolve()
|
||||
|
||||
|
||||
@@ -107,12 +129,30 @@ def main(argv: list[str] | None = None) -> int:
|
||||
|
||||
base = args.base or settings.get("base")
|
||||
object_ref = args.object or settings.get("object")
|
||||
out_raw = args.out_path or settings.get("out_path") or settings.get("out")
|
||||
out_path_raw = args.out_path or settings.get("out_path")
|
||||
out_file_raw = args.out_file or settings.get("out_file") or settings.get("out")
|
||||
|
||||
want_tree = bool(args.elements_tree)
|
||||
want_maket = bool(args.text_maket)
|
||||
text_only = bool(args.text_only)
|
||||
|
||||
if not base:
|
||||
parser.error("нужен -b/--base или base в -c/--config")
|
||||
if not object_ref:
|
||||
parser.error("нужен -o/--object или object в -c/--config")
|
||||
if text_only and not out_file_raw:
|
||||
parser.error("при -t/--text-only нужен -O/--out-file")
|
||||
if text_only and not (want_tree or want_maket):
|
||||
parser.error("при -t/--text-only укажите -T и/или -M")
|
||||
if text_only and out_path_raw:
|
||||
parser.error("при -t/--text-only используйте -O, не -p")
|
||||
|
||||
want_html = not text_only and bool(out_path_raw or out_file_raw)
|
||||
if not want_html and not (want_tree or want_maket):
|
||||
parser.error(
|
||||
"укажите вывод: -p/--out-path или -O/--out-file для HTML, "
|
||||
"либо -T/-M для текста в консоль (или -t -O для текстового файла)"
|
||||
)
|
||||
|
||||
search_roots = default_search_roots(config_path)
|
||||
extra_roots = settings.get("search_roots") or []
|
||||
@@ -131,28 +171,74 @@ def main(argv: list[str] | None = None) -> int:
|
||||
form_name=args.form,
|
||||
search_roots=search_roots,
|
||||
)
|
||||
out_root = _resolve_out_path(
|
||||
str(out_raw) if out_raw else None, config_path=config_path
|
||||
)
|
||||
output_html = build_output_path(
|
||||
out_root,
|
||||
base_name=base_name,
|
||||
type_dir=type_dir,
|
||||
object_name=object_name,
|
||||
form_name=args.form.strip(),
|
||||
)
|
||||
export_form_prototype(
|
||||
form_xml=form_xml,
|
||||
output_html=output_html,
|
||||
display_title=f"{object_name} · {args.form.strip()}",
|
||||
form = parse_form(form_xml)
|
||||
display_title = f"{object_name} · {args.form.strip()}"
|
||||
form["title"] = display_title
|
||||
|
||||
text_report = compose_text_report(
|
||||
form, include_tree=want_tree, include_maket=want_maket
|
||||
)
|
||||
|
||||
# Текст в консоль, если -O не задан (и есть что показывать)
|
||||
if not out_file_raw and (want_tree or want_maket) and text_report:
|
||||
sys.stdout.write(text_report)
|
||||
if not text_report.endswith("\n"):
|
||||
sys.stdout.write("\n")
|
||||
|
||||
written: Path | None = None
|
||||
|
||||
if text_only:
|
||||
out_file = _resolve_path(str(out_file_raw), config_path=config_path)
|
||||
out_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
out_file.write_text(text_report, encoding="utf-8")
|
||||
written = out_file
|
||||
elif want_html:
|
||||
if out_path_raw:
|
||||
out_root = _resolve_path(str(out_path_raw), config_path=config_path)
|
||||
output_html = build_output_path(
|
||||
out_root,
|
||||
base_name=base_name,
|
||||
type_dir=type_dir,
|
||||
object_name=object_name,
|
||||
form_name=args.form.strip(),
|
||||
)
|
||||
else:
|
||||
output_html = _resolve_path(str(out_file_raw), config_path=config_path)
|
||||
# В HTML дерево/макет добавляются при -O (и при -p тоже, если флаги заданы)
|
||||
# По ТЗ: при заданном -O — в HTML; без -O текст в консоль уже выше.
|
||||
embed_tree = want_tree and bool(out_file_raw or out_path_raw)
|
||||
embed_maket = want_maket and bool(out_file_raw or out_path_raw)
|
||||
# Уточнение ТЗ: «Если -O не задан → консоль; иначе → html с деревом».
|
||||
# При только -p без -O: HTML без обязательного встраивания; дерево уже в консоли.
|
||||
if out_file_raw and not out_path_raw:
|
||||
embed_tree = want_tree
|
||||
embed_maket = want_maket
|
||||
elif out_path_raw and not out_file_raw:
|
||||
# -p без -O: HTML базовый; -T/-M уже ушли в консоль
|
||||
embed_tree = False
|
||||
embed_maket = False
|
||||
else:
|
||||
# и -p, и -O: HTML в структуру -p, в файл встраиваем при наличии флагов
|
||||
embed_tree = want_tree
|
||||
embed_maket = want_maket
|
||||
|
||||
export_form_prototype(
|
||||
form=form,
|
||||
output_html=output_html,
|
||||
display_title=display_title,
|
||||
include_elements_tree=embed_tree,
|
||||
include_text_maket=embed_maket,
|
||||
)
|
||||
written = output_html
|
||||
|
||||
except ResolveError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
print(f"OK: {output_html}")
|
||||
print(f"src: {form_xml}")
|
||||
print(f"form_xml_to_html {__version__} — {__author__}")
|
||||
if written is not None:
|
||||
print(f"OK: {written}", file=sys.stderr)
|
||||
print(f"src: {form_xml}", file=sys.stderr)
|
||||
print(f"form_xml_to_html {__version__} — {__author__}", file=sys.stderr)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user