► |  | The Racket Guide

1 | Welcome to Racket
2 | Racket Essentials
3 | Built-In Datatypes
4 | Expressions and Definitions
5 | Programmer-Defined Datatypes
6 | Modules
7 | Contracts
8 | Input and Output
9 | Regular Expressions
10 | Exceptions and Control
11 | Iterations and Comprehensions
12 | Pattern Matching
13 | Classes and Objects
14 | Units
15 | Reflection and Dynamic Evaluation
16 | Macros
17 | Creating Languages
18 | Concurrency and Synchronization
19 | Performance
20 | Parallelism
21 | Running and Creating Executables
22 | More Libraries
23 | Dialects of Racket and Scheme
24 | Command-Line Tools and Your Editor of Choice
| Bibliography
| Index

► | 17 | Creating Languages

17.1 | Module Languages
17.2 | Reader Extensions
17.3 | Defining new #lang Languages

▼ | 17.3 | Defining new #lang Languages

17.3.1 | Designating a #lang Language
17.3.2 | Using #lang reader
17.3.3 | Using #lang s-exp syntax/ module-reader
17.3.4 | Installing a Language
17.3.5 | Source-Handling Configuration
17.3.6 | Module-Handling Configuration

top ← prev up next →

##### 17.3.5`` Source-Handling Configuration

The Racket distribution includes a Scribble language for writing prose documents, where Scribble extends the normal Racket to better support text. Here is an example Scribble document:

#lang scribble/base
@(define (get-name) "Self-Describing Document")
@title[(get-name)]
The title of this document is ``@(get-name).''

If you put that program in DrRacket’s definitions area and click Run, then nothing much appears to happen. The scribble/base language just binds and exports doc as a description of a document, similar to the way that "literal.rkt" exports a string as data.

Simply opening a module with the language scribble/base in DrRacket, however, causes a Scribble HTML button to appear. Furthermore, DrRacket knows how to colorize Scribble syntax by coloring green those parts of the document that correspond to literal text. The language name scribble/base is not hard-wired into DrRacket. Instead, the implementation of the scribble/base language provides button and syntax-coloring information in response to a query from DrRacket.

For security reasons, only languages that have been specifically installed by a user can respond to language-information queries. If you have installed the literal language as described in Installing a Language, then you can adjust "literal/main.rkt" so that DrRacket treats the content of a module in the literal language as plain text instead of (erroneously) as Racket syntax:

> > "literal/main.rkt"

> > > #lang racket
> > > (module reader racket
> > > (require syntax/strip-context)
> > > (provide (rename-out [literal-read read]
> > > [literal-read-syntax read-syntax])
> > > get-info)
> > > (define (literal-read in)
> > > (syntax->datum
> > > (literal-read-syntax #f in)))
> > > (define (literal-read-syntax src in)
> > > (with-syntax ([str (port->string in)])
> > > (strip-context
> > > #'(module anything racket
> > > (provide data)
> > > (define data 'str)))))
> > > (define (get-info in mod line col pos)
> > > (lambda (key default)
> > > (case key
> > > [(color-lexer)
> > > (dynamic-require 'syntax-color/default-lexer
> > > 'default-lexer)]
> > > [else default]))))

This revised literal implementation provides a get-info function. The get-info function is called by read-language (which DrRacket calls) with the source input stream and location information, in case query results should depend on the content of the module after the language name (which is not the case for literal). The result of get-info is a function of two arguments. The first argument is always a symbol, indicating the kind of information that a tool requests from the language; the second argument is the default result to be returned if the language does not recognize the query or has no information for it.

After DrRacket obtains the result of get-info for a language, it calls the function with a 'color-lexer query; the result should be a function that implements syntax-coloring parsing on an input stream. For literal, the syntax-color/default-lexer module provides a default-lexer syntax-coloring parser that is suitable for plain text, so literal loads and returns that parser in response to a 'color-lexer query.

The set of symbols that a programming tool uses for queries is entirely between the tool and the languages that choose to cooperate with it. For example, in addition to 'color-lexer, DrRacket uses a 'drracket:toolbar-buttons query to determine which buttons should be available in the toolbar to operate on modules using the language.

The syntax/module-reader language lets you specify get-info handling through a #:info optional specification. The protocol for an #:info function is slightly different from the raw get-info protocol; the revised protocol allows syntax/module-reader the possibility of handling future language-information queries automatically.

top ← prev up next →