Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r59296 - in branches/quickbook-1.5-spirit2: . detail
From: daniel_james_at_[hidden]
Date: 2010-01-27 17:01:10


Author: danieljames
Date: 2010-01-27 17:01:09 EST (Wed, 27 Jan 2010)
New Revision: 59296
URL: http://svn.boost.org/trac/boost/changeset/59296

Log:
Images.
Added:
   branches/quickbook-1.5-spirit2/phrase_image.cpp (contents, props changed)
Text files modified:
   branches/quickbook-1.5-spirit2/Jamfile.v2 | 1
   branches/quickbook-1.5-spirit2/detail/actions.cpp | 131 ----------------------------------------
   branches/quickbook-1.5-spirit2/detail/actions.hpp | 19 -----
   branches/quickbook-1.5-spirit2/detail/actions_class.cpp | 1
   branches/quickbook-1.5-spirit2/detail/actions_class.hpp | 1
   branches/quickbook-1.5-spirit2/phrase.cpp | 37 ++++++++--
   branches/quickbook-1.5-spirit2/phrase.hpp | 12 +++
   7 files changed, 41 insertions(+), 161 deletions(-)

Modified: branches/quickbook-1.5-spirit2/Jamfile.v2
==============================================================================
--- branches/quickbook-1.5-spirit2/Jamfile.v2 (original)
+++ branches/quickbook-1.5-spirit2/Jamfile.v2 2010-01-27 17:01:09 EST (Wed, 27 Jan 2010)
@@ -29,6 +29,7 @@
     detail/markups.cpp
     phrase.cpp
     phrase_actions.cpp
+ phrase_image.cpp
     block.cpp
     doc_info.cpp
     detail/syntax_highlight.cpp

Modified: branches/quickbook-1.5-spirit2/detail/actions.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/actions.cpp (original)
+++ branches/quickbook-1.5-spirit2/detail/actions.cpp 2010-01-27 17:01:09 EST (Wed, 27 Jan 2010)
@@ -397,137 +397,6 @@
         detail::print_char(*x.begin(), phrase.get());
     }
 
- void image_action::operator()(iterator position, std::string image_fileref,
- std::multimap<std::string, std::string> input_attributes) const
- {
- std::map<std::string, std::string> attributes(
- input_attributes.begin(), input_attributes.end());
-
- if(attributes.size() != input_attributes.size()) {
- boost::spirit::classic::file_position const pos = position.get_position();
-
- std::map<std::string, std::string> duplicates;
- std::set_difference(
- input_attributes.begin(), input_attributes.end(),
- attributes.begin(), attributes.end(),
- std::inserter(duplicates, duplicates.end()));
-
- for(std::map<std::string, std::string>::iterator
- begin = duplicates.begin(), end = duplicates.end();
- begin != end; ++begin)
- {
- detail::outerr(pos.file,pos.line)
- << "Duplicate image attribute: "
- << begin->first
- << std::endl;
- ++error_count;
- }
- }
-
- fs::path const img_path(image_fileref);
-
- attribute_map::iterator it = attributes.find("alt");
- std::string alt_text = it != attributes.end() ? it->second : fs::basename(img_path);
- attributes.erase("alt");
-
- attributes.insert(attribute_map::value_type("fileref", image_fileref));
-
- if(fs::extension(img_path) == ".svg")
- {
- //
- // SVG's need special handling:
- //
- // 1) We must set the "format" attribute, otherwise
- // HTML generation produces code that will not display
- // the image at all.
- // 2) We need to set the "contentwidth" and "contentdepth"
- // attributes, otherwise the image will be displayed inside
- // a tiny box with scrollbars (Firefox), or else cropped to
- // fit in a tiny box (IE7).
- //
- attributes.insert(attribute_map::value_type("format", "SVG"));
- //
- // Image paths are relative to the html subdirectory:
- // TODO: This only works when you're running in the correct directory.
- // Support 'boost:' directories? Include paths?
- //
- fs::path img;
- if(img_path.root_path().empty())
- img = "html" / img_path; // relative path
- else
- img = img_path; // absolute path
- //
- // Now load the SVG file:
- //
- std::string svg_text;
- fs::ifstream fs(img);
- char c;
- while(fs.get(c) && fs.good())
- svg_text.push_back(c);
- //
- // Extract the svg header from the file:
- //
- std::string::size_type a, b;
- a = svg_text.find("<svg");
- b = svg_text.find('>', a);
- svg_text = (a == std::string::npos) ? "" : svg_text.substr(a, b - a);
- //
- // Now locate the "width" and "height" attributes
- // and borrow their values:
- //
- a = svg_text.find("width");
- a = svg_text.find('=', a);
- a = svg_text.find('\"', a);
- b = svg_text.find('\"', a + 1);
- if(a != std::string::npos)
- {
- attributes.insert(attribute_map::value_type("contentwidth",
- std::string(svg_text.begin() + a + 1, svg_text.begin() + b)));
- }
- a = svg_text.find("height");
- a = svg_text.find('=', a);
- a = svg_text.find('\"', a);
- b = svg_text.find('\"', a + 1);
- if(a != std::string::npos)
- {
- attributes.insert(attribute_map::value_type("contentdepth",
- std::string(svg_text.begin() + a + 1, svg_text.begin() + b)));
- }
- }
-
- phrase << "<inlinemediaobject>";
-
- phrase << "<imageobject><imagedata";
-
- for(attribute_map::const_iterator
- attr_first = attributes.begin(), attr_last = attributes.end();
- attr_first != attr_last; ++attr_first)
- {
- phrase << " " << attr_first->first << "=\"";
-
- for(std::string::const_iterator
- first = attr_first->second.begin(),
- last = attr_first->second.end();
- first != last; ++first)
- {
- if (*first == '\\' && ++first == last) break;
- detail::print_char(*first, phrase.get());
- }
-
- phrase << "\"";
- }
-
- phrase << "></imagedata></imageobject>";
-
- // Also add a textobject -- use the basename of the image file.
- // This will mean we get "alt" attributes of the HTML img.
- phrase << "<textobject><phrase>";
- detail::print_string(alt_text, phrase.get());
- phrase << "</phrase></textobject>";
-
- phrase << "</inlinemediaobject>";
- }
-
     void macro_identifier_action::operator()(iterator_range x, unused_type, unused_type) const
     {
         actions.macro_id.assign(x.begin(), x.end());

Modified: branches/quickbook-1.5-spirit2/detail/actions.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/actions.hpp (original)
+++ branches/quickbook-1.5-spirit2/detail/actions.hpp 2010-01-27 17:01:09 EST (Wed, 27 Jan 2010)
@@ -376,25 +376,6 @@
         collector& phrase;
     };
     
- struct image_action
- {
- template <typename Arg1, typename Arg2, typename Arg3 = void>
- struct result {typedef void type; };
-
- // Handles inline images
-
- image_action(collector& phrase, int& error_count)
- : phrase(phrase)
- , error_count(error_count) {}
-
- void operator()(iterator, std::string,
- std::multimap<std::string, std::string>
- = std::multimap<std::string, std::string>()) const;
-
- collector& phrase;
- int& error_count;
- };
-
     struct markup_action
     {
         template <typename T = void> struct result { typedef void type; };

Modified: branches/quickbook-1.5-spirit2/detail/actions_class.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/actions_class.cpp (original)
+++ branches/quickbook-1.5-spirit2/detail/actions_class.cpp 2010-01-27 17:01:09 EST (Wed, 27 Jan 2010)
@@ -94,7 +94,6 @@
         , tip(out, temp_para, tip_pre, tip_post)
         , plain_char(phrase)
         , raw_char(phrase)
- , image(phrase, error_count)
         , cond_phrase_pre(phrase, conditions, macro)
         , cond_phrase_post(phrase, conditions, macro)
 

Modified: branches/quickbook-1.5-spirit2/detail/actions_class.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/actions_class.hpp (original)
+++ branches/quickbook-1.5-spirit2/detail/actions_class.hpp 2010-01-27 17:01:09 EST (Wed, 27 Jan 2010)
@@ -117,7 +117,6 @@
         phrase_action warning, caution, important, note, tip;
         plain_char_action plain_char;
         raw_char_action raw_char;
- image_action image;
         cond_phrase_action_pre cond_phrase_pre;
         cond_phrase_action_post cond_phrase_post;
 

Modified: branches/quickbook-1.5-spirit2/phrase.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/phrase.cpp (original)
+++ branches/quickbook-1.5-spirit2/phrase.cpp 2010-01-27 17:01:09 EST (Wed, 27 Jan 2010)
@@ -37,11 +37,26 @@
     (std::string, content)
 )
 
+BOOST_FUSION_ADAPT_STRUCT(
+ quickbook::image,
+ (quickbook::file_position, position)
+ (std::string, image_filename)
+ (quickbook::image::attribute_map, attributes)
+)
+
 namespace quickbook
 {
     namespace qi = boost::spirit::qi;
     namespace ph = boost::phoenix;
     
+ struct get_position_impl
+ {
+ template <typename Context>
+ void operator()(iterator_range& it, Context& c, unused_type x) const {
+ qi::_val(it, c, x) = it.begin().get_position();
+ }
+ } get_position;
+
     struct phrase_grammar::rules
     {
         rules(quickbook::actions& actions, bool& no_eols);
@@ -60,14 +75,16 @@
                         brackets_1_4, template_inner_arg_1_5, brackets_1_5
                         ;
 
+ qi::rule<iterator, file_position()> position;
+
         qi::rule<iterator, std::string()> template_arg_1_4, template_arg_1_5;
         qi::rule<iterator, std::vector<std::string>() > template_args;
 
         qi::rule<iterator, std::string()> phrase_attr;
 
- qi::rule<iterator> image, image_1_4, image_1_5;
+ qi::rule<iterator, quickbook::image()> image, image_1_4, image_1_5;
         qi::rule<iterator, std::string()> image_filename, image_attribute_key, image_attribute_value;
- qi::rule<iterator, std::multimap<std::string, std::string>()> image_attributes;
+ qi::rule<iterator, quickbook::image::attribute_map()> image_attributes;
         qi::rule<iterator, std::pair<std::string, std::string>()> image_attribute;
         
         qi::rule<iterator, boost::iterator_range<iterator>(char)> simple_markup;
@@ -254,7 +271,7 @@
         phrase_markup =
                 '['
>> ( cond_phrase
- | image
+ | image [actions.process]
                 | url [actions.process]
                 | link [actions.process]
                 | anchor
@@ -298,22 +315,22 @@
             (qi::eps(qbk_since(105u)) >> image_1_5) |
             (qi::eps(qbk_before(105u)) >> image_1_4);
         
- image_1_4 = (
- qi::raw['$']
+ image_1_4 =
+ position
+ >> '$'
>> blank
>> *(qi::char_ - phrase_end)
>> &qi::lit(']')
- ) [ph::bind(actions.image, ph::begin(qi::_1), as_string(qi::_2))]
             ;
         
- image_1_5 = (
- qi::raw['$']
+ image_1_5 =
+ position
+ >> '$'
>> blank
>> image_filename
>> hard_space
>> image_attributes
>> &qi::lit(']')
- ) [ph::bind(actions.image, ph::begin(qi::_1), qi::_2, qi::_3)]
             ;
 
         image_filename = qi::raw[
@@ -417,6 +434,8 @@
                 qi::lit("footnote") [actions.footnote_pre]
>> blank >> phrase [actions.footnote_post]
             ;
+
+ position = qi::raw[qi::eps] [get_position];
     }
 
     struct simple_phrase_grammar::rules

Modified: branches/quickbook-1.5-spirit2/phrase.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/phrase.hpp (original)
+++ branches/quickbook-1.5-spirit2/phrase.hpp 2010-01-27 17:01:09 EST (Wed, 27 Jan 2010)
@@ -11,11 +11,14 @@
 #define BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP
 
 #include <string>
+#include <map>
+#include <boost/spirit/include/classic_position_iterator.hpp>
 
 namespace quickbook
 {
     // TODO: Add to a forward header somewhere.
     class actions;
+ typedef boost::spirit::classic::file_position file_position;
 
     struct source_mode {
         source_mode() {}
@@ -39,9 +42,18 @@
         std::string destination;
         std::string content;
     };
+
+ struct image {
+ typedef std::multimap<std::string, std::string> attribute_map;
+
+ file_position position;
+ std::string image_filename;
+ attribute_map attributes;
+ };
 
     void process(quickbook::actions& actions, source_mode const& s);
     void process(quickbook::actions& actions, link const& x);
+ void process(quickbook::actions& actions, image const& x);
 }
 
 #endif // BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP

Added: branches/quickbook-1.5-spirit2/phrase_image.cpp
==============================================================================
--- (empty file)
+++ branches/quickbook-1.5-spirit2/phrase_image.cpp 2010-01-27 17:01:09 EST (Wed, 27 Jan 2010)
@@ -0,0 +1,147 @@
+/*=============================================================================
+ Copyright (c) 2002 2004 2006 Joel de Guzman
+ Copyright (c) 2004 Eric Niebler
+ http://spirit.sourceforge.net/
+
+ 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)
+=============================================================================*/
+
+#include "./phrase.hpp"
+#include "./detail/actions_class.hpp"
+#include <boost/filesystem/convenience.hpp>
+#include <boost/filesystem/fstream.hpp>
+
+namespace quickbook
+{
+ namespace fs = boost::filesystem;
+
+ void process(quickbook::actions& actions, image const& x)
+ {
+ std::map<std::string, std::string> attributes(
+ x.attributes.begin(), x.attributes.end());
+
+ if(attributes.size() != x.attributes.size()) {
+ std::map<std::string, std::string> duplicates;
+ std::set_difference(
+ x.attributes.begin(), x.attributes.end(),
+ attributes.begin(), attributes.end(),
+ std::inserter(duplicates, duplicates.end()));
+
+ for(std::map<std::string, std::string>::iterator
+ begin = duplicates.begin(), end = duplicates.end();
+ begin != end; ++begin)
+ {
+ detail::outerr(x.position.file, x.position.line)
+ << "Duplicate image attribute: "
+ << begin->first
+ << std::endl;
+ ++actions.error_count;
+ }
+ }
+
+ fs::path const img_path(x.image_filename);
+
+ attribute_map::iterator it = attributes.find("alt");
+ std::string alt_text = it != attributes.end() ? it->second : fs::basename(img_path);
+ attributes.erase("alt");
+
+ attributes.insert(attribute_map::value_type("fileref", x.image_filename));
+
+ if(fs::extension(img_path) == ".svg")
+ {
+ //
+ // SVG's need special handling:
+ //
+ // 1) We must set the "format" attribute, otherwise
+ // HTML generation produces code that will not display
+ // the image at all.
+ // 2) We need to set the "contentwidth" and "contentdepth"
+ // attributes, otherwise the image will be displayed inside
+ // a tiny box with scrollbars (Firefox), or else cropped to
+ // fit in a tiny box (IE7).
+ //
+ attributes.insert(attribute_map::value_type("format", "SVG"));
+ //
+ // Image paths are relative to the html subdirectory:
+ // TODO: This only works when you're running in the correct directory.
+ // Support 'boost:' directories? Include paths?
+ //
+ fs::path img;
+ if(img_path.root_path().empty())
+ img = "html" / img_path; // relative path
+ else
+ img = img_path; // absolute path
+ //
+ // Now load the SVG file:
+ //
+ std::string svg_text;
+ fs::ifstream fs(img);
+ char c;
+ while(fs.get(c) && fs.good())
+ svg_text.push_back(c);
+ //
+ // Extract the svg header from the file:
+ //
+ std::string::size_type a, b;
+ a = svg_text.find("<svg");
+ b = svg_text.find('>', a);
+ svg_text = (a == std::string::npos) ? "" : svg_text.substr(a, b - a);
+ //
+ // Now locate the "width" and "height" attributes
+ // and borrow their values:
+ //
+ a = svg_text.find("width");
+ a = svg_text.find('=', a);
+ a = svg_text.find('\"', a);
+ b = svg_text.find('\"', a + 1);
+ if(a != std::string::npos)
+ {
+ attributes.insert(attribute_map::value_type("contentwidth",
+ std::string(svg_text.begin() + a + 1, svg_text.begin() + b)));
+ }
+ a = svg_text.find("height");
+ a = svg_text.find('=', a);
+ a = svg_text.find('\"', a);
+ b = svg_text.find('\"', a + 1);
+ if(a != std::string::npos)
+ {
+ attributes.insert(attribute_map::value_type("contentdepth",
+ std::string(svg_text.begin() + a + 1, svg_text.begin() + b)));
+ }
+ }
+
+ actions.phrase << "<inlinemediaobject>";
+
+ actions.phrase << "<imageobject><imagedata";
+
+ for(attribute_map::const_iterator
+ attr_first = attributes.begin(), attr_last = attributes.end();
+ attr_first != attr_last; ++attr_first)
+ {
+ actions.phrase << " " << attr_first->first << "=\"";
+
+ for(std::string::const_iterator
+ first = attr_first->second.begin(),
+ last = attr_first->second.end();
+ first != last; ++first)
+ {
+ if (*first == '\\' && ++first == last) break;
+ detail::print_char(*first, actions.phrase.get());
+ }
+
+ actions.phrase << "\"";
+ }
+
+ actions.phrase << "></imagedata></imageobject>";
+
+ // Also add a textobject -- use the basename of the image file.
+ // This will mean we get "alt" attributes of the HTML img.
+ actions.phrase << "<textobject><phrase>";
+ detail::print_string(alt_text, actions.phrase.get());
+ actions.phrase << "</phrase></textobject>";
+
+ actions.phrase << "</inlinemediaobject>";
+ }
+}
\ No newline at end of file


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