- add Local Render Mermaid - add page-starе для указания смещения страниц - add Гиперссылки в документе на списки литературы
This commit is contained in:
+92
-10
@@ -65,7 +65,7 @@ TABLE_LABELS = {
|
||||
}
|
||||
FALLBACK_LABELS = {
|
||||
"remote": "Авто: локально, иначе интернет (kroki.io)",
|
||||
"local": "Только этот компьютер (нужна Java)",
|
||||
"local": "Только этот компьютер (без kroki.io)",
|
||||
"off": "Не рисовать диаграммы",
|
||||
}
|
||||
FORMAT_LABELS = {
|
||||
@@ -257,6 +257,7 @@ class Md2GostApp:
|
||||
self.plantuml_var = tk.StringVar()
|
||||
self.kroki_var = tk.StringVar()
|
||||
self.scale_var = tk.StringVar(value="2")
|
||||
self.page_start_var = tk.StringVar(value="")
|
||||
self.highlight_var = tk.BooleanVar(value=False)
|
||||
self.debug_var = tk.BooleanVar(value=False)
|
||||
self.output_var.trace_add("write", self._on_output_edited)
|
||||
@@ -351,8 +352,8 @@ class Md2GostApp:
|
||||
win = tk.Toplevel(self.root)
|
||||
win.title("Настройки — Диаграммы")
|
||||
win.configure(bg=PAPER)
|
||||
win.minsize(560, 420)
|
||||
win.geometry("680x520")
|
||||
win.minsize(560, 480)
|
||||
win.geometry("700x600")
|
||||
win.transient(self.root)
|
||||
extra = ttk.Frame(win, padding=12)
|
||||
extra.pack(fill=tk.BOTH, expand=True)
|
||||
@@ -363,7 +364,8 @@ class Md2GostApp:
|
||||
text=(
|
||||
"Блоки ```uml / ```uml-c4 / ```bpmn / ```mermaid сами станут рисунками.\n"
|
||||
"Схемы редактируются в меню «Шаблоны UML» (файл md2gost.schemes.json).\n"
|
||||
"UML: сначала PlantUML + Java, иначе интернет (kroki.io). Mermaid — только через Kroki."
|
||||
"UML: PlantUML + Java, иначе Kroki. Mermaid: системный браузер → "
|
||||
"Chromium → QuickJS → Kroki (kroki.io остаётся запасным)."
|
||||
),
|
||||
style="Hint.TLabel",
|
||||
wraplength=640,
|
||||
@@ -375,16 +377,25 @@ class Md2GostApp:
|
||||
status_row.grid(row=1, column=0, columnspan=2, sticky="ew", pady=(0, 8))
|
||||
status_row.columnconfigure(0, weight=1)
|
||||
self.diag_status = ttk.Label(status_row, text="", style="Hint.TLabel", wraplength=480, justify=tk.LEFT)
|
||||
self.diag_status.grid(row=0, column=0, sticky="w")
|
||||
self.diag_status.grid(row=0, column=0, sticky="w", rowspan=2)
|
||||
btn_dl = ttk.Button(status_row, text="Скачать PlantUML", command=self._download_plantuml)
|
||||
btn_dl.grid(row=0, column=1, sticky="e", padx=(8, 0))
|
||||
_tip(btn_dl, "Скачать plantuml.jar для локальной отрисовки (нужна Java)")
|
||||
btn_cr = ttk.Button(
|
||||
status_row, text="Скачать headless Chromium", command=self._download_chromium,
|
||||
)
|
||||
btn_cr.grid(row=1, column=1, sticky="e", padx=(8, 0), pady=(4, 0))
|
||||
_tip(
|
||||
btn_cr,
|
||||
"Скачать Chromium для Mermaid в %LOCALAPPDATA%\\md2gost "
|
||||
"(если нет системного Edge/Chrome)",
|
||||
)
|
||||
|
||||
self._combo(
|
||||
extra, 2, "Как рисовать",
|
||||
self.fallback_var,
|
||||
_combo_values(FALLBACK_LABELS, ("remote", "local", "off")),
|
||||
tip="Локально (PlantUML+Java), через интернет или не рисовать",
|
||||
tip="Локально (PlantUML / браузер / QuickJS), через интернет или не рисовать",
|
||||
)
|
||||
self._combo(
|
||||
extra, 3, "Формат схем",
|
||||
@@ -393,12 +404,12 @@ class Md2GostApp:
|
||||
tip="PNG везде; SVG — вектор в Word 2016+ (PNG рядом как запасной)",
|
||||
)
|
||||
|
||||
ttk.Label(extra, text="Scale PNG (PlantUML)").grid(row=4, column=0, sticky="w", padx=(0, 8), pady=3)
|
||||
ttk.Label(extra, text="Scale PNG").grid(row=4, column=0, sticky="w", padx=(0, 8), pady=3)
|
||||
scale_row = ttk.Frame(extra)
|
||||
scale_row.grid(row=4, column=1, sticky="w", pady=3)
|
||||
scale_entry = ttk.Entry(scale_row, textvariable=self.scale_var, width=8)
|
||||
scale_entry.pack(side=tk.LEFT)
|
||||
_tip(scale_entry, "Качество растра PlantUML; на странице размер как при 1")
|
||||
_tip(scale_entry, "Качество растра PlantUML / локального Mermaid; на странице размер как при 1")
|
||||
ttk.Label(
|
||||
scale_row,
|
||||
text=" качество; на странице размер как при 1",
|
||||
@@ -422,7 +433,10 @@ class Md2GostApp:
|
||||
tip="Пусто — вшитый jar или скачанный автоматически")
|
||||
ttk.Label(
|
||||
extra,
|
||||
text="Свой Kroki — только если у вас крутится свой сервер. Пусто = сначала localhost:8000, потом kroki.io.",
|
||||
text=(
|
||||
"Свой Kroki — запасной путь (и для UML без Java). Пусто = localhost:8000, потом kroki.io. "
|
||||
"Mermaid сначала рисуется локально (браузер / QuickJS)."
|
||||
),
|
||||
style="Hint.TLabel",
|
||||
wraplength=640,
|
||||
).grid(row=8, column=0, columnspan=2, sticky="w", pady=(6, 0))
|
||||
@@ -822,8 +836,24 @@ class Md2GostApp:
|
||||
self._combo(main, 4, "Продолжение листингов", self.listing_var, _combo_values(TABLE_LABELS, LISTING_CONTINUATION_MODES),
|
||||
tip="То же для листингов; word требует Windows + Word + pywin32")
|
||||
|
||||
ttk.Label(main, text="Смещение страниц").grid(row=5, column=0, sticky="w", padx=(0, 8), pady=3)
|
||||
page_row = ttk.Frame(main)
|
||||
page_row.grid(row=5, column=1, sticky="w", pady=3)
|
||||
page_entry = ttk.Entry(page_row, textvariable=self.page_start_var, width=8)
|
||||
page_entry.pack(side=tk.LEFT)
|
||||
_tip(
|
||||
page_entry,
|
||||
"Начальный номер PAGE в колонтитуле тела. Пусто — сквозная нумерация Word; "
|
||||
"например 1 — тело с 1 (титул/задание без номера)",
|
||||
)
|
||||
ttk.Label(
|
||||
page_row,
|
||||
text=" пусто = сквозной; 1 = тело с первой",
|
||||
style="Hint.TLabel",
|
||||
).pack(side=tk.LEFT)
|
||||
|
||||
flags = ttk.Frame(main)
|
||||
flags.grid(row=5, column=0, columnspan=2, sticky="w", pady=(8, 0))
|
||||
flags.grid(row=6, column=0, columnspan=2, sticky="w", pady=(8, 0))
|
||||
checks = [
|
||||
("Заменять «—» на «-»", self.emdash_var, "Типографское тире → дефис (методичка обычно требует «—»)"),
|
||||
("--- → разрыв страницы", self.hr_pagebreak_var, "Строка --- станет page break в Word"),
|
||||
@@ -1260,6 +1290,45 @@ class Md2GostApp:
|
||||
"Можно ничего не делать — диаграммы нарисует kroki.io.",
|
||||
)
|
||||
|
||||
def _download_chromium(self) -> None:
|
||||
from .mermaid_renderer import install_playwright_chromium, playwright_browsers_dir, playwright_available
|
||||
|
||||
if not playwright_available():
|
||||
messagebox.showerror(
|
||||
"md2gost",
|
||||
"Пакет playwright не установлен.\n"
|
||||
"Установите: pip install playwright\n"
|
||||
"Mermaid всё равно может рисоваться через QuickJS (mermaidx) или Kroki.",
|
||||
)
|
||||
return
|
||||
dest = playwright_browsers_dir()
|
||||
self._append_log(f"Скачиваю headless Chromium → {dest}")
|
||||
self.root.update_idletasks()
|
||||
|
||||
def work() -> None:
|
||||
ok = install_playwright_chromium()
|
||||
self.root.after(0, lambda: self._on_chromium_installed(ok, dest))
|
||||
|
||||
import threading
|
||||
|
||||
threading.Thread(target=work, daemon=True).start()
|
||||
|
||||
def _on_chromium_installed(self, ok: bool, dest) -> None:
|
||||
self._refresh_diagram_status()
|
||||
if ok:
|
||||
messagebox.showinfo(
|
||||
"md2gost",
|
||||
f"Chromium установлен:\n{dest}\n\n"
|
||||
"Будет использоваться для локального Mermaid, если нет системного Edge/Chrome.",
|
||||
)
|
||||
else:
|
||||
messagebox.showerror(
|
||||
"md2gost",
|
||||
"Не удалось скачать Chromium.\n"
|
||||
"Попробуйте: md2gost --install-chromium\n"
|
||||
"Или оставьте как есть — Mermaid через QuickJS / kroki.io.",
|
||||
)
|
||||
|
||||
def _pick_into(self, var: tk.StringVar, title: str, types) -> None:
|
||||
path = filedialog.askopenfilename(title=title, filetypes=types)
|
||||
if path:
|
||||
@@ -1300,6 +1369,8 @@ class Md2GostApp:
|
||||
self.strict_var.set(bool(req.strict))
|
||||
self.check_pages_var.set(bool(getattr(req, "check_pages", False)))
|
||||
self.table_repeat_header_var.set(bool(getattr(req, "table_repeat_header", False)))
|
||||
start = getattr(req, "page_number_start", None)
|
||||
self.page_start_var.set("" if start is None else str(int(start)))
|
||||
self.highlight_var.set(bool(req.syntax_highlighting))
|
||||
self.debug_var.set(bool(req.debug))
|
||||
self._debug_next = bool(req.debug)
|
||||
@@ -1333,6 +1404,7 @@ class Md2GostApp:
|
||||
check_only=self.check_only_var.get(),
|
||||
check_pages=self.check_pages_var.get(),
|
||||
table_repeat_header=self.table_repeat_header_var.get(),
|
||||
page_number_start=self._parse_page_start(),
|
||||
strict=self.strict_var.get(),
|
||||
syntax_highlighting=self.highlight_var.get(),
|
||||
plantuml_jar=self.plantuml_var.get().strip() or None,
|
||||
@@ -1345,6 +1417,16 @@ class Md2GostApp:
|
||||
open_when_done=self.open_var.get(),
|
||||
)
|
||||
|
||||
def _parse_page_start(self) -> int | None:
|
||||
raw = (self.page_start_var.get() or "").strip()
|
||||
if not raw:
|
||||
return None
|
||||
try:
|
||||
value = int(raw)
|
||||
except ValueError:
|
||||
return None
|
||||
return value if value >= 1 else None
|
||||
|
||||
def _parse_diagram_scale(self) -> float:
|
||||
raw = (self.scale_var.get() or "2").strip().replace(",", ".")
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user