The runes interface in Closure arose from the need for Unicode characters and strings, while not having a Lisp implementation available that offers those characters. The runes API offers an interface very similar to the character and string interface in standard Common Lisp.
There are two implementations:
This is for Unicode-aware Lisp implementations; rune is a synonym for character and rod is a synonym for string.
This is for environments that are not Unicode-aware. runes really are (unsigned-byte 16). And rods are specialized vectors of those runes.
Note that in any of these models, a rod is vector of rune objects. So that you can use all the standard Common Lisp sequence functions on rod objects; further it is guaranteed that eql works on rune objects.
Additionally there are two reader macros. #/… to read runes and #"…" to read rods.
Although most Common Lisp implementations these days have Unicode support, using runes is still a good idea in applications or libraries that aim to be highly portable amoung different implementations. For one thing you get Unicode support for the occasional non-Unicode aware implementation; For the other thing you can be sure, that certain things remain constant. Like the input syntax — is the ASCII Formfeed character called #\Page or #\Formfeed? Or: What code point is used to represent the end of a line? Additionally behavior of string-upcase and friends can vary a lot.
Runes are like characters. However different from Common Lisp, we specify that a rune is a single Unicode code point. And: For every Unicode code point there is a rune.
Implementation Note — In the current implementation a rune might be represented as an (unsigned-byte 16); this is a historical accident, as at the time of writing, the original author was not aware that there will be Unicode code points beyond 216.
Depending on the model choosen, a rune might be either be represented as an unsigned-byte, a character or some otherwise opaque structure.
Returns the rune which identifies the Unicode code point code.
Returns the code point that rune identifies.
Returns the rune that corresponds to the Common Lisp character char.
Returns the a Common Lisp character that corresponds to the rune rune. If the particular rune is not representable as a character in the implementation at hand, default is returned. If, in this case, default is nil, an error is signaled.
Rune to use as a replacement in rune-char and rod-string for runes not representable as characters. If nil, an error is signalled instead.
Returns true if object is a rune. Note that unless the rune-is-structure model is selected, we can't tell runes apart from either characters or integers, depending on the model choosen.
Returns true, if the rune rune is a white space. White space defined as either ASCII Space, Linefeed, Carrige Return, or Tabulator. (Code points decimal 32, 10, 13, and 9).
If rune is a digit according to the base radix, the weight of the digit is returned; otherwise nil is returned. radix should be an integer in the range [2; 36].
Only arabic digits and latin letters are ever considered to be digits.
Returns true, if rune1 and rune2 differ only by case.
Rods are vectors of runes. We specifically opted for not further warp rods into some structure say, for the benefit that the whole bunch of Common Lisp sequence functions work on rods.
This type refers to a vector of runes. Depending on the implementation model choosen, it is the appropriate subtype of vector.
This type refers to a simple vector of runes. Depending on the implementation model choosen, it is the appropriate subtype of simple-vector.
Returns a freshly allocated rod of length size. The initial content of the rod returned is unspecified.
Returns true, if object looks like a rod.
Returns the indexth rune from rod. It is an error if index is not a positive integer less than the length of rod.
Modifies the index'th rune of rod to become new-value. It is an error of index is not a positive integer less than the length of rod. It also is an error if new-value is not a rune.
Like the rune accessor, but rod is assumed to be simple-rod and index is assumed to be a legitimate index. This is a low safety variant for speed — use with care.
Returns a freshly allocated rod, that contains in sequence, all the runes in rod, indexed by the range from start to end (exclusively). end defaults to the length of rod.
Returns true, if rod1 and rod2 represent the same sequence of runes.
Returns true, if the sequences of runes are rune-equal. That is rod1 and rod2 are compared to each other while ignoring the case of the runes.
Note, that unlike string-upcase and string-downcase we do not make the promise that the length of a case converted string is the same as the original string.
Converts the rune rune to downcase. If the rune has no case or no down case equivalent is available the original rune is returned.
Returns the upcase equivalent of rune. If there the rune has no case or has no upcase equivalent the original rune is returned.
Converts each rune from rod to downcase and returns the resulting rod. Note that the result can have a length different from the input argument.
Converts each rune from rod to upcase and returns the resulting rod. Note that the result can have a length different from the input argument.
There are some convenience functions provided to convert from vanilla Common Lisp characters and strings to rune and rod objects.
Turns the rod rod into a Common Lisp string. default-char is as for rune-char.
Converts the Common Lisp string string into a rod.
This syntax is used to read a rune. It is similar to the Common Lisp #\… syntax.
rune with the code nnnn hexadecimal
The following semi-standard rune names are defined:
The following ASCII runes are defined:
start of header
start of text
end of text
end of transmission
data link escape
device control 1
device control 2
device control 3
device control 4
end of transmission block
end of medium
Additional control characters:
non breakable space
The printed representation of a rod is #" the runes and then another ". A double quote character is escaped by "\".