106 lines
3.3 KiB
Python
106 lines
3.3 KiB
Python
#!/usr/bin/env python
|
||
"""
|
||
Два пайплайна:
|
||
1) MD → LaTeX (этот модуль пишет project/)
|
||
2) LaTeX → PDF (XeLaTeX; флаг --pdf или scripts/md2pdf.ps1)
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import argparse
|
||
import shutil
|
||
import subprocess
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
from .converter import convert_md_to_latex_project
|
||
|
||
|
||
def _run_xelatex(project_dir: Path, passes: int = 2) -> int:
|
||
main = project_dir / "main.tex"
|
||
if not main.is_file():
|
||
print(f"Error: {main} not found", file=sys.stderr)
|
||
return 2
|
||
|
||
xelatex = shutil.which("xelatex")
|
||
latexmk = shutil.which("latexmk")
|
||
|
||
if latexmk:
|
||
cmd = [
|
||
latexmk, "-xelatex", "-interaction=nonstopmode",
|
||
"-halt-on-error", "main.tex",
|
||
]
|
||
print("Pipeline 2 (LaTeX → PDF):", " ".join(cmd))
|
||
r = subprocess.run(cmd, cwd=project_dir)
|
||
return r.returncode
|
||
|
||
if not xelatex:
|
||
print(
|
||
"Error: XeLaTeX not found (install MiKTeX/TeX Live and add to PATH).\n"
|
||
"Pipeline 1 done — compile manually:\n"
|
||
f" cd {project_dir}\n"
|
||
" xelatex main.tex && xelatex main.tex",
|
||
file=sys.stderr,
|
||
)
|
||
return 3
|
||
|
||
for i in range(passes):
|
||
cmd = [xelatex, "-interaction=nonstopmode", "-halt-on-error", "main.tex"]
|
||
print(f"Pipeline 2 pass {i + 1}/{passes}:", " ".join(cmd))
|
||
r = subprocess.run(cmd, cwd=project_dir)
|
||
if r.returncode != 0:
|
||
return r.returncode
|
||
return 0
|
||
|
||
|
||
def main() -> None:
|
||
p = argparse.ArgumentParser(
|
||
prog="md2latex",
|
||
description=(
|
||
"Пайплайн 1: MD (диалект md2gost) → LaTeX-проект (шаблон МИРЭА). "
|
||
"Пайплайн 2: XeLaTeX → PDF (опция --pdf)."
|
||
),
|
||
)
|
||
p.add_argument("filename", help="Исходный .md")
|
||
p.add_argument(
|
||
"-o", "--output-dir",
|
||
default=None,
|
||
help="Каталог LaTeX-проекта (по умолчанию: <stem>_latex рядом с md)",
|
||
)
|
||
p.add_argument("--titlepage", help="PDF титульного листа → titlepage.pdf")
|
||
p.add_argument(
|
||
"--pdf",
|
||
action="store_true",
|
||
help="Пайплайн 2: сразу собрать PDF через XeLaTeX/latexmk",
|
||
)
|
||
p.add_argument(
|
||
"--xelatex-passes",
|
||
type=int,
|
||
default=2,
|
||
help="Число проходов xelatex, если нет latexmk (по умолчанию 2)",
|
||
)
|
||
args = p.parse_args()
|
||
|
||
md = Path(args.filename)
|
||
if not md.suffix.lower() == ".md":
|
||
print("Error: filename must be .md", file=sys.stderr)
|
||
sys.exit(1)
|
||
if not md.is_file():
|
||
print(f"Error: file not found: {md}", file=sys.stderr)
|
||
sys.exit(1)
|
||
|
||
out = Path(args.output_dir) if args.output_dir else md.with_name(md.stem + "_latex")
|
||
main_tex = convert_md_to_latex_project(md, out, titlepage=args.titlepage)
|
||
print(f"Pipeline 1 (MD → LaTeX): {main_tex}")
|
||
|
||
if args.pdf:
|
||
code = _run_xelatex(out, passes=args.xelatex_passes)
|
||
pdf = out / "main.pdf"
|
||
if code == 0 and pdf.is_file():
|
||
print(f"Pipeline 2 (LaTeX → PDF): {pdf.resolve()}")
|
||
sys.exit(code)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|