2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-17 01:32:12 +00:00
Files
build/v2/util/print.jam
Douglas Gregor 4177e8e5cc print.jam: Provide escaped strings for Windows and Unix
regex.jam: Provide "escape" routine that escapes a string with certain escape
  characters

boostbook.jam: Use print.escape to properly escape argument to "echo" on
  Windows and Unix (BoostBook now works on non-Cygwin Windows)


[SVN r18148]
2003-04-01 14:34:31 +00:00

311 lines
8.6 KiB
Plaintext

# Copyright (C) 2002-2003, Rene Rivera. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears in
# all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
# Utilities for generating format independent output. Using these
# will help in generation of documentation in at minimum plain/console
# and html.
import modules ;
import numbers ;
import string ;
import regex ;
# The current output target. Defaults to console.
output-target = console ;
# The current output type. Defaults to plain.
output-type = plain ;
# Set the target and type of output to generate. This sets both
# the destination output and the type of docs to generate to that
# output. The target can be either a file or "console" for echoing
# to the console. If the type of output is not specified it defaults
# to plain text.
#
rule output (
target # The target file or device; file or "console".
type ? # The type of output; "plain", or "html".
)
{
type ?= plain ;
output-target = $(target) ;
output-type = $(type) ;
}
# Generate a section with a description. The type of output can be
# controlled by the value of the 'output-type' variable. If not set
# it defaults to 'console' indicating immediate display to the console.
# Other possible values are: 'html-file'.
#
rule section (
name # The name of the section.
description * # A number of description lines.
)
{
if $(output-type) = plain
{
lines [ split-at-words $(name): ] ;
lines ;
local pre = ;
while $(description)
{
local paragraph = ;
while $(description) && $(description[1]) = "" { description = $(description[2-]) ; }
if $(pre)
{
pre = ;
while $(description) && ( $(description[1]) = "" || [ MATCH "^([ ])" : $(description[1]) ] )
{ paragraph += $(description[1]) ; description = $(description[2-]) ; }
lines $(paragraph) : " " " " ;
}
else
{
while $(description) && $(description[1]) != ""
{ paragraph += $(description[1]) ; description = $(description[2-]) ; }
if $(paragraph[1]) = :: && ! $(paragraph[2])
{
pre = yes ;
}
if $(paragraph[1]) = ::
{
lines $(paragraph[2-]) : " " " " ;
lines ;
}
else
{
local p = [ MATCH "(.*)(::)$" : $(paragraph[-1]) ] ;
local pws = [ MATCH "([ ]*)$" : $(p[1]) ] ;
p = [ MATCH "(.*)($(pws))($(p[2]))$" : $(paragraph[-1]) ] ;
if $(p[3]) = ::
{
pre = yes ;
if ! $(p[2]) || $(p[2]) = "" { paragraph = $(paragraph[1--2]) $(p[1]): ; }
else { paragraph = $(paragraph[1--2]) $(p[1]) ; }
lines [ split-at-words " " $(paragraph) ] : " " " " ;
lines ;
}
else
{
lines [ split-at-words " " $(paragraph) ] : " " " " ;
lines ;
}
}
}
}
}
}
# Generate the start of a list of items. The type of output can be
# controlled by the value of the 'output-type' variable. If not set
# it defaults to 'console' indicating immediate display to the console.
# Other possible values are: 'html-file'.
#
rule list-start ( )
{
if $(output-type) = plain
{
}
}
# Generate an item in a list. The type of output can be
# controlled by the value of the 'output-type' variable. If not set
# it defaults to 'console' indicating immediate display to the console.
# Other possible values are: 'html-file'.
#
rule list-item (
item + # The item to list.
)
{
if $(output-type) = plain
{
lines [ split-at-words "*" $(item) ] : " " ;
}
}
# Generate the end of a list of items. The type of output can be
# controlled by the value of the 'output-type' variable. If not set
# it defaults to 'console' indicating immediate display to the console.
# Other possible values are: 'html-file'.
#
rule list-end ( )
{
if $(output-type) = plain
{
lines ;
}
}
# Split the given text into separate lines, word-wrapping to a margin.
# The default margin is 78 characters.
#
rule split-at-words (
text + # The text to split.
: margin ? # An optional margin, default is 78.
)
{
local lines = ;
text = [ string.words $(text:J=" ") ] ;
text = $(text:J=" ") ;
margin ?= 78 ;
local char-match-1 = ".?" ;
local char-match = "" ;
while $(margin) != 0
{
char-match = $(char-match)$(char-match-1) ;
margin = [ numbers.decrement $(margin) ] ;
}
while $(text)
{
local s = "" ;
local t = "" ;
# divide s into the first X characters and the rest
s = [ MATCH "^($(char-match))(.*)" : $(text) ] ;
if $(s[2])
{
# split the first half at a space
t = [ MATCH "^(.*)[\\ ]([^\\ ]*)$" : $(s[1]) ] ;
}
else
{
t = $(s) ;
}
if ! $(t[2])
{
t += "" ;
}
text = $(t[2])$(s[2]) ;
lines += $(t[1]) ;
}
return $(lines) ;
}
# Generate a set of fixed lines. Each single item passed in is
# output on a separate line. For console this just echos each line,
# but for html this will split them with <br>.
#
rule lines (
text * # The lines of text.
: indent ? # Optional indentation prepended to each line after the first one.
outdent ? # Optional indentation to prepend to the first line.
)
{
text ?= "" ;
indent ?= "" ;
outdent ?= "" ;
if $(output-type) = plain
{
text $(outdent)$(text[1]) $(indent)$(text[2-]) ;
}
else if $(output-type) = html
{
local indent-chars = [ string.chars $(indent) ] ;
indent = "" ;
for local c in $(indent-chars)
{
if $(c) = " " { c = &nbsp; ; }
else if $(c) = " " { c = &nbsp;&nbsp;&nbsp;&nbsp; ; }
indent = $(indent)$(c) ;
}
text $(text[1])<br> $(indent)$(text[2-])<br> ;
}
}
# Output text directly to the current target.
#
rule text (
strings * # The strings of text to output.
: overwrite ? # true to overwrite the output (if it is a file)
)
{
if $(output-target) = console
{
if ! $(strings)
{
ECHO ;
}
else
{
while $(strings)
{
ECHO $(strings[1]) ;
strings = $(strings[2-]) ;
}
}
}
else if $(output-target)
{
$(output-target).line ?= 0 ;
while $(strings)
{
local line-v = $(output-target).line.$($(output-target).line) ;
local echo-string = [ escape $(strings[1]) ] ;
$(line-v) on $(output-target) = $(echo-string) ;
NOCARE $(line-v) ;
NOTFILE $(line-v) ;
if $(overwrite) = "true"
{
overwrite = false ;
text-overwrite-action $(output-target) : $(line-v) ;
}
else
{
text-action $(output-target) : $(line-v) ;
}
strings = $(strings[2-]) ;
$(output-target).line = [ numbers.increment $($(output-target).line) ] ;
}
}
}
# Outputs the text to the current targets, after word-wrapping it.
rule wrapped-text ( text + )
{
local lines = [ split-at-words $(text) ] ;
text $(lines) ;
}
# Append single line to target file.
#
actions quietly text-action
{
echo $($(>)) >> $(<)
}
# Writes a single line to target file (overwriting or creating the
# file as necessary)
actions quietly text-overwrite-action {
echo $($(>)) > $(<)
}
if [ modules.peek : NT ]
{
rule escape ( string )
{
return [ regex.escape $(string) : "&|()<>^" : "^" ] ;
}
}
else
{
rule escape ( string )
{
local escaped = [ regex.escape $(string) : "\\\"" : "\\" ] ;
return "\"$(escaped)\"" ;
}
}
local rule __test__ ( )
{
import assert ;
assert.result one two three : split-at-words one two three : 5 ;
assert.result "one two" three : split-at-words one two three : 8 ;
assert.result "one two" three : split-at-words one two three : 9 ;
assert.result "one two three" : split-at-words one two three ;
}