diff --git a/src/packages/main/lektor_main/latex.py b/src/packages/main/lektor_main/latex.py index 0d29902..6a739a7 100644 --- a/src/packages/main/lektor_main/latex.py +++ b/src/packages/main/lektor_main/latex.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- from lektor.build_programs import BuildProgram # subclass -from lektor.reporter import reporter # build, verbosity from lektor.sourceobj import VirtualSourceObject # subclass -import click import os import re import shutil # which, copyfile, rmtree @@ -13,6 +11,7 @@ if TYPE_CHECKING: from lektor.builder import Artifact, Builder, BuildState from lektor.db import Record from lektor.environment import Environment +from .log import Log from .utils import lookup_template_path VPATH = 'LatexPDF' @@ -168,18 +167,6 @@ def raw_text_to_tex(text: str) -> str: return text.replace(' ', '~') -# ---------------------------------------------------- -# Helper methods -# ---------------------------------------------------- - -def _report_updated(msg: str) -> None: - click.echo('{} {}'.format(click.style('U', fg='green'), msg)) - - -def _report_error(msg: str) -> None: - click.echo('{} {}'.format(click.style('E', fg='red'), msg)) - - # ---------------------------------------------------- # PDF Build Program & Source # ---------------------------------------------------- @@ -220,7 +207,7 @@ class TexSources: if sources: msg = f'PDF builder ({TEXER})' - with reporter.build(msg, builder): # type: ignore[attr-defined] + with Log.group(msg, builder): for rec_ref in sources: builder.build(PdfSource(rec_ref())) @@ -259,7 +246,7 @@ class PdfSource(VirtualSourceObject): def build(self, build_state: 'BuildState') -> None: cmd_tex = shutil.which(TEXER) if not cmd_tex: - _report_error(f'Skip PDF export. {TEXER} not found.') + Log.error(f'Skip PDF export. {TEXER} not found.') return # filename / path variables @@ -278,10 +265,9 @@ class PdfSource(VirtualSourceObject): fp.write('\\def\\buildDir{' + build_dir + '}') # run lualatex - silent = reporter.verbosity == 0 # type: ignore[attr-defined] for i in range(1, 3): if i > 1: - _report_updated(self.url_path.lstrip('/') + f' [{i}/2]') + Log.updated(self.url_path.lstrip('/') + f' [{i}/2]') p = shell.run([ cmd_tex, # lualatex '--halt-on-error', @@ -289,13 +275,13 @@ class PdfSource(VirtualSourceObject): tex_src # tex file ], cwd=tex_root, # change work dir so lualatex can find setup.tex - stdout=shell.DEVNULL if silent else None, # dont spam console + stdout=None if Log.isVerbose() else shell.DEVNULL, input=b'') # auto-reply to stdin on error if p.returncode == 0: shutil.copyfile(pdf_src, pdf_dest) else: - _report_error(f'{TEXER} returned error code {p.returncode}') + Log.error(f'{TEXER} returned error code {p.returncode}') break # cleanup diff --git a/src/packages/main/lektor_main/log.py b/src/packages/main/lektor_main/log.py new file mode 100644 index 0000000..b3ab2d2 --- /dev/null +++ b/src/packages/main/lektor_main/log.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +from lektor.reporter import reporter # build, verbosity +from click import echo as c_echo, style as c_style # type:ignore[attr-defined] +from contextlib import contextmanager +import time +from typing import TYPE_CHECKING, Any, Optional +if TYPE_CHECKING: + from lektor.builder import Builder + + +class Log: + class Style: + @staticmethod + def red(msg: str) -> str: + return c_style(msg, fg='red', bold=True) # type: ignore + + @staticmethod + def verbosity() -> int: + return reporter.verbosity # type: ignore[attr-defined, no-any-return] + + @staticmethod + def isVerbose() -> bool: + return Log.verbosity() > 0 + + @staticmethod + def updated(msg: str) -> None: + c_echo('{} {}'.format(c_style('U', fg='green'), msg)) + + @staticmethod + def error(msg: str) -> None: + c_echo('{} {}'.format(c_style('E', fg='red'), msg)) + + @staticmethod + def generic(msg: str) -> None: + c_echo(c_style(msg, fg='cyan')) + + @staticmethod + def group(msg: str, builder: Optional['Builder'] = None) -> Any: + if builder: + return reporter.build(msg, builder) # type: ignore[attr-defined] + else: + return _fallback_grouping(msg) + + +@contextmanager +def _fallback_grouping(msg: str) -> Any: + start_time = time.time() + Log.generic('Started {}'.format(msg)) + try: + yield + finally: + Log.generic('Finished {} in {:.2f} sec'.format( + msg, time.time() - start_time))