Contents:

1. Introduction

This is a collection of useful REBOL scripts and modules. The goal of this project is to increase sharing across the REBOL community, and to reduce the need of reinventing the wheel for each developer.

2. License

A message from Qtask about this source code:

We have selected the MIT license (as of 2010-Jan-1) because it is the closest “standard” license to our intent. If we had our way, we would declare this source as public domain, with absolutely no strings attached, not even the string that says you have to have strings. We want to help people, so please feel free to contact us at API@Qtask.com if you have questions.

(you only need to include the standard license text below in your homage to this source code)

Copyright 2010 Qtask, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

3. Development

Please visit our page on SourceForge.

The list of available scripts and modules follows.

4. Dialects

This directory contains a collection of useful dialects.

4.1 Dialected EMIT function

It is common in REBOL to create dialects that generate some output (for e.g. HTML, or PDF, and so on). This program defines a function that generalizes this concept into a "emit dialect" that can be easily extended with "macros".

Download script | Read documentation

4.2 Finite State Machine interpreter

This script implements an interpreter for stack-based finite state machines. A FSM is defined by a simple dialect where each state is a REBOL block. The interpreter will process events and change state according to the dialect. It can be used in a wide range of cases where stateful processing of asynchronous events is desired.

Download script | Read documentation

4.3 Macros to emit [X][HT]ML

Generating XML, XHTML etc. is a very common task; this module defines emit macros to generate ML code.

Download script | Read documentation

5. Mezzanine functions

This directory contains a collection of useful mezzanine functions.

5.1 Command line arguments handling

Command line argument parsing is a basic component of all command line tools. This module simplifies the creation of such tools.

Download script | Read documentation

5.2 COLLECT function

A very common idiom in REBOL is:

func [block /local result] [
 result: copy [ ]
 foreach val block [
  append result do-something-with val
 ]
 result
]

which the collect function turns into:

func [block] [
 collect [
  foreach val block [
   keep do-something-with val
  ]
 ]
]

Download script | Read documentation

5.3 Macro expansion

Introduction to be written.

Download script | Read documentation

5.4 Extended version of FUNC

Introduction to be written.

Download script | Read documentation

5.5 HTML Filter

It is often desirable, for certain kinds of web sites (wikis, forums, blogs, and so on), to allow advanced users to customize any text input using HTML tags; in some cases, where the site allows users to publish new pages or edit existing content, allowing users to edit the HTML directly is even more desirable. However, if you can't trust the users, allowing HTML means opening up to a number of vulnerabilities (especially cross-site scripting, phishing, etc.); the solution to the problem is to "sanitize" any HTML text coming from an untrusted source before embedding it in the final web page. If all potentially harmful content is removed, it is possible to safely embed the HTML into any page.

Download script | Read documentation

5.6 FORM-ERROR function

Introduction to be written.

Download script | Read documentation

5.7 HTML to plain text converter

This module defines a function, html-to-text, that can convert a HTML string into just plain text. Currently the conversion is rather simple, but it is easy to improve it.

Download script | Read documentation

5.8 IMAP access functions

This module defines a number of functions that can be used to access mail on a IMAP server.

It is designed to be easily used through Hardball.

Download script | Read documentation

5.9 Common code for "daemons" on Linux

This module contains all the common code for "daemon" programs (eg. servers etc.) to be run on the Linux operating system. (All this is very likely to work on all Unix systems, though it has been tested on Linux only.)

Download script | Read documentation

5.10 Parse HTML text into a tree

This module is a complete HTML parser, supporting HTML 3.2 to 4.1 and XHTML 1.0.

Download script | Read documentation

5.11 Logging functions

Logging text messages to standard output, a file, or the system log (on Unix).

Download script | Read documentation

5.12 EMail related functions

Introduction to be written.

Download script | Read documentation

5.13 Functions to send and receive encrypted message packets

This module defines a set of functions to send and receive encrypted message packets. They are used as the basis of the Hardball protocol, and are defined separately to ease testing and to allow reuse in other similar REBOL based protocols.

Download script | Read documentation

5.14 Modules for REBOL 2

In a larger project with many people contributing to the code, it is useful to provide mechanisms to better isolate parts of the code from each other, so that mistakes, typos, etc. in some part will have a smaller chance of affecting the other parts. For this reason, we define here a module function that creates an "isolated" piece of code, that only interacts with the rest of the system according to the provided specification.

Download script | Read documentation

5.15 Grow trees using constraints

A "niwashi" is a state machine you can use to "grow" a tree data structure while maintaining a set of constraints. ("Niwashi" is the Japanese word for "gardener"; we want to make a "tree" "grow" in a specified, constrained way, sort of like you would do with a bonsai.)

In the simplest case, this can be used to create a tree from a simple sequence of commands; for example, while parsing something like XML: the niwashi will keep track of the state for you, so you only have to send commands much like "open tag" and "close tag".

But, a niwashi also allows you to define rules that apply while the tree is being built. This is an alternative to creating a tree, and then applying tree rewriting rules to transform it; the tree is instead transformed while it is being built. For example, this is very useful while parsing something like HTML, where the source is not necessarily properly formed, and where you want to apply some transformations to the HTML as well. This is much more efficient as it all happens in one pass.

Download script | Read documentation

5.16 HTML Normalizer

This module is deprecated. Please use load-html instead.

Download script | Read documentation

5.17 The PIPE function

A powerful feature of Unix systems is the ability to "connect together" commands so that the output of one becomes the input of another; this is called "piping" because it's like connecting the output of a command to the input of another command using a "pipe". We introduce the same concept in REBOL: the ability to connect a port to another port with a "pipe", using the pipe function. This function will read all the data in the first port, and write it to the second port. A number of options make it flexible, allowing users to do what they want without knowing the details of how ports work.

Download script | Read documentation

5.18 REBOL functions profiler

Performance optimization is an important part of software engineering. This module defines tools that can be used to profile function performance in REBOL applications.

Download script | Read documentation

5.19 "Random" 160-bit number sequences

This program implements a "Pseudo-Random Number Generator". All generated numbers are 160 bits long; it also allows for having more than one "sequence" going on at the same time (eg. with different seeds).

Download script | Read documentation

5.20 Test trace

Automated testing is very simple when you have simple functions, and you can just call them in your tests and check the result. If the result is not the one expected, you know you have a problem.

However, how do you do something like this for a network server (for example)? It's not like the server will "return a result" that you can check, most of the times.

Here I'm proposing a simple solution to this kind of problems. You "instrument" the server to produce, while testing, a "test trace". Then, you can treat the test trace as the "result" of running the server in that specific test.

Download script | Read documentation

5.21 Text encoding and decoding functions

This program defines two functions to encode and decode UTF-8 text to and from various other charsets and encodings.

Download script | Read documentation

5.22 Simple plain text to HTML converter

When showing a plain text document (e.g. an email message) inside a HTML page, it is very often desirable to make links clickable, and do other adjustments. This program provides a function to do just that.

Download script | Read documentation

5.23 Functions for handling trees

A tree is a very common data structure that can be used in many ways by many different algorithms. This module defines a set of functions to create and modify trees. A tree is composed of nodes; each node has a type, some properties, a parent node (unless it's the root of the three), and zero or more child nodes.

Download script | Read documentation

5.24 Stub code for "daemons" on Windows

This module contains all the common code for "daemon" programs (eg. servers etc.) to be run on the Linux operating system. (All this is very likely to work on all Unix systems, though it has been tested on Linux only.)

Download script | Read documentation

6. Macros (for use with EXPAND-MACROS)

This directory contains a collection of macros that can be used with the EXPAND-MACROS function.

6.1 Macros for handling trees

The trees module is very handy and user friendly, but it is a bit slow. The macros contained in this module provide targeted optimizations that can considerably speed up any code using trees.

Download script | Read documentation

7. Parsers

This directory contains a collection of parsers for common formats, such as HTML and XML and so on.

7.1 Common PARSE rules

This file just collects a number of charsets and parse rules that are commonly used in other modules.

Download script | Read documentation

7.2 (Simple) CSS Parser

This module defines functions to handle simple CSS strings such as the ones found inside a HTML tag's style attribute. It is not yet capable of parsing an actual style sheet.

Download script | Read documentation

7.3 HTTP Requests parser and Response generator

This is a simple incremental parser for HTTP requests which can be used to implement simple HTTP servers.

Download script | Read documentation

7.4 IMAP Parser

This has been taken out of the imapcommands:// scheme to ease testing and allow reuse.

Download script | Read documentation

7.5 [X][HT]ML Parser

Parsing XML, XHTML and HTML (as well as other variants) has increasingly become one of the most common tasks in programming. We present here a simple but robust "ML" parser; since this is fairly low level and rather permissive with the input, it can be used in a very wide range of situations.

Download script | Read documentation

7.6 Arguments for PARSE rules

Despite the huge power of the parse function, and the ability to define rules that can be reused inside other rules (they are just blocks), there is a lack of generic, reusable rules that solve very common problems. The main reason for this is the inability of passing parameters to rules, which means that only the most simple rules can really be made reusable across different "callers". This module proposes a possible solution.

Download script | Read documentation

7.7 A standards-compliant URI parser

URL parsing code in REBOL 2, despite being quite good for the job it needs to do, has a number of problems and limitations:

Also, REBOL 2 does not provide any tools for handling URIs, such as URI normalization, comparison, relative URI resolution and so on. I propose to improve the current code for use in REBOL 3.

Design flaw in url! load'ing

REBOL 2 has a design flaw in the way url! values are load'ed and mold'ed. load will decode all percent-encoded characters, while mold re-encodes only characters with an ASCII code less than 33. This is incorrect, and it makes it impossible to use URLs in some cases (the common example being a user name which contains a @ character). The standard states that "the components and subcomponents significant to the scheme-specific dereferencing process (if any) must be parsed and separated before the percent-encoded octets within those components can be safely decoded", with the exception of "percent-encoded octets corresponding to characters in the unreserved set, which can be decoded at any time".

I propose that REBOL 3 should follow the rules in the standard specification.

Download script | Read documentation

8. Port schemes

This directory contains a collection of useful port schemes implementations (handlers).

8.1 Chain port scheme for REBOL

This port scheme allows creating a "filter" port that is the combination of other "filter" ports. Data inserted to the chain port will be passed through all the ports in the chain in the order they are specified. This way you can do things like combine encryption with enbasing, or debasing and decryption, and have it work as a single port.

This port scheme is the ideal complement to the pipe function, because with it you can filter your data using a combination of different ports.

Download script | Read documentation

8.2 Filter port scheme for REBOL

This port scheme allows creating a "filter" port that applies a function to a data stream. The function should accept binary! or string! as input and return binary! or string! as output. (We recommend always using this port in /binary mode.) You can control the size of the data chunks that your function will be called on.

Download script | Read documentation

8.3 Hardball

Hardball is Rugby's successor. It is a simple RPC broker for REBOL that allows importing a "remote" module and using it just like it was local.

For example, if you have %my-module.r that you are importing in your program, like:

module [
 Imports: [%my-module.r]
] [
 do-something
]

but you want to move it to a separate process, perhaps on a remote computer, you just need to change that to:

module [
 Imports: [hardball://somehost/my-module.r]
] [
 do-something
]

Provided you're running:

serve-modules %my-module.r

on "somehost".

Download script | Read documentation

8.4 Better HTTP

In REBOL, a scheme is a set of definitions and functions that handle the operations of a kind of port. This scheme handles HTTP ports, allowing access to resources served via HTTP. Version 1.1 of the HTTP protocol is supported (although some features are not yet implemented at this point).

Download script | Read documentation

8.5 imapcommands:// protocol handler

REBOL's imap:// protocol handler is too limited for the purpose of writing a complete IMAP client. For this reason, imapcommands:// was created, that allows a lower level, but more complete, access to IMAP servers.

Download script | Read documentation

8.6 "Tee" port scheme for REBOL

This port scheme allows creating a "filter" port that works like a "tee"; that is, it lets data pass through it, but it also copies it into another port. This basically allows creating a "bifurcation", often called a "tee" (because of the shape of the letter T). This is very useful in combination with the chain:// scheme or the pipe function, as it allows creating complex filtering graphs for your data stream.

Download script | Read documentation