1# Copyright 2003, 2004, 2005 Dave Abrahams 2# Copyright 2003, 2004, 2005 Douglas Gregor 3# Copyright 2005, 2006, 2007 Rene Rivera 4# Copyright 2003, 2004, 2005 Vladimir Prus 5# Distributed under the Boost Software License, Version 1.0. 6# (See accompanying file LICENSE_1_0.txt or copy at 7# http://www.boost.org/LICENSE_1_0.txt) 8 9# This module defines rules to handle generation of documentation from BoostBook 10# sources. 11# 12# The type of output is controlled by the <format> feature which can have the 13# following values: 14# * html: Generates html documentation. This is the default. 15# * xhtml: Generates xhtml documentation. 16# * htmlhelp: Generates html help output. 17# * onehtml: Generates a single html page. 18# * man: Generates man pages. 19# * pdf: Generates pdf documentation. 20# * ps: Generates postscript output. 21# * docbook: Generates docbook XML. 22# * fo: Generates XSL formating objects. 23# * tests: Extracts test cases from the boostbook XML. 24# 25# <format> is an implicit feature, so for example, typing pdf on the command 26# line is a short-cut for format=pdf. 27 28import build-system ; 29import "class" : new ; 30import common ; 31import feature ; 32import generators ; 33import make ; 34import modules ; 35import os ; 36import path ; 37import print ; 38import project ; 39import property ; 40import property-set ; 41import regex ; 42import scanner ; 43import sequence ; 44import targets ; 45import type ; 46import virtual-target ; 47import xsltproc ; 48 49# Make this module into a project. 50project.initialize $(__name__) ; 51project boostbook ; 52 53.debug-configuration = [ MATCH ^(--debug-configuration)$ : [ modules.peek : ARGV 54 ] ] ; 55 56feature.feature format 57 : html xhtml htmlhelp onehtml man pdf ps docbook fo tests 58 : incidental implicit composite propagated ; 59 60type.register DTDXML : dtdxml ; 61type.register XML : xml ; 62type.register BOOSTBOOK : boostbook : XML ; 63type.register DOCBOOK : docbook : XML ; 64type.register FO : fo : XML ; 65type.register PDF : pdf ; 66type.register PS : ps ; 67type.register XSLT : xsl : XML ; 68type.register HTMLDIR ; 69type.register XHTMLDIR ; 70type.register HTMLHELP ; 71type.register MANPAGES ; 72type.register TESTS : tests ; 73 74 75# Initialize BoostBook support. 76# 77rule init ( 78 docbook-xsl-dir ? # The DocBook XSL stylesheet directory. If not provided, 79 # we use DOCBOOK_XSL_DIR from the environment (if 80 # available) or look in standard locations. Otherwise, 81 # we let the XML processor load the stylesheets 82 # remotely. 83 84 : docbook-dtd-dir ? # The DocBook DTD directory. If not provided, we use 85 # DOCBOOK_DTD_DIR From the environment (if available) or 86 # look in standard locations. Otherwise, we let the XML 87 # processor load the DTD remotely. 88 89 : boostbook-dir ? # The BoostBook directory with the DTD and XSL subdirs. 90) 91{ 92 if ! $(.initialized) 93 { 94 .initialized = true ; 95 96 check-boostbook-dir $(boostbook-dir) ; 97 find-tools $(docbook-xsl-dir) : $(docbook-dtd-dir) : $(boostbook-dir) ; 98 99 # Register generators only if we were called via "using boostbook ;" 100 local reg-gen = generators.register-standard ; 101 $(reg-gen) boostbook.dtdxml-to-boostbook : DTDXML : XML ; 102 $(reg-gen) boostbook.boostbook-to-docbook : XML : DOCBOOK ; 103 $(reg-gen) boostbook.boostbook-to-tests : XML : TESTS ; 104 $(reg-gen) boostbook.docbook-to-onehtml : DOCBOOK : HTML ; 105 $(reg-gen) boostbook.docbook-to-htmldir : DOCBOOK : HTMLDIR ; 106 $(reg-gen) boostbook.docbook-to-xhtmldir : DOCBOOK : XHTMLDIR ; 107 $(reg-gen) boostbook.docbook-to-htmlhelp : DOCBOOK : HTMLHELP ; 108 $(reg-gen) boostbook.docbook-to-manpages : DOCBOOK : MANPAGES ; 109 $(reg-gen) boostbook.docbook-to-fo : DOCBOOK : FO ; 110 111 # The same about Jamfile main target rules. 112 IMPORT $(__name__) : boostbook : : boostbook ; 113 } 114 else 115 { 116 if $(docbook-xsl-dir) 117 { 118 modify-config ; 119 .docbook-xsl-dir = [ path.make $(docbook-xsl-dir) ] ; 120 check-docbook-xsl-dir ; 121 } 122 if $(docbook-dtd-dir) 123 { 124 modify-config ; 125 .docbook-dtd-dir = [ path.make $(docbook-dtd-dir) ] ; 126 check-docbook-dtd-dir ; 127 } 128 if $(boostbook-dir) 129 { 130 modify-config ; 131 check-boostbook-dir $(boostbook-dir) ; 132 local boostbook-xsl-dir = [ path.glob $(boostbook-dir) : xsl ] ; 133 local boostbook-dtd-dir = [ path.glob $(boostbook-dir) : dtd ] ; 134 .boostbook-xsl-dir = $(boostbook-xsl-dir[1]) ; 135 .boostbook-dtd-dir = $(boostbook-dtd-dir[1]) ; 136 check-boostbook-xsl-dir ; 137 check-boostbook-dtd-dir ; 138 } 139 } 140} 141 142 143local rule lock-config ( ) 144{ 145 if ! $(.initialized) 146 { 147 import errors ; 148 errors.user-error BoostBook has not been configured. ; 149 } 150 if ! $(.config-locked) 151 { 152 .config-locked = true ; 153 154 if $(.error-message) 155 { 156 print-error $(.error-message) ; 157 } 158 } 159} 160 161 162local rule modify-config ( ) 163{ 164 if $(.config-locked) 165 { 166 import errors ; 167 errors.user-error BoostBook configuration cannot be changed after it has 168 been used. ; 169 } 170} 171 172rule print-error ( location message * ) 173{ 174 ECHO error: at $(location) ; 175 ECHO error: $(message) ; 176 EXIT ; 177} 178 179rule make-error ( message * ) 180{ 181 import errors ; 182 return [ errors.nearest-user-location ] $(message) ; 183} 184 185 186rule find-boost-in-registry ( keys * ) 187{ 188 local boost-root ; 189 for local R in $(keys) 190 { 191 local installed-boost = [ W32_GETREG 192 "HKEY_LOCAL_MACHINE\\SOFTWARE\\$(R)" : "InstallRoot" ] ; 193 if $(installed-boost) 194 { 195 boost-root += [ path.make $(installed-boost) ] ; 196 } 197 } 198 return $(boost-root) ; 199} 200 201 202rule check-docbook-xsl-dir ( ) 203{ 204 if $(.docbook-xsl-dir) 205 { 206 if ! [ path.glob $(.docbook-xsl-dir) : common/common.xsl ] 207 { 208 .error-message = [ make-error BoostBook: could not find docbook XSL stylesheets 209 in: [ path.native $(.docbook-xsl-dir) ] ] ; 210 } 211 else if $(.debug-configuration) 212 { 213 ECHO notice: BoostBook: found docbook XSL stylesheets in: [ 214 path.native $(.docbook-xsl-dir) ] ; 215 } 216 } 217} 218 219 220rule check-docbook-dtd-dir ( ) 221{ 222 if $(.docbook-dtd-dir) 223 { 224 if ! [ path.glob $(.docbook-dtd-dir) : docbookx.dtd ] 225 { 226 .error-message = [ make-error BoostBook: could not find docbook DTD in: [ 227 path.native $(.docbook-dtd-dir) ] ] ; 228 } 229 else if $(.debug-configuration) 230 { 231 ECHO notice: BoostBook: found docbook DTD in: [ path.native 232 $(.docbook-dtd-dir) ] ; 233 } 234 } 235} 236 237 238rule check-boostbook-xsl-dir ( ) 239{ 240 if ! $(.boostbook-xsl-dir) 241 { 242 .error-message = [ make-error BoostBook: could not find boostbook XSL stylesheets. ] ; 243 } 244 else if ! [ path.glob $(.boostbook-xsl-dir) : docbook.xsl ] 245 { 246 .error-message = [ make-error BoostBook: could not find docbook XSL stylesheets in: 247 [ path.native $(.boostbook-xsl-dir) ] ] ; 248 } 249 else if $(.debug-configuration) 250 { 251 ECHO notice: BoostBook: found boostbook XSL stylesheets in: [ 252 path.native $(.boostbook-xsl-dir) ] ; 253 } 254} 255 256 257rule check-boostbook-dtd-dir ( ) 258{ 259 if ! $(.boostbook-dtd-dir) 260 { 261 .error-message = [ make-error BoostBook: could not find boostbook DTD. ] ; 262 } 263 else if ! [ path.glob $(.boostbook-dtd-dir) : boostbook.dtd ] 264 { 265 .error-message = [ make-error BoostBook: could not find boostbook DTD in: [ 266 path.native $(.boostbook-dtd-dir) ] ] ; 267 } 268 else if $(.debug-configuration) 269 { 270 ECHO notice: BoostBook: found boostbook DTD in: [ path.native 271 $(.boostbook-dtd-dir) ] ; 272 } 273} 274 275 276rule check-boostbook-dir ( boostbook-dir ? ) 277{ 278 if $(boostbook-dir) && ! [ path.glob $(boostbook-dir) : xsl ] 279 { 280 .error-message = [ make-error BoostBook: could not find boostbook in: [ path.native 281 $(boostbook-dir) ] ] ; 282 } 283} 284 285 286rule find-tools ( docbook-xsl-dir ? : docbook-dtd-dir ? : boostbook-dir ? ) 287{ 288 docbook-xsl-dir ?= [ modules.peek : DOCBOOK_XSL_DIR ] ; 289 docbook-dtd-dir ?= [ modules.peek : DOCBOOK_DTD_DIR ] ; 290 boostbook-dir ?= [ modules.peek : BOOSTBOOK_DIR ] ; 291 292 # Look for the boostbook stylesheets relative to BOOST_ROOT and Boost.Build. 293 local boost-build-root = [ path.make [ build-system.location ] ] ; 294 local boostbook-search-dirs = [ path.join $(boost-build-root) .. .. ] ; 295 296 local boost-root = [ modules.peek : BOOST_ROOT ] ; 297 if $(boost-root) 298 { 299 boostbook-search-dirs += [ path.join [ path.make $(boost-root) ] tools ] 300 ; 301 } 302 boostbook-dir ?= [ path.glob $(boostbook-search-dirs) : boostbook* ] ; 303 304 # Try to find the tools in platform specific locations. 305 if [ os.name ] = NT 306 { 307 # If installed by the Boost installer. 308 local boost-root = ; 309 310 local boost-installer-versions = snapshot cvs 1.33.0 ; 311 local boost-consulting-installer-versions = 1.33.1 1.34.0 1.34.1 ; 312 local boostpro-installer-versions = 313 1.35.0 1.36.0 1.37.0 1.38.0 1.39.0 1.40.0 1.41.0 1.42.0 314 1.43.0 1.44.0 1.45.0 1.46.0 1.47.0 1.48.0 1.49.0 1.50.0 ; 315 316 local old-installer-root = [ find-boost-in-registry 317 Boost.org\\$(boost-installer-versions) ] ; 318 319 # Make sure that the most recent version is searched for first. 320 boost-root += [ sequence.reverse [ find-boost-in-registry 321 Boost-Consulting.com\\$(boost-consulting-installer-versions) 322 boostpro.com\\$(boostpro-installer-versions) ] ] ; 323 324 # Plausible locations. 325 local root = [ PWD ] ; 326 while $(root) != $(root:D) { root = $(root:D) ; } 327 root = [ path.make $(root) ] ; 328 local search-dirs ; 329 local docbook-search-dirs ; 330 for local p in $(boost-root) 331 { 332 search-dirs += [ path.join $(p) tools ] ; 333 } 334 for local p in $(old-installer-root) 335 { 336 search-dirs += [ path.join $(p) share ] ; 337 docbook-search-dirs += [ path.join $(p) share ] ; 338 } 339 search-dirs += [ path.join $(root) Boost tools ] ; 340 search-dirs += [ path.join $(root) Boost share ] ; 341 docbook-search-dirs += [ path.join $(root) Boost share ] ; 342 343 docbook-xsl-dir ?= [ path.glob $(docbook-search-dirs) : docbook-xsl* ] ; 344 docbook-dtd-dir ?= [ path.glob $(docbook-search-dirs) : docbook-xml* ] ; 345 boostbook-dir ?= [ path.glob $(search-dirs) : boostbook* ] ; 346 } 347 else 348 { 349 # Plausible locations. 350 351 local share = /usr/local/share /usr/share /opt/share /opt/local/share ; 352 local dtd-versions = 4.2 ; 353 354 docbook-xsl-dir ?= [ path.glob $(share) : docbook-xsl* ] ; 355 docbook-xsl-dir ?= [ path.glob $(share)/sgml/docbook : xsl-stylesheets ] 356 ; 357 docbook-xsl-dir ?= [ path.glob $(share)/xsl : docbook* ] ; 358 359 docbook-dtd-dir ?= [ path.glob $(share) : docbook-xml* ] ; 360 docbook-dtd-dir ?= [ path.glob $(share)/sgml/docbook : 361 xml-dtd-$(dtd-versions)* ] ; 362 docbook-dtd-dir ?= [ path.glob $(share)/xml/docbook : $(dtd-versions) ] 363 ; 364 365 boostbook-dir ?= [ path.glob $(share) : boostbook* ] ; 366 367 # Ubuntu Linux. 368 docbook-xsl-dir ?= [ path.glob /usr/share/xml/docbook/stylesheet : 369 nwalsh ] ; 370 docbook-dtd-dir ?= [ path.glob /usr/share/xml/docbook/schema/dtd : 371 $(dtd-versions) ] ; 372 373 # SUSE. 374 docbook-xsl-dir ?= [ path.glob /usr/share/xml/docbook/stylesheet/nwalsh 375 : current ] ; 376 } 377 378 if $(docbook-xsl-dir) 379 { 380 .docbook-xsl-dir = [ path.make $(docbook-xsl-dir[1]) ] ; 381 } 382 if $(docbook-dtd-dir) 383 { 384 .docbook-dtd-dir = [ path.make $(docbook-dtd-dir[1]) ] ; 385 } 386 387 if $(.debug-configuration) 388 { 389 ECHO notice: Boost.Book: searching XSL/DTD "in" ; 390 ECHO notice: [ sequence.transform path.native : $(boostbook-dir) ] ; 391 } 392 local boostbook-xsl-dir ; 393 for local dir in $(boostbook-dir) 394 { 395 boostbook-xsl-dir += [ path.glob $(dir) : xsl ] ; 396 } 397 local boostbook-dtd-dir ; 398 for local dir in $(boostbook-dir) 399 { 400 boostbook-dtd-dir += [ path.glob $(dir) : dtd ] ; 401 } 402 .boostbook-xsl-dir = $(boostbook-xsl-dir[1]) ; 403 .boostbook-dtd-dir = $(boostbook-dtd-dir[1]) ; 404 405 check-docbook-xsl-dir ; 406 check-docbook-dtd-dir ; 407 check-boostbook-xsl-dir ; 408 check-boostbook-dtd-dir ; 409} 410 411 412rule xsl-dir 413{ 414 lock-config ; 415 return $(.boostbook-xsl-dir) ; 416} 417 418 419rule dtd-dir 420{ 421 lock-config ; 422 return $(.boostbook-dtd-dir) ; 423} 424 425 426rule docbook-xsl-dir 427{ 428 lock-config ; 429 return $(.docbook-xsl-dir) ; 430} 431 432 433rule docbook-dtd-dir 434{ 435 lock-config ; 436 return $(.docbook-dtd-dir) ; 437} 438 439 440rule dtdxml-to-boostbook ( target : source : properties * ) 441{ 442 lock-config ; 443 xsltproc.xslt $(target) : $(source) 444 "$(.boostbook-xsl-dir)/dtd/dtd2boostbook.xsl" : $(properties) ; 445} 446 447 448rule boostbook-to-docbook ( target : source : properties * ) 449{ 450 lock-config ; 451 local stylesheet = [ path.native $(.boostbook-xsl-dir)/docbook.xsl ] ; 452 xsltproc.xslt $(target) : $(source) $(stylesheet) : $(properties) ; 453} 454 455 456rule docbook-to-onehtml ( target : source : properties * ) 457{ 458 lock-config ; 459 local stylesheet = [ path.native $(.boostbook-xsl-dir)/html-single.xsl ] ; 460 xsltproc.xslt $(target) : $(source) $(stylesheet) : $(properties) ; 461} 462 463 464rule docbook-to-htmldir ( target : source : properties * ) 465{ 466 lock-config ; 467 local stylesheet = [ path.native $(.boostbook-xsl-dir)/html.xsl ] ; 468 xsltproc.xslt-dir $(target) : $(source) $(stylesheet) : $(properties) : html 469 ; 470} 471 472 473rule docbook-to-xhtmldir ( target : source : properties * ) 474{ 475 lock-config ; 476 local stylesheet = [ path.native $(.boostbook-xsl-dir)/xhtml.xsl ] ; 477 xsltproc.xslt-dir $(target) : $(source) $(stylesheet) : $(properties) : 478 xhtml ; 479} 480 481 482rule docbook-to-htmlhelp ( target : source : properties * ) 483{ 484 lock-config ; 485 local stylesheet = [ path.native $(.boostbook-xsl-dir)/html-help.xsl ] ; 486 xsltproc.xslt-dir $(target) : $(source) $(stylesheet) : $(properties) : 487 htmlhelp ; 488} 489 490 491rule docbook-to-manpages ( target : source : properties * ) 492{ 493 lock-config ; 494 local stylesheet = [ path.native $(.boostbook-xsl-dir)/manpages.xsl ] ; 495 xsltproc.xslt-dir $(target) : $(source) $(stylesheet) : $(properties) : man 496 ; 497} 498 499 500rule docbook-to-fo ( target : source : properties * ) 501{ 502 lock-config ; 503 local stylesheet = [ path.native $(.boostbook-xsl-dir)/fo.xsl ] ; 504 xsltproc.xslt $(target) : $(source) $(stylesheet) : $(properties) ; 505} 506 507 508rule format-catalog-path ( path ) 509{ 510 local result = $(path) ; 511 if [ xsltproc.is-cygwin ] 512 { 513 if [ os.name ] = NT 514 { 515 drive = [ MATCH ^/(.):(.*)$ : $(path) ] ; 516 result = /cygdrive/$(drive[1])$(drive[2]) ; 517 } 518 } 519 else 520 { 521 if [ os.name ] = CYGWIN 522 { 523 local native-path = [ path.native $(path) ] ; 524 result = [ path.make $(native-path:W) ] ; 525 } 526 } 527 return [ regex.replace $(result) " " "%20" ] ; 528} 529 530 531rule generate-xml-catalog ( target : sources * : properties * ) 532{ 533 print.output $(target) ; 534 535 # BoostBook DTD catalog entry. 536 local boostbook-dtd-dir = [ boostbook.dtd-dir ] ; 537 if $(boostbook-dtd-dir) 538 { 539 boostbook-dtd-dir = [ format-catalog-path $(boostbook-dtd-dir) ] ; 540 } 541 542 print.text 543 "<?xml version=\"1.0\"?>" 544 "<!DOCTYPE catalog " 545 " PUBLIC \"-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN\"" 546 " \"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd\">" 547 "<catalog xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">" 548 " <rewriteURI uriStartString=\"http://www.boost.org/tools/boostbook/dtd/\" rewritePrefix=\"file://$(boostbook-dtd-dir)/\"/>" 549 : true ; 550 551 local docbook-xsl-dir = [ boostbook.docbook-xsl-dir ] ; 552 if ! $(docbook-xsl-dir) 553 { 554 ECHO "BoostBook warning: no DocBook XSL directory specified." ; 555 ECHO " If you have the DocBook XSL stylesheets installed, please " ; 556 ECHO " set DOCBOOK_XSL_DIR to the stylesheet directory on either " ; 557 ECHO " the command line (via -sDOCBOOK_XSL_DIR=...) or in a " ; 558 ECHO " Boost.Jam configuration file. The DocBook XSL stylesheets " ; 559 ECHO " are available here: http://docbook.sourceforge.net/ " ; 560 ECHO " Stylesheets will be downloaded on-the-fly (very slow!) " ; 561 } 562 else 563 { 564 docbook-xsl-dir = [ format-catalog-path $(docbook-xsl-dir) ] ; 565 print.text " <rewriteURI uriStartString=\"http://docbook.sourceforge.net/release/xsl/current/\" rewritePrefix=\"file://$(docbook-xsl-dir)/\"/>" ; 566 } 567 568 local docbook-dtd-dir = [ boostbook.docbook-dtd-dir ] ; 569 if ! $(docbook-dtd-dir) 570 { 571 ECHO "BoostBook warning: no DocBook DTD directory specified." ; 572 ECHO " If you have the DocBook DTD installed, please set " ; 573 ECHO " DOCBOOK_DTD_DIR to the DTD directory on either " ; 574 ECHO " the command line (via -sDOCBOOK_DTD_DIR=...) or in a " ; 575 ECHO " Boost.Jam configuration file. The DocBook DTD is available " ; 576 ECHO " here: http://www.oasis-open.org/docbook/xml/4.2/index.shtml" ; 577 ECHO " The DTD will be downloaded on-the-fly (very slow!) " ; 578 } 579 else 580 { 581 docbook-dtd-dir = [ format-catalog-path $(docbook-dtd-dir) ] ; 582 print.text " <rewriteURI uriStartString=\"http://www.oasis-open.org/docbook/xml/4.2/\" rewritePrefix=\"file://$(docbook-dtd-dir)/\"/>" ; 583 } 584 585 print.text "</catalog>" ; 586} 587 588 589# Returns information about the global XML catalog target, creating it lazily if 590# needed. To get the global catalog generated only once we do not create it in 591# every project that requests it but instead only create it based on the first 592# project requesting it and then reuse it from there for any later requests. 593# 594# To get 'as close as possible' to having the global catalog stored in the same 595# location independent of which folder our build was run from, we assign its 596# target to the given project's base Jamroot project. This works correctly as 597# long as we know the passed project is not standalone or one of Boost Build's 598# configuration module projects, as those to not have a Jamroot project in their 599# parent chain. Note also that we can still get our targets generated in 600# different folders in case when one build project references a target from 601# another build project with its own separate Jamroot. 602# 603# FIXME: Ideally the catalog target should be created as part of the boostbook 604# project and stored in some central location for all used standalone pojects, 605# shared between all builds made on that system. This however would require much 606# more though to add the necessary changes to Boost Build's internal design. 607# 608local rule xml-catalog ( project ) 609{ 610 if ! $(.xml-catalog) 611 { 612 local project-module = [ $(project).project-module ] ; 613 local root-module = [ project.get-jamroot-module $(project-module) ] ; 614 if ! $(root-module) 615 { 616 import errors ; 617 if [ project.is-config-module $(project-module) ] 618 { 619 errors.user-error boostbook targets can not be declared in Boost 620 Build's configuration modules. ; 621 } 622 else 623 { 624 errors.user-error boostbook targets can not be declared in 625 standalone projects. : use a Jamfile/Jamroot project 626 instead. ; 627 } 628 } 629 local root-project = [ project.target $(root-module) ] ; 630 631 .xml-catalog = [ virtual-target.register [ new file-target 632 boostbook_catalog : XML : $(root-project) : [ new action : 633 boostbook.generate-xml-catalog ] ] ] ; 634 .xml-catalog-file = [ $(.xml-catalog).path ] [ $(.xml-catalog).name ] ; 635 .xml-catalog-file = $(.xml-catalog-file:J=/) ; 636 } 637 return $(.xml-catalog) $(.xml-catalog-file) ; 638} 639 640 641class boostbook-target-class : basic-target 642{ 643 import generators ; 644 import property-set ; 645 import virtual-target ; 646 647 rule construct ( name : sources * : property-set ) 648 { 649 # Generate the catalog, but only once. 650 IMPORT boostbook : xml-catalog : $(__name__) : boostbook.xml-catalog ; 651 local global-catalog = [ boostbook.xml-catalog [ project ] ] ; 652 local catalog = $(global-catalog[1]) ; 653 local catalog-file = $(global-catalog[2]) ; 654 local targets ; 655 656 # Add the catalog to the property set. 657 property-set = [ $(property-set).add-raw <catalog>$(catalog-file) ] ; 658 659 local type = none ; 660 local manifest ; 661 local format = [ $(property-set).get <format> ] ; 662 switch $(format) 663 { 664 case html : type = HTMLDIR ; manifest = HTML.manifest ; 665 case xhtml : type = XHTMLDIR ; manifest = HTML.manifest ; 666 case htmlhelp : type = HTMLHELP ; manifest = HTML.manifest ; 667 case onehtml : type = HTML ; 668 case man : type = MANPAGES ; manifest = man.manifest ; 669 case docbook : type = DOCBOOK ; 670 case fo : type = FO ; 671 case pdf : type = PDF ; 672 case ps : type = PS ; 673 case tests : type = TESTS ; 674 } 675 676 local target ; 677 if $(manifest) 678 { 679 # Sources --> DOCBOOK. 680 local docbook-target = [ generators.construct [ project ] : DOCBOOK 681 : $(property-set) : $(sources) ] ; 682 docbook-target = $(docbook-target[2]) ; 683 $(docbook-target).depends $(catalog) ; 684 685 # DOCBOOK --> type. 686 target = [ generators.construct [ project ] $(name)_$(manifest) : 687 $(type) : [ $(property-set).add-raw 688 <xsl:param>manifest=$(name)_$(manifest) ] : $(docbook-target) ] 689 ; 690 target = $(target[2]) ; 691 local name = [ $(property-set).get <name> ] ; 692 name ?= $(format) ; 693 $(target).set-path $(name) ; 694 } 695 else 696 { 697 # Sources --> type. 698 target = [ generators.construct [ project ] : $(type) : 699 $(property-set) : $(sources) ] ; 700 target = $(target[2]) ; 701 if ! $(target) 702 { 703 import errors ; 704 errors.error Cannot build documentation type '$(format)'. ; 705 } 706 } 707 $(target).depends $(catalog) ; 708 709 return [ property-set.empty ] $(target) ; 710 } 711} 712 713 714# Declare a boostbook target. 715# 716rule boostbook ( target-name : sources * : requirements * : default-build * ) 717{ 718 return [ targets.create-metatarget boostbook-target-class : 719 [ project.current ] : $(target-name) : $(sources) : $(requirements) : 720 $(default-build) ] ; 721} 722 723 724rule boostbook-to-tests ( target : source : properties * ) 725{ 726 lock-config ; 727 local boost_root = [ modules.peek : BOOST_ROOT ] ; 728 local native-path = [ path.native [ path.join $(.boostbook-xsl-dir) testing 729 Jamfile ] ] ; 730 local stylesheet = $(native-path:S=.xsl) ; 731 xsltproc.xslt $(target) : $(source) $(stylesheet) : $(properties) 732 <xsl:param>boost.root=$(boost_root) ; 733} 734 735 736############################################################################# 737# Dependency scanners 738############################################################################# 739# XInclude scanner. Mostly stolen from c-scanner. :) 740# Note that this assumes an "xi" prefix for XIncludes. This is not always the 741# case for XML documents, but we assume it is true for anything we encounter. 742# 743class xinclude-scanner : scanner 744{ 745 import scanner ; 746 747 rule __init__ ( includes * ) 748 { 749 scanner.__init__ ; 750 self.includes = $(includes) ; 751 } 752 753 rule pattern ( ) 754 { 755 return "xi:include[ ]*href=\"([^\"]*)\"" ; 756 } 757 758 rule process ( target : matches * : binding ) 759 { 760 local target_path = [ NORMALIZE_PATH $(binding:D) ] ; 761 762 NOCARE $(matches) ; 763 INCLUDES $(target) : $(matches) ; 764 SEARCH on $(matches) = $(target_path) $(self.includes:G=) ; 765 766 scanner.propagate $(__name__) : $(matches) : $(target) ; 767 } 768} 769 770scanner.register xinclude-scanner : xsl:path ; 771type.set-scanner XML : xinclude-scanner ; 772