[Boost-docs] Enabling SVG support in quickbook.

Subject: [Boost-docs] Enabling SVG support in quickbook.
From: John Maddock (john_at_[hidden])
Date: 2007-12-05 18:49:32


Unfortunately if you try and use an SVG image inside quickbook using:

[$../my_image.svg]

for example, then the image does not display at all in the (X)HTML output,
the patch below fixes this, the comments in the code explain what it does
and why. Turned out to be a bigger patch than I had hoped for... but is
this acceptable to commit? I had to add some fairly brain-dead SVG/XML
parsing to get the job done, so if there's a better way I'm all ears :-)

Regards, John.

Index: detail/actions.cpp
===================================================================
--- detail/actions.cpp (revision 41684)
+++ detail/actions.cpp (working copy)
@@ -12,6 +12,7 @@
 #include <functional>
 #include <boost/bind.hpp>
 #include <boost/filesystem/convenience.hpp>
+#include <boost/filesystem/fstream.hpp>
 #include <boost/lexical_cast.hpp>
 #include "./actions.hpp"
 #include "./utils.hpp"
@@ -376,9 +377,73 @@
     {
         fs::path const img_path(std::string(first, last));

+ std::string attr_text;
+ 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).
+ //
+ attr_text = " format=\"SVG\"";
+ //
+ // Image paths are relative to the html subdirectory:
+ //
+ 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 = 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)
+ {
+ attr_text.append(" contentwidth=");
+ attr_text.append(svg_text.begin() + a, svg_text.begin() + b +
1);

+ }
+ 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)
+ {
+ attr_text.append(" contentdepth=");
+ attr_text.append(svg_text.begin() + a, svg_text.begin() + b +
1);

+ }
+ }
+
         phrase << "<inlinemediaobject>";

- phrase << "<imageobject><imagedata fileref=\"";
+ phrase << "<imageobject><imagedata ";
+ phrase << attr_text;
+ phrase << " fileref=\"";
         while (first != last)
             detail::print_char(*first++, phrase.get());
         phrase << "\"></imagedata></imageobject>";


This archive was generated by hypermail 2.1.7 : 2017-11-11 08:50:40 UTC