mathfmt 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ All notable changes to MathFmt are documented here.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.1.0] - 2026-06-21
8
+
9
+ - Added review-first `scan` and `apply` commands.
10
+ - Added conservative `convert` and environment `doctor` commands.
11
+ - Added native Word equation output for DOCX body text, tables, headers, and footers.
12
+ - Added Codex Skill, tests, bilingual documentation, and release automation.
@@ -0,0 +1,11 @@
1
+ # Code of Conduct
2
+
3
+ MathFmt welcomes contributors of every background and experience level.
4
+
5
+ - Be respectful, constructive, and specific.
6
+ - Critique ideas and code, never people.
7
+ - Do not harass, threaten, discriminate, or publish private information.
8
+ - Respect document privacy and intellectual property.
9
+
10
+ Project maintainers may edit or remove unacceptable contributions and may temporarily or permanently
11
+ restrict participation. Report conduct concerns privately to the repository owner through GitHub.
@@ -0,0 +1,12 @@
1
+ # Contributing
2
+
3
+ Thank you for helping improve MathFmt.
4
+
5
+ 1. Open an issue before large behavioral changes.
6
+ 2. Create a focused branch and keep source documents private.
7
+ 3. Install development dependencies with `python -m pip install -e ".[dev]"`.
8
+ 4. Run `ruff check .` and `pytest` before submitting a pull request.
9
+ 5. Add synthetic fixtures and tests for new notation or DOCX structures.
10
+
11
+ Do not commit copyrighted, confidential, or personally identifying documents. Reproduce document
12
+ problems with the smallest synthetic fixture possible.
mathfmt-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Leo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ include CHANGELOG.md CODE_OF_CONDUCT.md CONTRIBUTING.md LICENSE README.md SECURITY.md
2
+ recursive-include skills *.md *.yaml
mathfmt-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,128 @@
1
+ Metadata-Version: 2.4
2
+ Name: mathfmt
3
+ Version: 0.1.0
4
+ Summary: Typeset plain-text formulas in DOCX files as native Word equations.
5
+ Author: Leo
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/gml853503962-creator/mathfmt
8
+ Project-URL: Repository, https://github.com/gml853503962-creator/mathfmt
9
+ Project-URL: Issues, https://github.com/gml853503962-creator/mathfmt/issues
10
+ Keywords: docx,word,math,omml,equation,typesetting
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Education
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Office/Business :: Office Suites
22
+ Classifier: Topic :: Text Processing :: Markup :: XML
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: lxml>=5.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: build>=1.2; extra == "dev"
29
+ Requires-Dist: pytest>=8.0; extra == "dev"
30
+ Requires-Dist: ruff>=0.6; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # MathFmt
34
+
35
+ [中文](#中文) | [English](#english)
36
+
37
+ MathFmt turns awkward plain-text formulas in Word documents into native Word equations suitable for
38
+ textbooks, exams, and technical reports. Processing stays on your computer.
39
+
40
+ ## 中文
41
+
42
+ MathFmt 将 DOCX 文档中的普通文本公式转换为 Word 原生 OMML 公式,例如把 `ds(t)/dt`、
43
+ `sqrt(x^2+1)` 和 `p1` 排版为纸质教材中常见的分式、根号与上下标。
44
+
45
+ ### 特点
46
+
47
+ - 保留原始 DOCX,始终写入新文件。
48
+ - 支持正文、表格、页眉、页脚和混合文本公式。
49
+ - 自动跳过代码、图片公式和已有 Word 原生公式。
50
+ - 提供可审核流程和保守的一键转换。
51
+ - 完全本地运行,不上传文档。
52
+
53
+ ### 环境要求
54
+
55
+ - Windows 10/11
56
+ - Python 3.10 或更高版本
57
+ - Microsoft Word/Office,并包含 `MML2OMML.XSL`
58
+
59
+ MathFmt 不分发微软的 XSL 文件。它会自动检查常见 Office 安装目录,也可使用 `--xsl` 指定路径。
60
+
61
+ ### 安装
62
+
63
+ ```powershell
64
+ pip install mathfmt
65
+ mathfmt doctor
66
+ ```
67
+
68
+ 从源码开发安装:
69
+
70
+ ```powershell
71
+ git clone https://github.com/gml853503962-creator/mathfmt.git
72
+ cd mathfmt
73
+ python -m pip install -e ".[dev]"
74
+ ```
75
+
76
+ ### 使用
77
+
78
+ ```powershell
79
+ # 保守的一键转换
80
+ mathfmt convert input.docx
81
+
82
+ # 审核后转换
83
+ mathfmt scan input.docx --report candidates.json
84
+ mathfmt apply input.docx --review candidates.json --output output.docx --report result.json
85
+ ```
86
+
87
+ 一键转换默认生成 `input.mathfmt.docx` 和 `input.mathfmt.report.json`,不会覆盖原文件。编辑
88
+ `candidates.json` 中的 `selected`、`source` 或 `linear` 后再执行 `apply`。如果 Office 安装在
89
+ 非标准目录,为 `apply`、`convert` 或 `doctor` 添加 `--xsl C:\path\to\MML2OMML.XSL`。
90
+
91
+ ### Codex Skill
92
+
93
+ 仓库中的 `skills/mathfmt` 可复制到 Codex 技能目录。技能依赖已安装的 `mathfmt` 命令。
94
+
95
+ ## English
96
+
97
+ MathFmt converts plain-text formulas in DOCX files into native Word OMML equations with stacked
98
+ fractions, radicals, superscripts, subscripts, derivatives, and standard mathematical operators.
99
+
100
+ ### Highlights
101
+
102
+ - Never overwrites the source DOCX.
103
+ - Handles body text, tables, headers, footers, and formulas mixed with prose.
104
+ - Skips likely code, image formulas, and existing Word equations.
105
+ - Offers both a review-first workflow and conservative one-step conversion.
106
+ - Processes documents locally without uploading them.
107
+
108
+ ### Requirements and installation
109
+
110
+ MathFmt 0.1 supports Windows, Python 3.10+, and a Microsoft Office installation containing
111
+ `MML2OMML.XSL`. The Microsoft stylesheet is detected locally and is not distributed with MathFmt.
112
+
113
+ ```powershell
114
+ pip install mathfmt
115
+ mathfmt doctor
116
+ mathfmt convert input.docx
117
+ ```
118
+
119
+ For review-first conversion, run `scan`, edit the generated JSON, then run `apply` as shown above.
120
+
121
+ ## Contributing
122
+
123
+ Issues and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md),
124
+ [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md), and [SECURITY.md](SECURITY.md).
125
+
126
+ ## License
127
+
128
+ MIT License. Copyright (c) 2026 Leo.
@@ -0,0 +1,96 @@
1
+ # MathFmt
2
+
3
+ [中文](#中文) | [English](#english)
4
+
5
+ MathFmt turns awkward plain-text formulas in Word documents into native Word equations suitable for
6
+ textbooks, exams, and technical reports. Processing stays on your computer.
7
+
8
+ ## 中文
9
+
10
+ MathFmt 将 DOCX 文档中的普通文本公式转换为 Word 原生 OMML 公式,例如把 `ds(t)/dt`、
11
+ `sqrt(x^2+1)` 和 `p1` 排版为纸质教材中常见的分式、根号与上下标。
12
+
13
+ ### 特点
14
+
15
+ - 保留原始 DOCX,始终写入新文件。
16
+ - 支持正文、表格、页眉、页脚和混合文本公式。
17
+ - 自动跳过代码、图片公式和已有 Word 原生公式。
18
+ - 提供可审核流程和保守的一键转换。
19
+ - 完全本地运行,不上传文档。
20
+
21
+ ### 环境要求
22
+
23
+ - Windows 10/11
24
+ - Python 3.10 或更高版本
25
+ - Microsoft Word/Office,并包含 `MML2OMML.XSL`
26
+
27
+ MathFmt 不分发微软的 XSL 文件。它会自动检查常见 Office 安装目录,也可使用 `--xsl` 指定路径。
28
+
29
+ ### 安装
30
+
31
+ ```powershell
32
+ pip install mathfmt
33
+ mathfmt doctor
34
+ ```
35
+
36
+ 从源码开发安装:
37
+
38
+ ```powershell
39
+ git clone https://github.com/gml853503962-creator/mathfmt.git
40
+ cd mathfmt
41
+ python -m pip install -e ".[dev]"
42
+ ```
43
+
44
+ ### 使用
45
+
46
+ ```powershell
47
+ # 保守的一键转换
48
+ mathfmt convert input.docx
49
+
50
+ # 审核后转换
51
+ mathfmt scan input.docx --report candidates.json
52
+ mathfmt apply input.docx --review candidates.json --output output.docx --report result.json
53
+ ```
54
+
55
+ 一键转换默认生成 `input.mathfmt.docx` 和 `input.mathfmt.report.json`,不会覆盖原文件。编辑
56
+ `candidates.json` 中的 `selected`、`source` 或 `linear` 后再执行 `apply`。如果 Office 安装在
57
+ 非标准目录,为 `apply`、`convert` 或 `doctor` 添加 `--xsl C:\path\to\MML2OMML.XSL`。
58
+
59
+ ### Codex Skill
60
+
61
+ 仓库中的 `skills/mathfmt` 可复制到 Codex 技能目录。技能依赖已安装的 `mathfmt` 命令。
62
+
63
+ ## English
64
+
65
+ MathFmt converts plain-text formulas in DOCX files into native Word OMML equations with stacked
66
+ fractions, radicals, superscripts, subscripts, derivatives, and standard mathematical operators.
67
+
68
+ ### Highlights
69
+
70
+ - Never overwrites the source DOCX.
71
+ - Handles body text, tables, headers, footers, and formulas mixed with prose.
72
+ - Skips likely code, image formulas, and existing Word equations.
73
+ - Offers both a review-first workflow and conservative one-step conversion.
74
+ - Processes documents locally without uploading them.
75
+
76
+ ### Requirements and installation
77
+
78
+ MathFmt 0.1 supports Windows, Python 3.10+, and a Microsoft Office installation containing
79
+ `MML2OMML.XSL`. The Microsoft stylesheet is detected locally and is not distributed with MathFmt.
80
+
81
+ ```powershell
82
+ pip install mathfmt
83
+ mathfmt doctor
84
+ mathfmt convert input.docx
85
+ ```
86
+
87
+ For review-first conversion, run `scan`, edit the generated JSON, then run `apply` as shown above.
88
+
89
+ ## Contributing
90
+
91
+ Issues and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md),
92
+ [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md), and [SECURITY.md](SECURITY.md).
93
+
94
+ ## License
95
+
96
+ MIT License. Copyright (c) 2026 Leo.
@@ -0,0 +1,14 @@
1
+ # Security Policy
2
+
3
+ ## Supported versions
4
+
5
+ Security fixes are provided for the latest released version.
6
+
7
+ ## Reporting a vulnerability
8
+
9
+ Use GitHub private vulnerability reporting for the MathFmt repository. Do not include confidential
10
+ DOCX files; provide a synthetic reproducer instead. Please allow the maintainer reasonable time to
11
+ investigate before public disclosure.
12
+
13
+ MathFmt processes files locally. Treat untrusted DOCX files as untrusted ZIP/XML input and run the
14
+ tool with ordinary user privileges.
@@ -0,0 +1,57 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "mathfmt"
7
+ version = "0.1.0"
8
+ description = "Typeset plain-text formulas in DOCX files as native Word equations."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Leo" }]
14
+ keywords = ["docx", "word", "math", "omml", "equation", "typesetting"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Environment :: Console",
18
+ "Intended Audience :: Education",
19
+ "Intended Audience :: Science/Research",
20
+ "Operating System :: Microsoft :: Windows",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Topic :: Office/Business :: Office Suites",
27
+ "Topic :: Text Processing :: Markup :: XML",
28
+ ]
29
+ dependencies = ["lxml>=5.0"]
30
+
31
+ [project.optional-dependencies]
32
+ dev = ["build>=1.2", "pytest>=8.0", "ruff>=0.6"]
33
+
34
+ [project.scripts]
35
+ mathfmt = "mathfmt.cli:main"
36
+
37
+ [project.urls]
38
+ Homepage = "https://github.com/gml853503962-creator/mathfmt"
39
+ Repository = "https://github.com/gml853503962-creator/mathfmt"
40
+ Issues = "https://github.com/gml853503962-creator/mathfmt/issues"
41
+
42
+ [tool.setuptools]
43
+ package-dir = { "" = "src" }
44
+
45
+ [tool.setuptools.packages.find]
46
+ where = ["src"]
47
+
48
+ [tool.pytest.ini_options]
49
+ addopts = "-ra"
50
+ testpaths = ["tests"]
51
+
52
+ [tool.ruff]
53
+ line-length = 110
54
+ target-version = "py310"
55
+
56
+ [tool.ruff.lint]
57
+ select = ["F", "I", "UP"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: mathfmt
3
+ description: Typeset plain-text formulas in Word DOCX documents as native paper-style Word equations. Use for requests to fix awkward formula symbols, convert typed math into textbook or exam formatting, normalize derivatives and control-system notation, or review formula candidates in DOCX files.
4
+ ---
5
+
6
+ # MathFmt
7
+
8
+ Convert plain-text formulas to native Word OMML equations with the installed `mathfmt` CLI. Preserve
9
+ the source document and inspect the rendered result.
10
+
11
+ ## Workflow
12
+
13
+ 1. Run `mathfmt doctor` and resolve a missing `MML2OMML.XSL` with `--xsl PATH`.
14
+ 2. Use `mathfmt convert input.docx` only when conservative automatic selection is appropriate.
15
+ 3. For mixed technical prose, run `mathfmt scan input.docx --report candidates.json`, review the JSON,
16
+ then run `mathfmt apply input.docx --review candidates.json --output output.docx --report result.json`.
17
+ 4. Keep code, image formulas, and existing native Word equations unchanged.
18
+ 5. Inspect the result report and render every output page before delivery.
19
+
20
+ Read `references/paper-notation.md` when reviewing notation or correcting a candidate's `linear` value.
21
+
22
+ ## Safety
23
+
24
+ - Never use the input path as the output path.
25
+ - Prefer the review-first flow when prose may resemble formulas.
26
+ - Treat skipped candidates as unresolved work and report them.
27
+ - Deliver only the final DOCX unless QA artifacts are requested.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "MathFmt"
3
+ short_description: "Typeset DOCX formulas as native Word equations."
4
+ default_prompt: "Use $mathfmt to convert plain-text formulas in this DOCX into professional paper-style Word equations."
@@ -0,0 +1,11 @@
1
+ # Paper-Style Notation
2
+
3
+ - Use stacked fractions for mathematical division.
4
+ - Use radical bars for `sqrt(...)` or `√(...)`.
5
+ - Render powers and indexes as true superscripts and subscripts.
6
+ - Prefer fraction derivatives such as `ds(t)/dt` and `d²s(t)/dt²`.
7
+ - Use `u(t)` for the unit-step function.
8
+ - Preserve the source Laplace variable: commonly `p` in French material and `s` elsewhere.
9
+ - Use standard symbols such as `±`, `≠`, `≤`, `≥`, `→`, `∞`, `Δ`, and `π`.
10
+ - Prefer invisible multiplication for coefficient-variable products.
11
+ - Split long table formulas at top-level addition or subtraction operators when necessary.
@@ -0,0 +1,6 @@
1
+ """MathFmt public API."""
2
+
3
+ from .core import apply_docx, find_xsl, formula_to_mathml, scan_docx
4
+
5
+ __all__ = ["apply_docx", "find_xsl", "formula_to_mathml", "scan_docx"]
6
+ __version__ = "0.1.0"
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ raise SystemExit(main())
@@ -0,0 +1,136 @@
1
+ """Command-line interface for MathFmt."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import os
8
+ import platform
9
+ import sys
10
+ import tempfile
11
+ from collections.abc import Sequence
12
+ from pathlib import Path
13
+
14
+ from lxml import etree
15
+
16
+ from . import __version__
17
+ from .core import apply_docx, find_xsl, scan_docx
18
+
19
+
20
+ def default_output(input_path: Path) -> Path:
21
+ return input_path.with_name(f"{input_path.stem}.mathfmt.docx")
22
+
23
+
24
+ def default_result_report(output_path: Path) -> Path:
25
+ return output_path.with_name(f"{output_path.stem}.report.json")
26
+
27
+
28
+ def doctor_data(explicit_xsl: Path | None = None) -> dict[str, object]:
29
+ data: dict[str, object] = {
30
+ "mathfmt": __version__,
31
+ "python": platform.python_version(),
32
+ "platform": platform.platform(),
33
+ "windows": os.name == "nt",
34
+ "lxml": etree.LXML_VERSION,
35
+ "xsl": None,
36
+ "ready": False,
37
+ }
38
+ try:
39
+ data["xsl"] = str(find_xsl(explicit_xsl).resolve())
40
+ data["ready"] = True
41
+ except FileNotFoundError as exc:
42
+ data["error"] = str(exc)
43
+ return data
44
+
45
+
46
+ def build_parser() -> argparse.ArgumentParser:
47
+ parser = argparse.ArgumentParser(
48
+ prog="mathfmt",
49
+ description="Typeset plain-text DOCX formulas as native Word equations.",
50
+ )
51
+ parser.add_argument("--version", action="version", version=f"MathFmt {__version__}")
52
+ subparsers = parser.add_subparsers(dest="command", required=True)
53
+
54
+ scan = subparsers.add_parser("scan", help="create a reviewable formula candidate report")
55
+ scan.add_argument("input", type=Path)
56
+ scan.add_argument("--report", type=Path, required=True)
57
+
58
+ apply = subparsers.add_parser("apply", help="apply a reviewed candidate report")
59
+ apply.add_argument("input", type=Path)
60
+ apply.add_argument("--review", type=Path, required=True)
61
+ apply.add_argument("--output", "--out", dest="output", type=Path, required=True)
62
+ apply.add_argument("--report", type=Path, required=True)
63
+ apply.add_argument("--xsl", type=Path)
64
+
65
+ convert = subparsers.add_parser("convert", help="conservatively convert detected formulas in one step")
66
+ convert.add_argument("input", type=Path)
67
+ convert.add_argument("--output", "--out", dest="output", type=Path)
68
+ convert.add_argument("--report", type=Path)
69
+ convert.add_argument("--xsl", type=Path)
70
+
71
+ doctor = subparsers.add_parser("doctor", help="check the local MathFmt environment")
72
+ doctor.add_argument("--xsl", type=Path)
73
+ doctor.add_argument("--json", action="store_true", dest="as_json")
74
+ return parser
75
+
76
+
77
+ def run_convert(args: argparse.Namespace) -> int:
78
+ output = args.output or default_output(args.input)
79
+ report_path = args.report or default_result_report(output)
80
+ xsl = find_xsl(args.xsl)
81
+ with tempfile.TemporaryDirectory(prefix="mathfmt-") as temp_dir:
82
+ review_path = Path(temp_dir) / "candidates.json"
83
+ scan = scan_docx(args.input, review_path)
84
+ result = apply_docx(args.input, review_path, output, report_path, xsl)
85
+ print(f"Candidates: {scan['summary']['candidates']}")
86
+ print(f"Converted: {result['converted_count']}")
87
+ print(f"Skipped: {result['skipped_count']}")
88
+ print(f"Output: {output}")
89
+ print(f"Report: {report_path}")
90
+ return 0 if result["skipped_count"] == 0 else 2
91
+
92
+
93
+ def main(argv: Sequence[str] | None = None) -> int:
94
+ args = build_parser().parse_args(argv)
95
+ try:
96
+ if args.command == "scan":
97
+ report = scan_docx(args.input, args.report)
98
+ print(f"Candidates: {report['summary']['candidates']}")
99
+ print(f"Report: {args.report}")
100
+ return 0
101
+ if args.command == "apply":
102
+ result = apply_docx(
103
+ args.input,
104
+ args.review,
105
+ args.output,
106
+ args.report,
107
+ find_xsl(args.xsl),
108
+ )
109
+ print(f"Converted: {result['converted_count']}")
110
+ print(f"Skipped: {result['skipped_count']}")
111
+ print(f"Output: {args.output}")
112
+ print(f"Report: {args.report}")
113
+ return 0 if result["skipped_count"] == 0 else 2
114
+ if args.command == "convert":
115
+ return run_convert(args)
116
+ if args.command == "doctor":
117
+ data = doctor_data(args.xsl)
118
+ if args.as_json:
119
+ print(json.dumps(data, ensure_ascii=False, indent=2))
120
+ else:
121
+ print(f"MathFmt: {data['mathfmt']}")
122
+ print(f"Python: {data['python']}")
123
+ print(f"Platform: {data['platform']}")
124
+ print(f"MML2OMML.XSL: {data['xsl'] or 'not found'}")
125
+ print(f"Ready: {'yes' if data['ready'] else 'no'}")
126
+ if data.get("error"):
127
+ print(f"Hint: {data['error']}")
128
+ return 0 if data["ready"] else 1
129
+ except (FileNotFoundError, ValueError, json.JSONDecodeError, etree.XMLSyntaxError) as exc:
130
+ print(f"mathfmt: error: {exc}", file=sys.stderr)
131
+ return 1
132
+ return 1
133
+
134
+
135
+ if __name__ == "__main__":
136
+ raise SystemExit(main())