More flexible header names in .lgf + largely improved doc
authorAlpar Juttner <alpar@cs.elte.hu>
Sat, 17 May 2008 06:30:02 +0100
changeset 156e561aa7675de
parent 155 5c3604513ed0
child 157 2ccc1afc2c52
More flexible header names in .lgf + largely improved doc
doc/Makefile.am
doc/groups.dox
doc/lgf.dox
lemon/lgf_reader.h
lemon/lgf_writer.h
     1.1 --- a/doc/Makefile.am	Mon May 05 11:41:30 2008 +0200
     1.2 +++ b/doc/Makefile.am	Sat May 17 06:30:02 2008 +0100
     1.3 @@ -3,6 +3,7 @@
     1.4  	doc/coding_style.dox \
     1.5  	doc/dirs.dox \
     1.6  	doc/groups.dox \
     1.7 +	doc/lgf.dox \
     1.8  	doc/license.dox \
     1.9  	doc/mainpage.dox \
    1.10  	doc/namespaces.dox \
     2.1 --- a/doc/groups.dox	Mon May 05 11:41:30 2008 +0200
     2.2 +++ b/doc/groups.dox	Sat May 17 06:30:02 2008 +0100
     2.3 @@ -483,25 +483,6 @@
     2.4  */
     2.5  
     2.6  /**
     2.7 -@defgroup section_io Section readers and writers
     2.8 -@ingroup lemon_io
     2.9 -\brief Section readers and writers for LEMON Input-Output.
    2.10 -
    2.11 -This group describes section reader and writer classes that can be 
    2.12 -attached to \ref LemonReader and \ref LemonWriter.
    2.13 -*/
    2.14 -
    2.15 -/**
    2.16 -@defgroup item_io Item readers and writers
    2.17 -@ingroup lemon_io
    2.18 -\brief Item readers and writers for LEMON Input-Output.
    2.19 -
    2.20 -This group describes reader and writer classes for various data types
    2.21 -(e.g. map or attribute values). These classes can be attached to
    2.22 -\ref LemonReader and \ref LemonWriter.
    2.23 -*/
    2.24 -
    2.25 -/**
    2.26  @defgroup eps_io Postscript exporting
    2.27  @ingroup io_group
    2.28  \brief General \c EPS drawer and graph exporter
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/doc/lgf.dox	Sat May 17 06:30:02 2008 +0100
     3.3 @@ -0,0 +1,96 @@
     3.4 +/* -*- C++ -*-
     3.5 + *
     3.6 + * This file is a part of LEMON, a generic C++ optimization library
     3.7 + *
     3.8 + * Copyright (C) 2003-2008
     3.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    3.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    3.11 + *
    3.12 + * Permission to use, modify and distribute this software is granted
    3.13 + * provided that this copyright notice appears in all copies. For
    3.14 + * precise terms see the accompanying LICENSE file.
    3.15 + *
    3.16 + * This software is provided "AS IS" with no warranty of any kind,
    3.17 + * express or implied, and with no claim as to its suitability for any
    3.18 + * purpose.
    3.19 + *
    3.20 + */
    3.21 +
    3.22 +namespace lemon {
    3.23 +/*!
    3.24 +
    3.25 +
    3.26 +
    3.27 +\page lgf-format Lemon Graph Format (LGF)
    3.28 +
    3.29 +The \e LGF is a <em>column oriented</em>
    3.30 +file format for storing graphs and associated data like
    3.31 +node and edge maps.
    3.32 +
    3.33 +Each line with \c '#' first non-whitespace
    3.34 +character is considered as a comment line.
    3.35 +
    3.36 +Otherwise the file consists of sections starting with
    3.37 +a header line. The header lines starts with an \c '@' character followed by the
    3.38 +type of section. The standard section types are \c \@nodes, \c
    3.39 +\@arcs and \c \@edges
    3.40 +and \@attributes. Each header line may also have an optional
    3.41 +\e name, which can be use to distinguish the sections of the same
    3.42 +type.
    3.43 +
    3.44 +The standard sections are column oriented, each line consists of
    3.45 +<em>token</em>s separated by whitespaces. A token can be \e plain or
    3.46 +\e quoted. A plain token is just a sequence of non-whitespace characters,
    3.47 +while a quoted token is a
    3.48 +character sequence surrounded by double quotes, and it can also
    3.49 +contain whitespaces and escape sequences. 
    3.50 +
    3.51 +The \c \@nodes section describes a set of nodes and associated
    3.52 +maps. The first is a header line, it columns are the names of the
    3.53 +maps appearing in the following lines.
    3.54 +One of the maps must be called \c
    3.55 +"label", which plays special role in the file.
    3.56 +The following
    3.57 +non-empty lines until the next section describes nodes of the
    3.58 +graph. Each line contains the values of the node maps
    3.59 +associated to the current node.
    3.60 +
    3.61 +\code
    3.62 + @nodes
    3.63 + label   coordinates size    title
    3.64 + 1       (10,20)     10      "First node"
    3.65 + 2       (80,80)     8       "Second node"
    3.66 + 3       (40,10)     10      "Third node"
    3.67 +\endcode
    3.68 +
    3.69 +The \c \@arcs section is very similar to the \c \@nodes section,
    3.70 +it again starts with a header line describing the names of the arc,
    3.71 +but the \c "label" map is not obligatory here. The following lines
    3.72 +describe the arcs. The first two tokens of each line are
    3.73 +the source and the target node of the arc, respectively, then come the map
    3.74 +values. The source and target tokens must be node labels.
    3.75 +
    3.76 +\code
    3.77 + @arcs
    3.78 + 	      capacity
    3.79 + 1   2   16
    3.80 + 1   3   12
    3.81 + 2   3   18
    3.82 +\endcode
    3.83 +
    3.84 +The \c \@edges is just a synonym of \c \@arcs.
    3.85 +
    3.86 +The \c \@attributes section contains key-value pairs, each line
    3.87 +consists of two tokens, an attribute name, and then an attribute value.
    3.88 +
    3.89 +\code
    3.90 + @attributes
    3.91 + source 1
    3.92 + target 3
    3.93 + caption "LEMON test digraph"
    3.94 +\endcode
    3.95 +
    3.96 +*/
    3.97 +}
    3.98 +
    3.99 +//  LocalWords:  whitespace whitespaces
     4.1 --- a/lemon/lgf_reader.h	Mon May 05 11:41:30 2008 +0200
     4.2 +++ b/lemon/lgf_reader.h	Sat May 17 06:30:02 2008 +0100
     4.3 @@ -268,35 +268,58 @@
     4.4        str = os.str();
     4.5        return is;
     4.6      }
     4.7 -
     4.8 -    std::istream& readIdentifier(std::istream& is, std::string& str) {
     4.9 -      std::ostringstream os;
    4.10 -
    4.11 -      char c;
    4.12 -      is >> std::ws;
    4.13 -      
    4.14 -      if (!is.get(c))
    4.15 -	return is;
    4.16 -
    4.17 -      if (!isIdentifierFirstChar(c))
    4.18 -	throw DataFormatError("Wrong char in identifier");
    4.19 -      
    4.20 -      os << c;
    4.21 -      
    4.22 -      while (is.get(c) && !isWhiteSpace(c)) {
    4.23 -	if (!isIdentifierChar(c)) 
    4.24 -	  throw DataFormatError("Wrong char in identifier");	  
    4.25 -	os << c;
    4.26 -      }
    4.27 -      if (!is) is.clear();
    4.28 -     
    4.29 -      str = os.str();
    4.30 -      return is;
    4.31 -    }
    4.32      
    4.33    }
    4.34 -  
    4.35 -  /// \e
    4.36 +
    4.37 +  /// \ingroup lemon_io
    4.38 +  ///  
    4.39 +  /// \brief LGF reader for directed graphs
    4.40 +  ///
    4.41 +  /// This utility reads an \ref lgf-format "LGF" file.
    4.42 +  ///
    4.43 +  /// The reading method does a batch processing. The user creates a
    4.44 +  /// reader object, then various reading rules can be added to the
    4.45 +  /// reader, and eventually the reading is executed with the \c run()
    4.46 +  /// member function. A map reading rule can be added to the reader
    4.47 +  /// with the \c nodeMap() or \c arcMap() members. An optional
    4.48 +  /// converter parameter can also be added as a standard functor converting from
    4.49 +  /// std::string to the value type of the map. If it is set, it will
    4.50 +  /// determine how the tokens in the file should be is converted to the map's
    4.51 +  /// value type. If the functor is not set, then a default conversion
    4.52 +  /// will be used. One map can be read into multiple map objects at the
    4.53 +  /// same time. The \c attribute(), \c node() and \c arc() functions
    4.54 +  /// are used to add attribute reading rules.
    4.55 +  ///
    4.56 +  ///\code
    4.57 +  ///     DigraphReader<Digraph>(std::cin, digraph).
    4.58 +  ///       nodeMap("coordinates", coord_map).
    4.59 +  ///       arcMap("capacity", cap_map).
    4.60 +  ///       node("source", src).
    4.61 +  ///       node("target", trg).
    4.62 +  ///       attribute("caption", caption).
    4.63 +  ///       run();
    4.64 +  ///\endcode
    4.65 +  ///
    4.66 +  /// By default the reader uses the first section in the file of the
    4.67 +  /// proper type. If a section has an optional name, then it can be
    4.68 +  /// selected for reading by giving an optional name parameter to
    4.69 +  /// the \c nodes(), \c arcs() or \c attributes()
    4.70 +  /// functions.
    4.71 +  ///
    4.72 +  /// The \c useNodes() and \c useArcs() functions are used to tell the reader
    4.73 +  /// that the nodes or arcs should not be constructed (added to the
    4.74 +  /// graph) during the reading, but instead the label map of the items
    4.75 +  /// are given as a parameter of these functions. An
    4.76 +  /// application of these function is multipass reading, which is
    4.77 +  /// important if two \e \@arcs sections must be read from the
    4.78 +  /// file. In this example the first phase would read the node set and one
    4.79 +  /// of the arc sets, while the second phase would read the second arc
    4.80 +  /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
    4.81 +  /// The previously read label node map should be passed to the \c
    4.82 +  /// useNodes() functions. Another application of multipass reading when
    4.83 +  /// paths are given as a node map or an arc map. It is impossible read this in
    4.84 +  /// a single pass, because the arcs are not constructed when the node
    4.85 +  /// maps are read.
    4.86    template <typename _Digraph>
    4.87    class DigraphReader {
    4.88    public:
    4.89 @@ -341,23 +364,34 @@
    4.90  
    4.91    public:
    4.92  
    4.93 -    /// \e
    4.94 +    /// \brief Constructor
    4.95 +    ///
    4.96 +    /// Construct a directed graph reader, which reads from the given
    4.97 +    /// input stream.
    4.98      DigraphReader(std::istream& is, Digraph& digraph) 
    4.99        : _is(&is), local_is(false), _digraph(digraph),
   4.100  	_use_nodes(false), _use_arcs(false) {}
   4.101  
   4.102 -    /// \e
   4.103 +    /// \brief Constructor
   4.104 +    ///
   4.105 +    /// Construct a directed graph reader, which reads from the given
   4.106 +    /// file.
   4.107      DigraphReader(const std::string& fn, Digraph& digraph) 
   4.108        : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
   4.109      	_use_nodes(false), _use_arcs(false) {}
   4.110 -
   4.111 -
   4.112 -    /// \e
   4.113 +    
   4.114 +    /// \brief Constructor
   4.115 +    ///
   4.116 +    /// Construct a directed graph reader, which reads from the given
   4.117 +    /// file.
   4.118      DigraphReader(const char* fn, Digraph& digraph) 
   4.119        : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
   4.120      	_use_nodes(false), _use_arcs(false) {}
   4.121  
   4.122 -    /// \e
   4.123 +    /// \brief Copy constructor
   4.124 +    ///
   4.125 +    /// The copy constructor transfers all data from the other reader,
   4.126 +    /// therefore the copied reader will not be usable more. 
   4.127      DigraphReader(DigraphReader& other) 
   4.128        : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
   4.129  	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs) {
   4.130 @@ -377,7 +411,7 @@
   4.131        _attributes_caption = other._attributes_caption;
   4.132      }
   4.133  
   4.134 -    /// \e
   4.135 +    /// \brief Destructor
   4.136      ~DigraphReader() {
   4.137        for (typename NodeMaps::iterator it = _node_maps.begin(); 
   4.138  	   it != _node_maps.end(); ++it) {
   4.139 @@ -406,7 +440,12 @@
   4.140  
   4.141    public:
   4.142  
   4.143 -    /// \e
   4.144 +    /// \name Reading rules
   4.145 +    /// @{
   4.146 +    
   4.147 +    /// \brief Node map reading rule
   4.148 +    ///
   4.149 +    /// Add a node map reading rule to the reader.
   4.150      template <typename Map>
   4.151      DigraphReader& nodeMap(const std::string& caption, Map& map) {
   4.152        checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
   4.153 @@ -416,7 +455,10 @@
   4.154        return *this;
   4.155      }
   4.156  
   4.157 -    /// \e
   4.158 +    /// \brief Node map reading rule
   4.159 +    ///
   4.160 +    /// Add a node map reading rule with specialized converter to the
   4.161 +    /// reader.
   4.162      template <typename Map, typename Converter>
   4.163      DigraphReader& nodeMap(const std::string& caption, Map& map, 
   4.164  			   const Converter& converter = Converter()) {
   4.165 @@ -427,7 +469,9 @@
   4.166        return *this;
   4.167      }
   4.168  
   4.169 -    /// \e
   4.170 +    /// \brief Arc map reading rule
   4.171 +    ///
   4.172 +    /// Add an arc map reading rule to the reader.
   4.173      template <typename Map>
   4.174      DigraphReader& arcMap(const std::string& caption, Map& map) {
   4.175        checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
   4.176 @@ -437,7 +481,10 @@
   4.177        return *this;
   4.178      }
   4.179  
   4.180 -    /// \e
   4.181 +    /// \brief Arc map reading rule
   4.182 +    ///
   4.183 +    /// Add an arc map reading rule with specialized converter to the
   4.184 +    /// reader.
   4.185      template <typename Map, typename Converter>
   4.186      DigraphReader& arcMap(const std::string& caption, Map& map, 
   4.187  			  const Converter& converter = Converter()) {
   4.188 @@ -448,7 +495,9 @@
   4.189        return *this;
   4.190      }
   4.191  
   4.192 -    /// \e
   4.193 +    /// \brief Attribute reading rule
   4.194 +    ///
   4.195 +    /// Add an attribute reading rule to the reader.
   4.196      template <typename Value>
   4.197      DigraphReader& attribute(const std::string& caption, Value& value) {
   4.198        _reader_bits::ValueStorageBase* storage = 
   4.199 @@ -457,7 +506,10 @@
   4.200        return *this;
   4.201      }
   4.202  
   4.203 -    /// \e
   4.204 +    /// \brief Attribute reading rule
   4.205 +    ///
   4.206 +    /// Add an attribute reading rule with specialized converter to the
   4.207 +    /// reader.
   4.208      template <typename Value, typename Converter>
   4.209      DigraphReader& attribute(const std::string& caption, Value& value, 
   4.210  			     const Converter& converter = Converter()) {
   4.211 @@ -467,7 +519,9 @@
   4.212        return *this;
   4.213      }
   4.214  
   4.215 -    /// \e
   4.216 +    /// \brief Node reading rule
   4.217 +    ///
   4.218 +    /// Add a node reading rule to reader.
   4.219      DigraphReader& node(const std::string& caption, Node& node) {
   4.220        typedef _reader_bits::MapLookUpConverter<Node> Converter;
   4.221        Converter converter(_node_index);
   4.222 @@ -477,7 +531,9 @@
   4.223        return *this;
   4.224      }
   4.225  
   4.226 -    /// \e
   4.227 +    /// \brief Arc reading rule
   4.228 +    ///
   4.229 +    /// Add an arc reading rule to reader.
   4.230      DigraphReader& arc(const std::string& caption, Arc& arc) {
   4.231        typedef _reader_bits::MapLookUpConverter<Arc> Converter;
   4.232        Converter converter(_arc_index);
   4.233 @@ -487,25 +543,44 @@
   4.234        return *this;
   4.235      }
   4.236  
   4.237 -    /// \e
   4.238 +    /// @}
   4.239 +
   4.240 +    /// \name Select section by name
   4.241 +    /// @{
   4.242 +
   4.243 +    /// \brief Set \c \@nodes section to be read
   4.244 +    ///
   4.245 +    /// Set \c \@nodes section to be read
   4.246      DigraphReader& nodes(const std::string& caption) {
   4.247        _nodes_caption = caption;
   4.248        return *this;
   4.249      }
   4.250  
   4.251 -    /// \e
   4.252 +    /// \brief Set \c \@arcs section to be read
   4.253 +    ///
   4.254 +    /// Set \c \@arcs section to be read
   4.255      DigraphReader& arcs(const std::string& caption) {
   4.256        _arcs_caption = caption;
   4.257        return *this;
   4.258      }
   4.259  
   4.260 -    /// \e
   4.261 +    /// \brief Set \c \@attributes section to be read
   4.262 +    ///
   4.263 +    /// Set \c \@attributes section to be read
   4.264      DigraphReader& attributes(const std::string& caption) {
   4.265        _attributes_caption = caption;
   4.266        return *this;
   4.267      }
   4.268  
   4.269 -    /// \e
   4.270 +    /// @}
   4.271 +
   4.272 +    /// \name Using previously constructed node or arc set
   4.273 +    /// @{
   4.274 +
   4.275 +    /// \brief Use previously constructed node set
   4.276 +    ///
   4.277 +    /// Use previously constructed node set, and specify the node
   4.278 +    /// label map.
   4.279      template <typename Map>
   4.280      DigraphReader& useNodes(const Map& map) {
   4.281        checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   4.282 @@ -518,7 +593,11 @@
   4.283        return *this;
   4.284      }
   4.285  
   4.286 -    /// \e
   4.287 +    /// \brief Use previously constructed node set
   4.288 +    ///
   4.289 +    /// Use previously constructed node set, and specify the node
   4.290 +    /// label map and a functor which converts the label map values to
   4.291 +    /// std::string.
   4.292      template <typename Map, typename Converter>
   4.293      DigraphReader& useNodes(const Map& map, 
   4.294  			    const Converter& converter = Converter()) {
   4.295 @@ -531,7 +610,10 @@
   4.296        return *this;
   4.297      }
   4.298  
   4.299 -    /// \e
   4.300 +    /// \brief Use previously constructed arc set
   4.301 +    ///
   4.302 +    /// Use previously constructed arc set, and specify the arc
   4.303 +    /// label map.
   4.304      template <typename Map>
   4.305      DigraphReader& useArcs(const Map& map) {
   4.306        checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   4.307 @@ -544,7 +626,11 @@
   4.308        return *this;
   4.309      }
   4.310  
   4.311 -    /// \e
   4.312 +    /// \brief Use previously constructed arc set
   4.313 +    ///
   4.314 +    /// Use previously constructed arc set, and specify the arc
   4.315 +    /// label map and a functor which converts the label map values to
   4.316 +    /// std::string.
   4.317      template <typename Map, typename Converter>
   4.318      DigraphReader& useArcs(const Map& map, 
   4.319  			    const Converter& converter = Converter()) {
   4.320 @@ -557,6 +643,8 @@
   4.321        return *this;
   4.322      }
   4.323  
   4.324 +    /// @}
   4.325 +
   4.326    private:
   4.327  
   4.328      bool readLine() {
   4.329 @@ -597,7 +685,7 @@
   4.330  	
   4.331  	std::string map;
   4.332  	int index = 0;
   4.333 -	while (_reader_bits::readIdentifier(line, map)) {
   4.334 +	while (_reader_bits::readToken(line, map)) {
   4.335  	  if (maps.find(map) != maps.end()) {
   4.336  	    std::ostringstream msg;
   4.337  	    msg << "Multiple occurence of node map: " << map;
   4.338 @@ -680,7 +768,7 @@
   4.339  	
   4.340  	std::string map;
   4.341  	int index = 0;
   4.342 -	while (_reader_bits::readIdentifier(line, map)) {
   4.343 +	while (_reader_bits::readToken(line, map)) {
   4.344  	  if (maps.find(map) != maps.end()) {
   4.345  	    std::ostringstream msg;
   4.346  	    msg << "Multiple occurence of arc map: " << map;
   4.347 @@ -787,7 +875,7 @@
   4.348  	line.putback(c);
   4.349  	
   4.350  	std::string attr, token;
   4.351 -	if (!_reader_bits::readIdentifier(line, attr))
   4.352 +	if (!_reader_bits::readToken(line, attr))
   4.353  	  throw DataFormatError("Attribute name not found");
   4.354  	if (!_reader_bits::readToken(line, token))
   4.355  	  throw DataFormatError("Attribute value not found");
   4.356 @@ -827,8 +915,13 @@
   4.357      }
   4.358  
   4.359    public:
   4.360 -    
   4.361 -    /// \e
   4.362 +
   4.363 +    /// \name Execution of the reader    
   4.364 +    /// @{
   4.365 +
   4.366 +    /// \brief Start the batch processing
   4.367 +    ///
   4.368 +    /// This function starts the batch processing
   4.369      void run() {
   4.370        
   4.371        LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
   4.372 @@ -846,8 +939,8 @@
   4.373  	  char c;
   4.374  	  std::string section, caption;
   4.375  	  line >> c;
   4.376 -	  _reader_bits::readIdentifier(line, section);
   4.377 -	  _reader_bits::readIdentifier(line, caption);
   4.378 +	  _reader_bits::readToken(line, section);
   4.379 +	  _reader_bits::readToken(line, caption);
   4.380  
   4.381  	  if (line >> c) 
   4.382  	    throw DataFormatError("Extra character on the end of line");
   4.383 @@ -891,20 +984,25 @@
   4.384        }
   4.385  
   4.386      }
   4.387 +
   4.388 +    /// @}
   4.389      
   4.390    };
   4.391  
   4.392 +  /// \relates DigraphReader
   4.393    template <typename Digraph>
   4.394    DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
   4.395      return DigraphReader<Digraph>(is, digraph);
   4.396    }
   4.397  
   4.398 +  /// \relates DigraphReader
   4.399    template <typename Digraph>
   4.400    DigraphReader<Digraph> digraphReader(const std::string& fn, 
   4.401  				       Digraph& digraph) {
   4.402      return DigraphReader<Digraph>(fn, digraph);
   4.403    }
   4.404  
   4.405 +  /// \relates DigraphReader
   4.406    template <typename Digraph>
   4.407    DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
   4.408      return DigraphReader<Digraph>(fn, digraph);
     5.1 --- a/lemon/lgf_writer.h	Mon May 05 11:41:30 2008 +0200
     5.2 +++ b/lemon/lgf_writer.h	Sat May 17 06:30:02 2008 +0100
     5.3 @@ -204,6 +204,7 @@
     5.4      }
     5.5  
     5.6      bool requireEscape(const std::string& str) {
     5.7 +      if (str.empty() || str[0] == '@') return true;
     5.8        std::istringstream is(str);
     5.9        char c;
    5.10        while (is.get(c)) {
    5.11 @@ -231,7 +232,50 @@
    5.12  
    5.13    }
    5.14    
    5.15 -  /// \e
    5.16 +  /// \ingroup lemon_io
    5.17 +  ///  
    5.18 +  /// \brief LGF writer for directed graphs
    5.19 +  ///
    5.20 +  /// This utility writes an \ref lgf-format "LGF" file.
    5.21 +  ///
    5.22 +  /// The writing method does a batch processing. The user creates a
    5.23 +  /// writer object, then various writing rules can be added to the
    5.24 +  /// writer, and eventually the writing is executed with the \c run()
    5.25 +  /// member function. A map writing rule can be added to the writer
    5.26 +  /// with the \c nodeMap() or \c arcMap() members. An optional
    5.27 +  /// converter parameter can also be added as a standard functor converting from
    5.28 +  /// the value type of the map to std::string. If it is set, it will
    5.29 +  /// determine how the map's value type is written to the output
    5.30 +  /// stream. If the functor is not set, then a default conversion
    5.31 +  /// will be used. The \c attribute(), \c node() and \c arc() functions
    5.32 +  /// are used to add attribute writing rules.
    5.33 +  ///
    5.34 +  ///\code
    5.35 +  ///     DigraphWriter<Digraph>(std::cout, digraph).
    5.36 +  ///       nodeMap("coordinates", coord_map).
    5.37 +  ///       nodeMap("size", size).
    5.38 +  ///       nodeMap("title", title).
    5.39 +  ///       arcMap("capacity", cap_map).
    5.40 +  ///       node("source", src).
    5.41 +  ///       node("target", trg).
    5.42 +  ///       attribute("caption", caption).
    5.43 +  ///       run();
    5.44 +  ///\endcode
    5.45 +  ///
    5.46 +  ///
    5.47 +  /// By default, the writer does not write additional captions to the
    5.48 +  /// sections, but they can be give as an optional parameter of
    5.49 +  /// the \c nodes(), \c arcs() or \c
    5.50 +  /// attributes() functions.
    5.51 +  ///
    5.52 +  /// The \c skipNodes() and \c skipArcs() functions forbid the
    5.53 +  /// writing of the sections. If two arc sections should be written to the
    5.54 +  /// output, it can be done in two passes, the first pass writes the
    5.55 +  /// node section and the first arc section, then the second pass
    5.56 +  /// skips the node section and writes just the arc section to the
    5.57 +  /// stream. The output stream can be retrieved with the \c ostream()
    5.58 +  /// function, hence the second pass can append its output to the output of the
    5.59 +  /// first pass.
    5.60    template <typename _Digraph>
    5.61    class DigraphWriter {
    5.62    public:
    5.63 @@ -273,21 +317,34 @@
    5.64  
    5.65    public:
    5.66  
    5.67 -    /// \e
    5.68 +    /// \brief Constructor
    5.69 +    ///
    5.70 +    /// Construct a directed graph writer, which writes to the given
    5.71 +    /// output stream.
    5.72      DigraphWriter(std::ostream& is, Digraph& digraph) 
    5.73        : _os(&is), local_os(false), _digraph(digraph),
    5.74  	_skip_nodes(false), _skip_arcs(false) {}
    5.75  
    5.76 -    /// \e
    5.77 +    /// \brief Constructor
    5.78 +    ///
    5.79 +    /// Construct a directed graph writer, which writes to the given
    5.80 +    /// output file.
    5.81      DigraphWriter(const std::string& fn, Digraph& digraph) 
    5.82        : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
    5.83  	_skip_nodes(false), _skip_arcs(false) {}
    5.84  
    5.85 -    /// \e
    5.86 +    /// \brief Constructor
    5.87 +    ///
    5.88 +    /// Construct a directed graph writer, which writes to the given
    5.89 +    /// output file.
    5.90      DigraphWriter(const char* fn, Digraph& digraph) 
    5.91        : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
    5.92  	_skip_nodes(false), _skip_arcs(false) {}
    5.93  
    5.94 +    /// \brief Copy constructor
    5.95 +    ///
    5.96 +    /// The copy constructor transfers all data from the other writer,
    5.97 +    /// therefore the copied writer will not be usable more. 
    5.98      DigraphWriter(DigraphWriter& other) 
    5.99        : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
   5.100  	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
   5.101 @@ -307,7 +364,7 @@
   5.102        _attributes_caption = other._attributes_caption;
   5.103      }
   5.104  
   5.105 -    /// \e
   5.106 +    /// \brief Destructor
   5.107      ~DigraphWriter() {
   5.108        for (typename NodeMaps::iterator it = _node_maps.begin(); 
   5.109  	   it != _node_maps.end(); ++it) {
   5.110 @@ -335,7 +392,12 @@
   5.111  
   5.112    public:
   5.113  
   5.114 -    /// \e
   5.115 +    /// \name Writing rules
   5.116 +    /// @{
   5.117 +    
   5.118 +    /// \brief Node map reading rule
   5.119 +    ///
   5.120 +    /// Add a node map reading rule to the writer.
   5.121      template <typename Map>
   5.122      DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
   5.123        checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
   5.124 @@ -345,7 +407,10 @@
   5.125        return *this;
   5.126      }
   5.127  
   5.128 -    /// \e
   5.129 +    /// \brief Node map writing rule
   5.130 +    ///
   5.131 +    /// Add a node map writing rule with specialized converter to the
   5.132 +    /// writer.
   5.133      template <typename Map, typename Converter>
   5.134      DigraphWriter& nodeMap(const std::string& caption, const Map& map, 
   5.135  			   const Converter& converter = Converter()) {
   5.136 @@ -356,7 +421,9 @@
   5.137        return *this;
   5.138      }
   5.139  
   5.140 -    /// \e
   5.141 +    /// \brief Arc map writing rule
   5.142 +    ///
   5.143 +    /// Add an arc map writing rule to the writer.
   5.144      template <typename Map>
   5.145      DigraphWriter& arcMap(const std::string& caption, const Map& map) {
   5.146        checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
   5.147 @@ -366,7 +433,10 @@
   5.148        return *this;
   5.149      }
   5.150  
   5.151 -    /// \e
   5.152 +    /// \brief Arc map writing rule
   5.153 +    ///
   5.154 +    /// Add an arc map writing rule with specialized converter to the
   5.155 +    /// writer.
   5.156      template <typename Map, typename Converter>
   5.157      DigraphWriter& arcMap(const std::string& caption, const Map& map, 
   5.158  			  const Converter& converter = Converter()) {
   5.159 @@ -377,7 +447,9 @@
   5.160        return *this;
   5.161      }
   5.162  
   5.163 -    /// \e
   5.164 +    /// \brief Attribute writing rule
   5.165 +    ///
   5.166 +    /// Add an attribute writing rule to the writer.
   5.167      template <typename Value>
   5.168      DigraphWriter& attribute(const std::string& caption, const Value& value) {
   5.169        _writer_bits::ValueStorageBase* storage = 
   5.170 @@ -386,7 +458,10 @@
   5.171        return *this;
   5.172      }
   5.173  
   5.174 -    /// \e
   5.175 +    /// \brief Attribute writing rule
   5.176 +    ///
   5.177 +    /// Add an attribute writing rule with specialized converter to the
   5.178 +    /// writer.
   5.179      template <typename Value, typename Converter>
   5.180      DigraphWriter& attribute(const std::string& caption, const Value& value, 
   5.181  			     const Converter& converter = Converter()) {
   5.182 @@ -396,7 +471,9 @@
   5.183        return *this;
   5.184      }
   5.185  
   5.186 -    /// \e
   5.187 +    /// \brief Node writing rule
   5.188 +    ///
   5.189 +    /// Add a node writing rule to the writer.
   5.190      DigraphWriter& node(const std::string& caption, const Node& node) {
   5.191        typedef _writer_bits::MapLookUpConverter<Node> Converter;
   5.192        Converter converter(_node_index);
   5.193 @@ -406,7 +483,9 @@
   5.194        return *this;
   5.195      }
   5.196  
   5.197 -    /// \e
   5.198 +    /// \brief Arc writing rule
   5.199 +    ///
   5.200 +    /// Add an arc writing rule to writer.
   5.201      DigraphWriter& arc(const std::string& caption, const Arc& arc) {
   5.202        typedef _writer_bits::MapLookUpConverter<Arc> Converter;
   5.203        Converter converter(_arc_index);
   5.204 @@ -416,34 +495,54 @@
   5.205        return *this;
   5.206      }
   5.207  
   5.208 -    /// \e
   5.209 +    /// \name Select section by name
   5.210 +    /// @{
   5.211 +
   5.212 +    /// \brief Set \c \@nodes section to be read
   5.213 +    ///
   5.214 +    /// Set \c \@nodes section to be read
   5.215      DigraphWriter& nodes(const std::string& caption) {
   5.216        _nodes_caption = caption;
   5.217        return *this;
   5.218      }
   5.219  
   5.220 -    /// \e
   5.221 +    /// \brief Set \c \@arcs section to be read
   5.222 +    ///
   5.223 +    /// Set \c \@arcs section to be read
   5.224      DigraphWriter& arcs(const std::string& caption) {
   5.225        _arcs_caption = caption;
   5.226        return *this;
   5.227      }
   5.228  
   5.229 -    /// \e
   5.230 +    /// \brief Set \c \@attributes section to be read
   5.231 +    ///
   5.232 +    /// Set \c \@attributes section to be read
   5.233      DigraphWriter& attributes(const std::string& caption) {
   5.234        _attributes_caption = caption;
   5.235        return *this;
   5.236      }
   5.237  
   5.238 +    /// \name Skipping section
   5.239 +    /// @{
   5.240 +
   5.241 +    /// \brief Skip writing the node set
   5.242 +    ///
   5.243 +    /// The \c \@nodes section will be not written to the stream.
   5.244      DigraphWriter& skipNodes() {
   5.245        LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
   5.246        return *this;
   5.247      }
   5.248  
   5.249 +    /// \brief Skip writing arc set
   5.250 +    ///
   5.251 +    /// The \c \@arcs section will be not written to the stream.
   5.252      DigraphWriter& skipArcs() {
   5.253        LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
   5.254        return *this;
   5.255      }
   5.256  
   5.257 +    /// @}
   5.258 +
   5.259    private:
   5.260  
   5.261      void writeNodes() {
   5.262 @@ -458,7 +557,7 @@
   5.263  
   5.264        *_os << "@nodes";
   5.265        if (!_nodes_caption.empty()) {
   5.266 -	*_os << ' ' << _nodes_caption;
   5.267 +	_writer_bits::writeToken(*_os << ' ', _nodes_caption);
   5.268        }
   5.269        *_os << std::endl;
   5.270  
   5.271 @@ -467,7 +566,7 @@
   5.272        }
   5.273        for (typename NodeMaps::iterator it = _node_maps.begin();
   5.274  	   it != _node_maps.end(); ++it) {
   5.275 -	*_os << it->first << '\t';
   5.276 +	_writer_bits::writeToken(*_os, it->first) << '\t';
   5.277        }
   5.278        *_os << std::endl;
   5.279  
   5.280 @@ -518,7 +617,7 @@
   5.281  
   5.282        *_os << "@arcs";
   5.283        if (!_arcs_caption.empty()) {
   5.284 -	*_os << ' ' << _arcs_caption;
   5.285 +	_writer_bits::writeToken(*_os << ' ', _arcs_caption);
   5.286        }
   5.287        *_os << std::endl;
   5.288  
   5.289 @@ -528,7 +627,7 @@
   5.290        }
   5.291        for (typename ArcMaps::iterator it = _arc_maps.begin();
   5.292  	   it != _arc_maps.end(); ++it) {
   5.293 -	*_os << it->first << '\t';
   5.294 +	_writer_bits::writeToken(*_os, it->first) << '\t';
   5.295        }
   5.296        *_os << std::endl;
   5.297  
   5.298 @@ -577,12 +676,12 @@
   5.299        if (_attributes.empty()) return;
   5.300        *_os << "@attributes";
   5.301        if (!_attributes_caption.empty()) {
   5.302 -	*_os << ' ' << _attributes_caption;
   5.303 +	_writer_bits::writeToken(*_os << ' ', _attributes_caption);
   5.304        }
   5.305        *_os << std::endl;
   5.306        for (typename Attributes::iterator it = _attributes.begin();
   5.307  	   it != _attributes.end(); ++it) {
   5.308 -	*_os << it->first << ' ';
   5.309 +	_writer_bits::writeToken(*_os, it->first) << ' ';
   5.310  	_writer_bits::writeToken(*_os, it->second->get());
   5.311  	*_os << std::endl;
   5.312        }
   5.313 @@ -590,7 +689,12 @@
   5.314      
   5.315    public:
   5.316      
   5.317 -    /// \e
   5.318 +    /// \name Execution of the writer    
   5.319 +    /// @{
   5.320 +
   5.321 +    /// \brief Start the batch processing
   5.322 +    ///
   5.323 +    /// This function starts the batch processing
   5.324      void run() {
   5.325        if (!_skip_nodes) {
   5.326  	writeNodes();
   5.327 @@ -601,23 +705,30 @@
   5.328        writeAttributes();
   5.329      }
   5.330  
   5.331 -    /// \e
   5.332 -    std::ostream& stream() {
   5.333 +    /// \brief Gives back the stream of the writer
   5.334 +    ///
   5.335 +    /// Gives back the stream of the writer
   5.336 +    std::ostream& ostream() {
   5.337        return *_os;
   5.338      }
   5.339 +
   5.340 +    /// @}
   5.341    };
   5.342  
   5.343 +  /// \relates DigraphWriter
   5.344    template <typename Digraph>
   5.345    DigraphWriter<Digraph> digraphWriter(std::istream& is, Digraph& digraph) {
   5.346      return DigraphWriter<Digraph>(is, digraph);
   5.347    }
   5.348  
   5.349 +  /// \relates DigraphWriter
   5.350    template <typename Digraph>
   5.351    DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
   5.352  				       Digraph& digraph) {
   5.353      return DigraphWriter<Digraph>(fn, digraph);
   5.354    }
   5.355  
   5.356 +  /// \relates DigraphWriter
   5.357    template <typename Digraph>
   5.358    DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
   5.359      return DigraphWriter<Digraph>(fn, digraph);