Imported Upstream version 1.51.0
[platform/upstream/boost.git] / tools / build / src / tools / quickbook.jam
1 #
2 #   Copyright (c) 2005 João Abecasis
3 #   Copyright (c) 2005 Vladimir Prus
4 #   Copyright (c) 2006 Rene Rivera
5 #
6 #   Distributed under the Boost Software License, Version 1.0. (See
7 #   accompanying file LICENSE_1_0.txt or copy at
8 #   http://www.boost.org/LICENSE_1_0.txt)
9 #
10
11 # This toolset defines a generator to translate QuickBook to BoostBook. It can
12 # be used to generate nice (!) user documentation in different formats
13 # (pdf/html/...), from a single text file with simple markup.
14 #
15 # The toolset defines the QUICKBOOK type (file extension 'qbk') and
16 # a QUICKBOOK to XML (BOOSTBOOK) generator.
17 #
18 #
19 #   ===========================================================================
20 #   Q & A
21 #   ===========================================================================
22 #
23 #   If you don't know what this is all about, some Q & A will hopefully get you
24 #   up to speed with QuickBook and this toolset.
25 #
26 #
27 #   What is QuickBook ?
28 #
29 #       QuickBook is a WikiWiki style documentation tool geared towards C++
30 #       documentation using simple rules and markup for simple formatting tasks.
31 #       QuickBook extends the WikiWiki concept. Like the WikiWiki, QuickBook
32 #       documents are simple text files. A single QuickBook document can
33 #       generate a fully linked set of nice HTML and PostScript/PDF documents
34 #       complete with images and syntax-colorized source code.
35 #
36 #
37 #   Where can I get QuickBook ?
38 #
39 #       Quickbook can be found in Boost's repository, under the tools/quickbook
40 #       directory it was added there on Jan 2005, some time after the release of
41 #       Boost v1.32.0 and has been an integral part of the Boost distribution
42 #       since v1.33.
43 #
44 #       Here's a link to the SVN repository:
45 #           https://svn.boost.org/svn/boost/trunk/tools/quickbook
46 #
47 #       And to QuickBook's QuickBook-generated docs:
48 #           http://www.boost.org/doc/libs/release/tools/quickbook/index.html
49 #
50 #
51 #   How do I use QuickBook and this toolset in my projects ?
52 #
53 #       The minimal example is:
54 #
55 #           using boostbook ;
56 #           import quickbook ;
57 #
58 #           boostbook my_docs : my_docs_source.qbk ;
59 #
60 #       where my_docs is a target name and my_docs_source.qbk is a QuickBook
61 #       file. The documentation format to be generated is determined by the
62 #       boostbook toolset. By default html documentation should be generated,
63 #       but you should check BoostBook's docs to be sure.
64 #
65 #
66 #   What do I need ?
67 #
68 #       You should start by setting up the BoostBook toolset. Please refer to
69 #       boostbook.jam and the BoostBook documentation for information on how to
70 #       do this.
71 #
72 #       A QuickBook executable is also needed. The toolset will generate this
73 #       executable if it can find the QuickBook sources. The following
74 #       directories will be searched:
75 #
76 #           BOOST_ROOT/tools/quickbook/
77 #           BOOST_BUILD_PATH/../../quickbook/
78 #
79 #       (BOOST_ROOT and BOOST_BUILD_PATH are environment variables)
80 #
81 #       If QuickBook sources are not found the toolset will then try to use
82 #       the shell command 'quickbook'.
83 #
84 #
85 #   How do I provide a custom QuickBook executable ?
86 #
87 #       You may put the following in your user-config.jam or site-config.jam:
88 #
89 #           using quickbook : /path/to/quickbook ;
90 #
91 #       or, if 'quickbook' can be found in your PATH,
92 #
93 #           using quickbook : quickbook ;
94 #
95 #
96 #   For convenience three alternatives are tried to get a QuickBook executable:
97 #
98 #       1.  If the user points us to the a QuickBook executable, that is used.
99 #
100 #       2.  Otherwise, we search for the QuickBook sources and compile QuickBook
101 #           using the default toolset.
102 #
103 #       3.  As a last resort, we rely on the shell for finding 'quickbook'.
104 #
105
106 import boostbook ;
107 import "class" : new ;
108 import feature ;
109 import generators ;
110 import toolset ;
111 import type ;
112 import scanner ;
113 import project ;
114 import targets ;
115 import build-system ;
116 import path ;
117 import common ;
118 import errors ;
119
120 # The one and only QUICKBOOK type!
121 type.register QUICKBOOK : qbk ;
122
123 # <quickbook-binary> shell command to run QuickBook
124 # <quickbook-binary-dependencies> targets to build QuickBook from sources.
125 feature.feature <quickbook-binary> : : free ;
126 feature.feature <quickbook-binary-dependencies> : : free dependency ;
127 feature.feature <quickbook-define> : : free ;
128 feature.feature <quickbook-indent> : : free ;
129 feature.feature <quickbook-line-width> : : free ;
130
131
132 # quickbook-binary-generator handles generation of the QuickBook executable, by
133 # marking it as a dependency for QuickBook docs.
134 #
135 # If the user supplied the QuickBook command that will be used.
136 #
137 # Otherwise we search some sensible places for the QuickBook sources and compile
138 # from scratch using the default toolset.
139 #
140 # As a last resort we rely on the shell to find 'quickbook'.
141 #
142 class quickbook-binary-generator : generator
143 {
144     import modules path targets quickbook ;
145
146     rule run ( project name ? : property-set : sources * : multiple ? )
147     {
148         quickbook.freeze-config ;
149         # QuickBook invocation command and dependencies.
150         local quickbook-binary = [ modules.peek quickbook : .quickbook-binary ] ;
151         local quickbook-binary-dependencies ;
152
153         if ! $(quickbook-binary)
154         {
155             # If the QuickBook source directory was found, mark its main target
156             # as a dependency for the current project. Otherwise, try to find
157             # 'quickbook' in user's PATH
158             local quickbook-dir = [ modules.peek quickbook : .quickbook-dir ] ;
159             if $(quickbook-dir)
160             {
161                 # Get the main-target in QuickBook directory.
162                 local quickbook-main-target = [ targets.resolve-reference $(quickbook-dir) : $(project) ] ;
163
164                 # The first element are actual targets, the second are
165                 # properties found in target-id. We do not care about these
166                 # since we have passed the id ourselves.
167                 quickbook-main-target =
168                     [ $(quickbook-main-target[1]).main-target quickbook ] ;
169
170                 quickbook-binary-dependencies =
171                     [ $(quickbook-main-target).generate [ $(property-set).propagated ] ] ;
172
173                 # Ignore usage-requirements returned as first element.
174                 quickbook-binary-dependencies = $(quickbook-binary-dependencies[2-]) ;
175
176                 # Some toolsets generate extra targets (e.g. RSP). We must mark
177                 # all targets as dependencies for the project, but we will only
178                 # use the EXE target for quickbook-to-boostbook translation.
179                 for local target in $(quickbook-binary-dependencies)
180                 {
181                     if [ $(target).type ] = EXE
182                     {
183                         quickbook-binary = 
184                             [ path.native 
185                                 [ path.join
186                                     [ $(target).path ]
187                                     [ $(target).name ]
188                                 ]
189                             ] ;
190                     }
191                 }
192             }
193         }
194
195         # Add $(quickbook-binary-dependencies) as a dependency of the current
196         # project and set it as the <quickbook-binary> feature for the
197         # quickbook-to-boostbook rule, below.
198         property-set = [ $(property-set).add-raw
199             <dependency>$(quickbook-binary-dependencies)
200             <quickbook-binary>$(quickbook-binary)
201             <quickbook-binary-dependencies>$(quickbook-binary-dependencies)
202         ] ;
203
204         return [ generator.run $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
205     }
206 }
207
208
209 # Define a scanner for tracking QBK include dependencies.
210 #
211 class qbk-scanner : common-scanner
212 {
213     rule pattern ( )
214     {
215         return "\\[[ ]*include[ ]+([^]]+)\\]" 
216         "\\[[ ]*include:[a-zA-Z0-9_]+[ ]+([^]]+)\\]" 
217         "\\[[ ]*import[ ]+([^]]+)\\]" ;
218     }
219 }
220
221
222 scanner.register qbk-scanner : include ;
223
224 type.set-scanner QUICKBOOK : qbk-scanner ;
225
226
227 # Initialization of toolset.
228 #
229 # Parameters:
230 #   command ?    -> path to QuickBook executable.
231 #
232 # When command is not supplied toolset will search for QuickBook directory and
233 # compile the executable from source. If that fails we still search the path for
234 # 'quickbook'.
235 #
236 rule init (
237         command ?   # path to the QuickBook executable.
238     )
239 {
240     if $(command)
241     {
242         if $(.config-frozen)
243         {
244             errors.user-error "quickbook: configuration cannot be changed after it has been used." ;
245         }
246         .command = $(command) ;
247     }
248 }
249
250 rule freeze-config ( )
251 {
252     if ! $(.config-frozen)
253     {
254         .config-frozen = true ;
255
256         # QuickBook invocation command and dependencies.
257
258         .quickbook-binary = $(.command) ;
259
260         if $(.quickbook-binary)
261         {
262             # Use user-supplied command.
263             .quickbook-binary = [ common.get-invocation-command quickbook : quickbook : $(.quickbook-binary) ] ;
264         }
265         else
266         {
267             # Search for QuickBook sources in sensible places, like
268             #   $(BOOST_ROOT)/tools/quickbook
269             #   $(BOOST_BUILD_PATH)/../../quickbook
270
271             # And build quickbook executable from sources.
272
273             local boost-root = [ modules.peek : BOOST_ROOT ] ;
274             local boost-build-path = [ build-system.location ] ;
275
276             if $(boost-root)
277             {
278                 .quickbook-dir += [ path.join $(boost-root) tools ] ;
279             }
280
281             if $(boost-build-path)
282             {
283                 .quickbook-dir += $(boost-build-path)/../.. ;
284             }
285
286             .quickbook-dir = [ path.glob $(.quickbook-dir) : quickbook ] ;
287
288             # If the QuickBook source directory was found, mark its main target
289             # as a dependency for the current project. Otherwise, try to find
290             # 'quickbook' in user's PATH
291             if $(.quickbook-dir)
292             {
293                 .quickbook-dir = [ path.make $(.quickbook-dir[1]) ] ;
294             }
295             else
296             {
297                 ECHO "QuickBook warning: The path to the quickbook executable was" ;
298                 ECHO "  not provided. Additionally, couldn't find QuickBook" ;
299                 ECHO "  sources searching in" ;
300                 ECHO "    * BOOST_ROOT/tools/quickbook" ;
301                 ECHO "    * BOOST_BUILD_PATH/../../quickbook" ;
302                 ECHO "  Will now try to find a precompiled executable by searching" ;
303                 ECHO "  the PATH for 'quickbook'." ;
304                 ECHO "  To disable this warning in the future, or to completely" ;
305                 ECHO "  avoid compilation of quickbook, you can explicitly set the" ;
306                 ECHO "  path to a quickbook executable command in user-config.jam" ;
307                 ECHO "  or site-config.jam with the call" ;
308                 ECHO "    using quickbook : /path/to/quickbook ;" ;
309
310                 # As a last resort, search for 'quickbook' command in path. Note
311                 # that even if the 'quickbook' command is not found,
312                 # get-invocation-command will still return 'quickbook' and might
313                 # generate an error while generating the virtual-target.
314
315                 .quickbook-binary = [ common.get-invocation-command quickbook : quickbook ] ;
316             }
317         }
318     }
319 }
320
321
322 generators.register [ new quickbook-binary-generator quickbook.quickbook-to-boostbook : QUICKBOOK : XML ] ;
323
324
325 # <quickbook-binary> shell command to run QuickBook
326 # <quickbook-binary-dependencies> targets to build QuickBook from sources.
327 toolset.flags quickbook.quickbook-to-boostbook QB-COMMAND      <quickbook-binary> ;
328 toolset.flags quickbook.quickbook-to-boostbook QB-DEPENDENCIES <quickbook-binary-dependencies> ;
329 toolset.flags quickbook.quickbook-to-boostbook INCLUDES        <include> ;
330 toolset.flags quickbook.quickbook-to-boostbook QB-DEFINES      <quickbook-define> ;
331 toolset.flags quickbook.quickbook-to-boostbook QB-INDENT       <quickbook-indent> ;
332 toolset.flags quickbook.quickbook-to-boostbook QB-LINE-WIDTH   <quickbook-line-width> ;
333
334
335 rule quickbook-to-boostbook ( target : source : properties * )
336 {
337     # Signal dependency of quickbook sources on <quickbook-binary-dependencies>
338     # upon invocation of quickbook-to-boostbook.
339     DEPENDS $(target) : [ on $(target) return $(QB-DEPENDENCIES) ] ;
340 }
341
342
343 actions quickbook-to-boostbook
344 {
345     "$(QB-COMMAND)" -I"$(INCLUDES)" -D"$(QB-DEFINES)" --indent="$(QB-INDENT)" --linewidth="$(QB-LINE-WIDTH)" --output-file="$(1)" "$(2)"
346 }
347
348
349 # Declare a main target to convert a quickbook source into a boostbook XML file.
350 #
351 rule to-boostbook ( target-name : sources * : requirements * : default-build * )
352
353   local project = [ project.current ] ;
354     
355   targets.main-target-alternative 
356     [ new typed-target $(target-name) : $(project) : XML
357         : [ targets.main-target-sources $(sources) : $(target-name) ] 
358         : [ targets.main-target-requirements $(requirements) : $(project) ]
359         : [ targets.main-target-default-build $(default-build) : $(project) ] 
360     ] ;
361 }