Layout handlers

koskari.reader.layouts

Layout handlers for reader block syntax.

Handlers register via koskari.bootstrap.builtin into its builtin registry.

class koskari.reader.layouts.LayoutHandler(head_symbol, read_fn, peers=(), raw=False)

Bases: object

Wrapper for layout handlers with optional peer metadata.

A handler is called as read_fn(reader, source, peers), where reader is the LayoutReader expanding the source. The source is the block cons’s cdr, ((head . args) . entries), each entry a line, (:#line: ELEMENT ...) over the elements the reader saw on it, or a nested :#block: cons; the reader’s fold_line and fold_lines apply the line rule wherever a form is wanted.

koskari.reader.layouts.apply_layout(block, target)

Apply a layout handler to a single block of form `(:#block: (HEAD ARG ...) ENTRY ...)`

Parameters:
  • block – the block to apply the layout handler to

  • target – a LayoutReader or a namespace whose module owns one

Returns:

the layout form

koskari.reader.layouts.apply_layouts(blocks, target)

Walk a proper cons spine of forms and expand each :#block: through the layout handler namespace. Declared peer blocks are consumed from the cdr spine after each primary block; other forms are kept unchanged

Intended for binding as apply-blocks at runtime

Parameters:
  • blocks – proper cons list of forms

  • target – a LayoutReader or a namespace whose module owns one

Returns:

proper cons list of expanded forms

koskari.reader.layouts.apply_lines(entries, target)

Expand the sub-blocks of a body

A body is a proper list of entries, each a line, (:#line: ELEMENT ...) over the elements the reader saw on it, or a nested :#block: cons. A sub-block whose head is not a keyword is lowered in place into a one-element line holding its form, taking declared peer blocks from the entries that follow it. A sub-block whose head is a keyword is left as it is for the handler. A (:#splice: FORM ...) entry, left by a filled quasiquote block, spreads into one line per form. Any element of a line that is a pair is walked for embedded blocks

Parameters:
  • entries – proper cons list of lines and blocks

  • target – a LayoutReader or a namespace whose module owns one

Returns:

proper cons list of entries with every sub-block lowered

koskari.reader.layouts.find_layout(ns, name)

Resolve layout/<head> in the module namespace

Parameters:

name – symbol or string for the block head (e.g. if, begin)

Returns:

LayoutHandler instance, or None

koskari.reader.layouts.is_block(form)

True when form is a :#block: cons

koskari.reader.layouts.is_line(form)

True when form is a :#line: cons

koskari.reader.layouts.layout(head_symbol, peers=(), raw=False)

Decorator that wraps a layout handler function in LayoutHandler.

The handler must have signature (reader, source, peers) and return the parsed form. Optional peers declares peer block head symbols that the parser should gather contiguously after this block.

When raw is true, the reader passes child blocks through without eager layout expansion; the handler receives pure block source forms.

koskari.reader.layouts.reader_for(target)

The layout reader to expand with

Parameters:

target – a LayoutReader, or a namespace whose module owns one

Returns:

the LayoutReader