Skip to main content

A markup language for UI layouts — define panels once, render anywhere.

Project description

panelmark

panelmark is a zero-dependency Python library for defining terminal UI layouts using a readable ASCII-art shell language, and for implementing the interaction logic that runs inside them.

panelmark is the core library in the panelmark ecosystem. It has no runtime dependencies on any terminal library. It defines:


What is real today

Feature Status
Shell definition language (ASCII-art DSL) ✅ Fully working
# line comments and /* */ block comments ✅ Fully working
Horizontal splits (= / - border rows) ✅ Fully working
Vertical splits — single-line divider (|) ✅ Fully working
Vertical splits — double-line divider (||) ✅ Fully working
Equal-width fill splits (all columns fill-width) ✅ Columns share space equally (differ by at most 1 char)
Panel headings (__text__ syntax) ⚠️ Parsed and stored; renderers must implement display
Shell state machine (focus, dirty tracking, key dispatch, on_change, bind) ✅ Fully working
Draw command abstraction (DrawCommand, RenderContext, WriteCmd, FillCmd, CursorCmd) ✅ Fully working
Interaction base class ✅ Fully working

See panelmark-tui limitations for the combined limitations list.


  • The shell definition language — an ASCII-art syntax for describing layouts
  • The layout model — resolved geometry (row, col, width, height) for each named region
  • The draw command abstraction — renderer-agnostic DrawCommand types returned by interactions
  • The Interaction base class — the protocol all interactive widgets implement
  • The Shell state machine — focus, dirty tracking, key dispatch, and value observation

To actually display a shell in a terminal, pair panelmark with panelmark-tui, which wraps blessed and provides a full event loop, built-in interactions, and renderer-specific convenience widgets.


Installation

pip install panelmark

Quick start

from panelmark import Shell, Interaction
from panelmark.draw import DrawCommand, RenderContext, WriteCmd, FillCmd

# 1. Define a layout
LAYOUT = """
|=== <bold>My App</> ===|
|{10R $sidebar$  }|{$main$        }|
|==================|
|{2R  $status$              }|
|==================|
"""

# 2. Implement an interaction
class Label(Interaction):
    def __init__(self, text: str):
        self._text = text

    @property
    def is_focusable(self) -> bool:
        return False

    def render(self, context: RenderContext, focused: bool = False) -> list[DrawCommand]:
        line = self._text[:context.width].ljust(context.width)
        return [WriteCmd(row=0, col=0, text=line)]

    def handle_key(self, key) -> tuple:
        return False, self.get_value()

    def get_value(self):
        return self._text

    def set_value(self, value) -> None:
        self._text = str(value)

# 3. Assign interactions to regions
shell = Shell(LAYOUT)
shell.assign("sidebar", Label("Navigation"))
shell.assign("main", Label("Content area"))
shell.assign("status", Label("Ready"))

# 4. Drive with a renderer (e.g. panelmark-tui)
# result = shell.run()   ← panelmark_tui.Shell adds run()

Documentation

Document Description
Shell Language Shell, region, and panel concepts; state machine methods
Shell Language Syntax Full grammar reference for the ASCII-art layout DSL
Shell Language Examples Annotated examples; custom interactions; portable rendering patterns
Draw Commands DrawCommand types, RenderContext, and the style dict
Custom Interactions Implementing the Interaction ABC
Renderer Spec Renderer compatibility contract, portable library layer, and extension policy
Ecosystem Overview Layered design; package responsibilities; dependency direction
Choosing a Renderer Decision tree for selecting the right package

Ecosystem

panelmark follows a layered design. The core library is renderer-agnostic; renderer-specific packages extend it.

Package Role
panelmark (this package) Zero-dependency core: shell language, layout, draw commands, interaction protocol
panelmark-tui Terminal renderer (blessed); portable-library-compatible
panelmark-html Static HTML/CSS renderer; pre-alpha; foundation for panelmark-web
panelmark-web Live web runtime via WebSockets; portable-library-compatible

See ecosystem overview for the full design rationale and dependency diagram.


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

panelmark-0.1.0.tar.gz (27.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

panelmark-0.1.0-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file panelmark-0.1.0.tar.gz.

File metadata

  • Download URL: panelmark-0.1.0.tar.gz
  • Upload date:
  • Size: 27.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for panelmark-0.1.0.tar.gz
Algorithm Hash digest
SHA256 34c75eaafce1301a79638627e3d111ab8f591c0d52e11c81e86f9bc2384bba2d
MD5 7d6dc53d3d9413dc24e5cae9242ee7ba
BLAKE2b-256 3fee35f78a12ed1d49aea23e0ef0674eac03e5db6c4125b7d628520a465422dc

See more details on using hashes here.

File details

Details for the file panelmark-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: panelmark-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for panelmark-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 532d4aee96feea769b20739f65517ae1e966eb85633e9df52c0f677bd568f2e8
MD5 22d10292f8382eb5ed991586167cf6b4
BLAKE2b-256 7cad93028e10add8f9bfe660758e0ec5828b7abe2d6a6f9b70c5e5a02bad109a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page