diff --git a/CHANGES.md b/CHANGES.md index bfdd42c..6f6785c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ See for the complete log of changes made to Pythia/Pyre. +## Version 1.3.0 (2026-06-07) + +* Added pygments lexer `pyrejournal' for syntax highlighting of journal output. + ## Version 1.2.0 (2026-05-30) * Added `_flow` journal channel to Component for application flow. diff --git a/Makefile.am b/Makefile.am index 3070cf1..c30bdf3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,7 +3,8 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = \ bin \ libsrc \ - pythia + pythia \ + markup if ENABLE_MPI SUBDIRS += nemesis diff --git a/configure.ac b/configure.ac index 543bd6d..0a2af02 100644 --- a/configure.ac +++ b/configure.ac @@ -93,6 +93,9 @@ AC_CONFIG_FILES([ libsrc/Makefile libsrc/pythia/Makefile pythia/Makefile + markup/Makefile + markup/pygments/Makefile + markup/texmf/Makefile tests/Makefile tests/pytests/Makefile tests/libtests/Makefile diff --git a/markup/Makefile.am b/markup/Makefile.am new file mode 100644 index 0000000..f0dc2cc --- /dev/null +++ b/markup/Makefile.am @@ -0,0 +1,6 @@ +SUBDIRS = \ + pygments \ + texmf + + +# End of file diff --git a/markup/pygments/Makefile.am b/markup/pygments/Makefile.am new file mode 100644 index 0000000..a0f6c21 --- /dev/null +++ b/markup/pygments/Makefile.am @@ -0,0 +1,7 @@ +install-exec-local: + $(PYTHON) -m pip install $(srcdir) + +EXTRA_DIST = \ + pyrejournal_lexer.py \ + pyrejournal_style.py \ + setup.py diff --git a/markup/pygments/pyrejournal_lexer.py b/markup/pygments/pyrejournal_lexer.py new file mode 100644 index 0000000..857b3f4 --- /dev/null +++ b/markup/pygments/pyrejournal_lexer.py @@ -0,0 +1,61 @@ +"""Pygments lexer for PyLith simulation output (semantic, prefix-driven).""" + +from pygments.lexer import RegexLexer, bygroups +from pygments.token import Token + +# Semantic tokens +Marker = Token.Generic.Marker # >> +Info = Token.Keyword # info (green) +Warn = Token.Generic.Warning # warning (orange) +Err = Token.Generic.Error # error (red) +Channel = Token.Name.Tag # (application-flow) etc. (magenta) +Dash = Token.Comment # -- prefix and dim text +Path = Token.Generic.Path # file paths / C++ signatures +Comment = Token.Comment.Single # # ... comments (inline or full-line) +Proc = Token.Generic.Path # [Proc] + + +class PyreJournalLexer(RegexLexer): + name = 'pyrejournal' + aliases = ['pyrejournal', "pylith_output"] + + tokens = { + # Reusable: a '#' (and the rest of the line) is a comment. Placed at the + # end of body-bearing states so prefix rules win first. + 'comment': [ + (r'#.*?$', Comment), + ], + 'root': [ + # >> source/file reference lines (paths don't take # comments) + (r'^\s*(>>)( )(.*)$', bygroups(Marker, Token.Text, Path)), + # -- () — level colored, category magenta. + # Stop the match after the category so any trailing text (incl. an + # inline # comment) is handled by the 'body' state. + (r'^\s*(-- )(info)( )(\([\w._\-]+\))', + bygroups(Dash, Info, Token.Text, Channel), 'body'), + (r'^\s*(-- )(warning)( )(\([\w._\-]+\))', + bygroups(Dash, Warn, Token.Text, Channel), 'body'), + (r'^\s*(-- )(error)( )(\([\w._\-]+\))', + bygroups(Dash, Err, Token.Text, Channel), 'body'), + # plain -- lines: emit the prefix, then let 'body' handle the rest + (r'^\s*(--)( )', bygroups(Dash, Token.Text), 'body'), + (r'^\s*(--)$', Dash), + # PETSC ERROR + #(r'^\s*(\[[0-9]+\])(PETSC ERROR: #[0-9]+.*)$', + # bygroups(Proc, Path)), + #(r'^\s*(\[[0-9]+\])(PETSC ERROR:)( )', + # bygroups(Proc, Err, Token.Text), 'body'), + (r'^\s*(\[[0-9]+\])(PETSC ERROR: #[0-9]+.*)$', + bygroups(Token.Text, Token.Text)), + (r'^\s*(\[[0-9]+\])(PETSC ERROR:)( )', + bygroups(Token.Text, Token.Text, Token.Text), 'body'), + # any other line: hand off to 'body' so inline # comments are caught + (r'', Token.Text, 'body'), + ], + # Body of a line: text until a '#', then the comment, until newline. + 'body': [ + (r'\n', Token.Text, '#pop'), + (r'#.*?(?=\n|$)', Comment), + (r'[^#\n]+', Token.Text), + ], + } diff --git a/markup/pygments/pyrejournal_style.py b/markup/pygments/pyrejournal_style.py new file mode 100644 index 0000000..0295687 --- /dev/null +++ b/markup/pygments/pyrejournal_style.py @@ -0,0 +1,19 @@ +"""Pygments style for PyLith output, matching the terminal color scheme.""" + +from pygments.style import Style +from pygments.token import Token + + +class PyreJournalStyle(Style): + background_color = "#aaaaaa" + styles = { + Token.Generic.Marker: '#aaaaaa', # >> + Token.Keyword: 'bold #00aa00', # info (green) + Token.Generic.Warning: 'bold #ff6600', # warning (orange) + Token.Generic.Error: 'bold #aa0000', # error (red) + Token.Name.Tag: 'bold #aa00aa', # (category) (purple) + Token.Comment: "#aaaaaa", # -- / dim text + Token.Comment.Single: 'italic #6666ff', # # comments (inline/full) + Token.Generic.Path: "#bbbbbb", # paths / signatures + Token.Text: '#000000', # default text + } diff --git a/markup/pygments/setup.py b/markup/pygments/setup.py new file mode 100644 index 0000000..44ce263 --- /dev/null +++ b/markup/pygments/setup.py @@ -0,0 +1,17 @@ +from setuptools import setup + +setup( + name='pyre-journal-lexer', + version='0.1.0', + description='Pygments lexer and style for Pyre journal channels', + py_modules=['pyrejournal_lexer', 'pyrejournal_style'], + install_requires=['Pygments>=2.0'], + entry_points={ + 'pygments.lexers': [ + 'pyre_journal = pyrejournal_lexer:PyreJournalLexer', + ], + 'pygments.styles': [ + 'pyre_journal_style = pyrejournal_style:PyreJournalStyle', + ], + }, +) diff --git a/markup/texmf/Makefile.am b/markup/texmf/Makefile.am new file mode 100644 index 0000000..331e963 --- /dev/null +++ b/markup/texmf/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = \ + pyrejournal.sty diff --git a/markup/texmf/pyrejournal.sty b/markup/texmf/pyrejournal.sty new file mode 100644 index 0000000..421f715 --- /dev/null +++ b/markup/texmf/pyrejournal.sty @@ -0,0 +1,38 @@ +% pyrejournal.sty — minted-based environment for PyLith output. +% +% Requirements: +% 1. pip install -e . (in the pylith-output-lexer/ directory) +% 2. Compile with shell-escape, e.g.: +% pdflatex -shell-escape main.tex +% +% Usage: +% \usepackage{pyre-journal} +% \begin{pyre-journal} +% >> ../../../pylith-5.0.0/libsrc/pylith/meshio/MeshIOPetsc.cc:205:... +% -- info (application-flow) +% -- Component 'meshiopetsc.reader': Reading finite-element mesh ... +% \end{pyre-journal} + +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{pyrejournal}[2026/06/03 PyLith output highlighting] + +\RequirePackage{minted} +\RequirePackage{xcolor} + +% Configure minted defaults for the custom lexer + style. +\setminted[pyrejournal]{ + bgcolor=ltslate!50!white, + fontsize=\tiny, + autogobble, + style=pyre_journal_style, + breaklines=false, +} + +% Convenience environment so callers don't repeat the language name. +\newminted[pyrejournal]{pyrejournal}{} + +% Inline form and file-input form. +\newmintinline[pyrejournalinline]{pyrejournal}{} +\newmintedfile[pyrejournalfile]{pyrejournal}{} + +\endinput diff --git a/pythia/Makefile.am b/pythia/Makefile.am index a2f15df..c301476 100644 --- a/pythia/Makefile.am +++ b/pythia/Makefile.am @@ -1,5 +1,5 @@ install-exec-local: - $(PYTHON) -m pip install $(top_srcdir) + $(PYTHON) -m pip install --no-build-isolation --prefix=$(prefix) $(top_srcdir) EXTRA_DIST = \ __init__.py \