On this page:
bridge
Space  Name
Context
set
set_  group
adjust_  term
adjust_  group
adjust_  sequence
adjust_  rest_  sequence
adjust_  multi
adjust_  block
3.5.1 Spacers and Indirect Binding
8.16.0.4

3.5 Code Binding-Space Adjusters🔗ℹ

 import: scribble/spacer package: rhombus-scribble-lib

A spacer is a compile-time function that is used by forms like rhombus to determine how names within a typeset form should be linked to documentation. For example, :: in some contexts should be linked to the :: expression operator, and in other contexts to the :: binding operator. In general, typeset code cannot be executed or expanded to determine those bindings. Instead, links are determined by a combination of meta_label imports and spacer-applied properties. Spacers thus provide an approximate and best-effort attempt to properly link names in documentation.

A spacer can also communicate indirect binding information to support linking of names after .. For example, the length method name in [1, 2, 3].length() should be linked to the documentation of List.length, independent of whatever meta_label binding the identifier length length might have. See Spacers and Indirect Binding for more information.

definition

bridge name(maybe_left, self_id, tail_id, context_id, esc_id):

  ~in: space ...

  body

  ...

 

maybe_left

 = 

~left left_id

 | 

ϵ

Binds name in the typesetting space to a function that specifies space choices for terms within a name form. For example, fun is bound to a function that (along other things) looks for a result annotation in a fun form and specifies that the annotation is in the #'~annot space. The spacing function will be used only when name itself is in one of the spaces named by a space, where each space is either a keyword for a built-in space (such as #'~annot; see rhombus) or a symbol naming a space.

The body result should be a syntax object like '$self_id $tail_id', but where space properties are added within self_id and tail_id via functions like set and adjust_term. Take care to preserve syntax locations and properties via Syntax.relocate when reconstructing syntax objects; functions like adjust_term use Syntax.relocate automatically, but can obviously only cover the given syntax object.

The context_id argument will be a keyword, symbol, or list of symbols corresponding to one of the spaces. The spacer’s behavior might depend on that context, but often it’s passed along as-is to functions like set or adjust_group.

The esc_id argument is an identifier or operator syntax object that specifies an escape operator, such as #,. Spacing should general not traverse into escaped forms.

If a ~left argument is declared, then the spacer can be called in either infix or prefix mode. When called in prefix mode, the argument for ~left will be an empty syntax object, ''.

annotation

SpaceName

 

annotation

Context

A SpaceName represents a space as a symbol, keyword for a built-in space (see rhombus), or #false for the expr space. A Context is a SpaceName, list of SpaceNames, or pair list of SpaceNames.

A Context represents one or more spaces for recording as a property or adding further space annotations. When a Context is a list to be recorded in a property, space symbols in the list will be tried first to last to look for link-target bindings within each space.

function

fun set(stx :: TermSequence, context :: Context) :: Sequence

 

function

fun set_group(stx :: Group, context :: Context) :: Group

Returns a syntax object like stx, but with properties to specify that it should be rendered as being in the space indicated by context.

function

fun adjust_term(stx :: Term, context :: Context, esc :: Name)

  :: Syntax

 

function

fun adjust_group(stx :: Group, context :: Context, esc :: Name)

  :: Syntax

 

function

fun adjust_sequence(stx :: TermSequence, context :: Context,

                    esc :: Name)

  :: Syntax

 

function

fun adjust_rest_sequence(head :: TermSequence,

                         stx :: TermSequence, context :: Context,

                         esc :: Name)

  :: Syntax

 

function

fun adjust_multi(stx :: Syntax, context :: Context, esc :: Name)

  :: Syntax

 

function

fun adjust_block(stx :: Block, context :: Context, esc :: Name)

  :: Syntax

Similar to set, but recursively finds and applies spacers within stx according to the given context, passing along esc to nested spacers so that they can avoid traversing escape sequences.

The adjust_rest_sequence function supports the possibility of an infix spacer at the start of stx, in which case head is propagated to the spacer as the ~left argument.

3.5.1 Spacers and Indirect Binding🔗ℹ

In addition to setting the space of a name, a spacer can add syntax properties that communicate binding and annotation information. Resolving these properties some requires extra context as provided by the documentation of a form, such as the annotation for a function’s result.

For example, to implement the connection that links the length method name in [1, 2, 3].length() to List.length, the spacer for #%brackets adds a #'annot property to the [1, 2, 3] term with the value 'List'; then, the method List.length can be inferred by treating the annotation name as a namespace.

In the case of to_string(1).length(), the term before . is (1), but that term is part of a function call. The #%call infix spacer adds a property to (1) to say that its annotation is effectively the result of calling to_string. The result annotation for to_string is determined to be String via cross-reference information stored by the fun documentation form as used to document to_string.

The following syntax property keys (see Syntax/property) are recognized; take care to add them as preserved properties:

Some inference steps may require cross-reference information from documentation, such as the result annotation of a function. That cross-reference information can be provided by a documentation form that is bound by doc.bridge, implemented with doc_meta.transformer, and through an ~extract_spacer_infos function that produces a map with the following recognized keys: