$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r55917 - in trunk/tools/quickbook: . detail test
From: daniel_james_at_[hidden]
Date: 2009-08-31 07:38:48
Author: danieljames
Date: 2009-08-31 07:38:47 EDT (Mon, 31 Aug 2009)
New Revision: 55917
URL: http://svn.boost.org/trac/boost/changeset/55917
Log:
Support image attributes. Refs #1157.
Added:
   trunk/tools/quickbook/test/image_1_5.gold   (contents, props changed)
   trunk/tools/quickbook/test/image_1_5.quickbook   (contents, props changed)
Text files modified: 
   trunk/tools/quickbook/detail/actions.cpp       |    63 ++++++++++++++++++++++++++++++--------- 
   trunk/tools/quickbook/detail/actions.hpp       |    28 ++++++++++++++++-                       
   trunk/tools/quickbook/detail/actions_class.cpp |     6 +++                                     
   trunk/tools/quickbook/detail/actions_class.hpp |     4 ++                                      
   trunk/tools/quickbook/phrase.hpp               |    29 +++++++++++++++---                      
   trunk/tools/quickbook/test/Jamfile.v2          |     1                                         
   6 files changed, 108 insertions(+), 23 deletions(-)
Modified: trunk/tools/quickbook/detail/actions.cpp
==============================================================================
--- trunk/tools/quickbook/detail/actions.cpp	(original)
+++ trunk/tools/quickbook/detail/actions.cpp	2009-08-31 07:38:47 EDT (Mon, 31 Aug 2009)
@@ -400,11 +400,29 @@
         detail::print_char(*first, phrase.get());
     }
 
-    void image_action::operator()(iterator first, iterator last) const
+    void attribute_action::operator()(iterator first, iterator last) const
     {
-        fs::path const img_path(std::string(first, last));
+        boost::spirit::classic::file_position const pos = first.get_position();
+
+        if (!attributes.insert(
+                attribute_map::value_type(attribute_name, std::string(first, last))
+            ).second)
+        {
+            detail::outerr(pos.file,pos.line)
+                << "Repeated attribute: " << attribute_name << ".\n";
+        }
+    }
+
+    void image_action::operator()(iterator, iterator) const
+    {
+        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));
 
-        std::string attr_text;
         if(fs::extension(img_path) == ".svg")
         {
            //
@@ -418,7 +436,7 @@
            //    a tiny box with scrollbars (Firefox), or else cropped to
            //    fit in a tiny box (IE7).
            //
-           attr_text = " format=\"SVG\"";
+           attributes.insert(attribute_map::value_type("format", "SVG"));
            //
            // Image paths are relative to the html subdirectory:
            //
@@ -452,8 +470,8 @@
            b = svg_text.find('\"', a + 1);
            if(a != std::string::npos)
            {
-              attr_text.append(" contentwidth=");
-              attr_text.append(svg_text.begin() + a, svg_text.begin() + b + 1);
+              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);
@@ -461,24 +479,39 @@
            b = svg_text.find('\"', a + 1);
            if(a != std::string::npos)
            {
-              attr_text.append(" contentdepth=");
-              attr_text.append(svg_text.begin() + a, svg_text.begin() + b + 1);
+              attributes.insert(attribute_map::value_type("contentdepth",
+                std::string(svg_text.begin() + a + 1, svg_text.begin() + b)));
            }
         }
 
         phrase << "<inlinemediaobject>";
 
-        phrase << "<imageobject><imagedata ";
-        phrase << attr_text;
-        phrase << " fileref=\"";
-        while (first != last)
-            detail::print_char(*first++, phrase.get());
-        phrase << "\"></imagedata></imageobject>";
+        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(fs::basename(img_path), phrase.get());
+        detail::print_string(alt_text, phrase.get());
         phrase << "</phrase></textobject>";
 
         phrase << "</inlinemediaobject>";
Modified: trunk/tools/quickbook/detail/actions.hpp
==============================================================================
--- trunk/tools/quickbook/detail/actions.hpp	(original)
+++ trunk/tools/quickbook/detail/actions.hpp	2009-08-31 07:38:47 EDT (Mon, 31 Aug 2009)
@@ -36,6 +36,7 @@
     namespace fs = boost::filesystem;
     typedef position_iterator<std::string::const_iterator> iterator;
     typedef symbols<std::string> string_symbols;
+    typedef std::map<std::string, std::string> attribute_map;
 
     struct actions;
     extern tm* current_time; // the current time
@@ -369,17 +370,40 @@
 
         collector& phrase;
     };
+    
+    struct attribute_action
+    {
+        // Handle image attributes
+        
+        attribute_action(
+            attribute_map& attributes
+          , std::string& attribute_name)
+        : attributes(attributes)
+        , attribute_name(attribute_name) {}
+
+        void operator()(iterator first, iterator last) const;
+
+        attribute_map& attributes;
+        std::string& attribute_name;
+    };
 
     struct image_action
     {
         // Handles inline images
 
-        image_action(collector& phrase)
-        : phrase(phrase) {}
+        image_action(
+            collector& phrase
+          , attribute_map& attributes
+          , std::string& image_fileref)
+        : phrase(phrase)
+        , attributes(attributes)
+        , image_fileref(image_fileref) {}
 
         void operator()(iterator first, iterator last) const;
 
         collector& phrase;
+        attribute_map& attributes;
+        std::string& image_fileref;
     };
 
     struct markup_action
Modified: trunk/tools/quickbook/detail/actions_class.cpp
==============================================================================
--- trunk/tools/quickbook/detail/actions_class.cpp	(original)
+++ trunk/tools/quickbook/detail/actions_class.cpp	2009-08-31 07:38:47 EDT (Mon, 31 Aug 2009)
@@ -64,6 +64,9 @@
         , template_escape(false)
         , templates()
         , error_count(0)
+        , image_fileref()
+        , attribute_name()
+        , attributes()
 
     // actions
         , error(error_count)
@@ -94,7 +97,8 @@
         , tip(out, temp_para, tip_pre, tip_post)
         , plain_char(phrase)
         , raw_char(phrase)
-        , image(phrase)
+        , attribute(attributes, attribute_name)
+        , image(phrase, attributes, image_fileref)
         , cond_phrase_pre(phrase, conditions, macro)
         , cond_phrase_post(phrase, conditions, macro)
 
Modified: trunk/tools/quickbook/detail/actions_class.hpp
==============================================================================
--- trunk/tools/quickbook/detail/actions_class.hpp	(original)
+++ trunk/tools/quickbook/detail/actions_class.hpp	2009-08-31 07:38:47 EDT (Mon, 31 Aug 2009)
@@ -92,6 +92,9 @@
         bool                    template_escape;
         template_stack          templates;
         int                     error_count;
+        std::string             image_fileref;
+        std::string             attribute_name;
+        attribute_map           attributes;
 
     // push/pop the states and the streams
         void push();
@@ -117,6 +120,7 @@
         phrase_action           warning, caution, important, note, tip;
         plain_char_action       plain_char;
         raw_char_action         raw_char;
+        attribute_action        attribute;
         image_action            image;
         cond_phrase_action_pre  cond_phrase_pre;
         cond_phrase_action_post cond_phrase_post;
Modified: trunk/tools/quickbook/phrase.hpp
==============================================================================
--- trunk/tools/quickbook/phrase.hpp	(original)
+++ trunk/tools/quickbook/phrase.hpp	2009-08-31 07:38:47 EDT (Mon, 31 Aug 2009)
@@ -16,6 +16,7 @@
 #include <boost/spirit/include/classic_confix.hpp>
 #include <boost/spirit/include/classic_chset.hpp>
 #include <boost/spirit/include/classic_assign_actor.hpp>
+#include <boost/spirit/include/classic_clear_actor.hpp>
 #include <boost/spirit/include/classic_if.hpp>
 
 namespace quickbook
@@ -290,11 +291,29 @@
                     ;
 
                 image =
-                        '$' >> blank
-                    >> (*(anychar_p -
-                            phrase_end))                [actions.image]
+                        '$' >> blank                    [clear_a(actions.attributes)]
+                    >>  if_p(qbk_since(105u)) [
+                                (+(
+                                    *space_p
+                                >>  +(anychar_p - (space_p | phrase_end | '['))
+                                ))                       [assign_a(actions.image_fileref)]
+                            >>  hard_space
+                            >>  *(
+                                    '['
+                                >>  (*(alnum_p | '_'))  [assign_a(actions.attribute_name)]
+                                >>  space
+                                >>  (*(anychar_p - (phrase_end | '[')))
+                                                        [actions.attribute]
+                                >>  ']'
+                                >>  space
+                                )
+                        ].else_p [
+                                (*(anychar_p -
+                                    phrase_end))        [assign_a(actions.image_fileref)]
+                        ]
+                    >>  eps_p(']')                      [actions.image]
                     ;
-
+                    
                 url =
                         '@'
                     >>  (*(anychar_p -
@@ -453,7 +472,7 @@
                             dummy_block, cond_phrase, macro_identifier, template_args,
                             template_args_1_4, template_arg_1_4, brackets_1_4,
                             template_args_1_5, template_arg_1_5,
-                            template_inner_arg_1_5, brackets_1_5,
+                            template_inner_arg_1_5, brackets_1_5
                             ;
 
             rule<Scanner> const&
Modified: trunk/tools/quickbook/test/Jamfile.v2
==============================================================================
--- trunk/tools/quickbook/test/Jamfile.v2	(original)
+++ trunk/tools/quickbook/test/Jamfile.v2	2009-08-31 07:38:47 EDT (Mon, 31 Aug 2009)
@@ -28,6 +28,7 @@
     [ quickbook-test section_1_4 ]
     [ quickbook-test section_1_5 ]
     [ quickbook-test table_1_5 ]
+    [ quickbook-test image_1_5 ]
     [ quickbook-fail-test fail-include ]
     [ quickbook-fail-test fail-import ]
     [ quickbook-fail-test fail-template-arguments1 ]
Added: trunk/tools/quickbook/test/image_1_5.gold
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/image_1_5.gold	2009-08-31 07:38:47 EDT (Mon, 31 Aug 2009)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+<article id="images_1_5" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $" xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Images 1.5</title>
+  <articleinfo>
+  </articleinfo>
+  <para>
+    <inlinemediaobject><imageobject><imagedata fileref="test.gif"></imagedata></imageobject>
+    <textobject>
+      <phrase>test</phrase>
+    </textobject>
+    </inlinemediaobject> <inlinemediaobject><imageobject><imagedata fileref="test this.gif"></imagedata></imageobject>
+    <textobject>
+      <phrase>test this</phrase>
+    </textobject>
+    </inlinemediaobject> <inlinemediaobject><imageobject><imagedata fileref="test&this.gif"></imagedata></imageobject>
+    <textobject>
+      <phrase>test&this</phrase>
+    </textobject>
+    </inlinemediaobject> <inlinemediaobject><imageobject><imagedata fileref="test.gif"
+    height="10cm" width="10cm"></imagedata></imageobject>
+    <textobject>
+      <phrase>test</phrase>
+    </textobject>
+    </inlinemediaobject> <inlinemediaobject><imageobject><imagedata fileref="test.gif"></imagedata></imageobject>
+    <textobject>
+      <phrase>Foo</phrase>
+    </textobject>
+    </inlinemediaobject> <inlinemediaobject><imageobject><imagedata fileref="test.gif"></imagedata></imageobject>
+    <textobject>
+      <phrase>Foobie foobie foo</phrase>
+    </textobject>
+    </inlinemediaobject> <inlinemediaobject><imageobject><imagedata fileref="test.gif"></imagedata></imageobject>
+    <textobject>
+      <phrase>Foo & bar</phrase>
+    </textobject>
+    </inlinemediaobject> <inlinemediaobject><imageobject><imagedata fileref="test.gif"
+    height="10cm" width="10cm"></imagedata></imageobject>
+    <textobject>
+      <phrase>Foo</phrase>
+    </textobject>
+    </inlinemediaobject>
+  </para>
+  <para>
+    <inlinemediaobject><imageobject><imagedata fileref="test.gif"></imagedata></imageobject>
+    <textobject>
+      <phrase>test</phrase>
+    </textobject>
+    </inlinemediaobject> <inlinemediaobject><imageobject><imagedata fileref="test.gif"></imagedata></imageobject>
+    <textobject>
+      <phrase>test</phrase>
+    </textobject>
+    </inlinemediaobject> <inlinemediaobject><imageobject><imagedata fileref="test.gif"></imagedata></imageobject>
+    <textobject>
+      <phrase>comment</phrase>
+    </textobject>
+    </inlinemediaobject>
+  </para>
+</article>
Added: trunk/tools/quickbook/test/image_1_5.quickbook
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/test/image_1_5.quickbook	2009-08-31 07:38:47 EDT (Mon, 31 Aug 2009)
@@ -0,0 +1,16 @@
+[article Images 1.5
+    [quickbook 1.5]
+]
+
+[$test.gif]
+[$test this.gif]
+[$test&this.gif]
+[$test.gif [width 10cm] [height 10cm]]
+[$test.gif [alt Foo]]
+[$test.gif [alt Foobie foobie foo]]
+[$test.gif [alt Foo & bar]]
+[$test.gif [alt Foo] [width 10cm] [height 10cm]]
+
+[$ [/comment] test.gif  ]
+[$ [/comment] test.gif [/comment] ]
+[$ [/comment] test.gif [/comment] [alt comment] ]
\ No newline at end of file