@@ -0,0 +1,105 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user