/*============================================================================= 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 #include #include "phrase.hpp" #include "actions_class.hpp" #include "utils.hpp" namespace quickbook { namespace fs = boost::filesystem; void process(quickbook::actions& actions, image const& x) { std::map attributes( x.attributes.begin(), x.attributes.end()); if(attributes.size() != x.attributes.size()) { std::map duplicates; std::set_difference( x.attributes.begin(), x.attributes.end(), attributes.begin(), attributes.end(), std::inserter(duplicates, duplicates.end())); for(std::map::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("', 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 << ""; actions.phrase << "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 << ">"; // Also add a textobject -- use the basename of the image file. // This will mean we get "alt" attributes of the HTML img. actions.phrase << ""; detail::print_string(alt_text, actions.phrase.get()); actions.phrase << ""; actions.phrase << ""; } }