Boost logo

Boost-Commit :

From: srajko_at_[hidden]
Date: 2007-05-29 16:47:43


Author: srajko
Date: 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
New Revision: 4354
URL: http://svn.boost.org/trac/boost/changeset/4354

Log:
add support for template merges

Added:
   sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide/build.vcproj.py
      - copied, changed from r4349, /sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide/build.vcproj
Removed:
   sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide/build.vcproj
Text files modified:
   sandbox/template_under_construction/file_template/libs/file_template/doc/Jamfile.v2 | 6
   sandbox/template_under_construction/file_template/libs/file_template/doc/file_template.qbk | 95 +++++++++
   sandbox/template_under_construction/file_template/libs/file_template/doc/sandbox.qbk | 41 +---
   sandbox/template_under_construction/file_template/libs/file_template/doc/templates.qbk | 356 ++++++++++++++++++++++++++++++--------
   sandbox/template_under_construction/make_template.py | 370 ++++++++++++++++++++++++++++++---------
   sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide.py | 24 ++
   sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide/build.vcproj.py | 31 +-
   sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/xcodeide.py | 2
   sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/doc/$template_library$.qbk.py | 31 +-
   sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/doc/Jamfile.v2.py | 50 +++-
   sandbox/template_under_construction/sandbox/sandbox.py | 14
   11 files changed, 755 insertions(+), 265 deletions(-)

Modified: sandbox/template_under_construction/file_template/libs/file_template/doc/Jamfile.v2
==============================================================================
--- sandbox/template_under_construction/file_template/libs/file_template/doc/Jamfile.v2 (original)
+++ sandbox/template_under_construction/file_template/libs/file_template/doc/Jamfile.v2 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -18,7 +18,7 @@
    :
         <xsl:param>chunk.first.sections=1
         <xsl:param>chunk.section.depth=3
- <xsl:param>toc.section.depth=3
- <xsl:param>toc.max.depth=3
- <xsl:param>generate.section.toc.level=3
+ <xsl:param>toc.section.depth=4
+ <xsl:param>toc.max.depth=4
+ <xsl:param>generate.section.toc.level=2
     ;
\ No newline at end of file

Modified: sandbox/template_under_construction/file_template/libs/file_template/doc/file_template.qbk
==============================================================================
--- sandbox/template_under_construction/file_template/libs/file_template/doc/file_template.qbk (original)
+++ sandbox/template_under_construction/file_template/libs/file_template/doc/file_template.qbk 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -1,6 +1,6 @@
 [library FileTemplate
     [quickbook 1.4]
- [version 0.9]
+ [version 0.91]
     [authors [Rajko, Stjepan]]
     [copyright 2007 Stjepan Rajko]
     [purpose generates file and directory trees from templates]
@@ -11,18 +11,95 @@
     ]
 ]
 
-
-FileTemplate is a template processor for files and directories. It provides a basic
-framework which makes producing templated dile/directory trees relatively easy.
-The philosophy of the framework is that simple things should be simple, and more
-complicated things should be doable relatively simply. By being implemented in
-Python, and allowing template-specific python scripts in the template, FileTemplate
-has a pretty good degree of flexibility.
+[def template_object_ref [link filetemplate.templates.reference.template template object]]
+[def results_object_ref [link filetemplate.templates.reference.results results object]]
+[def python_file_ref [link filetemplate.templates.phases.processing.python_files
+ python generated file]]
+[def python_files_ref [link filetemplate.templates.phases.processing.python_files
+ python generated files]]
+[def python_script_ref [link filetemplate.templates.phases.examination.template_script template script]]
+[def python_scripts_ref [link filetemplate.templates.phases.examination.template_script template scripts]]
+[def sandbox_template_ref [link filetemplate.sandbox sandbox template]]
+[def template_option_ref [link filetemplate.templates.options FileTemplate option]]
+[def template_options_ref [link filetemplate.templates.options FileTemplate options]]
+[def sandbox_option_ref [link filetemplate.sandbox.options sandbox option]]
+[def sandbox_options_ref [link filetemplate.sandbox.options sandbox options]]
+[def substitution_template_ref [link filetemplate.templates.substitutions substitution template]]
+[def substitution_templates_ref [link filetemplate.templates.substitutions substitution templates]]
+[def invocation_phase_ref [link filetemplate.templates.phases.invocation invocation phase]]
+[def template_merge_ref [link filetemplate.templates.merges template merge]]
+[def template_merges_ref [link filetemplate.templates.merges template merges]]
+[def command_line_ref [link filetemplate.templates.phases.invocation.command_line command line]]
+[python]
+
+FileTemplate is a template processor for files and directories. This could be useful in the
+following scenarios:
+
+* There is a generic starting point for a certain type of project. The user can specify
+information to fine-tune their particular starting point.
+* The user would like to integrate their existing files, and integrate them into a starting
+point for a new project. The user can perform a template_merge_ref between the template
+for the new project, and the existing files (acting as a second template).
+
+FileTemplate provides a basic
+framework which makes producing templated file/directory trees relatively easy.
+The philosophy behind the development of the framework is that simple things should be simple,
+and more complicated things should be doable. By being implemented in
+Python, and allowing template-specific python scripts to be placed in a template, FileTemplate
+provides a reasonable degree of flexibility.
 
 FileTemplate is being developed for construction of seed projects for the Boost Sandbox.
-The [link filetemplate.sandbox sandbox] template, which is used for this purpose,
+The sandbox_template_ref, which is used for this purpose,
 is currently the only template developed using FileTemplate.
 
+[note FileTemplate is in no way an official part or tool of the Boost libraries.]
+
+Here are some examples of what you can do with FileTemplate, and how you would
+go about doing it:
+
+[table Examples of things you can do with the sandbox template
+ [[To accomplish this:][You can do this:]]
+ [
+ [Use the =sandbox= template to start a new Boost sandbox library (you will be prompted for whatever the
+ template processor needs to know)]
+ [Run: [^python make_template.py sandbox]
+
+ =sandbox= specifies the root directory of the template.]
+ ][
+ [Use the =sandbox= template and specify everything from the command line]
+ [Run: [^python make_template.py destination\=/boost_sandbox sandbox library\=my_new_library "author\=John Doe"]
+
+ =destination= is a global template_option_ref, and specifies where the result is constructed.
+ =library= and =author= are sandbox_options_ref.]
+ ][
+ [Tell the =sandbox= template to also construct MSVC 8.0 IDE projects (which
+ provide access to files and =bjam= builds)]
+ [Run: [^ python make_template.py sandbox vc8ide\=y]]
+ ][
+ [Combine the =sandbox= template with your existing code (the created documentation build files and MSVC IDE projects will include your existing files)]
+ [Run: [^ python make_template.py sandbox library\=boostified_library vc8ide=y /old_library/include/old_library into\=boostified_library/boost/boostified_library]
+
+ Here, the template processor is performing a template_merge_ref.
+ The existing source tree =/old_library/include/old_library= is used as an additional template.
+ It is given the option =into\=boostified_library/boost/boostified_library=, which specifies where the content
+ should go in the built result.]
+ ]
+]
+
+[table Examples of things you can do if you're designing your own template
+ [[To accomplish this:][You can do this:]]
+ [
+ [Design a template =simple= which is meant to be copied verbatim]
+ [Create a directory called =simple=, and place the desired files and directories inside.]
+ ][
+ [Design a template in which =$template_whatever$= inside template files is substituted into a user-specified value]
+ [Place inside the template directory a python_script_ref which uses the template_object_ref to get the user-specified value and set up the substitution.]
+ ][
+ [Create a template for file =random.txt= whose content requires more than simple substitutions]
+ [In place of =random.txt= create a python_file_ref =random.txt.py= which constructs the content and submits it to the template_object_ref.]
+ ]
+]
+
 * [link filetemplate.sandbox Learn more about using the sandbox template].
 * [link filetemplate.templates
  Learn more about the FileTemplate system, using and and developing templates].

Modified: sandbox/template_under_construction/file_template/libs/file_template/doc/sandbox.qbk
==============================================================================
--- sandbox/template_under_construction/file_template/libs/file_template/doc/sandbox.qbk (original)
+++ sandbox/template_under_construction/file_template/libs/file_template/doc/sandbox.qbk 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -17,7 +17,7 @@
 =sandbox/template-under-construction= directory and execute:
 
 [pre
- >python make_template.py template=sandbox.py
+ >python make_template.py sandbox
 ]
 
 The script will ask you some questions and create a seed project with the
@@ -42,13 +42,13 @@
 
 Second, you will need to download some additional tools to build the documentation.
 Instructions for this part can be found in the
-[@http://www.boost.org/doc/html/boostbook.html Boostbook documentation].
+[@http://www.boost.org/doc/html/boostbook.html Boostbook documentation]
+and the
+[@http://www.boost-consulting.com/boost/tools/quickbook/doc/html/quickbook/install.html
+Quickbook documentation].
 The projects generated by file_template rely on xsltproc,
 DocBook XSL and DTD distributions, and Doxygen. The sandbox template does not currently use
-Apache FOP. Here are some of the download links for your convenience:
-
-* [@http://sourceforge.net/project/showfiles.php?group_id=21935#files docbook xsl]
-* [@http://www.stack.nl/~dimitri/doxygen/download.html doxygen]
+Apache FOP.
 
 [caution Make sure you download docbook-xsl and not docbook5-xsl.]
 
@@ -57,16 +57,9 @@
 the directions in the [@http://svn.boost.org/trac/boost/wiki/BoostSubversion Boost subversion wiki].
 
 Once you have all this in place, go to the template-under-construction folder of the sandbox.
-Run the make_template.py script, and follow the instructions. For example,
-the project used to build this documentation was created as follows:
-
-[python]
-
- python make_template.py
- library name: (e.g., something_new): sandbox_template
- library author[s]: (e.g., Yours Truly[,Yours D. NotTruly]): Stjepan Rajko
+Run the make_template.py script, and follow the instructions.
 
-You can also use the command line to specify the options.
+You can also use the command_line_ref line to specify the options.
 
 Some other information that might come in handy as you start working on your project:
 
@@ -93,14 +86,14 @@
     [[vc8ide][Specifies whether the IDE projects for MSVC 8.0 should be generated][n]]
 ]
 
-For example, this project was started using the following command line:
+For example, this project could have been started using the following command line:
 
 [pre
- python make_template.py template=sandbox.py library=file_template "author=Stjepan Rajko" docs=qb vc8ide=y
+ python make_template.py sandbox library=file_template "author=Stjepan Rajko" docs=qb vc8ide=y
 ]
 
-For more information about template options, see the
-[link filetemplate.templates.options FileTemplate options] documentation.
+For more information about template options, and for other options provided
+by FileTemplate, see the template_options_ref documentation.
 
 [endsect]
 
@@ -161,17 +154,7 @@
 It might be better to perform a clean followed by a build. However, this has the downside
 of not being to be able to access =bjam -a= from the IDE.
 
-* The template directory structure should be revised. Instead of invoking the template
-processor by specifying the template script, perhaps it would be better to specify the
-template root directory - which can hold the template script if one is necessary,
-and the actual template tree.
-
-* Destination directory should be specifiable.
-
 * Since the template processor now supports file-specific substitution templates,
   most of the copyright templates should just be called $template\_copyright$.
 
-* the user-specified library name should be given in all lowercase - this should
- be enforced.
-
 [endsect]

Modified: sandbox/template_under_construction/file_template/libs/file_template/doc/templates.qbk
==============================================================================
--- sandbox/template_under_construction/file_template/libs/file_template/doc/templates.qbk (original)
+++ sandbox/template_under_construction/file_template/libs/file_template/doc/templates.qbk 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -8,26 +8,56 @@
 [link filetemplate.templates.phases processing phases] documentation.
 
 To learn about creating new templates or extending existing templates,
-you should also read about
-[link filetemplate.templates.options options] and
-[link filetemplate.templates.substitutions substitution templates]
-
+you should also read about template_options_ref and
+substitution_templates_ref.
 
 [section:phases Processing phases]
 
 [section:invocation Invocation]
-The template processor first initializes [link filetemplate.templates.reference template class]
-object, which processes the template and can be used by the python scripts present
-in the template to customize the behavior of the template.
-
-Then, the template processor will invoke the startup script for the template,
-which is specified through the =template= [link filetemplate.templates.options option].
-The startup script gives the template processor any information
-it needs to know, and sets up
-[link filetemplate.templates.substitutions substitution templates] if applicable.
+
+[section:command_line Command line]
+
+The template processor begins by processing the command line for template_options_ref.
+The options are specified via [~option=value] arguments. In simple cases, such
+as when using only one template, the ordering of the command line arguments should not
+affect the output. However, when multiple templates are used symoultaneously for a
+template_merge_ref, the order matters. The order is as follows.
+
+# Global template_options_ref can be specified at any point, but are recommended to be
+placed at the beginning for consistency.
+# template_options_ref that should be applied to all templates are specified before any
+template is listed.
+# template_options_ref that should be applied to an individual template only should be
+specified after listing the template (and before the next template is listed).
+
+[tip The template can be specified without explicitly using =template\==. E.g., you can run
+[^ python make_template.py sandbox] instead of [^ python make_template.py template=sandbox]]
+
+The following examples illustrates this structure:
+
+[table Command line structure examples:
+ [[invocation][global options][options for all templates][first template][second template]]
+
+ [[=python make_template.py=][][][sandbox][]]
+
+ [[=python make_template.py=][[^ destination=/boost_sandbox]]
+ []
+ [[^ sandbox library=boostified_library vc8ide\=y ignore\=$template_library$/boost]]
+ [ /old_library/include/old_library into\=boostified_library/boost/boostified_library]]
+]
+
+Some options, such as =ignore=, can be specified multiple times.
+
+[endsect]
+
+After processing the command line, or prompting the user if necessary, the template
+processor will initialize
+each template_object_ref (which processes the template and can be used by any in-template
+python_script_ref to customize the behavior of the template)
+and the global template_options_ref.
 
 The template processor will then
-[link filetemplate.templates.phases examine the template tree].
+[link filetemplate.templates.phases.examination examine the template tree].
 
 [endsect]
 
@@ -38,19 +68,20 @@
 the names of all directories and files located in the tree, which will then
 be copied / processed in the next phase.
 
+[section:template_script Template scripts]
+
 To customize what information is to be copied, and to specify additional
-customization possibilites (e.g., via [link filetemplate.templates.substitutions
-substitution templates]),
+customization possibilites (e.g., via substitution_templates_ref),
 template scripts may be inserted in the template tree.
 
 Template scripts are python files which begin with the following text on their first line:
-[python]
 
     # template script
 
 Every script found during the transversal will be executed. The script can
-interact with the template processor through the
-[link filetemplate.templates.reference template object].
+interact with the template processor through the template_object_ref.
+
+[endsect]
 
 [endsect]
 
@@ -62,18 +93,19 @@
 A file for which no specific substitution templates are specified will be copied verbatim.
 
 [h4 Processed file content]
-A file for which at least one specific substitution template is specified will be processed
-for substitution templates and specific templates.
+A file for which at least one specific substitution_template_ref is specified will be processed
+for global substitution_templates_ref and specific substitution_templates_ref.
 
-[h4 Python generated file content]
+[section:python_file Python generated files]
 A file of the name /filename/=.py= can be used to generate the file /filename/. To do so,
 it must begin with
 
     # template file
     
 When the script generates the content, it supplies it to the template processor via the
-`template.submit_content(content)` command (see the
-[link filetemplate.templates.reference template object] reference).
+`template.submit_content(content)` command (see the template_object_ref reference).
+
+[endsect]
 
 [endsect]
 
@@ -82,65 +114,165 @@
 [section:options Options]
 
 Options are used to fine-tune the behavior of the FileTemplate template processor as well
-as the behavior of the template. The following options are used by the template processor
-(specific templates may use additional options):
+as the behavior of the template.
+
+[h4 Global options]
+/Global options/ govern the behavior of the template processor.
+
+[table Global options
+ [[option][desctiption][valid values][default value]]
+
+ [[destination][Destination directory where the results will be constructed.]
+ [valid directory path (will be created if it does not exist)][current directory]]
+
+]
+
+[h4 Template options]
+/Template options/ can be used to specify how a particular template is processed.
+Templates may use additional, template-specific options, as is the case with sandbox_options_ref.
 
-[table Options used by the FileTemplate template processor
+[table Template options
     [[option][desctiption][valid values][default value]]
- [[template][Template-specific script][valid filename][]]
- [[erase][Determines whether the template processor should erase the destination
- directory tree if it already exists][y/n]]
+ [[template][Template directory][valid directory][]]
+
+ [[into][Determines where the output of the template will be placed inside the resulting tree]
+ [valid directoy in resulting tree][root of the resulting tree]]
+
+ [[ignore][Ignores a directory of the source template tree][directory in source template tree]
+ []]
+
+ [/ [[erase][Determines whether the template processor should erase the destination
+ directory tree if it already exists][y/n]]]
 ]
 
-Options can be specified at command-line via [~option=value] arguments. If an option
-is not specified, and it has no default value, the user will be prompted for the value.
+Options can be specified using the command line. See the invocation_phase_ref reference
+for more information. If an option
+is not specified in the command line, and it has no default value, the user will be prompted for the value.
 
 This is the output of a sample session:
 
 [pre
 
->python make_template.py [*template=sandbox.py] [*library=my_library]
-/--------------------
-| Executing template file sandbox.py...
-/
-/--------------------
-| Processing Boost Sandbox template.
-/
-[*author: [~John Doe]]
-/--------------------
-| Examining the template project tree...
-/
-$template_library$
-$template_library$\boost
-$template_library$\boost\$template_library$
-$template_library$\libs
-$template_library$\libs\$template_library$
-$template_library$\libs\$template_library$\build
-$template_library$\libs\$template_library$\doc
-$template_library$\libs\$template_library$\doc\html
-$template_library$\libs\$template_library$\doc\html\images
-$template_library$\libs\$template_library$\example
-$template_library$\libs\$template_library$\src
-$template_library$\libs\$template_library$\test
-Directory my_library already exists.
-[*erase: Erase it (please make sure you want to erase the entire directory tree rooted at my_library)? \[y/n\] [~y]]
-/--------------------
-| Erasing...
-/
-/--------------------
+python.exe make_template.py [* sandbox]
+/-------------------------------------------
+| Processing template sandbox with options:
++---
+|| {'ignore': set(\[\]), 'template': 'sandbox'}
+|\/-------------------------------------------
+|| Examining the template project tree...
+|+---
+|||
+||\/-------------------------------------------
+||| Welcome to the Boost Sandbox template.
+||+---
+||\/-------------------------------------------
+||| [* Enter value for option library:]
+||+---
+||| [* (all lowercase, use underscores to separate words, e.g. "my_library"): my_library]
+||\/-------------------------------------------
+||| [* Enter value for option author:
+||+---
+||| (comma separated, no spaces outside names, e.g., "My Name,Notmy R. Name": Stjepan Rajko]
+||| $template_library$
+||| $template_library$\/boost
+||| $template_library$\/boost\/$template_library$
+||| $template_library$\/libs
+||| $template_library$\/libs\/$template_library$
+||| $template_library$\/libs\/$template_library$\/build
+||| $template_library$\/libs\/$template_library$\/test
+||| $template_library$\/libs\/$template_library$\/doc
+||| $template_library$\/libs\/$template_library$\/doc\html
+||| $template_library$\/libs\/$template_library$\/doc\/html\/images
+||| $template_library$\/libs\/$template_library$\/src
+||| $template_library$\/libs\/$template_library$\/example
+\/-------------------------------------------
+| Preparing destination tree...
++---
+|\/-------------------------------------------
+|| Directories:
+|+---
+|| my_library
+|| my_library\/boost
+|| my_library\/libs
+|| my_library\/boost\/my_library
+|| my_library\/libs\/my_library
+|| my_library\/libs\/my_library\/build
+|| my_library\/libs\/my_library\/test
+|| my_library\/libs\/my_library\/doc
+|| my_library\/libs\/my_library\/src
+|| my_library\/libs\/my_library\/example
+|| my_library\/libs\/my_library\/doc\/html
+|| my_library\/libs\/my_library\/doc\/html\/images
+|\/-------------------------------------------
+|| Files:
+|+---
+|| my_library\/LICENSE_1_0.txt
+|| my_library\/boost-build.jam
+|| my_library\/Jamfile.v2
+|| my_library\/project-root.jam
+|| my_library\/boost\/my_library.hpp
+|| my_library\/boost\/my_library\/my_library.hpp
+|| my_library\/libs\/my_library\/test\/test.cpp
+|| my_library\/libs\/my_library\/test\/Jamfile.v2
+|| my_library\/libs\/my_library\/doc\/html\/reference.css
+|| my_library\/libs\/my_library\/doc\/html\/boostbook.css
+|| my_library\/libs\/my_library\/doc\/html\/images\/prev.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/tip.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/important.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/next.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/toc-minus.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/draft.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/caution.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/Thumbs.db
+|| my_library\/libs\/my_library\/doc\/html\/images\/up.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/note.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/warning.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/toc-plus.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/blank.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/home.png
+|| my_library\/libs\/my_library\/doc\/html\/images\/toc-blank.png
+|| my_library\/libs\/my_library\/example\/example.cpp
+|| my_library\/libs\/my_library\/example\/Jamfile.v2
+|| my_library\/libs\/my_library\/doc\/my_library.qbk
+|| my_library\/libs\/my_library\/doc\/Jamfile.v2
+\/-------------------------------------------
 | Creating file tree from template...
-/
-my_library\boost
-my_library\libs
-my_library\boost\my_library
-my_library\libs\my_library
-my_library\libs\my_library\build
-my_library\libs\my_library\doc
-my_library\libs\my_library\example
-my_library\libs\my_library\src
-my_library\libs\my_library\test
-my_library\libs\my_library\doc\html
-my_library\libs\my_library\doc\html\images
++---
+|/-------------------------------------------
+|| Python files...
+|+---
+||| .\/my_library\/libs\/my_library\/doc\/my_library.qbk
+||| .\/my_library\/libs\/my_library\/doc\/Jamfile.v2
+|\/-------------------------------------------
+|| Files...
+|+---
+||| .\/my_library\/LICENSE_1_0.txt
+||| .\/my_library\/boost-build.jam
+||| .\/my_library\/Jamfile.v2
+||| .\/my_library\/project-root.jam
+||| .\/my_library\/boost\/my_library.hpp
+||| .\/my_library\/boost\/my_library\/my_library.hpp
+||| .\/my_library\/libs\/my_library\/test\/test.cpp
+||| .\/my_library\/libs\/my_library\/test\/Jamfile.v2
+||| .\/my_library\/libs\/my_library\/doc\/html\/reference.css
+||| .\/my_library\/libs\/my_library\/doc\/html\/boostbook.css
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/prev.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/tip.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/important.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/next.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/toc-minus.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/draft.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/caution.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/Thumbs.db
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/up.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/note.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/warning.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/toc-plus.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/blank.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/home.png
+||| .\/my_library\/libs\/my_library\/doc\/html\/images\/toc-blank.png
+||| .\/my_library\/libs\/my_library\/example\/example.cpp
+||| .\/my_library\/libs\/my_library\/example\/Jamfile.v2
 ]
 [endsect]
 
@@ -178,7 +310,19 @@
 
 [endsect]
 
-[section:reference Template object reference]
+[section:merges Template merges]
+
+FileTemplate can be used to merge results created by several templates. If a template uses
+the results_object_ref to customize its output based on files created by all processed templates,
+this can be used to seamlessly integrate additional files in the template results.
+
+The sandbox_template_ref uses this to allow additional files (e.g., existing source code) to be
+integrated in the newly created Boost sandbox library project.
+
+[endsect]
+
+[section:reference Reference]
+[section:template Template object]
 The template object contains several functions which can be used from template
 scripts to customize template behavior.
 
@@ -200,11 +344,11 @@
 
     template.name_replacement('$template_library$', library_name)
 
-To set up a specific substitution template:
+To set up a specific substitution_template_ref:
 
     template.content_replacement(['.hpp', '.cpp'], '$template_created$', '// Created in $template_year$')
 
-To set up a general substitution template:
+To set up a general substitution_template_ref:
 
     template.all_content_replacement('$template_year$', str(time.localtime().tm_year))
 
@@ -224,6 +368,64 @@
     Yes it is."""
     
     template.submit_content(content)
+
+or
+
+ template.append_content("""
+ This is a script-generated file.""")
+ template.append_content("""
+ Yes it is.""")
+
+[endsect]
+
+[section:results Results object]
+
+The results object holds information about the files and directories which will
+be generated by the template processor. It includes files and directories from
+*all* templates being processed, and can therefore be used to allow seamless
+integration of templates.
+
+For example, if a template includes a file whose
+contents depend on the directory tree below a certain directory,
+you can =walk= the results object and extract the directory tree.
+The following example does so to include all non-detail include
+directories for the sandbox_template_ref:
+
+ doxy_source_files = list()
+ for root, dirs, files in results.walk(
+ # we want the returned root to be relative to $template_library$
+ template.replace_name('$template_library$'),
+ # and want to walk the boost/$template_library$ directory underneath that
+ template.replace_name('boost/$template_library$')):
+ if os.path.basename(root) != 'detail':
+ doxy_source_files.append(
+ template.replace_name(os.path.join(os.path.join('../../..',
+ root), '*.hpp').replace('\\','/')))
+
+A similar example uses the =files_in= and =directories_in= functions of the
+result object to construct the list of files and filters for a MSVC IDE:
+
+ def vc_list_files(level, output_base, destination_base, directory):
+ tabs = ''.join(['\t' for x in range(level)])
+ output_base_directory = os.path.join(output_base, directory)
+ destination_base_directory = os.path.join(destination_base, directory)
+ for name in results.files_in(destination_base_directory):
+ template.append_content("""
+ """ + tabs + """<File
+ """ + tabs + '\tRelativePath="'+os.path.join(output_base_directory,name)+""""
+ """ + tabs + """\t>
+ """ + tabs + """</File>""")
+
+ for name in results.directories_in(destination_base_directory):
+ template.append_content("""
+ """ + tabs + """<Filter
+ """ + tabs + '\tName="'+name+""""
+ """ + tabs + """\t>""")
+ vc_list_files(level+1, output_base_directory, destination_base_directory, name)
+ template.append_content("""
+ """ + tabs + """</Filter>""")
+
+[endsect]
 
 [endsect]
 
@@ -240,7 +442,9 @@
 in a directory other than the same directory as the script.
 This allows templates configured in a more centralized way.
 
+[/
 * The =erase= option should require the user to type =erase= for the value
 instead of =y=, just to be safe.
+]
 
 [endsect]
\ No newline at end of file

Modified: sandbox/template_under_construction/make_template.py
==============================================================================
--- sandbox/template_under_construction/make_template.py (original)
+++ sandbox/template_under_construction/make_template.py 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -12,40 +12,94 @@
 import re
 
 global template
+global log
+global options
+global results
+
+class Log(object):
+ def __init__(self):
+ self.__level__ = 0
+
+ def __prefix__(self):
+ return ''.join('|' for x in range(self.__level__))
+
+ def __print__(self, string):
+ print self.__prefix__() + string
+
+ def message(self, string):
+ self.__print__('/-------------------------------------------')
+ self.__print__('| ' + string)
+ self.__print__('+---')
+
+ def phase(self, string):
+ self.message(string)
+ self.__level__ += 1
+
+ def end(self):
+ self.__level__ -= 1
+
+ def line(self, string):
+ self.__print__('| ' + string)
+
+ def raw(self, string):
+ return raw_input(self.__prefix__() + '| ' + string)
+
+
+log = Log()
 
 # The Options class holds user-specified options.
 class Options(object):
+
+ # initializes the object
+ # initializes self.options
+ # initializes common regular expressions used for option verification
     def __init__(self):
+
+ # initialize self.options
         self.options = dict()
- for arg in sys.argv[1:]:
- option, eq, val = arg.partition('=')
- self.options[option] = val
+ self.options['ignore']=set()
+
+ # initialize common regular expressions
         self.any = re.compile(r'.*\Z')
         self.boolean = re.compile(r'[yn]\Z')
         self.alnum = re.compile(r'\w+\Z')
+ self.alnum_lowercase = re.compile(r'[a-z0-9_]+\Z')
 
+
+ # raises an exception if the string doesn't match the regular expression
+ # returns string
     def verify (self, string, regexp):
         if regexp != None and not regexp.match(string):
             raise NameError, string + ' does not match ' + regexp.pattern
         return string
 
+
+ # makes the value of the option to be value, or prompts if value==None
+ # value is set to the new value of the option and returned
     def make(self, option, value, prompt=None):
         if value==None:
- if prompt==None:
- prompt_text = option + ': '
+ if (option != None):
+ log.message('Enter value for option ' + option + ':')
             else:
- prompt_text = option + ': ' + prompt
- value = raw_input(prompt_text)
+ log.message('Enter value: ')
+ if prompt==None:
+ prompt = option + ': '
+ value = log.raw(prompt)
 
- self.options[option] = value
+ if option != None:
+ self.options[option] = value
         return value
 
+
+ # returns the value of an option. the user will be prompted if necessary.
     def get(self, option, regexp=None, default=None, prompt=None):
         if self.options.has_key(option):
             # option has already been set
             return self.verify(self.options[option], regexp)
         return self.verify(self.make(option, default, prompt), regexp)
 
+
+ # returns the value (True/False) of a boolean option.
     def get_boolean(self, option, default_bool=None, prompt=None):
         if default_bool != None:
             if default_bool:
@@ -57,6 +111,7 @@
         value = self.get(option, self.boolean, default, prompt)
         return value=='y'
 
+
 # The Replacement class models a template replacement,
 # either for file names or file content.
 class Replacement(object):
@@ -66,6 +121,7 @@
     def replace(self, string):
         return string.replace(self.template, self.value)
 
+
 # Replacements is a collection of Replacement objects.
 class Replacements(list):
     def replace(self, string):
@@ -73,6 +129,7 @@
             string = item.replace(string)
         return string
 
+
 # FileSpecificReplacement associates file extensions with a replacement
 class FileSpecificReplacement(Replacement):
     def __init__(self, extensions, key, value):
@@ -121,6 +178,10 @@
 # such as all of its options and replacements.
 class Template(object):
     def __init__(self):
+ self.__file_list__ = list()
+ self.__directory_list__ = list()
+ self.__python_list__ = list()
+
         self.template_dir = ''
         self.options = Options()
         self.content_replacements = ContentReplacements()
@@ -135,13 +196,19 @@
     def submit_content(self, content):
         self.__content__ = content
 
- def process_content(self, file_name, python=False):
+ def append_content(self, content):
+ self.__content__ += content
+
+ def process_content(self, name, python=False):
+ file_name = os.path.join(self.directory, name)
         if python:
             self.__content__ = ''
+ global template
+ template = self
             execfile(file_name + '.py')
             content = self.__content__
         else:
- if not template.content_replacements.matches(name):
+ if not self.content_replacements.matches(name):
                 return None
             content = self.read_content(file_name)
 
@@ -156,12 +223,7 @@
             content_lines.pop(0)
         content = '\n'.join(content_lines)
                 
- return self.replace_content(file_name, content)
-
- def log_message(self, string):
- print '/--------------------'
- print '| ' + string
- print '/'
+ return self.replace_content(name, content)
 
     def name_replacement(self, key, value):
         self.name_replacements.append(Replacement(key, value))
@@ -176,22 +238,20 @@
     def replace_name(self, name):
         return self.name_replacements.replace(name)
 
- def destination_name(self, name):
- if name.startswith(self.template_root):
- return self.name_replacements.replace(name[len(self.template_root):])
- else:
- return self.name_replacements.replace(name)
-
     def replace_content(self, name, content):
         return self.content_replacements.replace(name, content)
 
- def examine(self, directory):
- self.__file_list__ = list()
- self.__directory_list__ = list()
- self.__python_list__ = list()
 
- for root, dirs, files in os.walk(directory):
- print root
+ def examine(self):
+ self.directory = self.options.get('template')
+ self.into = self.options.get('into',None,'')
+ ignore_set = self.options.get('ignore')
+
+ cwd = os.getcwd()
+ os.chdir(self.directory)
+ for root, dirs, files in os.walk(''):
+ log.line(root)
+
             self.__dirs_clear__ = list()
             self.__files_clear__ = list()
 
@@ -201,13 +261,7 @@
                     content = self.read_content(os.path.join(root, name))
 
                     if content.startswith('# template script'):
- execfile(pathname)
- elif content.startswith('# template module'):
- module_name,py,nothing = name.rpartition('.py')
- sys.path.insert(os.path.abspath(root), 0)
- mod = __import__(module_name, globals(), locals(), [], -1)
- sys.path.remove(os.path.abspath(root))
- mod.do_smt()
+ execfile(pathname)
                     elif content.startswith('# template file'):
                         self.__python_list__.append(pathname[0:len(pathname)-3])
                     else:
@@ -219,13 +273,15 @@
                 self.__file_list__.remove(os.path.join(root, name))
 
             for name in dirs:
- if name.startswith('.'):
+ if name.startswith('.') or \
+ os.path.normpath(os.path.join(root, name)) in ignore_set:
                     self.ignore_subdirectory(name)
             for name in self.__dirs_clear__:
                 dirs.remove(name)
             for name in dirs:
                 self.__directory_list__.append( (os.path.join(root, name)) )
-
+
+ os.chdir(cwd)
         return self.__directory_list__, self.__file_list__, self.__python_list__
 
     def ignore_subdirectory(self, name):
@@ -256,56 +312,200 @@
     fout.write(content)
     fout.close()
 
-# The main processing script.
-
-# template is a global variable accessible by template scripts.
-template = Template()
+class Result(object):
+ def __init__(self, template, source, destination):
+ self.template = template
+ self.source = source
+ self.destination = destination
+ def __str__(self):
+ return str((self.template.options.get('template'), self.source, self.destination))
 
-# We first read a template script file and run it.
-template_file = template.options.get("template", template.options.any)
-template.log_message('Executing template file ' + template_file + '...')
-execfile(template_file)
-
-# We then traverse the template tree and prepare a list of
-# directories and files to be created, and process any found template
-# scripts.
-template.log_message('Examining the template project tree...')
-
-directory_list, file_list, python_list = template.examine(template.template_root + template.template_dir)
-
-project_dir = template.replace_name(template.template_dir)
-
-if os.path.exists(project_dir):
- print 'Directory ' + project_dir + ' already exists.'
- do_erase = template.options.get_boolean(
- 'erase', None, 'Erase it (please make sure you want to erase the entire directory tree rooted at ' + project_dir + ')? [y/n] ')
- if do_erase:
- template.log_message('Erasing...')
- for root, dirs, files in os.walk(project_dir, topdown=False):
- for name in files:
- os.remove(os.path.join(root, name))
- for name in dirs:
- os.rmdir(os.path.join(root, name))
- os.rmdir(project_dir)
+class Results(object):
+ def __init__(self):
+ self.directory_list = list()
+ self.file_list = list()
+ self.python_list = list()
+
+ def append(self, template, directory_list, file_list, python_list):
+ self.__append_list__(self.directory_list, template, directory_list)
+ self.__append_list__(self.file_list, template, file_list)
+ self.__append_list__(self.python_list, template, python_list)
+
+ def __append_list__(self, my_list, template, append_list):
+ for item in append_list:
+ result = Result(template, item, os.path.join(template.into,template.replace_name(item)))
+ my_list.append(result)
+
+ def __mkdir__(self,directory):
+ parent = os.path.dirname(directory)
+ if len(parent) and not os.path.exists(parent):
+ self.__mkdir__(parent)
+ os.mkdir(directory)
+
+ def prepare(self):
+ self.destination = options.get('destination', None, '.')
+ if not os.path.exists(self.destination):
+ self.__mkdir__(self.destination)
+
+ log.message('Directories:')
+ for item in self.directory_list:
+ log.line(item.destination)
+ self.erase(item.destination)
+ for item in self.directory_list:
+ path = os.path.join(self.destination, item.destination)
+ if not os.path.exists(path):
+ self.__mkdir__(path)
+
+ log.message('Files:')
+ for item in self.file_list + self.python_list:
+ log.line(item.destination)
+ self.erase(item.destination)
+
+ def erase(self, name):
+ path = os.path.join(self.destination, name)
+ if os.path.exists(path):
+ log.message(path + ' already exists.')
+ do_erase = options.get_boolean(
+ None, None, 'Erase ' + path + '? [y/n] ')
+ if do_erase:
+ if os.path.isfile(path):
+ os.remove(path)
+ if os.path.isdir(path):
+ log.phase('Erasing...')
+ for root, dirs, files in os.walk(path, topdown=False):
+ for name in files:
+ log.line(os.path.join(root, name))
+ os.remove(os.path.join(root, name))
+ for name in dirs:
+ log.line(os.path.join(root, name))
+ os.rmdir(os.path.join(root, name))
+ log.line(path)
+ os.rmdir(path)
+ log.end()
+
+ def create(self):
+ log.phase('Python files...')
+ for item in self.python_list:
+ new_name = os.path.join(self.destination, item.destination)
+ log.line(new_name)
+ content = item.template.process_content(item.source, True)
+ set_content(new_name, content)
+ log.end()
+
+ log.phase('Files...')
+ for item in self.file_list:
+ template = item.template
+ new_name = os.path.join(self.destination, item.destination)
+ log.line(new_name)
+ content = item.template.process_content(item.source)
+ if content:
+ set_content(new_name, content)
+ else:
+ shutil.copy(os.path.join(item.template.directory, item.source), new_name)
+ log.end()
 
-template.log_message('Creating file tree from template...')
+ def __scan__(self, my_list, directory):
+ result_list = list()
+ result_set = set()
+ for item in my_list:
+ idir, ibase = os.path.split(item.destination)
+ if os.path.normpath(idir) == os.path.normpath(directory) and ibase not in result_set :
+ result_list.append(ibase)
+ result_set.add(ibase)
+ return result_list
+
+ def files_in(self, directory):
+ return self.__scan__(self.file_list + self.python_list, directory)
+
+ def directories_in(self, directory):
+ return self.__scan__(self.directory_list, directory)
+
+ def walk(self, base, directory):
+ # get all files and subdirectories
+ root = os.path.normpath(directory)
+ dirs = self.directories_in(os.path.join(base, directory))
+ files = self.files_in(os.path.join(base, directory))
+ yield root, files, dirs
+ for d in dirs:
+ for root, files, dirs in self.walk(base, os.path.join(directory, d)):
+ yield root, files, dirs
+
+# reads options from the command line
+# command line has the format:
+# python make_template.py ((option=value )* (template))* (option=value)*
+# options specified immediately before a template are for that template only.
+# options specified at the end are for all templates.
+def process_command_line():
+ templates = list()
+ templates.append(Template())
+ index = 0
+
+ global_options = set(['destination'])
+ options = templates[0].options
+
+ for arg in sys.argv[1:]:
+ option, eq, val = arg.partition('=')
+ if len(eq)==0:
+ # templates can be specified without template=
+ val = option
+ option = 'template'
+
+ # option=value sets the option
+ if option=='template':
+ # done with this template, move to the next
+ templates.append(Template())
+ index += 1
+ if option in global_options:
+ options.options[option] = val
+ elif option == 'ignore':
+ templates[index].options.options[option].add(os.path.normpath(val))
+ else:
+ templates[index].options.options[option] = val
 
-os.mkdir(project_dir)
+ templates.pop(0)
 
-for name in directory_list:
- new_name = template.destination_name(name)
- print new_name
- os.mkdir(new_name)
-
-for name in python_list:
- new_name = template.destination_name(name)
- content = template.process_content(name, True)
- set_content(new_name, content)
-
-for name in file_list:
- new_name = template.destination_name(name)
- content = template.process_content(name)
- if content:
- set_content(new_name, content)
+ if not len(templates):
+ # user never specified a template
+ templates.append(Template())
+ templates[0].options.get('template')
     else:
- shutil.copy(name, new_name)
+ # last set of options applies to all templates
+ for t in templates[1:]:
+ for option,value in options.options.iteritems():
+ if not t.options.options.has_key(option):
+ t.options.options[option] = value
+
+ return templates, options
+
+# The main processing script.
+
+templates, options = process_command_line()
+results = Results()
+
+# template is a global variable accessible by template scripts.
+for template in templates:
+
+ # We first read the template script file and run it.
+ template_path = template.options.get('template')
+ log.phase('Processing template ' + template_path + ' with options:')
+ log.line(str(template.options.options))
+
+ # We then traverse the template tree and prepare a list of
+ # directories and files to be created, and process any found template
+ # scripts.
+ log.phase('Examining the template project tree...')
+ directory_list, file_list, python_list = template.examine()
+ results.append(template, directory_list, file_list, python_list)
+
+ log.end()
+
+ log.end()
+
+# prepare the destination tree by erasing existing files and directories.
+log.phase('Preparing destination tree...')
+results.prepare()
+log.end()
+
+log.phase('Creating file tree from template...')
+results.create()
+log.end()

Modified: sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide.py
==============================================================================
--- sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide.py (original)
+++ sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide.py 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -7,7 +7,7 @@
 
 if template.options.get_boolean('vc8ide', False):
 
- template.log_message('Processing MSVC 8.0 IDE template.')
+ log.message('Processing MSVC 8.0 IDE template.')
 
     _msvc_build_command = """\t\t\t\tBuildCommandLine="bjam --v2 ../../$(ProjectName) $(ConfigurationName)"
 \t\t\t\tReBuildCommandLine="bjam --v2 -a ../../$(ProjectName) $(ConfigurationName)"
@@ -26,6 +26,28 @@
     template.content_replacement(['.vcproj'], '$template_msvc_build_command$', _msvc_build_command)
     template.content_replacement(['.vcproj'], '$template_msvc_doc_build_command$', _msvc_doc_build_command)
 
+ global vc_list_files
+
+ def vc_list_files(level, output_base, destination_base, directory):
+ tabs = ''.join(['\t' for x in range(level)])
+ output_base_directory = os.path.join(output_base, directory)
+ destination_base_directory = os.path.join(destination_base, directory)
+ for name in results.files_in(destination_base_directory):
+ template.append_content("""
+""" + tabs + """<File
+""" + tabs + '\tRelativePath="'+os.path.join(output_base_directory,name)+""""
+""" + tabs + """\t>
+""" + tabs + """</File>""")
+
+ for name in results.directories_in(destination_base_directory):
+ template.append_content("""
+""" + tabs + """<Filter
+""" + tabs + '\tName="'+name+""""
+""" + tabs + """\t>""")
+ vc_list_files(level+1, output_base_directory, destination_base_directory, name)
+ template.append_content("""
+""" + tabs + """</Filter>""")
+
 else:
 
     template.ignore_subdirectory('vc8ide')

Deleted: sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide/build.vcproj
==============================================================================
--- sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide/build.vcproj 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
+++ (empty file)
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="build"
- ProjectGUID="{$template_msvc_build_uuid$}"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="debug|Win32"
- OutputDirectory="..\..\..\..\bin.v2\libs\$(SolutionName)\$(ProjectName)\msvc-8.0\$(ConfigurationName)\threading-multi"
- IntermediateDirectory="$(OutDir)"
- ConfigurationType="0"
- >
- <Tool
- Name="VCNMakeTool"
-$template_msvc_build_command$
- Output=""
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="release|Win32"
- OutputDirectory="..\..\..\..\bin.v2\libs\$(SolutionName)\$(ProjectName)\msvc-8.0\$(ConfigurationName)\threading-multi"
- IntermediateDirectory="$(OutDir)"
- ConfigurationType="0"
- >
- <Tool
- Name="VCNMakeTool"
-$template_msvc_build_command$
- Output=""
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="boost"
- >
- <Filter
- Name="$template_library$"
- >
- <File
- RelativePath="..\..\..\..\boost\$template_library$\$template_library$.hpp"
- >
- </File>
- </Filter>
- <File
- RelativePath="..\..\..\..\boost\$template_library$.hpp"
- >
- </File>
- </Filter>
- <Filter
- Name="solution build"
- >
- <File
- RelativePath="..\..\..\..\boost-build.jam"
- >
- </File>
- <File
- RelativePath="..\..\..\..\project-root.jam"
- >
- </File>
- <File
- RelativePath="..\..\..\..\Jamfile.v2"
- >
- </File>
- </Filter>
- <File
- RelativePath="..\..\build\Jamfile.v2"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>

Copied: sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide/build.vcproj.py (from r4349, /sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide/build.vcproj)
==============================================================================
--- /sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide/build.vcproj (original)
+++ sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/vc8ide/build.vcproj.py 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -1,4 +1,12 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+# template file
+
+# Copyright 2007 Stjepan Rajko.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+template.append_content(
+r"""<?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
         ProjectType="Visual C++"
         Version="8.00"
@@ -52,23 +60,9 @@
         </Configurations>
         <References>
         </References>
- <Files>
- <Filter
- Name="boost"
- >
- <Filter
- Name="$template_library$"
- >
- <File
- RelativePath="..\..\..\..\boost\$template_library$\$template_library$.hpp"
- >
- </File>
- </Filter>
- <File
- RelativePath="..\..\..\..\boost\$template_library$.hpp"
- >
- </File>
- </Filter>
+ <Files>""")
+vc_list_files(2, r'..\..\..\..', template.replace_name('$template_library$'), 'boost')
+template.append_content(r"""
                 <Filter
                         Name="solution build"
>
@@ -93,3 +87,4 @@
         <Globals>
         </Globals>
 </VisualStudioProject>
+""")

Modified: sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/xcodeide.py
==============================================================================
--- sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/xcodeide.py (original)
+++ sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/build/xcodeide.py 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -2,7 +2,7 @@
 
 if template.options.get_boolean('xcodeide', False):
 
- template.log_message('Processing Xcode IDE template.')
+ log.message('Processing Xcode IDE template.')
     
 else:
 

Modified: sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/doc/$template_library$.qbk.py
==============================================================================
--- sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/doc/$template_library$.qbk.py (original)
+++ sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/doc/$template_library$.qbk.py 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -7,7 +7,7 @@
 
 docs = template.options.get('docs')
                      
-content="""
+template.append_content("""
 [library $template_Library$
     [quickbook 1.4]
     [version 0.01e-10]
@@ -34,40 +34,37 @@
 
 The $template_Library$ is located in the $template_library$ directory of the boost sandbox.
 
-"""
+""")
 if docs!='qb':
- content+="""
+ template.append_content("""
 You might also want to look at the [link $template_library$.reference reference].
 
-"""
+""")
 
-content+="""
+template.append_content("""
 [endsect]
 
 [endsect]
-"""
+""")
 if docs=='qb+doxy':
- content+="""
+ template.append_content("""
 [section:reference Reference]
 
 The reference for this library is [@doxygen/index.html generated separately].
 
 [endsect]
 
-"""
+""")
+elif docs=='qb+doxyref':
+ template.append_content("""
+[xinclude $template_library$_doxygen.xml]
+""")
 
-content+="""
+template.append_content("""
 [section:license License]
 
 $template_qbk_copyright$
 
 [endsect]
-"""
-
-if docs=='qb+doxyref':
- content+="""
-[xinclude $template_library$_doxygen.xml]
-"""
-
-template.submit_content(content)
+""")
 

Modified: sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/doc/Jamfile.v2.py
==============================================================================
--- sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/doc/Jamfile.v2.py (original)
+++ sandbox/template_under_construction/sandbox/$template_library$/libs/$template_library$/doc/Jamfile.v2.py 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -6,10 +6,9 @@
 # http://www.boost.org/LICENSE_1_0.txt)
 
 docs = template.options.get('docs')
-doxygen = docs != 'qb'
-
+doxygen = docs != 'qb'
 
-content = """$template_start$
+template.append_content("""$template_start$
 $template_python_copyright$
 
 project boost/$template_library$/doc ;
@@ -20,13 +19,29 @@
 local loc = [ path.native [ path.pwd ] ] ;
 local root = [ path.native [ path.join [ path.pwd ] ../../.. ] ] ;
 
-xml $template_library$_xml : $template_library$.qbk ;"""
+xml $template_library$_xml : $template_library$.qbk ;""")
+
+doxy_source_files = list()
+for root, dirs, files in results.walk(
+ # we want the returned root to be relative to $template_library$
+ template.replace_name('$template_library$'),
+ # and want to walk the boost/$template_library$ directory underneath that
+ template.replace_name('boost/$template_library$')):
+ if os.path.basename(root) != 'detail':
+ doxy_source_files.append(
+ template.replace_name(os.path.join(os.path.join('../../..',
+ root), '*.hpp').replace('\\','/')))
+
+if docs=='qb+doxy':
+ doxy_source_files.append('dox/*.hpp')
 
 if doxygen:
- content += """
+ template.append_content("""
 doxygen $template_library$_doxygen
    :
- [ glob ../../../boost/$template_library$/*.hpp dox/*.hpp ]
+ [ glob
+ """ + """
+ """.join(doxy_source_files) + """ ]
    :
         <doxygen:param>EXAMPLE_PATH=../example
         <doxygen:param>STRIP_FROM_PATH=$(root)
@@ -39,26 +54,26 @@
         <doxygen:param>MACRO_EXPANSION=YES
         <doxygen:param>SEARCH_INCLUDES=YES
         <doxygen:param>INCLUDE_PATH=../../..
- <doxygen:param>PREDEFINED=DOXYGEN_DOCS_ONLY"""
+ <doxygen:param>PREDEFINED=DOXYGEN_DOCS_ONLY""")
 
     if docs=='qb+doxy':
- content += """
+ template.append_content("""
         <doxygen:param>GENERATE_HTML=YES
         <doxygen:param>HTML_OUTPUT=$(loc)/html/doxygen
- <doxygen:param>HTML_STYLESHEET=$(loc)/html/boostbook_doxygen.css"""
- content +="""
+ <doxygen:param>HTML_STYLESHEET=$(loc)/html/boostbook_doxygen.css""")
+ template.append_content("""
    ;
-"""
+""")
 
-content += """
+template.append_content("""
 boostbook standalone
    :
- $template_library$_xml"""
+ $template_library$_xml""")
 if (doxygen):
- content+="""
- $template_library$_doxygen"""
+ template.append_content("""
+ $template_library$_doxygen""")
 
-content +="""
+template.append_content("""
     :
         <xsl:param>chunk.first.sections=1
         <xsl:param>chunk.section.depth=3
@@ -66,6 +81,5 @@
         <xsl:param>toc.max.depth=3
         <xsl:param>generate.section.toc.level=3
     ;
-"""
+""")
 
-template.submit_content(content)

Modified: sandbox/template_under_construction/sandbox/sandbox.py
==============================================================================
--- sandbox/template_under_construction/sandbox/sandbox.py (original)
+++ sandbox/template_under_construction/sandbox/sandbox.py 2007-05-29 16:47:41 EDT (Tue, 29 May 2007)
@@ -1,17 +1,15 @@
 # template script
 
-template.log_message('Processing Boost Sandbox template.')
-
-template.template_root = 'sandbox/'
-template.template_dir = '$template_library$'
-
-library_name = template.options.get('library', template.options.alnum, None,
- 'library name (all lowercase, use underscores to separate words, e.g. "my_library"): ')
 # Copyright 2007 Stjepan Rajko.
 # Distributed under the Boost Software License, Version 1.0.
 # (See accompanying file LICENSE_1_0.txt or copy at
 # http://www.boost.org/LICENSE_1_0.txt)
 
+log.message('Welcome to the Boost Sandbox template.')
+
+library_name = template.options.get('library', template.options.alnum_lowercase, None,
+ '(all lowercase, use underscores to separate words, e.g. "my_library"): ')
+
 library_name_list = library_name.split("_")
 library_name_list_capitalized = list()
 for item in library_name_list[:]:
@@ -26,7 +24,7 @@
 """
 
 author_list = template.options.get('author', template.options.any, None,
- 'list of authors (comma separated, no spaces outside names, e.g., "My Name,Notmy R. Name": ')
+ '(comma separated, no spaces outside names, e.g., "My Name,Notmy R. Name": ')
 author_reversed = list()
 for name in author_list.rsplit(','):
     first_space_last = name.rpartition(" ")


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk