Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r68365 - in trunk/libs/geometry/doc: . doxy/doxygen_input/groups doxy/doxygen_input/pages src src/docutils/tools/doxygen_xml2qbk
From: barend.gehrels_at_[hidden]
Date: 2011-01-22 10:30:47


Author: barendgehrels
Date: 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
New Revision: 68365
URL: http://svn.boost.org/trac/boost/changeset/68365

Log:
Removed (Doxygen) group descriptions
Reworked doxygen_xml2qbk, splitted into headerfiles, using program_options, geometry independant

Added:
   trunk/libs/geometry/doc/src/copyright_block.qbk (contents, props changed)
   trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/configuration.hpp (contents, props changed)
   trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_elements.hpp (contents, props changed)
   trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml_parser.hpp (contents, props changed)
   trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/parameter_predicates.hpp (contents, props changed)
   trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/quickbook_output.hpp (contents, props changed)
   trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/rapidxml_util.hpp (contents, props changed)
Text files modified:
   trunk/libs/geometry/doc/doxy/doxygen_input/groups/groups.hpp | 886 +----------------------------------
   trunk/libs/geometry/doc/doxy/doxygen_input/pages/doxygen_mainpage.hpp | 2
   trunk/libs/geometry/doc/doxy/doxygen_input/pages/doxygen_pages.hpp | 2
   trunk/libs/geometry/doc/make_qbk.py | 11
   trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml2qbk.cpp | 1004 +++------------------------------------
   trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml2qbk.vcproj | 48 +
   trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/file_to_string.hpp | 8
   7 files changed, 186 insertions(+), 1775 deletions(-)

Modified: trunk/libs/geometry/doc/doxy/doxygen_input/groups/groups.hpp
==============================================================================
--- trunk/libs/geometry/doc/doxy/doxygen_input/groups/groups.hpp (original)
+++ trunk/libs/geometry/doc/doxy/doxygen_input/groups/groups.hpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -4,888 +4,60 @@
 // Use, modification and distribution is subject to 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)
-
 // File defining groups for Doxygen.
 // Note that group descriptions are (currently) not used.
-
-/*!
+/*
+\defgroup access access: get/set coordinate values, make objects, clear geometries, append point(s)
 \defgroup append append: append points to geometries
-*/
-
-/*!
-\defgroup make make: construct geometries
-*/
-
-/*!
-\defgroup assign assign: assign values to geometries
-*/
-
-/*!
-\defgroup clear clear: clear geometries
-*/
-
-/*!
-\defgroup correct correct: correct geometries
-*/
-
-
-/*!
-\defgroup get get: get geometries
-*/
-
-/*!
-\defgroup set set: set geometries
-*/
-
-/*!
-\defgroup num_geometries number of geometries: calculate the number of geometries in a multi-geometry
-*/
-
-/*!
-\defgroup num_interior_rings number of interior rings: calculate the number of interior rings
-*/
-
-/*!
-\defgroup num_points number of points: calculate number of points of a geometry
-*/
-
-/*!
-\defgroup exterior_ring exterior_ring: exterior_ring
-*/
-
-/*!
-\defgroup interior_rings interior_rings: interior_rings
-*/
-
-/*!
-\defgroup ranges ranges: ranges
-*/
-
-/*!
-\defgroup strategies strategies: strategies
-*/
-
-// -------------------------------------------------------
-// Former algorithms
-// -------------------------------------------------------
-
-/*!
 \defgroup area area: calculate area of a Geometry
-
-\par Performance
-2776 * 1000 area calculations are done in 0.11 seconds
-(http://trac.osgeo.org/ggl/wiki/Performance#Area1)
-
-\par Coordinate systems and strategies
-Area calculation can be done in Cartesian and in spherical/geographic
-coordinate systems.
-
-\par Geometries
-The area algorithm calculates the surface area of all geometries
-having a surface: box, polygon, multi_polygon. The units are the square of
-the units used for the points defining the surface. If the polygon is defined
-in meters, the area is in square meters.
-
-\par Example:
-Example showing area calculation of polygons built
-\dontinclude doxygen_1.cpp
-\skip example_area_polygon()
-\line {
-\until }
-
-*/
-
-
-/*!
+\defgroup arithmetic arithmetic: arithmetic operations on points
+\defgroup assign assign: assign values to geometries
 \defgroup buffer buffer: calculate buffer of a geometry
-\par Source description:
-- OGC: Returns a geometric object that represents all Points whose distance
-from this geometric object is less than or equal to distance. Calculations are in the spatial reference system of
-this geometric object. Because of the limitations of linear interpolation, there will often be some relatively
-small error in this distance, but it should be near the resolution of the coordinates used
-\see http://en.wikipedia.org/wiki/Buffer_(GIS)
-*/
-
-
-/*!
 \defgroup centroid centroid: calculate centroid (center of gravity) of a geometry
-\par Source descriptions:
-- OGC description: The mathematical centroid for this Surface as a Point. The
- result is not guaranteed to be on this Surface.
-- From Wikipedia: Informally, it is the "average" of all points
-\see http://en.wikipedia.org/wiki/Centroid
-\note Polygon should be closed, and can be orientated either way
-\note The "centroid" functions are taking a non const reference to the centroid.
- The "make_centroid" functions return the centroid, the type has to be
- specified.
-\note Both of them have an overloaded version where
- a centroid calculation strategy can be specified
-\exception centroid_exception if calculation is not successful,
- e.g. because polygon didn't contain points
-
-\par Example:
-Example showing centroid calculation
-\dontinclude doxygen_1.cpp
-\skip example_centroid_polygon
-\line {
-\until }
-
-\par Performance
-2776 * 1000 centroid calculations are done in 0.16 seconds
-(http://trac.osgeo.org/ggl/wiki/Performance#Centroid1)
-
-\par Geometries:
-- RING: \image html centroid_ring.png
-- BOX: the centroid of a 2D or 3D box is the center of the box
-- POLYGON \image html centroid_polygon.png
-- POINT: the point is the centroid
-- LINESTRING: the average of the centers of its segments
-- MULTIPOINT: the average of the points
-*/
-
-
-/*!
+\defgroup clear clear: clear geometries
 \defgroup combine combine: add a geometry to a bounding box
-\par Geometries:
-- \b box + \b box -> \b box: the box will be combined with the other box
- \image html combine_box_box.png
- \note Also if the input box is incorrect, the box will correctly updated
-- \b box + \b point -> \b box: the box will combined with the point
- \image html combine_box_point.png
-- \b box + \b segment -> \b box
-*/
-
-/*!
+\defgroup compare compare: define compare functors for points
+\defgroup concepts geometry concepts: defines and checks concepts for geometries
 \defgroup convert convert: convert geometries from one type to another
-\details Convert from one geometry type to another type,
- for example from BOX to POLYGON
-\par Geometries:
-- \b point to \b box -> a zero-area box of a point
-- \b box to \b ring -> a rectangular ring
-- \b box to \b polygon -> a rectangular polygon
-- \b ring to \b polygon -> polygon with an exterior ring (the input ring)
-- \b polygon to \b ring -> ring, interior rings (if any) are ignored
-*/
-
-
-/*!
+\defgroup convex_hull convex hull: calculate the convex hull of a geometry
+\defgroup core core: meta-functions for geometry types
+\defgroup correct correct: correct geometries
+\defgroup cs coordinate systems
 \defgroup difference difference: difference of two geometries
-*/
-
-
-/*!
 \defgroup disjoint disjoint: detect if geometries are not spatially related
-\details disjoint means spatially disjoint, there is no overlap of interiors
- and boundaries, the intersection of interiors or boundaries is empty.
-
-\par Geometries:
-- \b point + \b point (= ! equals)
-- \b point + \b box (= not within or on border)
-- \b box + \b box
-- \b ring + \b box
-- \b polygon + \b box
-- \b polygon + \b ring
-- \b polygon + \b polygon
-
-*/
-
-
-/*!
 \defgroup distance distance: calculate distance between two geometries
-The distance algorithm returns the distance between two geometries.
-\par Coordinate systems and strategies:
-With help of strategies the distance function returns the appropriate distance.
-If the input is in cartesian coordinates, the Euclidian distance (Pythagoras) is calculated.
-If the input is in spherical coordinates (either degree or radian), the distance over the sphere is returned.
-If the input is in geographic coordinates, distance is calculated over the globe and returned in meters.
-
-\par Distance result:
-Depending on calculation type the distance result is either a structure, convertable
-to a double, or a double value. In case of Pythagoras it makes sense to not draw the square root in the
-strategy itself. Taking a square root is relative expensive and is not necessary when comparing distances.
-
-\par Geometries:
-Currently implemented, for both cartesian and spherical/geographic:
-- POINT - POINT
-- POINT - SEGMENT and v.v.
-- POINT - LINESTRING and v.v.
-
-Not yet implemented:
-- POINT - RING etc, note that it will return a zero if the point is anywhere within the ring
-
-\par Example:
-Example showing distance calculation of two points, in xy and in latlong coordinates
-\dontinclude doxygen_1.cpp
-\skip example_distance_point_point
-\line {
-\until }
-*/
-
-
-/*!
 \defgroup envelope envelope: calculate envelope (minimum bounding rectangle) of a geometry
-\par Source descriptions:
-- OGC: Envelope (): Geometry - The minimum bounding rectangle (MBR) for this
- Geometry,
-returned as a Geometry. The polygon is defined by the corner points of the
- bounding box
- [(MINX, MINY), (MAXX, MINY), (MAXX, MAXY), (MINX, MAXY), (MINX, MINY)].
-
-\note Implemented in the Generic Geometry Library: The minimum bounding box,
- always as a box, having min <= max
-
-The envelope algorithm calculates the bounding box, or envelope, of a geometry.
-There are two versions:
-- envelope, taking a reference to a box as second parameter
-- make_envelope, returning a newly constructed box (type as a template parameter
- in the function call)
-
-\par Geometries:
-- \b point: a box with zero area, the maximum and the minimum point of the box are
-set to the point itself.
-- \b linestring, \b ring or \b range is the smallest box that contains all points of the
- specified point sequence.
-If the linestring is empty, the envelope is the inverse infinite box, that is,
- the minimum point is very large (max infinite) and the maximum point is
- very small (min infinite).
-- \b polygon, the envelope of the outer ring
-\image html envelope_polygon.png
-
-\par Example:
-Example showing envelope calculation
-\dontinclude doxygen_1.cpp
-\skip example_envelope_linestring
-\line {
-\until }
-*/
-
-
-
-/*!
 \defgroup equals equals: detect if two geometries are spatially equal
-\details Equals returns true if geometries are spatially equal. Spatially equal
-means including the same point-set. A linestring can be spatially equal to
-another linestring, even if both do not have the same amount of points.
-A polygon can be spatially equal to a multi-polygon (which then has
-only one element).
-
-\par Geometries:
-- \b point + \b point
-- \b box + \b box
-
-\note There is a functor \ref compare "compare" as well, which can be used
-for std:: library compatibility.
-
-*/
-
-/*!
+\defgroup exterior_ring exterior_ring: exterior_ring
 \defgroup for_each for_each: apply a functor to each point or segment of a geometry
-\details There are two algorithms provided which walk through the points or segments
-of linestrings and polygons. They are called for_each_point, for_each_segment,
-after the standard library
-\note For both for_each algorithms there is a \b const and a non-const version provided.
-*/
-
-
-/*!
+\defgroup geometries geometries: geometries provided by default
+\defgroup get get: get geometries
+\defgroup interior_rings interior_rings: interior_rings
 \defgroup intersection intersection: calculate new geometry
- containing geometries A and B
-\details The intersection of two geometries A and B is the geometry containing
- all points of A also belonging to B, but no other elements. The so-called
- clip is an intersection of a geometry with a box.
-\par Source description:
-- OGC: Returns a geometric object that represents the Point set intersection of
- this geometric object with another Geometry.
-\see http://en.wikipedia.org/wiki/Intersection_(set_theory)
-\note Any intersection can result in no geometry at all
-
-\par Performance
-- 2776 counties of US are intersected with a 100-points ellipse in 1.1 seconds
-(http://trac.osgeo.org/ggl/wiki/Performance#Interesection)
-- 2776 counties of US are clipped in 0.2 seconds
-(http://trac.osgeo.org/ggl/wiki/Performance#Clip)
-
-
-\par Geometries:
-- \b polygon + \b box (clip) -> \b polygon(s)
-\image html svg_intersection_polygon_box.png
-\image html svg_intersection_countries.png
-- \b ring + \b box (clip) -> \b polygon(s)
-\image html svg_intersection_ring_box.png
-- \b ring + \b ring -> \b polygon(s)
-\image html svg_intersection_ring_ring.png
-- \b polygon + \b ring -> \b polygon(s)
-\image html svg_intersection_polygon_ring.png
-- combinations above -> \b ring(s).
- <i>If the output is an ouput iterator of rings, holes are omitted</i>
-- \b linestring + \b box (clip)
-\image html svg_intersection_roads.png
-
-\par Example:
-Example showing clipping of linestring with box
-\dontinclude doxygen_1.cpp
-\skip example_clip_linestring1
-\line {
-\until }
-\par Example:
-Example showing clipping of vector, outputting vectors, with box
-\dontinclude doxygen_1.cpp
-\skip example_clip_linestring2
-\line {
-\until }
-\par Example:
-Example showing clipping of polygon with box
-\dontinclude doxygen_1.cpp
-\skip example_intersection_polygon1
-\line {
-\until }
-*/
-
-
-/*!
 \defgroup intersects intersects: detect if a geometry self-intersects or if two geometries intersect
-\par Source descriptions:
-- OGC description: Returns 1 (TRUE) if this geometric object spatially
- intersects anotherGeometry.
-- OGC: a.Intersects(b) <=> ! a.Disjoint(b)
-\note There are two overloaded versions:
-- with one geometry, detecting self-intersections
-- with two geometries, deferring to disjoint, returning !disjoint
-
-\par Geometries:
-- \b ring
-- \b polygon
-- for two geometries: same is disjoint
-
-\note if one geometry is completely within another geometry, it "intersects"
-
-*/
-
-/*!
+\defgroup iterators iterators: iterators
 \defgroup length length: calculate length of a linear geometry
-The length algorithm is implemented for the linestring and the multi_linestring
-geometry and results in the length of the linestring. If the points of
-a linestring have coordinates expressed in kilometers,
-the length of the line is expressed in kilometers as well.
-\par Example:
-Example showing length calculation
-\dontinclude doxygen_1.cpp
-\skip example_length_linestring_iterators1
-\line {
-\until }
-*/
-
-
-
-
-
-/*!
+\defgroup make make: construct geometries
+\defgroup num_geometries number of geometries: calculate the number of geometries in a multi-geometry
+\defgroup num_interior_rings number of interior rings: calculate the number of interior rings
+\defgroup num_points number of points: calculate number of points of a geometry
 \defgroup overlaps overlaps: detect overlap between two geometries
-\par Source descriptions:
-- Egenhofer: Two objects overlap if they have common interior faces and the bounding faces have common parts
-with the opposite interior faces.
-
-\par Geometries:
-- \b box + \b box
-
-*/
-
-
-/*!
 \defgroup perimeter perimeter: calculate perimeter of a geometry
-\par Geometries:
-- \b polygon
-- \b box
-- \b linear_ring
-- \b multi_polygon
-*/
-
-/*!
+\defgroup projection projection: Projection struct's, classes
+\defgroup projections projections: Projections
+\defgroup ranges ranges: ranges
+\defgroup register register: Macros for registration
 \defgroup reverse reverse: reverse a geometry
- This is functionally equivalent to the std::reverse algorithm.
- For a linestring or a linear ring, it is exactly the same as calling the std::reverse algorithm.
- For a polygon or a multi-geometry, all its rings or elements are reversed.
-
- No check on order is applied. So a clockwise polygon (having positive area)
- will be made counterclockwise (having negative area).
-
- The first and last points are reversed as well, even if they are closed and the same.
-*/
-
-
-
-/*!
+\defgroup selected selection: check if a geometry is "selected" by a point
+\defgroup set set: set geometries
 \defgroup simplify simplify: remove points from a geometry, keeping shape (simplification or generalization)
-\par Source description:
-- Wikipedia: given a 'curve' composed of line segments to find a curve
- not too dissimilar but that has fewer points
-
-\see http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
-
-\par Performance
-- Performance is measured on simplification of a collection of rings,
- such that 10% of the points is kept.
-- 2776 counties of US are simplified in 0.7 seconds
-(http://trac.osgeo.org/ggl/wiki/Performance#Simplify1)
-
-\par Geometries
-- \b linestring:
-\image html svg_simplify_road.png
-This US Road originally contained 34 points, the simplified version contains 7 points
-
-- \b polygon:
-\image html svg_simplify_country.png
-This country (Belgium) originally contained 55 points, the simplified version contains 24 points
-
-\note simplifying a valid simple polygon (which never intersects itself)
- might result in an invalid polygon, where the simplified rings intersect
- themselves or one of the other outer or inner rings.
-Efficient simplification of a ring/polygon is still an "Open Problem"
-(http://maven.smith.edu/~orourke/TOPP/P24.html#Problem.24)
-
-- \b multi_linestring
-- \b multi_polygon
-
-
-*/
-
-
-
-/*!
+\defgroup strategies strategies: strategies
+\defgroup svg x Extension svg: Stream SVG (Scalable Vector Graphics)
 \defgroup sym_difference sym_difference: sym_difference of two geometries
-*/
-/*!
+\defgroup traits traits: adapt geometries
 \defgroup transform transform: apply transformations on geometries
-\brief Transforms from one geometry to another geometry, optionally using a strategy
-\details The transform algorithm automatically transforms from one coordinate system to another coordinate system.
-If the coordinate system of both geometries are the same, the geometry is copied. All point(s of the geometry)
-are transformed.
-
-There is a version without a strategy, transforming automatically, and there is a version with a strategy.
-
-This function has a lot of appliances, for example
-- transform from spherical coordinates to cartesian coordinates, and back
-- transform from geographic coordinates to cartesian coordinates (projections) and back
-- transform from degree to radian, and back
-- transform from and to cartesian coordinates (mapping, translations, etc)
-
-The automatic transformations look to the coordinate system family, and dimensions, of the point type and by this
-apply the strategy (internally bounded by traits classes).
-
-\par Examples:
-The example below shows automatic transformations to go from one coordinate system to another one:
-\dontinclude doxygen_2.cpp
-\skip example_for_transform()
-\skipline XYZ
-\until endl;
-
-The next example takes another approach and transforms from Cartesian to Cartesian:
-\skipline XY
-\until endl;
-
-\note Not every possibility is yet worked out, e.g. polar coordinate system is ignored until now
-\note This "transform" is broader then geodetic datum transformations, those are currently not worked out
-
-*/
-
-
-/*!
 \defgroup union union: calculate new geometry containing geometries A or B
-\details The union of two geometries A and B is the geometry containing
- all points belong to either of A or B, but no other elements.
-\par Source description:
-- OGC: Returns a geometric object that represents the Point set union of
- this geometric object with another Geometry.
-\see http://en.wikipedia.org/wiki/Union_(set_theory)
-\note A union of two rings can result in a polygon having a hole
-
-\par Geometries:
-- \b polygon + \b box -> \b polygon(s)
-\image html svg_union_polygon_box.png
-- \b ring + \b box -> \b polygon(s)
-\image html svg_union_ring_box.png
-- \b ring + \b ring -> \b polygon(s)
-\image html svg_union_ring_ring.png
-- \b polygon + \b ring -> \b polygon(s)
-\image html svg_union_polygon_ring.png
-- combinations above -> \b ring(s).
- <i>If the output is an ouput iterator of rings, holes are omitted</i>
-
-*/
-
-/*!
 \defgroup unique unique: make a geometry unique w.r.t. points,
- so no duplicate consecutive points
-
-*/
-
-
-
-/*!
 \defgroup within within: detect if a geometry is inside another geometry, a.o. point-in-polygon
-
-\par Source descriptions:
-- OGC: Returns 1 (TRUE) if this geometric object is "spatially within"
- another Geometry.
-
-\par Performance
-- 2776 within determinations using bounding box and polygon are done
- in 0.05 seconds (http://trac.osgeo.org/ggl/wiki/Performance#Within1)
-- note that using another strategy the performance can be increased:
- - winding : 0.093 s
- - franklin : 0.062 s
- - Crossings-multiply : 0.047 s
-- but note also that the last two do not detect point-on-border cases
-
-\par Geometries:
-- \b point + \b polygon: The well-known point-in-polygon, returning true if
- a point falls within a polygon (and not
-within one of its holes) \image html within_polygon.png
-- \b point + \b ring: returns true if point is completely within
- a ring \image html within_ring.png
-- \b point + \b box
-- \b box + \b box
-
-\par Example:
-The within algorithm is used as following:
-\dontinclude doxygen_1.cpp
-\skip example_within
-\line {
-\until }
-
-*/
-
-
-
-
-
-
-
-
-
-
-
-/*!
-\defgroup iterators iterators: iterators
-*/
-
-/*!
-\defgroup core core: meta-functions for geometry types
-*/
-/*!
-\defgroup arithmetic arithmetic: arithmetic operations on points
-*/
-
-/*!
-\defgroup svg x Extension svg: Stream SVG (Scalable Vector Graphics)
-*/
-
-
-/*!
-\defgroup register register: Macros for registration
-\details Registration of custom geometry types.
-*/
-
-/*!
-\defgroup traits traits: adapt geometries
-\brief Traits classes are small classes or structs to adapt geometries
-such that they are recognized by the Generic Geometry Library
-*/
-
-/*!
-\defgroup geometries geometries: geometries provided by default
-\details The GGL can be used with the geometry classes provided by the library,
-and with custom geometries registered by traits classes or registration
-macros.
-
-This documentation page refers to the geometry classes provided by the library.
-
-*/
-
-/*!
 \defgroup wkt wkt: parse and stream WKT (Well-Known Text)
-The wkt classes stream the specified geometry as \ref OGC Well Known Text (\ref WKT). It is defined for OGC geometries.
-It is therefore not defined for all geometries (e.g. not for circle)
-\note The implementation is independant from point type, point_xy and point_ll are supported,
-as well as points with more than two coordinates.
-*/
-
-/*!
-\defgroup utility utility: utility meta-functions and functions
-\details The utilities, mostly in folder util, contain several headerfiles
-not fitting in one of the other folders.
-
-The following meta-functions are general and do not relate to GGL:
-- add_const_if_c
-- select_most_precise
-
-They might fit into boost as a separate trait or utility, or there might
-be a Boost equivalent which is yet unnoticed by the authors.
-
-
-*/
-
-/*!
-\defgroup selected selection: check if a geometry is "selected" by a point
-
-Checks if one geometry is selected by a point lying within or in the neighborhood of that geometry
-
-\par Geometries:
-- POINT: checks if points are CLOSE TO each other (< search_radius)
-- LINESTRING: checks if selection point is CLOSE TO linestring (< search_radius)
-- RING: checks if selection point is INSIDE the ring, search radius is ignored
-- POLYGON: checks if selection point is INSIDE the polygon, but not inside any of its holes
-
-*/
-
-
-/*!
-\defgroup cs coordinate systems
-\brief Defines coordinate systems
-\details Coordinate systems are essential for any point in the Generic Geometry Library. Many
-algorithms such as distance or transform use coordinate systems to select the strategy to use.
-*/
-
-
-
-
-/*!
-\defgroup access access: get/set coordinate values, make objects, clear geometries, append point(s)
-\details There are many ways to edit geometries. It is possible to:
-
-\li use the geometries themselves, so access point.x(). This is not done
-inside the library because it is agnostic to geometry type. However,
-library users can use this as it is intuitive.
-\li use the standard library, so use .push_back(point) or use inserters.
-This is also avoided inside the library. However, library users can use
-it if they are used to the standard library
-\li use the functionality provided in this geometry library. These are
-the functions in this module.
-
-The library provides the following functions to edit geometries:
-\li set to set one coordinate value
-\li assign to set two or more coordinate values
-\li make to construct and return geometries with specified coordinates.
-\li append to append one or more points to a geometry
-\li clear to remove all points from a geometry
-
-For getting coordinates it is similar:
-\li get to get a coordinate value
-\li or use the standard library
-\li or use the geometries themselves
-*/
-
-
-
-/*!
-\defgroup compare compare: define compare functors for points
-\details The compare policies enable to compare points in a way that they can
-be compared in many functions of the standard library.
-
-The functors do have an optional second template argument, \b dimension.
-If dimension is specified, comparison is only done on that dimension.
-
-This is useful for (a.o.):
-- std::sort (use geometry::less<P> or geometry::greater<P> or geometry::less<P, 1>)
-- std::map (use geometry::less<P>)
-- std::unique_copy (use geometry::equal_to<P>)
-
-\par Geometries:
-- \b point
-
-
-\par Example:
-Example showing how geometry::less can be used
-\dontinclude doxygen_3.cpp
-\skip example_less()
-\line {
-\until }
-
-
-\note There is a boolean function \ref equals "equals" as well, which returns
-true or false if a geometry is spatially equal to another geometry. That one
-is defined for OGC compatibility, while these ones are defined for
-compatibility with the std:: library. These ones are functors, operating on
-the same geometry type (currently only the point-type), the equals function is
-a free function operating on different point types or even different geometry
-types (a linestring can be spatially equal to a multi-linestring).
-*/
-
-
-/*!
-\defgroup convex_hull convex hull: calculate the convex hull of a geometry
-\par Source descriptions:
-- OGC description: Returns a geometric object that represents the convex hull of
- this geometric object. Convex hulls, being dependent on straight lines, can
- be accurately represented in linear interpolations
- for any geometry restricted to linear interpolations.
-\see http://en.wikipedia.org/wiki/Convex_hull
-
-\par Performance
-2776 counties of US are "hulled" in 0.9 seconds
-(http://trac.osgeo.org/ggl/wiki/Performance#Convexhull1)
-
-\note The convex hull is always a ring, holes are not possible. Therefore it is
- can also be used in combination with an output iterator.
-
-\par Geometries supported:
-In the images below the convex hull is painted in red.
-
-- \b point: will not compile
-
-- \b linestring:
-
-- \b polygon: will deliver a polygon without holes
- \image html svg_convex_hull_country.png
-
-- \b multi_point:
- \image html svg_convex_hull_cities.png
-
-- \b multi_linestring:
-
-- \b multi_polygon:
-
-\par Output geometries supported:
-
-- \b polygon
-
-- \b ring
-
-- inserter version (with output iterator) can output to any array supporting
- points of same type as the input geometry type
-
-*/
-
-
-/*!
-\defgroup concepts geometry concepts: defines and checks concepts for geometries
-
-All GGL algorithms use concepts for their geometries. This means that all
-algorithms work on the GGL-provided geometries (point, linestring, etc) but
-also on custom geometries.
-
-By declaring registration macro's or by specializating traits classes it is
-possible to adapt custom or legacy geometries to fulfil the GGL geometry
-concepts.
-
-GGL algorithms check the concepts of the input geometries.
-Concept checking is done using BCCL (Boost Concept Check Library).
-
-This means that geometries provided by library users, or legacy geometries, or
-plain arrays, or boost tuples, all can be handled by the Generic Geometry
-Library. Also std::vector of points, or tuples can be handled either as a
-linestring or as a linear ring (polygon without holes).
-
-There are concepts for
-- points
-- segment
-- box
-- linestring
-- (linear) ring
-- polygon
-- multi point
-- multi linestring
-- multi polygon
-
-The Generic Geometry Library uses the Boost Range Library to iterate through
-standard containers, boost arrays, c-arrays.
-So:
-- linestring
-- (linear) ring
-
-are all just ranges. So a std::vector, std::deque, boost::array,
-iterator pair or c-array will be accepted as such.
-
-Also the multi geometries:
-- multi point
-- multi linestring
-- multi polygon
-are considered as ranges of respectively points, linestrings and polygons.
-
-*/
-
-
-
-
-
-/*!
-\defgroup projections projections: Projections
-\brief Projections are algorithms to transform earth coordinates (latlong coordinates, sphere coordinates,
-coordinates in latitude longitude) to a cartesian system. Algorithms here are converted from PROJ4 (http://trac.osgeo.org/proj)
-
-\details Almost all projection sources are converted from PROJ4, from C to a C++ template structure.
-PROJ4 is originally written by Gerald Evenden (then of the USGS).
-
-Projections can be used in combination with the Generic Geometry Library.
-Because it does not use the Generic Geometry Library,
-it might also be used as a standalone map projection library.
-\par Projection parameters
-(This list is adapted from the PROJ4 documentation.)
-- \b proj is required for selection of the cartographic transformation
-function and where name is an acronym for the desired projection.
-- \b R specifies that the projection should be computed as a spherical Earth
-with radius R.
-- \b ellps The \b ellps option allows selection of standard, predefined
-ellipsoid figures. For spherical only projections, the major axis is used as the
-radius.
-- \b a specifies an elliptical Earth's major axis a.
-- \b es defines the elliptical Earth's squared eccentricity. Optionally,
- either \b b, \b e, \b rf or \b f may be used where \b b, \b e and \b f are respective minor axis,
- eccentricity and flattening and \b rf = 1/f
-- \b R_A must be used with elliptical Earth parameters. It determines that spherical
-computations be used with the radius of a sphere that has a surface area
-equivalent to the selected ellipsoid.
-- \b R_V can be used in a similar manner for sphere radius of an ellipse with equivalent volume.
-- \b R_a must be used with elliptical Earth parameters. Spherical radius of the
-arithmetic mean of the major and minor axis is used.
-- \b R_g and \b R_h can be used for equivalent geometric and harmonic means of major and minor axis.
-- \b R_lat_a must be used with elliptical Earth parameters. Spherical radius
-of the arithmetic mean of the principle radii of the ellipsoid at latitude is used.
-- \b R_lat_g can be used for equivalent geometric mean of the principle radii.
-- \b x_0 false easting; added to x value of the cartesian coordinate. Used in
-grid systems to avoid negative grid coordinates.
-- \b y_0 false northing; added to y value of the cartesian coordinate. See x_0.
-- \b lon_0 central meridian. Along with lat_0, normally determines the
-geographic origin of the projection.
-- \b lat_0 central parallel. See lon_0.
-- \b units selects conversion of cartesian values to units specified by name.
-When used, other + metric parameters must be in meters.
-- \b geoc data geographic coordinates are to be treated as geocentric when this
-option specified.
-- \b over inhibit reduction of input longitude values to a range within ca. 180 of the central meridian.
-
-\note
-- Note that many projections have also their own parameters, additionally to the list above
-- Note also that some of the parameters above are required for some projections, others are always optionally
-
-\par Original copyright of PROJ4:
-- Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-- The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
-
-
-/*!
-\defgroup projection projection: Projection struct's, classes
-\brief Projection struct's, classes
-
-\details
-*/
-
-
-/*
-- +init=file:key names a file containing cartographic control parameters associated
-with the keyword key.
 */

Modified: trunk/libs/geometry/doc/doxy/doxygen_input/pages/doxygen_mainpage.hpp
==============================================================================
--- trunk/libs/geometry/doc/doxy/doxygen_input/pages/doxygen_mainpage.hpp (original)
+++ trunk/libs/geometry/doc/doxy/doxygen_input/pages/doxygen_mainpage.hpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -26,7 +26,7 @@
 </em>
 
 \section intro Introduction
-Boost.Geometry, formally accepted by Boost, defines \ref concepts "concepts" for geometries and
+Boost.Geometry, formally accepted by Boost, defines concepts "concepts" for geometries and
 implements some algorithms on such geometries. Before acceptance by Boost it was known as GGL
 (Generic Geometry Library) and this documentation still contains that name on various places.
 

Modified: trunk/libs/geometry/doc/doxy/doxygen_input/pages/doxygen_pages.hpp
==============================================================================
--- trunk/libs/geometry/doc/doxy/doxygen_input/pages/doxygen_pages.hpp (original)
+++ trunk/libs/geometry/doc/doxy/doxygen_input/pages/doxygen_pages.hpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -61,7 +61,7 @@
 
 The GGL makes substantial use of the std library, and is designed to be compatible with it.
 - provided geometries (linestring, ring, polygon, multi-s) make default use of std::vector (but that is configurable)
-- std sorting, unique copies, maps can make use of provided functors in \ref compare "compare".
+- std sorting, unique copies, maps can make use of provided functors in compare "compare".
 - internally, there are vector's, deque's, there is sorting, many things are implemented using the std library
 
 */

Modified: trunk/libs/geometry/doc/make_qbk.py
==============================================================================
--- trunk/libs/geometry/doc/make_qbk.py (original)
+++ trunk/libs/geometry/doc/make_qbk.py 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -10,11 +10,16 @@
 # http://www.boost.org/LICENSE_1_0.txt)9
 # ============================================================================
 
-
 import os, sys
 
-
-cmd="doxygen_xml2qbk doxy/doxygen_output/xml/%s.xml ../../../ boost/geometry/geometry.hpp boost/geometry/geometries/geometries.hpp boost/geometry/multi/multi.hpp > reference/%s.qbk"
+cmd = "doxygen_xml2qbk"
+cmd = cmd + " --xml doxy/doxygen_output/xml/%s.xml"
+cmd = cmd + " --start_include boost/geometry/"
+cmd = cmd + " --convenience_header_path ../../../boost/geometry/"
+cmd = cmd + " --convenience_headers geometry.hpp,geometries/geometries.hpp,multi/multi.hpp"
+cmd = cmd + " --skip_namespace boost::geometry::"
+cmd = cmd + " --copyright src/copyright_block.qbk"
+cmd = cmd + " > reference/%s.qbk"
 
 def call_doxygen():
     os.chdir("doxy");

Added: trunk/libs/geometry/doc/src/copyright_block.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/geometry/doc/src/copyright_block.qbk 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -0,0 +1,11 @@
+[/============================================================================
+ Boost.Geometry (aka GGL, Generic Geometry Library)
+
+ Copyright (c) 2009-2011 Barend Gehrels, Geodan, Amsterdam, the Netherlands.
+ Copyright (c) 2009-2011 Mateusz Loskot (mateusz_at_[hidden])
+ Copyright (c) 2009-2011 Bruno Lalande, Paris, France.
+
+ Use, modification and distribution is subject to 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)
+=============================================================================/]

Added: trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/configuration.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/configuration.hpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -0,0 +1,33 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands
+// Use, modification and distribution is subject to 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)
+//
+//
+#ifndef CONFIGURATION_HPP
+#define CONFIGURATION_HPP
+
+
+#include <string>
+#include <vector>
+
+
+struct configuration
+{
+ // To transfer e.g. c:/_svn/boost/trunk/boost/geometry/algorithms/area.hpp
+ // to #include <boost/geometry/...>
+ // We need to find the position where the include path should start,
+ // so fill out "boost" here, or "boost/geometry" (it uses rfind)
+ std::string start_include;
+
+ // Convenience headers (headefiles with solely purpose of including others
+ std::string convenience_header_path;
+ std::vector<std::string> convenience_headers;
+
+ std::string skip_namespace;
+};
+
+
+#endif // CONFIGURATION_HPP

Added: trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_elements.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_elements.hpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -0,0 +1,95 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands
+// Use, modification and distribution is subject to 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)
+//
+//
+#ifndef DOXYGEN_ELEMENTS_HPP
+#define DOXYGEN_ELEMENTS_HPP
+
+
+#include <string>
+#include <vector>
+
+
+// contains (template)parameter
+struct param
+{
+ std::string name;
+ std::string description;
+ std::string type;
+ std::string fulltype; // post-processed
+};
+
+struct markup
+{
+ int code;
+ std::string value;
+
+ markup(int c = 0, std::string const& v = "")
+ : code(c)
+ , value(v)
+ {}
+
+};
+
+// Basic element, base of a class/struct, function, define
+struct element
+{
+ std::string name;
+ std::string brief_description, detailed_description;
+ std::string location;
+ int line; // To sort - Doxygen changes order - we change it back
+
+ // QBK-includes
+ // Filled with e.g.: \qbk([include reference/myqbk.qbk]}
+ std::vector<markup> qbk_markup;
+
+ // To distinguish overloads: unary, binary etc,
+ // Filled with: \qbk{distinguish,<A discerning description>}
+ std::string additional_description;
+
+ std::vector<param> template_parameters;
+ std::vector<param> parameters;
+
+ element()
+ : line(0)
+ {}
+};
+
+enum function_type { function_unknown, function_define, function_constructor, function_member, function_free };
+
+struct function : public element
+{
+ function_type type;
+ std::string definition, argsstring;
+ std::string return_type, return_description;
+
+ bool unique;
+
+ function()
+ : type(function_unknown)
+ , unique(true)
+ {}
+
+};
+
+struct class_or_struct : public element
+{
+ std::string name, fullname;
+ std::string model_of;
+ std::vector<function> functions;
+};
+
+
+struct documentation
+{
+ class_or_struct cos;
+ std::vector<function> functions;
+ std::vector<function> defines;
+};
+
+
+#endif // DOXYGEN_ELEMENTS_HPP

Modified: trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml2qbk.cpp
==============================================================================
--- trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml2qbk.cpp (original)
+++ trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml2qbk.cpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -1,4 +1,4 @@
-// doxygen_xml2qbk (developed in the context of Boost.Geometry documentation)
+// doxml2qbk (developed in the context of Boost.Geometry documentation)
 //
 // Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands
 // Use, modification and distribution is subject to the Boost Software License,
@@ -31,965 +31,149 @@
 #include <boost/algorithm/string/split.hpp>
 
 
+#include <boost/program_options.hpp>
+
 #include <rapidxml.hpp>
 
+#include <configuration.hpp>
 #include <file_to_string.hpp>
+#include <doxygen_elements.hpp>
+#include <doxygen_xml_parser.hpp>
+#include <parameter_predicates.hpp>
+#include <quickbook_output.hpp>
+#include <rapidxml_util.hpp>
 
 
-// -------------------------------------------------------------
-// rapid xml convenience code
-// -------------------------------------------------------------
-class xml_doc : public rapidxml::xml_document<>
-{
- public :
- xml_doc(const char* xml)
- {
- // Make a copy because rapidxml destructs string
- m_copy = new char[strlen(xml) + 1];
- strcpy(m_copy, xml);
- this->parse<0>(m_copy);
- };
- virtual ~xml_doc()
- {
- delete[] m_copy;
- }
- private :
- char* m_copy;
-
-};
-
-inline std::string get_attribute(rapidxml::xml_node<>* node, const char* name)
-{
- rapidxml::xml_attribute<> *attr = node->first_attribute(name);
- std::string value;
- if (attr)
- {
- value = attr->value();
- }
- return value;
-}
-
-inline void get_contents(rapidxml::xml_node<>* node, std::string& contents)
-{
- if (node != NULL && node->type() == rapidxml::node_element)
- {
- contents += node->value();
- get_contents(node->first_node(), contents);
- get_contents(node->next_sibling(), contents);
- }
-}
-
-// -------------------------------------------------------------
-
-inline std::string keep_after(std::string const& input, std::string const& sig)
-{
- std::size_t pos = input.rfind(sig);
- if (pos != std::string::npos)
- {
- std::string copy = input.substr(pos + sig.length());
- return copy;
- }
- return input;
-}
-
-
-
-
-// -------------------------------------------------------------
-// definitions
-// -------------------------------------------------------------
-
-// (template)parameter
-struct param
-{
- std::string name;
- std::string description;
- std::string type;
- std::string fulltype; // post-processed
-};
-
-struct markup
-{
- int code;
- std::string value;
-
- markup(int c = 0, std::string const& v = "")
- : code(c), value(v)
- {}
-
-};
-
-// Basic element, base of a class/struct, function, define
-struct element
-{
- std::string name;
- std::string brief_description, detailed_description;
- std::string location;
- int line; // To sort - Doxygen changes order - we change it back
-
- // QBK-includes
- // Filled with e.g.: \qbk([include reference/myqbk.qbk]}
- std::vector<markup> qbk_markup;
-
- // To distinguish overloads: unary, binary etc,
- // Filled with: \qbk{distinguish,<A discerning description>}
- std::string additional_description;
-
- std::vector<param> template_parameters;
- std::vector<param> parameters;
-
- element()
- : line(0)
- {}
-};
-
-enum function_type { function_unknown, function_define, function_constructor, function_member, function_free };
-
-struct function : public element
-{
- function_type type;
- std::string definition, argsstring;
- std::string return_type, return_description;
-
- bool unique;
-
- function()
- : type(function_unknown)
- , unique(true)
- {}
-
-};
-
-struct class_or_struct : public element
-{
- std::string name, fullname;
- std::string model_of;
- std::vector<function> functions;
-};
-
-struct documentation
-{
- class_or_struct cos;
- std::vector<function> functions;
- std::vector<function> defines;
-};
-
-struct configuration
-{
- // Prefix to find headerfiles (will not be outputted)
- std::string prefix;
- std::vector<std::string> headerfiles;
-};
-
-
-
-// Predicate for std::find_if
-struct par_by_name
-{
- par_by_name(std::string const& n)
- : m_name(n)
- {}
-
- inline bool operator()(param const& p)
- {
- return p.name == m_name;
- }
-private :
- std::string m_name;
-};
-
-
-// Predicate for std::find_if
-struct par_by_type
-{
- par_by_type(std::string const& n)
- : m_type(n)
- {}
-
- inline bool operator()(param const& p)
- {
- return p.type == m_type;
- }
-private :
- std::string m_type;
-};
-
-
-template <typename Element>
-struct sort_on_line
-{
- inline bool operator()(Element const& left, Element const& right)
- {
- return left.line < right.line;
- }
-};
-
 
-static inline void add_or_set(std::vector<param>& parameters, param const& p)
-{
- std::vector<param>::iterator it = std::find_if(parameters.begin(), parameters.end(), par_by_name(p.name));
- if (it != parameters.end())
- {
- if (it->description.empty()) it->description = p.description;
- if (it->type.empty()) it->type = p.type;
- if (it->fulltype.empty()) it->fulltype = p.fulltype;
- }
- else
- {
- parameters.push_back(p);
- }
-}
-
-// -------------------------------------------------------------
-static void parse_parameter(rapidxml::xml_node<>* node, param& p)
-{
- if (node != NULL)
- {
- std::string name = node->name();
- if (name == "type")
- {
- p.fulltype = node->value();
- p.type = p.fulltype;
- boost::replace_all(p.type, " const", "");
- boost::trim(p.type);
- boost::replace_all(p.type, "&", "");
- boost::replace_all(p.type, "*", "");
- boost::trim(p.type);
- }
- else if (name == "declname") p.name = node->value();
- else if (name == "parametername") p.name = node->value();
- // Define: <param><defname>Point</defname></param>
- else if (name == "defname") p.name = node->value(); // for defines
- else if (name == "para") p.description = node->value();
-
- parse_parameter(node->first_node(), p);
- parse_parameter(node->next_sibling(), p);
- }
-}
-
-// Definition is a function or a class/struct
-template <typename Parameters>
-static void parse_parameter_list(rapidxml::xml_node<>* node, Parameters& parameters)
+int main(int argc, char** argv)
 {
- if (node != NULL)
+ try
     {
- std::string name = node->name();
-
- if (name == "parameteritem")
- {
- param p;
- parse_parameter(node->first_node(), p);
- if (! p.name.empty())
- {
- // Copy its description
- std::vector<param>::iterator it = std::find_if(parameters.begin(),
- parameters.end(), par_by_name(p.name));
- if (it != parameters.end())
- {
- it->description = p.description;
- }
- else
- {
- parameters.push_back(p);
- }
- }
- }
- else if (name == "param")
- {
- // Element of 'templateparamlist.param (.type,.declname,.defname)'
- param p;
- parse_parameter(node->first_node(), p);
-
- // Doxygen handles templateparamlist param's differently:
- //
- // Case 1:
- // <param><type>typename T</type></param>
- // -> no name, assign type to name, replace typename
- //
- // Case 2:
- // <type>typename</type><declname>T</declname><defname>T</defname>
- // -> set full type
- if (p.name.empty())
- {
- // Case 1
- p.name = p.type;
- boost::replace_all(p.name, "typename", "");
- boost::trim(p.name);
+ configuration config;
+ std::string filename;
+ std::string copyright_filename;
+
+ // Read/get configuration
+ {
+ namespace po = boost::program_options;
+ po::options_description description("=== doxml2qbk ===\nAllowed options");
+
+
+ std::string convenience_headers;
+
+ description.add_options()
+ ("help", "Help message")
+ ("xml", po::value<std::string>(&filename),
+ "Name of XML file written by Doxygen")
+ ("start_include", po::value<std::string>(&config.start_include),
+ "Start include")
+ ("convenience_header_path", po::value<std::string>(&config.convenience_header_path),
+ "Convenience header path")
+ ("convenience_headers", po::value<std::string>(&convenience_headers),
+ "Convenience header(s) (comma-separated)")
+ ("skip_namespace", po::value<std::string>(&config.skip_namespace),
+ "Namespace to skip (e.g. boost::mylib::")
+ ("copyright", po::value<std::string>(&copyright_filename),
+ "Name of QBK file including (commented) copyright and license")
+ ;
+
+ po::variables_map varmap;
+
+ if (argc == 2 && ! boost::starts_with(argv[1], "--"))
+ {
+ // (especially for debugging) options might go into an INI file
+ std::ifstream config_file (argv[1], std::ifstream::in);
+ po::store(po::parse_config_file(config_file, description), varmap);
             }
             else
             {
- // Case 2
- p.fulltype = p.type + " " + p.name;
+ po::store(po::parse_command_line(argc, argv, description), varmap);
             }
 
- add_or_set(parameters, p);
- }
+ po::notify(varmap);
 
- parse_parameter_list(node->first_node(), parameters);
- parse_parameter_list(node->next_sibling(), parameters);
- }
-}
-
-
-template <typename Element>
-static void parse_element(rapidxml::xml_node<>* node, std::string const& parent, Element& el)
-{
- if (node != NULL)
- {
- std::string name = node->name();
- std::string full = parent + "." + name;
-
- if (full == ".briefdescription.para")
- {
- el.brief_description = node->value();
- }
- else if (full == ".detaileddescription.para")
- {
- std::string const para(node->value());
- if (!para.empty() && !el.detailed_description.empty())
- {
- el.detailed_description += "\n\n";
- }
- el.detailed_description += node->value();
- }
- else if (full == ".location")
- {
- std::string loc = get_attribute(node, "file");
- // Boost.Geometry specific, to make generic: make this path-start configurable
- std::size_t pos = loc.rfind("/boost/geometry/");
- if (pos != std::string::npos)
+ if (varmap.count("help") || filename.empty())
             {
- loc = loc.substr(pos + 1);
+ std::cout << description << std::endl;
+ return 1;
             }
- el.location = loc;
- el.line = atol(get_attribute(node, "line").c_str());
- }
- else if (full == ".detaileddescription.para.qbk")
- {
- el.qbk_markup.push_back(markup(0, boost::trim_copy(std::string(node->value()))));
- }
- else if (full == ".detaileddescription.para.qbk.include")
- {
- el.qbk_markup.push_back(markup(1, boost::trim_copy(std::string(node->value()))));
- }
- else if (full == ".detaileddescription.para.qbk.distinguish")
- {
- el.additional_description = node->value();
- boost::trim(el.additional_description);
- }
- else if (full == ".templateparamlist")
- {
- parse_parameter_list(node->first_node(), el.template_parameters);
- }
- else if (full == ".detaileddescription.para.parameterlist")
- {
- std::string kind = get_attribute(node, "kind");
- if (kind == "param")
- {
- parse_parameter_list(node->first_node(), el.parameters);
- }
- else if (kind == "templateparam")
- {
- parse_parameter_list(node->first_node(), el.template_parameters);
- }
- }
-
- parse_element(node->first_node(), full, el);
- parse_element(node->next_sibling(), parent, el);
- }
-}
-
-static void parse_function(rapidxml::xml_node<>* node, std::string const& parent, function& f)
-{
- if (node != NULL)
- {
- std::string name = node->name();
- std::string full = parent + "." + name;
 
- if (full == ".name") f.name = node->value();
- else if (full == ".argsstring") f.argsstring = node->value();
- else if (full == ".definition")
- {
- f.definition = node->value();
- // Boost.Geometry specific, to make generic: make this namespace-to-be-skipped configurable
- boost::replace_all(f.definition, "boost::geometry::", "");
- }
- else if (full == ".param")
- {
- param p;
- parse_parameter(node->first_node(), p);
- add_or_set(f.parameters, p);
- }
- else if (full == ".type")
- {
- f.return_type = node->value();
- }
- else if (full == ".detaileddescription.para.simplesect")
- {
- std::string kind = get_attribute(node, "kind");
- if (kind == "return")
+ // Split CSV with headerfile names into configuration
+ if (! convenience_headers.empty())
             {
- get_contents(node->first_node(), f.return_description);
+ boost::split(config.convenience_headers, convenience_headers, boost::is_any_of(","));
             }
- /*else if (kind == "param")
- {
- get_contents(node->first_node(), f.paragraphs);
- }*/
- }
- else if (full == ".detaileddescription.para.image")
- {
         }
 
- parse_function(node->first_node(), full, f);
- parse_function(node->next_sibling(), parent, f);
- }
-}
+ // Read files into strings
+ std::string xml_string = file_to_string(filename);
+ std::string license = copyright_filename.empty()
+ ? ""
+ : file_to_string(copyright_filename, true);
 
-static void parse(rapidxml::xml_node<>* node, documentation& doc, bool member = false)
-{
- if (node != NULL)
- {
- bool recurse = false;
- bool is_member = member;
+ // Parse the XML outputted by Doxygen
+ xml_doc xml(xml_string.c_str());
 
- std::string nodename = node->name();
+ documentation doc;
+ parse(xml.first_node(), config, doc);
 
- if (nodename == "doxygen")
- {
- recurse = true;
- }
- else if (nodename == "sectiondef")
+ // Check for duplicate function names
+ for (std::size_t i = 0; i < doc.functions.size(); i++)
         {
- std::string kind = get_attribute(node, "kind");
- if (kind == "func" )
+ function& f1 = doc.functions[i];
+ for (std::size_t j = i + 1; j < doc.functions.size(); j++)
             {
- // Get free function definition
- recurse = true;
- }
- if (kind == "define" )
- {
- // Get define or registration macro
- recurse = true;
- }
- else if (kind == "public-static-func" || kind == "public-func")
- {
- recurse = true;
- is_member = true;
- }
- }
- else if (nodename == "compounddef")
- {
- std::string kind = get_attribute(node, "kind");
- if (kind == "group")
- {
- recurse = true;
- }
- if (kind == "struct" || kind == "class")
- {
- recurse = true;
- parse_element(node->first_node(), "", doc.cos);
- }
- }
- else if (nodename == "memberdef")
- {
- std::string kind = get_attribute(node, "kind");
- if (kind == "function" || kind == "define")
- {
- function f;
- parse_element(node->first_node(), "", f);
- parse_function(node->first_node(), "", f);
- if (kind == "define")
- {
- f.type = function_define;
- doc.defines.push_back(f);
- }
- else if (member)
- {
- f.type = f.name == doc.cos.name ? function_constructor : function_member;
- doc.cos.functions.push_back(f);
- }
- else
- {
- f.type = function_free;
- doc.functions.push_back(f);
- }
- }
- }
- else if (nodename == "compoundname")
- {
- std::string name = node->value();
- if (name.find("::") != std::string::npos)
- {
- doc.cos.fullname = name;
+ function& f2 = doc.functions[j];
 
- // For a class, it should have "boost::something::" before
- // set its name without namespace
- doc.cos.name = keep_after(name, "::");
- }
- }
- else
- {
- //std::cout << nodename << " ignored." << std::endl;
- }
-
-
- if (recurse)
- {
- // First recurse into childnodes, then handle next siblings
- parse(node->first_node(), doc, is_member);
- }
- parse(node->next_sibling(), doc, is_member);
- }
-}
-
-void quickbook_template_parameter_list(std::vector<param> const& parameters, std::ostream& out, bool name = false)
-{
- if (!parameters.empty())
- {
- out << "template<" ;
- bool first = true;
- BOOST_FOREACH(param const& p, parameters)
- {
- out << (first ? "" : ", ") << p.fulltype;
- first = false;
- }
- out << ">" << std::endl;
- }
-}
-
-
-void quickbook_synopsis(function const& f, std::ostream& out)
-{
- out << "``";
- quickbook_template_parameter_list(f.template_parameters, out);
- switch(f.type)
- {
- case function_constructor :
- out << f.name;
- break;
- case function_member :
- out << f.return_type << " " << f.name;
- break;
- case function_free :
- out << f.definition;
- break;
- case function_define :
- {
- out << "#define " << f.name;
- bool first = true;
- BOOST_FOREACH(param const& p, f.parameters)
+ if (f1.name == f2.name)
                 {
- out << (first ? "(" : ", ") << p.name;
- first = false;
- }
- if (! first)
- {
- out << ")";
+ // It is not a unique function, so e.g. an overload,
+ // so a description must distinguish them.
+ // Difference is either the number of parameters, or a const / non-const version
+ // Use the "\qbk{distinguish,with strategy}" in the source code to distinguish
+ f1.unique = false;
+ f2.unique = false;
                 }
             }
- break;
- case function_unknown :
- // do nothing
- break;
- }
- if (! f.argsstring.empty())
- {
- out << " " << f.argsstring;
- }
- out << "``" << std::endl
- << std::endl;
-}
-
-inline bool includes(std::string const& filename, std::string const& header)
-{
- std::string result;
-
- std::ifstream cpp_file(filename.c_str());
- if (cpp_file.is_open())
- {
- while (! cpp_file.eof() )
- {
- std::string line;
- std::getline(cpp_file, line);
- boost::trim(line);
- if (boost::starts_with(line, "#include")
- && boost::contains(line, header))
- {
- return true;
- }
- }
- }
- return false;
-}
-
-
-void quickbook_header(std::string const& location,
- configuration const& config,
- std::ostream& out)
-{
- if (! location.empty())
- {
- std::vector<std::string> including_headers;
-
- // Check all headerfiles to see if this specific headerfile is found
- BOOST_FOREACH(std::string const& headerfile, config.headerfiles)
- {
- if (includes(config.prefix + headerfile, location))
- {
- including_headers.push_back(headerfile);
- }
- }
-
- out << "[heading Header]" << std::endl;
- if (! including_headers.empty())
- {
- out << "Either"
- << (including_headers.size() > 1 ? " one of" : "")
- << std::endl << std::endl;
- BOOST_FOREACH(std::string const& headerfile, including_headers)
- {
- out << "`#include <" << headerfile << ">`" << std::endl;
- }
-
- out << std::endl << "Or" << std::endl << std::endl;
- }
- out << "`#include <" << location << ">`" << std::endl;
- out << std::endl;
- }
-}
-
-
-void quickbook_markup(std::vector<markup> const& qbk_markup, std::ostream& out)
-{
- BOOST_FOREACH(markup const& inc, qbk_markup)
- {
- switch(inc.code)
- {
- case 0 :
- // Verbatim
- out << inc.value << std::endl;
- break;
- case 1 :
- out << "[include " << inc.value << "]" << std::endl;
- break;
- }
- }
-}
-
-
-
-void quickbook_heading_string(std::string const& heading,
- std::string const& contents, std::ostream& out)
-{
- if (! contents.empty())
- {
- out << "[heading " << heading << "]" << std::endl
- << contents << std::endl
- << std::endl;
- }
-}
-
-inline std::string to_section_name(std::string const& name)
-{
- // Make section-name lowercase and remove :: because these are filenames
- return boost::to_lower_copy(boost::replace_all_copy(name, "::", "_"));
-}
-
-
-
-void quickbook_output(function const& f, configuration const& config, std::ostream& out)
-{
- // Write the parsed function
- int arity = (int)f.parameters.size();
-
- std::string additional_description;
-
- if (! f.additional_description.empty())
- {
- additional_description = " (";
- additional_description += f.additional_description;
- additional_description += ")";
- }
-
- out << "[section:" << to_section_name(f.name);
- // Make section name unique if necessary by arity and additional description
- if (! f.unique)
- {
- out << "_" << arity;
- if (! f.additional_description.empty())
- {
- out << "_" << boost::to_lower_copy(boost::replace_all_copy(f.additional_description, " ", "_"));
         }
- }
- out << " " << f.name
- << additional_description
- << "]" << std::endl
- << std::endl;
-
- out << f.brief_description << std::endl;
- out << std::endl;
-
- quickbook_heading_string("Description", f.detailed_description, out);
 
- out << "[heading Synopsis]" << std::endl;
- quickbook_synopsis(f, out);
 
- out << "[heading Parameters]" << std::endl
- << std::endl;
-
- out << "[table" << std::endl << "[";
- if (f.type != function_define)
- {
- out << "[Type] [Concept] ";
- }
- out << "[Name] [Description] ]" << std::endl;
-
- // First: output any template parameter which is NOT used in the normal parameter list
- BOOST_FOREACH(param const& tp, f.template_parameters)
- {
- std::vector<param>::const_iterator it = std::find_if(f.parameters.begin(), f.parameters.end(), par_by_type(tp.name));
-
- if (it == f.parameters.end())
+ // Write copyright/license (keep inspect silent)
+ if (! license.empty())
         {
- out << "[[" << tp.name << "] [" << tp.description << "] [ - ] [Must be specified]]" << std::endl;
+ std::cout << license << std::endl;
         }
 
- }
+ // Write warning comment
+ std::cout
+ << "[/ Generated by doxygen_xml2qbk, don't change, will be overwritten automatically]" << std::endl
+ << "[/ Generated from " << filename << "]" << std::endl;
 
- BOOST_FOREACH(param const& p, f.parameters)
- {
- out << "[";
- std::vector<param>::const_iterator it = std::find_if(f.template_parameters.begin(),
- f.template_parameters.end(), par_by_name(p.type));
-
- if (f.type != function_define)
+ // Write the rest: functions, defines, classes or structs
+ BOOST_FOREACH(function const& f, doc.functions)
         {
- out << "[" << p.fulltype
- << "] [" << (it == f.template_parameters.end() ? "" : it->description)
- << "] ";
+ quickbook_output(f, config, std::cout);
         }
- out << "[" << p.name
- << "] [" << p.description
- << "]]"
- << std::endl;
- }
- out << "]" << std::endl
- << std::endl
- << std::endl;
-
- quickbook_heading_string("Returns", f.return_description, out);
-
- quickbook_header(f.location, config, out);
-
- quickbook_markup(f.qbk_markup, out);
-
- out << std::endl;
- out << "[endsect]" << std::endl;
- out << std::endl;
-}
-
-
-void quickbook_short_output(function const& f, std::ostream& out)
-{
- BOOST_FOREACH(param const& p, f.parameters)
- {
- out << "[* " << p.fulltype << "]: ['" << p.name << "]: " << p.description << std::endl << std::endl;
- }
- out << std::endl;
- out << std::endl;
-
- if (! f.return_description.empty())
- {
- out << "][" << std::endl;
- out << f.return_description << std::endl;
- out << std::endl;
- }
-
- out << std::endl;
-}
-
-void quickbook_output(class_or_struct const& cos, configuration const& config, std::ostream& out)
-{
- // Boost.Geometry specific, to make generic: make this namespace-to-be-skipped configurable
- std::string short_name =
- boost::replace_all_copy(cos.fullname, "boost::geometry::", "");
-
- // Write the parsed function
- out << "[section:" << to_section_name(short_name) << " " << short_name << "]" << std::endl
- << std::endl;
-
- quickbook_heading_string("Description", cos.detailed_description, out);
-
- out << "[heading Synopsis]" << std::endl
- << "``";
- quickbook_template_parameter_list(cos.template_parameters, out);
- out << "class " << short_name << std::endl
- << "{" << std::endl
- << " // ..." << std::endl
- << "};" << std::endl
- << "``" << std::endl << std::endl;
-
- if (! cos.template_parameters.empty())
- {
- out << "[heading Template parameter(s)]" << std::endl
- << "[table" << std::endl
- << "[[Parameter] [Description]]" << std::endl;
-
- BOOST_FOREACH(param const& p, cos.template_parameters)
+ BOOST_FOREACH(function const& f, doc.defines)
         {
- out << "[[" << p.fulltype << "] [" << p.description << "]]" << std::endl;
+ quickbook_output(f, config, std::cout);
         }
- out << "]" << std::endl
- << std::endl;
- }
-
-
- std::map<function_type, int> counts;
- BOOST_FOREACH(function const& f, cos.functions)
- {
- counts[f.type]++;
- }
-
- if (counts[function_constructor] > 0)
- {
- out << "[heading Constructor(s)]" << std::endl
- << "[table" << std::endl
- << "[[Function] [Description] [Parameters] ]" << std::endl;
 
- BOOST_FOREACH(function const& f, cos.functions)
+ if (! doc.cos.name.empty())
         {
- if (f.type == function_constructor)
- {
- out << "[[";
- quickbook_synopsis(f, out);
- out << "] [" << f.brief_description << "] [";
- quickbook_short_output(f, out);
- out << "]]" << std::endl;
- }
+ std::sort(doc.cos.functions.begin(), doc.cos.functions.end(), sort_on_line<function>());
+ quickbook_output(doc.cos, config, std::cout);
         }
- out << "]" << std::endl
- << std::endl;
- }
-
- if (counts[function_member] > 0)
- {
- out << "[heading Member Function(s)]" << std::endl
- << "[table" << std::endl
- << "[[Function] [Description] [Parameters] [Returns] ]" << std::endl;
 
- BOOST_FOREACH(function const& f, cos.functions)
- {
- if (f.type == function_member)
- {
- out << "[[";
- quickbook_synopsis(f, out);
- out << "] [" << f.brief_description << "] [";
- quickbook_short_output(f, out);
- out << "]]" << std::endl;
- }
- }
- out << "]" << std::endl
- << std::endl;
     }
-
- quickbook_header(cos.location, config, out);
- //quickbook_examples(cos.examples, out);
- quickbook_markup(cos.qbk_markup, out);
-
- out << "[endsect]" << std::endl
- << std::endl;
-}
-
-inline bool equal_ignore_fix(std::string const& a, std::string const& b, std::string const &fix)
-{
- return fix + a == b || a == fix + b
- || a + fix == b || a == b + fix;
-}
-
-
-int main(int argc, char** argv)
-{
- // TODO: use boost::program_options
- if (argc < 2)
+ catch(std::exception const& e)
     {
- std::cerr
- << "Usage: doxygen_xml2qbk [XML-filename] {prefix CH} {convenience header (CH) 1} {CH 2} ..." << std::endl
- << " where the XML refers to an XML written by Doxygen" << std::endl;
- return 1;
+ std::cerr << "Exception: " << e.what() << std::endl;
     }
-
- std::string filename = argv[1];
- std::string xml_string = file_to_string(filename);
-
- xml_doc xml(xml_string.c_str());
-
- documentation doc;
- parse(xml.first_node(), doc);
-
- for (std::size_t i = 0; i < doc.functions.size(); i++)
+ catch(...)
     {
- function& f1 = doc.functions[i];
- for (std::size_t j = i + 1; j < doc.functions.size(); j++)
- {
- function& f2 = doc.functions[j];
-
- if (f1.name == f2.name)
- {
- // It is not a unique function, so e.g. an overload,
- // so a description must distinguish them.
- // Difference is either the number of parameters, or a const / non-const version
- // Use the "\qbk{distinguish,with strategy}" in the source code to distinguish
- f1.unique = false;
- f2.unique = false;
- }
- }
- }
-
- configuration config;
- if (argc > 2)
- {
- config.prefix = argv[2];
- for (int i = 3; i < argc; i++)
- {
- config.headerfiles.push_back(argv[i]);
- }
+ std::cerr << "Unknown exception!" << std::endl;
     }
-
- // Keep inspect silent. TODO: read this block from a file.
- std::cout
- << "[/============================================================================" << std::endl
- << " Boost.Geometry (aka GGL, Generic Geometry Library)" << std::endl
- << std::endl
- << " Copyright (c) 2009-2011 Barend Gehrels, Geodan, Amsterdam, the Netherlands." << std::endl
- << " Copyright (c) 2009-2011 Mateusz Loskot (mateusz_at_[hidden])" << std::endl
- << " Copyright (c) 2009-2011 Bruno Lalande, Paris, France." << std::endl
- << std::endl
- << " Use, modification and distribution is subject to the Boost Software License," << std::endl
- << " Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at" << std::endl
- << " http://www.boost.org/LICENSE_1_0.txt)" << std::endl
- << "=============================================================================/]" << std::endl
- << std::endl
- << std::endl;
-
- std::cout
- << "[/ Generated by doxygen_xml2qbk, don't change, it will be overwritten automatically]" << std::endl
- << "[/ Generated from " << filename << "]" << std::endl;
-
- BOOST_FOREACH(function const& f, doc.functions)
- {
- quickbook_output(f, config, std::cout);
- }
- BOOST_FOREACH(function const& f, doc.defines)
- {
- quickbook_output(f, config, std::cout);
- }
-
- if (! doc.cos.name.empty())
- {
- std::sort(doc.cos.functions.begin(), doc.cos.functions.end(), sort_on_line<function>());
- quickbook_output(doc.cos, config, std::cout);
- }
-
     return 0;
 }
 

Modified: trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml2qbk.vcproj
==============================================================================
--- trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml2qbk.vcproj (original)
+++ trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml2qbk.vcproj 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -41,7 +41,7 @@
                                 Name="VCCLCompilerTool"
                                 Optimization="0"
                                 AdditionalIncludeDirectories=".;contrib/rapidxml-1.13"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE; _CRT_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;BOOST_ALL_NO_LIB"
                                 MinimalRebuild="true"
                                 BasicRuntimeChecks="3"
                                 RuntimeLibrary="3"
@@ -117,7 +117,7 @@
                         <Tool
                                 Name="VCCLCompilerTool"
                                 AdditionalIncludeDirectories=".;contrib/rapidxml-1.13"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE; _CRT_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;BOOST_ALL_NO_LIB"
                                 RuntimeLibrary="2"
                                 UsePrecompiledHeader="0"
                                 WarningLevel="3"
@@ -172,6 +172,50 @@
         <References>
         </References>
         <Files>
+ <Filter
+ Name="program options"
+ >
+ <File
+ RelativePath="..\..\..\..\..\..\program_options\src\cmdline.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\..\program_options\src\config_file.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\..\program_options\src\convert.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\..\program_options\src\options_description.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\..\program_options\src\parsers.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\..\program_options\src\positional_options.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\..\program_options\src\split.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\..\program_options\src\utf8_codecvt_facet.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\..\program_options\src\value_semantic.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\..\program_options\src\variables_map.cpp"
+ >
+ </File>
+ </Filter>
                 <File
                         RelativePath=".\doxygen_xml2qbk.cpp"
>

Added: trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml_parser.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/doxygen_xml_parser.hpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -0,0 +1,396 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands
+// Use, modification and distribution is subject to 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)
+//
+//
+#ifndef DOXYGEN_XML_PARSER_HPP
+#define DOXYGEN_XML_PARSER_HPP
+
+
+#include <string>
+#include <vector>
+
+#include <boost/algorithm/string.hpp>
+
+#include <rapidxml_util.hpp>
+#include <doxygen_elements.hpp>
+#include <parameter_predicates.hpp>
+#include <configuration.hpp>
+
+
+inline std::string keep_after(std::string const& input, std::string const& sig)
+{
+ std::size_t pos = input.rfind(sig);
+ if (pos != std::string::npos)
+ {
+ std::string copy = input.substr(pos + sig.length());
+ return copy;
+ }
+ return input;
+}
+
+
+
+static inline void add_or_set(std::vector<param>& parameters, param const& p)
+{
+ std::vector<param>::iterator it = std::find_if(parameters.begin(), parameters.end(), par_by_name(p.name));
+ if (it != parameters.end())
+ {
+ if (it->description.empty()) it->description = p.description;
+ if (it->type.empty()) it->type = p.type;
+ if (it->fulltype.empty()) it->fulltype = p.fulltype;
+ }
+ else
+ {
+ parameters.push_back(p);
+ }
+}
+
+// -------------------------------------------------------------
+// -------------------------------------------------------------
+static void parse_para(rapidxml::xml_node<>* node, std::string& contents, bool first = true)
+{
+ if (node != NULL)
+ {
+ if (node->type() == rapidxml::node_element)
+ {
+ //std::cout << "ELEMENT: " << node->name() << "=" << node->value() << std::endl;
+ std::string name = node->name();
+ if (! boost::equals(name, "para")
+ && ! boost::equals(name, "ref")
+ && ! boost::equals(name, "verbatim"))
+ {
+ return;
+ }
+ if (boost::equals(name, "para") && ! first)
+ {
+ return;
+ }
+ }
+ else if (node->type() == rapidxml::node_data)
+ {
+ contents += node->value();
+ //std::cout << "DATA: " << node->name() << "=" << node->value() << std::endl;
+ }
+ else
+ {
+ //std::cout << "OTHER: " << node->name() << "=" << node->value() << std::endl;
+ }
+ parse_para(node->first_node(), contents, false);
+ parse_para(node->next_sibling(), contents, false);
+ }
+}
+
+
+static void parse_parameter(rapidxml::xml_node<>* node, param& p)
+{
+ if (node != NULL)
+ {
+ std::string name = node->name();
+ if (name == "type")
+ {
+ p.fulltype = node->value();
+ p.type = p.fulltype;
+ boost::replace_all(p.type, " const", "");
+ boost::trim(p.type);
+ boost::replace_all(p.type, "&", "");
+ boost::replace_all(p.type, "*", "");
+ boost::trim(p.type);
+ }
+ else if (name == "declname") p.name = node->value();
+ else if (name == "parametername") p.name = node->value();
+ // Define: <param><defname>Point</defname></param>
+ else if (name == "defname") p.name = node->value(); // for defines
+ else if (name == "para")
+ {
+ parse_para(node, p.description);
+ }
+
+ parse_parameter(node->first_node(), p);
+ parse_parameter(node->next_sibling(), p);
+ }
+}
+
+// Definition is a function or a class/struct
+template <typename Parameters>
+static void parse_parameter_list(rapidxml::xml_node<>* node, Parameters& parameters)
+{
+ if (node != NULL)
+ {
+ std::string name = node->name();
+
+ if (name == "parameteritem")
+ {
+ param p;
+ parse_parameter(node->first_node(), p);
+ if (! p.name.empty())
+ {
+ // Copy its description
+ std::vector<param>::iterator it = std::find_if(parameters.begin(),
+ parameters.end(), par_by_name(p.name));
+ if (it != parameters.end())
+ {
+ it->description = p.description;
+ }
+ else
+ {
+ parameters.push_back(p);
+ }
+ }
+ }
+ else if (name == "param")
+ {
+ // Element of 'templateparamlist.param (.type,.declname,.defname)'
+ param p;
+ parse_parameter(node->first_node(), p);
+
+ // Doxygen handles templateparamlist param's differently:
+ //
+ // Case 1:
+ // <param><type>typename T</type></param>
+ // -> no name, assign type to name, replace typename
+ //
+ // Case 2:
+ // <type>typename</type><declname>T</declname><defname>T</defname>
+ // -> set full type
+ if (p.name.empty())
+ {
+ // Case 1
+ p.name = p.type;
+ boost::replace_all(p.name, "typename", "");
+ boost::trim(p.name);
+ }
+ else
+ {
+ // Case 2
+ p.fulltype = p.type + " " + p.name;
+ }
+
+ add_or_set(parameters, p);
+ }
+
+ parse_parameter_list(node->first_node(), parameters);
+ parse_parameter_list(node->next_sibling(), parameters);
+ }
+}
+
+
+template <typename Element>
+static void parse_element(rapidxml::xml_node<>* node, configuration const& config, std::string const& parent, Element& el)
+{
+ if (node != NULL)
+ {
+ std::string name = node->name();
+ std::string full = parent + "." + name;
+
+ if (full == ".briefdescription.para")
+ {
+ parse_para(node, el.brief_description);
+ }
+ else if (full == ".detaileddescription.para")
+ {
+ std::string para;
+ parse_para(node, para);
+ if (!para.empty() && !el.detailed_description.empty())
+ {
+ el.detailed_description += "\n\n";
+ }
+ el.detailed_description += para;
+ }
+ else if (full == ".location")
+ {
+ std::string loc = get_attribute(node, "file");
+ // Location of (header)file. It is a FULL path, so find the start
+ // and strip the rest
+ std::size_t pos = loc.rfind(config.start_include);
+ if (pos != std::string::npos)
+ {
+ loc = loc.substr(pos);
+ }
+ el.location = loc;
+ el.line = atol(get_attribute(node, "line").c_str());
+ }
+ else if (full == ".detaileddescription.para.qbk")
+ {
+ el.qbk_markup.push_back(markup(0, boost::trim_copy(std::string(node->value()))));
+ }
+ else if (full == ".detaileddescription.para.qbk.include")
+ {
+ el.qbk_markup.push_back(markup(1, boost::trim_copy(std::string(node->value()))));
+ }
+ else if (full == ".detaileddescription.para.qbk.distinguish")
+ {
+ el.additional_description = node->value();
+ boost::trim(el.additional_description);
+ }
+ else if (full == ".templateparamlist")
+ {
+ parse_parameter_list(node->first_node(), el.template_parameters);
+ }
+ else if (full == ".detaileddescription.para.parameterlist")
+ {
+ std::string kind = get_attribute(node, "kind");
+ if (kind == "param")
+ {
+ parse_parameter_list(node->first_node(), el.parameters);
+ }
+ else if (kind == "templateparam")
+ {
+ parse_parameter_list(node->first_node(), el.template_parameters);
+ }
+ }
+
+ parse_element(node->first_node(), config, full, el);
+ parse_element(node->next_sibling(), config, parent, el);
+ }
+}
+
+static void parse_function(rapidxml::xml_node<>* node, configuration const& config, std::string const& parent, function& f)
+{
+ if (node != NULL)
+ {
+ std::string name = node->name();
+ std::string full = parent + "." + name;
+
+ if (full == ".name") f.name = node->value();
+ else if (full == ".argsstring") f.argsstring = node->value();
+ else if (full == ".definition")
+ {
+ f.definition = node->value();
+ if (! config.skip_namespace.empty())
+ {
+ boost::replace_all(f.definition, config.skip_namespace, "");
+ }
+ }
+ else if (full == ".param")
+ {
+ param p;
+ parse_parameter(node->first_node(), p);
+ add_or_set(f.parameters, p);
+ }
+ else if (full == ".type")
+ {
+ f.return_type = node->value();
+ }
+ else if (full == ".detaileddescription.para.simplesect")
+ {
+ std::string kind = get_attribute(node, "kind");
+ if (kind == "return")
+ {
+ get_contents(node->first_node(), f.return_description);
+ }
+ /*else if (kind == "param")
+ {
+ get_contents(node->first_node(), f.paragraphs);
+ }*/
+ }
+ else if (full == ".detaileddescription.para.image")
+ {
+ }
+
+ parse_function(node->first_node(), config, full, f);
+ parse_function(node->next_sibling(), config, parent, f);
+ }
+}
+
+static void parse(rapidxml::xml_node<>* node, configuration const& config, documentation& doc, bool member = false)
+{
+ if (node != NULL)
+ {
+ bool recurse = false;
+ bool is_member = member;
+
+ std::string nodename = node->name();
+
+ if (nodename == "doxygen")
+ {
+ recurse = true;
+ }
+ else if (nodename == "sectiondef")
+ {
+ std::string kind = get_attribute(node, "kind");
+ if (kind == "func" )
+ {
+ // Get free function definition
+ recurse = true;
+ }
+ if (kind == "define" )
+ {
+ // Get define or registration macro
+ recurse = true;
+ }
+ else if (kind == "public-static-func" || kind == "public-func")
+ {
+ recurse = true;
+ is_member = true;
+ }
+ }
+ else if (nodename == "compounddef")
+ {
+ std::string kind = get_attribute(node, "kind");
+ if (kind == "group")
+ {
+ recurse = true;
+ }
+ if (kind == "struct" || kind == "class")
+ {
+ recurse = true;
+ parse_element(node->first_node(), config, "", doc.cos);
+ }
+ }
+ else if (nodename == "memberdef")
+ {
+ std::string kind = get_attribute(node, "kind");
+ if (kind == "function" || kind == "define")
+ {
+ function f;
+ parse_element(node->first_node(), config, "", f);
+ parse_function(node->first_node(), config, "", f);
+ if (kind == "define")
+ {
+ f.type = function_define;
+ doc.defines.push_back(f);
+ }
+ else if (member)
+ {
+ f.type = f.name == doc.cos.name ? function_constructor : function_member;
+ doc.cos.functions.push_back(f);
+ }
+ else
+ {
+ f.type = function_free;
+ doc.functions.push_back(f);
+ }
+ }
+ }
+ else if (nodename == "compoundname")
+ {
+ std::string name = node->value();
+ if (name.find("::") != std::string::npos)
+ {
+ doc.cos.fullname = name;
+
+ // For a class, it should have "boost::something::" before
+ // set its name without namespace
+ doc.cos.name = keep_after(name, "::");
+ }
+ }
+ else
+ {
+ //std::cout << nodename << " ignored." << std::endl;
+ }
+
+
+ if (recurse)
+ {
+ // First recurse into childnodes, then handle next siblings
+ parse(node->first_node(), config, doc, is_member);
+ }
+ parse(node->next_sibling(), config, doc, is_member);
+ }
+}
+
+#endif // DOXYGEN_XML_PARSER_HPP

Modified: trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/file_to_string.hpp
==============================================================================
--- trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/file_to_string.hpp (original)
+++ trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/file_to_string.hpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -15,7 +15,8 @@
 
 #include <boost/algorithm/string.hpp>
 
-inline std::string file_to_string(std::string const& filename)
+
+inline std::string file_to_string(std::string const& filename, bool add_nl = false)
 {
     std::string result;
 
@@ -29,6 +30,11 @@
             boost::trim(line);
 
             result += line;
+
+ if (add_nl)
+ {
+ result += "\n";
+ }
         }
     }
     return result;

Added: trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/parameter_predicates.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/parameter_predicates.hpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -0,0 +1,60 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands
+// Use, modification and distribution is subject to 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)
+//
+//
+#ifndef PARAMETER_PREDICATES_HPP
+#define PARAMETER_PREDICATES_HPP
+
+
+#include <string>
+
+#include <doxygen_elements.hpp>
+
+
+// Predicate for std::find_if
+struct par_by_name
+{
+ par_by_name(std::string const& n)
+ : m_name(n)
+ {}
+
+ inline bool operator()(param const& p)
+ {
+ return p.name == m_name;
+ }
+private :
+ std::string m_name;
+};
+
+
+// Predicate for std::find_if
+struct par_by_type
+{
+ par_by_type(std::string const& n)
+ : m_type(n)
+ {}
+
+ inline bool operator()(param const& p)
+ {
+ return p.type == m_type;
+ }
+private :
+ std::string m_type;
+};
+
+
+template <typename Element>
+struct sort_on_line
+{
+ inline bool operator()(Element const& left, Element const& right)
+ {
+ return left.line < right.line;
+ }
+};
+
+
+#endif // PARAMETER_PREDICATES_HPP

Added: trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/quickbook_output.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/quickbook_output.hpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -0,0 +1,381 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands
+// Use, modification and distribution is subject to 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)
+//
+//
+#ifndef QUICKBOOK_OUTPUT_HPP
+#define QUICKBOOK_OUTPUT_HPP
+
+
+#include <string>
+#include <vector>
+
+#include <boost/algorithm/string.hpp>
+
+#include <doxygen_elements.hpp>
+#include <parameter_predicates.hpp>
+
+
+void quickbook_template_parameter_list(std::vector<param> const& parameters, std::ostream& out, bool name = false)
+{
+ if (!parameters.empty())
+ {
+ out << "template<" ;
+ bool first = true;
+ BOOST_FOREACH(param const& p, parameters)
+ {
+ out << (first ? "" : ", ") << p.fulltype;
+ first = false;
+ }
+ out << ">" << std::endl;
+ }
+}
+
+
+void quickbook_synopsis(function const& f, std::ostream& out)
+{
+ out << "``";
+ quickbook_template_parameter_list(f.template_parameters, out);
+ switch(f.type)
+ {
+ case function_constructor :
+ out << f.name;
+ break;
+ case function_member :
+ out << f.return_type << " " << f.name;
+ break;
+ case function_free :
+ out << f.definition;
+ break;
+ case function_define :
+ {
+ out << "#define " << f.name;
+ bool first = true;
+ BOOST_FOREACH(param const& p, f.parameters)
+ {
+ out << (first ? "(" : ", ") << p.name;
+ first = false;
+ }
+ if (! first)
+ {
+ out << ")";
+ }
+ }
+ break;
+ case function_unknown :
+ // do nothing
+ break;
+ }
+ if (! f.argsstring.empty())
+ {
+ out << " " << f.argsstring;
+ }
+ out << "``" << std::endl
+ << std::endl;
+}
+
+inline bool includes(std::string const& filename, std::string const& header)
+{
+ std::string result;
+
+ std::ifstream cpp_file(filename.c_str());
+ if (cpp_file.is_open())
+ {
+ while (! cpp_file.eof() )
+ {
+ std::string line;
+ std::getline(cpp_file, line);
+ boost::trim(line);
+ if (boost::starts_with(line, "#include")
+ && boost::contains(line, header))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+void quickbook_header(std::string const& location,
+ configuration const& config,
+ std::ostream& out)
+{
+ if (! location.empty())
+ {
+ std::vector<std::string> including_headers;
+
+ // Select headerfiles containing to this location
+ BOOST_FOREACH(std::string const& header, config.convenience_headers)
+ {
+ if (includes(config.convenience_header_path + header, location))
+ {
+ including_headers.push_back(header);
+ }
+ }
+
+ out << "[heading Header]" << std::endl;
+ if (! including_headers.empty())
+ {
+ out << "Either"
+ << (including_headers.size() > 1 ? " one of" : "")
+ << std::endl << std::endl;
+ BOOST_FOREACH(std::string const& header, including_headers)
+ {
+ out << "`#include <" << config.start_include << header << ">`" << std::endl;
+ }
+
+ out << std::endl << "Or" << std::endl << std::endl;
+ }
+ out << "`#include <" << location << ">`" << std::endl;
+ out << std::endl;
+ }
+}
+
+
+void quickbook_markup(std::vector<markup> const& qbk_markup, std::ostream& out)
+{
+ BOOST_FOREACH(markup const& inc, qbk_markup)
+ {
+ switch(inc.code)
+ {
+ case 0 :
+ // Verbatim
+ out << inc.value << std::endl;
+ break;
+ case 1 :
+ out << "[include " << inc.value << "]" << std::endl;
+ break;
+ }
+ }
+}
+
+
+
+void quickbook_heading_string(std::string const& heading,
+ std::string const& contents, std::ostream& out)
+{
+ if (! contents.empty())
+ {
+ out << "[heading " << heading << "]" << std::endl
+ << contents << std::endl
+ << std::endl;
+ }
+}
+
+inline std::string to_section_name(std::string const& name)
+{
+ // Make section-name lowercase and remove :: because these are filenames
+ return boost::to_lower_copy(boost::replace_all_copy(name, "::", "_"));
+}
+
+
+
+void quickbook_output(function const& f, configuration const& config, std::ostream& out)
+{
+ // Write the parsed function
+ int arity = (int)f.parameters.size();
+
+ std::string additional_description;
+
+ if (! f.additional_description.empty())
+ {
+ additional_description = " (";
+ additional_description += f.additional_description;
+ additional_description += ")";
+ }
+
+ out << "[section:" << to_section_name(f.name);
+ // Make section name unique if necessary by arity and additional description
+ if (! f.unique)
+ {
+ out << "_" << arity;
+ if (! f.additional_description.empty())
+ {
+ out << "_" << boost::to_lower_copy(boost::replace_all_copy(f.additional_description, " ", "_"));
+ }
+ }
+ out << " " << f.name
+ << additional_description
+ << "]" << std::endl
+ << std::endl;
+
+ out << f.brief_description << std::endl;
+ out << std::endl;
+
+ quickbook_heading_string("Description", f.detailed_description, out);
+
+ out << "[heading Synopsis]" << std::endl;
+ quickbook_synopsis(f, out);
+
+ out << "[heading Parameters]" << std::endl
+ << std::endl;
+
+ out << "[table" << std::endl << "[";
+ if (f.type != function_define)
+ {
+ out << "[Type] [Concept] ";
+ }
+ out << "[Name] [Description] ]" << std::endl;
+
+ // First: output any template parameter which is NOT used in the normal parameter list
+ BOOST_FOREACH(param const& tp, f.template_parameters)
+ {
+ std::vector<param>::const_iterator it = std::find_if(f.parameters.begin(), f.parameters.end(), par_by_type(tp.name));
+
+ if (it == f.parameters.end())
+ {
+ out << "[[" << tp.name << "] [" << tp.description << "] [ - ] [Must be specified]]" << std::endl;
+ }
+
+ }
+
+ BOOST_FOREACH(param const& p, f.parameters)
+ {
+ out << "[";
+ std::vector<param>::const_iterator it = std::find_if(f.template_parameters.begin(),
+ f.template_parameters.end(), par_by_name(p.type));
+
+ if (f.type != function_define)
+ {
+ out << "[" << p.fulltype
+ << "] [" << (it == f.template_parameters.end() ? "" : it->description)
+ << "] ";
+ }
+ out << "[" << p.name
+ << "] [" << p.description
+ << "]]"
+ << std::endl;
+ }
+ out << "]" << std::endl
+ << std::endl
+ << std::endl;
+
+ quickbook_heading_string("Returns", f.return_description, out);
+
+ quickbook_header(f.location, config, out);
+ quickbook_markup(f.qbk_markup, out);
+
+ out << std::endl;
+ out << "[endsect]" << std::endl;
+ out << std::endl;
+}
+
+
+void quickbook_short_output(function const& f, std::ostream& out)
+{
+ BOOST_FOREACH(param const& p, f.parameters)
+ {
+ out << "[* " << p.fulltype << "]: ['" << p.name << "]: " << p.description << std::endl << std::endl;
+ }
+ out << std::endl;
+ out << std::endl;
+
+ if (! f.return_description.empty())
+ {
+ out << "][" << std::endl;
+ out << f.return_description << std::endl;
+ out << std::endl;
+ }
+
+ out << std::endl;
+}
+
+void quickbook_output(class_or_struct const& cos, configuration const& config, std::ostream& out)
+{
+ // Skip namespace
+ std::string short_name = config.skip_namespace.empty()
+ ? cos.fullname
+ : boost::replace_all_copy(cos.fullname, config.skip_namespace, "");
+
+ // Write the parsed function
+ out << "[section:" << to_section_name(short_name) << " " << short_name << "]" << std::endl
+ << std::endl;
+
+ out << cos.brief_description << std::endl;
+ out << std::endl;
+
+ quickbook_heading_string("Description", cos.detailed_description, out);
+
+ out << "[heading Synopsis]" << std::endl
+ << "``";
+ quickbook_template_parameter_list(cos.template_parameters, out);
+ out << "class " << short_name << std::endl
+ << "{" << std::endl
+ << " // ..." << std::endl
+ << "};" << std::endl
+ << "``" << std::endl << std::endl;
+
+ if (! cos.template_parameters.empty())
+ {
+ out << "[heading Template parameter(s)]" << std::endl
+ << "[table" << std::endl
+ << "[[Parameter] [Description]]" << std::endl;
+
+ BOOST_FOREACH(param const& p, cos.template_parameters)
+ {
+ out << "[[" << p.fulltype << "] [" << p.description << "]]" << std::endl;
+ }
+ out << "]" << std::endl
+ << std::endl;
+ }
+
+
+ std::map<function_type, int> counts;
+ BOOST_FOREACH(function const& f, cos.functions)
+ {
+ counts[f.type]++;
+ }
+
+ if (counts[function_constructor] > 0)
+ {
+ out << "[heading Constructor(s)]" << std::endl
+ << "[table" << std::endl
+ << "[[Function] [Description] [Parameters] ]" << std::endl;
+
+ BOOST_FOREACH(function const& f, cos.functions)
+ {
+ if (f.type == function_constructor)
+ {
+ out << "[[";
+ quickbook_synopsis(f, out);
+ out << "] [" << f.brief_description << "] [";
+ quickbook_short_output(f, out);
+ out << "]]" << std::endl;
+ }
+ }
+ out << "]" << std::endl
+ << std::endl;
+ }
+
+ if (counts[function_member] > 0)
+ {
+ out << "[heading Member Function(s)]" << std::endl
+ << "[table" << std::endl
+ << "[[Function] [Description] [Parameters] [Returns] ]" << std::endl;
+
+ BOOST_FOREACH(function const& f, cos.functions)
+ {
+ if (f.type == function_member)
+ {
+ out << "[[";
+ quickbook_synopsis(f, out);
+ out << "] [" << f.brief_description << "] [";
+ quickbook_short_output(f, out);
+ out << "]]" << std::endl;
+ }
+ }
+ out << "]" << std::endl
+ << std::endl;
+ }
+
+ quickbook_header(cos.location, config, out);
+ quickbook_markup(cos.qbk_markup, out);
+
+ out << "[endsect]" << std::endl
+ << std::endl;
+}
+#endif // QUICKBOOK_OUTPUT_HPP

Added: trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/rapidxml_util.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/rapidxml_util.hpp 2011-01-22 10:30:44 EST (Sat, 22 Jan 2011)
@@ -0,0 +1,56 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands
+// Use, modification and distribution is subject to 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)
+//
+//
+#ifndef RAPIDXML_UTIL_HPP
+#define RAPIDXML_UTIL_HPP
+
+
+#include <string>
+#include <rapidxml.hpp>
+
+class xml_doc : public rapidxml::xml_document<>
+{
+ public :
+ xml_doc(const char* xml)
+ {
+ // Make a copy because rapidxml destructs string
+ m_copy = new char[strlen(xml) + 1];
+ strcpy(m_copy, xml);
+ this->parse<0>(m_copy);
+ };
+ virtual ~xml_doc()
+ {
+ delete[] m_copy;
+ }
+ private :
+ char* m_copy;
+
+};
+
+inline std::string get_attribute(rapidxml::xml_node<>* node, const char* name)
+{
+ rapidxml::xml_attribute<> *attr = node->first_attribute(name);
+ std::string value;
+ if (attr)
+ {
+ value = attr->value();
+ }
+ return value;
+}
+
+inline void get_contents(rapidxml::xml_node<>* node, std::string& contents)
+{
+ if (node != NULL && node->type() == rapidxml::node_element)
+ {
+ contents += node->value();
+ get_contents(node->first_node(), contents);
+ get_contents(node->next_sibling(), contents);
+ }
+}
+
+#endif // RAPIDXML_UTIL_HPP


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