Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/tools/build/v2/util/print.jam @ 45

Last change on this file since 45 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 11.8 KB
Line 
1# Copyright 2003 Douglas Gregor
2# Copyright 2002, 2003, 2005 Rene Rivera
3# Copyright 2002, 2003, 2004, 2005 Vladimir Prus
4# Distributed under the Boost Software License, Version 1.0.
5# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
6
7# Utilities for generating format independent output. Using these
8# will help in generation of documentation in at minimum plain/console
9# and html.
10
11import modules ;
12import numbers ;
13import string ;
14import regex ;
15
16# The current output target. Defaults to console.
17output-target = console ;
18
19# The current output type. Defaults to plain.
20output-type = plain ;
21
22# Whitespace.
23.whitespace = [ string.whitespace ] ;
24
25# Set the target and type of output to generate. This sets both
26# the destination output and the type of docs to generate to that
27# output. The target can be either a file or "console" for echoing
28# to the console. If the type of output is not specified it defaults
29# to plain text.
30#
31rule output (
32    target # The target file or device; file or "console".
33    type ? # The type of output; "plain", or "html".
34    )
35{
36    type ?= plain ;
37    if $(output-target) != $(target)
38    {
39        output-target = $(target) ;
40        output-type = $(type) ;
41        if $(output-type) = html
42        {
43            text
44                "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"
45                "<html>"
46                "<head>"
47                "</head>"
48                "<body link=\"#0000ff\" vlink=\"#800080\">"
49                : true
50                : prefix ;
51            text
52                "</body>"
53                "</html>"
54                :
55                : suffix ;
56        }
57    }
58}
59
60# Generate a section with a description. The type of output can be
61# controlled by the value of the 'output-type' variable. If not set
62# it defaults to 'console' indicating immediate display to the console.
63# Other possible values are: 'html-file'.
64#
65rule section (
66    name # The name of the section.
67    description * # A number of description lines.
68    )
69{
70    if $(output-type) = plain
71    {
72        lines [ split-at-words $(name): ] ;
73        lines ;
74    }
75    else if $(output-type) = html
76    {
77        name = [ escape-html $(name) ] ;
78        text <h3>$(name)</h3> <p> ;
79    }
80    local pre = ;
81    while $(description)
82    {
83        local paragraph = ;
84        while $(description) && [ string.is-whitespace $(description[1]) ] { description = $(description[2-]) ; }
85        if $(pre)
86        {
87            while $(description) && (
88                $(pre) = " $(description[1])" ||
89                ( $(pre) < [ string.chars [ MATCH "^([$(.whitespace)]*)" : " $(description[1])" ] ] )
90                )
91                { paragraph += $(description[1]) ; description = $(description[2-]) ; }
92            while [ string.is-whitespace $(paragraph[-1]) ] { paragraph = $(paragraph[1--2]) ; }
93            pre = ;
94            if $(output-type) = plain
95            {
96                lines $(paragraph) "" : "  " "  " ;
97            }
98            else if $(output-type) = html
99            {
100                text <blockquote> ;
101                lines $(paragraph) ;
102                text </blockquote> ;
103            }
104        }
105        else
106        {
107            while $(description) && ! [ string.is-whitespace $(description[1]) ]
108                { paragraph += $(description[1]) ; description = $(description[2-]) ; }
109            if $(paragraph[1]) = :: && ! $(paragraph[2])
110            {
111                pre = " " ;
112            }
113            if $(paragraph[1]) = ::
114            {
115                if $(output-type) = plain
116                {
117                    lines $(paragraph[2-]) "" : "  " "  " ;
118                    lines ;
119                }
120                else if $(output-type) = html
121                {
122                    text <blockquote> ;
123                    lines $(paragraph[2-]) ;
124                    text </blockquote> ;
125                }
126            }
127            else
128            {
129                local p = [ MATCH "(.*)(::)$" : $(paragraph[-1]) ] ;
130                local pws = [ MATCH "([         ]*)$" : $(p[1]) ] ;
131                p = [ MATCH "(.*)($(pws))($(p[2]))$" :  $(paragraph[-1]) ] ;
132                if $(p[3]) = ::
133                {
134                    pre = [ string.chars [ MATCH "^([$(.whitespace)]*)" : " $(p[1])" ] ] ;
135                    if ! $(p[2]) || $(p[2]) = "" { paragraph = $(paragraph[1--2]) $(p[1]): ; }
136                    else { paragraph = $(paragraph[1--2]) $(p[1]) ; }
137                    if $(output-type) = plain
138                    {
139                        lines [ split-at-words " " $(paragraph) ] : "  " "  " ;
140                        lines ;
141                    }
142                    else if $(output-type) = html
143                    {
144                        text </p> <p> [ escape-html $(paragraph) ] ;
145                    }
146                }
147                else
148                {
149                    if $(output-type) = plain
150                    {
151                        lines [ split-at-words " " $(paragraph) ] : "  " "  " ;
152                        lines ;
153                    }
154                    else if $(output-type) = html
155                    {
156                        text </p> <p> [ escape-html $(paragraph) ] ;
157                    }
158                }
159            }
160        }
161    }
162    if $(output-type) = html
163    {
164        text </p> ;
165    }
166}
167
168# Generate the start of a list of items. The type of output can be
169# controlled by the value of the 'output-type' variable. If not set
170# it defaults to 'console' indicating immediate display to the console.
171# Other possible values are: 'html-file'.
172#
173rule list-start ( )
174{
175    if $(output-type) = plain
176    {
177    }
178    else if $(output-type) = html
179    {
180        text <ul> ;
181    }
182}
183
184# Generate an item in a list. The type of output can be
185# controlled by the value of the 'output-type' variable. If not set
186# it defaults to 'console' indicating immediate display to the console.
187# Other possible values are: 'html-file'.
188#
189rule list-item (
190    item + # The item to list.
191    )
192{
193    if $(output-type) = plain
194    {
195        lines [ split-at-words "*" $(item) ] : "    " "  " ;
196    }
197    else if $(output-type) = html
198    {
199        text <li> [ escape-html $(item) ] </li> ;
200    }
201}
202
203# Generate the end of a list of items. The type of output can be
204# controlled by the value of the 'output-type' variable. If not set
205# it defaults to 'console' indicating immediate display to the console.
206# Other possible values are: 'html-file'.
207#
208rule list-end ( )
209{
210    if $(output-type) = plain
211    {
212        lines ;
213    }
214    else if $(output-type) = html
215    {
216        text </ul> ;
217    }
218}
219
220# Split the given text into separate lines, word-wrapping to a margin.
221# The default margin is 78 characters.
222#
223rule split-at-words (
224    text + # The text to split.
225    : margin ? # An optional margin, default is 78.
226    )
227{
228    local lines = ;
229    text = [ string.words $(text:J=" ") ] ;
230    text = $(text:J=" ") ;
231    margin ?= 78 ;
232    local char-match-1 = ".?" ;
233    local char-match = "" ;
234    while $(margin) != 0
235    {
236        char-match = $(char-match)$(char-match-1) ;
237        margin = [ numbers.decrement $(margin) ] ;
238    }
239    while $(text)
240    {
241        local s = "" ;
242        local t = "" ;
243        # divide s into the first X characters and the rest
244        s = [ MATCH "^($(char-match))(.*)" : $(text) ] ;
245       
246        if $(s[2])
247        {
248            # split the first half at a space
249            t = [ MATCH "^(.*)[\\ ]([^\\ ]*)$" : $(s[1]) ] ;
250        }
251        else
252        {
253            t = $(s) ;
254        }
255       
256        if ! $(t[2])
257        {
258            t += "" ;
259        }
260       
261        text = $(t[2])$(s[2]) ;
262        lines += $(t[1]) ;
263    }
264    return $(lines) ;
265}
266
267# Generate a set of fixed lines. Each single item passed in is
268# output on a separate line. For console this just echos each line,
269# but for html this will split them with <br>.
270#
271rule lines (
272    text * # The lines of text.
273    : indent ? # Optional indentation prepended to each line after the first one.
274    outdent ? # Optional indentation to prepend to the first line.
275    )
276{
277    text ?= "" ;
278    indent ?= "" ;
279    outdent ?= "" ;
280    if $(output-type) = plain
281    {
282        text $(outdent)$(text[1]) $(indent)$(text[2-]) ;
283    }
284    else if $(output-type) = html
285    {
286        local indent-chars = [ string.chars $(indent) ] ;
287        indent = "" ;
288        for local c in $(indent-chars)
289        {
290            if $(c) = " " { c = &nbsp; ; }
291            else if $(c) = "    " { c = &nbsp;&nbsp;&nbsp;&nbsp; ; }
292            indent = $(indent)$(c) ;
293        }
294        local html-text = [ escape-html $(text) : &nbsp; ] ;
295        text $(html-text[1])<br> $(indent)$(html-text[2-])<br> ;
296    }
297}
298
299# Output text directly to the current target. When doing output
300# to a file, one can indicate if the text should be output to
301# "prefix" it, as the "body" (default), or "suffix" of the file. This is
302# independant of the actual execution order of the text rule. This rule
303# invokes a singular action, one action only once, which does the
304# build of the file. Therefore actions on the target outside of this
305# rule will happen entirely before and/or after all output using this rule.
306#
307rule text (
308    strings * # The strings of text to output.
309    : overwrite ? # true to overwrite the output (if it is a file)
310    : prefix-body-suffix ? # Indication to output prefix, body, or suffix (for a file).
311    )
312{
313    prefix-body-suffix ?= body ;
314    if $(output-target) = console
315    {
316        if ! $(strings)
317        {
318            ECHO ;
319        }
320        else
321        {
322            for local s in $(strings)
323            {
324                ECHO $(s) ;
325            }
326        }
327    }
328    if ! $($(output-target).did-action)
329    {
330        $(output-target).did-action = yes ;
331        $(output-target).text-prefix = ;
332        $(output-target).text-body = ;
333        $(output-target).text-suffix = ;
334       
335        nl on $(output-target) = "
336" ;
337        text-redirect on $(output-target) = ">>" ;
338        if $(overwrite)
339        {
340            text-redirect on $(output-target) = ">" ;
341        }
342        text-content on $(output-target) = ;
343       
344        text-action $(output-target) ;
345    }
346    $(output-target).text-$(prefix-body-suffix) += $(strings) ;
347    text-content on $(output-target) =
348        $($(output-target).text-prefix)
349        $($(output-target).text-body)
350        $($(output-target).text-suffix) ;
351}
352
353# Outputs the text to the current targets, after word-wrapping it.
354rule wrapped-text ( text + )
355{
356    local lines = [ split-at-words $(text) ] ;
357    text $(lines) ;
358}
359
360# Escapes text into html/xml printable equivalents.
361# Does not know about tags and therefore tags fed into
362# this will also be escaped. Currently escapes space, "<", ">", and "&".
363#
364rule escape-html (
365    text + # The text to escape.
366    : space ? # What to replace spaces with, defaults to " ".
367    )
368{
369    local html-text = ;
370    while $(text)
371    {
372        local html = $(text[1]) ;
373        text = $(text[2-]) ;
374        html = [ regex.replace $(html) "&" "&amp;" ] ;
375        html = [ regex.replace $(html) "<" "&lt;" ] ;
376        html = [ regex.replace $(html) ">" "&gt;" ] ;
377        if $(space)
378        {
379            html = [ regex.replace $(html) " " "$(space)" ] ;
380        }
381        html-text += $(html) ;
382    }
383    return $(html-text) ;
384}
385
386# Outputs the text strings collected by the text rule to the output
387# file.
388#
389actions quietly text-action
390{
391    @($(STDOUT):E=$(text-content:J=$(nl))) $(text-redirect) "$(<)"
392}
393
394local rule __test__ ( )
395{
396    import assert ;
397   
398    assert.result one two three : split-at-words one two three : 5 ;
399    assert.result "one two" three : split-at-words one two three : 8 ;
400    assert.result "one two" three : split-at-words one two three : 9 ;
401    assert.result "one two three" : split-at-words one two three ;
402    # VP, 2004-12-03 The following test fails for some reason,
403    # so commenting it out.
404    #assert.result "one&nbsp;two&nbsp;three" "&amp;&lt;&gt;" :
405    #    escape-html "one two three" "&<>" ;
406}
Note: See TracBrowser for help on using the repository browser.