change support python version
[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 feature.feature <quickbook-strict-mode> : : free ;
131
132
133 # quickbook-binary-generator handles generation of the QuickBook executable, by
134 # marking it as a dependency for QuickBook docs.
135 #
136 # If the user supplied the QuickBook command that will be used.
137 #
138 # Otherwise we search some sensible places for the QuickBook sources and compile
139 # from scratch using the default toolset.
140 #
141 # As a last resort we rely on the shell to find 'quickbook'.
142 #
143 class quickbook-binary-generator : generator
144 {
145     import modules path targets quickbook ;
146
147     rule run ( project name ? : property-set : sources * : multiple ? )
148     {
149         quickbook.freeze-config ;
150         # QuickBook invocation command and dependencies.
151         local quickbook-binary = [ modules.peek quickbook : .quickbook-binary ] ;
152         local quickbook-binary-dependencies ;
153
154         if ! $(quickbook-binary)
155         {
156             # If the QuickBook source directory was found, mark its main target
157             # as a dependency for the current project. Otherwise, try to find
158             # 'quickbook' in user's PATH
159             local quickbook-dir = [ modules.peek quickbook : .quickbook-dir ] ;
160             if $(quickbook-dir)
161             {
162                 # Get the main-target in QuickBook directory.
163                 local quickbook-main-target = [ targets.resolve-reference $(quickbook-dir) : $(project) ] ;
164
165                 # The first element are actual targets, the second are
166                 # properties found in target-id. We do not care about these
167                 # since we have passed the id ourselves.
168                 quickbook-main-target =
169                     [ $(quickbook-main-target[1]).main-target quickbook ] ;
170
171                 quickbook-binary-dependencies =
172                     [ $(quickbook-main-target).generate [ $(property-set).propagated ] ] ;
173
174                 # Ignore usage-requirements returned as first element.
175                 quickbook-binary-dependencies = $(quickbook-binary-dependencies[2-]) ;
176
177                 # Some toolsets generate extra targets (e.g. RSP). We must mark
178                 # all targets as dependencies for the project, but we will only
179                 # use the EXE target for quickbook-to-boostbook translation.
180                 for local target in $(quickbook-binary-dependencies)
181                 {
182                     if [ $(target).type ] = EXE
183                     {
184                         quickbook-binary = 
185                             [ path.native 
186                                 [ path.join
187                                     [ $(target).path ]
188                                     [ $(target).name ]
189                                 ]
190                             ] ;
191                     }
192                 }
193             }
194         }
195
196         # Add $(quickbook-binary-dependencies) as a dependency of the current
197         # project and set it as the <quickbook-binary> feature for the
198         # quickbook-to-boostbook rule, below.
199         property-set = [ $(property-set).add-raw
200             <dependency>$(quickbook-binary-dependencies)
201             <quickbook-binary>$(quickbook-binary)
202             <quickbook-binary-dependencies>$(quickbook-binary-dependencies)
203         ] ;
204
205         return [ generator.run $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
206     }
207 }
208
209
210 # Define a scanner for tracking QBK include dependencies.
211 #
212 class qbk-scanner : common-scanner
213 {
214     rule pattern ( )
215     {
216         return "\\[[ ]*include[ ]+([^]]+)\\]" 
217         "\\[[ ]*include:[a-zA-Z0-9_]+[ ]+([^]]+)\\]" 
218         "\\[[ ]*import[ ]+([^]]+)\\]" ;
219     }
220 }
221
222
223 scanner.register qbk-scanner : include ;
224
225 type.set-scanner QUICKBOOK : qbk-scanner ;
226
227
228 # Initialization of toolset.
229 #
230 # Parameters:
231 #   command ?    -> path to QuickBook executable.
232 #
233 # When command is not supplied toolset will search for QuickBook directory and
234 # compile the executable from source. If that fails we still search the path for
235 # 'quickbook'.
236 #
237 rule init (
238         command ?   # path to the QuickBook executable.
239     )
240 {
241     if $(command)
242     {
243         if $(.config-frozen)
244         {
245             errors.user-error "quickbook: configuration cannot be changed after it has been used." ;
246         }
247         .command = $(command) ;
248     }
249 }
250
251 rule freeze-config ( )
252 {
253     if ! $(.config-frozen)
254     {
255         .config-frozen = true ;
256
257         # QuickBook invocation command and dependencies.
258
259         .quickbook-binary = $(.command) ;
260
261         if $(.quickbook-binary)
262         {
263             # Use user-supplied command.
264             .quickbook-binary = [ common.get-invocation-command quickbook : quickbook : $(.quickbook-binary) ] ;
265         }
266         else
267         {
268             # Search for QuickBook sources in sensible places, like
269             #   $(BOOST_ROOT)/tools/quickbook
270             #   $(BOOST_BUILD_PATH)/../../quickbook
271
272             # And build quickbook executable from sources.
273
274             local boost-root = [ modules.peek : BOOST_ROOT ] ;
275             local boost-build-path = [ build-system.location ] ;
276
277             if $(boost-root)
278             {
279                 .quickbook-dir += [ path.join $(boost-root) tools ] ;
280             }
281
282             if $(boost-build-path)
283             {
284                 .quickbook-dir += $(boost-build-path)/../.. ;
285             }
286
287             .quickbook-dir = [ path.glob $(.quickbook-dir) : quickbook ] ;
288
289             # If the QuickBook source directory was found, mark its main target
290             # as a dependency for the current project. Otherwise, try to find
291             # 'quickbook' in user's PATH
292             if $(.quickbook-dir)
293             {
294                 .quickbook-dir = [ path.make $(.quickbook-dir[1]) ] ;
295             }
296             else
297             {
298                 ECHO "QuickBook warning: The path to the quickbook executable was" ;
299                 ECHO "  not provided. Additionally, couldn't find QuickBook" ;
300                 ECHO "  sources searching in" ;
301                 ECHO "    * BOOST_ROOT/tools/quickbook" ;
302                 ECHO "    * BOOST_BUILD_PATH/../../quickbook" ;
303                 ECHO "  Will now try to find a precompiled executable by searching" ;
304                 ECHO "  the PATH for 'quickbook'." ;
305                 ECHO "  To disable this warning in the future, or to completely" ;
306                 ECHO "  avoid compilation of quickbook, you can explicitly set the" ;
307                 ECHO "  path to a quickbook executable command in user-config.jam" ;
308                 ECHO "  or site-config.jam with the call" ;
309                 ECHO "    using quickbook : /path/to/quickbook ;" ;
310
311                 # As a last resort, search for 'quickbook' command in path. Note
312                 # that even if the 'quickbook' command is not found,
313                 # get-invocation-command will still return 'quickbook' and might
314                 # generate an error while generating the virtual-target.
315
316                 .quickbook-binary = [ common.get-invocation-command quickbook : quickbook ] ;
317             }
318         }
319     }
320 }
321
322
323 generators.register [ new quickbook-binary-generator quickbook.quickbook-to-boostbook : QUICKBOOK : XML ] ;
324
325
326 # <quickbook-binary> shell command to run QuickBook
327 # <quickbook-binary-dependencies> targets to build QuickBook from sources.
328 toolset.flags quickbook.quickbook-to-boostbook QB-COMMAND      <quickbook-binary> ;
329 toolset.flags quickbook.quickbook-to-boostbook QB-DEPENDENCIES <quickbook-binary-dependencies> ;
330 toolset.flags quickbook.quickbook-to-boostbook INCLUDES        <include> ;
331 toolset.flags quickbook.quickbook-to-boostbook QB-DEFINES      <quickbook-define> ;
332 toolset.flags quickbook.quickbook-to-boostbook QB-INDENT       <quickbook-indent> ;
333 toolset.flags quickbook.quickbook-to-boostbook QB-LINE-WIDTH   <quickbook-line-width> ;
334 toolset.flags quickbook.quickbook-to-boostbook QB-OPTIONS      <quickbook-strict-mode>on : --strict ;
335
336
337 rule quickbook-to-boostbook ( target : source : properties * )
338 {
339     # Signal dependency of quickbook sources on <quickbook-binary-dependencies>
340     # upon invocation of quickbook-to-boostbook.
341     DEPENDS $(target) : [ on $(target) return $(QB-DEPENDENCIES) ] ;
342 }
343
344
345 actions quickbook-to-boostbook
346 {
347     "$(QB-COMMAND)" -I"$(INCLUDES)" -D"$(QB-DEFINES)" --indent="$(QB-INDENT)" --linewidth="$(QB-LINE-WIDTH)" $(QB-OPTIONS) --output-file="$(1)" "$(2)"
348 }
349
350
351 # Declare a main target to convert a quickbook source into a boostbook XML file.
352 #
353 rule to-boostbook ( target-name : sources * : requirements * : default-build * )
354
355   local project = [ project.current ] ;
356     
357   targets.main-target-alternative 
358     [ new typed-target $(target-name) : $(project) : XML
359         : [ targets.main-target-sources $(sources) : $(target-name) ] 
360         : [ targets.main-target-requirements $(requirements) : $(project) ]
361         : [ targets.main-target-default-build $(default-build) : $(project) ] 
362     ] ;
363 }