• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2002 Dave Abrahams
2# Copyright 2002, 2003 Rene Rivera
3# Distributed under the Boost Software License, Version 1.0.
4# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
5
6import regex ;
7
8
9# Characters considered whitespace, as a list.
10.whitespace-chars = " " "	" "
11" ;
12
13# Characters considered whitespace, as a single string.
14.whitespace = $(.whitespace-chars:J="") ;
15
16
17# Returns the canonical set of whitespace characters, as a list.
18#
19rule whitespace-chars ( )
20{
21    return $(.whitespace-chars) ;
22}
23
24
25# Returns the canonical set of whitespace characters, as a single string.
26#
27rule whitespace ( )
28{
29    return $(.whitespace) ;
30}
31
32
33# Splits the given string into a list of strings composed of each character of
34# the string in sequence.
35#
36rule chars (
37    string  # The string to split.
38    )
39{
40    local result ;
41    while $(string)
42    {
43        local s = [ MATCH (.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.*) : $(string) ] ;
44        string = $(s[9]) ;
45        result += $(s[1-8]) ;
46    }
47
48    # Trim off empty strings.
49    while $(result[1]) && ! $(result[-1])
50    {
51        result = $(result[1--2]) ;
52    }
53
54    return $(result) ;
55}
56
57
58# Apply a set of standard transformations to string to produce an abbreviation
59# no more than 5 characters long.
60#
61rule abbreviate ( string )
62{
63    local r = $(.abbreviated-$(string)) ;
64    if $(r)
65    {
66        return $(r) ;
67    }
68    # Anything less than 4 characters gets no abbreviation.
69    else if ! [ MATCH (....) : $(string) ]
70    {
71        .abbreviated-$(string) = $(string) ;
72        return $(string) ;
73    }
74    else
75    {
76        # Separate the initial letter in case it's a vowel.
77        local s1 = [ MATCH ^(.)(.*) : $(string) ] ;
78
79        # Drop trailing "ing".
80        local s2 = [ MATCH ^(.*)ing$ : $(s1[2]) ] ;
81        s2 ?= $(s1[2]) ;
82
83        # Reduce all doubled characters to one.
84        local last = "" ;
85        for local c in [ chars $(s2) ]
86        {
87            if $(c) != $(last)
88            {
89                r += $(c) ;
90                last = $(c) ;
91            }
92        }
93        s2 = $(r:J="") ;
94
95        # Chop all vowels out of the remainder.
96        s2 = [ regex.replace $(s2) "[AEIOUaeiou]" "" ] ;
97
98        # Shorten remaining consonants to 4 characters.
99        s2 = [ MATCH ^(.?.?.?.?) : $(s2) ] ;
100
101        # Glue the initial character back on to the front.
102        s2 = $(s1[1])$(s2) ;
103
104        .abbreviated-$(string) = $(s2) ;
105        return $(s2) ;
106    }
107}
108
109
110# Concatenates the given strings, inserting the given separator between each
111# string.
112#
113rule join (
114    strings *  # The strings to join.
115    : separator ?  # The optional separator.
116    )
117{
118    separator ?= "" ;
119    return $(strings:J=$(separator)) ;
120}
121
122
123# Split a string into whitespace separated words.
124#
125rule words (
126    string  # The string to split.
127    : whitespace *  # Optional, characters to consider as whitespace.
128    )
129{
130    whitespace = $(whitespace:J="") ;
131    whitespace ?= $(.whitespace) ;
132    local w = ;
133    while $(string)
134    {
135        string = [ MATCH "^[$(whitespace)]*([^$(whitespace)]*)(.*)" : $(string) ] ;
136        if $(string[1]) && $(string[1]) != ""
137        {
138            w += $(string[1]) ;
139        }
140        string = $(string[2]) ;
141    }
142    return $(w) ;
143}
144
145
146# Check that the given string is composed entirely of whitespace.
147#
148rule is-whitespace (
149    string ?  # The string to test.
150    )
151{
152    if ! $(string) { return true ; }
153    else if $(string) = "" { return true ; }
154    else if [ MATCH "^([$(.whitespace)]+)$" : $(string) ] { return true ; }
155    else { return ; }
156}
157
158rule __test__ ( )
159{
160    import assert ;
161    assert.result a b c : chars abc ;
162
163    assert.result rntm : abbreviate runtime ;
164    assert.result ovrld : abbreviate overload ;
165    assert.result dbg : abbreviate debugging ;
166    assert.result async : abbreviate asynchronous ;
167    assert.result pop : abbreviate pop ;
168    assert.result aaa : abbreviate aaa ;
169    assert.result qck : abbreviate quack ;
170    assert.result sttc : abbreviate static ;
171
172    # Check boundary cases.
173    assert.result a : chars a ;
174    assert.result : chars "" ;
175    assert.result a b c d e f g h : chars abcdefgh ;
176    assert.result a b c d e f g h i : chars abcdefghi ;
177    assert.result a b c d e f g h i j : chars abcdefghij ;
178    assert.result a b c d e f g h i j k : chars abcdefghijk ;
179
180    assert.result a//b/c/d : join a "" b c d : / ;
181    assert.result abcd : join  a "" b c d ;
182
183    assert.result a b c : words "a b	c" ;
184
185    assert.true is-whitespace "     	" ;
186    assert.false is-whitespace "  a b c	" ;
187    assert.true is-whitespace "" ;
188    assert.true is-whitespace ;
189}
190