Files
md_to_gost/md2gost/converter.py
T
Igor20264 510f7e7adf
Python application / build (push) Waiting to run
v0.5.2
Что то сделал
2026-09-08 19:37:54 +03:00

156 lines
5.7 KiB
Python

import os
import docx
from docx.document import Document
from .debugger import Debugger
from .parser_ import Parser
from .toc_processor import TocProcessor
from .renderer import Renderer
from .styles import apply_document_styles
from .profiles import (
preprocess_markdown,
find_formula_refs,
get_profile,
DEFAULT_HEADING_NUMBERING,
HEADING_NUMBERING_MODES,
DEFAULT_TOC_MODE,
TOC_MODES,
DEFAULT_TABLE_CONTINUATION,
DEFAULT_LISTING_CONTINUATION,
TABLE_CONTINUATION_MODES,
LISTING_CONTINUATION_MODES,
)
from .label_pass import (
assign_numbers,
set_active_registry,
resolve_reference,
resolve_pending_in_renderables,
)
from .renderable.heading import Heading
from .renderable.toc import ToC
from .renderable.table import Table
from .renderable.listing import Listing
from .renderable.diagram import DiagramFigure
class Converter:
"""Converts markdown file to docx file (MIREA TZ)."""
def __init__(self, input_path: str, output_path: str,
template_path: str = None, debug: bool = False,
doc_type: str = "practice",
heading_numbering: str = DEFAULT_HEADING_NUMBERING,
emdash_to_hyphen: bool = False,
toc_mode: str = DEFAULT_TOC_MODE,
table_continuation: str = DEFAULT_TABLE_CONTINUATION,
listing_continuation: str = DEFAULT_LISTING_CONTINUATION,
hr_pagebreak: bool = False,
styles_path: str | None = None,
markdown_text: str | None = None):
if heading_numbering not in HEADING_NUMBERING_MODES:
raise ValueError(
f"heading_numbering must be one of {HEADING_NUMBERING_MODES}, "
f"got {heading_numbering!r}"
)
if toc_mode not in TOC_MODES:
raise ValueError(
f"toc_mode must be one of {TOC_MODES}, got {toc_mode!r}"
)
if table_continuation not in TABLE_CONTINUATION_MODES:
raise ValueError(
f"table_continuation must be one of {TABLE_CONTINUATION_MODES}, "
f"got {table_continuation!r}"
)
if listing_continuation not in LISTING_CONTINUATION_MODES:
raise ValueError(
f"listing_continuation must be one of {LISTING_CONTINUATION_MODES}, "
f"got {listing_continuation!r}"
)
self._output_path = output_path
self._doc_type = doc_type
self._heading_numbering = heading_numbering
self._emdash_to_hyphen = emdash_to_hyphen
self._toc_mode = toc_mode
self._table_continuation = table_continuation
self._listing_continuation = listing_continuation
self._hr_pagebreak = hr_pagebreak
self._styles_path = styles_path
self._profile = get_profile(doc_type)
self._document: Document = docx.Document(template_path)
self._document._body.clear_content()
md_dir = os.path.dirname(os.path.abspath(input_path)) or "."
os.environ["WORKING_DIR"] = md_dir
self._style_config = apply_document_styles(
self._document,
self._profile.style_preset,
md_dir=md_dir,
styles_path=styles_path,
)
self._debugger = Debugger(self._document) if debug else None
if markdown_text is not None:
raw = markdown_text
else:
with open(input_path, encoding="utf-8") as f:
raw = f.read()
self._raw_markdown = raw
self._preprocessed = preprocess_markdown(raw, emdash_to_hyphen=emdash_to_hyphen)
self.parser = Parser(self._document, self._preprocessed, hr_pagebreak=hr_pagebreak)
def convert(self):
renderables = list(self.parser.parse())
from .biblio_processor import fold_bibliography
renderables = fold_bibliography(
renderables, self._document._body, raw_markdown=self._preprocessed
)
# Resolve heading numbering mode + TOC mode + table continuation
for r in renderables:
if isinstance(r, Heading):
r.apply_numbering_mode(self._heading_numbering)
elif isinstance(r, ToC):
r.set_heading_numbering(self._heading_numbering)
r.set_toc_mode(self._toc_mode)
elif isinstance(r, Table):
r.set_continuation_mode(self._table_continuation)
elif isinstance(r, Listing):
r.set_continuation_mode(self._listing_continuation)
elif isinstance(r, DiagramFigure) and r.listing:
r.listing.set_continuation_mode(self._listing_continuation)
formula_refs = find_formula_refs(self._raw_markdown)
registry = assign_numbers(
renderables, formula_refs,
numbering_scope=self._profile.numbering_scope,
)
set_active_registry(registry)
resolve_pending_in_renderables(renderables, resolve_reference)
renderer = Renderer(self._document, self._debugger,
numbered_equations=formula_refs,
skip_numbering=True,
numbering_scope=self._profile.numbering_scope)
renderer.process(renderables)
TocProcessor().process(renderables)
set_active_registry(None)
@property
def document(self) -> Document:
return self._document
@property
def style_config(self):
return self._style_config
@property
def raw_markdown(self) -> str:
return self._raw_markdown
@property
def doc_type(self) -> str:
return self._doc_type
@property
def heading_numbering(self) -> str:
return self._heading_numbering